NCSA httpd 1.0a5

Rob McCool (robm@ncsa.uiuc.edu)
Mon, 15 Nov 1993 21:11:49 -0600


Well, my week is ruined.

NCSA httpd 1.0a5 is now released. It's a bug fix for 1.0a4.

When fixing a bug in the inetd code, I broke the standalone code which
changed the user id to the one dictated in the configuration file.

THE NET EFFECT OF THIS IS HTTPD IS ALWAYS RUNNING AS ROOT. THIS IS BAD.

If you downloaded 1.0a4, I have made a "bin" directory full of binaries so
that you can plug in the new binary. Included at the end of this message and
in that directory is a source patch for those of you compiling from source.

Obviously, I feel terrible about this unexcusable oversight, and I can only
ask you to bear with us until 1.0. If you have already upgraded to 1.0a4,
PLEASE APPLY THIS PATCH OR GET A NEW BINARY.

Begging your forgiveness
--Rob

*** httpd_1.0a4/src/httpd.h Sun Nov 14 03:12:19 1993
--- httpd_1.0a5/src/httpd.h Mon Nov 15 19:59:06 1993
***************
*** 169,175 ****

/* ------------------------------ error types ------------------------------ */

! #define SERVER_VERSION "NCSA/1.0a4"
#define SERVER_PROTOCOL "HTTP/1.0"
#define SERVER_SUPPORT "httpd@ncsa.uiuc.edu"

--- 169,175 ----

/* ------------------------------ error types ------------------------------ */

! #define SERVER_VERSION "NCSA/1.0a5"
#define SERVER_PROTOCOL "HTTP/1.0"
#define SERVER_SUPPORT "httpd@ncsa.uiuc.edu"

*** httpd_1.0a4/src/httpd.c Sun Nov 14 03:12:18 1993
--- httpd_1.0a5/src/httpd.c Mon Nov 15 20:38:28 1993
***************
*** 154,165 ****
}
log_error("socket error: accept failed");
}
if((pid = fork()) == -1)
log_error("unable to fork new process");
else if(!pid) {
! /* we do this here so that logs can be opened as root */
! setuid(user_id);
! setgid(group_id);
close(0);
close(1);
dup2(csd,0);
--- 154,189 ----
}
log_error("socket error: accept failed");
}
+ /* we do this here so that logs can be opened as root */
if((pid = fork()) == -1)
log_error("unable to fork new process");
else if(!pid) {
! struct passwd* pwent;
!
! /* Only effective if we're running as root */
! if(!getuid()) {
! /* Now, make absolutely certain we don't have any privileges
! * except those mentioned in the configuration file. */
! if ((pwent = getpwuid(user_id)) == NULL) {
! log_error("couldn't determine user name from uid");
! exit(-1);
! }
! /* Reset `groups' attribute. */
! if (initgroups(pwent->pw_name, group_id) == -1) {
! log_error("unable to setgroups");
! exit(-1);
! }
! /* Note the order, first setgid() and then setuid(), it
! * wouldn't work the other way around. */
! if (setgid(group_id) == -1) {
! log_error("unable change gid");
! exit(-1);
! }
! if (setuid(user_id) == -1) {
! log_error("unable change uid");
! exit(-1);
! }
! }
close(0);
close(1);
dup2(csd,0);
***************
*** 170,178 ****
fclose(stdout);
exit(0);
}
! close(csd);
}
- }

extern char *optarg;
extern int optind;
--- 194,202 ----
fclose(stdout);
exit(0);
}
! close(csd);
! }
}

extern char *optarg;
extern int optind;
***************
*** 195,207 ****
read_config();
open_logs();
get_local_host();
- user_id = getuid();
- group_id = getgid();

set_env_vars();
if(standalone)
standalone_main();
else {
port = get_portnum(fileno(stdout),stdout);
process_request(stdin,stdout);
}
--- 219,231 ----
read_config();
open_logs();
get_local_host();

set_env_vars();
if(standalone)
standalone_main();
else {
+ user_id = getuid();
+ group_id = getgid();
port = get_portnum(fileno(stdout),stdout);
process_request(stdin,stdout);
}