lists.arthurdejong.org
RSS feed

nss-pam-ldapd commit: r1874 - in nss-pam-ldapd: . nslcd nss pynslcd tests

[Date Prev][Date Next] [Thread Prev][Thread Next]

nss-pam-ldapd commit: r1874 - in nss-pam-ldapd: . nslcd nss pynslcd tests



Author: arthur
Date: Sun Dec 23 20:35:12 2012
New Revision: 1874
URL: http://arthurdejong.org/viewvc/nss-pam-ldapd?revision=1874&view=revision

Log:
update the netgroup by name request to have one result entry per netgroup with 
multiple rows within one result

Modified:
   nss-pam-ldapd/nslcd.h
   nss-pam-ldapd/nslcd/netgroup.c
   nss-pam-ldapd/nss/netgroup.c
   nss-pam-ldapd/pynslcd/netgroup.py
   nss-pam-ldapd/tests/test_nsscmds.sh

Modified: nss-pam-ldapd/nslcd.h
==============================================================================
--- nss-pam-ldapd/nslcd.h       Sat Dec 22 22:38:26 2012        (r1873)
+++ nss-pam-ldapd/nslcd.h       Sun Dec 23 20:35:12 2012        (r1874)
@@ -115,18 +115,25 @@
 #define NSLCD_ACTION_HOST_BYADDR       0x00050002
 #define NSLCD_ACTION_HOST_ALL          0x00050008
 
-/* Netgroup NSS request return a number of results. Result values
-   can be either a reference to another netgroup:
+/* Netgroup NSS result entries contain a number of parts. A result entry
+   starts with:
+     STRING  netgroup name
+   followed by zero or more references to other netgroups or netgroup
+   triples. A reference to another netgroup looks like:
      INT32   NSLCD_NETGROUP_TYPE_NETGROUP
      STRING  other netgroup name
-   or a netgroup triple:
+   A a netgroup triple looks like:
      INT32   NSLCD_NETGROUP_TYPE_TRIPLE
      STRING  host
      STRING  user
-     STRING  domain */
+     STRING  domain
+   A netgroup result entry is terminated by:
+     INT32   NSLCD_NETGROUP_TYPE_END
+   */
 #define NSLCD_ACTION_NETGROUP_BYNAME   0x00060001
 #define NSLCD_NETGROUP_TYPE_NETGROUP 1
 #define NSLCD_NETGROUP_TYPE_TRIPLE   2
+#define NSLCD_NETGROUP_TYPE_END      3
 
 /* Network name (/etc/networks) NSS requests. Result values for a single
    entry are:

Modified: nss-pam-ldapd/nslcd/netgroup.c
==============================================================================
--- nss-pam-ldapd/nslcd/netgroup.c      Sat Dec 22 22:38:26 2012        (r1873)
+++ nss-pam-ldapd/nslcd/netgroup.c      Sun Dec 23 20:35:12 2012        (r1874)
@@ -96,25 +96,18 @@
   int32_t tmpint32;
   int i, j;
   DEBUG_PRINT("WRITE_STRING: var=" __STRING(str) " string=\"%s\"", str);
-  if (str == NULL)
+  /* skip leading spaces */
+  for (i = 0; (str[i] != '\0') && (isspace(str[i])); i++)
+    /* nothing */ ;
+  /* skip trailing spaces */
+  for (j = len; (j > i) && (isspace(str[j - 1])); j--)
+    /* nothing */ ;
+  /* write length of string */
+  WRITE_INT32(fp, j - i);
+  /* write string itself */
+  if (j > i)
   {
-    WRITE_INT32(fp, 0);
-  }
-  else
-  {
-    /* skip leading spaces */
-    for (i = 0; (str[i] != '\0') && (isspace(str[i])); i++)
-      /* nothing */ ;
-    /* skip trailing spaces */
-    for (j = len; (j > i) && (isspace(str[j - 1])); j--)
-      /* nothing */ ;
-    /* write length of string */
-    WRITE_INT32(fp, j - i);
-    /* write string itself */
-    if (j > i)
-    {
-      WRITE(fp, str + i, j - i);
-    }
+    WRITE(fp, str + i, j - i);
   }
   /* we're done */
   return 0;
@@ -148,38 +141,35 @@
   /* find comma (end of host string) */
   for (; (triple[i] != '\0') && (triple[i] != ','); i++)
     /* nothing */ ;
