/* run_email2trac.c Authors: Bas van der Vlies, Walter de Jong and Michel Jouvin SVN Info: $Id: run_email2trac.c 654 2014-04-24 20:01:07Z bas $ Only nobody can become the user www-data. Postfix uses this user to start an program Copyright 2002 SURFsara Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #include "config.h" #include #include #include #include #include #include #include #include #include #ifdef HAVE_INITGROUPS #include #endif #include "run_email2trac.h" #ifndef DEBUG #define DEBUG 0 #endif void check_username(char *name) { if ( strlen(name) > 30 ) { openlog("run_email2trac", LOG_PID, LOG_MAIL); syslog(LOG_ERR, "MTA_USERNAME is to large; %s\n", name); closelog(); exit(-1); } } void email2trac_log(char *message) { openlog("run_email2trac", LOG_PID, LOG_MAIL); syslog(LOG_ERR, "%s", message); closelog(); } int main(int argc, char** argv) { int i,j; int caller = getuid(); int status; char **trac_script_args; char *python_egg_cache = NULL; struct passwd *TRAC; struct passwd *MTA; struct stat script_attrs; const char *trac_script = TRAC_SCRIPT_PATH "/" TRAC_SCRIPT_NAME; char error_msg[1024]; /* printf("trac_script = %s\n", trac_script); */ /* First copy arguments passed to the wrapper as scripts arguments aft er filtering out some of the possible script options */ trac_script_args = (char**) malloc((argc+1)*sizeof(char*)); if (trac_script_args == NULL) { snprintf(error_msg, sizeof(error_msg), "malloc failed"); email2trac_log(error_msg); return 1; } trac_script_args[0] = TRAC_SCRIPT_NAME; for (i=j=1; ipw_uid ) { snprintf(error_msg, sizeof(error_msg), "Invalid caller UID (%d)", caller); email2trac_log(error_msg); return -2; /* 254 : Invalid caller */ } /* set UID/GID and supplementary groups to be Trac (or apache) user */ check_username(TRAC_USER); if ( TRAC = getpwnam(TRAC_USER) ) { #ifdef HAVE_INITGROUPS if (initgroups(TRAC_USER, TRAC->pw_gid)) { snprintf(error_msg, sizeof(error_msg), "initgroups failed"); email2trac_log(error_msg); return -7; /* 249 : Can't set supplementary groups */ } #endif if (setgid(TRAC->pw_gid) || setuid(TRAC->pw_uid)) { snprintf(error_msg, sizeof(error_msg), "setgid or setuid failed"); email2trac_log(error_msg); return -5; /* 251: Can't set gid or uid */ } } else { snprintf(error_msg, sizeof(error_msg), "Invalid Trac user (%s)", TRAC_USER); email2trac_log(error_msg); return -6; /* 250 : Trac user not found */ } /* Check that script exists */ if ( stat(trac_script,&script_attrs) ) { snprintf(error_msg, sizeof(error_msg), "Script not found (%s)", trac_script); email2trac_log(error_msg); return -4; /* 252 : script not found */ } /* Set PYTHON_EGG_CACHE env variable if we have been told to do so */ if ( python_egg_cache != NULL ) { setenv("PYTHON_EGG_CACHE",python_egg_cache ,1); } /* Execute script */ status = execv(trac_script, trac_script_args); /* should never reach this point */ snprintf(error_msg, sizeof(error_msg), "Script %s execution failure (error=%d). Check permission and interpreter path.", trac_script, status); email2trac_log(error_msg); return -1; } /* EOB */