svn commit: samba r10291 - in branches/SAMBA_4_0/source: auth/gensec param

abartlet at samba.org abartlet at samba.org
Sat Sep 17 09:46:21 GMT 2005


Author: abartlet
Date: 2005-09-17 09:46:20 +0000 (Sat, 17 Sep 2005)
New Revision: 10291

WebSVN: http://websvn.samba.org/cgi-bin/viewcvs.cgi?view=rev&root=samba&rev=10291

Log:
The patch optionally (off by default, not available in all cases) allows
Samba to use the target principal name supplied in the mechTokenMIC of
an SPNEGO negTokenInit.

This isn't a great idea for security reasons, but is how Samba3 behaves,
and allows kerberos to function more often in some environments.  It is
only available for CIFS session setups, due to the ordering of the
exchange.

Andrew Bartlett

Modified:
   branches/SAMBA_4_0/source/auth/gensec/gensec.c
   branches/SAMBA_4_0/source/auth/gensec/gensec_gssapi.c
   branches/SAMBA_4_0/source/auth/gensec/gensec_krb5.c
   branches/SAMBA_4_0/source/auth/gensec/spnego.c
   branches/SAMBA_4_0/source/param/loadparm.c


Changeset:
Modified: branches/SAMBA_4_0/source/auth/gensec/gensec.c
===================================================================
--- branches/SAMBA_4_0/source/auth/gensec/gensec.c	2005-09-17 07:48:49 UTC (rev 10290)
+++ branches/SAMBA_4_0/source/auth/gensec/gensec.c	2005-09-17 09:46:20 UTC (rev 10291)
@@ -707,6 +707,15 @@
 	return NT_STATUS_OK;
 }
 
