diff options
-rw-r--r-- | ChangeLog | 9 | ||||
-rw-r--r-- | auth.c | 3 | ||||
-rw-r--r-- | sshd.c | 32 |
3 files changed, 28 insertions, 16 deletions
@@ -1,3 +1,10 @@ | |||
1 | 20060907 | ||
2 | - (djm) [sshd.c auth.c] Set up fakepw() with privsep uid/gid, so it can | ||
3 | be used to drop privilege to; fixes Solaris GSSAPI crash reported by | ||
4 | Magnus Abrante; suggestion and feedback dtucker@ | ||
5 | NB. this change will require that the privilege separation user must | ||
6 | exist on all the time, not just when UsePrivilegeSeparation=yes | ||
7 | |||
1 | 20060905 | 8 | 20060905 |
2 | - (dtucker) [configure.ac] s/AC_DEFINES/AC_DEFINE/ spotted by Roumen Petrov. | 9 | - (dtucker) [configure.ac] s/AC_DEFINES/AC_DEFINE/ spotted by Roumen Petrov. |
3 | - (dtucker) [loginrec.c] Include paths.h for _PATH_BTMP. | 10 | - (dtucker) [loginrec.c] Include paths.h for _PATH_BTMP. |
@@ -5399,4 +5406,4 @@ | |||
5399 | - (djm) Trim deprecated options from INSTALL. Mention UsePAM | 5406 | - (djm) Trim deprecated options from INSTALL. Mention UsePAM |
5400 | - (djm) Fix quote handling in sftp; Patch from admorten AT umich.edu | 5407 | - (djm) Fix quote handling in sftp; Patch from admorten AT umich.edu |
5401 | 5408 | ||
5402 | $Id: ChangeLog,v 1.4531 2006/09/05 09:25:19 dtucker Exp $ | 5409 | $Id: ChangeLog,v 1.4532 2006/09/07 00:36:43 djm Exp $ |
@@ -73,6 +73,7 @@ | |||
73 | extern ServerOptions options; | 73 | extern ServerOptions options; |
74 | extern int use_privsep; | 74 | extern int use_privsep; |
75 | extern Buffer loginmsg; | 75 | extern Buffer loginmsg; |
76 | extern struct passwd *privsep_pw; | ||
76 | 77 | ||
77 | /* Debugging messages */ | 78 | /* Debugging messages */ |
78 | Buffer auth_debug; | 79 | Buffer auth_debug; |
@@ -570,6 +571,8 @@ fakepw(void) | |||
570 | fake.pw_gecos = "NOUSER"; | 571 | fake.pw_gecos = "NOUSER"; |
571 | fake.pw_uid = (uid_t)-1; | 572 | fake.pw_uid = (uid_t)-1; |
572 | fake.pw_gid = (gid_t)-1; | 573 | fake.pw_gid = (gid_t)-1; |
574 | fake.pw_uid = privsep_pw->pw_uid; | ||
575 | fake.pw_gid = privsep_pw->pw_gid; | ||
573 | #ifdef HAVE_PW_CLASS_IN_PASSWD | 576 | #ifdef HAVE_PW_CLASS_IN_PASSWD |
574 | fake.pw_class = ""; | 577 | fake.pw_class = ""; |
575 | #endif | 578 | #endif |
@@ -244,6 +244,9 @@ Buffer cfg; | |||
244 | /* message to be displayed after login */ | 244 | /* message to be displayed after login */ |
245 | Buffer loginmsg; | 245 | Buffer loginmsg; |
246 | 246 | ||
247 | /* Unprivileged user */ | ||
248 | struct passwd *privsep_pw = NULL; | ||
249 | |||
247 | /* Prototypes for various functions defined later in this file. */ | 250 | /* Prototypes for various functions defined later in this file. */ |
248 | void destroy_sensitive_data(void); | 251 | void destroy_sensitive_data(void); |
249 | void demote_sensitive_data(void); | 252 | void demote_sensitive_data(void); |
@@ -579,7 +582,6 @@ privsep_preauth_child(void) | |||
579 | { | 582 | { |
580 | u_int32_t rnd[256]; | 583 | u_int32_t rnd[256]; |
581 | gid_t gidset[1]; | 584 | gid_t gidset[1]; |
582 | struct passwd *pw; | ||
583 | int i; | 585 | int i; |
584 | 586 | ||
585 | /* Enable challenge-response authentication for privilege separation */ | 587 | /* Enable challenge-response authentication for privilege separation */ |
@@ -592,12 +594,6 @@ privsep_preauth_child(void) | |||
592 | /* Demote the private keys to public keys. */ | 594 | /* Demote the private keys to public keys. */ |
593 | demote_sensitive_data(); | 595 | demote_sensitive_data(); |
594 | 596 | ||
595 | if ((pw = getpwnam(SSH_PRIVSEP_USER)) == NULL) | ||
596 | fatal("Privilege separation user %s does not exist", | ||
597 | SSH_PRIVSEP_USER); | ||
598 | memset(pw->pw_passwd, 0, strlen(pw->pw_passwd)); | ||
599 | endpwent(); | ||
600 | |||
601 | /* Change our root directory */ | 597 | /* Change our root directory */ |
602 | if (chroot(_PATH_PRIVSEP_CHROOT_DIR) == -1) | 598 | if (chroot(_PATH_PRIVSEP_CHROOT_DIR) == -1) |
603 | fatal("chroot(\"%s\"): %s", _PATH_PRIVSEP_CHROOT_DIR, | 599 | fatal("chroot(\"%s\"): %s", _PATH_PRIVSEP_CHROOT_DIR, |
@@ -606,16 +602,16 @@ privsep_preauth_child(void) | |||
606 | fatal("chdir(\"/\"): %s", strerror(errno)); | 602 | fatal("chdir(\"/\"): %s", strerror(errno)); |
607 | 603 | ||
608 | /* Drop our privileges */ | 604 | /* Drop our privileges */ |
609 | debug3("privsep user:group %u:%u", (u_int)pw->pw_uid, | 605 | debug3("privsep user:group %u:%u", (u_int)privsep_pw->pw_uid, |
610 | (u_int)pw->pw_gid); | 606 | (u_int)privsep_pw->pw_gid); |
611 | #if 0 | 607 | #if 0 |
612 | /* XXX not ready, too heavy after chroot */ | 608 | /* XXX not ready, too heavy after chroot */ |
613 | do_setusercontext(pw); | 609 | do_setusercontext(privsep_pw); |
614 | #else | 610 | #else |
615 | gidset[0] = pw->pw_gid; | 611 | gidset[0] = privsep_pw->pw_gid; |
616 | if (setgroups(1, gidset) < 0) | 612 | if (setgroups(1, gidset) < 0) |
617 | fatal("setgroups: %.100s", strerror(errno)); | 613 | fatal("setgroups: %.100s", strerror(errno)); |
618 | permanently_set_uid(pw); | 614 | permanently_set_uid(privsep_pw); |
619 | #endif | 615 | #endif |
620 | } | 616 | } |
621 | 617 | ||
@@ -1435,6 +1431,15 @@ main(int ac, char **av) | |||
1435 | 1431 | ||
1436 | debug("sshd version %.100s", SSH_RELEASE); | 1432 | debug("sshd version %.100s", SSH_RELEASE); |
1437 | 1433 | ||
1434 | /* Store privilege separation user for later use */ | ||
1435 | if ((privsep_pw = getpwnam(SSH_PRIVSEP_USER)) == NULL) | ||
1436 | fatal("Privilege separation user %s does not exist", | ||
1437 | SSH_PRIVSEP_USER); | ||
1438 | memset(privsep_pw->pw_passwd, 0, strlen(privsep_pw->pw_passwd)); | ||
1439 | strlcpy(privsep_pw->pw_passwd, "*", sizeof(privsep_pw->pw_passwd)); | ||
1440 | privsep_pw = pwcopy(privsep_pw); | ||
1441 | endpwent(); | ||
1442 | |||
1438 | /* load private host keys */ | 1443 | /* load private host keys */ |
1439 | sensitive_data.host_keys = xcalloc(options.num_host_key_files, | 1444 | sensitive_data.host_keys = xcalloc(options.num_host_key_files, |
1440 | sizeof(Key *)); | 1445 | sizeof(Key *)); |
@@ -1504,9 +1509,6 @@ main(int ac, char **av) | |||
1504 | if (use_privsep) { | 1509 | if (use_privsep) { |
1505 | struct stat st; | 1510 | struct stat st; |
1506 | 1511 | ||
1507 | if (getpwnam(SSH_PRIVSEP_USER) == NULL) | ||
1508 | fatal("Privilege separation user %s does not exist", | ||
1509 | SSH_PRIVSEP_USER); | ||
1510 | if ((stat(_PATH_PRIVSEP_CHROOT_DIR, &st) == -1) || | 1512 | if ((stat(_PATH_PRIVSEP_CHROOT_DIR, &st) == -1) || |
1511 | (S_ISDIR(st.st_mode) == 0)) | 1513 | (S_ISDIR(st.st_mode) == 0)) |
1512 | fatal("Missing privilege separation directory: %s", | 1514 | fatal("Missing privilege separation directory: %s", |