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.
* 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;
}
}
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 {
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':
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>]>
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
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>
*/
#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 */