+const char *gensec_get_target_service(struct gensec_security *gensec_security) 
+{
+	if (gensec_security->target.service) {
+		return gensec_security->target.service;
+	}
+
+	return "host";
+}
+
 /** 
  * Set the target hostname (suitable for kerberos resolutation) on a GENSEC context - ensures it is talloc()ed 
  *
@@ -731,13 +740,28 @@
 	return NULL;
 }
 
-const char *gensec_get_target_service(struct gensec_security *gensec_security) 
+/** 
+ * Set the target principal (assuming it it known, say from the SPNEGO reply)
+ *  - ensures it is talloc()ed 
+ *
+ */
+
+NTSTATUS gensec_set_target_principal(struct gensec_security *gensec_security, const char *principal) 
 {
-	if (gensec_security->target.service) {
-		return gensec_security->target.service;
+	gensec_security->target.principal = talloc_strdup(gensec_security, principal);
+	if (!gensec_security->target.principal) {
+		return NT_STATUS_NO_MEMORY;
 	}
+	return NT_STATUS_OK;
+}
 
-	return "host";
+const char *gensec_get_target_principal(struct gensec_security *gensec_security) 
+{
+	if (gensec_security->target.principal) {
+		return gensec_security->target.principal;
+	}
+
+	return NULL;
 }
 
 /*

Modified: branches/SAMBA_4_0/source/auth/gensec/gensec_gssapi.c
===================================================================
--- branches/SAMBA_4_0/source/auth/gensec/gensec_gssapi.c	2005-09-17 07:48:49 UTC (rev 10290)
+++ branches/SAMBA_4_0/source/auth/gensec/gensec_gssapi.c	2005-09-17 09:46:20 UTC (rev 10291)
@@ -229,8 +229,10 @@
 	krb5_error_code ret;
 	NTSTATUS nt_status;
 	gss_buffer_desc name_token;
+	gss_OID name_type;
 	OM_uint32 maj_stat, min_stat;
 	const char *hostname = gensec_get_target_hostname(gensec_security);
+	const char *principal;
 
 	if (!hostname) {
 		DEBUG(1, ("Could not determine hostname for target computer, cannot use kerberos\n"));
@@ -248,14 +250,22 @@
 
 	gensec_gssapi_state = gensec_security->private_data;
 
-	name_token.value = talloc_asprintf(gensec_gssapi_state, "%s@%s", 
-					   gensec_get_target_service(gensec_security), 
-					   hostname);
-	name_token.length = strlen(name_token.value);
+	principal = gensec_get_target_principal(gensec_security);
+	if (principal && lp_client_use_spnego_principal()) {
+		name_token.value = gensec_get_target_principal(gensec_security);
+		name_token.length = strlen(name_token.value);
+		name_type = GSS_C_NULL_OID;
+	} else {
+		name_token.value = talloc_asprintf(gensec_gssapi_state, "%s@%s", 
+						   gensec_get_target_service(gensec_security), 
+						   hostname);
+		name_token.length = strlen(name_token.value);
+		name_type = GSS_C_NT_HOSTBASED_SERVICE;
+	}		
 
 	maj_stat = gss_import_name (&min_stat,
 				    &name_token,
-				    GSS_C_NT_HOSTBASED_SERVICE,
+				    name_type,
 				    &gensec_gssapi_state->server_name);
 	if (maj_stat) {
 		DEBUG(2, ("GSS Import name of %s failed: %s\n",

Modified: branches/SAMBA_4_0/source/auth/gensec/gensec_krb5.c
===================================================================
--- branches/SAMBA_4_0/source/auth/gensec/gensec_krb5.c	2005-09-17 07:48:49 UTC (rev 10290)
+++ branches/SAMBA_4_0/source/auth/gensec/gensec_krb5.c	2005-09-17 09:46:20 UTC (rev 10291)
@@ -50,10 +50,14 @@
 	krb5_ticket *ticket;
 };
 
-static int gensec_krb5_destory(void *ptr) 
+static int gensec_krb5_destroy(void *ptr) 
 {
 	struct gensec_krb5_state *gensec_krb5_state = ptr;
 
+	if (!gensec_krb5_state->smb_krb5_context) {
+		/* We can't clean anything else up unless we started up this far */
+		return 0;
+	}
 	if (gensec_krb5_state->enc_ticket.length) { 
 		kerberos_free_data_contents(gensec_krb5_state->smb_krb5_context->krb5_context, 
 					    &gensec_krb5_state->enc_ticket); 
@@ -88,6 +92,7 @@
 
 	gensec_security->private_data = gensec_krb5_state;
 
+	gensec_krb5_state->smb_krb5_context = NULL;
 	gensec_krb5_state->auth_context = NULL;
 	gensec_krb5_state->ticket = NULL;
 	ZERO_STRUCT(gensec_krb5_state->enc_ticket);
@@ -95,7 +100,7 @@
 	gensec_krb5_state->session_key = data_blob(NULL, 0);
 	gensec_krb5_state->pac = data_blob(NULL, 0);
 
-	talloc_set_destructor(gensec_krb5_state, gensec_krb5_destory); 
+	talloc_set_destructor(gensec_krb5_state, gensec_krb5_destroy); 
 
 	return NT_STATUS_OK;
 }
@@ -141,8 +146,10 @@
 	krb5_error_code ret;
 	NTSTATUS nt_status;
 	struct ccache_container *ccache_container;
+	const char *hostname;
+	krb5_flags ap_req_options = AP_OPTS_USE_SUBKEY | AP_OPTS_MUTUAL_REQUIRED;
 
-	const char *hostname = gensec_get_target_hostname(gensec_security);
+	hostname = gensec_get_target_hostname(gensec_security);
 	if (!hostname) {
 		DEBUG(1, ("Could not determine hostname for target computer, cannot use kerberos\n"));
 		return NT_STATUS_INVALID_PARAMETER;
@@ -178,18 +185,35 @@
 		return NT_STATUS_INTERNAL_ERROR;
 	}
 
