summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/Makefile.in4
-rw-r--r--source3/utils/ntlm_auth.c122
2 files changed, 112 insertions, 14 deletions
diff --git a/source3/Makefile.in b/source3/Makefile.in
index a55a1f5e12..92f3c44ddc 100644
--- a/source3/Makefile.in
+++ b/source3/Makefile.in
@@ -618,7 +618,7 @@ 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 $(LIBSAMBA_OBJ) $(POPT_LIB_OBJ) \
- libsmb/asn1.o libsmb/spnego.o
+ libsmb/asn1.o libsmb/spnego.o libsmb/clikrb5.o libads/kerberos.o
######################################################################
# now the rules...
@@ -1079,7 +1079,7 @@ bin/ntlm_auth@EXEEXT@: $(NTLM_AUTH_OBJ) $(PARAM_OBJ) $(LIB_OBJ) \
$(UBIQX_OBJ) @BUILD_POPT@ bin/.dummy
@echo Linking $@
@$(LINK) -o $@ $(NTLM_AUTH_OBJ) $(PARAM_OBJ) $(LIB_OBJ) \
- $(UBIQX_OBJ) $(LIBS) @POPTLIBS@
+ $(UBIQX_OBJ) $(LIBS) @POPTLIBS@ $(KRB5LIBS)
bin/pam_smbpass.@SHLIBEXT@: $(PAM_SMBPASS_PICOOBJ)
@echo "Linking shared library $@"
diff --git a/source3/utils/ntlm_auth.c b/source3/utils/ntlm_auth.c
index 5154744ed1..5f6950385e 100644
--- a/source3/utils/ntlm_auth.c
+++ b/source3/utils/ntlm_auth.c
@@ -498,6 +498,10 @@ static void manage_gss_spnego_request(enum squid_mode squid_mode,
dump_data(10, request.negTokenInit.mechToken.data,
request.negTokenInit.mechToken.length);
+ response.type = SPNEGO_NEG_TOKEN_TARG;
+ response.negTokenTarg.supportedMech = strdup(OID_NTLMSSP);
+ response.negTokenTarg.mechListMIC = data_blob(NULL, 0);
+
status = ntlmssp_server_update(ntlmssp_state,
request.negTokenInit.mechToken,
&response.negTokenTarg.responseToken);
@@ -505,10 +509,18 @@ static void manage_gss_spnego_request(enum squid_mode squid_mode,
} else {
- /* request.type == SPNEGO_NEG_TOKEN_TARG */
+ 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\n");
+ return;
+ }
if (request.negTokenTarg.responseToken.data == NULL) {
- DEBUG(1, ("Got a negTokenArg without a responseToken!\n"));
+ DEBUG(1, ("Got a negTokenTarg without a responseToken!\n"));
x_fprintf(x_stdout, "BH\n");
return;
}
@@ -517,6 +529,10 @@ static void manage_gss_spnego_request(enum squid_mode squid_mode,
request.negTokenTarg.responseToken,
&response.negTokenTarg.responseToken);
+ response.type = SPNEGO_NEG_TOKEN_TARG;
+ response.negTokenTarg.supportedMech = strdup(OID_NTLMSSP);
+ response.negTokenTarg.mechListMIC = data_blob(NULL, 0);
+
if (NT_STATUS_IS_OK(status)) {
user = strdup(ntlmssp_state->user);
domain = strdup(ntlmssp_state->domain);
@@ -526,10 +542,6 @@ static void manage_gss_spnego_request(enum squid_mode squid_mode,
free_spnego_data(&request);
- response.type = SPNEGO_NEG_TOKEN_TARG;
- response.negTokenTarg.supportedMech = strdup(OID_NTLMSSP);
- response.negTokenTarg.mechListMIC = data_blob(NULL, 0);
-
if (NT_STATUS_IS_OK(status)) {
response.negTokenTarg.negResult = SPNEGO_ACCEPT_COMPLETED;
reply_code = "AF";
@@ -724,16 +736,102 @@ static void manage_client_ntlmssp_targ(SPNEGO_DATA spnego)
static BOOL manage_client_krb5_init(SPNEGO_DATA spnego)
{
- DEBUG(1, ("to be done ... \n"));
- return False;
+ char *principal;
+ DATA_BLOB tkt, to_server;
+ unsigned char session_key_krb5[16];
+ SPNEGO_DATA reply;
+ char *reply_base64;
+
+ const char *my_mechs[] = {OID_KERBEROS5_OLD, NULL};
+ ssize_t len;
+
+ if ( (spnego.negTokenInit.mechListMIC.data == NULL) ||
+ (spnego.negTokenInit.mechListMIC.length == 0) ) {
+ DEBUG(1, ("Did not get a principal for krb5\n"));
+ return False;
+ }
+
+ principal = malloc(spnego.negTokenInit.mechListMIC.length+1);
+
+ if (principal == NULL) {
+ DEBUG(1, ("Could not malloc principal\n"));
+ return False;
+ }
+
+ memcpy(principal, spnego.negTokenInit.mechListMIC.data,
+ spnego.negTokenInit.mechListMIC.length);
+ principal[spnego.negTokenInit.mechListMIC.length] = '\0';
+
+ tkt = cli_krb5_get_ticket(principal, 0, session_key_krb5);
+
+ if (tkt.data == NULL) {
+
+ pstring user;
+
+ /* Let's try to first get the TGT, for that we need a
+ password. */
+
+ if (opt_password == NULL) {
+ DEBUG(10, ("Requesting password\n"));
+ x_fprintf(x_stdout, "PW\n");
+ return True;
+ }
+
+ pstr_sprintf(user, "%s@%s", opt_username, opt_domain);
+
+ if (kerberos_kinit_password(user, opt_password, 0) != 0) {
+ DEBUG(10, ("Requesting TGT failed\n"));
+ x_fprintf(x_stdout, "NA\n");
+ return True;
+ }
+
+ tkt = cli_krb5_get_ticket(principal, 0, session_key_krb5);
+ }
+
+ ZERO_STRUCT(reply);
+
+ reply.type = SPNEGO_NEG_TOKEN_INIT;
+ reply.negTokenInit.mechTypes = my_mechs;
+ reply.negTokenInit.reqFlags = 0;
+ reply.negTokenInit.mechToken = tkt;
+ reply.negTokenInit.mechListMIC = data_blob(NULL, 0);
+
+ len = write_spnego_data(&to_server, &reply);
+ data_blob_free(&tkt);
+
+ if (len == -1) {
+ DEBUG(1, ("Could not write SPNEGO data blob\n"));
+ return False;
+ }
+
+ reply_base64 = base64_encode_data_blob(to_server);
+ x_fprintf(x_stdout, "KK %s *\n", reply_base64);
+
+ SAFE_FREE(reply_base64);
+ data_blob_free(&to_server);
+ DEBUG(10, ("sent GSS-SPNEGO KERBEROS5 negTokenInit\n"));
+ return True;
}
static void manage_client_krb5_targ(SPNEGO_DATA spnego)
{
- DEBUG(1, ("Got a negTokenTarg with a Kerberos token. This should not "
- "happen!\n"));
- x_fprintf(x_stdout, "BH\n");
- return;
+ switch (spnego.negTokenTarg.negResult) {
+ case SPNEGO_ACCEPT_INCOMPLETE:
+ DEBUG(1, ("Got a Kerberos negTokenTarg with ACCEPT_INCOMPLETE\n"));
+ x_fprintf(x_stdout, "BH\n");
+ break;
+ case SPNEGO_ACCEPT_COMPLETED:
+ DEBUG(10, ("Accept completed\n"));
+ x_fprintf(x_stdout, "AF\n");
+ break;
+ case SPNEGO_REJECT:
+ DEBUG(10, ("Rejected\n"));
+ x_fprintf(x_stdout, "NA\n");
+ break;
+ default:
+ DEBUG(1, ("Got an invalid negTokenTarg\n"));
+ x_fprintf(x_stdout, "AF\n");
+ }
}
static void manage_gss_spnego_client_request(enum squid_mode squid_mode,