]> sourceware.org Git - newlib-cygwin.git/commitdiff
* autoload.cc (ldap_search_sW): Replace ldap_search_stW.
authorCorinna Vinschen <corinna@vinschen.de>
Wed, 25 Jun 2014 09:10:50 +0000 (09:10 +0000)
committerCorinna Vinschen <corinna@vinschen.de>
Wed, 25 Jun 2014 09:10:50 +0000 (09:10 +0000)
(LdapMapErrorToWin32): Import.
* fhandler_disk_file.cc (fhandler_base::fstat_by_nfs_ea): Accommodate
change to cyg_ldap::open.
* ldap.cc (CYG_LDAP_TIMEOUT): Remove.
(CYG_LDAP_ENUM_TIMEOUT): Remove.
(def_tv): Remove.
(enum_tv): Remove.
(cyg_ldap::map_ldaperr_to_errno): New method to map LDAP error codes to
POSIX errno codes.  Explicitly map LDAP_NO_RESULTS_RETURNED to ENMFILE.
(cyg_ldap::wait): Ditto.
(struct cyg_ldap_init): New struct.
(cyg_ldap::connect_ssl): Return ULONG.  Drop setting LDAP_OPT_TIMELIMIT.
Add call to ldap_search_sW to fetch root DSE.
(cyg_ldap::connect_non_ssl): Ditto.
(ldap_init_thr): New static thread function.
(cyg_ldap::connect): New method to call connect_ssl/connect_non_ssl in
an interruptible cygthread.
(struct cyg_ldap_search): New struct.
(cyg_ldap::search_s): New method to perform generic synchronous search.
(ldap_search_thr): New static thread function.
(cyg_ldap::search): New method to call search_s in an interruptible
cygthread.
(struct cyg_ldap_next_page): New struct.
(cyg_ldap::next_page_s): New method to perform generic synchronous
paged search.
(ldap_next_page_thr): New static thread function.
(cyg_ldap::next_page): New method to call next_page_s in an
interruptible cygthread.
(cyg_ldap::open): Return POSIX errno.  Call connect method.
(cyg_ldap::fetch_ad_account): Call search method rather than
ldap_search_stW.
(cyg_ldap::enumerate_ad_accounts): Return POSIX errno.  Use infinite
timeout in call to ldap_search_init_pageW.
(cyg_ldap::next_account): Return POSIX errno.  Call next_page method
rather than ldap_get_next_page_s.
(cyg_ldap::fetch_posix_offset_for_domain): Call search method rather
than ldap_search_stW.
(cyg_ldap::fetch_unix_sid_from_ad): Ditto.
(cyg_ldap::fetch_unix_name_from_rfc2307): Ditto.
* ldap.h (class cyg_ldap): Accommodate aforementioned changes.
* passwd.cc (pg_ent::enumerate_ad): Ditto.  Break search if one of
cyg_ldap::enumerate_ad_accounts or cldap.next_account returns with
an error code other than ENMFILE.
* sec_helper.cc (cygpsid::get_id): Accommodate change to cyg_ldap::open.
* uinfo.cc (fetch_posix_offset): Ditto.

winsup/cygwin/ChangeLog
winsup/cygwin/autoload.cc
winsup/cygwin/fhandler_disk_file.cc
winsup/cygwin/ldap.cc
winsup/cygwin/ldap.h
winsup/cygwin/passwd.cc
winsup/cygwin/sec_helper.cc
winsup/cygwin/uinfo.cc

