Mercurial > dropbear
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 */ |