/* $Source: /v/ossp/cvs/ossp-pkg/petidomo/subscribe.c,v $ $Revision: 1.23 $ Copyright (C) 2000 by CyberSolutions GmbH, Germany. This file is part of Petidomo. Petidomo is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. Petidomo is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. */ #include #include #include "libtext/text.h" #include "petidomo.h" int AddAddress(struct Mail * MailStruct, const char * param1, const char * param2, const char * defaultlist) { const struct PD_Config * MasterConfig; const struct List_Config * ListConfig; FILE * fh; const char * address = NULL; const char * listname = NULL; char owner[4096]; char envelope[4096]; char * buffer; char * originator; char * p; /* Initialize internal stuff from master config file. */ MasterConfig = getMasterConfig(); sprintf(envelope, "petidomo-manager@%s", MasterConfig->fqdn); originator = (MailStruct->Reply_To) ? MailStruct->Reply_To : MailStruct->From; /* Try to find out, which parameter is what. */ if (param1 != NULL) { if (isValidListName(param1) == TRUE) listname = param1; else if (isRFC822Address(param1) == TRUE) address = param1; if (param2 != NULL) { if (listname == NULL && isValidListName(param2) == TRUE) listname = param2; else if (address == NULL && isRFC822Address(param2) == TRUE) address = param2; } } if (address == NULL) address = (MailStruct->Reply_To) ? MailStruct->Reply_To : MailStruct->From; assert(address != NULL); if (listname == NULL) { if (defaultlist != NULL) listname = defaultlist; else { syslog(LOG_INFO, "%s: subscribe-command invalid: No list specified.", MailStruct->From); fh = vOpenMailer(envelope, originator, NULL); if (fh != NULL) { fprintf(fh, "From: petidomo@%s (Petidomo Mailing List Server)\n", MasterConfig->fqdn); fprintf(fh, "To: %s\n", originator); fprintf(fh, "Subject: Petidomo: Your request \"subscribe %s\"\n", address); if (MailStruct->Message_Id != NULL) fprintf(fh, "In-Reply-To: %s\n", MailStruct->Message_Id); fprintf(fh, "Precedence: junk\n"); fprintf(fh, "Sender: %s\n", envelope); fprintf(fh, "\n"); buffer = text_easy_sprintf("You tried to subscribe the address \"%s\" to a mailing list. " \ "Unfortunately, your request could not be processed, because " \ "you did not specify a valid mailing list name to which the " \ "address should be subscribed to. You may use the command INDEX " \ "to receive an overview of the available mailing lists. Also, " \ "use the command HELP to verify that you got the command syntax " \ "right.", address); text_wordwrap(buffer, 70); fprintf(fh, "%s\n", buffer); CloseMailer(fh); } else syslog(LOG_ERR, "Failed to send email to \"%s\" concerning his request.", originator); return 0; } } /* Initialize internal stuff again from list config. */ ListConfig = getListConfig(listname); sprintf(owner, "%s-owner@%s", listname, ListConfig->fqdn); sprintf(envelope, "%s-owner@%s", listname, ListConfig->fqdn); /* Check whether the request is authorized at all. */ if (isValidAdminPassword(getPassword(), listname) == FALSE) { /* No valid password, check further. */ if (ListConfig->subtype == SUBSCRIPTION_ADMIN) { /* Access was unauthorized, notify the originator. */ syslog(LOG_INFO, "%s: Attempt to subscribe \"%s\" to list \"%s\" rejected due to lack of " \ "a correct admin password.", MailStruct->From, address, listname); fh = vOpenMailer(envelope, originator, NULL); if (fh != NULL) { fprintf(fh, "From: %s-request@%s (Petidomo Mailing List Server)\n", listname, ListConfig->fqdn); fprintf(fh, "To: %s\n", originator); fprintf(fh, "Subject: Petidomo: Your request \"subscribe %s %s\"\n", address, listname); if (MailStruct->Message_Id != NULL) fprintf(fh, "In-Reply-To: %s\n", MailStruct->Message_Id); fprintf(fh, "Precedence: junk\n"); fprintf(fh, "Sender: %s\n", envelope); fprintf(fh, "\n"); buffer = text_easy_sprintf( "The mailing list \"%s\" is a closed forum and only the maintainer may " \ "subscribe addresses. Your request has been forwarded to the " \ "appropriate person, so please don't send any further mail. You will " \ "be notified as soon as possible.", listname); text_wordwrap(buffer, 70); fprintf(fh, "%s\n", buffer); CloseMailer(fh); } else syslog(LOG_ERR, "Failed to send email to \"%s\" concerning his request.", originator); /* Notify the owner. */ fh = vOpenMailer(envelope, owner, NULL); if (fh != NULL) { fprintf(fh, "From: %s-request@%s (Petidomo Mailing List Server)\n", listname, ListConfig->fqdn); fprintf(fh, "To: %s\n", owner); fprintf(fh, "Subject: Petidomo: APPROVE %s@%s: Unauthorized request from \"%s\"\n", listname, ListConfig->fqdn, originator); fprintf(fh, "Precedence: junk\n"); fprintf(fh, "Sender: %s\n", envelope); fprintf(fh, "\n"); buffer = text_easy_sprintf( "\"%s\" tried to subscribe the address \"%s\" to the \"%s\" mailing list, " \ "but couldn't provide the correct password. To subscribe him, send the " \ "following commands to the server:", originator, address, listname); text_wordwrap(buffer, 70); fprintf(fh, "%s\n\n", buffer); fprintf(fh, "password \n"); fprintf(fh, "subscribe %s %s\n", address, listname); CloseMailer(fh); } else { syslog(LOG_ERR, "Failed to send email to \"%s\"!", owner); return -1; } return 0; } } /* Check whether the address is subscribed already. */ if (isSubscribed(listname, address, NULL, NULL, FALSE) == TRUE) { syslog(LOG_INFO, "%s: Attempt to subscribe \"%s\" to list \"%s\" rejected, because the " \ "address is already on the list.", MailStruct->From, address, listname); /* Notify the originator, that the address is already a member. */ fh = vOpenMailer(envelope, originator, NULL); if (fh != NULL) { fprintf(fh, "From: %s-request@%s (Petidomo Mailing List Server)\n", listname, ListConfig->fqdn); fprintf(fh, "To: %s\n", originator); fprintf(fh, "Subject: Petidomo: Your request \"subscribe %s %s\"\n", address, listname); if (MailStruct->Message_Id != NULL) fprintf(fh, "In-Reply-To: %s\n", MailStruct->Message_Id); fprintf(fh, "Precedence: junk\n"); fprintf(fh, "Sender: %s\n", envelope); fprintf(fh, "\n"); fprintf(fh, "The address \"%s\" is already subscribed to list \"%s\".\n", address, listname); CloseMailer(fh); } else { syslog(LOG_ERR, "Failed to send email to \"%s\" concerning his request.", originator); return -1; } return 0; } if (isValidAdminPassword(getPassword(), listname) == FALSE && ListConfig->subtype == SUBSCRIPTION_ACKED && !g_is_approved) { /* Require approval. */ char* command; char c; char* cookie; syslog(LOG_INFO, "%s: Attempt to subscribe \"%s\" to list \"%s\" deferred, because the " \ "request must be acknowledged first.", MailStruct->From, address, listname); command = text_easy_sprintf("subscribe %s %s", address, listname); cookie = queue_command(MailStruct, command); /* Send request for approval to the user. */ fh = vOpenMailer(envelope, address, NULL); if (fh != NULL) { fprintf(fh, "From: petidomo-approve@%s (Petidomo Mailing List Server)\n", ListConfig->fqdn); fprintf(fh, "To: %s\n", address); if (strcasecmp(address, originator) == 0) fprintf(fh, "Subject: Petidomo: APPROVE %s@%s: Your request \"subscribe %s\"\n", listname, ListConfig->fqdn, listname); else fprintf(fh, "Subject: Petidomo: APPROVE %s@%s: Request \"subscribe %s\" from \"%s\"\n", listname, ListConfig->fqdn, listname, originator); fprintf(fh, "Precedence: junk\n"); fprintf(fh, "Sender: %s\n", envelope); fprintf(fh, "\n"); if (strcasecmp(address, originator) == 0) buffer = text_easy_sprintf("You requested that the address \"%s\" should be subscribed to " \ "the mailing list \"%s\". This will not happen unless you approve the " \ "request by replying to this mail and concatenating the following two strings into one", address, listname); else buffer = text_easy_sprintf("Per request from \"%s\", the address \"%s\" should be subscribed to " \ "the mailing list \"%s\". This will not happen unless you approve the " \ "request by replying to this mail and concatenating the following two strings into one", originator, address, listname); text_wordwrap(buffer, 70); fprintf(fh, "%s\n", buffer); fprintf(fh, "\n"); c = cookie[16]; cookie[16] = '\0'; fprintf(fh, " %s\n", &cookie[ 0]); cookie[16] = c; fprintf(fh, " %s\n", &cookie[16]); fprintf(fh, "\n"); fprintf(fh, "in your reply.\n"); CloseMailer(fh); /* If the request for approval has been sent to an address different to that of the originator, notify him what happened. */ if (strcasecmp(address, originator) != 0) { fh = vOpenMailer(envelope, originator, NULL); if (fh != NULL) { fprintf(fh, "From: %s-request@%s (Petidomo Mailing List Server)\n", listname, ListConfig->fqdn); fprintf(fh, "To: %s\n", originator); fprintf(fh, "Subject: Petidomo: Your request \"subscribe %s %s\"\n", address, listname); if (MailStruct->Message_Id != NULL) fprintf(fh, "In-Reply-To: %s\n", MailStruct->Message_Id); fprintf(fh, "Precedence: junk\n"); fprintf(fh, "Sender: %s\n", envelope); fprintf(fh, "\n"); fprintf(fh, "Subscribing the address \"%s\" to the list \"%s\"\n", address, listname); fprintf(fh, "requires additional approval by \"%s\". A request\n", address); fprintf(fh, "has been sent to this address. We are now awaiting the approval.\n"); CloseMailer(fh); } else { syslog(LOG_ERR, "Failed to send email to \"%s\" concerning his request.", originator); return -1; } } } else { syslog(LOG_ERR, "Failed to send email to \"%s\"!", owner); return -1; } return 0; } /* Okay, add the address to the list. */ syslog(LOG_INFO, "%s: Okay; subscribing address \"%s\" to list \"%s\".", MailStruct->From, address, listname); fh = fopen(ListConfig->address_file, "a"); if (fh == NULL) { syslog(LOG_ERR, "Failed to open file \"%s\" for writing: %s", ListConfig->address_file, strerror(errno)); return -1; } fprintf(fh, "%s\n", address); fclose(fh); /* Send success notification to the originator and the new subscriber */ if (!strcasecmp(address, originator) == TRUE) fh = vOpenMailer(envelope, address, NULL); else fh = vOpenMailer(envelope, address, originator, NULL); if (fh != NULL) { fprintf(fh, "From: %s-request@%s (Petidomo Mailing List Server)\n", listname, ListConfig->fqdn); fprintf(fh, "To: %s\n", address); if (strcasecmp(address, originator) == TRUE) fprintf(fh, "Cc: %s\n", originator); fprintf(fh, "Subject: Petidomo: Request \"subscribe %s %s\"\n", address, listname); if (MailStruct->Message_Id != NULL) fprintf(fh, "In-Reply-To: %s\n", MailStruct->Message_Id); fprintf(fh, "Precedence: junk\n"); fprintf(fh, "Sender: %s\n", envelope); fprintf(fh, "\n"); if (!strcasecmp(address, originator) == TRUE) { buffer = text_easy_sprintf( "Per your request, the address \"%s\" has been subscribed to the " \ "\"%s\" mailing list. If you want to unsubscribe later, you can " \ "do so by sending the following command to \"%s-request@%s\":", address, listname, listname, ListConfig->fqdn); } else { buffer = text_easy_sprintf( "Per request from \"%s\", the address \"%s\" has been subscribed to the " \ "\"%s\" mailing list. If you want to unsubscribe later, you can " \ "do so by sending the following command to \"%s-request@%s\":", originator, address, listname, listname, ListConfig->fqdn); } text_wordwrap(buffer, 70); fprintf(fh, "%s\n\n", buffer); fprintf(fh, "unsubscribe %s\n\n", address); fprintf(fh, "Please save a copy of this mail, to make sure you remember how " \ "to\nunsubscribe!\n"); CloseMailer(fh); } else { syslog(LOG_ERR, "Failed to send email to \"%s\"!", address); return -1; } /* Send success notification to the list owner */ fh = vOpenMailer(envelope, owner, NULL); if (fh != NULL) { fprintf(fh, "From: %s-request@%s (Petidomo Mailing List Server)\n", listname, ListConfig->fqdn); fprintf(fh, "To: %s\n", owner); fprintf(fh, "Subject: Petidomo: SUBSCRIBE %s@%s: %s\n", listname, ListConfig->fqdn, address); if (MailStruct->Message_Id != NULL) fprintf(fh, "In-Reply-To: %s\n", MailStruct->Message_Id); fprintf(fh, "Precedence: junk\n"); fprintf(fh, "Sender: %s\n", envelope); fprintf(fh, "\n"); if (!strcasecmp(address, originator) == TRUE) { buffer = text_easy_sprintf( "Per request from the subscriber, the address \"%s\"\n" "has been subscribed to the \"%s\" mailing list.\n", address, listname, ListConfig->fqdn); } else { buffer = text_easy_sprintf( "Per request from \"%s\", the address \"%s\"\n" "has been subscribed to the \"%s\" mailing list.\n", originator, address, listname, ListConfig->fqdn); } text_wordwrap(buffer, 75); fprintf(fh, "%s\n", buffer); fprintf(fh, "No action is required on your part.\n"); CloseMailer(fh); } else { syslog(LOG_ERR, "Failed to send email to \"%s\"!", owner); return -1; } /* Send introduction text to the new member. */ p = loadfile(ListConfig->intro_file); if (p != NULL) { fh = vOpenMailer(envelope, address, NULL); if (fh != NULL) { fprintf(fh, "From: %s-request@%s (Petidomo Mailing List Server)\n", listname, ListConfig->fqdn); fprintf(fh, "To: %s\n", address); fprintf(fh, "Subject: Petidomo: Welcome to \"%s@%s\"!\n", listname, ListConfig->fqdn); if (MailStruct->Message_Id != NULL) fprintf(fh, "In-Reply-To: %s\n", MailStruct->Message_Id); fprintf(fh, "Precedence: junk\n"); fprintf(fh, "Sender: %s\n", envelope); fprintf(fh, "\n"); fprintf(fh, "%s\n", p); CloseMailer(fh); free(p); } else { free(p); syslog(LOG_ERR, "Failed to send introduction mail to \"%s\"!", address); return -1; } } return 0; }