The branch, master has been updated
       via  cf0cfa03ac6 s3: libads: Don't re-do DNS lookups in 
ads_domain_func_level() if not needed.
       via  1d066f37b92 s3: libads: Don't re-do DNS lookups in 
ads_current_time() if not needed.
       via  c863cc2ba34 s3: libads: ads_connect can be passed in an ADS_STRUCT 
with an existing IP address.
       via  6b47f3dbbcd s3: libads: In ads_connect(), and ads_disconnect(), 
replace ZERO_STRUCT(ads->ldap) with calls to ads_zero_ldap(ads)
       via  61895749f54 s3: libads: Where we implicitly zero out ads->ldap in 
ads_init() or ads_destroy() ensure we call ads_zero_ldap() after.
       via  0535a265f94 s3: libads: Add utility function ads_zero_ldap().
      from  8bb6a6607da ctdb-recoverd: Broadcast takeover run message when 
verifying IPs

https://git.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit cf0cfa03ac6fd4c4e2c7d86079796079754f3cf2
Author: Jeremy Allison <[email protected]>
Date:   Wed Jul 22 19:03:23 2020 -0700

    s3: libads: Don't re-do DNS lookups in ads_domain_func_level() if not 
needed.
    
    ADS_STRUCT may be being reused after a
    DC lookup from ads_find_dc(), so ads->ldap.ss may already have a
    good address (even if ads->server.ldap_server == NULL).
    Only re-initialize the ADS_STRUCT and redo the ads_find_fc()
    DNS lookups if we have to.
    
    Signed-off-by: Jeremy Allison <[email protected]>
    Reviewed-by: Andreas Schneider <[email protected]>
    
    Autobuild-User(master): Andreas Schneider <[email protected]>
    Autobuild-Date(master): Tue Aug 18 09:46:28 UTC 2020 on sn-devel-184

commit 1d066f37b9217a475b6b84a935ad51fbec88fe04
Author: Jeremy Allison <[email protected]>
Date:   Wed Jul 22 19:00:52 2020 -0700

    s3: libads: Don't re-do DNS lookups in ads_current_time() if not needed.
    
    ADS_STRUCT may be being reused after a
    DC lookup from ads_find_dc(), so ads->ldap.ss may already have a
    good address (even if ads->server.ldap_server == NULL).
    Only re-initialize the ADS_STRUCT and redo the ads_find_fc()
    DNS lookups if we have to.
    
    Signed-off-by: Jeremy Allison <[email protected]>
    Reviewed-by: Andreas Schneider <[email protected]>

commit c863cc2ba34025731a18ac735f714b5b888504da
Author: Jeremy Allison <[email protected]>
Date:   Wed Jul 22 15:35:43 2020 -0700

    s3: libads: ads_connect can be passed in an ADS_STRUCT with an existing IP 
address.
    
    ads_connect can be passed in a reused ADS_STRUCT
    with an existing ads->ldap.ss IP address that
    is stored by going through ads_find_dc()
    if ads->server.ldap_server was NULL.
    
    If ads->server.ldap_server is still NULL but
    the target address isn't a zero ip address,
    then store it off before zeroing out ads->ldap
    so we don't keep doing multiple calls to
    ads_find_dc() in the reuse case.
    
    If a caller wants a clean ADS_STRUCT they
    will re-initialize by calling ads_init(), or
    call ads_destroy() both of which ensures
    ads->ldap.ss is a correctly zero'ed out IP address
    by using ads_zero_ldap().
    
    Signed-off-by: Jeremy Allison <[email protected]>
    Reviewed-by: Andreas Schneider <[email protected]>

commit 6b47f3dbbcdb692e46237aa1d9aeeb944a78b308
Author: Jeremy Allison <[email protected]>
Date:   Fri Aug 7 20:24:07 2020 -0700

    s3: libads: In ads_connect(), and ads_disconnect(), replace 
ZERO_STRUCT(ads->ldap) with calls to ads_zero_ldap(ads)
    
    This clears out the memory, but also leaves ads->ldap as a valid (zero) 
IPaddr.
    Otherwise it's left by accident as AF_UNSPEC (0).
    
    Signed-off-by: Jeremy Allison <[email protected]>
    Reviewed-by: Andreas Schneider <[email protected]>

commit 61895749f54abc44dd793bc4d0abf179c0d02987
Author: Jeremy Allison <[email protected]>
Date:   Fri Aug 7 20:22:50 2020 -0700

    s3: libads: Where we implicitly zero out ads->ldap in ads_init() or 
ads_destroy() ensure we call ads_zero_ldap() after.
    
    For ads_destroy(), this has a mode where the memory is not destroyed
    but is being re-initialized. Horrid, but that's the way it works right
    now.
    
    This clears out the memory, but also leaves ads->ldap as a valid (zero) 
IPaddr.
    Otherwise it's left by accident as AF_UNSPEC (0).
    
    Signed-off-by: Jeremy Allison <[email protected]>
    Reviewed-by: Andreas Schneider <[email protected]>

