lists.arthurdejong.org
RSS feed

RE: [nssldap] Re: Re: disconnected nss_ldap

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

RE: [nssldap] Re: Re: disconnected nss_ldap



Ryan,
 
please try this out - it applies and runs in the environment here but I would 
not call that an exhaustive test!
 
This is very much a hack - but without a complete write through the ldap-nss 
logic is too complex to do this any other way today.
 
Howard.
 

On Tue, Oct 27, 2009 at 10:35, Howard Wilkinson <howard@cohtech.com> wrote:
> I am working on this now and hope to have something out today. The internals 
> of nss_ldap are a bit of mess in this area, but I think I have a handle on it.

Fire when ready.

> This will have to go on the top of the mega patch as the original code is 
> even worse in this area..... ;-(

That's good--I was in the process of rebuilding RPMs with your latest
mega rev when I saw your original message, so I can save a little time
testing both at once.

-Ryan


diff -ruN nss_ldap-264-save/nss_ldap-264/ldap-nss.c 
nss_ldap-264/nss_ldap-264/ldap-nss.c
--- nss_ldap-264-save/nss_ldap-264/ldap-nss.c   2009-10-26 11:05:50.659588000 
+0000
+++ nss_ldap-264/nss_ldap-264/ldap-nss.c        2009-10-27 15:19:42.053806000 
+0000
@@ -308,6 +308,11 @@
 static NSS_STATUS do_map_error (int rc);
 
 /*
+ * Map status to status and errno - handles out of buffer fudges
+ */
+static NSS_STATUS do_map_errno (NSS_STATUS status, int *errnop);
+
+/*
  * support the sasl interaction
  */
 static int do_sasl_interact (LDAP * ld, unsigned flags, void *defaults, void 
*p);
@@ -1665,7 +1670,7 @@
     }
 }
 
-void
+static void
 do_init_mechs (ldap_session_t *session)
 {
   int i;
@@ -2523,7 +2528,7 @@
 #define _APPEND_STRING(_buffer, _buflen, _s, _len) do { \
                if ((_buflen) < (size_t)((_len) + 1)) \
                { \
-                       return NSS_TRYAGAIN; \
+                       return NSS_RETURN; \
                } \
                memcpy((_buffer), (_s), (_len)); \
                (_buffer)[(_len)] = '\0'; \
@@ -2610,7 +2615,7 @@
       len = strlen (filter);
 
       if (buflen < len + 1 /* ')' */ )
-       return NSS_TRYAGAIN;
+       return NSS_RETURN;
 
       memcpy (bufptr, filter, len);
       bufptr[len] = '\0';
@@ -2619,7 +2624,7 @@
     }
 
   if (buflen < 2)
-    return NSS_TRYAGAIN;
+    return NSS_RETURN;
 
   *bufptr++ = ')';
   *bufptr++ = '\0';
@@ -2705,7 +2710,7 @@
                                             args->la_arg1.la_triple.user,
                                             args->la_arg1.la_triple.domain,
                                             filterBufP, filterSiz);
-             if (stat == NSS_TRYAGAIN)
+             if (stat == NSS_RETURN)
                {
                  filterBufP = *dynamicUserBuf = realloc (*dynamicUserBuf,
                                                          2 * filterSiz);
@@ -2714,7 +2719,7 @@
                  filterSiz *= 2;
                }
            }
-         while (stat == NSS_TRYAGAIN);
+         while (stat == NSS_RETURN);
          break;
 #endif /* HAVE_NSSWITCH_H || HAVE_IRS_H */
        case LA_TYPE_STRING_LIST_OR:
@@ -2724,7 +2729,7 @@
              stat = do_aggregate_filter (args->la_arg1.la_string_list,
                                          args->la_type,
                                          filterprot, filterBufP, filterSiz);
-             if (stat == NSS_TRYAGAIN)
+             if (stat == NSS_RETURN)
                {
                  filterBufP = *dynamicUserBuf = realloc (*dynamicUserBuf,
                                                          2 * filterSiz);
@@ -2733,7 +2738,7 @@
                  filterSiz *= 2;
                }
            }
-         while (stat == NSS_TRYAGAIN);
+         while (stat == NSS_RETURN);
          break;
        default:
          return NSS_UNAVAIL;
@@ -2963,6 +2968,7 @@
   int maxtries;
   int hard;
   int firstTime = 1;
+  int errnotmp = 0;
 
   debug ("==> do_with_reconnect");
 
@@ -3116,7 +3122,7 @@
              "nss_ldap: could not %s %sconnect to LDAP server - %s",
              hard ? "hard" : "soft", tries ? "re" : "",
              ldap_err2string (rc));
-      stat = NSS_UNAVAIL;
+      /* stat = NSS_UNAVAIL; */
       break;
     case NSS_SUCCESS:
       if (log != 0)
