The branch, master has been updated via 0858b75 s3: Add the PAC info3 struct to the netsamlogon_cache in ntlm_auth via 547b268 s3: Correctly unwrap the krb ticket in gss-spnego via 70ab7eb s3: Fall back to raw NTLMSSP for the gss-spnego protocol via de2c143 s3: Split off output generation from manage_squid_ntlmssp_request via ae483bb s3: Wrap the ntlm_auth loop with a talloc_stackframe from 0730d98 s4-smbtorture: add NDR spoolss_GetPrinterDriver2 in and out check functions.
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master - Log ----------------------------------------------------------------- commit 0858b7546eebf9e853e4e7288b50edbcdcdc5826 Author: Volker Lendecke <v...@samba.org> Date: Thu Sep 16 09:31:10 2010 +0200 s3: Add the PAC info3 struct to the netsamlogon_cache in ntlm_auth commit 547b268cfaa2e791bf92e8804bfa504c4e37050b Author: Volker Lendecke <v...@samba.org> Date: Thu Sep 16 10:34:59 2010 +0200 s3: Correctly unwrap the krb ticket in gss-spnego commit 70ab7eb5303a5ff058939541dd5bc1f81113a48e Author: Volker Lendecke <v...@samba.org> Date: Thu Sep 16 10:22:00 2010 +0200 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. commit de2c143f4d540f695db5c7fe8685614c03977365 Author: Volker Lendecke <v...@samba.org> Date: Thu Sep 16 10:21:20 2010 +0200 s3: Split off output generation from manage_squid_ntlmssp_request commit ae483bbe9af526623189cefe7735f3f2813da6d7 Author: Volker Lendecke <v...@samba.org> Date: Thu Sep 16 10:36:21 2010 +0200 s3: Wrap the ntlm_auth loop with a talloc_stackframe ----------------------------------------------------------------------- Summary of changes: source3/Makefile.in | 1 + source3/utils/ntlm_auth.c | 142 +++++++++++++++++++++++++++++++++++++++------ 2 files changed, 125 insertions(+), 18 deletions(-) Changeset truncated at 500 lines: diff --git a/source3/Makefile.in b/source3/Makefile.in index 64d0a6a..d712df6 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -1430,6 +1430,7 @@ NTLM_AUTH_OBJ1 = utils/ntlm_auth.o utils/ntlm_auth_diagnostics.o NTLM_AUTH_OBJ = ${NTLM_AUTH_OBJ1} $(LIBSAMBA_OBJ) $(POPT_LIB_OBJ) \ ../lib/util/asn1.o ../libcli/auth/spnego_parse.o libsmb/clikrb5.o libads/kerberos.o \ + libsmb/samlogon_cache.o \ $(LIBADS_SERVER_OBJ) \ $(PASSDB_OBJ) $(LIBTSOCKET_OBJ) $(GROUPDB_OBJ) \ $(SMBLDAP_OBJ) $(LIBNMB_OBJ) \ diff --git a/source3/utils/ntlm_auth.c b/source3/utils/ntlm_auth.c index 38ed9f7..f8145b4 100644 --- a/source3/utils/ntlm_auth.c +++ b/source3/utils/ntlm_auth.c @@ -34,6 +34,7 @@ #include "../lib/crypto/arcfour.h" #include "libads/kerberos_proto.h" #include "nsswitch/winbind_client.h" +#include "librpc/gen_ndr/krb5pac.h" #ifndef PAM_WINBIND_CONFIG_FILE #define PAM_WINBIND_CONFIG_FILE "/etc/security/pam_winbind.conf" @@ -812,15 +813,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; } @@ -830,7 +833,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); @@ -847,12 +850,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; } @@ -866,10 +869,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; @@ -878,17 +882,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; } @@ -896,7 +901,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, @@ -911,22 +917,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))); TALLOC_FREE(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->callback_private); + *response = talloc_asprintf( + mem_ctx, "AF %s", + (char *)state->ntlmssp_state->callback_private); DEBUG(10, ("NTLMSSP OK!\n")); if(state->have_session_key) @@ -942,6 +951,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) { @@ -1199,6 +1224,45 @@ static void offer_gss_spnego_mechs(void) { return; } +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) { @@ -1250,6 +1314,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); @@ -1318,6 +1407,8 @@ static void manage_gss_spnego_request(struct ntlm_auth_state *state, DATA_BLOB ap_rep; DATA_BLOB session_key; struct PAC_LOGON_INFO *logon_info = NULL; + DATA_BLOB ticket; + uint8_t tok_id[2]; if ( request.negTokenInit.mechToken.data == NULL ) { DEBUG(1, ("Client did not provide Kerberos data\n")); @@ -1326,13 +1417,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, &logon_info, &ap_rep, &session_key, True); @@ -1356,6 +1457,9 @@ static void manage_gss_spnego_request(struct ntlm_auth_state *state, domain = SMB_STRDUP(domain); user = SMB_STRDUP(principal); + netsamlogon_cache_store( + user, &logon_info->info3); + data_blob_free(&ap_rep); } @@ -2319,7 +2423,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); } } -- Samba Shared Repository