diff -ur openssh/auth.c openssh-4.3p2/auth.c --- openssh/auth.c 2007-03-29 12:37:41.000000000 +0200 +++ openssh-4.3p2/auth.c 2007-03-29 19:26:10.000000000 +0200 @@ -57,6 +57,7 @@ extern ServerOptions options; extern int use_privsep; extern Buffer loginmsg; +extern struct passwd *privsep_pw; /* Debugging messages */ Buffer auth_debug; @@ -559,6 +560,8 @@ fake.pw_gecos = "NOUSER"; fake.pw_uid = (uid_t)-1; fake.pw_gid = (gid_t)-1; + fake.pw_uid = privsep_pw->pw_uid; + fake.pw_gid = privsep_pw->pw_gid; #ifdef HAVE_PW_CLASS_IN_PASSWD fake.pw_class = ""; #endif diff -ur openssh/sshd.c openssh-4.3p2/sshd.c --- openssh/sshd.c 2007-03-29 12:37:41.000000000 +0200 +++ openssh-4.3p2/sshd.c 2007-03-29 19:31:45.000000000 +0200 @@ -211,6 +211,9 @@ /* message to be displayed after login */ Buffer loginmsg; +/* Unprivileged user */ +struct passwd *privsep_pw = NULL; + /* Prototypes for various functions defined later in this file. */ void destroy_sensitive_data(void); void demote_sensitive_data(void); @@ -542,7 +545,6 @@ { u_int32_t rnd[256]; gid_t gidset[1]; - struct passwd *pw; int i; /* Enable challenge-response authentication for privilege separation */ @@ -555,12 +557,6 @@ /* Demote the private keys to public keys. */ demote_sensitive_data(); - if ((pw = getpwnam(SSH_PRIVSEP_USER)) == NULL) - fatal("Privilege separation user %s does not exist", - SSH_PRIVSEP_USER); - memset(pw->pw_passwd, 0, strlen(pw->pw_passwd)); - endpwent(); - /* Open the syslog permanently so the chrooted process still can write to syslog. */ open_log(); @@ -573,16 +569,16 @@ fatal("chdir(\"/\"): %s", strerror(errno)); /* Drop our privileges */ - debug3("privsep user:group %u:%u", (u_int)pw->pw_uid, - (u_int)pw->pw_gid); + debug3("privsep user:group %u:%u", (u_int)privsep_pw->pw_uid, + (u_int)privsep_pw->pw_gid); #if 0 /* XXX not ready, too heavy after chroot */ - do_setusercontext(pw); + do_setusercontext(privsep_pw); #else - gidset[0] = pw->pw_gid; + gidset[0] = privsep_pw->pw_gid; if (setgroups(1, gidset) < 0) fatal("setgroups: %.100s", strerror(errno)); - permanently_set_uid(pw); + permanently_set_uid(privsep_pw); #endif } @@ -1097,6 +1093,15 @@ debug("sshd version %.100s", (options.show_patchlevel == 1) ? SSH_VENDOR_PATCHLEVEL : SSH_RELEASE); + /* Store privilege separation user for later use */ + if ((privsep_pw = getpwnam(SSH_PRIVSEP_USER)) == NULL) + fatal("Privilege separation user %s does not exist", + SSH_PRIVSEP_USER); + memset(privsep_pw->pw_passwd, 0, strlen(privsep_pw->pw_passwd)); + strlcpy(privsep_pw->pw_passwd, "*", sizeof(privsep_pw->pw_passwd)); + privsep_pw = pwcopy(privsep_pw); + endpwent(); + /* load private host keys */ sensitive_data.host_keys = xmalloc(options.num_host_key_files * sizeof(Key *)); @@ -1167,9 +1172,6 @@ struct passwd *pw; struct stat st; - if ((pw = getpwnam(SSH_PRIVSEP_USER)) == NULL) - fatal("Privilege separation user %s does not exist", - SSH_PRIVSEP_USER); if ((stat(_PATH_PRIVSEP_CHROOT_DIR, &st) == -1) || (S_ISDIR(st.st_mode) == 0)) fatal("Missing privilege separation directory: %s",