diff --git a/src/lxc/utils.c b/src/lxc/utils.c index b85383a42..ff02bba96 100644 --- a/src/lxc/utils.c +++ b/src/lxc/utils.c @@ -1353,19 +1353,27 @@ int lxc_preserve_ns(const int pid, const char *ns) int lxc_switch_uid_gid(uid_t uid, gid_t gid) { - if (setgid(gid) < 0) { - SYSERROR("Failed to switch to gid %d.", gid); - return -errno; - } - NOTICE("Switched to gid %d.", gid); + int ret = 0; - if (setuid(uid) < 0) { - SYSERROR("Failed to switch to uid %d.", uid); - return -errno; + if (gid != LXC_INVALID_GID) { + ret = setgid(gid); + if (ret < 0) { + SYSERROR("Failed to switch to gid %d", gid); + return -1; + } + NOTICE("Switched to gid %d", gid); } - NOTICE("Switched to uid %d.", uid); - return 0; + if (uid != LXC_INVALID_UID) { + ret = setuid(uid); + if (ret < 0) { + SYSERROR("Failed to switch to uid %d", uid); + return -1; + } + NOTICE("Switched to uid %d", uid); + } + + return ret; } /* Simple covenience function which enables uniform logging. */ diff --git a/src/lxc/utils.h b/src/lxc/utils.h index 51cfe4c85..947b15e16 100644 --- a/src/lxc/utils.h +++ b/src/lxc/utils.h @@ -358,7 +358,9 @@ extern int lxc_preserve_ns(const int pid, const char *ns); /* Check whether a signal is blocked by a process. */ extern bool task_blocks_signal(pid_t pid, int signal); -/* Switch to a new uid and gid. */ +/* Switch to a new uid and gid. + * If LXC_INVALID_{G,U}ID is passed then the set{g,u}id() will not be called. + */ extern int lxc_switch_uid_gid(uid_t uid, gid_t gid); extern int lxc_setgroups(int size, gid_t list[]);