]> granicus.if.org Git - sudo/commitdiff
The -i and -s flags can now take an optional command.
authorTodd C. Miller <Todd.Miller@courtesan.com>
Mon, 3 Dec 2007 16:36:49 +0000 (16:36 +0000)
committerTodd C. Miller <Todd.Miller@courtesan.com>
Mon, 3 Dec 2007 16:36:49 +0000 (16:36 +0000)
WHATSNEW
sudo.c
sudo.pod
sudo_usage.h.in

index 45c91131867c1e21f00a3b2a08682ac22b830e95..1bb4378db9750573d0731064c24e278c23dcfc7b 100644 (file)
--- 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 e174ff8d3fbb96322b95d153261eeab1ce304a4d..85d1d550a3367a09f83e9d1fa95f8853009120e7 100644 (file)
--- 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':
index b6e060266c325c64a461f4474c00549924d40871..bc05b5f2ecc4de39e03cdc0d96536629dc5034f8 100644 (file)
--- a/sudo.pod
+++ b/sudo.pod
@@ -35,8 +35,8 @@ S<[B<-u> I<username>|I<#uid>]> [I<command>]
 
 B<sudo> [B<-bEHPS>] S<[B<-a> I<auth_type>]> S<[B<-C> I<fd>]>
 S<[B<-c> I<class>|I<->]> S<[B<-g> I<groupname>|I<#gid>]> S<[B<-p> I<prompt>]>
-S<[B<-u> I<username>|I<#uid>]> S<[B<VAR>=I<value>]>
-S<{B<-i> | B<-s> | I<command>}>
+S<[B<-u> I<username>|I<#uid>]> S<[B<VAR>=I<value>]> [S<{B<-i> | B<-s>]
+[<I<command>}>]
 
 B<sudoedit> [B<-S>] S<[B<-a> I<auth_type>]> S<[B<-C> I<fd>]>
 S<[B<-c> I<class>|I<->]> S<[B<-g> I<groupname>|I<#gid>]> S<[B<-p> I<prompt>]>
@@ -198,16 +198,18 @@ in passwd(5).  By default, B<sudo> does not modify C<HOME>
 
 The B<-h> (I<help>) option causes B<sudo> to print a usage message and exit.
 
-=item -i
+=item -i [command]
 
 The B<-i> (I<simulate initial login>) option runs the shell specified
-in the L<passwd(5)> 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<sudo>
-attempts to change to that user's home directory before running the
-shell.  It also initializes the environment, leaving I<DISPLAY>
-and I<TERM> unchanged, setting I<HOME>, I<SHELL>, I<USER>, I<LOGNAME>, and
-I<PATH>, and unsetting all other environment variables.
+in the L<passwd(5)> 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<sudo> attempts to change to that user's home
+directory before running the shell.  It also initializes the
+environment, leaving I<DISPLAY> and I<TERM> unchanged, setting
+I<HOME>, I<SHELL>, I<USER>, I<LOGNAME>, and I<PATH>, and unsetting
+all other environment variables.
 
 =item -K
 
@@ -289,11 +291,12 @@ I<passprompt_override> flag is disabled in I<sudoers>.
 The B<-S> (I<stdin>) option causes B<sudo> to read the password from
 the standard input instead of the terminal device.
 
-=item -s
+=item -s [command]
 
 The B<-s> (I<shell>) option runs the shell specified by the I<SHELL>
-environment variable if it is set or the shell as specified
-in L<passwd(5)>.
+environment variable if it is set or the shell as specified in
+L<passwd(5)>.  If a command is specified, it is passed to the shell
+for execution.  Otherwise, an interactive shell is executed.
 
 =item -U I<user>
 
index 3f1de3407815465ef5ab761b37ce35d019f978e0..70c99ed37b4df38656141cdebad00875818b17de 100644 (file)
@@ -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 | <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] [<command>]"
 #define SUDO_USAGE4 " -e [-S] @BSDAUTH_USAGE@[-C fd] @LOGINCAP_USAGE@[-g groupname|#gid] [-p prompt] [-u username|#uid] file ..."
 
 #endif /* _SUDO_USAGE_H */