diff --git a/acl.y b/acl.y index af800ea..3aa5b32 100644 --- a/acl.y +++ b/acl.y @@ -235,7 +235,8 @@ domatch(int qualifier, int oper, char * string) int checkACL(struct Mail * MailStruct, const char * listname, int * operation_ptr, - char ** parameter_ptr) + char ** parameter_ptr, + acl_type_t type) { const struct PD_Config * MasterConfig; const struct List_Config * ListConfig; @@ -256,15 +257,17 @@ int checkACL(struct Mail * MailStruct, /* First check the mail against the master acl file. */ - yyin = fopen(MasterConfig->acl_file, "r"); + yyin = fopen((type == ACL_PRE ? MasterConfig->acl_file_pre : MasterConfig->acl_file_post), "r"); if (yyin == NULL) { switch(errno) { case ENOENT: /* no master acl file */ - syslog(LOG_WARNING, "You have no global acl file (%s). This is probably not a good idea.", MasterConfig->acl_file); + syslog(LOG_WARNING, "You have no global acl file (%s). This is probably not a good idea.", + (type == ACL_PRE ? MasterConfig->acl_file_pre : MasterConfig->acl_file_post)); goto check_local_acl_file; default: - syslog(LOG_ERR, "Couldn't open \"%s\" acl file: %s", MasterConfig->acl_file, strerror(errno)); + syslog(LOG_ERR, "Couldn't open \"%s\" acl file: %s", + (type == ACL_PRE ? MasterConfig->acl_file_pre : MasterConfig->acl_file_post), strerror(errno)); return -1; } } @@ -277,7 +280,8 @@ int checkACL(struct Mail * MailStruct, yyin = NULL; } if (rc != 0) { - syslog(LOG_ERR, "Parsing \"%s\" file returned with an error.", MasterConfig->acl_file); + syslog(LOG_ERR, "Parsing \"%s\" file returned with an error.", + (type == ACL_PRE ? MasterConfig->acl_file_pre : MasterConfig->acl_file_post)); return -1; } @@ -301,14 +305,16 @@ check_local_acl_file: lineno = 1; operation = ACL_NONE; ListConfig = getListConfig(listname); - yyin = fopen(ListConfig->acl_file, "r"); + yyin = fopen((type == ACL_PRE ? ListConfig->acl_file_pre : ListConfig->acl_file_post), "r"); if (yyin == NULL) { switch(errno) { case ENOENT: /* no list acl file */ goto finished; default: - syslog(LOG_ERR, "Couldn't open acl file \"%s\": %s", ListConfig->acl_file, strerror(errno)); + syslog(LOG_ERR, "Couldn't open acl file \"%s\": %s", + (type == ACL_PRE ? ListConfig->acl_file_pre : ListConfig->acl_file_post), + strerror(errno)); return -1; } } @@ -317,7 +323,8 @@ check_local_acl_file: fclose(yyin); yyin = NULL; if (rc != 0) { - syslog(LOG_ERR, "Parsing \"%s\" file returned with an error.", ListConfig->acl_file); + syslog(LOG_ERR, "Parsing \"%s\" file returned with an error.", + (type == ACL_PRE ? ListConfig->acl_file_pre : ListConfig->acl_file_post)); return -1; } diff --git a/config-files.c b/config-files.c index 66b2747..41462c0 100644 --- a/config-files.c +++ b/config-files.c @@ -38,7 +38,8 @@ static char* master_password = NULL; static char* mta = NULL; static char* mta_options = "-i -f%s"; static char* help_file = DATADIR "/help"; -static char* acl_file = SYSCONFDIR "/petidomo.acl"; +static char* acl_file_pre = SYSCONFDIR "/petidomo.acl-pre"; +static char* acl_file_post = SYSCONFDIR "/petidomo.acl-post"; static char* index_file = LOCALSTATEDIR "/index"; static char* list_dir = LOCALSTATEDIR "/lists"; static char* ack_queue_dir = LOCALSTATEDIR "/ack-queue"; @@ -56,7 +57,8 @@ int InitPetidomo(const char* masterconfig) { "MTA", CF_STRING, &mta }, { "MTAOptions", CF_STRING, &mta_options }, { "HelpFile", CF_STRING, &help_file }, - { "AclFile", CF_STRING, &acl_file }, + { "AclFilePre", CF_STRING, &acl_file_pre }, + { "AclFilePost", CF_STRING, &acl_file_post }, { "IndexFile", CF_STRING, &index_file }, { "ListDirectory", CF_STRING, &list_dir }, { "AckQueueDirectory", CF_STRING, &ack_queue_dir }, @@ -115,7 +117,8 @@ int InitPetidomo(const char* masterconfig) MasterConfig->mta = mta; MasterConfig->mta_options = mta_options; MasterConfig->help_file = help_file; - MasterConfig->acl_file = acl_file; + MasterConfig->acl_file_pre = acl_file_pre; + MasterConfig->acl_file_post = acl_file_post; MasterConfig->index_file = index_file; MasterConfig->list_dir = list_dir; MasterConfig->ack_queue_dir = ack_queue_dir; @@ -142,7 +145,8 @@ static char* intro_file; static char* sig_file; static char* desc_file; static char* header_file; -static char* list_acl_file; +static char* list_acl_file_pre; +static char* list_acl_file_post; static char* address_file; static char* ack_file; @@ -172,7 +176,8 @@ const struct List_Config* getListConfig(const char * listname) { "SignatureFile", CF_STRING, &sig_file }, { "DescriptionFile", CF_STRING, &desc_file }, { "HeaderFile", CF_STRING, &header_file }, - { "ACLFile", CF_STRING, &list_acl_file }, + { "ACLFilePre", CF_STRING, &list_acl_file_pre }, + { "ACLFilePost", CF_STRING, &list_acl_file_post }, { "AddressFile", CF_STRING, &address_file }, { "AcknowledgementFile", CF_STRING, &ack_file }, { NULL, 0, NULL} @@ -193,7 +198,8 @@ const struct List_Config* getListConfig(const char * listname) sig_file = "signature"; desc_file = "description"; header_file = "header"; - list_acl_file = "acl"; + list_acl_file_pre = "acl-pre"; + list_acl_file_post = "acl-post"; address_file = "list"; ack_file = "acks"; @@ -301,7 +307,8 @@ const struct List_Config* getListConfig(const char * listname) EXPAND(desc_file, desc_file); EXPAND(sig_file, sig_file); EXPAND(header_file, header_file); - EXPAND(acl_file, list_acl_file); + EXPAND(acl_file_pre, list_acl_file_pre); + EXPAND(acl_file_post, list_acl_file_post); EXPAND(address_file, address_file); EXPAND(ack_file, ack_file); diff --git a/hermes.c b/hermes.c index 15da928..4f944d4 100644 --- a/hermes.c +++ b/hermes.c @@ -101,7 +101,7 @@ void hermes_main(char * incoming_mail, const char * listname) processing is over. That's why we check the posting password again below. */ - if (checkACL(MailStruct, listname, &operation, ¶meter) != 0) + if (checkACL(MailStruct, listname, &operation, ¶meter, ACL_PRE) != 0) { syslog(LOG_ERR, "checkACL() failed with an error."); exit(1); @@ -286,6 +286,27 @@ void hermes_main(char * incoming_mail, const char * listname) } } + /* additional ACL check */ + if (isValidPostingPassword(MailStruct->Approve, listname) == FALSE) + { + if (checkACL(MailStruct, listname, &operation, ¶meter, ACL_POST) != 0) + { + syslog(LOG_ERR, "checkACL() failed with an error."); + exit(1); + } + rc = handleACL(MailStruct, listname, operation, parameter); + switch(rc) + { + case -1: + syslog(LOG_ERR, "handleACL() failed with an error."); + exit(1); + case 0: + break; + case 1: + return; + } + } + /* Copy the desired headers from the original mail to our own buffer. */ diff --git a/listserv.c b/listserv.c index a2a3eaa..c6cc102 100644 --- a/listserv.c +++ b/listserv.c @@ -64,7 +64,21 @@ void listserv_main(char * incoming_mail, char * default_list) /* Do access control. */ - if (checkACL(MailStruct, NULL, &operator, ¶meter) != 0) { + if (checkACL(MailStruct, NULL, &operator, ¶meter, ACL_PRE) != 0) { + syslog(LOG_ERR, "checkACL() failed with an error."); + exit(1); + } + rc = handleACL(MailStruct, NULL, operator, parameter); + switch(rc) { + case -1: + syslog(LOG_ERR, "handleACL() failed with an error."); + exit(1); + case 0: + break; + case 1: + return; + } + if (checkACL(MailStruct, NULL, &operator, ¶meter, ACL_POST) != 0) { syslog(LOG_ERR, "checkACL() failed with an error."); exit(1); } diff --git a/petidomo.h b/petidomo.h index bee5543..373266c 100644 --- a/petidomo.h +++ b/petidomo.h @@ -64,7 +64,8 @@ struct PD_Config char * list_dir; char * ack_queue_dir; char * help_file; - char * acl_file; + char * acl_file_pre; + char * acl_file_post; char * index_file; }; @@ -77,6 +78,12 @@ enum list_type_t LIST_ACKED_ONCE }; +typedef enum + { + ACL_PRE, + ACL_POST + } acl_type_t; + enum subscription_type_t { SUBSCRIPTION_PUBLIC, @@ -99,7 +106,8 @@ struct List_Config char * desc_file; char * sig_file; char * header_file; - char * acl_file; + char * acl_file_pre; + char * acl_file_post; char * list_dir; char * address_file; char * ack_file; @@ -156,7 +164,7 @@ int MailFilter(struct Mail *MailStruct, const char *filter); /********** acl.c **********/ -int checkACL(struct Mail *, const char *, int *, char **); +int checkACL(struct Mail *, const char *, int *, char **, acl_type_t); enum { ACL_DROP, diff --git a/version.c b/version.c index 26a531b..80c7445 100644 --- a/version.c +++ b/version.c @@ -8,7 +8,7 @@ #ifndef _VERSION_C_ #define _VERSION_C_ -#define PETIDOMO_VERSION 0x400101 +#define PETIDOMO_VERSION 0x400102 typedef struct { const int v_hex; @@ -32,13 +32,13 @@ extern petidomo_version_t petidomo_version; #undef _VERSION_C_AS_HEADER_ petidomo_version_t petidomo_version = { - 0x400101, - "4.0b1", - "4.0b1 (18-Jan-2001)", - "This is Petidomo, Version 4.0b1 (18-Jan-2001)", - "Petidomo 4.0b1 (18-Jan-2001)", - "Petidomo/4.0b1", - "@(#)Petidomo 4.0b1 (18-Jan-2001)", + 0x400102, + "4.0b2", + "4.0b2 (24-Apr-2002)", + "This is Petidomo, Version 4.0b2 (24-Apr-2002)", + "Petidomo 4.0b2 (24-Apr-2002)", + "Petidomo/4.0b2", + "@(#)Petidomo 4.0b2 (24-Apr-2002)", "$Id$" };