The branch, master has been updated via 1722e5fb1c3 s3: include: printing: align function parameters via 31563f5759f s3: include: printing: fix indentation of struct printif via 073dc735b4e s3: include: printing: move copyright notice to beginning via fd5cf415a75 s4:kdc: fix the principal names in samba_kdc_update_delegation_info_blob via 90bdaaf09d9 selftest: add a test for PAC delegation-info blob in S4U2Proxy via d6a4eea5fd2 selftest/remote_pac: split test_PACVerify() in two from 5216fd22872 smbstatus: fix column length for DenyMode
https://git.samba.org/?p=samba.git;a=shortlog;h=master - Log ----------------------------------------------------------------- commit 1722e5fb1c3df34fd8eb3f7d215b6d9a913ee45f Author: Marco Wang <m.aesop...@gmail.com> Date: Wed Aug 28 17:29:31 2019 +0800 s3: include: printing: align function parameters Signed-off-by: Marco Wang <m.aesop...@gmail.com> Reviewed-by: Andrew Bartlett <abart...@samba.org> Reviewed-by: Ralph Boehme <s...@samba.org> Autobuild-User(master): Andreas Schneider <a...@cryptomilk.org> Autobuild-Date(master): Mon Oct 21 16:01:56 UTC 2019 on sn-devel-184 commit 31563f5759f9aeab35b566e77e6ec20b0c4589e1 Author: Marco Wang <m.aesop...@gmail.com> Date: Wed Aug 28 17:28:26 2019 +0800 s3: include: printing: fix indentation of struct printif Signed-off-by: Marco Wang <m.aesop...@gmail.com> Reviewed-by: Andrew Bartlett <abart...@samba.org> Reviewed-by: Ralph Boehme <s...@samba.org> commit 073dc735b4e286ff1c57cb2634832eb04a78baac Author: Marco Wang <m.aesop...@gmail.com> Date: Wed Aug 28 17:26:14 2019 +0800 s3: include: printing: move copyright notice to beginning Signed-off-by: Marco Wang <m.aesop...@gmail.com> Reviewed-by: Andrew Bartlett <abart...@samba.org> Reviewed-by: Ralph Boehme <s...@samba.org> commit fd5cf415a7536c9f020fff57a707caa703c33b9c Author: Stefan Metzmacher <me...@samba.org> Date: Thu Sep 28 14:51:43 2017 +0200 s4:kdc: fix the principal names in samba_kdc_update_delegation_info_blob We need the target service without realm, but the proxy services with realm. I have a domain with an w2008r2 server and a samba and now both generate the same S4U_DELEGATION_INFO. BUG: https://bugzilla.samba.org/show_bug.cgi?id=13133 Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Alexander Bokovoy <a...@samba.org> Reviewed-by: Andreas Schneider <a...@samba.org> commit 90bdaaf09d9c5595170272bd0bfebaac0a90ae01 Author: Isaac Boukris <ibouk...@gmail.com> Date: Sun Oct 13 22:32:36 2019 +0300 selftest: add a test for PAC delegation-info blob in S4U2Proxy BUG: https://bugzilla.samba.org/show_bug.cgi?id=13133 Signed-off-by: Isaac Boukris <ibouk...@gmail.com> Reviewed-by: Alexander Bokovoy <a...@samba.org> Reviewed-by: Andreas Schneider <a...@samba.org> commit d6a4eea5fd284755d181426dba84ddd5c1ba9769 Author: Isaac Boukris <ibouk...@gmail.com> Date: Wed Oct 16 00:55:04 2019 +0300 selftest/remote_pac: split test_PACVerify() in two BUG: https://bugzilla.samba.org/show_bug.cgi?id=13133 Signed-off-by: Isaac Boukris <ibouk...@gmail.com> Reviewed-by: Alexander Bokovoy <a...@samba.org> Reviewed-by: Andreas Schneider <a...@samba.org> ----------------------------------------------------------------------- Summary of changes: source3/include/printing.h | 46 +++--- source4/kdc/pac-glue.c | 6 +- source4/torture/rpc/remote_pac.c | 330 ++++++++++++++++++++++++++++++++++----- 3 files changed, 319 insertions(+), 63 deletions(-) Changeset truncated at 500 lines: diff --git a/source3/include/printing.h b/source3/include/printing.h index 6fb730119f5..8a0bef31da1 100644 --- a/source3/include/printing.h +++ b/source3/include/printing.h @@ -1,6 +1,3 @@ -#ifndef PRINTING_H_ -#define PRINTING_H_ - /* Unix SMB/CIFS implementation. printing definitions @@ -24,6 +21,9 @@ This file defines the low-level printing system interfaces used by the SAMBA printing subsystem. */ +#ifndef PRINTING_H_ +#define PRINTING_H_ + #include <tdb.h> #include "lib/param/loadparm.h" @@ -90,22 +90,22 @@ struct printjob { /* Information for print interfaces */ struct printif { - /* value of the 'printing' option for this service */ - enum printing_types type; - - int (*queue_get)(const char *printer_name, - enum printing_types printing_type, - char *lpq_command, - print_queue_struct **q, - print_status_struct *status); - int (*queue_pause)(int snum); - int (*queue_resume)(int snum); - int (*job_delete)(const char *sharename, const char *lprm_command, struct printjob *pjob); - int (*job_pause)(int snum, struct printjob *pjob); - int (*job_resume)(int snum, struct printjob *pjob); - int (*job_submit)(int snum, struct printjob *pjob, - enum printing_types printing_type, - char *lpq_command); + /* value of the 'printing' option for this service */ + enum printing_types type; + + int (*queue_get)(const char *printer_name, + enum printing_types printing_type, + char *lpq_command, + print_queue_struct **q, + print_status_struct *status); + int (*queue_pause)(int snum); + int (*queue_resume)(int snum); + int (*job_delete)(const char *sharename, const char *lprm_command, struct printjob *pjob); + int (*job_pause)(int snum, struct printjob *pjob); + int (*job_resume)(int snum, struct printjob *pjob); + int (*job_submit)(int snum, struct printjob *pjob, + enum printing_types printing_type, + char *lpq_command); }; extern struct printif generic_printif; @@ -258,8 +258,8 @@ void close_all_print_db(void); TDB_DATA get_printer_notify_pid_list(struct tdb_context *tdb, const char *printer_name, bool cleanlist); void print_queue_receive(struct messaging_context *msg, - void *private_data, - uint32_t msg_type, - struct server_id server_id, - DATA_BLOB *data); + void *private_data, + uint32_t msg_type, + struct server_id server_id, + DATA_BLOB *data); #endif /* PRINTING_H_ */ diff --git a/source4/kdc/pac-glue.c b/source4/kdc/pac-glue.c index 126001cb718..04fbc5cf487 100644 --- a/source4/kdc/pac-glue.c +++ b/source4/kdc/pac-glue.c @@ -833,14 +833,14 @@ NTSTATUS samba_kdc_update_delegation_info_blob(TALLOC_CTX *mem_ctx, } smb_krb5_free_data_contents(context, &old_data); - ret = krb5_unparse_name(context, server_principal, &server); + ret = krb5_unparse_name_flags(context, server_principal, + KRB5_PRINCIPAL_UNPARSE_NO_REALM, &server); if (ret) { talloc_free(tmp_ctx); return NT_STATUS_INTERNAL_ERROR; } - ret = krb5_unparse_name_flags(context, proxy_principal, - KRB5_PRINCIPAL_UNPARSE_NO_REALM, &proxy); + ret = krb5_unparse_name(context, proxy_principal, &proxy); if (ret) { SAFE_FREE(server); talloc_free(tmp_ctx); diff --git a/source4/torture/rpc/remote_pac.c b/source4/torture/rpc/remote_pac.c index 7a5cda74b74..d0075d77745 100644 --- a/source4/torture/rpc/remote_pac.c +++ b/source4/torture/rpc/remote_pac.c @@ -35,12 +35,16 @@ #include "librpc/gen_ndr/ndr_krb5pac.h" #include "librpc/gen_ndr/ndr_samr_c.h" #include "param/param.h" +#include <ldb.h> +#include "ldb_wrap.h" +#include "dsdb/samdb/samdb.h" #define TEST_MACHINE_NAME_BDC "torturepacbdc" #define TEST_MACHINE_NAME_WKSTA "torturepacwksta" #define TEST_MACHINE_NAME_WKSTA_DES "torturepacwkdes" #define TEST_MACHINE_NAME_S4U2SELF_BDC "tests4u2selfbdc" #define TEST_MACHINE_NAME_S4U2SELF_WKSTA "tests4u2selfwk" +#define TEST_MACHINE_NAME_S4U2PROXY_WKSTA "tests4u2proxywk" struct pac_data { DATA_BLOB pac_blob; @@ -141,38 +145,34 @@ static const struct PAC_BUFFER *get_pac_buffer(const struct PAC_DATA *pac_data, /* Also happens to be a really good one-step verfication of our Kerberos stack */ +static bool netlogon_validate_pac(struct torture_context *tctx, + struct dcerpc_pipe *p1, + struct cli_credentials *server_creds, + enum netr_SchannelType secure_channel_type, + const char *test_machine_name, + uint32_t negotiate_flags, + struct pac_data *pac_data, + struct auth_session_info *session_info); + static bool test_PACVerify(struct torture_context *tctx, - struct dcerpc_pipe *p1, + struct dcerpc_pipe *p, struct cli_credentials *credentials, enum netr_SchannelType secure_channel_type, const char *test_machine_name, uint32_t negotiate_flags) { NTSTATUS status; + bool ok; bool pkinit_in_use = torture_setting_bool(tctx, "pkinit_in_use", false); bool expect_pac_upn_dns_info = torture_setting_bool(tctx, "expect_pac_upn_dns_info", true); size_t num_pac_buffers; - - struct netr_LogonSamLogon r; - - union netr_LogonLevel logon; - union netr_Validation validation; - uint8_t authoritative; - struct netr_Authenticator return_authenticator; - - struct netr_GenericInfo generic; - struct netr_Authenticator auth, auth2; - - struct netlogon_creds_CredentialState *creds; struct gensec_security *gensec_client_context; struct gensec_security *gensec_server_context; struct cli_credentials *client_creds; struct cli_credentials *server_creds; - DATA_BLOB client_to_server, server_to_client, pac_wrapped, payload; - struct PAC_Validate pac_wrapped_struct; + DATA_BLOB client_to_server, server_to_client; struct PAC_DATA pac_data_struct; - enum ndr_err_code ndr_err; struct auth4_context *auth_context; @@ -180,8 +180,6 @@ static bool test_PACVerify(struct torture_context *tctx, struct pac_data *pac_data; const struct PAC_BUFFER *pac_buf = NULL; - struct dcerpc_pipe *p = NULL; - struct dcerpc_binding_handle *b = NULL; TALLOC_CTX *tmp_ctx = talloc_new(tctx); torture_assert(tctx, tmp_ctx != NULL, "talloc_new() failed"); @@ -207,17 +205,6 @@ static bool test_PACVerify(struct torture_context *tctx, credentials); torture_assert(tctx, server_creds, "Failed to copy of credentials"); - if (!test_SetupCredentials2(p1, tctx, negotiate_flags, - server_creds, secure_channel_type, - &creds)) { - return false; - } - if (!test_SetupCredentialsPipe(p1, tctx, server_creds, creds, - DCERPC_SIGN | DCERPC_SEAL, &p)) { - return false; - } - b = p->binding_handle; - auth_context = talloc_zero(tmp_ctx, struct auth4_context); torture_assert(tctx, auth_context != NULL, "talloc_new() failed"); @@ -331,11 +318,53 @@ static bool test_PACVerify(struct torture_context *tctx, pac_buf->info != NULL, "PAC_TYPE_KDC_CHECKSUM info"); + ok = netlogon_validate_pac(tctx, p, server_creds, secure_channel_type, test_machine_name, + negotiate_flags, pac_data, session_info); + + talloc_free(tmp_ctx); + + return ok; +} + +static bool netlogon_validate_pac(struct torture_context *tctx, + struct dcerpc_pipe *p1, + struct cli_credentials *server_creds, + enum netr_SchannelType secure_channel_type, + const char *test_machine_name, + uint32_t negotiate_flags, + struct pac_data *pac_data, + struct auth_session_info *session_info) +{ + struct PAC_Validate pac_wrapped_struct; + struct netlogon_creds_CredentialState *creds = NULL; + struct netr_Authenticator return_authenticator; + struct netr_Authenticator auth, auth2; + struct netr_GenericInfo generic; + struct netr_LogonSamLogon r; + union netr_Validation validation; + union netr_LogonLevel logon; + uint8_t authoritative; + struct dcerpc_pipe *p = NULL; + struct dcerpc_binding_handle *b = NULL; + enum ndr_err_code ndr_err; + DATA_BLOB payload, pac_wrapped; + + if (!test_SetupCredentials2(p1, tctx, negotiate_flags, + server_creds, secure_channel_type, + &creds)) { + return false; + } + if (!test_SetupCredentialsPipe(p1, tctx, server_creds, creds, + DCERPC_SIGN | DCERPC_SEAL, &p)) { + return false; + } + b = p->binding_handle; + pac_wrapped_struct.ChecksumLength = pac_data->pac_srv_sig->signature.length; pac_wrapped_struct.SignatureType = pac_data->pac_kdc_sig->type; pac_wrapped_struct.SignatureLength = pac_data->pac_kdc_sig->signature.length; pac_wrapped_struct.ChecksumAndSignature = payload - = data_blob_talloc(tmp_ctx, NULL, + = data_blob_talloc(tctx, NULL, pac_wrapped_struct.ChecksumLength + pac_wrapped_struct.SignatureLength); memcpy(&payload.data[0], @@ -345,7 +374,7 @@ static bool test_PACVerify(struct torture_context *tctx, pac_data->pac_kdc_sig->signature.data, pac_wrapped_struct.SignatureLength); - ndr_err = ndr_push_struct_blob(&pac_wrapped, tmp_ctx, &pac_wrapped_struct, + ndr_err = ndr_push_struct_blob(&pac_wrapped, tctx, &pac_wrapped_struct, (ndr_push_flags_fn_t)ndr_push_PAC_Validate); torture_assert(tctx, NDR_ERR_CODE_IS_SUCCESS(ndr_err), "ndr_push_struct_blob of PACValidate structure failed"); @@ -444,7 +473,7 @@ static bool test_PACVerify(struct torture_context *tctx, pac_wrapped_struct.SignatureLength = pac_data->pac_kdc_sig->signature.length; pac_wrapped_struct.ChecksumAndSignature = payload - = data_blob_talloc(tmp_ctx, NULL, + = data_blob_talloc(tctx, NULL, pac_wrapped_struct.ChecksumLength + pac_wrapped_struct.SignatureLength); memcpy(&payload.data[0], @@ -454,7 +483,7 @@ static bool test_PACVerify(struct torture_context *tctx, pac_data->pac_kdc_sig->signature.data, pac_wrapped_struct.SignatureLength); - ndr_err = ndr_push_struct_blob(&pac_wrapped, tmp_ctx, &pac_wrapped_struct, + ndr_err = ndr_push_struct_blob(&pac_wrapped, tctx, &pac_wrapped_struct, (ndr_push_flags_fn_t)ndr_push_PAC_Validate); torture_assert(tctx, NDR_ERR_CODE_IS_SUCCESS(ndr_err), "ndr_push_struct_blob of PACValidate structure failed"); @@ -493,7 +522,7 @@ static bool test_PACVerify(struct torture_context *tctx, pac_wrapped_struct.SignatureLength = pac_data->pac_kdc_sig->signature.length; pac_wrapped_struct.ChecksumAndSignature = payload - = data_blob_talloc(tmp_ctx, NULL, + = data_blob_talloc(tctx, NULL, pac_wrapped_struct.ChecksumLength + pac_wrapped_struct.SignatureLength); memcpy(&payload.data[0], @@ -506,7 +535,7 @@ static bool test_PACVerify(struct torture_context *tctx, /* Break the signature length */ pac_wrapped_struct.SignatureLength++; - ndr_err = ndr_push_struct_blob(&pac_wrapped, tmp_ctx, &pac_wrapped_struct, + ndr_err = ndr_push_struct_blob(&pac_wrapped, tctx, &pac_wrapped_struct, (ndr_push_flags_fn_t)ndr_push_PAC_Validate); torture_assert(tctx, NDR_ERR_CODE_IS_SUCCESS(ndr_err), "ndr_push_struct_blob of PACValidate structure failed"); @@ -540,8 +569,6 @@ static bool test_PACVerify(struct torture_context *tctx, torture_assert(tctx, netlogon_creds_client_check(creds, &r.out.return_authenticator->cred), "Credential chaining failed"); - talloc_free(tmp_ctx); - return true; } @@ -977,6 +1004,227 @@ static bool test_S4U2Self_workstation_aes(struct torture_context *tctx, TEST_MACHINE_NAME_S4U2SELF_WKSTA, NETLOGON_NEG_AUTH2_ADS_FLAGS | NETLOGON_NEG_SUPPORTS_AES); } + +static bool test_S4U2Proxy(struct torture_context *tctx, + struct dcerpc_pipe *p, + struct cli_credentials *credentials, + enum netr_SchannelType secure_channel_type, + const char *test_machine_name, + uint32_t negotiate_flags) +{ + NTSTATUS status; + struct gensec_security *gensec_client_context = NULL; + struct gensec_security *gensec_server_context = NULL; + struct cli_credentials *server_creds = NULL; + size_t num_pac_buffers; + struct auth4_context *auth_context = NULL; + struct auth_session_info *session_info = NULL; + struct pac_data *pac_data = NULL; + const struct PAC_BUFFER *pac_buf = NULL; + char *impersonate_princ = NULL, *self_princ = NULL, *target_princ = NULL; + enum ndr_err_code ndr_err; + struct PAC_DATA pac_data_struct; + struct PAC_CONSTRAINED_DELEGATION *deleg = NULL; + + DATA_BLOB client_to_server, server_to_client; + + auth_context = talloc_zero(tctx, struct auth4_context); + torture_assert_not_null(tctx, auth_context, "talloc_new() failed"); + + auth_context->generate_session_info_pac = test_generate_session_info_pac; + + torture_comment(tctx, + "Testing S4U2Proxy (secure_channel_type: %d, machine: %s, negotiate_flags: 0x%08x\n", + secure_channel_type, test_machine_name, negotiate_flags); + + impersonate_princ = cli_credentials_get_principal(popt_get_cmdline_credentials(), tctx); + torture_assert_not_null(tctx, impersonate_princ, "Failed to get impersonate client name"); + + server_creds = cli_credentials_shallow_copy(tctx, credentials); + torture_assert_not_null(tctx, server_creds, "Failed to copy of credentials"); + + self_princ = talloc_asprintf(tctx, "host/%s", test_machine_name); + cli_credentials_invalidate_ccache(server_creds, CRED_SPECIFIED); + cli_credentials_set_impersonate_principal(server_creds, impersonate_princ, self_princ); + + /* Trigger S4U2Proxy by setting a target_service different than self_principal */ + target_princ = talloc_asprintf(tctx, "%s$", test_machine_name); + cli_credentials_set_target_service(server_creds, target_princ); + + 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"); + + status = gensec_set_target_principal(gensec_client_context, target_princ); + torture_assert_ntstatus_ok(tctx, status, "gensec_set_target_hostname (client) failed"); + + /* We now set the same credentials on both client and server contexts */ + status = gensec_set_credentials(gensec_client_context, server_creds); + torture_assert_ntstatus_ok(tctx, status, "gensec_set_credentials (client) failed"); + + status = gensec_start_mech_by_sasl_name(gensec_client_context, "GSSAPI"); + torture_assert_ntstatus_ok(tctx, status, "gensec_start_mech_by_sasl_name (client) failed"); + + status = gensec_server_start(tctx, + lpcfg_gensec_settings(tctx, tctx->lp_ctx), + auth_context, &gensec_server_context); + torture_assert_ntstatus_ok(tctx, status, "gensec_server_start (server) failed"); + + status = gensec_set_credentials(gensec_server_context, server_creds); + torture_assert_ntstatus_ok(tctx, status, "gensec_set_credentials (server) failed"); + + status = gensec_start_mech_by_sasl_name(gensec_server_context, "GSSAPI"); + torture_assert_ntstatus_ok(tctx, status, "gensec_start_mech_by_sasl_name (server) failed"); + + server_to_client = data_blob(NULL, 0); + + do { + /* Do a client-server update dance */ + status = gensec_update(gensec_client_context, tctx, server_to_client, &client_to_server); + if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {; + torture_assert_ntstatus_ok(tctx, status, "gensec_update (client) failed"); + } + + status = gensec_update(gensec_server_context, tctx, client_to_server, &server_to_client); + if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {; + torture_assert_ntstatus_ok(tctx, status, "gensec_update (server) failed"); + } + + if (NT_STATUS_IS_OK(status)) { + break; + } + } while (1); + + /* Extract the PAC using Samba's code */ + + status = gensec_session_info(gensec_server_context, gensec_server_context, &session_info); + torture_assert_ntstatus_ok(tctx, status, "gensec_session_info failed"); + + pac_data = talloc_get_type(auth_context->private_data, struct pac_data); + + torture_assert_not_null(tctx, pac_data, "gensec_update failed to fill in pac_data in auth_context"); + torture_assert_not_null(tctx, pac_data->pac_srv_sig, "pac_srv_sig not present"); + torture_assert_not_null(tctx, pac_data->pac_kdc_sig, "pac_kdc_sig not present"); + + ndr_err = ndr_pull_struct_blob(&pac_data->pac_blob, tctx, &pac_data_struct, + (ndr_pull_flags_fn_t)ndr_pull_PAC_DATA); + torture_assert(tctx, NDR_ERR_CODE_IS_SUCCESS(ndr_err), "ndr_pull_struct_blob of PAC_DATA structure failed"); + + num_pac_buffers = 6; + + torture_assert_int_equal(tctx, pac_data_struct.version, 0, "version"); + torture_assert_int_equal(tctx, pac_data_struct.num_buffers, num_pac_buffers, "num_buffers"); + + pac_buf = get_pac_buffer(&pac_data_struct, PAC_TYPE_LOGON_INFO); + torture_assert_not_null(tctx, pac_buf, "PAC_TYPE_LOGON_INFO"); + torture_assert_not_null(tctx, pac_buf->info, "PAC_TYPE_LOGON_INFO info"); + + pac_buf = get_pac_buffer(&pac_data_struct, PAC_TYPE_LOGON_NAME); + torture_assert_not_null(tctx, pac_buf, "PAC_TYPE_LOGON_NAME"); + torture_assert_not_null(tctx, pac_buf->info, "PAC_TYPE_LOGON_NAME info"); + + pac_buf = get_pac_buffer(&pac_data_struct, PAC_TYPE_UPN_DNS_INFO); + torture_assert_not_null(tctx, pac_buf, "PAC_TYPE_UPN_DNS_INFO"); + torture_assert_not_null(tctx, pac_buf->info, "PAC_TYPE_UPN_DNS_INFO info"); + + pac_buf = get_pac_buffer(&pac_data_struct, PAC_TYPE_SRV_CHECKSUM); + torture_assert_not_null(tctx, pac_buf, "PAC_TYPE_SRV_CHECKSUM"); + torture_assert_not_null(tctx, pac_buf->info, "PAC_TYPE_SRV_CHECKSUM info"); + + pac_buf = get_pac_buffer(&pac_data_struct, PAC_TYPE_KDC_CHECKSUM); + torture_assert_not_null(tctx, pac_buf, "PAC_TYPE_KDC_CHECKSUM"); + torture_assert_not_null(tctx, pac_buf->info, "PAC_TYPE_KDC_CHECKSUM info"); + + pac_buf = get_pac_buffer(&pac_data_struct, PAC_TYPE_CONSTRAINED_DELEGATION); + torture_assert_not_null(tctx, pac_buf, "PAC_TYPE_CONSTRAINED_DELEGATION"); + torture_assert_not_null(tctx, pac_buf->info, "PAC_TYPE_CONSTRAINED_DELEGATION info"); + + deleg = pac_buf->info->constrained_delegation.info; + torture_assert_str_equal(tctx, deleg->proxy_target.string, target_princ, "wrong proxy_target"); + torture_assert_int_equal(tctx, deleg->num_transited_services, 1, "wrong transited_services number"); + torture_assert_str_equal(tctx, deleg->transited_services[0].string, + talloc_asprintf(tctx, "%s@%s", self_princ, cli_credentials_get_realm(credentials)), + "wrong transited_services[0]"); + + return netlogon_validate_pac(tctx, p, server_creds, secure_channel_type, test_machine_name, + negotiate_flags, pac_data, session_info); +} + +static bool setup_constrained_delegation(struct torture_context *tctx, + struct dcerpc_pipe *p, + struct test_join *join_ctx, + const char *machine_name) +{ + struct samr_SetUserInfo r; + union samr_UserInfo user_info; + struct dcerpc_pipe *samr_pipe = torture_join_samr_pipe(join_ctx); + const char *server_dn_str = NULL; + struct ldb_context *sam_ctx = NULL; + struct ldb_dn *server_dn = NULL; + struct ldb_message *msg = NULL; + char *url = NULL; + int ret; + + url = talloc_asprintf(tctx, "ldap://%s", dcerpc_server_name(p)); + sam_ctx = ldb_wrap_connect(tctx, tctx->ev, tctx->lp_ctx, url, NULL, popt_get_cmdline_credentials(), 0); + torture_assert_not_null(tctx, sam_ctx, "Connection to the SAMDB on DC failed!"); + + server_dn_str = samdb_search_string(sam_ctx, tctx, ldb_get_default_basedn(sam_ctx), "distinguishedName", + "samaccountname=%s$", machine_name); + torture_assert_not_null(tctx, server_dn_str, "samdb_search_string()"); + + server_dn = ldb_dn_new(tctx, sam_ctx, server_dn_str); + torture_assert_not_null(tctx, server_dn, "ldb_dn_new()"); + + msg = ldb_msg_new(tctx); + torture_assert_not_null(tctx, msg, "ldb_msg_new()"); + + msg->dn = server_dn; + ret = ldb_msg_add_string(msg, "msDS-AllowedToDelegateTo", talloc_asprintf(tctx, "%s$", machine_name)); + torture_assert_int_equal(tctx, ret, 0, "ldb_msg_add_string())"); + + ret = ldb_modify(sam_ctx, msg); + torture_assert_int_equal(tctx, ret, 0, "ldb_modify()"); + + /* Allow forwardable flag in S4U2Self */ + user_info.info16.acct_flags = ACB_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION | ACB_WSTRUST; + r.in.user_handle = torture_join_samr_user_policy(join_ctx); + r.in.level = 16; + r.in.info = &user_info; + + torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetUserInfo_r(samr_pipe->binding_handle, tctx, &r), + "failed to set ACB_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION info account flags"); + torture_assert_ntstatus_ok(tctx, r.out.result, + "failed to set ACB_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION into account flags"); + -- Samba Shared Repository