s3:libads: split out ads_connect_internal() and call it with ads_legacy_creds()
authorStefan Metzmacher <metze@samba.org>
Wed, 27 Apr 2022 11:11:26 +0000 (13:11 +0200)
committerStefan Metzmacher <metze@samba.org>
Tue, 14 May 2024 10:18:31 +0000 (10:18 +0000)
Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Andreas Schneider <asn@samba.org>
source3/libads/ads_proto.h
source3/libads/ldap.c
source3/libads/sasl.c

index 93fe2a2082fb3839640d51268a8560931d9cbe34..16fc24264cb9de660739d731213ee1cd61f8963a 100644 (file)
@@ -206,7 +206,7 @@ ADS_STATUS ads_ranged_search(ADS_STRUCT *ads,
 NTSTATUS ads_legacy_creds(ADS_STRUCT *ads,
                          TALLOC_CTX *mem_ctx,
                          struct cli_credentials **_creds);
-ADS_STATUS ads_sasl_bind(ADS_STRUCT *ads);
+ADS_STATUS ads_sasl_bind(ADS_STRUCT *ads, struct cli_credentials *creds);
 
 /* The following definitions come from libads/sasl_wrapping.c  */
 
index b5bf5634086e71b7f9a858c1391c61a4c7ba9dc6..26e3107c0420a2a484283e427270ab8b7f6c8ca9 100644 (file)
@@ -34,6 +34,7 @@
 #include "lib/param/loadparm.h"
 #include "libsmb/namequery.h"
 #include "../librpc/gen_ndr/ndr_ads.h"
+#include "auth/credentials/credentials.h"
 
 #ifdef HAVE_LDAP
 
@@ -810,12 +811,14 @@ static NTSTATUS ads_find_dc(ADS_STRUCT *ads)
                  c_realm, c_domain, nt_errstr(status)));
        return status;
 }
+
 /**
  * Connect to the LDAP server
  * @param ads Pointer to an existing ADS_STRUCT
  * @return status of connection
  **/
-ADS_STATUS ads_connect(ADS_STRUCT *ads)
+static ADS_STATUS ads_connect_internal(ADS_STRUCT *ads,
+                                      struct cli_credentials *creds)
 {
        int version = LDAP_VERSION3;
        ADS_STATUS status;
@@ -827,6 +830,18 @@ ADS_STATUS ads_connect(ADS_STRUCT *ads)
 
        zero_sockaddr(&existing_ss);
 
+       if (!(ads->auth.flags & ADS_AUTH_NO_BIND)) {
+               SMB_ASSERT(creds != NULL);
+       }
+
+       if (ads->auth.flags & ADS_AUTH_ANON_BIND) {
+               /*
+                * Simple anonyous binds are only
+                * allowed for anonymous credentials
+                */
+               SMB_ASSERT(cli_credentials_is_anonymous(creds));
+       }
+
        /*
         * ads_connect can be passed in a reused ADS_STRUCT
         * with an existing non-zero ads->ldap.ss IP address
@@ -1076,7 +1091,7 @@ got_connection:
                goto out;
        }
 
-       status = ads_sasl_bind(ads);
+       status = ads_sasl_bind(ads, creds);
 
  out:
        if (DEBUGLEVEL >= 11) {
@@ -1090,6 +1105,29 @@ got_connection:
        return status;
 }
 
+/*
+ * Connect to the LDAP server
+ * @param ads Pointer to an existing ADS_STRUCT
+ * @return status of connection
+ **/
+ADS_STATUS ads_connect(ADS_STRUCT *ads)
+{
+       TALLOC_CTX *frame = talloc_stackframe();
+       struct cli_credentials *creds = NULL;
+       ADS_STATUS status;
+       NTSTATUS ntstatus;
+
+       ntstatus = ads_legacy_creds(ads, frame, &creds);
+       if (!NT_STATUS_IS_OK(ntstatus)) {
+               TALLOC_FREE(frame);
+               return ADS_ERROR_NT(ntstatus);
+       }
+
+       status = ads_connect_internal(ads, creds);
+       TALLOC_FREE(frame);
+       return status;
+}
+
 /**
  * Connect to the LDAP server using given credentials
  * @param ads Pointer to an existing ADS_STRUCT
index 3d0bac4c4a9de409d035c17a7acaf2a96196d871..55e77cd71b40b0d3707b59862652b922a5e65367 100644 (file)
@@ -634,36 +634,29 @@ static ADS_STATUS ads_generate_service_principal(ADS_STRUCT *ads,
 /*
    this performs a SASL/SPNEGO bind
 */
-static ADS_STATUS ads_sasl_spnego_bind(ADS_STRUCT *ads)
+static ADS_STATUS ads_sasl_spnego_bind(ADS_STRUCT *ads,
+                                      struct cli_credentials *creds)
 {
        TALLOC_CTX *frame = talloc_stackframe();
        struct ads_service_principal p = {0};
-       struct cli_credentials *creds = NULL;
-       NTSTATUS nt_status;
        ADS_STATUS status;
        const char *mech = NULL;
        const char *debug_username = NULL;
        enum credentials_use_kerberos krb5_state;
 
+       krb5_state = cli_credentials_get_kerberos_state(creds);
+
        status = ads_generate_service_principal(ads, &p);
        if (!ADS_ERR_OK(status)) {
                goto done;
        }
 
-       nt_status = ads_legacy_creds(ads, frame, &creds);
-       if (!NT_STATUS_IS_OK(nt_status)) {
-               status = ADS_ERROR_NT(nt_status);
-               goto done;
-       }
-
        debug_username = cli_credentials_get_unparsed_name(creds, frame);
        if (debug_username == NULL) {
                status = ADS_ERROR_SYSTEM(errno);
                goto done;
        }
 
-       krb5_state = cli_credentials_get_kerberos_state(creds);
-
 #ifdef HAVE_KRB5
        if (krb5_state != CRED_USE_KERBEROS_DISABLED &&
            !is_ipaddress(p.hostname))
@@ -760,7 +753,7 @@ done:
        return status;
 }
 
-ADS_STATUS ads_sasl_bind(ADS_STRUCT *ads)
+ADS_STATUS ads_sasl_bind(ADS_STRUCT *ads, struct cli_credentials *creds)
 {
        ADS_STATUS status;
        struct ads_saslwrap *wrap = &ads->ldap_wrap_data;
@@ -791,7 +784,7 @@ ADS_STATUS ads_sasl_bind(ADS_STRUCT *ads)
        }
 
 retry:
-       status = ads_sasl_spnego_bind(ads);
+       status = ads_sasl_spnego_bind(ads, creds);
        if (status.error_type == ENUM_ADS_ERROR_LDAP &&
            status.err.rc == LDAP_STRONG_AUTH_REQUIRED &&
            !tls &&