diff -ruN apache_1.3.27-orig/src/support/suexec.c apache_1.3.27/src/support/suexec.c --- apache_1.3.27-orig/src/support/suexec.c 2002-03-13 16:05:37.000000000 -0500 +++ apache_1.3.27/src/support/suexec.c 2003-02-02 14:10:27.000000000 -0500 @@ -88,9 +88,8 @@ #include #include #include - #include - +#include #include "suexec.h" /* @@ -124,6 +123,8 @@ extern char **environ; static FILE *log = NULL; +char *newargv[2]; + char *safe_env_lst[] = { "AUTH_TYPE", @@ -249,9 +250,40 @@ environ = cleanenv; } +int phpcheck(char *prog) +{ + char *ext; + // Default argv for normal cgi + newargv[0]=prog; + newargv[1]=NULL; + + if ((ext = strrchr(prog,'.')) == NULL) + { + return -1; + } + else if (!strncmp(ext, ".php", 4) || !strncmp(ext, ".php4", 5) || !strncmp(ext, ".phtml",6)) + { + newargv[0]=PHP4; + newargv[1]=prog; + } + else if (!strncmp(ext, ".php3",5)) + { + newargv[0]=PHP3; + newargv[1]=prog; + } +// no else needed, as default options take care of this +/* { + newargv[0]=prog; + newargv[1]=NULL; + } +*/ + return 1; +} + int main(int argc, char *argv[]) { int userdir = 0; /* ~userdir flag */ + int phpver; /* version of php used */ uid_t uid; /* user information */ gid_t gid; /* target group placeholder */ char *target_uname; /* target user name */ @@ -563,19 +595,32 @@ (gid != dir_info.st_gid) || (uid != prg_info.st_uid) || (gid != prg_info.st_gid)) { +#ifdef TRUSTED_USERS_SCRIPTS + if ((atoi(SUEXEC_TRUSTED_USER) != prg_info.st_uid) || + (atoi(SUEXEC_TRUSTED_GROUP) != prg_info.st_gid)) { + log_err("error: target uid/gid (%ld/%ld) mismatch " + "with directory (%ld/%ld) or program (%ld/%ld)\n", + uid, gid, + dir_info.st_uid, dir_info.st_gid, + prg_info.st_uid, prg_info.st_gid); + exit(120); + } +#else log_err("error: target uid/gid (%ld/%ld) mismatch " "with directory (%ld/%ld) or program (%ld/%ld)\n", uid, gid, dir_info.st_uid, dir_info.st_gid, prg_info.st_uid, prg_info.st_gid); exit(120); +#endif } /* * Error out if the program is not executable for the user. * Otherwise, she won't find any error in the logs except for * "[error] Premature end of script headers: ..." */ - if (!(prg_info.st_mode & S_IXUSR)) { + phpver=phpcheck(argv[3]); + if ((phpver == -1) && !(prg_info.st_mode & S_IXUSR)) { log_err("error: file has no execute permission: (%s/%s)\n", cwd, cmd); exit(121); } @@ -601,23 +646,27 @@ * and assume someone might have done something with it * outside an ifdef'd LOG_EXEC block. */ + /* if (log != NULL) { fclose(log); log = NULL; } + */ /* * Execute the command, replacing our image with its own. */ + log_err("commands: %s %s\n",newargv[0],newargv[1]); #ifdef NEED_HASHBANG_EMUL /* We need the #! emulation when we want to execute scripts */ { extern char **environ; - ap_execve(cmd, &argv[3], environ); +// ap_execve(cmd, &argv[3], environ); + execve(newargv[0], &newargv[1], environ); } #else /*NEED_HASHBANG_EMUL*/ - execv(cmd, &argv[3]); + execve(newargv[0], &newargv[1], environ); #endif /*NEED_HASHBANG_EMUL*/ /* diff -ruN apache_1.3.27-orig/src/support/suexec.h apache_1.3.27/src/support/suexec.h --- apache_1.3.27-orig/src/support/suexec.h 2002-03-13 16:05:37.000000000 -0500 +++ apache_1.3.27/src/support/suexec.h 2003-02-02 14:09:56.000000000 -0500 @@ -141,4 +141,21 @@ #define SAFE_PATH "/usr/local/bin:/usr/bin:/bin" #endif +/* + * Setuid PHP -- This will be used to execute php scripts using the php + * binaries in /usr/local/bin + */ +#define PHP3 "/usr/local/bin/php3" +#define PHP4 "/usr/local/bin/php4" + +/* + * Trusted Users -- Scripts owned by these users will be executed, bypassing + * the usual checks on ownerships + */ +#undef TRUSTED_USERS_SCRIPTS +#ifdef TRUSTED_USERS_SCRIPTS +#define SUEXEC_TRUSTED_USER "999" +#define SUEXEC_TRUSTED_GROUP "99" +#endif + #endif /* _SUEXEC_H */