]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
s3:libads: make use of GENSEC_OID_SPNEGO in ads_sasl_spnego_ntlmssp_bind()
authorStefan Metzmacher <metze@samba.org>
Wed, 9 Dec 2015 14:02:29 +0000 (15:02 +0100)
committerStefan Metzmacher <metze@samba.org>
Thu, 10 Mar 2016 05:52:30 +0000 (06:52 +0100)
This avoids using the hand made spnego code, that
doesn't support the GENSEC_FEATURE_NEW_SPNEGO protection.

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
Reviewed-by: Günther Deschner <gd@samba.org>
source3/libads/sasl.c

index 0251980ae6e781c9fd846cee3c8bce805973f66f..ba33c1d5e6bc2d741b9a2d37ab79b4ef75ef0748 100644 (file)
@@ -19,6 +19,7 @@
 
 #include "includes.h"
 #include "../libcli/auth/spnego.h"
+#include "auth/credentials/credentials.h"
 #include "auth/gensec/gensec.h"
 #include "auth_generic.h"
 #include "ads.h"
@@ -120,16 +121,11 @@ static const struct ads_saslwrap_ops ads_sasl_ntlmssp_ops = {
 */
 static ADS_STATUS ads_sasl_spnego_ntlmssp_bind(ADS_STRUCT *ads)
 {
-       DATA_BLOB msg1 = data_blob_null;
-       DATA_BLOB blob = data_blob_null;
        DATA_BLOB blob_in = data_blob_null;
        DATA_BLOB blob_out = data_blob_null;
-       struct berval cred, *scred = NULL;
        int rc;
        NTSTATUS nt_status;
        ADS_STATUS status;
-       int turn = 1;
-
        struct auth_generic_state *auth_generic_state;
 
        nt_status = auth_generic_client_prepare(NULL, &auth_generic_state);
@@ -147,6 +143,9 @@ static ADS_STATUS ads_sasl_spnego_ntlmssp_bind(ADS_STRUCT *ads)
                return ADS_ERROR_NT(nt_status);
        }
 
+       cli_credentials_set_kerberos_state(auth_generic_state->credentials,
+                                          CRED_DONT_USE_KERBEROS);
+
        switch (ads->ldap.wrap_type) {
        case ADS_SASLWRAP_TYPE_SEAL:
                gensec_want_feature(auth_generic_state->gensec_security, GENSEC_FEATURE_SIGN);
@@ -169,87 +168,68 @@ static ADS_STATUS ads_sasl_spnego_ntlmssp_bind(ADS_STRUCT *ads)
                break;
        }
 
-       nt_status = auth_generic_client_start(auth_generic_state, GENSEC_OID_NTLMSSP);
+       nt_status = auth_generic_client_start(auth_generic_state, GENSEC_OID_SPNEGO);
        if (!NT_STATUS_IS_OK(nt_status)) {
                return ADS_ERROR_NT(nt_status);
        }
 
+       rc = LDAP_SASL_BIND_IN_PROGRESS;
+       nt_status = NT_STATUS_MORE_PROCESSING_REQUIRED;
        blob_in = data_blob_null;
+       blob_out = data_blob_null;
+
+       while (true) {
+               struct berval cred, *scred = NULL;
 
-       do {
                nt_status = gensec_update(auth_generic_state->gensec_security,
                                          talloc_tos(), blob_in, &blob_out);
                data_blob_free(&blob_in);
-               if ((NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED) 
-                    || NT_STATUS_IS_OK(nt_status))
-                   && blob_out.length) {
-                       if (turn == 1) {
-                               const char *OIDs_ntlm[] = {OID_NTLMSSP, NULL};
-                               /* and wrap it in a SPNEGO wrapper */
-                               msg1 = spnego_gen_negTokenInit(talloc_tos(),
-                                               OIDs_ntlm, &blob_out, NULL);
-                       } else {
-                               /* wrap it in SPNEGO */
-                               msg1 = spnego_gen_auth(talloc_tos(), blob_out);
-                       }
-
+               if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)
+                   && !NT_STATUS_IS_OK(nt_status))
+               {
+                       TALLOC_FREE(auth_generic_state);
                        data_blob_free(&blob_out);
+                       return ADS_ERROR_NT(nt_status);
+               }
 
-                       cred.bv_val = (char *)msg1.data;
-                       cred.bv_len = msg1.length;
-                       scred = NULL;
-                       rc = ldap_sasl_bind_s(ads->ldap.ld, NULL, "GSS-SPNEGO", &cred, NULL, NULL, &scred);
-                       data_blob_free(&msg1);
-                       if ((rc != LDAP_SASL_BIND_IN_PROGRESS) && (rc != 0)) {
-                               if (scred) {
-                                       ber_bvfree(scred);
-                               }
+               if (NT_STATUS_IS_OK(nt_status) && rc == 0 && blob_out.length == 0) {
+                       break;
+               }
 
-                               TALLOC_FREE(auth_generic_state);
-                               return ADS_ERROR(rc);
-                       }
+               cred.bv_val = (char *)blob_out.data;
+               cred.bv_len = blob_out.length;
+               scred = NULL;
+               rc = ldap_sasl_bind_s(ads->ldap.ld, NULL, "GSS-SPNEGO", &cred, NULL, NULL, &scred);
+               data_blob_free(&blob_out);
+               if ((rc != LDAP_SASL_BIND_IN_PROGRESS) && (rc != 0)) {
                        if (scred) {
-                               blob = data_blob(scred->bv_val, scred->bv_len);
                                ber_bvfree(scred);
-                       } else {
-                               blob = data_blob_null;
                        }
 
-               } else {
-
                        TALLOC_FREE(auth_generic_state);
-                       data_blob_free(&blob_out);
-                       return ADS_ERROR_NT(nt_status);
+                       return ADS_ERROR(rc);
                }
-               
-               if ((turn == 1) && 
-                   (rc == LDAP_SASL_BIND_IN_PROGRESS)) {
-                       DATA_BLOB tmp_blob = data_blob_null;
-                       /* the server might give us back two challenges */
-                       if (!spnego_parse_challenge(talloc_tos(), blob, &blob_in, 
-                                                   &tmp_blob)) {
-
-                               TALLOC_FREE(auth_generic_state);
-                               data_blob_free(&blob);
-                               DEBUG(3,("Failed to parse challenges\n"));
-                               return ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER);
-                       }
-                       data_blob_free(&tmp_blob);
-               } else if (rc == LDAP_SASL_BIND_IN_PROGRESS) {
-                       if (!spnego_parse_auth_response(talloc_tos(), blob, nt_status, OID_NTLMSSP, 
-                                                       &blob_in)) {
-
+               if (scred) {
+                       blob_in = data_blob_talloc(talloc_tos(),
+                                                  scred->bv_val,
+                                                  scred->bv_len);
+                       if (blob_in.length != scred->bv_len) {
+                               ber_bvfree(scred);
                                TALLOC_FREE(auth_generic_state);
-                               data_blob_free(&blob);
-                               DEBUG(3,("Failed to parse auth response\n"));
-                               return ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER);
+                               return ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
                        }
+                       ber_bvfree(scred);
+               } else {
+                       blob_in = data_blob_null;
                }
-               data_blob_free(&blob);
-               data_blob_free(&blob_out);
-               turn++;
-       } while (rc == LDAP_SASL_BIND_IN_PROGRESS && !NT_STATUS_IS_OK(nt_status));
-       
+               if (NT_STATUS_IS_OK(nt_status) && rc == 0 && blob_in.length == 0) {
+                       break;
+               }
+       }
+
+       data_blob_free(&blob_in);
+       data_blob_free(&blob_out);
+
        if (ads->ldap.wrap_type > ADS_SASLWRAP_TYPE_PLAIN) {
                size_t max_wrapped = gensec_max_wrapped_size(auth_generic_state->gensec_security);
                ads->ldap.out.max_unwrapped = gensec_max_input_size(auth_generic_state->gensec_security);