-  if (triple[i] != ',')
+  hoste = i;
+  if (triple[i++] != ',')
   {
     log_log(LOG_WARNING, "%s: %s: missing ','",
             myldap_get_dn(entry), attmap_netgroup_nisNetgroupTriple);
     return 0;
   }
-  hoste = i;
-  i++;
   userb = i;
   /* find comma (end of user string) */
   for (; (triple[i] != '\0') && (triple[i] != ','); i++)
     /* nothing */ ;
-  if (triple[i] != ',')
+  usere = i;
+  if (triple[i++] != ',')
   {
     log_log(LOG_WARNING, "%s: %s: missing ','",
             myldap_get_dn(entry), attmap_netgroup_nisNetgroupTriple);
     return 0;
   }
-  usere = i;
-  i++;
   domainb = i;
   /* find closing bracket (end of domain string) */
   for (; (triple[i] != '\0') && (triple[i] != ')'); i++)
     /* nothing */ ;
-  if (triple[i] != ')')
+  domaine=i;
+  if (triple[i++] != ')')
   {
     log_log(LOG_WARNING, "%s: %s: missing ')'",
             myldap_get_dn(entry), attmap_netgroup_nisNetgroupTriple);
     return 0;
   }
-  domaine = i;
-  i++;
   /* skip trailing spaces */
   for (; (triple[i] != '\0') && (isspace(triple[i])); i++)
     /* nothing */ ;
@@ -191,23 +181,18 @@
     return 0;
   }
   /* write strings */
-  WRITE_INT32(fp, NSLCD_RESULT_BEGIN);
   WRITE_INT32(fp, NSLCD_NETGROUP_TYPE_TRIPLE);
-  WRITE_STRING_STRIPSPACE_LEN(fp, triple + hostb, hoste - hostb);
-  WRITE_STRING_STRIPSPACE_LEN(fp, triple + userb, usere - userb);
-  WRITE_STRING_STRIPSPACE_LEN(fp, triple + domainb, domaine - domainb);
+  WRITE_STRING_STRIPSPACE_LEN(fp, triple + hostb, hoste - hostb)
+  WRITE_STRING_STRIPSPACE_LEN(fp, triple + userb, usere - userb)
+  WRITE_STRING_STRIPSPACE_LEN(fp, triple + domainb, domaine - domainb)
   /* we're done */
   return 0;
 }
 
-#define WRITE_NETGROUP_TRIPLE(fp, entry, triple)                            \
-  if (write_netgroup_triple(fp, entry, triple))                             \
-    return -1;
-
 static int write_netgroup(TFILE *fp, MYLDAP_ENTRY *entry, const char *reqname)
 {
   int32_t tmpint32;
-  int i;
+  int i, j;
   const char **names;
   const char **triples;
   const char **members;
@@ -219,29 +204,32 @@
             myldap_get_dn(entry), attmap_netgroup_cn);
     return 0;
   }
-  for (i = 0; (names[i] != NULL) && (STR_CMP(reqname, names[i]) != 0); i++)
-    /* nothing */ ;
-  if (names[i] == NULL)
-    return 0; /* the name was not found */
   /* get the netgroup triples and member */
   triples = myldap_get_values(entry, attmap_netgroup_nisNetgroupTriple);
   members = myldap_get_values(entry, attmap_netgroup_memberNisNetgroup);
-  /* write the netgroup triples */
-  if (triples != NULL)
-    for (i = 0; triples[i] != NULL; i++)
-    {
-      WRITE_NETGROUP_TRIPLE(fp, entry, triples[i]);
-    }
-  /* write netgroup members */
-  if (members != NULL)
-    for (i = 0; members[i] != NULL; i++)
+  /* write the entries */
+  for (i = 0; names[i] != NULL; i++)
+    if ((reqname == NULL) || (STR_CMP(reqname, names[i]) == 0))
     {
-      /* write the result code */
+      /* write first part of result */
       WRITE_INT32(fp, NSLCD_RESULT_BEGIN);
-      /* write triple indicator */
-      WRITE_INT32(fp, NSLCD_NETGROUP_TYPE_NETGROUP);
-      /* write netgroup name */
-      WRITE_STRING_STRIPSPACE(fp, members[i]);
+      WRITE_STRING(fp, names[i]);
+      /* write the netgroup triples */
+      if (triples != NULL)
+        for (j = 0; triples[j] != NULL; j++)
+          if (write_netgroup_triple(fp, entry, triples[j]))
+            return -1;
+      /* write netgroup members */
+      if (members != NULL)
+        for (j = 0; members[j] != NULL; j++)
+        {
+          /* write triple indicator */
+          WRITE_INT32(fp, NSLCD_NETGROUP_TYPE_NETGROUP);
+          /* write netgroup name */
+          WRITE_STRING_STRIPSPACE(fp, members[j]);
+        }
+      /* write end of result marker */
+      WRITE_INT32(fp, NSLCD_NETGROUP_TYPE_END);
     }
   /* we're done */
   return 0;

