One more thing that these diffs include is a rearrangement of the log
output that more closely matches a standard apache log.
These diffs apply to the 1.2.4 release of suexec.c
*** suexec.c.dist Mon Sep 29 12:27:41 1997
--- z.c Tue Oct 21 20:11:54 1997
***************
*** 1,3 ****
--- 1,6 ----
+ /*
+ * $Id: suexec.c,v 1.5 1997/10/06 22:29:52 mdpc Exp $
+ */
/* ====================================================================
* Copyright (c) 1995-1997 The Apache Group. All rights reserved.
*
***************
*** 151,158 ****
time(&timevar);
lt = localtime(&timevar);
! fprintf(log, "[%.2d:%.2d:%.2d %.2d-%.2d-%.2d]: ", lt->tm_hour, lt->tm_min,
! lt->tm_sec, lt->tm_mday, (lt->tm_mon + 1), lt->tm_year);
vfprintf(log, fmt, ap);
--- 154,172 ----
time(&timevar);
lt = localtime(&timevar);
! /***
! ** fprintf(log, "[%.2d:%.2d:%.2d %.2d-%.2d-%.2d]: ", lt->tm_hour,
lt->tm_min,
! ** lt->tm_sec, lt->tm_year, lt->tm_mday, (lt->tm_mon + 1));
! **/
!
! fprintf(log, "[%.2d/%.2d/%.4d:%.2d:%.2d:%.2d]: ",
! (lt->tm_mon + 1),
! lt->tm_mday,
! (lt->tm_year)+1900,
! lt->tm_hour,
! lt->tm_min,
! lt->tm_sec
! );
vfprintf(log, fmt, ap);
***************
*** 182,188 ****
if ((cleanenv = (char **)calloc(AP_ENVBUF, sizeof(char *))) == NULL) {
! log_err("failed to malloc env mem\n");
exit(120);
}
--- 196,202 ----
if ((cleanenv = (char **)calloc(AP_ENVBUF, sizeof(char *))) == NULL) {
! log_err("ERROR: failed to malloc env mem\n");
exit(120);
}
***************
*** 236,242 ****
*/
prog = argv[0];
if (argc < 4) {
! log_err("too few arguments\n");
exit(101);
}
target_uname = argv[1];
--- 250,256 ----
*/
prog = argv[0];
if (argc < 4) {
! log_err("ERROR: too few arguments\n");
exit(101);
}
target_uname = argv[1];
***************
*** 249,257 ****
*/
uid = getuid();
if ((pw = getpwuid(uid)) == NULL) {
! log_err("invalid uid: (%ld)\n", uid);
exit(102);
}
/*
* Check to see if the user running this program
--- 263,272 ----
*/
uid = getuid();
if ((pw = getpwuid(uid)) == NULL) {
! log_err("ERROR: invalid uid: (%ld)\n", uid);
exit(102);
}
+
/*
* Check to see if the user running this program
***************
*** 259,265 ****
* suexec.h. If not the allowed user, error out.
*/
if (strcmp(HTTPD_USER, pw->pw_name)) {
! log_err("user mismatch (%s)\n", pw->pw_name);
exit(103);
}
--- 274,280 ----
* suexec.h. If not the allowed user, error out.
*/
if (strcmp(HTTPD_USER, pw->pw_name)) {
! log_err("ERROR: user mismatch (%s)\n", pw->pw_name);
exit(103);
}
***************
*** 274,280 ****
(! strncmp (cmd, "../", 3)) ||
(strstr (cmd, "/../") != NULL)
) {
! log_err("invalid command (%s)\n", cmd);
exit(104);
}
--- 289,295 ----
(! strncmp (cmd, "../", 3)) ||
(strstr (cmd, "/../") != NULL)
) {
! log_err("ERROR: invalid command (%s)\n", cmd);
exit(104);
}
***************
*** 283,298 ****
* so, set the flag, and remove the '~' from the
* target username.
*/
if (!strncmp("~", target_uname, 1)) {
target_uname++;
userdir = 1;
! }
/*
* Error out if the target username is invalid.
*/
if ((pw = getpwnam(target_uname)) == NULL) {
! log_err("invalid target user name: (%s)\n", target_uname);
exit(105);
}
--- 298,315 ----
* so, set the flag, and remove the '~' from the
* target username.
*/
+
if (!strncmp("~", target_uname, 1)) {
+
target_uname++;
userdir = 1;
! }
/*
* Error out if the target username is invalid.
*/
if ((pw = getpwnam(target_uname)) == NULL) {
! log_err("ERROR: invalid target user name: (%s)\n", target_uname);
exit(105);
}
***************
*** 301,307 ****
*/
if (strspn(target_gname, "1234567890") != strlen(target_gname)) {
if ((gr = getgrnam(target_gname)) == NULL) {
! log_err("invalid target group name: (%s)\n", target_gname);
exit(106);
}
gid = gr->gr_gid;
--- 318,324 ----
*/
if (strspn(target_gname, "1234567890") != strlen(target_gname)) {
if ((gr = getgrnam(target_gname)) == NULL) {
! log_err("ERROR: invalid target group name: (%s)\n", target_gname);
exit(106);
}
gid = gr->gr_gid;
***************
*** 332,340 ****
* Error out if attempt is made to execute as root or as
* a UID less than UID_MIN. Tsk tsk.
*/
! if ((uid == 0) ||
(uid < UID_MIN)) {
! log_err("cannot run as forbidden uid (%d/%s)\n", uid, cmd);
exit(107);
}
--- 349,357 ----
* Error out if attempt is made to execute as root or as
* a UID less than UID_MIN. Tsk tsk.
*/
! if ((uid == 0) ||
(uid < UID_MIN)) {
! log_err("ERROR: cannot run as forbidden uid (%d/%s)\n", uid, cmd);
exit(107);
}
***************
*** 342,350 ****
* Error out if attempt is made to execute as root group
* or as a GID less than GID_MIN. Tsk tsk.
*/
! if ((gid == 0) ||
! (gid < GID_MIN)) {
! log_err("cannot run as forbidden gid (%d/%s)\n", gid, cmd);
exit(108);
}
--- 359,366 ----
* Error out if attempt is made to execute as root group
* or as a GID less than GID_MIN. Tsk tsk.
*/
! if ((gid == 0) || (gid < GID_MIN)) {
! log_err("ERROR: cannot run as forbidden gid (%d/%s)\n", gid, cmd);
exit(108);
}
***************
*** 355,361 ****
* 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);
}
--- 371,377 ----
* and setgid() to the target group. If unsuccessful, error out.
*/
if (((setgid(gid)) != 0) || (initgroups(actual_uname,gid) != 0)) {
! log_err("ERROR: failed to setgid (%ld: %s/%s)\n", gid, cwd, cmd);
exit(109);
}
***************
*** 363,369 ****
* 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);
}
--- 379,385 ----
* setuid() to the target user. Error out on fail.
*/
if ((setuid(uid)) != 0) {
! log_err("ERROR: failed to setuid (%ld: %s/%s)\n", uid, cwd, cmd);
exit(110);
}
***************
*** 376,407 ****
* directories. Yuck.
*/
if (getcwd(cwd, AP_MAXPATH) == NULL) {
! log_err("cannot get current working directory\n");
exit(111);
}
if (userdir) {
if (((chdir(target_homedir)) != 0) ||
((chdir(USERDIR_SUFFIX)) != 0) ||
! ((getcwd(dwd, AP_MAXPATH)) == NULL) ||
((chdir(cwd)) != 0))
{
! log_err("cannot get docroot information (%s)\n", target_homedir);
exit(112);
}
}
else {
if (((chdir(DOC_ROOT)) != 0) ||
! ((getcwd(dwd, AP_MAXPATH)) == NULL) ||
((chdir(cwd)) != 0))
{
! log_err("cannot get docroot information (%s)\n", DOC_ROOT);
exit(113);
}
}
if ((strncmp(cwd, dwd, strlen(dwd))) != 0) {
! log_err("command not in docroot (%s/%s)\n", cwd, cmd);
exit(114);
}
--- 392,425 ----
* directories. Yuck.
*/
if (getcwd(cwd, AP_MAXPATH) == NULL) {
! log_err("ERROR: cannot get current working directory\n");
exit(111);
}
+
if (userdir) {
if (((chdir(target_homedir)) != 0) ||
((chdir(USERDIR_SUFFIX)) != 0) ||
! ((getcwd(dwd, AP_MAXPATH)) == NULL) ||
((chdir(cwd)) != 0))
{
! log_err("ERROR: cannot get docroot information (%s)\n",
target_homedir);
exit(112);
}
}
else {
+
if (((chdir(DOC_ROOT)) != 0) ||
! ((getcwd(dwd, AP_MAXPATH)) == NULL) ||
((chdir(cwd)) != 0))
{
! log_err("ERROR: cannot get docroot information (%s)\n", DOC_ROOT);
exit(113);
}
}
if ((strncmp(cwd, dwd, strlen(dwd))) != 0) {
! log_err("ERROR: command not in docroot (%s/%s)\n", cwd, cmd);
exit(114);
}
***************
*** 409,423 ****
* Stat the cwd and verify it is a directory, or error out.
*/
if (((lstat(cwd, &dir_info)) != 0) || !(S_ISDIR(dir_info.st_mode))) {
! log_err("cannot stat directory: (%s)\n", cwd);
exit(115);
}
/*
* Error out if cwd is writable by others.
*/
! if ((dir_info.st_mode & S_IWOTH) || (dir_info.st_mode & S_IWGRP)) {
! log_err("directory is writable by others: (%s)\n", cwd);
exit(116);
}
--- 427,441 ----
* Stat the cwd and verify it is a directory, or error out.
*/
if (((lstat(cwd, &dir_info)) != 0) || !(S_ISDIR(dir_info.st_mode))) {
! log_err("ERROR: cannot stat directory: (%s)\n", cwd);
exit(115);
}
/*
* Error out if cwd is writable by others.
*/
! if ( (dir_info.st_mode & S_IWOTH) || (dir_info.st_mode & S_IWGRP)) {
! log_err("ERROR: directory is writable by others: (%s)\n", cwd);
exit(116);
}
***************
*** 425,439 ****
* Error out if we cannot stat the program.
*/
if (((lstat(cmd, &prg_info)) != 0) || (S_ISLNK(prg_info.st_mode))) {
! log_err("cannot stat program: (%s)\n", cmd);
exit(117);
}
/*
* Error out if the program is writable by others.
*/
! if ((prg_info.st_mode & S_IWOTH) || (prg_info.st_mode & S_IWGRP)) {
! log_err("file is writable by others: (%s/%s)\n", cwd, cmd);
exit(118);
}
--- 443,457 ----
* Error out if we cannot stat the program.
*/
if (((lstat(cmd, &prg_info)) != 0) || (S_ISLNK(prg_info.st_mode))) {
! log_err("ERROR: cannot stat program: (%s)\n", cmd);
exit(117);
}
/*
* Error out if the program is writable by others.
*/
! if ((prg_info.st_mode & S_IWOTH) || (prg_info.st_mode & S_IWGRP)) {
! log_err("ERROR: file is writable by others: (%s/%s)\n", cwd, cmd);
exit(118);
}
***************
*** 441,447 ****
* Error out if the file is setuid or setgid.
*/
if ((prg_info.st_mode & S_ISUID) || (prg_info.st_mode & S_ISGID)) {
! log_err("file is either setuid or setgid: (%s/%s)\n",cwd,cmd);
exit(119);
}
--- 459,465 ----
* Error out if the file is setuid or setgid.
*/
if ((prg_info.st_mode & S_ISUID) || (prg_info.st_mode & S_ISGID)) {
! log_err("ERROR: file is either setuid or setgid: (%s/%s)\n",cwd,cmd);
exit(119);
}
***************
*** 454,460 ****
(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);
--- 472,478 ----
(uid != prg_info.st_uid) ||
(gid != 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);
***************
*** 484,489 ****
*
* Oh well, log the failure and error out.
*/
! log_err("exec failed (%s)\n", cmd);
exit(255);
}
--- 502,507 ----
*
* Oh well, log the failure and error out.
*/
! log_err("ERROR: exec failed (%s)\n", cmd);
exit(255);
}