From cbbb73da90bac5029cbd58f4a8f148312768bc0f Mon Sep 17 00:00:00 2001 From: Ron Yorston Date: Wed, 26 Apr 2023 08:33:28 +0100 Subject: su: pass additional arguments to sh The real su allows a command file to be run, with arguments given on the command line. Similarly it allows the script run with '-c' to take arguments. In fact, any arguments can be passed to sh. Permit the same in the Windows implementation. For compatibility this requires a user name to be specified, even though we only support elevation. The user name must be 'root'. Also, ensure the '-c' command is properly quoted. Adds 144-152 bytes. (GitHub PR #317) --- loginutils/suw32.c | 37 ++++++++++++++++++++++++++++--------- 1 file changed, 28 insertions(+), 9 deletions(-) diff --git a/loginutils/suw32.c b/loginutils/suw32.c index 3500c08db..34cb175ab 100644 --- a/loginutils/suw32.c +++ b/loginutils/suw32.c @@ -16,7 +16,7 @@ //kbuild:lib-$(CONFIG_SUW32) += suw32.o //usage:#define suw32_trivial_usage -//usage: "[-c \"CMD\"]" +//usage: "[-c 'CMD'] [root [FILE ARGS | ARG0 ARGS]]" //usage:#define suw32_full_usage "\n\n" //usage: "Run shell with elevated privileges\n" //usage: "\n -c CMD Command to pass to 'sh -c'" @@ -29,12 +29,17 @@ int suw32_main(int argc UNUSED_PARAM, char **argv) { char *opt_command = NULL; SHELLEXECUTEINFO info; - char *bb_path, *cwd; + char *bb_path, *cwd, *q, *args; DECLARE_PROC_ADDR(BOOL, ShellExecuteExA, SHELLEXECUTEINFOA *); getopt32(argv, "c:", &opt_command); - if (argv[optind]) - bb_show_usage(); + argv += optind; + if (argv[0]) { + if (strcmp(argv[0], "root") != 0) { + bb_error_msg_and_die("unknown user '%s'", argv[0]); + } + ++argv; + } /* ShellExecuteEx() needs backslash as separator in UNC paths. */ bb_path = xstrdup(bb_busybox_exec_path); @@ -57,11 +62,25 @@ int suw32_main(int argc UNUSED_PARAM, char **argv) * privileges. */ cwd = xmalloc_realpath(getcwd(NULL, 0)); - info.lpParameters = - xasprintf("--busybox ash -d \"%s\" -t \"BusyBox ash (Admin)\" ", cwd); - if (opt_command) - info.lpParameters = - xasprintf("%s -s -c \"%s\"", info.lpParameters, opt_command); + q = quote_arg(cwd); + args = xasprintf("--busybox ash -d %s -t \"BusyBox ash (Admin)\"", q); + free(q); + free(cwd); + + if (opt_command) { + args = xappendword(args, "-s -c"); + q = quote_arg(opt_command); + args = xappendword(args, q); + free(q); + } + + while (*argv) { + q = quote_arg(*argv++); + args = xappendword(args, q); + free(q); + } + + info.lpParameters = args; /* info.lpDirectory = NULL; */ info.nShow = SW_SHOWNORMAL; -- cgit v1.2.3-55-g6feb