[SSSD] [PATCHES] Netgroup support for LDAP provider

Sumit Bose sbose at redhat.com
Thu Oct 7 11:28:51 UTC 2010


On Tue, Oct 05, 2010 at 04:21:01PM +0200, Sumit Bose wrote:
> Hi,
> 
> this series of patches continue the work Stephen has started in
> "[PATCHES] Support for netgroups in the NSS client and responder".
> 
> We decided to try to be as compatible to nss_ldap as possible, i.e. we
> do not any group unrolling or loop detection inside of sssd, but rely on
> glibc. To achieve this I added support to return netgroup member groups
> to the client and glibc. This is mostly done in 0003 and 0006. 0007 and
> 0008 add the necessary support to the LDAP provider.
> 
> There is one difference to nss_ldap. If a netgroup member is not
> specified by a plain name but by a DN nss_ldap just returns the DN
> string to glibc and then glibc searches for a netgroup where the name is
> the returned DN. Even nss_ldap cannot find a matching netgroup for this
> name. If sssd detects a DN in the member list it tries to translate it
> to the corresponding name of the netgroup. If this fails it will return
> the full DN.
> 
> The patches 0001 and 0002 fixes two errors in Stephen's patches.
> 
> bye,
> Sumit

Hi,

the attached patch can be applied on top of all the other netgroup
patches and should help the nss client to behave better in multi
threaded environment when it comes to parallel netgroup enumeration.
Please note that also the innetgr() call triggers a numeration of the
related netgroup.

bye,
Sumit
-------------- next part --------------
From 9f9f19bf931572e3bba83642120b12ffa90bcf4e Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose at redhat.com>
Date: Thu, 7 Oct 2010 13:15:52 +0200
Subject: [PATCH] Avoid a global variable in netgroup client.

The structure which is used to store the result also provides elements to
store a context for the netgroup enumeration call.
---
 src/sss_client/nss_compat.h   |    2 +-
 src/sss_client/nss_netgroup.c |   62 ++++++++++++++++------------------------
 2 files changed, 26 insertions(+), 38 deletions(-)

diff --git a/src/sss_client/nss_compat.h b/src/sss_client/nss_compat.h
index 37871c2..97fbfeb 100644
--- a/src/sss_client/nss_compat.h
+++ b/src/sss_client/nss_compat.h
@@ -57,7 +57,7 @@ struct __netgrent
   {
     char *cursor;
     unsigned long int position;
-  } insertedname; /* added name to union to avoid warning */
+  } idx;  /* added name to union to avoid warning */
   int first;
   struct name_list *known_groups;
   struct name_list *needed_groups;
diff --git a/src/sss_client/nss_netgroup.c b/src/sss_client/nss_netgroup.c
index 1b213c6..9921ee5 100644
--- a/src/sss_client/nss_netgroup.c
+++ b/src/sss_client/nss_netgroup.c
@@ -35,12 +35,12 @@
 
 #define MAX_NETGR_NAME_LENGTH 2048
 
-static struct sss_nss_getnetgrent_data {
-    char *name;
-    size_t len;
-    size_t ptr;
-    uint8_t *data;
-} sss_nss_getnetgrent_data;
+#define CLEAR_NETGRENT_DATA(netgrent) do { \
+        free(netgrent->data); \
+        netgrent->data = NULL; \
+        netgrent->idx.position = 0; \
+        netgrent->data_size = 0; \
+} while (0);
 
 /*
  * Replies:
@@ -60,19 +60,6 @@ struct sss_nss_netgr_rep {
     size_t buflen;
 };
 
-static void sss_nss_getnetgrent_data_clean(void) {
-    if (sss_nss_getnetgrent_data.name != NULL) {
-        free(sss_nss_getnetgrent_data.name);
-        sss_nss_getnetgrent_data.name = NULL;
-    }
-    if (sss_nss_getnetgrent_data.data != NULL) {
-        free(sss_nss_getnetgrent_data.data);
-        sss_nss_getnetgrent_data.data = NULL;
-    }
-    sss_nss_getnetgrent_data.len = 0;
-    sss_nss_getnetgrent_data.ptr = 0;
-}
-
 static int sss_nss_getnetgr_readrep(struct sss_nss_netgr_rep *pr,
                                     uint8_t *buf, size_t *len)
 {
@@ -200,28 +187,30 @@ enum nss_status _nss_sss_setnetgrent(const char *netgroup,
     enum nss_status nret;
     struct sss_cli_req_data rd;
     int errnop;
+    char *name;
     size_t name_len;
     errno_t ret;
 
     if (!netgroup) return NSS_STATUS_NOTFOUND;
 
     /* make sure we do not have leftovers, and release memory */
