[PATCH 6/7] nscd: Add __nscd_getgrnam and __nscd_getgrgid client functions

Florian Weimer fweimer@redhat.com
Mon Nov 24 19:48:16 GMT 2025


They allocate an appropriately sized result and do not need the
ERANGE protocol.  The current implementation still uses ERANGE
internally, but the plan is to change that eventually.
---
 nscd/nscd_getgr_r.c | 52 ++++++++++++++++++++++++++++++++++++++++++++-
 nscd/nscd_proto.h   |  2 ++
 2 files changed, 53 insertions(+), 1 deletion(-)

diff --git a/nscd/nscd_getgr_r.c b/nscd/nscd_getgr_r.c
index 173fadbd97..942eb8c2db 100644
--- a/nscd/nscd_getgr_r.c
+++ b/nscd/nscd_getgr_r.c
@@ -34,11 +34,13 @@
 
 #include "nscd-client.h"
 #include "nscd_proto.h"
+#include <nss/nss_generic.h>
 
 static int nscd_getgr_r (const char *key, size_t keylen, request_type type,
 			 struct group *resultbuf, char *buffer,
 			 size_t buflen, struct group **result);
-
+static int nscd_getgr (const char *key, size_t keylen, request_type type,
+		       struct group **result);
 
 int
 __nscd_getgrnam_r (const char *name, struct group *resultbuf, char *buffer,
@@ -48,6 +50,11 @@ __nscd_getgrnam_r (const char *name, struct group *resultbuf, char *buffer,
 		       buffer, buflen, result);
 }
 
+int
+__nscd_getgrnam (const char *name, struct group **result)
+{
+  return nscd_getgr (name, strlen (name) + 1, GETGRBYNAME, result);
+}
 
 int
 __nscd_getgrgid_r (gid_t gid, struct group *resultbuf, char *buffer,
@@ -61,6 +68,15 @@ __nscd_getgrgid_r (gid_t gid, struct group *resultbuf, char *buffer,
 		       buffer, buflen, result);
 }
 
+int
+__nscd_getgrgid (gid_t gid, struct group **result)
+{
+  char buf[3 * sizeof (gid_t)];
+  buf[sizeof (buf) - 1] = '\0';
+  char *cp = _itoa_word (gid, buf + sizeof (buf) - 1, 10, 0);
+
+  return nscd_getgr (cp, buf + sizeof (buf) - cp, GETGRBYGID, result);
+}
 
 libc_locked_map_ptr (,__gr_map_handle) attribute_hidden;
 /* Note that we only free the structure if necessary.  The memory
@@ -324,3 +340,37 @@ nscd_getgr_r (const char *key, size_t keylen, request_type type,
 
   return retval;
 }
+
+static int
+nscd_getgr (const char *key, size_t keylen, request_type type,
+	    struct group **result)
+{
+  struct scratch_buffer buf;
+  scratch_buffer_init (&buf);
+
+  *result = NULL;
+  while (true)
+    {
+      struct group storage;
+      struct group *ptr = NULL;
+      int ret = nscd_getgr_r (key, keylen, type, &storage,
+			      buf.data, buf.length, &ptr);
+      if (ret == ERANGE)
+	{
+	  if (!scratch_buffer_grow (&buf))
+	    return ENOMEM;
+	}
+      else
+	{
+	  if (ret == 0 && ptr != NULL)
+	    {
+	      ptr = __nss_generic_dup (nss_lookup_getgrgid, ptr);
+	      if (ptr == NULL)
+		ret = ENOMEM;
+	      *result = ptr;
+	    }
+	  scratch_buffer_free (&buf);
+	  return ret;
+	}
+    }
+}
diff --git a/nscd/nscd_proto.h b/nscd/nscd_proto.h
index 3b635620dc..db49a02b73 100644
--- a/nscd/nscd_proto.h
+++ b/nscd/nscd_proto.h
@@ -54,9 +54,11 @@ extern int __nscd_getpwuid_r (uid_t uid, struct passwd *resultbuf,
 extern int __nscd_getgrnam_r (const char *name, struct group *resultbuf,
 			      char *buffer, size_t buflen,
 			      struct group **result) attribute_hidden;
+int __nscd_getgrnam (const char *name, struct group **result) attribute_hidden;
 extern int __nscd_getgrgid_r (gid_t gid, struct group *resultbuf,
 			      char *buffer,  size_t buflen,
 			      struct group **result) attribute_hidden;
+int __nscd_getgrgid (gid_t, struct group **result) attribute_hidden;
 extern int __nscd_gethostbyname_r (const char *name,
 				   struct hostent *resultbuf,
 				   char *buffer, size_t buflen,
-- 
2.52.0




More information about the Libc-alpha mailing list