Since introduction of the DAC security driver we've documented that seclabels with a leading + can be used with numerical uid. This would not work though with the rest of libvirt if the uid was not actually used in the system as we'd fail when trying to get a list of supplementary groups for the given uid. Since a uid without entry in /etc/passwd (or other user database) will not have any supplementary groups we can treat the failure to obtain them as such. This patch modifies virGetGroupList to not report the error for missing users and makes it return an empty list or just the group specified in @gid. All callers will grand less permissions in case of failure and thus this change is safe. --- src/util/virutil.c | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/src/util/virutil.c b/src/util/virutil.c index 392091b..60da17b 100644 --- a/src/util/virutil.c +++ b/src/util/virutil.c @@ -1120,29 +1120,30 @@ virGetGroupID(const char *group, gid_t *gid) /* Compute the list of primary and supplementary groups associated * with @uid, and including @gid in the list (unless it is -1), - * storing a malloc'd result into @list. Return the size of the list - * on success, or -1 on failure with error reported and errno set. May - * not be called between fork and exec. */ + * storing a malloc'd result into @list. If uid is -1 or doesn't exist in the + * system database querying of the supplementary groups is skipped. + * + * Returns the size of the list on success, or -1 on failure with error + * reported and errno set. May not be called between fork and exec. + * */ int virGetGroupList(uid_t uid, gid_t gid, gid_t **list) { - int ret = -1; + int ret = 0; char *user = NULL; gid_t primary; *list = NULL; - if (uid == (uid_t)-1) - return 0; - if (virGetUserEnt(uid, &user, &primary, NULL, NULL, false) < 0) - return -1; - - ret = mgetgroups(user, primary, list); - if (ret < 0) { - sa_assert(!*list); - virReportSystemError(errno, - _("cannot get group list for '%s'"), user); - goto cleanup; + /* invalid users have no supplementary groups */ + if (uid != (uid_t)-1 && + virGetUserEnt(uid, &user, &primary, NULL, NULL, true) >= 0) { + if ((ret = mgetgroups(user, primary, list)) < 0) { + virReportSystemError(errno, + _("cannot get group list for '%s'"), user); + ret = -1; + goto cleanup; + } } if (gid != (gid_t)-1) { -- 2.8.3 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list