#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"
*/
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);
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);
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);