source: trunk/run_email2trac.c @ 586

Last change on this file since 586 was 574, checked in by bas, 12 years ago

added support for initgroup, thanks to Dennis McRitchie?,
closes #274

  • Property svn:keywords set to Id
File size: 4.0 KB
Line 
1/*
2        run_email2trac.c
3        Authors: Bas van der Vlies, Walter de Jong and Michel Jouvin
4        SVN Info:
5                $Id: run_email2trac.c 574 2011-10-20 07:20:17Z bas $
6
7        Only nobody can become the user www-data. Postfix uses this
8        user to start an program
9
10# Copyright (C) 2002
11#
12# This file is part of the email2trac utils
13#
14# This program is free software; you can redistribute it and/or modify it
15# under the terms of the GNU General Public License as published by the
16# Free Software Foundation; either version 2, or (at your option) any
17# later version.
18#
19# This program is distributed in the hope that it will be useful,
20# but WITHOUT ANY WARRANTY; without even the implied warranty of
21# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22# GNU General Public License for more details.
23#
24# You should have received a copy of the GNU General Public License
25# along with this program; if not, write to the Free Software
26# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA
27#
28*/
29#include "config.h"
30
31#include <sys/types.h>
32#include <stdlib.h>
33#include <unistd.h>
34#include <pwd.h>
35#include <sys/stat.h>
36#include <string.h>
37#include <stdio.h>
38#include <limits.h>
39#ifdef HAVE_INITGROUPS
40#include <grp.h>
41#endif
42
43#include "run_email2trac.h"
44
45#ifndef DEBUG
46#define DEBUG 0
47#endif
48
49void check_username(char *name)
50{
51  if ( strlen(name) > 30 ) {
52          if ( DEBUG ) printf("MTA_USERNAME is to large; %s\n", name);
53          exit(-1);
54  }
55}
56
57int main(int argc, char** argv) {
58
59  int i,j;
60  int caller = getuid();
61  int status;
62
63  char   **trac_script_args;
64  char   *python_egg_cache = NULL;
65  struct passwd *TRAC; 
66  struct passwd *MTA;
67  struct stat script_attrs;
68  const char *trac_script = TRAC_SCRIPT_PATH "/" TRAC_SCRIPT_NAME;
69 
70  /*
71  printf("trac_script = %s\n", trac_script);
72  */
73
74  /* First copy arguments passed to the wrapper as scripts arguments
75     after filtering out some of the possible script options */
76
77  trac_script_args = (char**) malloc((argc+1)*sizeof(char*));
78  if (trac_script_args == NULL) {
79    if ( DEBUG ) printf("malloc failed\n");
80    return 1;
81  }
82  trac_script_args[0] = TRAC_SCRIPT_NAME;
83  for (i=j=1; i<argc; i++) {
84    if ( (strcmp(argv[i],"--file") == 0) || 
85         (strcmp(argv[i],"-f") == 0) ) {
86      i++;
87      continue;
88    }
89    else if ( (strcmp(argv[i],"--eggcache") == 0) ||
90         (strcmp(argv[i],"-e") == 0) ) {
91      i++;
92      python_egg_cache = argv[i];
93      continue;
94    }
95   
96    trac_script_args[j] = argv[i];
97    j++;
98  }
99  trac_script_args[j] = NULL;
100
101  /* Check caller */
102  check_username(MTA_USER);
103  MTA = getpwnam(MTA_USER);
104
105  if ( MTA == NULL ) {
106    if ( DEBUG ) printf("Invalid MTA user (%s)\n", MTA_USER);
107    return -3;     /* 253 : MTA user not found */
108  }
109
110  if ( caller !=  MTA->pw_uid ) {
111    if ( DEBUG ) printf("Invalid caller UID (%d)\n",caller);
112    return -2;     /* 254 : Invalid caller */
113  }
114 
115  /* set UID/GID and supplementary groups to be Trac (or apache) user */
116  check_username(TRAC_USER);
117  if ( TRAC = getpwnam(TRAC_USER) ) {
118#ifdef HAVE_INITGROUPS
119    if (initgroups(TRAC_USER, TRAC->pw_gid)) {
120      if ( DEBUG ) printf("initgroups failed\n");
121      return -7;    /* 249 : Can't set supplementary groups */
122    }
123#endif
124    if (setgid(TRAC->pw_gid) || setuid(TRAC->pw_uid)) {
125      if ( DEBUG ) printf("setgid or setuid failed\n");
126      return -5;   /* 251: Can't set gid or uid */
127    }
128  } else {
129    if ( DEBUG ) printf("Invalid Trac user (%s)\n",TRAC_USER);
130    return -6;     /* 250 : Trac user not found */
131  }
132         
133  /* Check that script exists */
134  if ( stat(trac_script,&script_attrs) ) {
135    if ( DEBUG ) printf("Script not found (%s)\n",trac_script);
136    return -4;    /* 252 : script not found */
137  }
138 
139  /* Set PYTHON_EGG_CACHE env variable if we have been told to do so */
140  if ( python_egg_cache != NULL ) {
141    setenv("PYTHON_EGG_CACHE",python_egg_cache ,1);
142  }
143
144  /* Execute script */
145  status = execv(trac_script, trac_script_args);
146 
147  if ( DEBUG ) printf("Script %s execution failure (error=%d). Check permission and interpreter path.\n",trac_script,status);
148  return -1;     /* 255 : should never reach this point */
149
150}
151
152/* EOB */
Note: See TracBrowser for help on using the repository browser.