mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-21 21:25:25 +00:00
util: add virGetSubUIDs
A function for parsing /etc/sub[ug]id Signed-off-by: Ján Tomko <jtomko@redhat.com> Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
This commit is contained in:
parent
42edb10f17
commit
2ef4be0a3e
@ -3641,6 +3641,7 @@ virGetHostname;
|
||||
virGetHostnameQuiet;
|
||||
virGetPassword;
|
||||
virGetSelfLastChanged;
|
||||
virGetSubIDs;
|
||||
virGetSystemPageSize;
|
||||
virGetSystemPageSizeKB;
|
||||
virGetUserCacheDirectory;
|
||||
@ -3671,6 +3672,7 @@ virSetNonBlock;
|
||||
virSetSockReuseAddr;
|
||||
virSetUIDGID;
|
||||
virSetUIDGIDWithCaps;
|
||||
virSubIDsFree;
|
||||
virUpdateSelfLastChanged;
|
||||
virValidateWWN;
|
||||
virWaitForDevices;
|
||||
|
@ -1086,6 +1086,76 @@ virGetGroupName(gid_t gid G_GNUC_UNUSED)
|
||||
}
|
||||
#endif /* WITH_GETPWUID_R */
|
||||
|
||||
void
|
||||
virSubIDsFree(virSubID **uids, size_t n)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
if ((*uids)[i].idstr)
|
||||
g_free((*uids)[i].idstr);
|
||||
}
|
||||
g_clear_pointer(uids, g_free);
|
||||
}
|
||||
|
||||
int
|
||||
virGetSubIDs(virSubID **retval, const char *file)
|
||||
{
|
||||
g_autofree char *buf = NULL;
|
||||
g_auto(GStrv) lines = NULL;
|
||||
virSubID *entries = NULL;
|
||||
size_t i = 0;
|
||||
size_t len;
|
||||
int ret = -1;
|
||||
|
||||
*retval = NULL;
|
||||
|
||||
if (virFileReadAll(file, BUFSIZ, &buf) < 0)
|
||||
return -1;
|
||||
|
||||
lines = g_strsplit(buf, "\n", 0);
|
||||
if (!lines)
|
||||
return -1;
|
||||
|
||||
len = g_strv_length(lines);
|
||||
entries = g_new0(virSubID, len);
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
g_auto(GStrv) fields = NULL;
|
||||
unsigned long ulong_id;
|
||||
|
||||
fields = g_strsplit(lines[i], ":", 0);
|
||||
if (!fields)
|
||||
goto cleanup;
|
||||
|
||||
if (g_strv_length(fields) != 3)
|
||||
break;
|
||||
|
||||
if (g_ascii_isdigit(fields[0][0])) {
|
||||
if (virStrToLong_ul(fields[0], NULL, 10, &ulong_id) < 0)
|
||||
goto cleanup;
|
||||
entries[i].id = ulong_id;
|
||||
} else {
|
||||
entries[i].idstr = g_strdup(fields[0]);
|
||||
}
|
||||
|
||||
if (virStrToLong_ul(fields[1], NULL, 10, &ulong_id) < 0)
|
||||
goto cleanup;
|
||||
entries[i].start = ulong_id;
|
||||
|
||||
if (virStrToLong_ul(fields[2], NULL, 10, &ulong_id) < 0)
|
||||
goto cleanup;
|
||||
entries[i].range = ulong_id;
|
||||
}
|
||||
|
||||
*retval = g_steal_pointer(&entries);
|
||||
ret = i;
|
||||
cleanup:
|
||||
if (entries)
|
||||
virSubIDsFree(&entries, len);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if WITH_CAPNG
|
||||
/* Set the real and effective uid and gid to the given values, while
|
||||
* maintaining the capabilities indicated by bits in @capBits. Return
|
||||
|
@ -102,6 +102,18 @@ char *virGetUserName(uid_t uid) G_NO_INLINE;
|
||||
char *virGetGroupName(gid_t gid) G_NO_INLINE;
|
||||
int virGetGroupList(uid_t uid, gid_t group, gid_t **groups)
|
||||
ATTRIBUTE_NONNULL(3);
|
||||
|
||||
typedef struct _virSubID {
|
||||
uid_t id;
|
||||
char *idstr;
|
||||
uid_t start;
|
||||
uid_t range;
|
||||
} virSubID;
|
||||
|
||||
int virGetSubIDs(virSubID **ret, const char *file);
|
||||
void virSubIDsFree(virSubID **uids, size_t n);
|
||||
|
||||
|
||||
int virGetUserID(const char *name,
|
||||
uid_t *uid) G_GNUC_WARN_UNUSED_RESULT;
|
||||
int virGetGroupID(const char *name,
|
||||
|
@ -377,6 +377,38 @@ testKernelCmdlineMatchParam(const void *data G_GNUC_UNUSED)
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
testGetSubIDs(const void *data G_GNUC_UNUSED)
|
||||
{
|
||||
g_autofree char *subuid_file = g_strdup_printf("%s/virutiltestdata/subuid", abs_srcdir);
|
||||
virSubID *subids = NULL;
|
||||
int len = 0;
|
||||
int ret = -1;
|
||||
|
||||
if ((len = virGetSubIDs(&subids, subuid_file)) < 0) {
|
||||
VIR_TEST_DEBUG("virGetSubIDs failed");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (len != 4) {
|
||||
VIR_TEST_DEBUG("virGetSubIDs returned %d (expected 4)", len);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (STRNEQ(subids[0].idstr, "joe")) {
|
||||
VIR_TEST_DEBUG("virGetSubIDs returned wrong name for entry 0: '%s'", NULLSTR(subids[0].idstr));
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
|
||||
cleanup:
|
||||
if (len >= 0)
|
||||
virSubIDsFree(&subids, len);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
mymain(void)
|
||||
{
|
||||
@ -400,6 +432,7 @@ mymain(void)
|
||||
DO_TEST(OverflowCheckMacro);
|
||||
DO_TEST(KernelCmdlineNextParam);
|
||||
DO_TEST(KernelCmdlineMatchParam);
|
||||
DO_TEST(GetSubIDs);
|
||||
|
||||
return result == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
|
||||
}
|
||||
|
4
tests/virutiltestdata/subuid
Normal file
4
tests/virutiltestdata/subuid
Normal file
@ -0,0 +1,4 @@
|
||||
joe:100000:65535
|
||||
bob:300000:65535
|
||||
1024:400000:65535
|
||||
alice:200000:65535
|
Loading…
Reference in New Issue
Block a user