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