summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDamien Miller <djm@mindrot.org>2006-09-07 10:36:43 +1000
committerDamien Miller <djm@mindrot.org>2006-09-07 10:36:43 +1000
commit6433df036e6cf37c5ac8fc69dcedc464e6424b16 (patch)
tree6524438f390452a9020cc76e253801c4c3ec8b02
parent6e1033318cc0bc82a45a18d97894bee7bd60e935 (diff)
- (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
-rw-r--r--ChangeLog9
-rw-r--r--auth.c3
-rw-r--r--sshd.c32
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 @@
120060907
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
120060905 820060905
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 $
diff --git a/auth.c b/auth.c
index 5da140b07..db2aa7bf9 100644
--- a/auth.c
+++ b/auth.c
@@ -73,6 +73,7 @@
73extern ServerOptions options; 73extern ServerOptions options;
74extern int use_privsep; 74extern int use_privsep;
75extern Buffer loginmsg; 75extern Buffer loginmsg;
76extern struct passwd *privsep_pw;
76 77
77/* Debugging messages */ 78/* Debugging messages */
78Buffer auth_debug; 79Buffer 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
diff --git a/sshd.c b/sshd.c
index 3fb146424..e61adc1b5 100644
--- a/sshd.c
+++ b/sshd.c
@@ -244,6 +244,9 @@ Buffer cfg;
244/* message to be displayed after login */ 244/* message to be displayed after login */
245Buffer loginmsg; 245Buffer loginmsg;
246 246
247/* Unprivileged user */
248struct 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. */
248void destroy_sensitive_data(void); 251void destroy_sensitive_data(void);
249void demote_sensitive_data(void); 252void 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",