s3:libads: Fix creating machine account using LDAP
[bbaumbach/samba-autobuild/.git] / source3 / libads / ldap_utils.c
index 0c0796115308fe4683dffb5e06beb1b78dcf9510..c9039684bf00508903f4d41420841e7026bd9b45 100644 (file)
@@ -5,25 +5,41 @@
 
    Copyright (C) Andrew Tridgell 2001
    Copyright (C) Guenther Deschner 2006,2007
-   
+
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
-   
+
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
-   
+
    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
 #include "includes.h"
 #include "ads.h"
+#include "lib/param/loadparm.h"
 
 #ifdef HAVE_LDAP
+
+static ADS_STATUS ads_ranged_search_internal(ADS_STRUCT *ads,
+                                            TALLOC_CTX *mem_ctx,
+                                            int scope,
+                                            const char *base,
+                                            const char *filter,
+                                            const char **attrs,
+                                            void *args,
+                                            const char *range_attr,
+                                            char ***strings,
+                                            size_t *num_strings,
+                                            uint32_t *first_usn,
+                                            int *num_retries,
+                                            bool *more_values);
+
 /*
   a wrapper around ldap_search_s that retries depending on the error code
   this is supposed to catch dropped connections and auto-reconnect
@@ -33,7 +49,7 @@ static ADS_STATUS ads_do_search_retry_internal(ADS_STRUCT *ads, const char *bind
                                               const char **attrs, void *args,
                                               LDAPMessage **res)
 {
-       ADS_STATUS status = ADS_SUCCESS;
+       ADS_STATUS status;
        int count = 3;
        char *bp;
 
@@ -69,20 +85,38 @@ static ADS_STATUS ads_do_search_retry_internal(ADS_STRUCT *ads, const char *bind
 
        while (--count) {
 
+               if (NT_STATUS_EQUAL(ads_ntstatus(status), NT_STATUS_IO_TIMEOUT) &&
+                   ads->config.ldap_page_size >= (lp_ldap_page_size() / 4) &&
+                   lp_ldap_page_size() > 4) {
+                       int new_page_size = (ads->config.ldap_page_size / 2);
+                       DEBUG(1, ("Reducing LDAP page size from %d to %d due to IO_TIMEOUT\n",
+                                 ads->config.ldap_page_size, new_page_size));
+                       ads->config.ldap_page_size = new_page_size;
+               }
+
                if (*res) 
                        ads_msgfree(ads, *res);
                *res = NULL;
-               
+
                DEBUG(3,("Reopening ads connection to realm '%s' after error %s\n", 
                         ads->config.realm, ads_errstr(status)));
-                        
+
                ads_disconnect(ads);
                status = ads_connect(ads);
-               
+
                if (!ADS_ERR_OK(status)) {
+                       bool orig_is_mine = ads->is_mine;
+
                        DEBUG(1,("ads_search_retry: failed to reconnect (%s)\n",
                                 ads_errstr(status)));
+                       /*
+                        * We need to keep the ads pointer
+                        * from being freed here as we don't own it and
+                        * callers depend on it being around.
+                        */
+                       ads->is_mine = false;
                        ads_destroy(&ads);
+                       ads->is_mine = orig_is_mine;
                        SAFE_FREE(bp);
                        return status;
                }
@@ -121,10 +155,10 @@ static ADS_STATUS ads_do_search_retry_internal(ADS_STRUCT *ads, const char *bind
        return ads_do_search_retry_internal(ads, bind_path, scope, expr, attrs, NULL, res);
 }
 
- ADS_STATUS ads_do_search_retry_args(ADS_STRUCT *ads, const char *bind_path,
-                                    int scope, const char *expr,
-                                    const char **attrs, void *args,
-                                    LDAPMessage **res)
+static ADS_STATUS ads_do_search_retry_args(ADS_STRUCT *ads, const char *bind_path,
+                                          int scope, const char *expr,
+                                          const char **attrs, void *args,
+                                          LDAPMessage **res)
 {
        return ads_do_search_retry_internal(ads, bind_path, scope, expr, attrs, args, res);
 }
