From 6433df036e6cf37c5ac8fc69dcedc464e6424b16 Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Thu, 7 Sep 2006 10:36:43 +1000 Subject: - (djm) [sshd.c auth.c] Set up fakepw() with privsep uid/gid, so it can be used to drop privilege to; fixes Solaris GSSAPI crash reported by Magnus Abrante; suggestion and feedback dtucker@ NB. this change will require that the privilege separation user must exist on all the time, not just when UsePrivilegeSeparation=yes --- ChangeLog | 9 ++++++++- auth.c | 3 +++ sshd.c | 32 +++++++++++++++++--------------- 3 files changed, 28 insertions(+), 16 deletions(-) diff --git a/ChangeLog b/ChangeLog index ff2d6ae00..b4340de78 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +20060907 + - (djm) [sshd.c auth.c] Set up fakepw() with privsep uid/gid, so it can + be used to drop privilege to; fixes Solaris GSSAPI crash reported by + Magnus Abrante; suggestion and feedback dtucker@ + NB. this change will require that the privilege separation user must + exist on all the time, not just when UsePrivilegeSeparation=yes + 20060905 - (dtucker) [configure.ac] s/AC_DEFINES/AC_DEFINE/ spotted by Roumen Petrov. - (dtucker) [loginrec.c] Include paths.h for _PATH_BTMP. @@ -5399,4 +5406,4 @@ - (djm) Trim deprecated options from INSTALL. Mention UsePAM - (djm) Fix quote handling in sftp; Patch from admorten AT umich.edu -$Id: ChangeLog,v 1.4531 2006/09/05 09:25:19 dtucker Exp $ +$Id: ChangeLog,v 1.4532 2006/09/07 00:36:43 djm Exp $ diff --git a/auth.c b/auth.c index 5da140b07..db2aa7bf9 100644 --- a/auth.c +++ b/auth.c @@ -73,6 +73,7 @@ extern ServerOptions options; extern int use_privsep; extern Buffer loginmsg; +extern struct passwd *privsep_pw; /* Debugging messages */ Buffer auth_debug; @@ -570,6 +571,8 @@ fakepw(void) 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 --git a/sshd.c b/sshd.c index 3fb146424..e61adc1b5 100644 --- a/sshd.c +++ b/sshd.c @@ -244,6 +244,9 @@ Buffer cfg; /* 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); @@ -579,7 +582,6 @@ privsep_preauth_child(void) { u_int32_t rnd[256]; gid_t gidset[1]; - struct passwd *pw; int i; /* Enable challenge-response authentication for privilege separation */ @@ -592,12 +594,6 @@ privsep_preauth_child(void) /* 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(); - /* Change our root directory */ if (chroot(_PATH_PRIVSEP_CHROOT_DIR) == -1) fatal("chroot(\"%s\"): %s", _PATH_PRIVSEP_CHROOT_DIR, @@ -606,16 +602,16 @@ privsep_preauth_child(void) 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 } @@ -1435,6 +1431,15 @@ main(int ac, char **av) debug("sshd version %.100s", 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 = xcalloc(options.num_host_key_files, sizeof(Key *)); @@ -1504,9 +1509,6 @@ main(int ac, char **av) if (use_privsep) { struct stat st; - if (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", -- cgit v1.2.3