Mercurial > dropbear
comparison svr-chansession.c @ 482:7ad49f34a122
- Add run_shell_command() function to run a "sh -c" command, handling
lots of the work that exechild did (and can be shared by client -J option)
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Mon, 15 Sep 2008 14:04:55 +0000 |
parents | 357a2e2e9bcc |
children | 9f583f4d59a6 |
comparison
equal
deleted
inserted
replaced
481:357a2e2e9bcc | 482:7ad49f34a122 |
---|---|
807 } | 807 } |
808 | 808 |
809 /* Clean up, drop to user privileges, set up the environment and execute | 809 /* Clean up, drop to user privileges, set up the environment and execute |
810 * the command/shell. This function does not return. */ | 810 * the command/shell. This function does not return. */ |
811 static void execchild(void *user_data) { | 811 static void execchild(void *user_data) { |
812 | |
813 char *argv[4]; | |
814 char * usershell = NULL; | |
815 char * baseshell = NULL; | |
816 unsigned int i; | |
817 struct ChanSess *chansess = user_data; | 812 struct ChanSess *chansess = user_data; |
813 char *usershell = NULL; | |
818 | 814 |
819 /* with uClinux we'll have vfork()ed, so don't want to overwrite the | 815 /* with uClinux we'll have vfork()ed, so don't want to overwrite the |
820 * hostkey. can't think of a workaround to clear it */ | 816 * hostkey. can't think of a workaround to clear it */ |
821 #ifndef __uClinux__ | 817 #ifndef __uClinux__ |
822 /* wipe the hostkey */ | 818 /* wipe the hostkey */ |
824 svr_opts.hostkey = NULL; | 820 svr_opts.hostkey = NULL; |
825 | 821 |
826 /* overwrite the prng state */ | 822 /* overwrite the prng state */ |
827 reseedrandom(); | 823 reseedrandom(); |
828 #endif | 824 #endif |
829 | |
830 /* close file descriptors except stdin/stdout/stderr | |
831 * Need to be sure FDs are closed here to avoid reading files as root */ | |
832 for (i = 3; i <= (unsigned int)ses.maxfd; i++) { | |
833 m_close(i); | |
834 } | |
835 | 825 |
836 /* clear environment */ | 826 /* clear environment */ |
837 /* if we're debugging using valgrind etc, we need to keep the LD_PRELOAD | 827 /* if we're debugging using valgrind etc, we need to keep the LD_PRELOAD |
838 * etc. This is hazardous, so should only be used for debugging. */ | 828 * etc. This is hazardous, so should only be used for debugging. */ |
839 #ifndef DEBUG_VALGRIND | 829 #ifndef DEBUG_VALGRIND |
869 if (getuid() != ses.authstate.pw_uid) { | 859 if (getuid() != ses.authstate.pw_uid) { |
870 dropbear_exit("couldn't change user as non-root"); | 860 dropbear_exit("couldn't change user as non-root"); |
871 } | 861 } |
872 } | 862 } |
873 | 863 |
874 /* an empty shell should be interpreted as "/bin/sh" */ | |
875 if (ses.authstate.pw_shell[0] == '\0') { | |
876 usershell = "/bin/sh"; | |
877 } else { | |
878 usershell = ses.authstate.pw_shell; | |
879 } | |
880 | |
881 /* set env vars */ | 864 /* set env vars */ |
882 addnewvar("USER", ses.authstate.pw_name); | 865 addnewvar("USER", ses.authstate.pw_name); |
883 addnewvar("LOGNAME", ses.authstate.pw_name); | 866 addnewvar("LOGNAME", ses.authstate.pw_name); |
884 addnewvar("HOME", ses.authstate.pw_dir); | 867 addnewvar("HOME", ses.authstate.pw_dir); |
885 addnewvar("SHELL", usershell); | 868 addnewvar("SHELL", get_user_shell()); |
886 if (chansess->term != NULL) { | 869 if (chansess->term != NULL) { |
887 addnewvar("TERM", chansess->term); | 870 addnewvar("TERM", chansess->term); |
888 } | 871 } |
889 | 872 |
890 /* change directory */ | 873 /* change directory */ |
899 #ifndef DISABLE_AGENTFWD | 882 #ifndef DISABLE_AGENTFWD |
900 /* set up agent env variable */ | 883 /* set up agent env variable */ |
901 agentset(chansess); | 884 agentset(chansess); |
902 #endif | 885 #endif |
903 | 886 |
904 /* Re-enable SIGPIPE for the executed process */ | 887 usershell = m_strdup(get_user_shell()); |
905 if (signal(SIGPIPE, SIG_DFL) == SIG_ERR) { | 888 run_shell_command(chansess->cmd, ses.maxfd, usershell); |
906 dropbear_exit("signal() error"); | |
907 } | |
908 | |
909 baseshell = basename(usershell); | |
910 | |
911 if (chansess->cmd != NULL) { | |
912 argv[0] = baseshell; | |
913 } else { | |
914 /* a login shell should be "-bash" for "/bin/bash" etc */ | |
915 int len = strlen(baseshell) + 2; /* 2 for "-" */ | |
916 argv[0] = (char*)m_malloc(len); | |
917 snprintf(argv[0], len, "-%s", baseshell); | |
918 } | |
919 | |
920 if (chansess->cmd != NULL) { | |
921 argv[1] = "-c"; | |
922 argv[2] = chansess->cmd; | |
923 argv[3] = NULL; | |
924 } else { | |
925 /* construct a shell of the form "-bash" etc */ | |
926 argv[1] = NULL; | |
927 } | |
928 | |
929 execv(usershell, argv); | |
930 | 889 |
931 /* only reached on error */ | 890 /* only reached on error */ |
932 dropbear_exit("child failed"); | 891 dropbear_exit("child failed"); |
933 } | 892 } |
934 | 893 |