@@ -3148,6 +3154,8 @@
 
   debug ("<== do_with_reconnect returns %s(%d)", 
__nss_ldap_status2string(stat), stat);
 
+  stat = do_map_errno(stat, &errnotmp);
+
   return stat;
 }
 
@@ -3273,10 +3281,10 @@
   return rc;
 }
 
-static void
+static NSS_STATUS
 do_map_errno (NSS_STATUS status, int *errnop)
 {
-  if (status == NSS_TRYAGAIN)
+  if (status == NSS_RETURN)
     {
 #ifdef HAVE_NSSWITCH_H
       errno = ERANGE;
@@ -3284,11 +3292,17 @@
 #else
       *errnop = errno = ERANGE;
 #endif
+      status = NSS_TRYAGAIN;
+    }
+  else if (status == NSS_TRYAGAIN)
+    {
+      *errnop = errno = EAGAIN;
     }
   else
     {
       *errnop = 0;
     }
+  return status;
 }
 
 /*
@@ -3342,7 +3356,7 @@
                          buffer, buflen);
 
       /* hold onto the state if we're out of memory XXX */
-      ctx->ec_state.ls_retry = (parseStat == NSS_TRYAGAIN && buffer != NULL ? 
1 : 0);
+      ctx->ec_state.ls_retry = (parseStat == NSS_RETURN && buffer != NULL ? 1 
: 0);
 
       /* free entry is we're moving on */
       if (ctx->ec_state.ls_retry == 0 &&
@@ -3356,7 +3370,7 @@
     }
   while (parseStat == NSS_NOTFOUND);
 
-  do_map_errno (parseStat, errnop);
+  parseStat = do_map_errno (parseStat, errnop);
 
   debug ("<== do_parse");
 
@@ -3408,17 +3422,17 @@
        * If we do not parse the entry because of a schema
        * violation, the parser should return NSS_NOTFOUND.
        * We'll keep on trying subsequent entries until we
-       * find one which is parseable, or exhaust avialable
+       * find one which is parseable, or exhaust available
        * entries, whichever is first.
        */
       parseStat = parser (e, &ctx->ec_state, result, buffer, buflen);
 
       /* hold onto the state if we're out of memory XXX */
-      ctx->ec_state.ls_retry = (parseStat == NSS_TRYAGAIN && buffer != NULL ? 
1 : 0);
+      ctx->ec_state.ls_retry = (parseStat == NSS_RETURN && buffer != NULL ? 1 
: 0);
     }
   while (parseStat == NSS_NOTFOUND);
 
-  do_map_errno (parseStat, errnop);
+  parseStat = do_map_errno (parseStat, errnop);
 
   debug ("<== do_parse_s");
 
@@ -4076,7 +4090,7 @@
   if (bytesleft (buffer, buflen, char *) < (valcount + 1) * sizeof (char *))
     {
       ldap_value_free (vals);
-      return NSS_TRYAGAIN;
+      return NSS_RETURN;
     }
 
   align (buffer, buflen, char *);
@@ -4110,7 +4124,7 @@
          if (buflen < (size_t) (vallen + 1))
            {
              ldap_value_free (vals);
-             return NSS_TRYAGAIN;
+             return NSS_RETURN;
            }
 
          /* copy this value into the next block of buffer space */
@@ -4156,7 +4170,7 @@
       vallen = strlen (ovr);
       if (*buflen < (size_t) (vallen + 1))
        {
-         return NSS_TRYAGAIN;
+         return NSS_RETURN;
        }
 
       *valptr = *buffer;
@@ -4184,7 +4198,7 @@
          vallen = strlen (def);
          if (*buflen < (size_t) (vallen + 1))
            {
-             return NSS_TRYAGAIN;
+             return NSS_RETURN;
            }
 
          *valptr = *buffer;
@@ -4207,7 +4221,7 @@
   if (*buflen < (size_t) (vallen + 1))
     {
       ldap_value_free (vals);
-      return NSS_TRYAGAIN;
+      return NSS_RETURN;
     }
 
   *valptr = *buffer;
@@ -4304,7 +4318,7 @@
          ldap_value_free (vals);
        }
       debug ("<== _nss_ldap_assign_userpassword");
-      return NSS_TRYAGAIN;
+      return NSS_RETURN;
     }
 
   *valptr = *buffer;
@@ -4679,6 +4693,7 @@
     {
       debug ("<== _nss_ldap_proxy_bind (empty password not permitted)");
       /* XXX overload */
+      do_map_errno(NSS_TRYAGAIN, &rc);
       return NSS_TRYAGAIN;
     }
 
@@ -4749,6 +4764,8 @@
 
   debug ("<== _nss_ldap_proxy_bind");
 
+  stat = do_map_errno(stat, &rc);
+
   return stat;
 }