From: Todd C. Miller Date: Mon, 3 Dec 2007 16:36:49 +0000 (+0000) Subject: The -i and -s flags can now take an optional command. X-Git-Tag: SUDO_1_7_0~318 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=3592cc0b1807a2844934840663968eafc5f3b599;p=sudo The -i and -s flags can now take an optional command. --- diff --git a/WHATSNEW b/WHATSNEW index 45c911318..1bb4378db 100644 --- a/WHATSNEW +++ b/WHATSNEW @@ -29,3 +29,6 @@ What's new in Sudo 1.7? configurable via sudoers and, optionally, the command line. * Visudo will now warn about aliases that are defined but not used. + + * The -i and -s command line flags now take an optional command + to be run via the shell. diff --git a/sudo.c b/sudo.c index e174ff8d3..85d1d550a 100644 --- a/sudo.c +++ b/sudo.c @@ -671,22 +671,35 @@ init_vars(sudo_mode, envp) * If we were given the '-e', '-i' or '-s' options we need to redo * NewArgv and NewArgc. */ - if ((sudo_mode & (MODE_SHELL | MODE_EDIT))) { - char **dst, **src = NewArgv; + if (ISSET(sudo_mode, MODE_EDIT)) { + NewArgv--; + NewArgc++; + NewArgv[0] = "sudoedit"; + } else if (ISSET(sudo_mode, MODE_SHELL)) { + char **av; /* Allocate an extra slot for execve() failure (ENOEXEC). */ - NewArgv = (char **) emalloc2((++NewArgc + 2), sizeof(char *)); - NewArgv++; - if (ISSET(sudo_mode, MODE_EDIT)) - NewArgv[0] = "sudoedit"; - else if (user_shell && *user_shell) - NewArgv[0] = user_shell; - else - errorx(1, "unable to determine shell"); - - /* copy the args from NewArgv */ - for (dst = NewArgv + 1; (*dst = *src) != NULL; ++src, ++dst) - continue; + av = (char **) emalloc2(5, sizeof(char *)); + av++; + + av[0] = user_shell; /* may be updated later */ + if (NewArgc > 0) { + size_t size; + char *cmnd, *src, *dst, *end; + size = (size_t) (NewArgv[NewArgc - 1] - NewArgv[0]) + + strlen(NewArgv[NewArgc - 1]) + 1; + cmnd = emalloc(size); + src = NewArgv[0]; + dst = cmnd; + for (end = src + size - 1; src < end; src++, dst++) + *dst = *src == 0 ? ' ' : *src; + *dst = '\0'; + av[1] = "-c"; + av[2] = cmnd; + NewArgc = 2; + } + av[++NewArgc] = NULL; + NewArgv = av; } } @@ -725,7 +738,7 @@ set_cmnd(sudo_mode) size_t size, n; /* If we didn't realloc NewArgv it is contiguous so just count. */ - if (!(sudo_mode & (MODE_SHELL | MODE_EDIT))) { + if (!ISSET(sudo_mode, MODE_SHELL)) { size = (size_t) (NewArgv[NewArgc-1] - NewArgv[1]) + strlen(NewArgv[NewArgc-1]) + 1; } else { @@ -779,8 +792,10 @@ parse_args(argc, argv) while (NewArgc > 0) { if (NewArgv[0][0] == '-') { - if (NewArgv[0][1] != '\0' && NewArgv[0][2] != '\0') + if (NewArgv[0][1] != '\0' && NewArgv[0][2] != '\0') { warningx("please use single character options"); + usage(1); + } switch (NewArgv[0][1]) { case 'p': diff --git a/sudo.pod b/sudo.pod index b6e060266..bc05b5f2e 100644 --- a/sudo.pod +++ b/sudo.pod @@ -35,8 +35,8 @@ S<[B<-u> I|I<#uid>]> [I] B [B<-bEHPS>] S<[B<-a> I]> S<[B<-C> I]> S<[B<-c> I|I<->]> S<[B<-g> I|I<#gid>]> S<[B<-p> I]> -S<[B<-u> I|I<#uid>]> S<[B=I]> -S<{B<-i> | B<-s> | I}> +S<[B<-u> I|I<#uid>]> S<[B=I]> [S<{B<-i> | B<-s>] +[}>] B [B<-S>] S<[B<-a> I]> S<[B<-C> I]> S<[B<-c> I|I<->]> S<[B<-g> I|I<#gid>]> S<[B<-p> I]> @@ -198,16 +198,18 @@ in passwd(5). By default, B does not modify C The B<-h> (I) option causes B to print a usage message and exit. -=item -i +=item -i [command] The B<-i> (I) option runs the shell specified -in the L entry of the user that the command is -being run as. The command name argument given to the shell begins -with a `C<->' to tell the shell to run as a login shell. B -attempts to change to that user's home directory before running the -shell. It also initializes the environment, leaving I -and I unchanged, setting I, I, I, I, and -I, and unsetting all other environment variables. +in the L entry of the target user as a login shell. This +means that login-specific resource files such as C<.profile> or +C<.login> will be read by the shell. If a command is specified, +it is passed to the shell for execution. Otherwise, an interactive +shell is executed. B attempts to change to that user's home +directory before running the shell. It also initializes the +environment, leaving I and I unchanged, setting +I, I, I, I, and I, and unsetting +all other environment variables. =item -K @@ -289,11 +291,12 @@ I flag is disabled in I. The B<-S> (I) option causes B to read the password from the standard input instead of the terminal device. -=item -s +=item -s [command] The B<-s> (I) option runs the shell specified by the I -environment variable if it is set or the shell as specified -in L. +environment variable if it is set or the shell as specified in +L. If a command is specified, it is passed to the shell +for execution. Otherwise, an interactive shell is executed. =item -U I diff --git a/sudo_usage.h.in b/sudo_usage.h.in index 3f1de3407..70c99ed37 100644 --- a/sudo_usage.h.in +++ b/sudo_usage.h.in @@ -7,7 +7,7 @@ */ #define SUDO_USAGE1 " -h | -K | -k | -L | -V | -v" #define SUDO_USAGE2 " -l [-g groupname|#gid] [-U username] [-u username|#uid] [-g groupname|#gid] [command]" -#define SUDO_USAGE3 " [-bEHPS] @BSDAUTH_USAGE@[-C fd] @LOGINCAP_USAGE@[-g groupname|#gid] [-p prompt] [-u username|#uid] [-g groupname|#gid] [VAR=value] {-i | -s | }" +#define SUDO_USAGE3 " [-bEHPS] @BSDAUTH_USAGE@[-C fd] @LOGINCAP_USAGE@[-g groupname|#gid] [-p prompt] [-u username|#uid] [-g groupname|#gid] [VAR=value] [-i|-s] []" #define SUDO_USAGE4 " -e [-S] @BSDAUTH_USAGE@[-C fd] @LOGINCAP_USAGE@[-g groupname|#gid] [-p prompt] [-u username|#uid] file ..." #endif /* _SUDO_USAGE_H */