diff options
author | Stefano Brivio <sbrivio@redhat.com> | 2022-05-18 19:10:45 +0200 |
---|---|---|
committer | Stefano Brivio <sbrivio@redhat.com> | 2022-05-19 16:27:20 +0200 |
commit | a951e0b9efcbb64ca8b1d7c62c6c27a4498d21d6 (patch) | |
tree | 83c88879af000c010bed7273f7518d4fc4c235b4 /util.c | |
parent | c318ffcb4c932752cd1f48bf5d1b0268f58895bd (diff) | |
download | passt-a951e0b9efcbb64ca8b1d7c62c6c27a4498d21d6.tar passt-a951e0b9efcbb64ca8b1d7c62c6c27a4498d21d6.tar.gz passt-a951e0b9efcbb64ca8b1d7c62c6c27a4498d21d6.tar.bz2 passt-a951e0b9efcbb64ca8b1d7c62c6c27a4498d21d6.tar.lz passt-a951e0b9efcbb64ca8b1d7c62c6c27a4498d21d6.tar.xz passt-a951e0b9efcbb64ca8b1d7c62c6c27a4498d21d6.tar.zst passt-a951e0b9efcbb64ca8b1d7c62c6c27a4498d21d6.zip |
conf: Add --runas option, changing to given UID and GID if started as root
On some systems, user and group "nobody" might not be available. The
new --runas option allows to override the default "nobody" choice if
started as root.
Now that we allow this, drop the initgroups() call that was used to
add any additional groups for the given user, as that might now
grant unnecessarily broad permissions. For instance, several
distributions have a "kvm" group to allow regular user access to
/dev/kvm, and we don't need that in passt or pasta.
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
Diffstat (limited to 'util.c')
-rw-r--r-- | util.c | 52 |
1 files changed, 52 insertions, 0 deletions
@@ -33,6 +33,8 @@ #include <string.h> #include <time.h> #include <errno.h> +#include <pwd.h> +#include <grp.h> #include <linux/capability.h> @@ -533,6 +535,56 @@ void drop_caps(void) } /** + * check_root() - Check if root in init ns, exit if we can't drop to user + */ +void check_root(struct ctx *c) +{ + const char root_uid_map[] = " 0 0 4294967295"; + struct passwd *pw; + char buf[BUFSIZ]; + int fd; + + if (getuid() && geteuid()) + return; + + if ((fd = open("/proc/self/uid_map", O_RDONLY | O_CLOEXEC)) < 0) + return; + + if (read(fd, buf, BUFSIZ) != sizeof(root_uid_map) || + strncmp(buf, root_uid_map, sizeof(root_uid_map) - 1)) { + close(fd); + return; + } + + close(fd); + + if (!c->uid) { + fprintf(stderr, "Don't run as root. Changing to nobody...\n"); +#ifndef GLIBC_NO_STATIC_NSS + pw = getpwnam("nobody"); + if (!pw) { + perror("getpwnam"); + exit(EXIT_FAILURE); + } + + c->uid = pw->pw_uid; + c->gid = pw->pw_gid; +#else + (void)pw; + + /* Common value for 'nobody', not really specified */ + c->uid = c->gid = 65534; +#endif + } + + if (!setgid(c->gid) && !setuid(c->uid)) + return; + + fprintf(stderr, "Can't change user/group, exiting"); + exit(EXIT_FAILURE); +} + +/** * ns_enter() - Enter configured user (unless already joined) and network ns * @c: Execution context * |