index c55b34bcc7cf5e839f7d2a7e44d431bec0067d5b..26978251bec237f630b743d16e461d0dea760195 100644 (file)
@@ -1,3 +1,52 @@
+2014-06-25  Corinna Vinschen  <corinna@vinschen.de>
+
+       * autoload.cc (ldap_search_sW): Replace ldap_search_stW.
+       (LdapMapErrorToWin32): Import.
+       * fhandler_disk_file.cc (fhandler_base::fstat_by_nfs_ea): Accommodate
+       change to cyg_ldap::open.
+       * ldap.cc (CYG_LDAP_TIMEOUT): Remove.
+       (CYG_LDAP_ENUM_TIMEOUT): Remove.
+       (def_tv): Remove.
+       (enum_tv): Remove.
+       (cyg_ldap::map_ldaperr_to_errno): New method to map LDAP error codes to
+       POSIX errno codes.  Explicitly map LDAP_NO_RESULTS_RETURNED to ENMFILE.
+       (cyg_ldap::wait): Ditto.
+       (struct cyg_ldap_init): New struct.
+       (cyg_ldap::connect_ssl): Return ULONG.  Drop setting LDAP_OPT_TIMELIMIT.
+       Add call to ldap_search_sW to fetch root DSE.
+       (cyg_ldap::connect_non_ssl): Ditto.
+       (ldap_init_thr): New static thread function.
+       (cyg_ldap::connect): New method to call connect_ssl/connect_non_ssl in
+       an interruptible cygthread.
+       (struct cyg_ldap_search): New struct.
+       (cyg_ldap::search_s): New method to perform generic synchronous search.
+       (ldap_search_thr): New static thread function.
+       (cyg_ldap::search): New method to call search_s in an interruptible
+       cygthread.
+       (struct cyg_ldap_next_page): New struct.
+       (cyg_ldap::next_page_s): New method to perform generic synchronous
+       paged search.
+       (ldap_next_page_thr): New static thread function.
+       (cyg_ldap::next_page): New method to call next_page_s in an
+       interruptible cygthread.
+       (cyg_ldap::open): Return POSIX errno.  Call connect method.
+       (cyg_ldap::fetch_ad_account): Call search method rather than
+       ldap_search_stW.
+       (cyg_ldap::enumerate_ad_accounts): Return POSIX errno.  Use infinite
+       timeout in call to ldap_search_init_pageW.
+       (cyg_ldap::next_account): Return POSIX errno.  Call next_page method
+       rather than ldap_get_next_page_s.
+       (cyg_ldap::fetch_posix_offset_for_domain): Call search method rather
+       than ldap_search_stW.
+       (cyg_ldap::fetch_unix_sid_from_ad): Ditto.
+       (cyg_ldap::fetch_unix_name_from_rfc2307): Ditto.
+       * ldap.h (class cyg_ldap): Accommodate aforementioned changes.
+       * passwd.cc (pg_ent::enumerate_ad): Ditto.  Break search if one of
+       cyg_ldap::enumerate_ad_accounts or cldap.next_account returns with
+       an error code other than ENMFILE.
+       * sec_helper.cc (cygpsid::get_id): Accommodate change to cyg_ldap::open.
+       * uinfo.cc (fetch_posix_offset): Ditto.
+
 2014-06-23  Corinna Vinschen  <corinna@vinschen.de>
 
        * spawn.cc (find_exec): Initialize err (CID 60111).
index 5cc296e2543b0282a37ee840bb4d8c336fa15206..8e3733e5cb570b3c6ef51af69a1c536aee90f9e3 100644 (file)
@@ -597,13 +597,14 @@ LoadDLLfunc (ldap_msgfree, 0, wldap32)
 LoadDLLfunc (ldap_next_entry, 0, wldap32)
 LoadDLLfunc (ldap_search_abandon_page, 0, wldap32)
 LoadDLLfunc (ldap_search_init_pageW, 0, wldap32)
-LoadDLLfunc (ldap_search_stW, 0, wldap32)
+LoadDLLfunc (ldap_search_sW, 0, wldap32)
 LoadDLLfunc (ldap_set_option, 0, wldap32)
 LoadDLLfunc (ldap_sslinitW, 0, wldap32)
 LoadDLLfunc (ldap_unbind, 0, wldap32)
 LoadDLLfunc (ldap_value_freeW, 0, wldap32)
 LoadDLLfunc (ldap_value_free_len, 0, wldap32)
 LoadDLLfunc (LdapGetLastError, 0, wldap32)
+LoadDLLfunc (LdapMapErrorToWin32, 0, wldap32)
 #pragma pop_macro ("mangle")
 
 LoadDLLfunc (WNetCloseEnum, 4, mpr)
index b03e9c7fd091c2313783ed2e3c0529055a02ebd2..ac8116486b8fcd95583d49a81b2caa57c9978454 100644 (file)
@@ -354,7 +354,7 @@ fhandler_base::fstat_by_nfs_ea (struct stat *buf)
       uid_t map_uid = ILLEGAL_UID;
 
       domain = cygheap->dom.get_rfc2307_domain ();
-      if ((ldap_open = cldap.open (domain)))
+      if ((ldap_open = (cldap.open (domain) == NO_ERROR)))
        map_uid = cldap.remap_uid (nfs_attr->uid);
       if (map_uid == ILLEGAL_UID)
        map_uid = MAP_UNIX_TO_CYGWIN_ID (nfs_attr->uid);
@@ -366,7 +366,7 @@ fhandler_base::fstat_by_nfs_ea (struct stat *buf)
       gid_t map_gid = ILLEGAL_GID;
 
       domain = cygheap->dom.get_rfc2307_domain ();
