diff options
author | David Gibson <david@gibson.dropbear.id.au> | 2022-09-12 22:24:00 +1000 |
---|---|---|
committer | Stefano Brivio <sbrivio@redhat.com> | 2022-09-13 05:31:51 +0200 |
commit | 10c63477476acdd5cbe6f3ac13dc637e80d0104b (patch) | |
tree | 82a8d9240f34d4d55cb7c23ba7717adb16f71eaf /util.c | |
parent | 7330ae3abfba9722c04e6c52ae6222de47016834 (diff) | |
download | passt-10c63477476acdd5cbe6f3ac13dc637e80d0104b.tar passt-10c63477476acdd5cbe6f3ac13dc637e80d0104b.tar.gz passt-10c63477476acdd5cbe6f3ac13dc637e80d0104b.tar.bz2 passt-10c63477476acdd5cbe6f3ac13dc637e80d0104b.tar.lz passt-10c63477476acdd5cbe6f3ac13dc637e80d0104b.tar.xz passt-10c63477476acdd5cbe6f3ac13dc637e80d0104b.tar.zst passt-10c63477476acdd5cbe6f3ac13dc637e80d0104b.zip |
Split checking for root from dropping root privilege
check_root() both checks to see if we are root (in the init namespace),
and if we are drops to an unprivileged user. To make future cleanups
simpler, split the checking for root (now in check_root()) from the actual
dropping of privilege (now in drop_root()).
Note that this does slightly alter semantics. Previously we would only
setuid() if we were originally root (in the init namespace). Now we will
always setuid() and setgid(), though it won't actually change anything if
we weren't privileged to begin with. This also means that we will now
always attempt to switch to the user specified with --runas, even if we
aren't (init namespace) root to begin with. Obviously this will fail with
an error if we weren't privileged to start with. --help and the man page
are updated accordingly.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Diffstat (limited to 'util.c')
-rw-r--r-- | util.c | 29 |
1 files changed, 26 insertions, 3 deletions
@@ -492,7 +492,13 @@ void check_root(uid_t *uid, gid_t *gid) char buf[BUFSIZ]; int fd; - if (getuid() && geteuid()) + if (!*uid) + *uid = geteuid(); + + if (!*gid) + *gid = getegid(); + + if (*uid) return; if ((fd = open("/proc/self/uid_map", O_RDONLY | O_CLOEXEC)) < 0) @@ -524,11 +530,28 @@ void check_root(uid_t *uid, gid_t *gid) *uid = *gid = 65534; #endif } +} + +/** + * drop_root() - Switch to given UID and GID + * @uid: User ID to switch to + * @gid: Group ID to switch to + */ +void drop_root(uid_t uid, gid_t gid) +{ + if (setgroups(0, NULL)) { + /* If we don't start with CAP_SETGID, this will EPERM */ + if (errno != EPERM) { + err("Can't drop supplementary groups: %s", + strerror(errno)); + exit(EXIT_FAILURE); + } + } - if (!setgroups(0, NULL) && !setgid(*gid) && !setuid(*uid)) + if (!setgid(gid) && !setuid(uid)) return; - fprintf(stderr, "Can't change user/group, exiting"); + err("Can't change user/group, exiting"); exit(EXIT_FAILURE); } |