Add the gss-spnego kerberos server side to ntml_auth. This uses the
authorVolker Lendecke <vlendec@samba.org>
Fri, 15 Aug 2003 02:57:59 +0000 (02:57 +0000)
committerVolker Lendecke <vlendec@samba.org>
Fri, 15 Aug 2003 02:57:59 +0000 (02:57 +0000)
same ads_verify_ticket routine that smbd uses, so in the current state
we have to be have the host password in secrets.tdb instead of the
keytab. This means we have to be an ADS member, but it's a start.

Volker

source/Makefile.in
source/libsmb/spnego.c
source/utils/ntlm_auth.c

index ebf4c1abd520d7e49ca907749518c63d62a72748..4e3daa50a21cbace156b9ce3c3d3bbb11e47a60d 100644 (file)
@@ -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...
index 0b2dec7ef84f1239b55b2fd539ae90258254ad71..50caf7b4c0e9d09b6016e45c25218f58b0cd5b02 100644 (file)
@@ -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);
        }
 
index 19d485a936715b78c723af371726e178e0536108..4ac125f317f643a1e952e2fa0a8badd31d30e305 100644 (file)
@@ -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) ||