This came up recently: https://github.com/landley/toybox/issues/117#issuecomment-465610332
And it's been on my todo list forever: if you want to run a command as an arbitrary UID/GID, it's kinda awkward to do so with sudo or su because both conventionally want to look up a name out of /etc/passwd, and will error out on a uid with no passwd entry even for root. But these days with things like containers, there's lots of interesting UIDs and GIDs that aren't active in /etc/passwd. (And then there's the whole android thing of not having an /etc/passwd and using their version of the Windows Registry instead, because keeping system information in human readable text files is too unixy or something....) So anyway, I want su -u UID and su -g GID[,gid,gid...] to work, at least for root. And I want to be able to run an arbitrary command line without necessarily having to wash it through a random command shell. And _implementing this is fairly straightforward. No the hard part is writing the help text to explain it, especially if I've kept compatibility with the original su behavior. A word on the legacy su behavior: way back when setting a user's shell in /etc/passwd to /bin/false or /dev/null was a way of preventing anybody from running commands as that user. Then su grew -s to override which shell you were running as, so this stopped working from a security standpoint. (Besides, if you were running as root you could whip up a trivial C program to do it anyway, but the point was _su_ no longer enforced it.) And it let you specify -c to pass a command line to that shell so su could "run a command as a user" instead of being interactive, so this ability is already _there_ for most users, just awkward to use. Here's the new help text I've got so far. Is it intelligible? usage: su [-lmp] [-u UID] [-g GID,...] [-s SHELL] [-c CMD] [USER [COMMAND...]] Switch user, prompting for password of new user when not run as root. With one argument, switch to USER and run user's shell from /etc/passwd. With no arguments, USER is root. If COMMAND line provided after USER, exec() it as new USER (bypasing shell). If -u or -g specified, first argument (if any) isn't USER (it's COMMAND). first argument is USER name to switch to (which must exist). Non-root users are prompted for new user's password. -s Shell to use (default is user's shell from /etc/passwd) -c Command line to pass to -s shell (ala sh -c "CMD") -l Reset environment as if new login. -u Switch to UID instead of USER -g Switch to GID (only root allowed, can be comma separated list) -p Preserve environment One other thing... I've been pondering a "contain" command for a long time that combines unshare, nsenter, chroot (really pivot_root because http://lkml.iu.edu/hypermail/linux/kernel/1310.0/02823.html), uid/gid range remapping, su, and possibly oneit or similar. (How you marshall stdin/stdout/stderr out of the container and into something the host can see is sort of a pty problem requiring a host daemon to monitor the container. And what _does_ happen to dmesg, anyway? I forget...) It's probably still worth upgrading su anyway, but there _is_ no contain-equivalent pipeline that doesn't have circular dependencies in the order the commands need to run, and then your init binary needs to do setup _in_ the new namespace which with chroot means you need a binary in the new chroot that's really all about the host, not the chroot. Static qemu application mode that can't do it's own chroot had this problem too, which is why I submitted a patch to it many moons ago... Rob P.S. https://twitter.com/__apf__/status/1098265272782184448 _______________________________________________ Toybox mailing list [email protected] http://lists.landley.net/listinfo.cgi/toybox-landley.net