@@ -145,23 +179,8 @@ static ADS_STATUS ads_do_search_retry_internal(ADS_STRUCT *ads, const char *bind
                                   "(objectclass=*)", attrs, res);
 }
 
- ADS_STATUS ads_search_retry_extended_dn(ADS_STRUCT *ads, LDAPMessage **res, 
-                                        const char *dn, 
-                                        const char **attrs,
-                                        enum ads_extended_dn_flags flags)
-{
-       ads_control args;
-
-       args.control = ADS_EXTENDED_DN_OID;
-       args.val = flags;
-       args.critical = True;
-
-       return ads_do_search_retry_args(ads, dn, LDAP_SCOPE_BASE,
-                                       "(objectclass=*)", attrs, &args, res);
-}
-
  ADS_STATUS ads_search_retry_dn_sd_flags(ADS_STRUCT *ads, LDAPMessage **res, 
-                                        uint32 sd_flags,
+                                        uint32_t sd_flags,
                                         const char *dn, 
                                         const char **attrs)
 {
@@ -205,21 +224,21 @@ static ADS_STATUS ads_do_search_retry_internal(ADS_STRUCT *ads, const char *bind
 {
        char *dn, *sid_string;
        ADS_STATUS status;
-       
-       sid_string = sid_binstring_hex(sid);
+
+       sid_string = sid_binstring_hex_talloc(talloc_tos(), sid);
        if (sid_string == NULL) {
                return ADS_ERROR(LDAP_NO_MEMORY);
        }
 
        if (!asprintf(&dn, "<SID=%s>", sid_string)) {
-               SAFE_FREE(sid_string);
+               TALLOC_FREE(sid_string);
                return ADS_ERROR(LDAP_NO_MEMORY);
        }
 
        status = ads_do_search_retry(ads, dn, LDAP_SCOPE_BASE,
                                   "(objectclass=*)", attrs, res);
        SAFE_FREE(dn);
-       SAFE_FREE(sid_string);
+       TALLOC_FREE(sid_string);
        return status;
 }
 
@@ -234,7 +253,7 @@ ADS_STATUS ads_ranged_search(ADS_STRUCT *ads,
                             size_t *num_strings)
 {
        ADS_STATUS status;
-       uint32 first_usn;
+       uint32_t first_usn;
        int num_retries = 0;
        const char **attrs;
        bool more_values = False;
@@ -242,7 +261,7 @@ ADS_STATUS ads_ranged_search(ADS_STRUCT *ads,
        *num_strings = 0;
        *strings = NULL;
 
-       attrs = TALLOC_ARRAY(mem_ctx, const char *, 3);
+       attrs = talloc_array(mem_ctx, const char *, 3);
        ADS_ERROR_HAVE_NO_MEMORY(attrs);
 
        attrs[0] = talloc_strdup(mem_ctx, range_attr);
@@ -278,7 +297,7 @@ ADS_STATUS ads_ranged_search(ADS_STRUCT *ads,
        return status;
 }
 
-ADS_STATUS ads_ranged_search_internal(ADS_STRUCT *ads, 
+static ADS_STATUS ads_ranged_search_internal(ADS_STRUCT *ads,
                                      TALLOC_CTX *mem_ctx,
                                      int scope,
                                      const char *base,
@@ -288,14 +307,14 @@ ADS_STATUS ads_ranged_search_internal(ADS_STRUCT *ads,
                                      const char *range_attr,
                                      char ***strings,
                                      size_t *num_strings,
-                                     uint32 *first_usn,
+                                     uint32_t *first_usn,
                                      int *num_retries,
                                      bool *more_values)
 {
        LDAPMessage *res = NULL;
        ADS_STATUS status;
        int count;
-       uint32 current_usn;
+       uint32_t current_usn;
 
        DEBUG(10, ("Searching for attrs[0] = %s, attrs[1] = %s\n", attrs[0], attrs[1]));
 
@@ -308,7 +327,7 @@ ADS_STATUS ads_ranged_search_internal(ADS_STRUCT *ads,
                         ads_errstr(status)));
                return status;
        }
-       
+
        if (!res) {
                return ADS_ERROR(LDAP_NO_MEMORY);
        }