From fe693e9148cdd9faf3525289a97373a5989e5416 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 29 Dec 2011 11:46:41 +1100 Subject: s4-torture: Demonstrate handling of the PAC in a custom auth_context This demonstrates how a different function pointer can be supplied to handle the PAC blob, without depending on the provisioned samdb etc. Andrew Bartlett --- source4/auth/gensec/gensec_util.c | 62 ++--------------------------- source4/auth/gensec/wscript_build | 2 +- source4/torture/rpc/remote_pac.c | 83 +++++++++++++++++++++++++++++++++++++-- 3 files changed, 85 insertions(+), 62 deletions(-) (limited to 'source4') diff --git a/source4/auth/gensec/gensec_util.c b/source4/auth/gensec/gensec_util.c index fa28c6528c..2b890239b0 100644 --- a/source4/auth/gensec/gensec_util.c +++ b/source4/auth/gensec/gensec_util.c @@ -26,9 +26,6 @@ #include "auth/auth.h" #include "auth/credentials/credentials.h" #include "auth/system_session_proto.h" -#include "system/kerberos.h" -#include "auth/kerberos/kerberos.h" -#include "auth/kerberos/kerberos_util.h" NTSTATUS gensec_generate_session_info(TALLOC_CTX *mem_ctx, struct gensec_security *gensec_security, @@ -71,12 +68,7 @@ NTSTATUS gensec_generate_session_info_pac(TALLOC_CTX *mem_ctx_out, const struct tsocket_address *remote_address, struct auth_session_info **session_info) { - NTSTATUS nt_status; uint32_t session_info_flags = 0; - TALLOC_CTX *mem_ctx; - struct auth_user_info_dc *user_info_dc; - struct PAC_SIGNATURE_DATA *pac_srv_sig = NULL; - struct PAC_SIGNATURE_DATA *pac_kdc_sig = NULL; if (gensec_security->want_features & GENSEC_FEATURE_UNIX_TOKEN) { session_info_flags |= AUTH_SESSION_INFO_UNIX_TOKEN; @@ -94,7 +86,7 @@ NTSTATUS gensec_generate_session_info_pac(TALLOC_CTX *mem_ctx_out, principal_string)); } - if (gensec_security->auth_context) { + if (gensec_security->auth_context && gensec_security->auth_context->generate_session_info_pac) { return gensec_security->auth_context->generate_session_info_pac(gensec_security->auth_context, mem_ctx_out, smb_krb5_context, @@ -103,54 +95,8 @@ NTSTATUS gensec_generate_session_info_pac(TALLOC_CTX *mem_ctx_out, remote_address, session_info_flags, session_info); - } else if (!pac_blob) { - DEBUG(0, ("Cannot generate a session_info without either the PAC or the auth_context\n")); - return NT_STATUS_NO_SUCH_USER; - } - - mem_ctx = talloc_named(mem_ctx_out, 0, "gensec_gssapi_session_info context"); - NT_STATUS_HAVE_NO_MEMORY(mem_ctx); - - pac_srv_sig = talloc(mem_ctx, struct PAC_SIGNATURE_DATA); - if (!pac_srv_sig) { - talloc_free(mem_ctx); - return NT_STATUS_NO_MEMORY; - } - pac_kdc_sig = talloc(mem_ctx, struct PAC_SIGNATURE_DATA); - if (!pac_kdc_sig) { - talloc_free(mem_ctx); - return NT_STATUS_NO_MEMORY; - } - - nt_status = kerberos_pac_blob_to_user_info_dc(mem_ctx, - *pac_blob, - smb_krb5_context->krb5_context, - &user_info_dc, - pac_srv_sig, - pac_kdc_sig); - if (!NT_STATUS_IS_OK(nt_status)) { - talloc_free(mem_ctx); - return nt_status; - } - - session_info_flags |= AUTH_SESSION_INFO_SIMPLE_PRIVILEGES; - nt_status = auth_generate_session_info(mem_ctx_out, - NULL, - NULL, - user_info_dc, session_info_flags, - session_info); - if (!NT_STATUS_IS_OK(nt_status)) { - talloc_free(mem_ctx); - return nt_status; - } - - if ((*session_info)->torture) { - (*session_info)->torture->pac_srv_sig - = talloc_steal((*session_info)->torture, pac_srv_sig); - (*session_info)->torture->pac_kdc_sig - = talloc_steal((*session_info)->torture, pac_kdc_sig); + } else { + DEBUG(0, ("Cannot generate a session_info without the auth_context\n")); + return NT_STATUS_INTERNAL_ERROR; } - - talloc_free(mem_ctx); - return nt_status; } diff --git a/source4/auth/gensec/wscript_build b/source4/auth/gensec/wscript_build index a4c5685f2e..9919cffeea 100644 --- a/source4/auth/gensec/wscript_build +++ b/source4/auth/gensec/wscript_build @@ -2,7 +2,7 @@ bld.SAMBA_SUBSYSTEM('gensec_util', source='socket.c gensec_tstream.c gensec_util.c', - deps='tevent-util tevent samba-util LIBTSOCKET KERBEROS_UTIL', + deps='tevent-util tevent samba-util LIBTSOCKET', autoproto='gensec_proto.h') bld.SAMBA_MODULE('gensec_krb5', diff --git a/source4/torture/rpc/remote_pac.c b/source4/torture/rpc/remote_pac.c index 22fcd73cb4..aca518799d 100644 --- a/source4/torture/rpc/remote_pac.c +++ b/source4/torture/rpc/remote_pac.c @@ -42,6 +42,71 @@ #define TEST_MACHINE_NAME_S2U4SELF_BDC "tests2u4selfbdc" #define TEST_MACHINE_NAME_S2U4SELF_WKSTA "tests2u4selfwk" +/* A helper function which avoids touching the local databases to + * generate the session info, as we just want to verify the PAC + * details, not the full local token */ +static NTSTATUS test_generate_session_info_pac(struct auth4_context *auth_ctx, + TALLOC_CTX *mem_ctx_out, + struct smb_krb5_context *smb_krb5_context, + DATA_BLOB *pac_blob, + const char *principal_name, + const struct tsocket_address *remote_address, + uint32_t session_info_flags, + struct auth_session_info **session_info) +{ + NTSTATUS nt_status; + struct auth_user_info_dc *user_info_dc; + struct PAC_SIGNATURE_DATA *pac_srv_sig = NULL; + struct PAC_SIGNATURE_DATA *pac_kdc_sig = NULL; + TALLOC_CTX *mem_ctx; + + mem_ctx = talloc_named(mem_ctx_out, 0, "gensec_gssapi_session_info context"); + NT_STATUS_HAVE_NO_MEMORY(mem_ctx); + + pac_srv_sig = talloc(mem_ctx, struct PAC_SIGNATURE_DATA); + if (!pac_srv_sig) { + talloc_free(mem_ctx); + return NT_STATUS_NO_MEMORY; + } + pac_kdc_sig = talloc(mem_ctx, struct PAC_SIGNATURE_DATA); + if (!pac_kdc_sig) { + talloc_free(mem_ctx); + return NT_STATUS_NO_MEMORY; + } + + nt_status = kerberos_pac_blob_to_user_info_dc(mem_ctx, + *pac_blob, + smb_krb5_context->krb5_context, + &user_info_dc, + pac_srv_sig, + pac_kdc_sig); + if (!NT_STATUS_IS_OK(nt_status)) { + talloc_free(mem_ctx); + return nt_status; + } + + session_info_flags |= AUTH_SESSION_INFO_SIMPLE_PRIVILEGES; + nt_status = auth_generate_session_info(mem_ctx_out, + NULL, + NULL, + user_info_dc, session_info_flags, + session_info); + if (!NT_STATUS_IS_OK(nt_status)) { + talloc_free(mem_ctx); + return nt_status; + } + + if ((*session_info)->torture) { + (*session_info)->torture->pac_srv_sig + = talloc_steal((*session_info)->torture, pac_srv_sig); + (*session_info)->torture->pac_kdc_sig + = talloc_steal((*session_info)->torture, pac_kdc_sig); + } + + talloc_free(mem_ctx); + return nt_status; +} + /* Check to see if we can pass the PAC across to the NETLOGON server for validation */ /* Also happens to be a really good one-step verfication of our Kerberos stack */ @@ -73,6 +138,7 @@ static bool test_PACVerify(struct torture_context *tctx, enum ndr_err_code ndr_err; + struct auth4_context *auth_context; struct auth_session_info *session_info; struct dcerpc_binding_handle *b = p->binding_handle; @@ -85,6 +151,11 @@ static bool test_PACVerify(struct torture_context *tctx, return false; } + auth_context = talloc_zero(tmp_ctx, struct auth4_context); + torture_assert(tctx, auth_context != NULL, "talloc_new() failed"); + + auth_context->generate_session_info_pac = test_generate_session_info_pac; + status = gensec_client_start(tctx, &gensec_client_context, lpcfg_gensec_settings(tctx, tctx->lp_ctx)); torture_assert_ntstatus_ok(tctx, status, "gensec_client_start (client) failed"); @@ -99,7 +170,7 @@ static bool test_PACVerify(struct torture_context *tctx, status = gensec_server_start(tctx, lpcfg_gensec_settings(tctx, tctx->lp_ctx), - NULL, &gensec_server_context); + auth_context, &gensec_server_context); torture_assert_ntstatus_ok(tctx, status, "gensec_server_start (server) failed"); status = gensec_set_credentials(gensec_server_context, credentials); @@ -407,6 +478,7 @@ static bool test_S2U4Self(struct torture_context *tctx, struct gensec_security *gensec_client_context; struct gensec_security *gensec_server_context; + struct auth4_context *auth_context; struct auth_session_info *kinit_session_info; struct auth_session_info *s2u4self_session_info; struct auth_user_info_dc *netlogon_user_info_dc; @@ -422,6 +494,11 @@ static bool test_S2U4Self(struct torture_context *tctx, torture_assert(tctx, tmp_ctx != NULL, "talloc_new() failed"); + auth_context = talloc_zero(tmp_ctx, struct auth4_context); + torture_assert(tctx, auth_context != NULL, "talloc_new() failed"); + + auth_context->generate_session_info_pac = test_generate_session_info_pac; + /* First, do a normal Kerberos connection */ status = gensec_client_start(tctx, &gensec_client_context, @@ -438,7 +515,7 @@ static bool test_S2U4Self(struct torture_context *tctx, status = gensec_server_start(tctx, lpcfg_gensec_settings(tctx, tctx->lp_ctx), - NULL, &gensec_server_context); + auth_context, &gensec_server_context); torture_assert_ntstatus_ok(tctx, status, "gensec_server_start (server) failed"); status = gensec_set_credentials(gensec_server_context, credentials); @@ -495,7 +572,7 @@ static bool test_S2U4Self(struct torture_context *tctx, status = gensec_server_start(tctx, lpcfg_gensec_settings(tctx, tctx->lp_ctx), - NULL, &gensec_server_context); + auth_context, &gensec_server_context); torture_assert_ntstatus_ok(tctx, status, "gensec_server_start (server) failed"); status = gensec_set_credentials(gensec_server_context, credentials); -- cgit