diff options
-rw-r--r-- | source3/Makefile.in | 7 | ||||
-rw-r--r-- | source3/libsmb/spnego.c | 14 | ||||
-rw-r--r-- | source3/utils/ntlm_auth.c | 78 |
3 files changed, 87 insertions, 12 deletions
diff --git a/source3/Makefile.in b/source3/Makefile.in index ebf4c1abd5..4e3daa50a2 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -623,8 +623,11 @@ POPT_OBJS=popt/findme.o popt/popt.o popt/poptconfig.o \ TDBBACKUP_OBJ = tdb/tdbbackup.o tdb/tdbback.o $(TDBBASE_OBJ) -NTLM_AUTH_OBJ = utils/ntlm_auth.o $(SECRETS_OBJ) $(LIBSAMBA_OBJ) $(POPT_LIB_OBJ) \ - libsmb/asn1.o libsmb/spnego.o libsmb/clikrb5.o libads/kerberos.o +NTLM_AUTH_OBJ = utils/ntlm_auth.o $(LIBSAMBA_OBJ) $(POPT_LIB_OBJ) \ + libsmb/asn1.o libsmb/spnego.o libsmb/clikrb5.o libads/kerberos.o \ + libads/kerberos_verify.o passdb/secrets.o lib/server_mutex.o \ + libads/authdata.o rpc_parse/parse_prs.o rpc_parse/parse_misc.o \ + libsmb/doserr.o ###################################################################### # now the rules... diff --git a/source3/libsmb/spnego.c b/source3/libsmb/spnego.c index 0b2dec7ef8..50caf7b4c0 100644 --- a/source3/libsmb/spnego.c +++ b/source3/libsmb/spnego.c @@ -140,8 +140,22 @@ static BOOL write_negTokenInit(ASN1_DATA *asn1, negTokenInit_t *token) /* write mechListMIC */ if (token->mechListMIC.data) { asn1_push_tag(asn1, ASN1_CONTEXT(3)); +#if 0 + /* This is what RFC 2478 says ... */ asn1_write_OctetString(asn1, token->mechListMIC.data, token->mechListMIC.length); +#else + /* ... but unfortunately this is what Windows + sends/expects */ + asn1_push_tag(asn1, ASN1_SEQUENCE(0)); + asn1_push_tag(asn1, ASN1_CONTEXT(0)); + asn1_push_tag(asn1, ASN1_GENERAL_STRING); + asn1_write(asn1, token->mechListMIC.data, + token->mechListMIC.length); + asn1_pop_tag(asn1); + asn1_pop_tag(asn1); + asn1_pop_tag(asn1); +#endif asn1_pop_tag(asn1); } diff --git a/source3/utils/ntlm_auth.c b/source3/utils/ntlm_auth.c index 19d485a936..4ac125f317 100644 --- a/source3/utils/ntlm_auth.c +++ b/source3/utils/ntlm_auth.c @@ -361,27 +361,35 @@ static void manage_squid_basic_request(enum squid_mode squid_mode, static void offer_gss_spnego_mechs(void) { DATA_BLOB token; - ASN1_DATA asn1; SPNEGO_DATA spnego; ssize_t len; char *reply_base64; + pstring principal; + pstring myname_lower; + ZERO_STRUCT(spnego); + pstrcpy(myname_lower, global_myname()); + strlower_m(myname_lower); + + pstr_sprintf(principal, "%s$@%s", myname_lower, lp_realm()); + /* Server negTokenInit (mech offerings) */ spnego.type = SPNEGO_NEG_TOKEN_INIT; - spnego.negTokenInit.mechTypes = smb_xmalloc(sizeof(char *) * 2); + spnego.negTokenInit.mechTypes = smb_xmalloc(sizeof(char *) * 3); +#ifdef HAVE_KRB5 + spnego.negTokenInit.mechTypes[0] = smb_xstrdup(OID_KERBEROS5_OLD); + spnego.negTokenInit.mechTypes[1] = smb_xstrdup(OID_NTLMSSP); + spnego.negTokenInit.mechTypes[2] = NULL; +#else spnego.negTokenInit.mechTypes[0] = smb_xstrdup(OID_NTLMSSP); spnego.negTokenInit.mechTypes[1] = NULL; +#endif + - ZERO_STRUCT(asn1); - asn1_push_tag(&asn1, ASN1_SEQUENCE(0)); - asn1_push_tag(&asn1, ASN1_CONTEXT(0)); - asn1_write_GeneralString(&asn1, "NONE"); - asn1_pop_tag(&asn1); - asn1_pop_tag(&asn1); - spnego.negTokenInit.mechListMIC = data_blob(asn1.data, asn1.length); - asn1_free(&asn1); + spnego.negTokenInit.mechListMIC = data_blob(principal, + strlen(principal)); len = write_spnego_data(&token, &spnego); free_spnego_data(&spnego); @@ -507,6 +515,56 @@ static void manage_gss_spnego_request(enum squid_mode squid_mode, &response.negTokenTarg.responseToken); } +#ifdef HAVE_KRB5 + if (strcmp(request.negTokenInit.mechTypes[0], OID_KERBEROS5_OLD) == 0) { + + char *principal; + DATA_BLOB auth_data; + DATA_BLOB ap_rep; + uint8 session_key[16]; + + if ( request.negTokenInit.mechToken.data == NULL ) { + DEBUG(1, ("Client did not provide Kerberos data\n")); + x_fprintf(x_stdout, "BH\n"); + return; + } + + response.type = SPNEGO_NEG_TOKEN_TARG; + response.negTokenTarg.supportedMech = strdup(OID_KERBEROS5_OLD); + response.negTokenTarg.mechListMIC = data_blob(NULL, 0); + response.negTokenTarg.responseToken = data_blob(NULL, 0); + + status = ads_verify_ticket(lp_realm(), + &request.negTokenInit.mechToken, + &principal, &auth_data, &ap_rep, + session_key); + + /* Now in "principal" we have the name we are + authenticated as. */ + + if (NT_STATUS_IS_OK(status)) { + + domain = strchr(principal, '@'); + + if (domain == NULL) { + DEBUG(1, ("Did not get a valid principal " + "from ads_verify_ticket\n")); + x_fprintf(x_stdout, "BH\n"); + return; + } + + *domain++ = '\0'; + domain = strdup(domain); + user = strdup(principal); + + data_blob_free(&ap_rep); + data_blob_free(&auth_data); + + SAFE_FREE(principal); + } + } +#endif + } else { if ( (request.negTokenTarg.supportedMech == NULL) || |