head 1.12; access; symbols PETIDOMO_4_0b6:1.12 PETIDOMO_4_0b5:1.12 PETIDOMO_4_0b4:1.12 PETIDOMO_4_0b3:1.12 BEFORETHL:1.11 petidomo-2-2:1.1.1.1 petidomo:1.1.1; locks; strict; comment @ * @; 1.12 date 2004.02.02.19.50.25; author thl; state Exp; branches; next 1.11; 1.11 date 2001.01.20.13.42.01; author simons; state Exp; branches; next 1.10; 1.10 date 2001.01.19.16.08.51; author simons; state Exp; branches; next 1.9; 1.9 date 2001.01.19.14.56.33; author rse; state Exp; branches; next 1.8; 1.8 date 2001.01.18.20.30.50; author rse; state Exp; branches; next 1.7; 1.7 date 2001.01.16.10.49.08; author simons; state Exp; branches; next 1.6; 1.6 date 2001.01.10.17.07.19; author simons; state Exp; branches; next 1.5; 1.5 date 2001.01.08.20.49.52; author simons; state Exp; branches; next 1.4; 1.4 date 2001.01.08.20.36.19; author simons; state Exp; branches; next 1.3; 1.3 date 2000.12.15.15.48.00; author simons; state Exp; branches; next 1.2; 1.2 date 2000.12.13.15.35.14; author simons; state Exp; branches; next 1.1; 1.1 date 2000.12.13.13.19.22; author simons; state Exp; branches 1.1.1.1; next ; 1.1.1.1 date 2000.12.13.13.19.22; author simons; state Exp; branches; next ; desc @@ 1.12 log @both peti and rse did overlapping work based on (untagged) 4.0b1; peti committed to the CVS first (no version created ever); this is an attempt to manually merge rse's acl pre/post changes in (claim themselfs to lead to 4.0b2 @ text @/* $Source: /e/ossp/cvs/ossp-pkg/petidomo/acl.y,v $ $Revision: 1.11 $ 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. */ %{ /* Definitions we need in the parser. */ #include #include #include #include #include #include "libtext/text.h" #include "petidomo.h" static int yyerror(char *); static int yylex(void); static int domatch(int, int, char *); static int dofilter(const char *); unsigned int lineno; int operation, g_rc; char * g_parameter = NULL; struct Mail * g_MailStruct; #include "acl-scan.c" #define YYERROR_VERBOSE %} %token TOK_IF TOK_EQUAL TOK_EQUAL TOK_FROM TOK_SUBJECT %token TOK_ENVELOPE TOK_HEADER TOK_BODY TOK_AND TOK_OR TOK_NOT %token TOK_THEN TOK_MATCH TOK_STRING TOK_DROP TOK_PASS TOK_APPROVE %token TOK_REDIRECT TOK_FORWARD TOK_REJECT TOK_REJECTWITH %token TOK_FILTER %left TOK_AND %left TOK_OR %right TOK_NOT %% input: /* empty */ | input statmt ; statmt: ';' | TOK_IF exp TOK_THEN action ';' { if ($2 == TRUE) { operation = $4; YYACCEPT; } } ; exp: qualifier TOK_EQUAL TOK_STRING { g_rc = domatch($1, TOK_EQUAL, yytext); if (g_rc == -1) YYABORT; $$ = g_rc; } | qualifier TOK_MATCH TOK_STRING { g_rc = domatch($1, TOK_MATCH, yytext); if (g_rc == -1) YYABORT; $$ = g_rc; } | TOK_STRING { g_rc = dofilter(yytext); if (g_rc == -1) YYABORT; $$ = g_rc; } | exp TOK_OR exp { $$ = $1 || $3; } | exp TOK_AND exp { $$ = $1 && $3; } | TOK_NOT exp { $$ = ! $2; } | '(' exp ')' { $$ = $2; } ; qualifier: TOK_FROM { $$ = TOK_FROM; } | TOK_SUBJECT { $$ = TOK_SUBJECT; } | TOK_ENVELOPE { $$ = TOK_ENVELOPE; } | TOK_HEADER { $$ = TOK_HEADER; } | TOK_BODY { $$ = TOK_BODY; } ; action: TOK_PASS { $$ = ACL_PASS; } | TOK_APPROVE { $$ = ACL_APPROVE; } | TOK_DROP { $$ = ACL_DROP; } | TOK_REJECT { $$ = ACL_REJECT; } | TOK_REJECTWITH TOK_STRING { $$ = ACL_REJECTWITH; if (g_parameter != NULL) free(g_parameter); g_parameter = strdup(yytext); if (g_parameter == NULL) YYABORT; } | TOK_REDIRECT TOK_STRING { $$ = ACL_REDIRECT; if (g_parameter != NULL) free(g_parameter); g_parameter = strdup(yytext); if (g_parameter == NULL) YYABORT; } | TOK_FORWARD TOK_STRING { $$ = ACL_FORWARD; if (g_parameter != NULL) free(g_parameter); g_parameter = strdup(yytext); if (g_parameter == NULL) YYABORT; } | TOK_FILTER TOK_STRING { $$ = ACL_FILTER; if (g_parameter != NULL) free(g_parameter); g_parameter = strdup(yytext); if (g_parameter == NULL) YYABORT; } ; %% /***** internal routines *****/ int yywrap(void) { return 1; } static int yyerror(char * string) { syslog(LOG_ERR, "Syntax error in line %u: %s\n", lineno, string); return 0; } static int dofilter(const char * filter) { FILE * fh; int rc; fh = popen(filter, "w"); if (fh == NULL) { syslog(LOG_ERR, "Failed to open ACL-filter \"%s\": %s", filter, strerror(errno)); return -1; } fprintf(fh, "%s\n", g_MailStruct->Header); fprintf(fh, "%s", g_MailStruct->Body); rc = pclose(fh); if (!WIFEXITED(rc)) return -1; rc = WEXITSTATUS(rc); switch(rc) { case 0: return TRUE; case 1: return FALSE; default: syslog(LOG_ERR, "ACL-filter \"%s\" returned unexpected value %d.", filter, rc); return -1; } } static int domatch(int qualifier, int oper, char * string) { char * left; switch(qualifier) { case TOK_FROM: left = g_MailStruct->From; break; case TOK_SUBJECT: left = g_MailStruct->Subject; break; case TOK_ENVELOPE: left = g_MailStruct->Envelope; break; case TOK_HEADER: left = g_MailStruct->Header; break; case TOK_BODY: left = g_MailStruct->Body; break; default: syslog(LOG_CRIT, "Internal error in the ACL parser. Unknown qualifier %d.", qualifier); return -1; } switch(oper) { case TOK_EQUAL: if (left != NULL && strcasecmp(left, string) == 0) { return TRUE; } else { return FALSE; } case TOK_MATCH: if (left != NULL && text_easy_pattern_match(left, string) == TRUE) { return TRUE; } else { return FALSE; } default: syslog(LOG_CRIT, "Internal error in the ACL parser. Unknown operator %d.", oper); return -1; } } /****** public routines ******/ int checkACL(struct Mail * MailStruct, const char * listname, int * operation_ptr, char ** parameter_ptr, acl_type_t type) { const struct PD_Config * MasterConfig; const struct List_Config * ListConfig; int rc; assert(MailStruct != NULL); assert(operation_ptr != NULL); assert(parameter_ptr != NULL); MasterConfig = getMasterConfig(); g_MailStruct = MailStruct; g_parameter = NULL; /* Set up the lex scanner. */ BEGIN(INITIAL); lineno = 1; operation = ACL_NONE; /* First check the mail against the master acl file. */ 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.", (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", (type == ACL_PRE ? MasterConfig->acl_file_pre : MasterConfig->acl_file_post), strerror(errno)); return -1; } } /* Parse the acl file. */ rc = yyparse(); if (yyin != NULL) { fclose(yyin); yyin = NULL; } if (rc != 0) { syslog(LOG_ERR, "Parsing \"%s\" file returned with an error.", (type == ACL_PRE ? MasterConfig->acl_file_pre : MasterConfig->acl_file_post)); return -1; } /* If we had a hit, return now. */ if (operation != ACL_NONE) goto finished; check_local_acl_file: /* Do we have a local acl file to test? */ if (listname == NULL) goto finished; /* Set up the lex scanner. */ BEGIN(INITIAL); lineno = 1; operation = ACL_NONE; ListConfig = getListConfig(listname); 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", (type == ACL_PRE ? ListConfig->acl_file_pre : ListConfig->acl_file_post), strerror(errno)); return -1; } } rc = yyparse(); fclose(yyin); yyin = NULL; if (rc != 0) { syslog(LOG_ERR, "Parsing \"%s\" file returned with an error.", (type == ACL_PRE ? ListConfig->acl_file_pre : ListConfig->acl_file_post)); return -1; } /* Return to the caller. */ finished: *operation_ptr = operation; *parameter_ptr = g_parameter; return 0; } @ 1.11 log @Underscores in file names suck, because you need an extra key-press to type them compared to the hyphen. For this reason (and for consistency) I corrected this horrible, horrible mistake of the past and renamed those files. @ text @d3 1 a3 1 $Revision: 1.10 $ d238 2 a239 1 char ** parameter_ptr) d260 1 a260 1 yyin = fopen(MasterConfig->acl_file, "r"); d265 2 a266 1 syslog(LOG_WARNING, "You have no global acl file (%s). This is probably not a good idea.", MasterConfig->acl_file); d269 2 a270 1 syslog(LOG_ERR, "Couldn't open \"%s\" acl file: %s", MasterConfig->acl_file, strerror(errno)); d283 2 a284 1 syslog(LOG_ERR, "Parsing \"%s\" file returned with an error.", MasterConfig->acl_file); d308 1 a308 1 yyin = fopen(ListConfig->acl_file, "r"); d315 3 a317 1 syslog(LOG_ERR, "Couldn't open acl file \"%s\": %s", ListConfig->acl_file, strerror(errno)); d326 2 a327 1 syslog(LOG_ERR, "Parsing \"%s\" file returned with an error.", ListConfig->acl_file); @ 1.10 log @- Added a warning message to be logged when no global ACL file exists. - Reordered tests in check_local_acl_file: When no listname has been given, we don't need to initialize the lexer at all. @ text @d3 1 a3 1 $Revision: 1.9 $ d42 1 a42 1 #include "acl_scan.c" @ 1.9 log @Get rid of all complaints from GCC 2.97 (except for two things which I do not want to change on my own) @ text @d3 1 a3 1 $Revision: 1.8 $ d264 1 d293 5 a301 5 /* Do we have a local acl file to test? */ if (listname == NULL) goto finished; @ 1.8 log @As we agreed today, Petidomo is now open because licensed under GPL and always will be licensed under GPL, so use "Petidomo" as the program name everywhere and consistently. @ text @d3 1 a3 1 $Revision: 1.7 $ d161 1 a161 1 syslog(LOG_ERR, "Failed to open ACL-filter \"%s\": %m", filter); d266 1 a266 1 syslog(LOG_ERR, "Couldn't open \"%s\" acl file.: %m", MasterConfig->acl_file); d310 1 a310 1 syslog(LOG_ERR, "Couldn't open acl file \"%s\": %m", ListConfig->acl_file); d319 1 a319 1 syslog(LOG_ERR, "Parsing \"~petidomo/etc/acl\" file returned with an error."); @ 1.7 log @Added new action keyword to the Access Control Language: approve. This keyword will -- unlike to "pass" -- not only pass the mail, but will also make sure that the mail passes all other authorization controls. This means, the mail will be treated as if the Petidomo master password had been given in the header. @ text @d2 2 a3 2 $Source: /d1/e/petidomo/cvs/petidomo/source/acl.y,v $ $Revision: 1.6 $ d7 1 a7 1 This file is part of OpenPetidomo. d9 1 a9 1 OpenPetidomo is free software; you can redistribute it and/or modify d14 1 a14 1 OpenPetidomo is distributed in the hope that it will be useful, but @ 1.6 log @When running in listserv mode, there is no 'listname' which can be used to get the mailing list's configuration. Thus, the routine shouldn't try to got one. Fixed it. @ text @d3 1 a3 1 $Revision: 1.5 $ d48 1 a48 1 %token TOK_THEN TOK_MATCH TOK_STRING TOK_DROP TOK_PASS d100 1 @ 1.5 log @Changed the ACL code to use the configured locations of the list's ACL file rather than the hard-coded one. @ text @d3 1 a3 1 $Revision: 1.4 $ a247 1 ListConfig = getListConfig(listname); d301 1 @ 1.4 log @Rewrote Petidomo so that virtually any file's path can be configured at run-time now. @ text @d3 1 a3 1 $Revision: 1.3 $ d240 1 a240 1 char * filename; d248 1 d302 1 a302 2 filename = text_easy_sprintf("lists/%s/acl", listname); yyin = fopen(filename, "r"); d309 1 a309 1 syslog(LOG_ERR, "Couldn't open \"~petidomo/%s\" file: %m", filename); @ 1.3 log @ - Removed all debugging code. Now that Petidomo will be "rewritten" in C++, I need a new paradigm for debugging anyway and the old solution of mine was to messy for my taste anyway. - Petidomo no longer cares under what name it has been started. The different modes of operation will now be distinguished by a mandatory command line parameter. @ text @d3 1 a3 1 $Revision: 1.2 $ d239 1 d247 1 d258 1 a258 1 yyin = fopen("etc/acl", "r"); d265 1 a265 1 syslog(LOG_ERR, "Couldn't open \"~petidomo/etc/acl\" acl file.: %m"); d278 1 a278 1 syslog(LOG_ERR, "Parsing \"~petidomo/etc/acl\" file returned with an error."); @ 1.2 log @ - Added correct GNU GPL copyright statements to the files. - Removed unnecessary include statements. @ text @d2 2 a3 2 $Source$ $Revision$ a157 1 debug((DEBUG_ACL, 2, "Starting ACL-filter \"%s\".", filter)); a172 1 debug((DEBUG_ACL, 2, "Filter returned %d (TRUE).", rc)); a174 1 debug((DEBUG_ACL, 2, "Filter returned %d (FALSE).", rc)); a212 1 debug((DEBUG_ACL, 1, "ACL: \"%s\" == \"%s\" == TRUE", left, string)); a215 1 debug((DEBUG_ACL, 1, "ACL: \"%s\" == \"%s\" == FALSE", left, string)); a219 1 debug((DEBUG_ACL, 1, "ACL: \"%s\" match \"%s\" == TRUE", left, string)); a222 1 debug((DEBUG_ACL, 1, "ACL: \"%s\" match \"%s\" == FALSE", left, string)); a255 1 debug((DEBUG_ACL, 2, "Testing mail against \"~petidomo/etc/acl\".")); a260 1 debug((DEBUG_ACL, 1, "No master acl file found.")); a299 1 debug((DEBUG_ACL, 2, "Testing mail against \"~petidomo/%s\".", filename)); a304 1 debug((DEBUG_ACL, 1, "No acl file for list \"%s\".", listname)); @ 1.1 log @Initial revision @ text @d2 17 a18 7 * $Source: /usr/local/libdata/cvs/simons/petidomo/src/petidomo/acl.y,v $ * $Revision: 1.8 $ * $Date: 1997/12/22 16:13:10 $ * * Copyright (C) 1997 by CyberSolutions GmbH. * All rights reserved. */ d29 2 a30 2 #include #include @ 1.1.1.1 log @Imported Petidomo 2.2 as found on www.petidomo.com. @ text @@