From cd6026135d3dc7eaa773c60aa168bae8f3f15502 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 13 Feb 2009 14:02:49 +1100 Subject: Push sam_get_server_info_principal into the auth subsystem This means it must be accessed via the supplied auth_context in the GENSEC server, and should remove the hard depenceny of GENSEC on the auth subsystem and ldb (allowing LDB not to rely on LDB is considered a good thing, apparently) Andrew Bartlett --- source4/auth/auth.h | 12 ++++++- source4/auth/gensec/config.mk | 2 +- source4/auth/gensec/gensec_gssapi.c | 10 +++--- source4/auth/gensec/gensec_krb5.c | 19 +++++++++-- source4/auth/ntlm/auth.c | 31 ++++++++++++++++++ source4/auth/ntlm/auth_sam.c | 65 ++++++++++++++++++++++++++++++++----- source4/auth/ntlm/config.mk | 1 - source4/auth/sam.c | 45 ------------------------- 8 files changed, 122 insertions(+), 63 deletions(-) diff --git a/source4/auth/auth.h b/source4/auth/auth.h index 0ef1e24cd3..973102d842 100644 --- a/source4/auth/auth.h +++ b/source4/auth/auth.h @@ -123,6 +123,7 @@ struct auth_serversupplied_info struct auth_method_context; struct auth_check_password_request; +struct auth_context; struct auth_operations { const char *name; @@ -144,6 +145,12 @@ struct auth_operations { NTSTATUS (*check_password)(struct auth_method_context *ctx, TALLOC_CTX *mem_ctx, const struct auth_usersupplied_info *user_info, struct auth_serversupplied_info **server_info); + + /* Lookup a 'server info' return based only on the principal */ + NTSTATUS (*get_server_info_principal)(TALLOC_CTX *mem_ctx, + struct auth_context *auth_context, + const char *principal, + struct auth_serversupplied_info **server_info); }; struct auth_method_context { @@ -187,7 +194,10 @@ struct auth_context { NTSTATUS (*set_challenge)(struct auth_context *auth_ctx, const uint8_t chal[8], const char *set_by); - + NTSTATUS (*get_server_info_principal)(TALLOC_CTX *mem_ctx, + struct auth_context *auth_context, + const char *principal, + struct auth_serversupplied_info **server_info); }; diff --git a/source4/auth/gensec/config.mk b/source4/auth/gensec/config.mk index 3d13ce7f6d..27cf442b68 100644 --- a/source4/auth/gensec/config.mk +++ b/source4/auth/gensec/config.mk @@ -21,7 +21,7 @@ $(eval $(call proto_header_template,$(gensecsrcdir)/gensec_proto.h,$(gensec_OBJ_ [MODULE::gensec_krb5] SUBSYSTEM = gensec INIT_FUNCTION = gensec_krb5_init -PRIVATE_DEPENDENCIES = CREDENTIALS KERBEROS auth_session auth_sam +PRIVATE_DEPENDENCIES = CREDENTIALS KERBEROS auth_session # End MODULE gensec_krb5 ################################################ diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index dcfffef3df..aae04dffe2 100644 --- a/source4/auth/gensec/gensec_gssapi.c +++ b/source4/auth/gensec/gensec_gssapi.c @@ -1290,12 +1290,14 @@ static NTSTATUS gensec_gssapi_session_info(struct gensec_security *gensec_securi return NT_STATUS_NO_MEMORY; } - if (!gensec_setting_bool(gensec_security->settings, "gensec", "require_pac", false)) { + if (gensec_security->auth_context && + !gensec_setting_bool(gensec_security->settings, "gensec", "require_pac", false)) { DEBUG(1, ("Unable to find PAC, resorting to local user lookup: %s\n", gssapi_error_string(mem_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid))); - nt_status = sam_get_server_info_principal(mem_ctx, gensec_security->event_ctx, - gensec_security->settings->lp_ctx, principal_string, - &server_info); + nt_status = gensec_security->auth_context->get_server_info_principal(mem_ctx, + gensec_security->auth_context, + principal_string, + &server_info); if (!NT_STATUS_IS_OK(nt_status)) { talloc_free(mem_ctx); diff --git a/source4/auth/gensec/gensec_krb5.c b/source4/auth/gensec/gensec_krb5.c index 6e715d0090..b04abfc16c 100644 --- a/source4/auth/gensec/gensec_krb5.c +++ b/source4/auth/gensec/gensec_krb5.c @@ -607,8 +607,23 @@ static NTSTATUS gensec_krb5_session_info(struct gensec_security *gensec_security DEBUG(5, ("krb5_ticket_get_authorization_data_type failed to find PAC: %s\n", smb_get_krb5_error_message(context, ret, mem_ctx))); - nt_status = sam_get_server_info_principal(mem_ctx, gensec_security->event_ctx, gensec_security->settings->lp_ctx, principal_string, - &server_info); + if (gensec_security->auth_context && + !gensec_setting_bool(gensec_security->settings, "gensec", "require_pac", false)) { + DEBUG(1, ("Unable to find PAC, resorting to local user lookup: %s")); + nt_status = gensec_security->auth_context->get_server_info_principal(mem_ctx, + gensec_security->auth_context, + principal_string, + &server_info); + if (!NT_STATUS_IS_OK(nt_status)) { + talloc_free(mem_ctx); + return nt_status; + } + } else { + DEBUG(1, ("Unable to find PAC in ticket from %s, failing to allow access\n", + principal_string)); + return NT_STATUS_ACCESS_DENIED; + } + krb5_free_principal(context, client_principal); free(principal_string); diff --git a/source4/auth/ntlm/auth.c b/source4/auth/ntlm/auth.c index 2aae4a075e..5520c9d01f 100644 --- a/source4/auth/ntlm/auth.c +++ b/source4/auth/ntlm/auth.c @@ -103,6 +103,36 @@ _PUBLIC_ NTSTATUS auth_get_challenge(struct auth_context *auth_ctx, const uint8_ return NT_STATUS_OK; } +/**************************************************************************** + Try to get a challenge out of the various authentication modules. + Returns a const char of length 8 bytes. +****************************************************************************/ +_PUBLIC_ NTSTATUS auth_get_server_info_principal(TALLOC_CTX *mem_ctx, + struct auth_context *auth_ctx, + const char *principal, + struct auth_serversupplied_info **server_info) +{ + NTSTATUS nt_status; + struct auth_method_context *method; + + for (method = auth_ctx->methods; method; method = method->next) { + if (!method->ops->get_server_info_principal) { + continue; + } + + nt_status = method->ops->get_server_info_principal(mem_ctx, auth_ctx, principal, server_info); + if (NT_STATUS_EQUAL(nt_status, NT_STATUS_NOT_IMPLEMENTED)) { + continue; + } + + NT_STATUS_NOT_OK_RETURN(nt_status); + + break; + } + + return NT_STATUS_OK; +} + struct auth_check_password_sync_state { bool finished; NTSTATUS status; @@ -411,6 +441,7 @@ _PUBLIC_ NTSTATUS auth_context_create_methods(TALLOC_CTX *mem_ctx, const char ** ctx->get_challenge = auth_get_challenge; ctx->set_challenge = auth_context_set_challenge; ctx->challenge_may_be_modified = auth_challenge_may_be_modified; + ctx->get_server_info_principal = auth_get_server_info_principal; *auth_ctx = ctx; diff --git a/source4/auth/ntlm/auth_sam.c b/source4/auth/ntlm/auth_sam.c index 384d342e00..96a13d5ed9 100644 --- a/source4/auth/ntlm/auth_sam.c +++ b/source4/auth/ntlm/auth_sam.c @@ -1,7 +1,7 @@ /* Unix SMB/CIFS implementation. Password and authentication handling - Copyright (C) Andrew Bartlett 2001-2004 + Copyright (C) Andrew Bartlett 2001-2009 Copyright (C) Gerald Carter 2003 Copyright (C) Stefan Metzmacher 2005 @@ -419,18 +419,65 @@ static NTSTATUS authsam_check_password(struct auth_method_context *ctx, return authsam_check_password_internals(ctx, mem_ctx, domain, user_info, server_info); } + +/* Used in the gensec_gssapi and gensec_krb5 server-side code, where the PAC isn't available */ +NTSTATUS authsam_get_server_info_principal(TALLOC_CTX *mem_ctx, + struct auth_context *auth_context, + const char *principal, + struct auth_serversupplied_info **server_info) +{ + NTSTATUS nt_status; + DATA_BLOB user_sess_key = data_blob(NULL, 0); + DATA_BLOB lm_sess_key = data_blob(NULL, 0); + + struct ldb_message **msgs; + struct ldb_message **msgs_domain_ref; + struct ldb_context *sam_ctx; + + TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx); + if (!tmp_ctx) { + return NT_STATUS_NO_MEMORY; + } + + sam_ctx = samdb_connect(tmp_ctx, auth_context->event_ctx, auth_context->lp_ctx, + system_session(tmp_ctx, auth_context->lp_ctx)); + if (sam_ctx == NULL) { + talloc_free(tmp_ctx); + return NT_STATUS_INVALID_SYSTEM_SERVICE; + } + + nt_status = sam_get_results_principal(sam_ctx, tmp_ctx, principal, + &msgs, &msgs_domain_ref); + if (!NT_STATUS_IS_OK(nt_status)) { + return nt_status; + } + + nt_status = authsam_make_server_info(tmp_ctx, sam_ctx, + lp_netbios_name(auth_context->lp_ctx), + msgs[0], msgs_domain_ref[0], + user_sess_key, lm_sess_key, + server_info); + if (NT_STATUS_IS_OK(nt_status)) { + talloc_steal(mem_ctx, *server_info); + } + talloc_free(tmp_ctx); + return nt_status; +} + static const struct auth_operations sam_ignoredomain_ops = { - .name = "sam_ignoredomain", - .get_challenge = auth_get_challenge_not_implemented, - .want_check = authsam_ignoredomain_want_check, - .check_password = authsam_ignoredomain_check_password + .name = "sam_ignoredomain", + .get_challenge = auth_get_challenge_not_implemented, + .want_check = authsam_ignoredomain_want_check, + .check_password = authsam_ignoredomain_check_password, + .get_server_info_principal = authsam_get_server_info_principal }; static const struct auth_operations sam_ops = { - .name = "sam", - .get_challenge = auth_get_challenge_not_implemented, - .want_check = authsam_want_check, - .check_password = authsam_check_password + .name = "sam", + .get_challenge = auth_get_challenge_not_implemented, + .want_check = authsam_want_check, + .check_password = authsam_check_password, + .get_server_info_principal = authsam_get_server_info_principal }; _PUBLIC_ NTSTATUS auth_sam_init(void) diff --git a/source4/auth/ntlm/config.mk b/source4/auth/ntlm/config.mk index 6a487f9b9e..668c528ea9 100644 --- a/source4/auth/ntlm/config.mk +++ b/source4/auth/ntlm/config.mk @@ -8,7 +8,6 @@ ntlm_check_OBJ_FILES = $(addprefix $(authsrcdir)/ntlm/, ntlm_check.o) ####################### # Start MODULE auth_sam [MODULE::auth_sam_module] -# gensec_krb5 and gensec_gssapi depend on it INIT_FUNCTION = auth_sam_init SUBSYSTEM = auth PRIVATE_DEPENDENCIES = \ diff --git a/source4/auth/sam.c b/source4/auth/sam.c index 0017db260c..819bca0db0 100644 --- a/source4/auth/sam.c +++ b/source4/auth/sam.c @@ -428,48 +428,3 @@ NTSTATUS sam_get_results_principal(struct ldb_context *sam_ctx, return NT_STATUS_OK; } - -/* Used in the gensec_gssapi and gensec_krb5 server-side code, where the PAC isn't available */ -NTSTATUS sam_get_server_info_principal(TALLOC_CTX *mem_ctx, - struct tevent_context *event_ctx, - struct loadparm_context *lp_ctx, - const char *principal, - struct auth_serversupplied_info **server_info) -{ - NTSTATUS nt_status; - DATA_BLOB user_sess_key = data_blob(NULL, 0); - DATA_BLOB lm_sess_key = data_blob(NULL, 0); - - struct ldb_message **msgs; - struct ldb_message **msgs_domain_ref; - struct ldb_context *sam_ctx; - - TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx); - if (!tmp_ctx) { - return NT_STATUS_NO_MEMORY; - } - - sam_ctx = samdb_connect(tmp_ctx, event_ctx, lp_ctx, - system_session(tmp_ctx, lp_ctx)); - if (sam_ctx == NULL) { - talloc_free(tmp_ctx); - return NT_STATUS_INVALID_SYSTEM_SERVICE; - } - - nt_status = sam_get_results_principal(sam_ctx, tmp_ctx, principal, - &msgs, &msgs_domain_ref); - if (!NT_STATUS_IS_OK(nt_status)) { - return nt_status; - } - - nt_status = authsam_make_server_info(tmp_ctx, sam_ctx, - lp_netbios_name(lp_ctx), - msgs[0], msgs_domain_ref[0], - user_sess_key, lm_sess_key, - server_info); - if (NT_STATUS_IS_OK(nt_status)) { - talloc_steal(mem_ctx, *server_info); - } - talloc_free(tmp_ctx); - return nt_status; -} -- cgit