s3-libads: Use a reducing page size to try and cope with a slow LDAP server
[samba.git] / source3 / libads / ldap.c
index 102fc83d0fc92048ab964a9c23537c9dd048ace0..99ec2e46dc6d0edf15d500ba3cc99e507df2f0ea 100644 (file)
@@ -192,29 +192,42 @@ static bool ads_try_connect(ADS_STRUCT *ads, const char *server, bool gc)
 {
        char *srv;
        struct NETLOGON_SAM_LOGON_RESPONSE_EX cldap_reply;
-       TALLOC_CTX *mem_ctx = NULL;
+       TALLOC_CTX *frame = talloc_stackframe();
        bool ret = false;
 
        if (!server || !*server) {
+               TALLOC_FREE(frame);
                return False;
        }
 
-       DEBUG(5,("ads_try_connect: sending CLDAP request to %s (realm: %s)\n", 
-               server, ads->server.realm));
+       if (!is_ipaddress(server)) {
+               struct sockaddr_storage ss;
+               char addr[INET6_ADDRSTRLEN];
 
-       mem_ctx = talloc_init("ads_try_connect");
-       if (!mem_ctx) {
-               DEBUG(0,("out of memory\n"));
-               return false;
+               if (!resolve_name(server, &ss, 0x20, true)) {
+                       DEBUG(5,("ads_try_connect: unable to resolve name %s\n",
+                               server ));
+                       TALLOC_FREE(frame);
+                       return false;
+               }
+               print_sockaddr(addr, sizeof(addr), &ss);
+               srv = talloc_strdup(frame, addr);
+       } else {
+               /* this copes with inet_ntoa brokenness */
+               srv = talloc_strdup(frame, server);
        }
 
-       /* this copes with inet_ntoa brokenness */
+       if (!srv) {
+               TALLOC_FREE(frame);
+               return false;
+       }
 
-       srv = SMB_STRDUP(server);
+       DEBUG(5,("ads_try_connect: sending CLDAP request to %s (realm: %s)\n", 
+               srv, ads->server.realm));
 
        ZERO_STRUCT( cldap_reply );
 
-       if ( !ads_cldap_netlogon_5(mem_ctx, srv, ads->server.realm, &cldap_reply ) ) {
+       if ( !ads_cldap_netlogon_5(frame, srv, ads->server.realm, &cldap_reply ) ) {
                DEBUG(3,("ads_try_connect: CLDAP request %s failed.\n", srv));
                ret = false;
                goto out;
@@ -267,10 +280,10 @@ static bool ads_try_connect(ADS_STRUCT *ads, const char *server, bool gc)
        sitename_store( cldap_reply.dns_domain, cldap_reply.client_site);
 
        ret = true;
+
  out:
-       SAFE_FREE(srv);
-       TALLOC_FREE(mem_ctx);
 
+       TALLOC_FREE(frame);
        return ret;
 }
 
@@ -911,11 +924,11 @@ static ADS_STATUS ads_do_paged_search_args(ADS_STRUCT *ads,
 
        cookie_be = ber_alloc_t(LBER_USE_DER);
        if (*cookie) {
-               ber_printf(cookie_be, "{iO}", (ber_int_t) 1000, *cookie);
+               ber_printf(cookie_be, "{iO}", (ber_int_t) ads->config.ldap_page_size, *cookie);
                ber_bvfree(*cookie); /* don't need it from last time */
                *cookie = NULL;
        } else {
-               ber_printf(cookie_be, "{io}", (ber_int_t) 1000, "", 0);
+               ber_printf(cookie_be, "{io}", (ber_int_t) ads->config.ldap_page_size, "", 0);
        }
        ber_flatten(cookie_be, &cookie_bv);
        PagedResults.ldctl_oid = CONST_DISCARD(char *, ADS_PAGE_CTL_OID);
@@ -2076,7 +2089,7 @@ ADS_STATUS ads_move_machine_acct(ADS_STRUCT *ads, const char *machine_name,
 done:
        ads_msgfree(ads, res);
        SAFE_FREE(filter);
-       SAFE_FREE(computer_dn);
+       TALLOC_FREE(computer_dn);
        SAFE_FREE(computer_rdn);
 
        if (!ADS_ERR_OK(rc)) {
@@ -2128,7 +2141,9 @@ static void dump_sid(ADS_STRUCT *ads, const char *field, struct berval **values)
        for (i=0; values[i]; i++) {
                DOM_SID sid;
                fstring tmp;
-               sid_parse(values[i]->bv_val, values[i]->bv_len, &sid);
+               if (!sid_parse(values[i]->bv_val, values[i]->bv_len, &sid)) {
+                       continue;
+               }
                printf("%s: %s\n", field, sid_to_fstring(tmp, &sid));
        }
 }
@@ -3842,39 +3857,36 @@ ADS_STATUS ads_check_ou_dn(TALLOC_CTX *mem_ctx,
                           ADS_STRUCT *ads,
                           const char **account_ou)
 {
-       struct ldb_dn *name_dn = NULL;
-       const char *name = NULL;
-       char *ou_string = NULL;
-       struct ldb_context *ldb = ldb_init(mem_ctx, NULL);
+       char **exploded_dn;
+       const char *name;
+       char *ou_string;
 
-       name_dn = ldb_dn_new(mem_ctx, ldb, *account_ou);
-       if (name_dn && ldb_dn_validate(name_dn)) {
-               talloc_free(ldb);
+       exploded_dn = ldap_explode_dn(*account_ou, 0);
+       if (exploded_dn) {
+               ldap_value_free(exploded_dn);
                return ADS_SUCCESS;
        }
 
        ou_string = ads_ou_string(ads, *account_ou);
        if (!ou_string) {
-               talloc_free(ldb);
                return ADS_ERROR_LDAP(LDAP_INVALID_DN_SYNTAX);
        }
 
-       name_dn = ldb_dn_new_fmt(mem_ctx, ldb, "%s,%s", ou_string,
-                                ads->config.bind_path);
+       name = talloc_asprintf(mem_ctx, "%s,%s", ou_string,
+                              ads->config.bind_path);
        SAFE_FREE(ou_string);
 
-       if (!name_dn || !ldb_dn_validate(name_dn)) {
-               talloc_free(ldb);
-               return ADS_ERROR_LDAP(LDAP_INVALID_DN_SYNTAX);
+       if (!name) {
+               return ADS_ERROR_LDAP(LDAP_NO_MEMORY);
        }
 
-       *account_ou = talloc_strdup(mem_ctx, name);
-       if (!*account_ou) {
-               talloc_free(ldb);
-               return ADS_ERROR_LDAP(LDAP_NO_MEMORY);
+       exploded_dn = ldap_explode_dn(name, 0);
+       if (!exploded_dn) {
+               return ADS_ERROR_LDAP(LDAP_INVALID_DN_SYNTAX);
        }
+       ldap_value_free(exploded_dn);
 
-       talloc_free(ldb);
+       *account_ou = name;
        return ADS_SUCCESS;
 }