Modified: nss-pam-ldapd/nss/netgroup.c
==============================================================================
--- nss-pam-ldapd/nss/netgroup.c        Sat Dec 22 22:38:26 2012        (r1873)
+++ nss-pam-ldapd/nss/netgroup.c        Sun Dec 23 20:35:12 2012        (r1874)
@@ -32,17 +32,9 @@
 #include "compat/attrs.h"
 #include "common/set.h"
 
-/* we redefine this here because we need to return NSS_STATUS_RETURN
-   instead of NSS_STATUS_NOTFOUND */
-#undef ERROR_OUT_NOSUCCESS
-#define ERROR_OUT_NOSUCCESS(fp)                                             \
-  (void)tio_close(fp);                                                      \
-  fp = NULL;                                                                \
-  return NSS_STATUS_RETURN;
-
 /* function for reading a single result entry */
-static nss_status_t read_netgrent(TFILE *fp, struct __netgrent *result,
-                                  char *buffer, size_t buflen, int *errnop)
+static nss_status_t read_netgrent_line(TFILE *fp, struct __netgrent *result,
+                                       char *buffer, size_t buflen, int 
*errnop)
 {
   int32_t tmpint32;
   int type;
@@ -54,6 +46,7 @@
     /* the response is a reference to another netgroup */
     result->type = group_val;
     READ_BUF_STRING(fp, result->val.group);
+    return NSS_STATUS_SUCCESS;
   }
   else if (type == NSLCD_NETGROUP_TYPE_TRIPLE)
   {
@@ -80,11 +73,14 @@
       result->val.triple.domain = NULL;
       bufptr--; /* free unused space */
     }
+    return NSS_STATUS_SUCCESS;
   }
-  else
-    return NSS_STATUS_UNAVAIL;
-  /* we're done */
-  return NSS_STATUS_SUCCESS;
+  else if (type == NSLCD_NETGROUP_TYPE_END)
+    /* make _nss_ldap_getnetgrent_r() indicate the end of the netgroup */
+    return NSS_STATUS_RETURN;
+  /* we got something unexpected */
+  ERROR_OUT_NOSUCCESS(fp);
+  return NSS_STATUS_UNAVAIL;
 }
 
 #ifdef NSS_FLAVOUR_GLIBC
@@ -100,16 +96,18 @@
      available in this function */
   int32_t tmpint32;
   int errnocp;
-  int *errnop;
-  if (!_nss_ldap_enablelookups)
-    return NSS_STATUS_UNAVAIL;
-  errnop = &errnocp;
+  int *errnop = &errnocp;
+  NSS_EXTRA_DEFS
+  NSS_AVAILCHECK;
   /* check parameter */
   if ((group == NULL) || (group[0] == '\0'))
     return NSS_STATUS_UNAVAIL;
   /* open a new stream and write the request */
   NSLCD_REQUEST(netgrentfp, NSLCD_ACTION_NETGROUP_BYNAME,
                 WRITE_STRING(netgrentfp, group));
+  /* read response code */
+  READ_RESPONSE_CODE(netgrentfp);
+  SKIP_STRING(netgrentfp); /* netgroup name */
   return NSS_STATUS_SUCCESS;
 }
 
@@ -117,8 +115,35 @@
 nss_status_t _nss_ldap_getnetgrent_r(struct __netgrent *result,
                                      char *buffer, size_t buflen, int *errnop)
 {
-  NSS_GETENT(netgrentfp, NSLCD_ACTION_NETGROUP_BYNAME,
-             read_netgrent(netgrentfp, result, buffer, buflen, errnop));
+  nss_status_t retv;
+  NSS_EXTRA_DEFS;
+  NSS_AVAILCHECK;
+  NSS_BUFCHECK;
+  /* check that we have a valid file descriptor */
+  if (netgrentfp == NULL)
+    return NSS_STATUS_UNAVAIL;
+  /* prepare for buffer errors */
+  tio_mark(netgrentfp);
+  /* read a response */
+  retv = read_netgrent_line(netgrentfp, result, buffer, buflen, errnop);
+  /* check read result */
+  if (retv == NSS_STATUS_TRYAGAIN)
+  {
+    /* if we have a full buffer try to reset the stream */
+    if (tio_reset(netgrentfp))
+    {
+      /* reset failed, we close and give up with a permanent error
+         because we cannot retry just the getent() call because it
+         may not be only the first entry that failed */
+      tio_close(netgrentfp);
+      netgrentfp = NULL;
+      *errnop = EINVAL;
+      return NSS_STATUS_UNAVAIL;
+    }
+  }
+  else if ((retv != NSS_STATUS_SUCCESS) && (retv != NSS_STATUS_RETURN))
+    netgrentfp = NULL; /* file should be closed by now */
+  return retv;
 }
 
 /* close the stream opened with setnetgrent() above */