-      if ((ldap_open || cldap.open (domain)))
+      if ((ldap_open || cldap.open (domain) == NO_ERROR))
        map_gid = cldap.remap_gid (nfs_attr->gid);
       if (map_gid == ILLEGAL_GID)
        map_gid = MAP_UNIX_TO_CYGWIN_ID (nfs_attr->gid);
index 0010c1df96143bd39c2c42dff1eb7f736d36d288..fa19c307eca3b4af36ebb8fdbb7cae21bcddec85 100644 (file)
@@ -22,14 +22,8 @@ details. */
 #include "dsgetdc.h"
 #include "tls_pbuf.h"
 
-#define CYG_LDAP_TIMEOUT         5     /* seconds */
-#define CYG_LDAP_ENUM_TIMEOUT   60     /* seconds */
-
 #define CYG_LDAP_ENUM_PAGESIZE 100     /* entries per page */
 
-static LDAP_TIMEVAL def_tv = { CYG_LDAP_TIMEOUT, 0 };
-static LDAP_TIMEVAL enum_tv = { CYG_LDAP_ENUM_TIMEOUT, 0 };
-
 static PWCHAR rootdse_attr[] =
 {
   (PWCHAR) L"defaultNamingContext",
@@ -78,38 +72,84 @@ PWCHAR rfc2307_gid_attr[] =
   NULL
 };
 
-bool
+/* ================================================================= */
+/* Helper methods.                                                  */
+/* ================================================================= */
+
+inline int
+cyg_ldap::map_ldaperr_to_errno (ULONG lerr)
+{
+  switch (lerr)
+    {
+    case LDAP_SUCCESS:
+      return NO_ERROR;
+    case LDAP_NO_RESULTS_RETURNED:
+      /* LdapMapErrorToWin32 maps LDAP_NO_RESULTS_RETURNED to ERROR_MORE_DATA,
+        which in turn is mapped to EMSGSIZE by geterrno_from_win_error.  This
+        is SO wrong, especially considering that LDAP_MORE_RESULTS_TO_RETURN
+        is mapped to ERROR_MORE_DATA as well :-P */
+      return ENMFILE;
+    default:
+      break;
+    }
+  return geterrno_from_win_error (LdapMapErrorToWin32 (lerr));
+}
+
+inline int
+cyg_ldap::wait (cygthread *thr)
+{
+  if (!thr)
+    return EIO;
+  if (cygwait (*thr, INFINITE, cw_sig | cw_sig_eintr) != WAIT_OBJECT_0)
+    {
+      thr->terminate_thread ();
+      _my_tls.call_signal_handler ();
+      return EINTR;
+    }
+  thr->detach ();
+  return 0;
+}
+
+/* ================================================================= */
+/* Helper struct and functions for interruptible LDAP initalization. */
+/* ================================================================= */
+
+struct cyg_ldap_init {
+  cyg_ldap *that;
+  PCWSTR domain;
+  bool ssl;
+  ULONG ret;
+};
+
+ULONG
 cyg_ldap::connect_ssl (PCWSTR domain)
 {
-  ULONG ret, timelimit = CYG_LDAP_TIMEOUT;
+  ULONG ret;
 
   if (!(lh = ldap_sslinitW ((PWCHAR) domain, LDAP_SSL_PORT, 1)))
     {
       debug_printf ("ldap_init(%W) error 0x%02x", domain, LdapGetLastError ());
-      return false;
+      return LdapGetLastError ();
     }
-  if ((ret = ldap_set_option (lh, LDAP_OPT_TIMELIMIT, &timelimit))
-      != LDAP_SUCCESS)
-    debug_printf ("ldap_set_option(LDAP_OPT_TIMELIMIT) error 0x%02x", ret);
   if ((ret = ldap_bind_s (lh, NULL, NULL, LDAP_AUTH_NEGOTIATE)) != LDAP_SUCCESS)
-    {
-      debug_printf ("ldap_bind(%W) 0x%02x", domain, ret);
-      ldap_unbind (lh);
-      lh = NULL;
-      return false;
-    }
-  return true;
+    debug_printf ("ldap_bind(%W) 0x%02x", domain, ret);
+  else if ((ret = ldap_search_sW (lh, NULL, LDAP_SCOPE_BASE,
+                                 (PWCHAR) L"(objectclass=*)", rootdse_attr,
+                                 0, &msg))
+      != LDAP_SUCCESS)
+    debug_printf ("ldap_search(%W, ROOTDSE) error 0x%02x", domain, ret);
+  return ret;
 }
 
