comparison svr-chansession.c @ 464:4317be8b7cf9

Make a copy of passwd fields since getpwnam()'s retval isn't safe to keep
author Matt Johnston <matt@ucc.asn.au>
date Sun, 13 Jan 2008 03:55:59 +0000
parents 5df05d0a5366
children af3307f46a3d
comparison
equal deleted inserted replaced
461:db4f6adcb7e2 464:4317be8b7cf9
522 * Returns DROPBEAR_SUCCESS or DROPBEAR_FAILURE */ 522 * Returns DROPBEAR_SUCCESS or DROPBEAR_FAILURE */
523 static int sessionpty(struct ChanSess * chansess) { 523 static int sessionpty(struct ChanSess * chansess) {
524 524
525 unsigned int termlen; 525 unsigned int termlen;
526 unsigned char namebuf[65]; 526 unsigned char namebuf[65];
527 struct passwd * pw = NULL;
527 528
528 TRACE(("enter sessionpty")) 529 TRACE(("enter sessionpty"))
529 chansess->term = buf_getstring(ses.payload, &termlen); 530 chansess->term = buf_getstring(ses.payload, &termlen);
530 if (termlen > MAX_TERM_LEN) { 531 if (termlen > MAX_TERM_LEN) {
531 /* TODO send disconnect ? */ 532 /* TODO send disconnect ? */
545 chansess->tty = (char*)m_strdup(namebuf); 546 chansess->tty = (char*)m_strdup(namebuf);
546 if (!chansess->tty) { 547 if (!chansess->tty) {
547 dropbear_exit("out of memory"); /* TODO disconnect */ 548 dropbear_exit("out of memory"); /* TODO disconnect */
548 } 549 }
549 550
550 pty_setowner(ses.authstate.pw, chansess->tty); 551 pw = getpwnam(ses.authstate.pw_name);
552 if (!pw)
553 dropbear_exit("getpwnam failed after succeeding previously");
554 pty_setowner(pw, chansess->tty);
551 555
552 /* Set up the rows/col counts */ 556 /* Set up the rows/col counts */
553 sessionwinchange(chansess); 557 sessionwinchange(chansess);
554 558
555 /* Read the terminal modes */ 559 /* Read the terminal modes */
602 } 606 }
603 607
604 #ifdef LOG_COMMANDS 608 #ifdef LOG_COMMANDS
605 if (chansess->cmd) { 609 if (chansess->cmd) {
606 dropbear_log(LOG_INFO, "user %s executing '%s'", 610 dropbear_log(LOG_INFO, "user %s executing '%s'",
607 ses.authstate.printableuser, chansess->cmd); 611 ses.authstate.pw_name, chansess->cmd);
608 } else { 612 } else {
609 dropbear_log(LOG_INFO, "user %s executing login shell", 613 dropbear_log(LOG_INFO, "user %s executing login shell",
610 ses.authstate.printableuser); 614 ses.authstate.pw_name);
611 } 615 }
612 #endif 616 #endif
613 617
614 if (chansess->term == NULL) { 618 if (chansess->term == NULL) {
615 /* no pty */ 619 /* no pty */
793 #ifdef DO_MOTD 797 #ifdef DO_MOTD
794 if (svr_opts.domotd) { 798 if (svr_opts.domotd) {
795 /* don't show the motd if ~/.hushlogin exists */ 799 /* don't show the motd if ~/.hushlogin exists */
796 800
797 /* 11 == strlen("/hushlogin\0") */ 801 /* 11 == strlen("/hushlogin\0") */
798 len = strlen(ses.authstate.pw->pw_dir) + 11; 802 len = strlen(ses.authstate.pw_dir) + 11;
799 803
800 hushpath = m_malloc(len); 804 hushpath = m_malloc(len);
801 snprintf(hushpath, len, "%s/hushlogin", ses.authstate.pw->pw_dir); 805 snprintf(hushpath, len, "%s/hushlogin", ses.authstate.pw_dir);
802 806
803 if (stat(hushpath, &sb) < 0) { 807 if (stat(hushpath, &sb) < 0) {
804 /* more than a screenful is stupid IMHO */ 808 /* more than a screenful is stupid IMHO */
805 motdbuf = buf_new(80 * 25); 809 motdbuf = buf_new(80 * 25);
806 if (buf_readfile(motdbuf, MOTD_FILENAME) == DROPBEAR_SUCCESS) { 810 if (buf_readfile(motdbuf, MOTD_FILENAME) == DROPBEAR_SUCCESS) {
906 #endif /* DEBUG_VALGRIND */ 910 #endif /* DEBUG_VALGRIND */
907 911
908 /* We can only change uid/gid as root ... */ 912 /* We can only change uid/gid as root ... */
909 if (getuid() == 0) { 913 if (getuid() == 0) {
910 914
911 if ((setgid(ses.authstate.pw->pw_gid) < 0) || 915 if ((setgid(ses.authstate.pw_gid) < 0) ||
912 (initgroups(ses.authstate.pw->pw_name, 916 (initgroups(ses.authstate.pw_name,
913 ses.authstate.pw->pw_gid) < 0)) { 917 ses.authstate.pw_gid) < 0)) {
914 dropbear_exit("error changing user group"); 918 dropbear_exit("error changing user group");
915 } 919 }
916 if (setuid(ses.authstate.pw->pw_uid) < 0) { 920 if (setuid(ses.authstate.pw_uid) < 0) {
917 dropbear_exit("error changing user"); 921 dropbear_exit("error changing user");
918 } 922 }
919 } else { 923 } else {
920 /* ... but if the daemon is the same uid as the requested uid, we don't 924 /* ... but if the daemon is the same uid as the requested uid, we don't
921 * need to */ 925 * need to */
922 926
923 /* XXX - there is a minor issue here, in that if there are multiple 927 /* XXX - there is a minor issue here, in that if there are multiple
924 * usernames with the same uid, but differing groups, then the 928 * usernames with the same uid, but differing groups, then the
925 * differing groups won't be set (as with initgroups()). The solution 929 * differing groups won't be set (as with initgroups()). The solution
926 * is for the sysadmin not to give out the UID twice */ 930 * is for the sysadmin not to give out the UID twice */
927 if (getuid() != ses.authstate.pw->pw_uid) { 931 if (getuid() != ses.authstate.pw_uid) {
928 dropbear_exit("couldn't change user as non-root"); 932 dropbear_exit("couldn't change user as non-root");
929 } 933 }
930 } 934 }
931 935
932 /* an empty shell should be interpreted as "/bin/sh" */ 936 /* an empty shell should be interpreted as "/bin/sh" */
933 if (ses.authstate.pw->pw_shell[0] == '\0') { 937 if (ses.authstate.pw_shell[0] == '\0') {
934 usershell = "/bin/sh"; 938 usershell = "/bin/sh";
935 } else { 939 } else {
936 usershell = ses.authstate.pw->pw_shell; 940 usershell = ses.authstate.pw_shell;
937 } 941 }
938 942
939 /* set env vars */ 943 /* set env vars */
940 addnewvar("USER", ses.authstate.pw->pw_name); 944 addnewvar("USER", ses.authstate.pw_name);
941 addnewvar("LOGNAME", ses.authstate.pw->pw_name); 945 addnewvar("LOGNAME", ses.authstate.pw_name);
942 addnewvar("HOME", ses.authstate.pw->pw_dir); 946 addnewvar("HOME", ses.authstate.pw_dir);
943 addnewvar("SHELL", usershell); 947 addnewvar("SHELL", usershell);
944 if (chansess->term != NULL) { 948 if (chansess->term != NULL) {
945 addnewvar("TERM", chansess->term); 949 addnewvar("TERM", chansess->term);
946 } 950 }
947 951
948 /* change directory */ 952 /* change directory */
949 if (chdir(ses.authstate.pw->pw_dir) < 0) { 953 if (chdir(ses.authstate.pw_dir) < 0) {
950 dropbear_exit("error changing directory"); 954 dropbear_exit("error changing directory");
951 } 955 }
952 956
953 #ifndef DISABLE_X11FWD 957 #ifndef DISABLE_X11FWD
954 /* set up X11 forwarding if enabled */ 958 /* set up X11 forwarding if enabled */