* include/rpc/pmap_prot.h: Mark all functions as hidden.
[platform/upstream/glibc.git] / nscd / nscd_initgroups.c
index ea32ab6..3d82275 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2004 Free Software Foundation, Inc.
+/* Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2004.
 
 #include "nscd_proto.h"
 
 
-libc_locked_map_ptr (map_handle);
-/* Note that we only free the structure if necessary.  The memory
-   mapping is not removed since it is not visible to the malloc
-   handling.  */
-libc_freeres_fn (gr_map_free)
-{
-  if (map_handle.mapped != NO_MAPPING)
-    free (map_handle.mapped);
-}
+/* We use the same mapping as in nscd_getgr.   */
+libc_locked_map_ptr (extern, __gr_map_handle) attribute_hidden;
 
 
 int
@@ -50,7 +43,7 @@ __nscd_getgrouplist (const char *user, gid_t group, long int *size,
   /* If the mapping is available, try to search there instead of
      communicating with the nscd.  */
   struct mapped_database *mapped;
-  mapped = __nscd_get_map_ref (GETFDGR, "group", &map_handle, &gc_cycle);
+  mapped = __nscd_get_map_ref (GETFDGR, "group", &__gr_map_handle, &gc_cycle);
 
  retry:;
   const initgr_response_header *initgr_resp = NULL;
@@ -81,8 +74,11 @@ __nscd_getgrouplist (const char *user, gid_t group, long int *size,
       sock = __nscd_open_socket (user, userlen, INITGROUPS, &initgr_resp_mem,
                                 sizeof (initgr_resp_mem));
       if (sock == -1)
-       /* nscd not running or wrong version or hosts caching disabled.  */
-       __nss_not_use_nscd_group = 1;
+       {
+         /* nscd not running or wrong version.  */
+         __nss_not_use_nscd_group = 1;
+         goto out;
+       }
 
       initgr_resp = &initgr_resp_mem;
     }
@@ -95,6 +91,7 @@ __nscd_getgrouplist (const char *user, gid_t group, long int *size,
         doesn't use memcpy but instead copies each array element one
         by one.  */
       assert (sizeof (int32_t) == sizeof (gid_t));
+      assert (initgr_resp->ngrps > 0);
 
       /* Make sure we have enough room.  We always count GROUP in even
         though we might not end up adding it.  */
@@ -104,7 +101,7 @@ __nscd_getgrouplist (const char *user, gid_t group, long int *size,
                                 (initgr_resp->ngrps + 1) * sizeof (gid_t));
          if (newp == NULL)
            /* We cannot increase the buffer size.  */
-           goto out;
+           goto out_close;
 
          *groupsp = newp;
          *size = initgr_resp->ngrps + 1;
@@ -113,9 +110,8 @@ __nscd_getgrouplist (const char *user, gid_t group, long int *size,
       if (respdata == NULL)
        {
          /* Read the data from the socket.  */
-         if ((size_t) TEMP_FAILURE_RETRY (__read (sock, *groupsp,
-                                                  initgr_resp->ngrps
-                                                  * sizeof (gid_t)))
+         if ((size_t) __readall (sock, *groupsp, initgr_resp->ngrps
+                                                 * sizeof (gid_t))
              == initgr_resp->ngrps * sizeof (gid_t))
            retval = initgr_resp->ngrps;
        }
@@ -125,27 +121,35 @@ __nscd_getgrouplist (const char *user, gid_t group, long int *size,
          retval = initgr_resp->ngrps;
          memcpy (*groupsp, respdata, retval * sizeof (gid_t));
        }
-
-      /* Check whether GROUP is part of the mix.  If not, add it.  */
-      if (retval >= 0)
-       {
-         int cnt;
-         for (cnt = 0; cnt < retval; ++cnt)
-           if ((*groupsp)[cnt] == group)
-             break;
-
-         if (cnt == retval)
-           (*groupsp)[retval++] = group;
-       }
     }
   else
     {
-      /* The `errno' to some value != ERANGE.  */
-      __set_errno (ENOENT);
-      /* Even though we have not found anything, the result is zero.  */
+      if (__builtin_expect (initgr_resp->found == -1, 0))
+       {
+         /* The daemon does not cache this database.  */
+         __nss_not_use_nscd_group = 1;
+         goto out_close;
+       }
+
+      /* No group found yet.   */
       retval = 0;
+
+      assert (*size >= 1);
+    }
+
+  /* Check whether GROUP is part of the mix.  If not, add it.  */
+  if (retval >= 0)
+    {
+      int cnt;
+      for (cnt = 0; cnt < retval; ++cnt)
+       if ((*groupsp)[cnt] == group)
+         break;
+
+      if (cnt == retval)
+       (*groupsp)[retval++] = group;
     }
 
+ out_close:
   if (sock != -1)
     close_not_cancel_no_status (sock);
  out: