diff options
author | Ron Yorston <rmy@pobox.com> | 2024-08-04 12:36:09 +0100 |
---|---|---|
committer | Ron Yorston <rmy@pobox.com> | 2024-08-04 12:36:09 +0100 |
commit | 5eb14d55da843927f792e35dbf54079579f0d701 (patch) | |
tree | 98116bdbfbe3e990f98d06751d569d647979d040 | |
parent | fb959dd3f29c2d0655e01147f7b0b9bb2dab4223 (diff) | |
download | busybox-w32-5eb14d55da843927f792e35dbf54079579f0d701.tar.gz busybox-w32-5eb14d55da843927f792e35dbf54079579f0d701.tar.bz2 busybox-w32-5eb14d55da843927f792e35dbf54079579f0d701.zip |
su: allow an alternative shell to be selected
Add the '-s' option to allow an alternative shell to be given.
No PATH search is performed for the shell, so an absolute or
relative path to a suitable executable must be provided.
Certain features are only available when the built-in shell is
used:
- The '-N' option, which allows the console window to remain open
when the shell exits.
- The fix which allows the current directory to be retained despite
the efforts of ShellExecute() to change it.
- The friendly message in the console title.
Adds 128 bytes.
(GitHub issue #438)
-rw-r--r-- | loginutils/suw32.c | 49 |
1 files changed, 30 insertions, 19 deletions
diff --git a/loginutils/suw32.c b/loginutils/suw32.c index a0afe5bb7..cbe727969 100644 --- a/loginutils/suw32.c +++ b/loginutils/suw32.c | |||
@@ -16,22 +16,24 @@ | |||
16 | //kbuild:lib-$(CONFIG_SUW32) += suw32.o | 16 | //kbuild:lib-$(CONFIG_SUW32) += suw32.o |
17 | 17 | ||
18 | //usage:#define suw32_trivial_usage | 18 | //usage:#define suw32_trivial_usage |
19 | //usage: "[-NW] [root]\n" | 19 | //usage: "[-W] [-N|-s SHELL] [root]\n" |
20 | //usage: "or: su [-NW] -c CMD_STRING [[--] root [ARG0 [ARG...]]]\n" | 20 | //usage: "or: su [-W] [-N|-s SHELL] -c CMD_STRING [[--] root [ARG0 [ARG...]]]\n" |
21 | //usage: "or: su [-NW] [--] root [arbitrary sh arguments]" | 21 | //usage: "or: su [-W] [-N|-s SHELL] [--] root [arbitrary sh arguments]" |
22 | //usage:#define suw32_full_usage "\n\n" | 22 | //usage:#define suw32_full_usage "\n\n" |
23 | //usage: "Run shell with elevated privileges\n" | 23 | //usage: "Run shell with elevated privileges\n" |
24 | //usage: "\n -c CMD Command to pass to 'sh -c'" | 24 | //usage: "\n -c CMD Command to pass to 'sh -c'" |
25 | //usage: "\n -N Don't close console when shell exits" | 25 | //usage: "\n -s SHELL Use specified shell" |
26 | //usage: "\n -W Wait for shell exit code" | 26 | //usage: "\n -N Don't close console when shell exits" |
27 | //usage: "\n -W Wait for shell exit code" | ||
27 | 28 | ||
28 | #include "libbb.h" | 29 | #include "libbb.h" |
29 | #include "lazyload.h" | 30 | #include "lazyload.h" |
30 | 31 | ||
31 | enum { | 32 | enum { |
32 | OPT_c = (1 << 0), | 33 | OPT_c = (1 << 0), |
33 | OPT_N = (1 << 1), | 34 | OPT_s = (1 << 1), |
34 | OPT_W = (1 << 2) | 35 | OPT_N = (1 << 2), |
36 | OPT_W = (1 << 3) | ||
35 | }; | 37 | }; |
36 | 38 | ||
37 | int suw32_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 39 | int suw32_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
@@ -40,6 +42,7 @@ int suw32_main(int argc UNUSED_PARAM, char **argv) | |||
40 | int ret = 0; | 42 | int ret = 0; |
41 | unsigned opt; | 43 | unsigned opt; |
42 | char *opt_command = NULL; | 44 | char *opt_command = NULL; |
45 | char *opt_shell = NULL; | ||
43 | SHELLEXECUTEINFO info; | 46 | SHELLEXECUTEINFO info; |
44 | char *bb_path, *cwd, *realcwd, *q, *args; | 47 | char *bb_path, *cwd, *realcwd, *q, *args; |
45 | DECLARE_PROC_ADDR(BOOL, ShellExecuteExA, SHELLEXECUTEINFOA *); | 48 | DECLARE_PROC_ADDR(BOOL, ShellExecuteExA, SHELLEXECUTEINFOA *); |
@@ -54,7 +57,7 @@ int suw32_main(int argc UNUSED_PARAM, char **argv) | |||
54 | } | 57 | } |
55 | #endif | 58 | #endif |
56 | 59 | ||
57 | opt = getopt32(argv, "c:NW", &opt_command); | 60 | opt = getopt32(argv, "^c:s:NW" "\0" "s--N:N--s", &opt_command, &opt_shell); |
58 | argv += optind; | 61 | argv += optind; |
59 | if (argv[0]) { | 62 | if (argv[0]) { |
60 | if (strcmp(argv[0], "root") != 0) { | 63 | if (strcmp(argv[0], "root") != 0) { |
@@ -64,7 +67,15 @@ int suw32_main(int argc UNUSED_PARAM, char **argv) | |||
64 | } | 67 | } |
65 | 68 | ||
66 | /* ShellExecuteEx() needs backslash as separator in UNC paths. */ | 69 | /* ShellExecuteEx() needs backslash as separator in UNC paths. */ |
67 | bb_path = xstrdup(bb_busybox_exec_path); | 70 | if (opt_shell) { |
71 | bb_path = file_is_win32_exe(opt_shell); | ||
72 | if (!bb_path) | ||
73 | bb_error_msg_and_die("%s: Not found", opt_shell); | ||
74 | args = NULL; | ||
75 | } else { | ||
76 | bb_path = xstrdup(bb_busybox_exec_path); | ||
77 | args = xasprintf("--busybox ash -t \"BusyBox ash (Admin)\""); | ||
78 | } | ||
68 | slash_to_bs(bb_path); | 79 | slash_to_bs(bb_path); |
69 | 80 | ||
70 | memset(&info, 0, sizeof(SHELLEXECUTEINFO)); | 81 | memset(&info, 0, sizeof(SHELLEXECUTEINFO)); |
@@ -85,15 +96,15 @@ int suw32_main(int argc UNUSED_PARAM, char **argv) | |||
85 | * a network share it may not be available once we have elevated | 96 | * a network share it may not be available once we have elevated |
86 | * privileges. | 97 | * privileges. |
87 | */ | 98 | */ |
88 | args = xasprintf("--busybox ash -t \"BusyBox ash (Admin)\""); | 99 | if (opt_shell == NULL) { |
89 | 100 | cwd = getcwd(NULL, 0); | |
90 | cwd = getcwd(NULL, 0); | 101 | realcwd = cwd ? xmalloc_realpath(cwd) : NULL; |
91 | realcwd = cwd ? xmalloc_realpath(cwd) : NULL; | 102 | if (realcwd || cwd) { |
92 | if (realcwd || cwd) { | 103 | args = xappendword(args, "-d"); |
93 | args = xappendword(args, "-d"); | 104 | q = quote_arg(realcwd ?: cwd); |
94 | q = quote_arg(realcwd ?: cwd); | 105 | args = xappendword(args, q); |
95 | args = xappendword(args, q); | 106 | free(q); |
96 | free(q); | 107 | } |
97 | } | 108 | } |
98 | 109 | ||
99 | if (opt & OPT_N) | 110 | if (opt & OPT_N) |