@@ -185,8 +210,7 @@
                                                void *args)
 {
   NSS_GETENT(NETGROUP_BE(be)->fp, NSLCD_ACTION_NETGROUP_BYNAME,
-             read_netgrent(NETGROUP_BE(be)->fp, result, buffer, buflen,
-                           errnop));
+             read_netgrent_line(NETGROUP_BE(be)->fp, result, buffer, buflen, 
errnop));
 }
 
 static nss_status_t netgroup_setnetgrent_setnetgrent(nss_backend_t

Modified: nss-pam-ldapd/pynslcd/netgroup.py
==============================================================================
--- nss-pam-ldapd/pynslcd/netgroup.py   Sat Dec 22 22:38:26 2012        (r1873)
+++ nss-pam-ldapd/pynslcd/netgroup.py   Sun Dec 23 20:35:12 2012        (r1874)
@@ -47,25 +47,26 @@
 
 class NetgroupRequest(common.Request):
 
-    def write(self, name, member):
-        m = _netgroup_triple_re.match(member)
-        if m:
-            self.fp.write_int32(constants.NSLCD_NETGROUP_TYPE_TRIPLE)
-            self.fp.write_string(m.group('host'))
-            self.fp.write_string(m.group('user'))
-            self.fp.write_string(m.group('domain'))
-        else:
+    def write(self, name, triples, members):
+        self.fp.write_string(name)
+        for triple in triples:
+            m = _netgroup_triple_re.match(triple)
+            if m:
+                self.fp.write_int32(constants.NSLCD_NETGROUP_TYPE_TRIPLE)
+                self.fp.write_string(m.group('host'))
+                self.fp.write_string(m.group('user'))
+                self.fp.write_string(m.group('domain'))
+        for member in members:
             self.fp.write_int32(constants.NSLCD_NETGROUP_TYPE_NETGROUP)
             self.fp.write_string(member)
+        self.fp.write_int32(constants.NSLCD_NETGROUP_TYPE_END)
 
     def convert(self, dn, attributes, parameters):
-        # write the netgroup triples
-        name = attributes['cn'][0]
-        for triple in attributes['nisNetgroupTriple']:
-            yield (name, triple)
-        # write netgroup members
-        for member in attributes['memberNisNetgroup']:
-            yield (name, member)
+        names = attributes['cn']
+        triples = attributes['nisNetgroupTriple']
+        members = attributes['memberNisNetgroup']
+        for name in names:
+            yield (name, triples, members)
 
 
 class NetgroupByNameRequest(NetgroupRequest):

Modified: nss-pam-ldapd/tests/test_nsscmds.sh
==============================================================================
--- nss-pam-ldapd/tests/test_nsscmds.sh Sat Dec 22 22:38:26 2012        (r1873)
+++ nss-pam-ldapd/tests/test_nsscmds.sh Sun Dec 23 20:35:12 2012        (r1874)
@@ -2,7 +2,7 @@
 
 # test_nsscmds.sh - simple test script to check output of name lookup commands
 #
-# Copyright (C) 2007, 2008, 2009, 2010, 2011 Arthur de Jong
+# Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012 Arthur de Jong
 #
 # This library is free software; you can redistribute it and/or
 # modify it under the terms of the GNU Lesser General Public
@@ -221,9 +221,7 @@
 EOM
 
 # check netgroup lookup with different case
-# Note: this should return nothing at all (this is a bug)
 check "getent netgroup TSTNETGROUP" << EOM
-TSTNETGROUP
 EOM
 
 ###########################################################################
-- 
To unsubscribe send an email to
nss-pam-ldapd-commits-unsubscribe@lists.arthurdejong.org or see
http://lists.arthurdejong.org/nss-pam-ldapd-commits/