The Samba-Bugzilla – Attachment 6125 Details for
Bug 7855
ntlm_auth only handles the first spnego mech
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Backport Patch for v3-5-test
tmp.diff (text/plain), 31.35 KB, created by
Stefan Metzmacher
on 2010-12-08 03:53:11 UTC
(
hide
)
Description:
Backport Patch for v3-5-test
Filename:
MIME Type:
Creator:
Stefan Metzmacher
Created:
2010-12-08 03:53:11 UTC
Size:
31.35 KB
patch
obsolete
>From 9445c24d452bcf389682c6cabcf7459276e154de Mon Sep 17 00:00:00 2001 >From: Volker Lendecke <vl@samba.org> >Date: Mon, 13 Sep 2010 18:09:20 +0200 >Subject: [PATCH 1/9] ntlm_auth: Fix a valgrind error > (cherry picked from commit 69db4b4ccf051b05517e6eb9039ab48f90608075) > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >--- > source3/utils/ntlm_auth.c | 2 +- > 1 files changed, 1 insertions(+), 1 deletions(-) > >diff --git a/source3/utils/ntlm_auth.c b/source3/utils/ntlm_auth.c >index afd0b99..ec035a1 100644 >--- a/source3/utils/ntlm_auth.c >+++ b/source3/utils/ntlm_auth.c >@@ -1137,7 +1137,7 @@ static void offer_gss_spnego_mechs(void) { > > /* Server negTokenInit (mech offerings) */ > spnego.type = SPNEGO_NEG_TOKEN_INIT; >- spnego.negTokenInit.mechTypes = talloc_array(ctx, const char *, 2); >+ spnego.negTokenInit.mechTypes = talloc_array(ctx, const char *, 3); > #ifdef HAVE_KRB5 > spnego.negTokenInit.mechTypes[0] = talloc_strdup(ctx, OID_KERBEROS5_OLD); > spnego.negTokenInit.mechTypes[1] = talloc_strdup(ctx, OID_NTLMSSP); >-- >1.7.0.4 > > >From 4f7f5c91609ba6bfc0cb4b5a1a9793136b97a8a7 Mon Sep 17 00:00:00 2001 >From: Volker Lendecke <vl@samba.org> >Date: Wed, 15 Sep 2010 10:29:44 +0200 >Subject: [PATCH 2/9] s3: Fix some debug msgs in ntlm_auth > (cherry picked from commit 6400f3ee62108e3dd1e6c1013ccea9fb4b08d562) > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >--- > source3/utils/ntlm_auth.c | 16 ++++++++-------- > 1 files changed, 8 insertions(+), 8 deletions(-) > >diff --git a/source3/utils/ntlm_auth.c b/source3/utils/ntlm_auth.c >index ec035a1..20f58fe 100644 >--- a/source3/utils/ntlm_auth.c >+++ b/source3/utils/ntlm_auth.c >@@ -785,7 +785,7 @@ static void manage_squid_ntlmssp_request(struct ntlm_auth_state *state, > NTSTATUS nt_status; > > if (strlen(buf) < 2) { >- DEBUG(1, ("NTLMSSP query [%s] invalid", buf)); >+ DEBUG(1, ("NTLMSSP query [%s] invalid\n", buf)); > x_fprintf(x_stdout, "BH NTLMSSP query invalid\n"); > return; > } >@@ -854,7 +854,7 @@ static void manage_squid_ntlmssp_request(struct ntlm_auth_state *state, > data_blob_free(&request); > return; > } else { >- DEBUG(1, ("NTLMSSP query [%s] invalid", buf)); >+ DEBUG(1, ("NTLMSSP query [%s] invalid\n", buf)); > x_fprintf(x_stdout, "BH NTLMSSP query invalid\n"); > return; > } >@@ -921,7 +921,7 @@ static void manage_client_ntlmssp_request(struct ntlm_auth_state *state, > } > > if (strlen(buf) < 2) { >- DEBUG(1, ("NTLMSSP query [%s] invalid", buf)); >+ DEBUG(1, ("NTLMSSP query [%s] invalid\n", buf)); > x_fprintf(x_stdout, "BH NTLMSSP query invalid\n"); > return; > } >@@ -1013,7 +1013,7 @@ static void manage_client_ntlmssp_request(struct ntlm_auth_state *state, > data_blob_free(&request); > return; > } else { >- DEBUG(1, ("NTLMSSP query [%s] invalid", buf)); >+ DEBUG(1, ("NTLMSSP query [%s] invalid\n", buf)); > x_fprintf(x_stdout, "BH NTLMSSP query invalid\n"); > return; > } >@@ -1187,7 +1187,7 @@ static void manage_gss_spnego_request(struct ntlm_auth_state *state, > char *reply_argument = NULL; > > if (strlen(buf) < 2) { >- DEBUG(1, ("SPENGO query [%s] invalid", buf)); >+ DEBUG(1, ("SPENGO query [%s] invalid\n", buf)); > x_fprintf(x_stdout, "BH SPENGO query invalid\n"); > return; > } >@@ -1198,7 +1198,7 @@ static void manage_gss_spnego_request(struct ntlm_auth_state *state, > } else if (strncmp(buf, "KK", 2) == 0) { > ; > } else { >- DEBUG(1, ("SPENGO query [%s] invalid", buf)); >+ DEBUG(1, ("SPENGO query [%s] invalid\n", buf)); > x_fprintf(x_stdout, "BH SPENGO query invalid\n"); > return; > } >@@ -1225,7 +1225,7 @@ static void manage_gss_spnego_request(struct ntlm_auth_state *state, > data_blob_free(&token); > > if (len == -1) { >- DEBUG(1, ("GSS-SPNEGO query [%s] invalid", buf)); >+ DEBUG(1, ("GSS-SPNEGO query [%s] invalid\n", buf)); > x_fprintf(x_stdout, "BH GSS-SPNEGO query invalid\n"); > return; > } >@@ -1237,7 +1237,7 @@ static void manage_gss_spnego_request(struct ntlm_auth_state *state, > > if ( (request.negTokenInit.mechTypes == NULL) || > (request.negTokenInit.mechTypes[0] == NULL) ) { >- DEBUG(1, ("Client did not offer any mechanism")); >+ DEBUG(1, ("Client did not offer any mechanism\n")); > x_fprintf(x_stdout, "BH Client did not offer any " > "mechanism\n"); > return; >-- >1.7.0.4 > > >From d393661c45f806692437620dcec7295e402b0f9b Mon Sep 17 00:00:00 2001 >From: Volker Lendecke <vl@samba.org> >Date: Thu, 16 Sep 2010 10:36:21 +0200 >Subject: [PATCH 3/9] s3: Wrap the ntlm_auth loop with a talloc_stackframe > (cherry picked from commit ae483bbe9af526623189cefe7735f3f2813da6d7) > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >--- > source3/utils/ntlm_auth.c | 2 ++ > 1 files changed, 2 insertions(+), 0 deletions(-) > >diff --git a/source3/utils/ntlm_auth.c b/source3/utils/ntlm_auth.c >index 20f58fe..9b9b1b8 100644 >--- a/source3/utils/ntlm_auth.c >+++ b/source3/utils/ntlm_auth.c >@@ -2288,7 +2288,9 @@ static void squid_stream(enum stdio_helper_mode stdio_mode, stdio_helper_functio > state->helper_mode = stdio_mode; > > while(1) { >+ TALLOC_CTX *frame = talloc_stackframe(); > manage_squid_request(state, fn); >+ TALLOC_FREE(frame); > } > } > >-- >1.7.0.4 > > >From 14c09b8de414f9ad1da3d1a1ca399f0d80ecf74f Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Tue, 30 Nov 2010 10:46:28 +0100 >Subject: [PATCH 4/9] s3: Split off output generation from manage_squid_ntlmssp_request > (cherry picked from commit de2c143f4d540f695db5c7fe8685614c03977365) > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >--- > source3/utils/ntlm_auth.c | 58 +++++++++++++++++++++++++++++++------------- > 1 files changed, 41 insertions(+), 17 deletions(-) > >diff --git a/source3/utils/ntlm_auth.c b/source3/utils/ntlm_auth.c >index 9b9b1b8..0c2546e 100644 >--- a/source3/utils/ntlm_auth.c >+++ b/source3/utils/ntlm_auth.c >@@ -778,15 +778,17 @@ static NTSTATUS do_ccache_ntlm_auth(DATA_BLOB initial_msg, DATA_BLOB challenge_m > return NT_STATUS_MORE_PROCESSING_REQUIRED; > } > >-static void manage_squid_ntlmssp_request(struct ntlm_auth_state *state, >- char *buf, int length) >+static void manage_squid_ntlmssp_request_int(struct ntlm_auth_state *state, >+ char *buf, int length, >+ TALLOC_CTX *mem_ctx, >+ char **response) > { > DATA_BLOB request, reply; > NTSTATUS nt_status; > > if (strlen(buf) < 2) { > DEBUG(1, ("NTLMSSP query [%s] invalid\n", buf)); >- x_fprintf(x_stdout, "BH NTLMSSP query invalid\n"); >+ *response = talloc_strdup(mem_ctx, "BH NTLMSSP query invalid"); > return; > } > >@@ -796,7 +798,7 @@ static void manage_squid_ntlmssp_request(struct ntlm_auth_state *state, > TALLOC_FREE(state->want_feature_list); > state->want_feature_list = talloc_strdup(state->mem_ctx, > buf+3); >- x_fprintf(x_stdout, "OK\n"); >+ *response = talloc_strdup(mem_ctx, "OK"); > return; > } > request = base64_decode_data_blob(buf + 3); >@@ -813,12 +815,12 @@ static void manage_squid_ntlmssp_request(struct ntlm_auth_state *state, > > if (opt_password == NULL) { > DEBUG(1, ("Out of memory\n")); >- x_fprintf(x_stdout, "BH Out of memory\n"); >+ *response = talloc_strdup(mem_ctx, "BH Out of memory"); > data_blob_free(&request); > return; > } > >- x_fprintf(x_stdout, "OK\n"); >+ *response = talloc_strdup(mem_ctx, "OK"); > data_blob_free(&request); > return; > } >@@ -833,10 +835,11 @@ static void manage_squid_ntlmssp_request(struct ntlm_auth_state *state, > DEBUG(10, ("Requested negotiated NTLMSSP flags\n")); > > if (state->svr_state == SERVER_FINISHED) { >- x_fprintf(x_stdout, "GF 0x%08x\n", state->neg_flags); >+ *response = talloc_asprintf(mem_ctx, "GF 0x%08x", >+ state->neg_flags); > } > else { >- x_fprintf(x_stdout, "BH\n"); >+ *response = talloc_strdup(mem_ctx, "BH\n"); > } > data_blob_free(&request); > return; >@@ -845,17 +848,18 @@ static void manage_squid_ntlmssp_request(struct ntlm_auth_state *state, > if(state->have_session_key) { > char *key64 = base64_encode_data_blob(state->mem_ctx, > state->session_key); >- x_fprintf(x_stdout, "GK %s\n", key64?key64:"<NULL>"); >+ *response = talloc_asprintf(mem_ctx, "GK %s", >+ key64 ? key64 : "<NULL>"); > TALLOC_FREE(key64); > } else { >- x_fprintf(x_stdout, "BH\n"); >+ *response = talloc_strdup(mem_ctx, "BH"); > } > > data_blob_free(&request); > return; > } else { > DEBUG(1, ("NTLMSSP query [%s] invalid\n", buf)); >- x_fprintf(x_stdout, "BH NTLMSSP query invalid\n"); >+ *response = talloc_strdup(mem_ctx, "BH NTLMSSP query invalid"); > return; > } > >@@ -863,7 +867,8 @@ static void manage_squid_ntlmssp_request(struct ntlm_auth_state *state, > nt_status = ntlm_auth_start_ntlmssp_server( > &state->ntlmssp_state); > if (!NT_STATUS_IS_OK(nt_status)) { >- x_fprintf(x_stdout, "BH %s\n", nt_errstr(nt_status)); >+ *response = talloc_asprintf( >+ mem_ctx, "BH %s", nt_errstr(nt_status)); > return; > } > ntlmssp_want_feature_list(state->ntlmssp_state, >@@ -878,22 +883,25 @@ static void manage_squid_ntlmssp_request(struct ntlm_auth_state *state, > if (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { > char *reply_base64 = base64_encode_data_blob(state->mem_ctx, > reply); >- x_fprintf(x_stdout, "TT %s\n", reply_base64); >+ *response = talloc_asprintf(mem_ctx, "TT %s", reply_base64); > TALLOC_FREE(reply_base64); > data_blob_free(&reply); > state->svr_state = SERVER_CHALLENGE; > DEBUG(10, ("NTLMSSP challenge\n")); > } else if (NT_STATUS_EQUAL(nt_status, NT_STATUS_ACCESS_DENIED)) { >- x_fprintf(x_stdout, "BH %s\n", nt_errstr(nt_status)); >+ *response = talloc_asprintf(mem_ctx, "BH %s", >+ nt_errstr(nt_status)); > DEBUG(0, ("NTLMSSP BH: %s\n", nt_errstr(nt_status))); > > ntlmssp_end(&state->ntlmssp_state); > } else if (!NT_STATUS_IS_OK(nt_status)) { >- x_fprintf(x_stdout, "NA %s\n", nt_errstr(nt_status)); >+ *response = talloc_asprintf(mem_ctx, "NA %s", >+ nt_errstr(nt_status)); > DEBUG(10, ("NTLMSSP %s\n", nt_errstr(nt_status))); > } else { >- x_fprintf(x_stdout, "AF %s\n", >- (char *)state->ntlmssp_state->auth_context); >+ *response = talloc_asprintf( >+ mem_ctx, "AF %s", >+ (char *)state->ntlmssp_state->auth_context); > DEBUG(10, ("NTLMSSP OK!\n")); > > if(state->have_session_key) >@@ -909,6 +917,22 @@ static void manage_squid_ntlmssp_request(struct ntlm_auth_state *state, > data_blob_free(&request); > } > >+static void manage_squid_ntlmssp_request(struct ntlm_auth_state *state, >+ char *buf, int length) >+{ >+ char *response; >+ >+ manage_squid_ntlmssp_request_int(state, buf, length, >+ talloc_tos(), &response); >+ >+ if (response == NULL) { >+ x_fprintf(x_stdout, "BH Out of memory\n"); >+ return; >+ } >+ x_fprintf(x_stdout, "%s\n", response); >+ TALLOC_FREE(response); >+} >+ > static void manage_client_ntlmssp_request(struct ntlm_auth_state *state, > char *buf, int length) > { >-- >1.7.0.4 > > >From 26edcb345f8863f67c6258219043788c097fc5f4 Mon Sep 17 00:00:00 2001 >From: Volker Lendecke <vl@samba.org> >Date: Thu, 16 Sep 2010 10:22:00 +0200 >Subject: [PATCH 5/9] s3: Fall back to raw NTLMSSP for the gss-spnego protocol > >This is to handle the mod_auth_ntlm_winbind protocol >sending "Negotiate" to IE, which sends raw NTLMSSP >instead of a SPNEGO wrapped NTLMSSP blob. >(cherry picked from commit 70ab7eb5303a5ff058939541dd5bc1f81113a48e) > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >--- > source3/utils/ntlm_auth.c | 25 +++++++++++++++++++++++++ > 1 files changed, 25 insertions(+), 0 deletions(-) > >diff --git a/source3/utils/ntlm_auth.c b/source3/utils/ntlm_auth.c >index 0c2546e..835c227 100644 >--- a/source3/utils/ntlm_auth.c >+++ b/source3/utils/ntlm_auth.c >@@ -1245,6 +1245,31 @@ static void manage_gss_spnego_request(struct ntlm_auth_state *state, > } > > token = base64_decode_data_blob(buf + 3); >+ >+ if ((token.length >= 7) >+ && (strncmp((char *)token.data, "NTLMSSP", 7) == 0)) { >+ char *reply; >+ >+ DEBUG(10, ("Could not parse GSS-SPNEGO, trying raw " >+ "ntlmssp\n")); >+ >+ manage_squid_ntlmssp_request_int(state, buf, length, >+ talloc_tos(), &reply); >+ if (reply == NULL) { >+ x_fprintf(x_stdout, "BH Out of memory\n"); >+ return; >+ } >+ >+ if (strncmp(reply, "AF ", 3) == 0) { >+ x_fprintf(x_stdout, "AF * %s\n", reply+3); >+ } else { >+ x_fprintf(x_stdout, "%s *\n", reply); >+ } >+ >+ TALLOC_FREE(reply); >+ return; >+ } >+ > len = spnego_read_data(ctx, token, &request); > data_blob_free(&token); > >-- >1.7.0.4 > > >From 33ac52375ed533717158cea8058b4d36dbed33de Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Tue, 30 Nov 2010 10:52:52 +0100 >Subject: [PATCH 6/9] s3: Correctly unwrap the krb ticket in gss-spnego > (cherry picked from commit 547b268cfaa2e791bf92e8804bfa504c4e37050b) > >Signed-off-by: Stefan Metzmacher <metze@samba.org> > >renamed to _spnego_parse_krb5_wrap() > >metze >--- > source3/utils/ntlm_auth.c | 53 ++++++++++++++++++++++++++++++++++++++++++++- > 1 files changed, 52 insertions(+), 1 deletions(-) > >diff --git a/source3/utils/ntlm_auth.c b/source3/utils/ntlm_auth.c >index 835c227..4384946 100644 >--- a/source3/utils/ntlm_auth.c >+++ b/source3/utils/ntlm_auth.c >@@ -1193,6 +1193,45 @@ static void offer_gss_spnego_mechs(void) { > return; > } > >+static bool _spnego_parse_krb5_wrap(TALLOC_CTX *ctx, DATA_BLOB blob, DATA_BLOB *ticket, uint8 tok_id[2]) >+{ >+ bool ret; >+ ASN1_DATA *data; >+ int data_remaining; >+ >+ data = asn1_init(talloc_tos()); >+ if (data == NULL) { >+ return false; >+ } >+ >+ asn1_load(data, blob); >+ asn1_start_tag(data, ASN1_APPLICATION(0)); >+ asn1_check_OID(data, OID_KERBEROS5); >+ >+ data_remaining = asn1_tag_remaining(data); >+ >+ if (data_remaining < 3) { >+ data->has_error = True; >+ } else { >+ asn1_read(data, tok_id, 2); >+ data_remaining -= 2; >+ *ticket = data_blob_talloc(ctx, NULL, data_remaining); >+ asn1_read(data, ticket->data, ticket->length); >+ } >+ >+ asn1_end_tag(data); >+ >+ ret = !data->has_error; >+ >+ if (data->has_error) { >+ data_blob_free(ticket); >+ } >+ >+ asn1_free(data); >+ >+ return ret; >+} >+ > static void manage_gss_spnego_request(struct ntlm_auth_state *state, > char *buf, int length) > { >@@ -1338,6 +1377,8 @@ static void manage_gss_spnego_request(struct ntlm_auth_state *state, > DATA_BLOB ap_rep; > DATA_BLOB session_key; > struct PAC_DATA *pac_data = NULL; >+ DATA_BLOB ticket; >+ uint8_t tok_id[2]; > > if ( request.negTokenInit.mechToken.data == NULL ) { > DEBUG(1, ("Client did not provide Kerberos data\n")); >@@ -1346,13 +1387,23 @@ static void manage_gss_spnego_request(struct ntlm_auth_state *state, > return; > } > >+ dump_data(10, request.negTokenInit.mechToken.data, >+ request.negTokenInit.mechToken.length); >+ >+ if (!_spnego_parse_krb5_wrap(ctx, request.negTokenInit.mechToken, >+ &ticket, tok_id)) { >+ DEBUG(1, ("spnego_parse_krb5_wrap failed\n")); >+ x_fprintf(x_stdout, "BH spnego_parse_krb5_wrap failed\n"); >+ return; >+ } >+ > response.type = SPNEGO_NEG_TOKEN_TARG; > response.negTokenTarg.supportedMech = talloc_strdup(ctx, OID_KERBEROS5_OLD); > response.negTokenTarg.mechListMIC = data_blob_talloc(ctx, NULL, 0); > response.negTokenTarg.responseToken = data_blob_talloc(ctx, NULL, 0); > > status = ads_verify_ticket(mem_ctx, lp_realm(), 0, >- &request.negTokenInit.mechToken, >+ &ticket, > &principal, &pac_data, &ap_rep, > &session_key, True); > >-- >1.7.0.4 > > >From ac4992ddaf47f110ccf9ecfa4a2ab8daec79936f Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Wed, 1 Dec 2010 05:50:59 +0100 >Subject: [PATCH 7/9] s3:ntlm_auth: fix memory leak in the raw ntlmssp code path > >metze >(cherry picked from commit 9a56ade6b1d627126418c75de4602610b4482503) >--- > source3/utils/ntlm_auth.c | 2 ++ > 1 files changed, 2 insertions(+), 0 deletions(-) > >diff --git a/source3/utils/ntlm_auth.c b/source3/utils/ntlm_auth.c >index 4384946..c6b3038 100644 >--- a/source3/utils/ntlm_auth.c >+++ b/source3/utils/ntlm_auth.c >@@ -1289,6 +1289,8 @@ static void manage_gss_spnego_request(struct ntlm_auth_state *state, > && (strncmp((char *)token.data, "NTLMSSP", 7) == 0)) { > char *reply; > >+ data_blob_free(&token); >+ > DEBUG(10, ("Could not parse GSS-SPNEGO, trying raw " > "ntlmssp\n")); > >-- >1.7.0.4 > > >From 1ca5566a439bc9abe1f639c4e090362056f629ff Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Wed, 1 Dec 2010 05:59:16 +0100 >Subject: [PATCH 8/9] s3:ntlm_auth: free session key, as we don't use it (at least for now) > >metze >(cherry picked from commit ee4f5ac6182969bcab91955e6d6581e408d222f1) >--- > source3/utils/ntlm_auth.c | 3 ++- > 1 files changed, 2 insertions(+), 1 deletions(-) > >diff --git a/source3/utils/ntlm_auth.c b/source3/utils/ntlm_auth.c >index c6b3038..bc1ff2f 100644 >--- a/source3/utils/ntlm_auth.c >+++ b/source3/utils/ntlm_auth.c >@@ -1377,7 +1377,7 @@ static void manage_gss_spnego_request(struct ntlm_auth_state *state, > TALLOC_CTX *mem_ctx = talloc_init("manage_gss_spnego_request"); > char *principal; > DATA_BLOB ap_rep; >- DATA_BLOB session_key; >+ DATA_BLOB session_key = data_blob_null; > struct PAC_DATA *pac_data = NULL; > DATA_BLOB ticket; > uint8_t tok_id[2]; >@@ -1430,6 +1430,7 @@ static void manage_gss_spnego_request(struct ntlm_auth_state *state, > user = SMB_STRDUP(principal); > > data_blob_free(&ap_rep); >+ data_blob_free(&session_key); > } > > TALLOC_FREE(mem_ctx); >-- >1.7.0.4 > > >From 77058284b99cf5a17f06d8d573bc46216e6af8e4 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Thu, 2 Dec 2010 00:39:23 +0100 >Subject: [PATCH 9/9] s3:ntlm_auth: support clients which offer a spnego mechs we don't support (bug #7855) > >Before we rejected the authentication if we don't support the >first spnego mech the client offered. > >We now negotiate the first mech we support. > >This fix works arround problems, when a client >sends the NEGOEX (1.3.6.1.4.1.311.2.2.30) oid, >which we don't support. > >metze >(cherry picked from commit f802075f08fe0d86f3d176f2302236aeb5834f3d) >Modified to work in the v3-5-test branch, e.g. use ntlmssp_end() >--- > source3/Makefile.in | 2 +- > source3/utils/ntlm_auth.c | 284 ++++++++++++++++++++++++++++----------------- > 2 files changed, 177 insertions(+), 109 deletions(-) > >diff --git a/source3/Makefile.in b/source3/Makefile.in >index 9e960c9..8cdecef 100644 >--- a/source3/Makefile.in >+++ b/source3/Makefile.in >@@ -1315,7 +1315,7 @@ NTLM_AUTH_OBJ = ${NTLM_AUTH_OBJ1} $(LIBSAMBA_OBJ) $(POPT_LIB_OBJ) \ > $(LIBADS_SERVER_OBJ) \ > $(PASSDB_OBJ) $(LIBTSOCKET_OBJ) $(GROUPDB_OBJ) \ > $(SMBLDAP_OBJ) $(LIBNMB_OBJ) \ >- $(LDB_OBJ) $(WBCOMMON_OBJ) \ >+ $(LDB_OBJ) $(WBCOMMON_OBJ) $(SLCACHE_OBJ) \ > $(LIBNDR_GEN_OBJ0) $(LIBNDR_GEN_OBJ1) @BUILD_INIPARSER@ > > >diff --git a/source3/utils/ntlm_auth.c b/source3/utils/ntlm_auth.c >index bc1ff2f..a85f123 100644 >--- a/source3/utils/ntlm_auth.c >+++ b/source3/utils/ntlm_auth.c >@@ -76,6 +76,8 @@ struct ntlm_auth_state { > struct ntlmssp_state *ntlmssp_state; > uint32_t neg_flags; > char *want_feature_list; >+ char *spnego_mech; >+ char *spnego_mech_oid; > bool have_session_key; > DATA_BLOB session_key; > DATA_BLOB initial_message; >@@ -1161,11 +1163,12 @@ static void offer_gss_spnego_mechs(void) { > > /* Server negTokenInit (mech offerings) */ > spnego.type = SPNEGO_NEG_TOKEN_INIT; >- spnego.negTokenInit.mechTypes = talloc_array(ctx, const char *, 3); >+ spnego.negTokenInit.mechTypes = talloc_array(ctx, const char *, 4); > #ifdef HAVE_KRB5 > spnego.negTokenInit.mechTypes[0] = talloc_strdup(ctx, OID_KERBEROS5_OLD); >- spnego.negTokenInit.mechTypes[1] = talloc_strdup(ctx, OID_NTLMSSP); >- spnego.negTokenInit.mechTypes[2] = NULL; >+ spnego.negTokenInit.mechTypes[1] = talloc_strdup(ctx, OID_KERBEROS5); >+ spnego.negTokenInit.mechTypes[2] = talloc_strdup(ctx, OID_NTLMSSP); >+ spnego.negTokenInit.mechTypes[3] = NULL; > #else > spnego.negTokenInit.mechTypes[0] = talloc_strdup(ctx, OID_NTLMSSP); > spnego.negTokenInit.mechTypes[1] = NULL; >@@ -1235,9 +1238,10 @@ static bool _spnego_parse_krb5_wrap(TALLOC_CTX *ctx, DATA_BLOB blob, DATA_BLOB * > static void manage_gss_spnego_request(struct ntlm_auth_state *state, > char *buf, int length) > { >- static NTLMSSP_STATE *ntlmssp_state = NULL; > struct spnego_data request, response; > DATA_BLOB token; >+ DATA_BLOB raw_in_token = data_blob_null; >+ DATA_BLOB raw_out_token = data_blob_null; > NTSTATUS status; > ssize_t len; > TALLOC_CTX *ctx = talloc_tos(); >@@ -1248,6 +1252,7 @@ static void manage_gss_spnego_request(struct ntlm_auth_state *state, > const char *reply_code; > char *reply_base64; > char *reply_argument = NULL; >+ char *supportedMech = NULL; > > if (strlen(buf) < 2) { > DEBUG(1, ("SPENGO query [%s] invalid\n", buf)); >@@ -1256,8 +1261,10 @@ static void manage_gss_spnego_request(struct ntlm_auth_state *state, > } > > if (strncmp(buf, "YR", 2) == 0) { >- if (ntlmssp_state) >- ntlmssp_end(&ntlmssp_state); >+ if (state->ntlmssp_state) >+ ntlmssp_end(&state->ntlmssp_state); >+ TALLOC_FREE(state->spnego_mech); >+ TALLOC_FREE(state->spnego_mech_oid); > } else if (strncmp(buf, "KK", 2) == 0) { > ; > } else { >@@ -1311,6 +1318,7 @@ static void manage_gss_spnego_request(struct ntlm_auth_state *state, > return; > } > >+ ZERO_STRUCT(request); > len = spnego_read_data(ctx, token, &request); > data_blob_free(&token); > >@@ -1321,6 +1329,20 @@ static void manage_gss_spnego_request(struct ntlm_auth_state *state, > } > > if (request.type == SPNEGO_NEG_TOKEN_INIT) { >+#ifdef HAVE_KRB5 >+ int krb5_idx = -1; >+#endif >+ int ntlm_idx = -1; >+ int used_idx = -1; >+ int i; >+ >+ if (state->spnego_mech) { >+ DEBUG(1, ("Client restarted SPNEGO with NegTokenInit " >+ "while mech[%s] was already negotiated\n", >+ state->spnego_mech)); >+ x_fprintf(x_stdout, "BH Client send NegTokenInit twice\n"); >+ return; >+ } > > /* Second request from Client. This is where the > client offers its mechanism to use. */ >@@ -1334,156 +1356,204 @@ static void manage_gss_spnego_request(struct ntlm_auth_state *state, > } > > status = NT_STATUS_UNSUCCESSFUL; >- if (strcmp(request.negTokenInit.mechTypes[0], OID_NTLMSSP) == 0) { >+ for (i = 0; request.negTokenInit.mechTypes[i] != NULL; i++) { >+ DEBUG(10,("got mech[%d][%s]\n", >+ i, request.negTokenInit.mechTypes[i])); >+#ifdef HAVE_KRB5 >+ if (strcmp(request.negTokenInit.mechTypes[i], OID_KERBEROS5_OLD) == 0) { >+ krb5_idx = i; >+ break; >+ } >+ if (strcmp(request.negTokenInit.mechTypes[i], OID_KERBEROS5) == 0) { >+ krb5_idx = i; >+ break; >+ } >+#endif >+ if (strcmp(request.negTokenInit.mechTypes[i], OID_NTLMSSP) == 0) { >+ ntlm_idx = i; >+ break; >+ } >+ } > >- if ( request.negTokenInit.mechToken.data == NULL ) { >- DEBUG(1, ("Client did not provide NTLMSSP data\n")); >- x_fprintf(x_stdout, "BH Client did not provide " >- "NTLMSSP data\n"); >+ used_idx = ntlm_idx; >+#ifdef HAVE_KRB5 >+ if (krb5_idx != -1) { >+ ntlm_idx = -1; >+ used_idx = krb5_idx; >+ } >+#endif >+ if (ntlm_idx > -1) { >+ state->spnego_mech = talloc_strdup(state, "ntlmssp"); >+ if (state->spnego_mech == NULL) { >+ x_fprintf(x_stdout, "BH Out of memory\n"); > return; > } > >- if ( ntlmssp_state != NULL ) { >+ if (state->ntlmssp_state) { > DEBUG(1, ("Client wants a new NTLMSSP challenge, but " > "already got one\n")); > x_fprintf(x_stdout, "BH Client wants a new " > "NTLMSSP challenge, but " > "already got one\n"); >- ntlmssp_end(&ntlmssp_state); >+ ntlmssp_end(&state->ntlmssp_state); > return; > } > >- if (!NT_STATUS_IS_OK(status = ntlm_auth_start_ntlmssp_server(&ntlmssp_state))) { >+ status = ntlm_auth_start_ntlmssp_server(&state->ntlmssp_state); >+ if (!NT_STATUS_IS_OK(status)) { > x_fprintf(x_stdout, "BH %s\n", nt_errstr(status)); > return; > } >- >- DEBUG(10, ("got NTLMSSP packet:\n")); >- dump_data(10, request.negTokenInit.mechToken.data, >- request.negTokenInit.mechToken.length); >- >- response.type = SPNEGO_NEG_TOKEN_TARG; >- response.negTokenTarg.supportedMech = talloc_strdup(ctx, OID_NTLMSSP); >- response.negTokenTarg.mechListMIC = data_blob_talloc(ctx, NULL, 0); >- >- status = ntlmssp_update(ntlmssp_state, >- request.negTokenInit.mechToken, >- &response.negTokenTarg.responseToken); > } > > #ifdef HAVE_KRB5 >- if (strcmp(request.negTokenInit.mechTypes[0], OID_KERBEROS5_OLD) == 0) { >- >- TALLOC_CTX *mem_ctx = talloc_init("manage_gss_spnego_request"); >- char *principal; >- DATA_BLOB ap_rep; >- DATA_BLOB session_key = data_blob_null; >- struct PAC_DATA *pac_data = NULL; >- DATA_BLOB ticket; >- uint8_t tok_id[2]; >- >- if ( request.negTokenInit.mechToken.data == NULL ) { >- DEBUG(1, ("Client did not provide Kerberos data\n")); >- x_fprintf(x_stdout, "BH Client did not provide " >- "Kerberos data\n"); >+ if (krb5_idx > -1) { >+ state->spnego_mech = talloc_strdup(state, "krb5"); >+ if (state->spnego_mech == NULL) { >+ x_fprintf(x_stdout, "BH Out of memory\n"); > return; > } >- >- dump_data(10, request.negTokenInit.mechToken.data, >- request.negTokenInit.mechToken.length); >- >- if (!_spnego_parse_krb5_wrap(ctx, request.negTokenInit.mechToken, >- &ticket, tok_id)) { >- DEBUG(1, ("spnego_parse_krb5_wrap failed\n")); >- x_fprintf(x_stdout, "BH spnego_parse_krb5_wrap failed\n"); >+ } >+#endif >+ if (used_idx > -1) { >+ state->spnego_mech_oid = talloc_strdup(state, >+ request.negTokenInit.mechTypes[used_idx]); >+ if (state->spnego_mech_oid == NULL) { >+ x_fprintf(x_stdout, "BH Out of memory\n"); > return; > } >- >- response.type = SPNEGO_NEG_TOKEN_TARG; >- response.negTokenTarg.supportedMech = talloc_strdup(ctx, OID_KERBEROS5_OLD); >- response.negTokenTarg.mechListMIC = data_blob_talloc(ctx, NULL, 0); >- response.negTokenTarg.responseToken = data_blob_talloc(ctx, NULL, 0); >- >- status = ads_verify_ticket(mem_ctx, lp_realm(), 0, >- &ticket, >- &principal, &pac_data, &ap_rep, >- &session_key, True); >- >- /* Now in "principal" we have the name we are >- authenticated as. */ >- >- if (NT_STATUS_IS_OK(status)) { >- >- domain = strchr_m(principal, '@'); >- >- if (domain == NULL) { >- DEBUG(1, ("Did not get a valid principal " >- "from ads_verify_ticket\n")); >- x_fprintf(x_stdout, "BH Did not get a " >- "valid principal from " >- "ads_verify_ticket\n"); >- return; >- } >- >- *domain++ = '\0'; >- domain = SMB_STRDUP(domain); >- user = SMB_STRDUP(principal); >- >- data_blob_free(&ap_rep); >- data_blob_free(&session_key); >+ supportedMech = talloc_strdup(ctx, state->spnego_mech_oid); >+ if (supportedMech == NULL) { >+ x_fprintf(x_stdout, "BH Out of memory\n"); >+ return; > } > >- TALLOC_FREE(mem_ctx); >+ status = NT_STATUS_MORE_PROCESSING_REQUIRED; >+ } else { >+ status = NT_STATUS_NOT_SUPPORTED; >+ } >+ if (used_idx == 0) { >+ status = NT_STATUS_OK; >+ raw_in_token = request.negTokenInit.mechToken; > } >-#endif >- > } else { >+ if (state->spnego_mech == NULL) { >+ DEBUG(1,("Got netTokenTarg without negTokenInit\n")); >+ x_fprintf(x_stdout, "BH Got a negTokenTarg without " >+ "negTokenInit\n"); >+ return; >+ } > >- if ( (request.negTokenTarg.supportedMech == NULL) || >- ( strcmp(request.negTokenTarg.supportedMech, OID_NTLMSSP) != 0 ) ) { >- /* Kerberos should never send a negTokenTarg, OID_NTLMSSP >- is the only one we support that sends this stuff */ >- DEBUG(1, ("Got a negTokenTarg for something non-NTLMSSP: %s\n", >- request.negTokenTarg.supportedMech)); >- x_fprintf(x_stdout, "BH Got a negTokenTarg for " >- "something non-NTLMSSP\n"); >+ if ((request.negTokenTarg.supportedMech != NULL) && >+ (strcmp(request.negTokenTarg.supportedMech, state->spnego_mech_oid) != 0 ) ) { >+ DEBUG(1, ("Got a negTokenTarg with mech[%s] while [%s] was already negotiated\n", >+ request.negTokenTarg.supportedMech, >+ state->spnego_mech_oid)); >+ x_fprintf(x_stdout, "BH Got a negTokenTarg with speficied mech\n"); > return; > } > >- if (request.negTokenTarg.responseToken.data == NULL) { >- DEBUG(1, ("Got a negTokenTarg without a responseToken!\n")); >- x_fprintf(x_stdout, "BH Got a negTokenTarg without a " >- "responseToken!\n"); >+ status = NT_STATUS_OK; >+ raw_in_token = request.negTokenTarg.responseToken; >+ } >+ >+ if (!NT_STATUS_IS_OK(status)) { >+ /* error or more processing */ >+ } else if (strcmp(state->spnego_mech, "ntlmssp") == 0) { >+ >+ DEBUG(10, ("got NTLMSSP packet:\n")); >+ dump_data(10, raw_in_token.data, raw_in_token.length); >+ >+ status = ntlmssp_update(state->ntlmssp_state, >+ raw_in_token, >+ &raw_out_token); >+ if (NT_STATUS_IS_OK(status)) { >+ user = talloc_strdup(ctx, state->ntlmssp_state->user); >+ domain = talloc_strdup(ctx, state->ntlmssp_state->domain); >+ } >+ if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { >+ ntlmssp_end(&state->ntlmssp_state); >+ } >+#ifdef HAVE_KRB5 >+ } else if (strcmp(state->spnego_mech, "krb5") == 0) { >+ char *principal; >+ DATA_BLOB ap_rep; >+ DATA_BLOB session_key; >+ struct PAC_DATA *pac_data = NULL; >+ DATA_BLOB ticket; >+ uint8_t tok_id[2]; >+ >+ if (!_spnego_parse_krb5_wrap(ctx, raw_in_token, >+ &ticket, tok_id)) { >+ DEBUG(1, ("spnego_parse_krb5_wrap failed\n")); >+ x_fprintf(x_stdout, "BH spnego_parse_krb5_wrap failed\n"); > return; > } > >- status = ntlmssp_update(ntlmssp_state, >- request.negTokenTarg.responseToken, >- &response.negTokenTarg.responseToken); >+ status = ads_verify_ticket(ctx, lp_realm(), 0, >+ &ticket, >+ &principal, &pac_data, &ap_rep, >+ &session_key, True); > >- response.type = SPNEGO_NEG_TOKEN_TARG; >- response.negTokenTarg.supportedMech = talloc_strdup(ctx, OID_NTLMSSP); >- response.negTokenTarg.mechListMIC = data_blob_talloc(ctx, NULL, 0); >+ /* Now in "principal" we have the name we are authenticated as. */ > > if (NT_STATUS_IS_OK(status)) { >- user = SMB_STRDUP(ntlmssp_state->user); >- domain = SMB_STRDUP(ntlmssp_state->domain); >- ntlmssp_end(&ntlmssp_state); >+ >+ domain = strchr_m(principal, '@'); >+ >+ if (domain == NULL) { >+ DEBUG(1, ("Did not get a valid principal " >+ "from ads_verify_ticket\n")); >+ x_fprintf(x_stdout, "BH Did not get a " >+ "valid principal from " >+ "ads_verify_ticket\n"); >+ return; >+ } >+ >+ *domain++ = '\0'; >+ domain = talloc_strdup(ctx, domain); >+ user = talloc_strdup(ctx, principal); >+ >+ if (pac_data) { >+ struct PAC_LOGON_INFO *logon_info; >+ logon_info = get_logon_info_from_pac( >+ pac_data); >+ if (logon_info) { >+ netsamlogon_cache_store( >+ user, >+ &logon_info->info3); >+ } >+ } >+ >+ data_blob_free(&ap_rep); >+ data_blob_free(&session_key); > } >+ data_blob_free(&ticket); >+#endif > } > > spnego_free_data(&request); >+ ZERO_STRUCT(response); >+ response.type = SPNEGO_NEG_TOKEN_TARG; > > if (NT_STATUS_IS_OK(status)) { >+ TALLOC_FREE(state->spnego_mech); >+ TALLOC_FREE(state->spnego_mech_oid); > response.negTokenTarg.negResult = SPNEGO_ACCEPT_COMPLETED; >+ response.negTokenTarg.responseToken = raw_out_token; > reply_code = "AF"; > reply_argument = talloc_asprintf(ctx, "%s\\%s", domain, user); > } else if (NT_STATUS_EQUAL(status, > NT_STATUS_MORE_PROCESSING_REQUIRED)) { >+ response.negTokenTarg.supportedMech = supportedMech; >+ response.negTokenTarg.responseToken = raw_out_token; > response.negTokenTarg.negResult = SPNEGO_ACCEPT_INCOMPLETE; > reply_code = "TT"; > reply_argument = talloc_strdup(ctx, "*"); > } else { >+ TALLOC_FREE(state->spnego_mech); >+ TALLOC_FREE(state->spnego_mech_oid); >+ data_blob_free(&raw_out_token); > response.negTokenTarg.negResult = SPNEGO_REJECT; > reply_code = "NA"; > reply_argument = talloc_strdup(ctx, nt_errstr(status)); >@@ -1492,12 +1562,10 @@ static void manage_gss_spnego_request(struct ntlm_auth_state *state, > if (!reply_argument) { > DEBUG(1, ("Could not write SPNEGO data blob\n")); > x_fprintf(x_stdout, "BH Could not write SPNEGO data blob\n"); >+ spnego_free_data(&response); > return; > } > >- SAFE_FREE(user); >- SAFE_FREE(domain); >- > len = spnego_write_data(ctx, &token, &response); > spnego_free_data(&response); > >-- >1.7.0.4 >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Raw
Actions:
View
Attachments on
bug 7855
:
6125
|
6130