From nobody Sun Feb 8 10:03:48 2026 Delivered-To: importer@patchew.org Received-SPF: none (zohomail.com: 8.43.85.245 is neither permitted nor denied by domain of lists.libvirt.org) client-ip=8.43.85.245; envelope-from=devel-bounces@lists.libvirt.org; helo=lists.libvirt.org; Authentication-Results: mx.zohomail.com; spf=none (zohomail.com: 8.43.85.245 is neither permitted nor denied by domain of lists.libvirt.org) smtp.mailfrom=devel-bounces@lists.libvirt.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.libvirt.org (lists.libvirt.org [8.43.85.245]) by mx.zohomail.com with SMTPS id 1702479708618202.78236009957425; Wed, 13 Dec 2023 07:01:48 -0800 (PST) Received: by lists.libvirt.org (Postfix, from userid 996) id 4E88E194F; Wed, 13 Dec 2023 10:01:47 -0500 (EST) Received: from lists.libvirt.org (localhost [IPv6:::1]) by lists.libvirt.org (Postfix) with ESMTP id D02631902; Wed, 13 Dec 2023 09:51:29 -0500 (EST) Received: by lists.libvirt.org (Postfix, from userid 996) id B4CCF177E; Wed, 13 Dec 2023 09:50:53 -0500 (EST) Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by lists.libvirt.org (Postfix) with ESMTPS id 0C5F417B2 for ; Wed, 13 Dec 2023 09:50:28 -0500 (EST) Received: from mimecast-mx02.redhat.com (mx-ext.redhat.com [66.187.233.73]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-363-T0ig9vewOQOb2es11p9LSQ-1; Wed, 13 Dec 2023 09:50:26 -0500 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.rdu2.redhat.com [10.11.54.4]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 298AD1C05EAB for ; Wed, 13 Dec 2023 14:50:26 +0000 (UTC) Received: from fedora.redhat.com (unknown [10.45.224.157]) by smtp.corp.redhat.com (Postfix) with ESMTP id 9D7932026D66 for ; Wed, 13 Dec 2023 14:50:25 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on lists.libvirt.org X-Spam-Level: X-Spam-Status: No, score=-0.8 required=5.0 tests=HEADER_FROM_DIFFERENT_DOMAINS, MAILING_LIST_MULTI,RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL,SPF_HELO_NONE,T_SCC_BODY_TEXT_LINE autolearn=unavailable autolearn_force=no version=3.4.4 X-MC-Unique: T0ig9vewOQOb2es11p9LSQ-1 From: =?UTF-8?q?J=C3=A1n=20Tomko?= To: devel@lists.libvirt.org Subject: [libvirt PATCHv2 7/9] util: add virGetSubUIDs Date: Wed, 13 Dec 2023 15:47:23 +0100 Message-ID: <89003e730006f7c7fcdb0a0db8a392983bd90267.1702478845.git.jtomko@redhat.com> In-Reply-To: References: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.11.54.4 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Message-ID-Hash: 6GU4FDVNUZSGDELMKTZDOPPR5N5P7EAA X-Message-ID-Hash: 6GU4FDVNUZSGDELMKTZDOPPR5N5P7EAA X-MailFrom: jtomko@redhat.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; header-match-config-1; header-match-config-2; header-match-config-3; header-match-devel.lists.libvirt.org-0; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; suspicious-header X-Mailman-Version: 3.2.2 Precedence: list List-Id: Development discussions about the libvirt library & tools Archived-At: List-Archive: List-Help: List-Post: List-Subscribe: List-Unsubscribe: Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-ZM-MESSAGEID: 1702479709065100001 A function for parsing /etc/sub[ug]id Signed-off-by: J=C3=A1n Tomko --- src/libvirt_private.syms | 2 ++ src/util/virutil.c | 70 ++++++++++++++++++++++++++++++++++++ src/util/virutil.h | 12 +++++++ tests/utiltest.c | 33 +++++++++++++++++ tests/virutiltestdata/subuid | 4 +++ 5 files changed, 121 insertions(+) create mode 100644 tests/virutiltestdata/subuid diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 553b01b8c0..20f34d72b5 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -3640,6 +3640,7 @@ virGetHostname; virGetHostnameQuiet; virGetPassword; virGetSelfLastChanged; +virGetSubIDs; virGetSystemPageSize; virGetSystemPageSizeKB; virGetUserCacheDirectory; @@ -3670,6 +3671,7 @@ virSetNonBlock; virSetSockReuseAddr; virSetUIDGID; virSetUIDGIDWithCaps; +virSubIDsFree; virUpdateSelfLastChanged; virValidateWWN; virWaitForDevices; diff --git a/src/util/virutil.c b/src/util/virutil.c index 17d65ad834..369e0bc4dc 100644 --- a/src/util/virutil.c +++ b/src/util/virutil.c @@ -738,6 +738,76 @@ virGetUserIDByName(const char *name, uid_t *uid, bool = missing_ok) return ret; } =20 +void +virSubIDsFree(virSubID **uids, size_t n) +{ + size_t i; + + for (i =3D 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 =3D NULL; + g_auto(GStrv) lines =3D NULL; + virSubID *entries =3D NULL; + size_t i =3D 0; + size_t len; + int ret =3D -1; + + *retval =3D NULL; + + if (virFileReadAll(file, BUFSIZ, &buf) < 0) + return -1; + + lines =3D g_strsplit(buf, "\n", 0); + if (!lines) + return -1; + + len =3D g_strv_length(lines); + entries =3D g_new0(virSubID, len); + + for (i =3D 0; i < len; i++) { + g_auto(GStrv) fields =3D NULL; + unsigned long ulong_id; + + fields =3D g_strsplit(lines[i], ":", 0); + if (!fields) + goto cleanup; + + if (g_strv_length(fields) !=3D 3) + break; + + if (g_ascii_isdigit(fields[0][0])) { + if (virStrToLong_ul(fields[0], NULL, 10, &ulong_id) < 0) + goto cleanup; + entries[i].id =3D ulong_id; + } else { + entries[i].idstr =3D g_strdup(fields[0]); + } + + if (virStrToLong_ul(fields[1], NULL, 10, &ulong_id) < 0) + goto cleanup; + entries[i].start =3D ulong_id; + + if (virStrToLong_ul(fields[2], NULL, 10, &ulong_id) < 0) + goto cleanup; + entries[i].range =3D ulong_id; + } + + *retval =3D g_steal_pointer(&entries); + ret =3D i; + cleanup: + if (entries) + virSubIDsFree(&entries, len); + return ret; +} + /* Try to match a user id based on `user`. The default behavior is to parse * `user` first as a user name and then as a user id. However if `user` * contains a leading '+', the rest of the string is always parsed as a ui= d. diff --git a/src/util/virutil.h b/src/util/virutil.h index ab8511bf8d..3bac15d02b 100644 --- a/src/util/virutil.h +++ b/src/util/virutil.h @@ -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, diff --git a/tests/utiltest.c b/tests/utiltest.c index 5930557c08..b30bfbed70 100644 --- a/tests/utiltest.c +++ b/tests/utiltest.c @@ -377,6 +377,38 @@ testKernelCmdlineMatchParam(const void *data G_GNUC_UN= USED) } =20 =20 +static int +testGetSubIDs(const void *data G_GNUC_UNUSED) +{ + g_autofree char *subuid_file =3D g_strdup_printf("%s/virutiltestdata/s= ubuid", abs_srcdir); + virSubID *subids =3D NULL; + int len =3D 0; + int ret =3D -1; + + if ((len =3D virGetSubIDs(&subids, subuid_file)) < 0) { + VIR_TEST_DEBUG("virGetSubIDs failed"); + goto cleanup; + } + + if (len !=3D 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 =3D 0; + + cleanup: + if (len >=3D 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); =20 return result =3D=3D 0 ? EXIT_SUCCESS : EXIT_FAILURE; } diff --git a/tests/virutiltestdata/subuid b/tests/virutiltestdata/subuid new file mode 100644 index 0000000000..c873c0e3bf --- /dev/null +++ b/tests/virutiltestdata/subuid @@ -0,0 +1,4 @@ +joe:100000:65535 +bob:300000:65535 +1024:400000:65535 +alice:200000:65535 --=20 2.42.0 _______________________________________________ Devel mailing list -- devel@lists.libvirt.org To unsubscribe send an email to devel-leave@lists.libvirt.org