commit 0535a265f94e0f828d0b8408c05d59a0dff3dbce
Author: Jeremy Allison <[email protected]>
Date:   Fri Aug 7 20:18:50 2020 -0700

    s3: libads: Add utility function ads_zero_ldap().
    
    When initializing or re-initializing the ldap part of the ADS_STRUCT,
    we should call this to ensure that ads->ldap.ss is correctly recognized
    as a zero IPaddr by is_zero_addr(). It zeros out the ads->ldap but
    then adds zero_sockaddr() to initialize as AF_INET. Otherwise it's
    left by accident as AF_UNSPEC (0).
    
    Not yet used.
    
    Signed-off-by: Jeremy Allison <[email protected]>
    Reviewed-by: Andreas Schneider <[email protected]>

-----------------------------------------------------------------------

Summary of changes:
 source3/libads/ads_proto.h  |   1 +
 source3/libads/ads_struct.c |   6 +++
 source3/libads/ldap.c       | 119 +++++++++++++++++++++++++++++++++++++++-----
 3 files changed, 114 insertions(+), 12 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source3/libads/ads_proto.h b/source3/libads/ads_proto.h
index 6cdde0cf6eb..5701a5d79d4 100644
--- a/source3/libads/ads_proto.h
+++ b/source3/libads/ads_proto.h
@@ -81,6 +81,7 @@ bool ads_sitename_match(ADS_STRUCT *ads);
 bool ads_closest_dc(ADS_STRUCT *ads);
 ADS_STATUS ads_connect(ADS_STRUCT *ads);
 ADS_STATUS ads_connect_user_creds(ADS_STRUCT *ads);
+void ads_zero_ldap(ADS_STRUCT *ads);
 void ads_disconnect(ADS_STRUCT *ads);
 ADS_STATUS ads_do_search_all_fn(ADS_STRUCT *ads, const char *bind_path,
                                int scope, const char *expr, const char **attrs,
diff --git a/source3/libads/ads_struct.c b/source3/libads/ads_struct.c
index 67a9a7cf75e..413e566b287 100644
--- a/source3/libads/ads_struct.c
+++ b/source3/libads/ads_struct.c
@@ -140,6 +140,9 @@ ADS_STRUCT *ads_init(const char *realm,
 
        ads = SMB_XMALLOC_P(ADS_STRUCT);
        ZERO_STRUCTP(ads);
+#ifdef HAVE_LDAP
+       ads_zero_ldap(ads);
+#endif
 
        ads->server.realm = realm? SMB_STRDUP(realm) : NULL;
        ads->server.workgroup = workgroup ? SMB_STRDUP(workgroup) : NULL;
@@ -222,6 +225,9 @@ void ads_destroy(ADS_STRUCT **ads)
                SAFE_FREE((*ads)->config.config_path);
 
                ZERO_STRUCTP(*ads);
+#ifdef HAVE_LDAP
+               ads_zero_ldap(*ads);
+#endif
 
                if ( is_mine )
                        SAFE_FREE(*ads);
diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c
index ee4628a09a2..2fc9b2009b6 100755
--- a/source3/libads/ldap.c
+++ b/source3/libads/ldap.c
@@ -594,8 +594,36 @@ ADS_STATUS ads_connect(ADS_STRUCT *ads)
        ADS_STATUS status;
        NTSTATUS ntstatus;
        char addr[INET6_ADDRSTRLEN];
+       struct samba_sockaddr existing_sa = {0};
 
-       ZERO_STRUCT(ads->ldap);
+       /*
+        * ads_connect can be passed in a reused ADS_STRUCT
+        * with an existing non-zero ads->ldap.ss IP address
+        * that was stored by going through ads_find_dc()
+        * if ads->server.ldap_server was NULL.
+        *
+        * If ads->server.ldap_server is still NULL but
+        * the target address isn't the zero address, then
+        * store that address off off before zeroing out
+        * ads->ldap so we don't keep doing multiple calls
+        * to ads_find_dc() in the reuse case.
+        *
+        * If a caller wants a clean ADS_STRUCT they
+        * will re-initialize by calling ads_init(), or
+        * call ads_destroy() both of which ensures
+        * ads->ldap.ss is a properly zero'ed out valid IP
+        * address.
+        */
+       if (ads->server.ldap_server == NULL && !is_zero_addr(&ads->ldap.ss)) {
+               /* Save off the address we previously found by ads_find_dc(). */
+               bool ok = sockaddr_storage_to_samba_sockaddr(&existing_sa,
+                                                            &ads->ldap.ss);
+               if (!ok) {
+                       return ADS_ERROR_NT(NT_STATUS_INVALID_ADDRESS);
+               }
+       }
+
+       ads_zero_ldap(ads);
        ZERO_STRUCT(ads->ldap_wrap_data);
        ads->ldap.last_attempt  = time_mono(NULL);
        ads->ldap_wrap_data.wrap_type   = ADS_SASLWRAP_TYPE_PLAIN;
@@ -640,6 +668,20 @@ ADS_STATUS ads_connect(ADS_STRUCT *ads)
                }
        }
 