-    sss_nss_getnetgrent_data_clean();
+    CLEAR_NETGRENT_DATA(result);
 
     ret = sss_strnlen(netgroup, MAX_NETGR_NAME_LENGTH, &name_len);
     if (ret != 0) return NSS_STATUS_NOTFOUND;
 
-    sss_nss_getnetgrent_data.name = malloc(sizeof(char)*name_len + 1);
-    if (sss_nss_getnetgrent_data.name == NULL) {
+    name = malloc(sizeof(char)*name_len + 1);
+    if (name == NULL) {
         return NSS_STATUS_TRYAGAIN;
     }
-    strncpy(sss_nss_getnetgrent_data.name, netgroup, name_len + 1);
+    strncpy(name, netgroup, name_len + 1);
 
-    rd.data = sss_nss_getnetgrent_data.name;
+    rd.data = name;
     rd.len = name_len + 1;
 
     nret = sss_nss_make_request(SSS_NSS_SETNETGRENT, &rd,
                                 &repbuf, &replen, &errnop);
+    free(name);
     if (nret != NSS_STATUS_SUCCESS) {
         errno = errnop;
         return nret;
@@ -233,6 +222,7 @@ enum nss_status _nss_sss_setnetgrent(const char *netgroup,
         return NSS_STATUS_NOTFOUND;
     }
 
+    free(repbuf);
     return NSS_STATUS_SUCCESS;
 }
 
@@ -254,13 +244,11 @@ enum nss_status _nss_sss_getnetgrent_r(struct __netgrent *result,
     /* If we're already processing result data, continue to
      * return it.
      */
-    if (sss_nss_getnetgrent_data.data != NULL &&
-        sss_nss_getnetgrent_data.ptr < sss_nss_getnetgrent_data.len) {
+    if (result->data != NULL &&
+        result->idx.position < result->data_size) {
 
-        repbuf = (uint8_t *)sss_nss_getnetgrent_data.data +
-                sss_nss_getnetgrent_data.ptr;
-        replen = sss_nss_getnetgrent_data.len -
-                    sss_nss_getnetgrent_data.ptr;
+        repbuf = (uint8_t *) result->data + result->idx.position;
+        replen = result->data_size - result->idx.position;
 
         netgrrep.result = result;
         netgrrep.buffer = buffer;
@@ -272,13 +260,13 @@ enum nss_status _nss_sss_getnetgrent_r(struct __netgrent *result,
             return NSS_STATUS_TRYAGAIN;
         }
 
-        sss_nss_getnetgrent_data.ptr = sss_nss_getnetgrent_data.len - replen;
+        result->idx.position = result->data_size - replen;
 
         return NSS_STATUS_SUCCESS;
     }
 
     /* Release memory, if any */
-    sss_nss_getnetgrent_data_clean();
+    CLEAR_NETGRENT_DATA(result);
 
     /* retrieve no more than SSS_NSS_MAX_ENTRIES at a time */
     num_entries = SSS_NSS_MAX_ENTRIES;
@@ -297,22 +285,22 @@ enum nss_status _nss_sss_getnetgrent_r(struct __netgrent *result,
         return NSS_STATUS_RETURN;
     }
 
-    sss_nss_getnetgrent_data.data = repbuf;
-    sss_nss_getnetgrent_data.len = replen;
+    result->data = (char *) repbuf;
+    result->data_size = replen;
     /* skip metadata fields */
-    sss_nss_getnetgrent_data.ptr = NETGR_METADATA_COUNT;
+    result->idx.position = NETGR_METADATA_COUNT;
 
     /* call again ourselves, this will return the first result */
     return _nss_sss_getnetgrent_r(result, buffer, buflen, errnop);
 }
 
-enum nss_status _nss_sss_endnetgrent(void)
+enum nss_status _nss_sss_endnetgrent(struct __netgrent *result)
 {
     enum nss_status nret;
     int errnop;
 
     /* make sure we do not have leftovers, and release memory */
-    sss_nss_getnetgrent_data_clean();
+    CLEAR_NETGRENT_DATA(result);
 
     nret = sss_nss_make_request(SSS_NSS_ENDNETGRENT,
                                 NULL, NULL, NULL, &errnop);
-- 
1.7.2.3



More information about the sssd-devel mailing list