-bool
+ULONG
 cyg_ldap::connect_non_ssl (PCWSTR domain)
 {
-  ULONG ret, timelimit = CYG_LDAP_TIMEOUT;
+  ULONG ret;
 
   if (!(lh = ldap_initW ((PWCHAR) domain, LDAP_PORT)))
     {
       debug_printf ("ldap_init(%W) error 0x%02x", domain, LdapGetLastError ());
-      return false;
+      return LdapGetLastError ();
     }
   if ((ret = ldap_set_option (lh, LDAP_OPT_SIGN, LDAP_OPT_ON))
       != LDAP_SUCCESS)
@@ -117,40 +157,133 @@ cyg_ldap::connect_non_ssl (PCWSTR domain)
   if ((ret = ldap_set_option (lh, LDAP_OPT_ENCRYPT, LDAP_OPT_ON))
       != LDAP_SUCCESS)
     debug_printf ("ldap_set_option(LDAP_OPT_ENCRYPT) error 0x%02x", ret);
-  if ((ret = ldap_set_option (lh, LDAP_OPT_TIMELIMIT, &timelimit))
-      != LDAP_SUCCESS)
-    debug_printf ("ldap_set_option(LDAP_OPT_TIMELIMIT) error 0x%02x", ret);
   if ((ret = ldap_bind_s (lh, NULL, NULL, LDAP_AUTH_NEGOTIATE)) != LDAP_SUCCESS)
+    debug_printf ("ldap_bind(%W) 0x%02x", domain, ret);
+  else if ((ret = ldap_search_sW (lh, NULL, LDAP_SCOPE_BASE,
+                                 (PWCHAR) L"(objectclass=*)", rootdse_attr,
+                                 0, &msg))
+      != LDAP_SUCCESS)
+    debug_printf ("ldap_search(%W, ROOTDSE) error 0x%02x", domain, ret);
+  return ret;
+}
+
+static DWORD WINAPI
+ldap_init_thr (LPVOID param)
+{
+  cyg_ldap_init *cl = (cyg_ldap_init *) param;
+  cl->ret = cl->ssl ? cl->that->connect_ssl (cl->domain)
+                   : cl->that->connect_non_ssl (cl->domain);
+  return 0;
+}
+
+inline int
+cyg_ldap::connect (PCWSTR domain)
+{
+  /* FIXME?  connect_ssl can take ages even when failing, so we're trying to
+     do everything the non-SSL (but still encrypted) way. */
+  cyg_ldap_init cl = { this, domain, false, NO_ERROR };
+  cygthread *thr = new cygthread (ldap_init_thr, &cl, "ldap_init");
+  return wait (thr) ?: map_ldaperr_to_errno (cl.ret);
+}
+
+/* ================================================================= */
+/* Helper struct and functions for interruptible LDAP search.        */
+/* ================================================================= */
+
+struct cyg_ldap_search {
+  cyg_ldap *that;
+  PWCHAR base;
+  PWCHAR filter;
+  PWCHAR *attrs;
+  ULONG ret;
+};
+
+ULONG
+cyg_ldap::search_s (PWCHAR base, PWCHAR filter, PWCHAR *attrs)
+{
+  ULONG ret;
+  
+  if ((ret = ldap_search_sW (lh, base, LDAP_SCOPE_SUBTREE, filter,
+                            attrs, 0, &msg)) != LDAP_SUCCESS)
+    debug_printf ("ldap_search_sW(%W,%W) error 0x%02x", base, filter, ret);
+  return ret;
+}
+
+static DWORD WINAPI
+ldap_search_thr (LPVOID param)
+{
+  cyg_ldap_search *cl = (cyg_ldap_search *) param;
+  cl->ret = cl->that->search_s (cl->base, cl->filter, cl->attrs);
+  return 0;
+}
+
+inline int
+cyg_ldap::search (PWCHAR base, PWCHAR filter, PWCHAR *attrs)
+{
+  cyg_ldap_search cl = { this, base, filter, attrs, NO_ERROR };
+  cygthread *thr = new cygthread (ldap_search_thr, &cl, "ldap_search");
+  return wait (thr) ?: map_ldaperr_to_errno (cl.ret);
+}
+
+/* ================================================================= */
+/* Helper struct and functions for interruptible LDAP page search.        */
+/* ================================================================= */
+
+struct cyg_ldap_next_page {
+  cyg_ldap *that;
+  ULONG ret;
+};
+
+ULONG
+cyg_ldap::next_page_s ()
+{
+  ULONG total;
+  ULONG ret;
+  
+  do
     {
-      debug_printf ("ldap_bind(%W) 0x%02x", domain, ret);
-      ldap_unbind (lh);
-      lh = NULL;
-      return false;
+      ret = ldap_get_next_page_s (lh, srch_id, NULL, CYG_LDAP_ENUM_PAGESIZE,
+                                 &total, &srch_msg);
     }
-  return true;
+  while (ret == LDAP_SUCCESS && ldap_count_entries (lh, srch_msg) == 0);
+  if (ret && ret != LDAP_NO_RESULTS_RETURNED)
+    debug_printf ("ldap_result() error 0x%02x", ret);
+  return ret;
 }
 
