]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
util: use getgrouplist() directly instead of mgetgroups
authorDaniel P. Berrangé <berrange@redhat.com>
Fri, 17 Jan 2020 12:33:37 +0000 (12:33 +0000)
committerDaniel P. Berrangé <berrange@redhat.com>
Wed, 29 Jan 2020 14:51:39 +0000 (14:51 +0000)
The mgetgroups function is a GNULIB custom wrapper around
getgrouplist(). This implements a simplified version of
that code directly.

Reviewed-by: Pavel Hrdina <phrdina@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
src/internal.h
src/util/virutil.c

index 4b0286e237e0c3258e16a4574e5abc0e6b5feeb1..4a63984cecd484a095850a55d16dfcdf5dd4cc81 100644 (file)
     _Pragma ("GCC diagnostic push") \
     _Pragma ("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
 
+#define VIR_WARNINGS_NO_POINTER_SIGN \
+    _Pragma ("GCC diagnostic push") \
+    _Pragma ("GCC diagnostic ignored \"-Wpointer-sign\"")
+
 #if HAVE_SUGGEST_ATTRIBUTE_FORMAT
 # define VIR_WARNINGS_NO_PRINTF \
     _Pragma ("GCC diagnostic push") \
index 87ca16c088ceb496743240ba223c9bc52aa910d7..77460c9577e16effe085b2a62dc3f18608cdb759 100644 (file)
@@ -66,7 +66,6 @@
 # include <sys/un.h>
 #endif
 
-#include "mgetgroups.h"
 #include "virerror.h"
 #include "virlog.h"
 #include "virbuffer.h"
@@ -980,6 +979,11 @@ virDoesGroupExist(const char *name)
 }
 
 
+
+/* Work around an incompatibility of OS X 10.11: getgrouplist
+   accepts int *, not gid_t *, and int and gid_t differ in sign.  */
+VIR_WARNINGS_NO_POINTER_SIGN
+
 /* 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. If uid is -1 or doesn't exist in the
@@ -1000,11 +1004,28 @@ virGetGroupList(uid_t uid, gid_t gid, gid_t **list)
     /* 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;
+        int nallocgrps = 10;
+        gid_t *grps = g_new(gid_t, nallocgrps);
+
+        while (1) {
+            int nprevallocgrps = nallocgrps;
+            int rv;
+
+            rv = getgrouplist(user, primary, grps, &nallocgrps);
+
+            /* Some systems (like Darwin) have a bug where they
+               never increase max_n_groups.  */
+            if (rv < 0 && nprevallocgrps == nallocgrps)
+                nallocgrps *= 2;
+
+            /* either shrinks to actual size, or enlarges to new size */
+            grps = g_renew(gid_t, grps, nallocgrps);
+
+            if (rv >= 0) {
+                ret = rv;
+                *list = grps;
+                break;
+            }
         }
     }
 
@@ -1029,6 +1050,8 @@ virGetGroupList(uid_t uid, gid_t gid, gid_t **list)
     return ret;
 }
 
+VIR_WARNINGS_RESET
+
 
 /* Set the real and effective uid and gid to the given values, as well
  * as all the supplementary groups, so that the process has all the