+       if (!is_zero_addr(&existing_sa.u.ss)) {
+               /* We saved off who we should talk to. */
+               bool ok = ads_try_connect(ads,
+                                         ads->server.gc,
+                                         &existing_sa.u.ss);
+               if (ok) {
+                       goto got_connection;
+               }
+               /*
+                * Keep trying to find a server and fall through
+                * into ads_find_dc() again.
+                */
+       }
+
        ntstatus = ads_find_dc(ads);
        if (NT_STATUS_IS_OK(ntstatus)) {
                goto got_connection;
@@ -749,6 +791,25 @@ ADS_STATUS ads_connect_user_creds(ADS_STRUCT *ads)
        return ads_connect(ads);
 }
 
+/**
+ * Zero out the internal ads->ldap struct and initialize the address to zero 
IP.
+ * @param ads Pointer to an existing ADS_STRUCT
+ *
+ * Sets the ads->ldap.ss to a valid
+ * zero ip address that can be detected by
+ * our is_zero_addr() function. Otherwise
+ * it is left as AF_UNSPEC (0).
+ **/
+void ads_zero_ldap(ADS_STRUCT *ads)
+{
+       ZERO_STRUCT(ads->ldap);
+       /*
+        * Initialize the sockaddr_storage so we can use
+        * sockaddr test functions against it.
+        */
+       zero_sockaddr(&ads->ldap.ss);
+}
+
 /**
  * Disconnect the LDAP server
  * @param ads Pointer to an existing ADS_STRUCT
@@ -766,7 +827,7 @@ void ads_disconnect(ADS_STRUCT *ads)
        if (ads->ldap_wrap_data.mem_ctx) {
                talloc_free(ads->ldap_wrap_data.mem_ctx);
        }
-       ZERO_STRUCT(ads->ldap);
+       ads_zero_ldap(ads);
        ZERO_STRUCT(ads->ldap_wrap_data);
 }
 
@@ -3211,11 +3272,28 @@ ADS_STATUS ads_current_time(ADS_STRUCT *ads)
         /* establish a new ldap tcp session if necessary */
 
        if ( !ads->ldap.ld ) {
-               if ( (ads_s = ads_init( ads->server.realm, 
ads->server.workgroup, 
-                       ads->server.ldap_server, ADS_SASL_PLAIN )) == NULL )
-               {
-                       status = ADS_ERROR(LDAP_NO_MEMORY);
-                       goto done;
+               /*
+                * ADS_STRUCT may be being reused after a
+                * DC lookup, so ads->ldap.ss may already have a
+                * good address. If not, re-initialize the passed-in
+                * ADS_STRUCT with the given server.XXXX parameters.
+                *
+                * Note that this doesn't depend on
+                * ads->server.ldap_server != NULL,
+                * as the case where ads->server.ldap_server==NULL and
+                * ads->ldap.ss != zero_address is precisely the DC
+                * lookup case where ads->ldap.ss was found by going
+                * through ads_find_dc() again we want to avoid repeating.
+                */
+               if (is_zero_addr(&ads->ldap.ss)) {
+                       ads_s = ads_init(ads->server.realm,
+                                        ads->server.workgroup,
+                                        ads->server.ldap_server,
+                                        ADS_SASL_PLAIN );
+                       if (ads_s == NULL) {
+                               status = ADS_ERROR(LDAP_NO_MEMORY);
+                               goto done;
+                       }
                }
                ads_s->auth.flags = ADS_AUTH_ANON_BIND;
                status = ads_connect( ads_s );
@@ -3273,11 +3351,28 @@ ADS_STATUS ads_domain_func_level(ADS_STRUCT *ads, 
uint32_t *val)
         /* establish a new ldap tcp session if necessary */
 
        if ( !ads->ldap.ld ) {
-               if ( (ads_s = ads_init( ads->server.realm, 
ads->server.workgroup, 
-                       ads->server.ldap_server, ADS_SASL_PLAIN )) == NULL )
-               {
-                       status = ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
-                       goto done;
+               /*
+                * ADS_STRUCT may be being reused after a
+                * DC lookup, so ads->ldap.ss may already have a
+                * good address. If not, re-initialize the passed-in
+                * ADS_STRUCT with the given server.XXXX parameters.
+                *
+                * Note that this doesn't depend on
+                * ads->server.ldap_server != NULL,
+                * as the case where ads->server.ldap_server==NULL and
+                * ads->ldap.ss != zero_address is precisely the DC
+                * lookup case where ads->ldap.ss was found by going
+                * through ads_find_dc() again we want to avoid repeating.
+                */
+               if (is_zero_addr(&ads->ldap.ss)) {
+                       ads_s = ads_init(ads->server.realm,
+                                        ads->server.workgroup,
+                                        ads->server.ldap_server,
+                                        ADS_SASL_PLAIN );
+                       if (ads_s == NULL ) {
+                               status = ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
+                               goto done;
+                       }
                }
                ads_s->auth.flags = ADS_AUTH_ANON_BIND;
                status = ads_connect( ads_s );


-- 
Samba Shared Repository

Reply via email to