-bool
+static DWORD WINAPI
+ldap_next_page_thr (LPVOID param)
+{
+  cyg_ldap_next_page *cl = (cyg_ldap_next_page *) param;
+  cl->ret = cl->that->next_page_s ();
+  return 0;
+}
+
+inline int
+cyg_ldap::next_page ()
+{
+  cyg_ldap_next_page cl = { this, NO_ERROR };
+  cygthread *thr = new cygthread (ldap_next_page_thr, &cl, "ldap_next_page");
+  return wait (thr) ?: map_ldaperr_to_errno (cl.ret);
+}
+
+/* ================================================================= */
+/* Public methods.                                                  */
+/* ================================================================= */
+
+int
 cyg_ldap::open (PCWSTR domain)
 {
-  ULONG ret;
+  int ret = 0;
 
   /* Already open? */
   if (lh)
-    return true;
+    return 0;
 
-  /* FIXME?  connect_ssl can take ages even when failing, so we're trying to
-     do everything the non-SSL (but still encrypted) way. */
-  if (/*!connect_ssl (NULL) && */ !connect_non_ssl (domain))
-    return false;
-  if ((ret = ldap_search_stW (lh, NULL, LDAP_SCOPE_BASE,
-                             (PWCHAR) L"(objectclass=*)", rootdse_attr,
-                             0, &def_tv, &msg))
-      != LDAP_SUCCESS)
-    {
-      debug_printf ("ldap_search(%W, ROOTDSE) error 0x%02x", domain, ret);
-      goto err;
-    }
+  if ((ret = connect (domain)) != NO_ERROR)
+    goto err;
+  /* Prime `ret' and fetch ROOTDSE search result. */
+  ret = EIO;
   if (!(entry = ldap_first_entry (lh, msg)))
     {
       debug_printf ("No ROOTDSE entry for %W", domain);
@@ -179,10 +312,11 @@ cyg_ldap::open (PCWSTR domain)
   ldap_value_freeW (val);
   val = NULL;
   ldap_msgfree (msg);
-  msg = entry = NULL; return true;
+  msg = entry = NULL;
+  return 0;
 err:
   close ();
-  return false;
+  return ret;
 }
 
 void
@@ -215,7 +349,6 @@ cyg_ldap::fetch_ad_account (PSID sid, bool group, PCWSTR domain)
   LONG len = (LONG) RtlLengthSid (sid);
   PBYTE s = (PBYTE) sid;
   static WCHAR hex_wchars[] = L"0123456789abcdef";
-  ULONG ret;
   tmp_pathbuf tp;
 
   if (msg)
@@ -256,13 +389,8 @@ cyg_ldap::fetch_ad_account (PSID sid, bool group, PCWSTR domain)
        }
     }
   attr = group ? group_attr : user_attr;
-  if ((ret = ldap_search_stW (lh, rdse, LDAP_SCOPE_SUBTREE, filter,
-                             attr, 0, &def_tv, &msg)) != LDAP_SUCCESS)
-    {
-      debug_printf ("ldap_search_stW(%W,%W) error 0x%02x",
-                   rdse, filter, ret);
+  if (search (rdse, filter, attr) != 0)
       return false;
-    }
   if (!(entry = ldap_first_entry (lh, msg)))
     {
       debug_printf ("No entry for %W in rootdse %W", filter, rdse);
@@ -271,15 +399,16 @@ cyg_ldap::fetch_ad_account (PSID sid, bool group, PCWSTR domain)
   return true;
 }
 
