*** 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 <sys/types.h>
  #include <stdio.h>
  #include <stdarg.h>
! #include <string.h>
  #include <pwd.h>
  #include <grp.h>
  #include <time.h>
--- 98,104 ----
  #include <sys/types.h>
  #include <stdio.h>
  #include <stdarg.h>
! #include <strings.h>
  #include <pwd.h>
  #include <grp.h>
  #include <time.h>
***************
*** 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);
  }
