1
0
mirror of https://github.com/samba-team/samba.git synced 2025-02-05 21:57:51 +03:00

r10291: 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
This commit is contained in:
Andrew Bartlett 2005-09-17 09:46:20 +00:00 committed by Gerald (Jerry) Carter
parent 1a833690b8
commit f6a6456441
5 changed files with 85 additions and 22 deletions

View File

@ -707,6 +707,15 @@ NTSTATUS gensec_set_target_service(struct gensec_security *gensec_security, cons
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 @@ const char *gensec_get_target_hostname(struct gensec_security *gensec_security)
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;
}
const char *gensec_get_target_principal(struct gensec_security *gensec_security)
{
if (gensec_security->target.principal) {
return gensec_security->target.principal;
}
return "host";
return NULL;
}
/*

View File

@ -229,8 +229,10 @@ static NTSTATUS gensec_gssapi_client_start(struct gensec_security *gensec_securi
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 @@ static NTSTATUS gensec_gssapi_client_start(struct gensec_security *gensec_securi
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",

View File

@ -50,10 +50,14 @@ struct gensec_krb5_state {
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 @@ static NTSTATUS gensec_krb5_start(struct gensec_security *gensec_security)
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 @@ static NTSTATUS gensec_krb5_start(struct gensec_security *gensec_security)
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 @@ static NTSTATUS gensec_krb5_client_start(struct gensec_security *gensec_security
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 @@ static NTSTATUS gensec_krb5_client_start(struct gensec_security *gensec_security
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:

View File

@ -636,7 +636,8 @@ static NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TA
}
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,

View File

@ -184,6 +184,7 @@ typedef struct
BOOL bClientPlaintextAuth;
BOOL bClientLanManAuth;
BOOL bClientNTLMv2Auth;
BOOL client_use_spnego_principal;
BOOL bHostMSDfs;
BOOL bUnicode;
BOOL bUnixExtensions;
@ -422,6 +423,7 @@ static struct parm_struct parm_table[] = {
{"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 @@ static void init_globals(void)
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_ntlm_auth, &Globals.bNTLMAuth)
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)