-bool
+int
 cyg_ldap::enumerate_ad_accounts (PCWSTR domain, bool group)
 {
+  int ret;
   tmp_pathbuf tp;
   PCWSTR filter;
 
   close ();
-  if (!open (domain))
-    return false;
+  if ((ret = open (domain)) != NO_ERROR)
+    return ret;
 
   if (!group)
     filter = L"(&(objectClass=User)"
@@ -296,26 +425,23 @@ cyg_ldap::enumerate_ad_accounts (PCWSTR domain, bool group)
                "(!(groupType:" LDAP_MATCHING_RULE_BIT_AND ":=1))"
                "(objectSid=*))";
   srch_id = ldap_search_init_pageW (lh, rootdse, LDAP_SCOPE_SUBTREE,
-                                   (PWCHAR) filter, sid_attr, 0,
-                                   NULL, NULL, CYG_LDAP_ENUM_TIMEOUT,
-                                   CYG_LDAP_ENUM_PAGESIZE, NULL);
+                                   (PWCHAR) filter, sid_attr, 0, NULL, NULL,
+                                   INFINITE, CYG_LDAP_ENUM_PAGESIZE, NULL);
   if (srch_id == NULL)
     {
       debug_printf ("ldap_search_init_pageW(%W,%W) error 0x%02x",
                    rootdse, filter, LdapGetLastError ());
-      return false;
+      return map_ldaperr_to_errno (LdapGetLastError ());
     }
-  return true;
+  return NO_ERROR;
 }
 
