From 97ecce03de5d4e9e9e3f9bab55af0fe171045085 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 4 Nov 2005 17:39:42 +0000 Subject: r11504: Added Andrew Bartletts removal of another NTLMSSP implementation patch. Jeremy. (This used to be commit 4591984176fd32ba25155fbc6889a1c637019a08) --- source3/libads/ads_struct.c | 2 + source3/libads/sasl.c | 174 ++++++++++++++++++++++---------------------- 2 files changed, 91 insertions(+), 85 deletions(-) diff --git a/source3/libads/ads_struct.c b/source3/libads/ads_struct.c index d8676d050d..55a6d66440 100644 --- a/source3/libads/ads_struct.c +++ b/source3/libads/ads_struct.c @@ -105,6 +105,8 @@ ADS_STRUCT *ads_init(const char *realm, /* the caller will own the memory by default */ ads->is_mine = 1; + ads->auth.flags = ADS_AUTH_DISABLE_KERBEROS | ADS_AUTH_ALLOW_NTLMSSP; + return ads; } diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index 72cbf7264e..44a95f5990 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -28,108 +28,112 @@ */ static ADS_STATUS ads_sasl_spnego_ntlmssp_bind(ADS_STRUCT *ads) { - const char *mechs[] = {OID_NTLMSSP, NULL}; DATA_BLOB msg1 = data_blob(NULL, 0); - DATA_BLOB blob, chal1, chal2, auth; - uint8 challenge[8]; - uint8 nthash[24], lmhash[24], sess_key[16]; - uint32 neg_flags; + DATA_BLOB blob = data_blob(NULL, 0); + DATA_BLOB blob_in = data_blob(NULL, 0); + DATA_BLOB blob_out = data_blob(NULL, 0); struct berval cred, *scred = NULL; - ADS_STATUS status; int rc; + NTSTATUS nt_status; + int turn = 1; - if (!ads->auth.password) { - /* No password, don't segfault below... */ - return ADS_ERROR_NT(NT_STATUS_LOGON_FAILURE); - } - - neg_flags = NTLMSSP_NEGOTIATE_UNICODE | - NTLMSSP_NEGOTIATE_128 | - NTLMSSP_NEGOTIATE_NTLM; - - memset(sess_key, 0, 16); - - /* generate the ntlmssp negotiate packet */ - msrpc_gen(&blob, "CddB", - "NTLMSSP", - NTLMSSP_NEGOTIATE, - neg_flags, - sess_key, 16); + struct ntlmssp_state *ntlmssp_state; - /* and wrap it in a SPNEGO wrapper */ - msg1 = gen_negTokenTarg(mechs, blob); - data_blob_free(&blob); - - cred.bv_val = (char *)msg1.data; - cred.bv_len = msg1.length; - - rc = ldap_sasl_bind_s(ads->ld, NULL, "GSS-SPNEGO", &cred, NULL, NULL, &scred); - if (rc != LDAP_SASL_BIND_IN_PROGRESS) { - status = ADS_ERROR(rc); - goto failed; + if (!NT_STATUS_IS_OK(nt_status = ntlmssp_client_start(&ntlmssp_state))) { + return ADS_ERROR_NT(nt_status); } + ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_SIGN; - blob = data_blob(scred->bv_val, scred->bv_len); - ber_bvfree(scred); - - /* the server gives us back two challenges */ - if (!spnego_parse_challenge(blob, &chal1, &chal2)) { - DEBUG(3,("Failed to parse challenges\n")); - status = ADS_ERROR(LDAP_OPERATIONS_ERROR); - goto failed; + if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_username(ntlmssp_state, ads->auth.user_name))) { + return ADS_ERROR_NT(nt_status); + } + if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_domain(ntlmssp_state, ads->auth.realm))) { + return ADS_ERROR_NT(nt_status); + } + if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_password(ntlmssp_state, ads->auth.password))) { + return ADS_ERROR_NT(nt_status); } - data_blob_free(&blob); - - /* encrypt the password with the challenge */ - memcpy(challenge, chal1.data + 24, 8); - SMBencrypt(ads->auth.password, challenge,lmhash); - SMBNTencrypt(ads->auth.password, challenge,nthash); - - data_blob_free(&chal1); - data_blob_free(&chal2); - - /* this generates the actual auth packet */ - msrpc_gen(&blob, "CdBBUUUBd", - "NTLMSSP", - NTLMSSP_AUTH, - lmhash, 24, - nthash, 24, - lp_workgroup(), - ads->auth.user_name, - global_myname(), - sess_key, 16, - neg_flags); - - /* wrap it in SPNEGO */ - auth = spnego_gen_auth(blob); + blob_in = data_blob(NULL, 0); + + do { + nt_status = ntlmssp_update(ntlmssp_state, + 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) { + /* and wrap it in a SPNEGO wrapper */ + msg1 = gen_negTokenInit(OID_NTLMSSP, blob_out); + } else { + /* wrap it in SPNEGO */ + msg1 = spnego_gen_auth(blob_out); + } - data_blob_free(&blob); + data_blob_free(&blob_out); - /* Remember to free the msg1 blob. The contents of this - have been copied into cred and need freeing before reassignment. */ - data_blob_free(&msg1); + cred.bv_val = (char *)msg1.data; + cred.bv_len = msg1.length; + scred = NULL; + rc = ldap_sasl_bind_s(ads->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); + } - /* now send the auth packet and we should be done */ - cred.bv_val = (char *)auth.data; - cred.bv_len = auth.length; + ntlmssp_end(&ntlmssp_state); + return ADS_ERROR(rc); + } + if (scred) { + blob = data_blob(scred->bv_val, scred->bv_len); + ber_bvfree(scred); + } else { + blob = data_blob(NULL, 0); + } - rc = ldap_sasl_bind_s(ads->ld, NULL, "GSS-SPNEGO", &cred, NULL, NULL, &scred); + } else { - ber_bvfree(scred); - data_blob_free(&auth); + ntlmssp_end(&ntlmssp_state); + data_blob_free(&blob_out); + return ADS_ERROR_NT(nt_status); + } + + if ((turn == 1) && + (rc == LDAP_SASL_BIND_IN_PROGRESS)) { + DATA_BLOB tmp_blob = data_blob(NULL, 0); + /* the server might give us back two challenges */ + if (!spnego_parse_challenge(blob, &blob_in, + &tmp_blob)) { + + ntlmssp_end(&ntlmssp_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(blob, nt_status, + &blob_in)) { + + ntlmssp_end(&ntlmssp_state); + data_blob_free(&blob); + DEBUG(3,("Failed to parse auth response\n")); + return ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER); + } + } + data_blob_free(&blob); + data_blob_free(&blob_out); + turn++; + } while (rc == LDAP_SASL_BIND_IN_PROGRESS && !NT_STATUS_IS_OK(nt_status)); - return ADS_ERROR(rc); - -failed: + /* we have a reference conter on ntlmssp_state, if we are signing + then the state will be kept by the signing engine */ - /* Remember to free the msg1 blob. The contents of this - have been copied into cred and need freeing. */ - data_blob_free(&msg1); + ntlmssp_end(&ntlmssp_state); - if(scred) - ber_bvfree(scred); - return status; + return ADS_ERROR(rc); } /* -- cgit