From 5a9fb75c653eb65d249f5158666029a0bb0f8137 Mon Sep 17 00:00:00 2001 From: phoebos Date: Mon, 9 May 2022 17:01:41 +0100 Subject: [PATCH] su: support numeric UIDs with a -n flag --- loginutils/su.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/loginutils/su.c b/loginutils/su.c index 6efe1981a..51c6d9885 100644 --- a/loginutils/su.c +++ b/loginutils/su.c @@ -35,10 +35,11 @@ //kbuild:lib-$(CONFIG_SU) += su.o //usage:#define su_trivial_usage -//usage: "[-lmp] [-s SH] [-] [USER [FILE ARGS | -c 'CMD' [ARG0 ARGS]]]" +//usage: "[-lnmp] [-s SH] [-] [USER [FILE ARGS | -c 'CMD' [ARG0 ARGS]]]" //usage:#define su_full_usage "\n\n" //usage: "Run shell under USER (by default, root)\n" //usage: "\n -,-l Clear environment, go to home dir, run shell as login shell" +//usage: "\n -n Interpret USER as numeric ID" //usage: "\n -p,-m Do not set new $HOME, $SHELL, $USER, $LOGNAME" //usage: "\n -c CMD Command to pass to 'sh -c'" //usage: "\n -s SH Shell to use instead of user's default" @@ -69,6 +70,7 @@ static int restricted_shell(const char *shell) #define SU_OPT_mp (3) #define SU_OPT_l (4) +#define SU_OPT_n (32) int su_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; int su_main(int argc UNUSED_PARAM, char **argv) @@ -91,7 +93,7 @@ int su_main(int argc UNUSED_PARAM, char **argv) * ARGS starting with dash will be treated as su options, * not passed to shell. (Tested on util-linux 2.28). */ - flags = getopt32(argv, "mplc:s:", &opt_command, &opt_shell); + flags = getopt32(argv, "mplc:s:n", &opt_command, &opt_shell); argv += optind; if (argv[0] && LONE_DASH(argv[0])) { @@ -103,6 +105,8 @@ int su_main(int argc UNUSED_PARAM, char **argv) if (argv[0]) { opt_username = argv[0]; argv++; + } else if (flags & SU_OPT_n) { + opt_username = "0"; } tty = xmalloc_ttyname(STDIN_FILENO); @@ -126,7 +130,14 @@ int su_main(int argc UNUSED_PARAM, char **argv) openlog(applet_name, 0, LOG_AUTH); } - pw = xgetpwnam(opt_username); + if (flags & SU_OPT_n) { + unsigned long uid = bb_strtoul(opt_username, NULL, 10); + if (uid == ULLONG_MAX) + bb_error_msg_and_die("invalid uid %s", opt_username); + pw = xgetpwuid((uid_t)uid); + } else { + pw = xgetpwnam(opt_username); + } r = 1; if (cur_uid != 0) -- 2.36.1