TODO CRED_MUST_USE_KERBEROS without password s3-libads: Simplify ads_sasl_spnego_bind()
authorStefan Metzmacher <metze@samba.org>
Tue, 1 Mar 2016 14:29:08 +0000 (15:29 +0100)
committerStefan Metzmacher <metze@samba.org>
Mon, 18 Feb 2019 12:46:10 +0000 (13:46 +0100)
source3/libads/sasl.c

index 98d683788be53a491e044461bf6f99c0e6e71631..0dc7597e8e175a8a73ea998a8860610c8b36cea8 100644 (file)
@@ -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;
 }