*** support/suexec.c.orig Fri Jan 30 08:45:44 1998 --- support/suexec.c Fri Apr 24 17:32:21 1998 *************** *** 66,71 **** --- 66,94 ---- * */ + /* + * "System" CGI modification 97.05.10 by Rick Franchuk (rickf@netnation.com) + * + * I found that while it's great to make scripts run under the UID and GID + * specified in httpd.conf or what /etc/passwd says is 'cool', suEXEC can + * really put a damper on 'System' cgi's, forcing copies of the scripts + * to be installed into users' home directories. That didn't seem very + * fitting... so I changed it so that the target UID check is disabled in + * a system directory #defined in suexec+.h. I hope you all find it useful. + * + * The docroot check had to be bypassed to allow functionality for VirtualHost + * entries. I'm somewhat suprised noone encountered that behavior before. + */ + + /* "FPEXE modification made on 98.04.24 by Scot Hetzel (hetzels@westbend.net) + * based on previous FPEXE modifications supplied by Mark Wormgoor + * (riddles@ipe.nl) + * + * Changes were made in order to use Suexec and Frontpage 98 at the same time. + * After we change to the target_uid and target_gid. We check if cmd = FPEXE, + * if it does then we execute the cmd without performing any further tests. + * + */ #include "suexec.h" *************** *** 75,81 **** #include #include #include ! #include #include #include #include --- 98,104 ---- #include #include #include ! #include #include #include #include *************** *** 138,144 **** static void err_output(const char *fmt, va_list ap) { - #ifdef LOG_EXEC time_t timevar; struct tm *lt; --- 161,166 ---- *************** *** 158,164 **** vfprintf(log, fmt, ap); fflush(log); - #endif /* LOG_EXEC */ return; } --- 180,185 ---- *************** *** 264,270 **** log_err("user mismatch (%s)\n", pw->pw_name); exit(103); } ! /* * Check for a leading '/' (absolute path) in the command to be executed, * or attempts to back up out of the current directory, --- 285,291 ---- log_err("user mismatch (%s)\n", pw->pw_name); exit(103); } ! /* * Check for a leading '/' (absolute path) in the command to be executed, * or attempts to back up out of the current directory, *************** *** 301,306 **** --- 322,328 ---- /* * Error out if the target group name is invalid. */ + if (strspn(target_gname, "1234567890") != strlen(target_gname)) { if ((gr = getgrnam(target_gname)) == NULL) { log_err("invalid target group name: (%s)\n", target_gname); *************** *** 325,331 **** * Log the transaction here to be sure we have an open log * before we setuid(). */ ! log_err("uid: (%s/%s) gid: (%s/%s) %s\n", target_uname, actual_uname, target_gname, actual_gname, cmd); --- 347,353 ---- * Log the transaction here to be sure we have an open log * before we setuid(). */ ! log_err("uid: (%s/%s) gid: (%s/%s) cmd: %s\n", target_uname, actual_uname, target_gname, actual_gname, cmd); *************** *** 357,363 **** * and setgid() to the target group. If unsuccessful, error out. */ if (((setgid(gid)) != 0) || (initgroups(actual_uname,gid) != 0)) { ! log_err("failed to setgid (%ld: %s)\n", gid, cmd); exit(109); } --- 379,385 ---- * and setgid() to the target group. If unsuccessful, error out. */ if (((setgid(gid)) != 0) || (initgroups(actual_uname,gid) != 0)) { ! log_err("failed to setgid (%ld: %s/%s)\n", gid, cwd, cmd); exit(109); } *************** *** 365,375 **** * setuid() to the target user. Error out on fail. */ if ((setuid(uid)) != 0) { ! log_err("failed to setuid (%ld: %s)\n", uid, cmd); exit(110); } /* * Get the current working directory, as well as the proper * document root (dependant upon whether or not it is a * ~userdir request). Error out if we cannot get either one, --- 387,405 ---- * setuid() to the target user. Error out on fail. */ if ((setuid(uid)) != 0) { ! log_err("failed to setuid (%ld: %s/%s)\n", uid, cwd, cmd); exit(110); } /* + * We logged everything, changed to the target uid/gid, and know the + * user is ok. We run fpexe now and bail out before anything goes wrong. + */ + #ifdef FPEXE + if ((strcmp(cmd, FPEXE)) != NULL) { + #endif + + /* * Get the current working directory, as well as the proper * document root (dependant upon whether or not it is a * ~userdir request). Error out if we cannot get either one, *************** *** 402,411 **** --- 432,446 ---- } } + /* + * This section must be commented out to work properly with + * VirtualHosts running CGI in thier own directories. + * if ((strncmp(cwd, dwd, strlen(dwd))) != 0) { log_err("command not in docroot (%s/%s)\n", cwd, cmd); exit(114); } + */ /* * Stat the cwd and verify it is a directory, or error out. *************** *** 451,470 **** * Error out if the target name/group is different from * the name/group of the cwd or the program. */ ! if ((uid != dir_info.st_uid) || ! (gid != dir_info.st_gid) || ! (uid != prg_info.st_uid) || ! (gid != prg_info.st_gid)) ! { ! log_err("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); } clean_env(); /* * Be sure to close the log file so the CGI can't * mess with it. If the exec fails, it will be reopened --- 486,516 ---- * Error out if the target name/group is different from * the name/group of the cwd or the program. */ ! ! #ifdef SYSTEM_CGI ! if (strncmp(cwd, SYSTEM_CGI, strlen(SYSTEM_CGI))) { ! #endif ! if ((uid != dir_info.st_uid) || ! (gid != dir_info.st_gid) || ! (uid != prg_info.st_uid) || ! (gid != prg_info.st_gid)) ! { ! log_err("target uid/gid (%ld/%ld) mismatch with directory %s(%ld/%ld) or program %s(%ld/%ld)\n", ! uid, gid, ! cwd, dir_info.st_uid, dir_info.st_gid, ! cmd, prg_info.st_uid, prg_info.st_gid); ! exit(120); ! } ! #ifdef SYSTEM_CGI } + #endif clean_env(); + #ifdef FPEXE + } + #endif + /* * Be sure to close the log file so the CGI can't * mess with it. If the exec fails, it will be reopened *************** *** 486,491 **** --- 532,538 ---- * * Oh well, log the failure and error out. */ + log_err("exec failed (%s)\n", cmd); exit(255); }