Re: getgrouplist(3) vs. getgroups(3)



Jakub Jelinek wrote:
But, IMHO far better would be to:
static gid_t *groups;
if (!groups) {
  uid = getuid ();
  n = getgroups (0, NULL);
  if (n < 0) error_handling;
  groups = malloc (n * sizeof (gid_t));
  if (groups == NULL) error_handling;
  n = getgroups (n, groups);
  if (n < 0) error_handling;
}

I updated the patch.

Roland
Index: utilunix.c
===================================================================
RCS file: /cvsroot/mc/mc/src/utilunix.c,v
retrieving revision 1.86
diff -u -p -r1.86 utilunix.c
--- utilunix.c	27 May 2005 03:35:15 -0000	1.86
+++ utilunix.c	22 Jul 2005 09:54:53 -0000
@@ -46,124 +46,6 @@
 
 struct sigaction startup_handler;
 
-/* uid of the MC user */
-static uid_t current_user_uid = -1;
-/* List of the gids of the user */
-static GTree *current_user_gid = NULL;
-
-/* Helper function to compare 2 gids */
-static gint
-mc_gid_compare (gconstpointer v, gconstpointer v2)
-{
-    return ((GPOINTER_TO_UINT(v) > GPOINTER_TO_UINT(v2)) ? 1 :
-	    (GPOINTER_TO_UINT(v) < GPOINTER_TO_UINT(v2)) ? -1 : 0);
-}
-
-/* Helper function to delete keys of the gids tree */
-static gint
-mc_gid_destroy (gpointer key, gpointer value, gpointer data)
-{
-    (void) key;
-    (void) data;
-    g_free (value);
-    
-    return FALSE;
-}
-
-/* This function initialize global GTree with the gids of groups,
-   to which user belongs. Tree also store corresponding string 
-   with the name of the group.
-   FIXME: Do we need this names at all? If not, we can simplify
-   initialization by eliminating g_strdup's.
-*/
-void init_groups (void)
-{
-    int i;
-    struct passwd *pwd;
-    struct group *grp;
-
-    current_user_uid = getuid ();
-    pwd = getpwuid (current_user_uid);
-    g_return_if_fail (pwd != NULL);
-
-    current_user_gid = g_tree_new (mc_gid_compare);
-
-    /* Put user's primary group first. */
-    if ((grp = getgrgid (pwd->pw_gid)) != NULL) {
-	g_tree_insert (current_user_gid,
-		       GUINT_TO_POINTER ((int) grp->gr_gid),
-		       g_strdup (grp->gr_name));
-    }
-
-#ifdef HAVE_GETGROUPLIST
-    {
-	gid_t *groups = g_new (gid_t, 1);
-	int ng = 1;
-	gid_t *newgroups = NULL;
-
-	if (getgrouplist (pwd->pw_name, pwd->pw_gid, groups, &ng) == -1) {
-	    newgroups = g_new (gid_t, ng);
-	    if (newgroups != NULL) {
-		g_free (groups);
-		groups = newgroups;
-		getgrouplist (pwd->pw_name, pwd->pw_gid, groups, &ng);
-	    } else
-		ng = 1;
-	}
-
-	for (i = 0; i < ng; i++) {
-	    grp = getgrgid (groups[i]);
-	    if (grp != NULL
-		&& !g_tree_lookup (current_user_gid,
-				   GUINT_TO_POINTER ((int) grp->gr_gid))) {
-		g_tree_insert (current_user_gid,
-			       GUINT_TO_POINTER ((int) grp->gr_gid),
-			       g_strdup (grp->gr_name));
-	    }
-	}
-
-	g_free (groups);
-    }
-#else
-    setgrent ();
-    while ((grp = getgrent ()) != NULL) {
-	for (i = 0; grp->gr_mem[i]; i++) {
-	    if (!strcmp (pwd->pw_name, grp->gr_mem[i]) &&
-		!g_tree_lookup (current_user_gid,
-				GUINT_TO_POINTER ((int) grp->gr_gid))) {
-		g_tree_insert (current_user_gid,
-			       GUINT_TO_POINTER ((int) grp->gr_gid),
-			       g_strdup (grp->gr_name));
-		break;
-	    }
-	}
-    }
-    endgrent ();
-#endif
-}
-
-/* Return the index of the permissions triplet */
-int
-get_user_permissions (struct stat *buf) {
-
-    if (buf->st_uid == current_user_uid || current_user_uid == 0)
-       return 0;
-    
-    if (current_user_gid && g_tree_lookup (current_user_gid,
-					   GUINT_TO_POINTER((int) buf->st_gid)))
-       return 1;
-
-    return 2;
-}
-
-/* Completely destroys the gids tree */
-void
-destroy_groups (void)
-{
-    g_tree_traverse (current_user_gid, mc_gid_destroy, G_POST_ORDER, NULL);
-    g_tree_destroy (current_user_gid);
-}
-
 #define UID_CACHE_SIZE 200
 #define GID_CACHE_SIZE 30
 
@@ -828,4 +710,40 @@ mc_realpath (const char *path, char reso
     strcpy (resolved_path, got_path);
     return resolved_path;
 #endif	/* USE_SYSTEM_REALPATH */
+}
+
+/* Return the index of the permissions triplet */
+int
+get_user_permissions (struct stat *st) {
+    static gboolean initialized = FALSE;
+    static gid_t *groups;
+    static int ngroups;
+    static uid_t uid;
+    int i;
+
+    if (!initialized) {
+	uid = getuid ();
+	ngroups = getgroups (0, NULL);
+	if (ngroups != -1) {
+	    groups = g_new (gid_t, ngroups + 1);
+	    ngroups = getgroups (ngroups, groups);
+
+	    /* getgroups() may or may not return the effective group ID,
+	     * so we always include it at the end of the list. */
+	    if (ngroups >= 0) {
+		groups[ngroups++] = getegid();
+	    }
+	}
+	initialized = TRUE;
+    }
+
+    if (st->st_uid == uid || uid == 0)
+       return 0;
+
+    for (i = 0; i < ngroups; i++) {
+	if (st->st_gid == groups[i])
+	    return 1;
+    }
+
+    return 2;
 }


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]