-	if (!ret) {
+	if (ret == 0) {
+		char *principal;
 		krb5_data in_data;
 		in_data.length = 0;
 		
-		ret = krb5_mk_req(gensec_krb5_state->smb_krb5_context->krb5_context, 
-				  &gensec_krb5_state->auth_context,
-				  AP_OPTS_USE_SUBKEY | AP_OPTS_MUTUAL_REQUIRED,
-				  gensec_get_target_service(gensec_security),
-				  hostname,
-				  &in_data, ccache_container->ccache, 
-				  &gensec_krb5_state->enc_ticket);
-		
+		principal = gensec_get_target_principal(gensec_security);
+		if (principal && lp_client_use_spnego_principal()) {
+			krb5_principal target_principal;
+			ret = krb5_parse_name(gensec_krb5_state->smb_krb5_context->krb5_context, principal,
+					      &target_principal);
+			if (ret == 0) {
+				ret = krb5_mk_req_exact(gensec_krb5_state->smb_krb5_context->krb5_context, 
+							&gensec_krb5_state->auth_context,
+							ap_req_options, 
+							target_principal,
+							&in_data, ccache_container->ccache, 
+							&gensec_krb5_state->enc_ticket);
+				krb5_free_principal(gensec_krb5_state->smb_krb5_context->krb5_context, 
+						    target_principal);
+			}
+		} else {
+			ret = krb5_mk_req(gensec_krb5_state->smb_krb5_context->krb5_context, 
+					  &gensec_krb5_state->auth_context,
+					  ap_req_options,
+					  gensec_get_target_service(gensec_security),
+					  hostname,
+					  &in_data, ccache_container->ccache, 
+					  &gensec_krb5_state->enc_ticket);
+		}
 	}
 	switch (ret) {
 	case 0:

Modified: branches/SAMBA_4_0/source/auth/gensec/spnego.c
===================================================================
--- branches/SAMBA_4_0/source/auth/gensec/spnego.c	2005-09-17 07:48:49 UTC (rev 10290)
+++ branches/SAMBA_4_0/source/auth/gensec/spnego.c	2005-09-17 09:46:20 UTC (rev 10291)
@@ -636,7 +636,8 @@
 		}
 
 		if (spnego.negTokenInit.targetPrincipal) {
-			DEBUG(5, ("Server claims it's principal name is %s (ignored)\n", spnego.negTokenInit.targetPrincipal));
+			DEBUG(5, ("Server claims it's principal name is %s\n", spnego.negTokenInit.targetPrincipal));
+			gensec_set_target_principal(gensec_security, spnego.negTokenInit.targetPrincipal);
 		}
 
 		nt_status = gensec_spnego_parse_negTokenInit(gensec_security,

Modified: branches/SAMBA_4_0/source/param/loadparm.c
===================================================================
--- branches/SAMBA_4_0/source/param/loadparm.c	2005-09-17 07:48:49 UTC (rev 10290)
+++ branches/SAMBA_4_0/source/param/loadparm.c	2005-09-17 09:46:20 UTC (rev 10291)
@@ -184,6 +184,7 @@
 	BOOL bClientPlaintextAuth;
 	BOOL bClientLanManAuth;
 	BOOL bClientNTLMv2Auth;
+	BOOL client_use_spnego_principal;
 	BOOL bHostMSDfs;
 	BOOL bUnicode;
 	BOOL bUnixExtensions;
@@ -422,6 +423,7 @@
 	{"client NTLMv2 auth", P_BOOL, P_GLOBAL, &Globals.bClientNTLMv2Auth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
 	{"client lanman auth", P_BOOL, P_GLOBAL, &Globals.bClientLanManAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
 	{"client plaintext auth", P_BOOL, P_GLOBAL, &Globals.bClientPlaintextAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
+	{"client use spnego principal", P_BOOL, P_GLOBAL, &Globals.client_use_spnego_principal, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
 	
 	{"read only", P_BOOL, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE},
 
@@ -659,6 +661,7 @@
 	do_parameter("ClientLanManAuth", "True", NULL);
 	do_parameter("LanmanAuth", "True", NULL);
 	do_parameter("NTLMAuth", "True", NULL);
+	do_parameter("client use spnego principal", "False", NULL);
 	
 	do_parameter("UnixExtensions", "False", NULL);
 
@@ -853,6 +856,7 @@
 FN_GLOBAL_BOOL(lp_client_plaintext_auth, &Globals.bClientPlaintextAuth)
 FN_GLOBAL_BOOL(lp_client_lanman_auth, &Globals.bClientLanManAuth)
 FN_GLOBAL_BOOL(lp_client_ntlmv2_auth, &Globals.bClientNTLMv2Auth)
+FN_GLOBAL_BOOL(lp_client_use_spnego_principal, &Globals.client_use_spnego_principal)
 FN_GLOBAL_BOOL(lp_host_msdfs, &Globals.bHostMSDfs)
 FN_GLOBAL_BOOL(lp_unix_extensions, &Globals.bUnixExtensions)
 FN_GLOBAL_BOOL(lp_use_spnego, &Globals.bUseSpnego)



More information about the samba-cvs mailing list