-bool
+int
 cyg_ldap::next_account (cygsid &sid)
 {
   ULONG ret;
   PLDAP_BERVAL *bval;
 
-  ULONG total;
-
   if (srch_entry)
     {
       if ((srch_entry = ldap_next_entry (lh, srch_entry))
@@ -323,38 +449,32 @@ cyg_ldap::next_account (cygsid &sid)
        {
          sid = (PSID) bval[0]->bv_val;
          ldap_value_free_len (bval);
-         return true;
+         return NO_ERROR;
        }
       ldap_msgfree (srch_msg);
       srch_msg = srch_entry = NULL;
     }
-  do
-    {
-      ret = ldap_get_next_page_s (lh, srch_id, &enum_tv, CYG_LDAP_ENUM_PAGESIZE,
-                                 &total, &srch_msg);
-    }
-  while (ret == LDAP_SUCCESS && ldap_count_entries (lh, srch_msg) == 0);
-  if (ret == LDAP_NO_RESULTS_RETURNED)
-    ;
-  else if (ret != LDAP_SUCCESS)
-    debug_printf ("ldap_result() error 0x%02x", ret);
-  else if ((srch_entry = ldap_first_entry (lh, srch_msg))
-          && (bval = ldap_get_values_lenW (lh, srch_entry, sid_attr[0])))
+  ret = next_page ();
+  if (ret == NO_ERROR)
     {
-      sid = (PSID) bval[0]->bv_val;
-      ldap_value_free_len (bval);
-      return true;
+      if ((srch_entry = ldap_first_entry (lh, srch_msg))
+         && (bval = ldap_get_values_lenW (lh, srch_entry, sid_attr[0])))
+       {
+         sid = (PSID) bval[0]->bv_val;
+         ldap_value_free_len (bval);
+         return NO_ERROR;
+       }
+      ret = EIO;
     }
   ldap_search_abandon_page (lh, srch_id);
   srch_id = NULL;
-  return false;
+  return ret;
 }
 
 uint32_t
 cyg_ldap::fetch_posix_offset_for_domain (PCWSTR domain)
 {
   WCHAR filter[300];
-  ULONG ret;
 
   if (msg)
     {
@@ -370,14 +490,8 @@ cyg_ldap::fetch_posix_offset_for_domain (PCWSTR domain)
      by flatName rather than by name. */
   __small_swprintf (filter, L"(&(objectClass=trustedDomain)(%W=%W))",
                    wcschr (domain, L'.') ? L"name" : L"flatName", domain);
-  if ((ret = ldap_search_stW (lh, rootdse, LDAP_SCOPE_SUBTREE, filter,
-                             attr = tdom_attr, 0, &def_tv, &msg))
-      != LDAP_SUCCESS)
-    {
-      debug_printf ("ldap_search_stW(%W,%W) error 0x%02x",
-                   rootdse, filter, ret);
-      return 0;
-    }
+  if (search (rootdse, filter, attr = tdom_attr) != 0)
+    return 0;
   if (!(entry = ldap_first_entry (lh, msg)))
     {
       debug_printf ("No entry for %W in rootdse %W", filter, rootdse);
@@ -410,7 +524,6 @@ bool
 cyg_ldap::fetch_unix_sid_from_ad (uint32_t id, cygsid &sid, bool group)
 {
   WCHAR filter[48];
-  ULONG ret;
   PLDAP_BERVAL *bval;
 
   if (msg)
@@ -422,13 +535,8 @@ cyg_ldap::fetch_unix_sid_from_ad (uint32_t id, cygsid &sid, bool group)
     __small_swprintf (filter, L"(&(objectClass=Group)(gidNumber=%u))", id);
   else
     __small_swprintf (filter, L"(&(objectClass=User)(uidNumber=%u))", id);
-  if ((ret = ldap_search_stW (lh, rootdse, LDAP_SCOPE_SUBTREE, filter,
-                             sid_attr, 0, &def_tv, &msg)) != LDAP_SUCCESS)
-    {
-      debug_printf ("ldap_search_stW(%W,%W) error 0x%02x",
-                   rootdse, filter, ret);
-      return false;
-    }
+  if (search (rootdse, filter, sid_attr) != 0)
+    return false;
   if ((entry = ldap_first_entry (lh, msg))
       && (bval = ldap_get_values_lenW (lh, entry, sid_attr[0])))
     {
@@ -443,7 +551,6 @@ PWCHAR
 cyg_ldap::fetch_unix_name_from_rfc2307 (uint32_t id, bool group)
 {
   WCHAR filter[52];
-  ULONG ret;
 
   if (msg)
     {
@@ -461,13 +568,8 @@ cyg_ldap::fetch_unix_name_from_rfc2307 (uint32_t id, bool group)
   else
     __small_swprintf (filter, L"(&(objectClass=posixAccount)(uidNumber=%u))",
                      id);
-  if ((ret = ldap_search_stW (lh, rootdse, LDAP_SCOPE_SUBTREE, filter, attr,
-                             0, &def_tv, &msg)) != LDAP_SUCCESS)
-    {
-      debug_printf ("ldap_search_stW(%W,%W) error 0x%02x",
-                   rootdse, filter, ret);
-      return NULL;
-    }
+  if (search (rootdse, filter, attr) != 0)
+    return NULL;
   if (!(entry = ldap_first_entry (lh, msg)))
     {
       debug_printf ("No entry for %W in rootdse %W", filter, rootdse);
index 696fbebe0aa509edd46907623144771c22ed6ad2..7f90a3821d571116b09cace4e6fe3037f171b1b9 100644 (file)
@@ -36,8 +36,11 @@ class cyg_ldap {
   PLDAPSearch srch_id;
   PLDAPMessage srch_msg, srch_entry;
 
-  bool connect_ssl (PCWSTR domain);
-  bool connect_non_ssl (PCWSTR domain);
+  inline int map_ldaperr_to_errno (ULONG lerr);
+  inline int wait (cygthread *thr);
+  inline int connect (PCWSTR domain);
+  inline int search (PWCHAR base, PWCHAR filter, PWCHAR *attrs);
+  inline int next_page ();
   bool fetch_unix_sid_from_ad (uint32_t id, cygsid &sid, bool group);
   PWCHAR fetch_unix_name_from_rfc2307 (uint32_t id, bool group);
   PWCHAR get_string_attribute (int idx);
@@ -49,12 +52,17 @@ public:
   {}
   ~cyg_ldap () { close (); }
 
+  ULONG connect_ssl (PCWSTR domain);
+  ULONG connect_non_ssl (PCWSTR domain);
+  ULONG search_s (PWCHAR base, PWCHAR filter, PWCHAR *attrs);
+  ULONG next_page_s ();
+
   operator PLDAP () const { return lh; }
-  bool open (PCWSTR in_domain);
+  int open (PCWSTR in_domain);
   void close ();
   bool fetch_ad_account (PSID sid, bool group, PCWSTR domain = NULL);
-  bool enumerate_ad_accounts (PCWSTR domain, bool group);
-  bool next_account (cygsid &sid);
+  int enumerate_ad_accounts (PCWSTR domain, bool group);
+  int next_account (cygsid &sid);
   uint32_t fetch_posix_offset_for_domain (PCWSTR domain);
   uid_t remap_uid (uid_t uid);
   gid_t remap_gid (gid_t gid);
index 4482ce12470b2ea6dc9b2c6b73928f7b28667cc9..928633559db0e6c457abcd784ab7e1a2e06a0f84 100644 (file)
@@ -593,13 +593,19 @@ pg_ent::enumerate_ad ()
       if (!cnt)
        {
          PDS_DOMAIN_TRUSTSW td;
+         int ret;
 
          if (!resume)
            {
              ++resume;
-             if (!nss_db_enum_primary ()
-                 || !cldap.enumerate_ad_accounts (NULL, group))
+             if (!nss_db_enum_primary ())
                continue;
+             if ((ret = cldap.enumerate_ad_accounts (NULL, group)) != NO_ERROR)
+               {
+                 cldap.close ();
+                 set_errno (ret);
+                 return NULL;
+               }
            }
          else if ((td = cygheap->dom.trusted_domain (resume - 1)))
            {
@@ -612,9 +618,15 @@ pg_ent::enumerate_ad ()
              if (((enums & ENUM_TDOMS_ALL) && td->Flags & DS_DOMAIN_PRIMARY)
                  || !td->DomainSid
                  || (!nss_db_enum_tdom (td->NetbiosDomainName)
-                     && !nss_db_enum_tdom (td->DnsDomainName))
-                 || !cldap.enumerate_ad_accounts (td->DnsDomainName, group))
+                     && !nss_db_enum_tdom (td->DnsDomainName)))
                continue;
+             if ((ret = cldap.enumerate_ad_accounts (td->DnsDomainName, group))
+                 != NO_ERROR)
+               {
+                 cldap.close ();
+                 set_errno (ret);
+                 return NULL;
+               }
            }
          else
            {
@@ -624,7 +636,8 @@ pg_ent::enumerate_ad ()
        }
       ++cnt;
       cygsid sid;
-      if (cldap.next_account (sid))
+      int ret = cldap.next_account (sid);
+      if (ret == NO_ERROR)
        {
          fetch_user_arg_t arg;
          arg.type = SID_arg;
@@ -632,6 +645,13 @@ pg_ent::enumerate_ad ()
          char *line = pg.fetch_account_from_windows (arg, &cldap);
          if (line)
            return pg.add_account_post_fetch (line, false);
+         ret = EIO;
+       }
+      if (ret != ENMFILE)
+       {
+         cldap.close ();
+         set_errno (ret);
+         return NULL;
        }
       cnt = 0;
     }
index 00123935b380db2767190d0d2ed156054af323fc..946e78a8e98cae7f4d03f3150d618b5a36db4a50 100644 (file)
@@ -122,7 +122,7 @@ cygpsid::get_id (BOOL search_grp, int *type, cyg_ldap *pldap)
          gid_t map_gid = cygheap->ugid_cache.get_gid (gid);
          if (map_gid == ILLEGAL_GID)
            {
-             if (pldap->open (cygheap->dom.get_rfc2307_domain ()))
+             if (pldap->open (cygheap->dom.get_rfc2307_domain ()) == NO_ERROR)
                map_gid = pldap->remap_gid (gid);
              if (map_gid == ILLEGAL_GID) 
                map_gid = MAP_UNIX_TO_CYGWIN_ID (gid);
@@ -151,7 +151,7 @@ cygpsid::get_id (BOOL search_grp, int *type, cyg_ldap *pldap)
          uid_t map_uid = cygheap->ugid_cache.get_uid (uid);
          if (map_uid == ILLEGAL_UID)
            {
-             if (pldap->open (cygheap->dom.get_rfc2307_domain ()))
+             if (pldap->open (cygheap->dom.get_rfc2307_domain ()) == NO_ERROR)
                map_uid = pldap->remap_uid (uid);
              if (map_uid == ILLEGAL_UID)
                map_uid = MAP_UNIX_TO_CYGWIN_ID (uid);
index 2b91835f156696ecf87643369202cace0839dab3..cc757f9fe66f8864576b79b05c33cf6e3ea23d1a 100644 (file)
@@ -1141,7 +1141,7 @@ fetch_posix_offset (PDS_DOMAIN_TRUSTSW td, cyg_ldap *cldap)
 
   if (!td->PosixOffset && !(td->Flags & DS_DOMAIN_PRIMARY) && td->DomainSid)
     {
-      if (!cldap->open (NULL))
+      if (cldap->open (NULL) != NO_ERROR)
        {
          /* We're probably running under a local account, so we're not allowed
             to fetch any information from AD beyond the most obvious.  Never
@@ -1241,7 +1241,7 @@ pwdgrp::fetch_account_from_windows (fetch_user_arg_t &arg, cyg_ldap *pldap)
             DC for some weird reason.  Use LDAP instead. */
          PWCHAR val;
 
-         if (cldap->open (NULL)
+         if (cldap->open (NULL) == NO_ERROR
              && cldap->fetch_ad_account (sid, is_group ())
              && (val = cldap->get_group_name ()))
            {
@@ -1598,7 +1598,7 @@ pwdgrp::fetch_account_from_windows (fetch_user_arg_t &arg, cyg_ldap *pldap)
          if (is_domain_account)
            {
              /* Use LDAP to fetch domain account infos. */
-             if (!cldap->open (NULL))
+             if (cldap->open (NULL) != NO_ERROR)
                break;
              if (cldap->fetch_ad_account (sid, is_group (), domain))
                {
This page took 0.054264 seconds and 5 git commands to generate.