From f15f6584a2606b700db2c16706f9d4c2d06f96c0 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 1 Mar 2016 15:29:08 +0100 Subject: [PATCH 1/1] TODO CRED_MUST_USE_KERBEROS without password s3-libads: Simplify ads_sasl_spnego_bind() --- source3/libads/sasl.c | 143 +++++++++++++----------------------------- 1 file changed, 42 insertions(+), 101 deletions(-) diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index 98d683788be5..0dc7597e8e17 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -532,51 +532,15 @@ static ADS_STATUS ads_sasl_spnego_bind(ADS_STRUCT *ads) { TALLOC_CTX *frame = talloc_stackframe(); struct ads_service_principal p = {0}; - struct berval *scred=NULL; - int rc, i; ADS_STATUS status; - DATA_BLOB blob = data_blob_null; - char *given_principal = NULL; - char *OIDs[ASN1_MAX_OIDS]; -#ifdef HAVE_KRB5 - bool got_kerberos_mechanism = False; -#endif - const char *mech = NULL; - - rc = ldap_sasl_bind_s(ads->ldap.ld, NULL, "GSS-SPNEGO", NULL, NULL, NULL, &scred); - - if (rc != LDAP_SASL_BIND_IN_PROGRESS) { - status = ADS_ERROR(rc); - goto done; - } - - blob = data_blob(scred->bv_val, scred->bv_len); - - ber_bvfree(scred); - -#if 0 - file_save("sasl_spnego.dat", blob.data, blob.length); -#endif - - /* the server sent us the first part of the SPNEGO exchange in the negprot - reply */ - if (!spnego_parse_negTokenInit(talloc_tos(), blob, OIDs, &given_principal, NULL) || - OIDs[0] == NULL) { - status = ADS_ERROR(LDAP_OPERATIONS_ERROR); - goto done; - } - TALLOC_FREE(given_principal); + enum credentials_use_kerberos krb5_state; - /* make sure the server understands kerberos */ - for (i=0;OIDs[i];i++) { - DEBUG(3,("ads_sasl_spnego_bind: got OID=%s\n", OIDs[i])); -#ifdef HAVE_KRB5 - if (strcmp(OIDs[i], OID_KERBEROS5_OLD) == 0 || - strcmp(OIDs[i], OID_KERBEROS5) == 0) { - got_kerberos_mechanism = True; - } -#endif - talloc_free(OIDs[i]); + if (ads->auth.flags & ADS_AUTH_DISABLE_KERBEROS) { + krb5_state = CRED_DONT_USE_KERBEROS; + } else if (ads->auth.flags & ADS_AUTH_ALLOW_NTLMSSP) { + krb5_state = CRED_AUTO_USE_KERBEROS; + } else { + krb5_state = CRED_MUST_USE_KERBEROS; } status = ads_generate_service_principal(ads, &p); @@ -584,75 +548,55 @@ static ADS_STATUS ads_sasl_spnego_bind(ADS_STRUCT *ads) goto done; } -#ifdef HAVE_KRB5 - if (!(ads->auth.flags & ADS_AUTH_DISABLE_KERBEROS) && - got_kerberos_mechanism) - { - mech = "KRB5"; - - if (ads->auth.password == NULL || - ads->auth.password[0] == '\0') - { - - status = ads_sasl_spnego_gensec_bind(ads, "GSS-SPNEGO", - CRED_MUST_USE_KERBEROS, - p.service, p.hostname, - blob); - if (ADS_ERR_OK(status)) { - ads_free_service_principal(&p); - goto done; - } + if (krb5_state == CRED_DONT_USE_KERBEROS) { + goto do_ntlmssp; + } - DEBUG(10,("ads_sasl_spnego_gensec_bind(KRB5) failed with: %s, " - "calling kinit\n", ads_errstr(status))); + if (ads->auth.password == NULL || + ads->auth.password[0] == '\0') + { + status = ads_sasl_spnego_gensec_bind(ads, + "GSS-SPNEGO", + krb5_state, + p.service, + p.hostname, + data_blob_null); + if (ADS_ERR_OK(status)) { + goto done; } - status = ADS_ERROR_KRB5(ads_kinit_password(ads)); + DEBUG(10,("ads_sasl_spnego_gensec_bind(GSS-SPNEGO): " + "failed with: %s, calling kinit\n", + ads_errstr(status))); + } - if (ADS_ERR_OK(status)) { - status = ads_sasl_spnego_gensec_bind(ads, "GSS-SPNEGO", - CRED_MUST_USE_KERBEROS, - p.service, p.hostname, - blob); - if (!ADS_ERR_OK(status)) { - DEBUG(0,("kinit succeeded but " - "ads_sasl_spnego_gensec_bind(KRB5) failed " - "for %s/%s with user[%s] realm[%s]: %s\n", - p.service, p.hostname, - ads->auth.user_name, - ads->auth.realm, - ads_errstr(status))); - } - } + status = ADS_ERROR_KRB5(ads_kinit_password(ads)); - /* only fallback to NTLMSSP if allowed */ - if (ADS_ERR_OK(status) || - !(ads->auth.flags & ADS_AUTH_ALLOW_NTLMSSP)) { - goto done; + do_ntlmssp: + if (ADS_ERR_OK(status)) { + status = ads_sasl_spnego_gensec_bind(ads, + "GSS-SPNEGO", + krb5_state, + p.service, + p.hostname, + data_blob_null); + if (!ADS_ERR_OK(status)) { + DEBUG(0,("kinit succeeded but " + "ads_sasl_spnego_gensec_bind() failed: %s\n", + ads_errstr(status))); } - DEBUG(1,("ads_sasl_spnego_gensec_bind(KRB5) failed " - "for %s/%s with user[%s] realm[%s]: %s, " - "fallback to NTLMSSP\n", + DEBUG(1,("ads_sasl_spnego_gensec_bind(GSS-SPNEGO) failed " + "for %s/%s with user[%s] realm[%s]: %s\n", p.service, p.hostname, ads->auth.user_name, ads->auth.realm, ads_errstr(status))); } -#endif - - /* lets do NTLMSSP ... this has the big advantage that we don't need - to sync clocks, and we don't rely on special versions of the krb5 - library for HMAC_MD4 encryption */ - mech = "NTLMSSP"; - status = ads_sasl_spnego_gensec_bind(ads, "GSS-SPNEGO", - CRED_DONT_USE_KERBEROS, - p.service, p.hostname, - data_blob_null); done: if (!ADS_ERR_OK(status)) { - DEBUG(1,("ads_sasl_spnego_gensec_bind(%s) failed " - "for %s/%s with user[%s] realm=[%s]: %s\n", mech, + DEBUG(1,("ads_sasl_spnego_gensec_bind(GSS-SPNEGO) failed " + "for %s/%s with user[%s] realm=[%s]: %s\n", p.service, p.hostname, ads->auth.user_name, ads->auth.realm, @@ -660,9 +604,6 @@ done: } ads_free_service_principal(&p); TALLOC_FREE(frame); - if (blob.data != NULL) { - data_blob_free(&blob); - } return status; } -- 2.34.1