LCOV - code coverage report
Current view: top level - source4/torture/rpc - remote_pac.c (source / functions) Hit Total Coverage
Test: coverage report for master 98b443d9 Lines: 618 717 86.2 %
Date: 2024-05-31 13:13:24 Functions: 19 19 100.0 %

          Line data    Source code
       1             : /*
       2             :    Unix SMB/CIFS implementation.
       3             : 
       4             :    test suite for netlogon PAC operations
       5             : 
       6             :    Copyright (C) Andrew Bartlett <abartlet@samba.org> 2012
       7             : 
       8             :    This program is free software; you can redistribute it and/or modify
       9             :    it under the terms of the GNU General Public License as published by
      10             :    the Free Software Foundation; either version 3 of the License, or
      11             :    (at your option) any later version.
      12             : 
      13             :    This program is distributed in the hope that it will be useful,
      14             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      15             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      16             :    GNU General Public License for more details.
      17             : 
      18             :    You should have received a copy of the GNU General Public License
      19             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      20             : */
      21             : 
      22             : #include "includes.h"
      23             : #include "auth/auth.h"
      24             : #include "auth/auth_sam_reply.h"
      25             : #include "auth/gensec/gensec.h"
      26             : #include "system/kerberos.h"
      27             : #include "auth/kerberos/kerberos.h"
      28             : #include "auth/credentials/credentials.h"
      29             : #include "auth/credentials/credentials_krb5.h"
      30             : #include "lib/cmdline/cmdline.h"
      31             : #include "torture/rpc/torture_rpc.h"
      32             : #include "libcli/auth/libcli_auth.h"
      33             : #include "libcli/security/security.h"
      34             : #include "librpc/gen_ndr/ndr_netlogon_c.h"
      35             : #include "librpc/gen_ndr/ndr_krb5pac.h"
      36             : #include "librpc/gen_ndr/ndr_samr_c.h"
      37             : #include "param/param.h"
      38             : #include <ldb.h>
      39             : #include "ldb_wrap.h"
      40             : #include "dsdb/samdb/samdb.h"
      41             : 
      42             : #define TEST_MACHINE_NAME_BDC "torturepacbdc"
      43             : #define TEST_MACHINE_NAME_WKSTA "torturepacwksta"
      44             : #define TEST_MACHINE_NAME_S4U2SELF_BDC "tests4u2selfbdc"
      45             : #define TEST_MACHINE_NAME_S4U2SELF_WKSTA "tests4u2selfwk"
      46             : #define TEST_MACHINE_NAME_S4U2PROXY_WKSTA "tests4u2proxywk"
      47             : 
      48             : struct pac_data {
      49             :         DATA_BLOB pac_blob;
      50             :         struct PAC_SIGNATURE_DATA *pac_srv_sig;
      51             :         struct PAC_SIGNATURE_DATA *pac_kdc_sig;
      52             : };
      53             : 
      54             : /* A helper function which avoids touching the local databases to
      55             :  * generate the session info, as we just want to verify the PAC
      56             :  * details, not the full local token */
      57          90 : static NTSTATUS test_generate_session_info_pac(struct auth4_context *auth_ctx,
      58             :                                                TALLOC_CTX *mem_ctx,
      59             :                                                struct smb_krb5_context *smb_krb5_context,
      60             :                                                DATA_BLOB *pac_blob,
      61             :                                                const char *principal_name,
      62             :                                                const struct tsocket_address *remote_address,
      63             :                                                uint32_t session_info_flags,
      64             :                                                struct auth_session_info **session_info)
      65             : {
      66           0 :         NTSTATUS nt_status;
      67           0 :         struct auth_user_info_dc *user_info_dc;
      68           0 :         TALLOC_CTX *tmp_ctx;
      69           0 :         struct pac_data *pac_data;
      70             : 
      71          90 :         if (pac_blob == NULL) {
      72           0 :                 DBG_ERR("pac_blob missing\n");
      73           0 :                 return NT_STATUS_NO_IMPERSONATION_TOKEN;
      74             :         }
      75             : 
      76          90 :         tmp_ctx = talloc_named(mem_ctx, 0, "gensec_gssapi_session_info context");
      77          90 :         NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
      78             : 
      79          90 :         auth_ctx->private_data = pac_data = talloc_zero(auth_ctx, struct pac_data);
      80             : 
      81          90 :         pac_data->pac_blob = data_blob_dup_talloc(pac_data, *pac_blob);
      82          90 :         if (pac_data->pac_blob.length != pac_blob->length) {
      83           0 :                 talloc_free(tmp_ctx);
      84           0 :                 return NT_STATUS_NO_MEMORY;
      85             :         }
      86             : 
      87          90 :         pac_data->pac_srv_sig = talloc(tmp_ctx, struct PAC_SIGNATURE_DATA);
      88          90 :         if (!pac_data->pac_srv_sig) {
      89           0 :                 talloc_free(tmp_ctx);
      90           0 :                 return NT_STATUS_NO_MEMORY;
      91             :         }
      92          90 :         pac_data->pac_kdc_sig = talloc(tmp_ctx, struct PAC_SIGNATURE_DATA);
      93          90 :         if (!pac_data->pac_kdc_sig) {
      94           0 :                 talloc_free(tmp_ctx);
      95           0 :                 return NT_STATUS_NO_MEMORY;
      96             :         }
      97             : 
      98          90 :         nt_status = kerberos_pac_blob_to_user_info_dc(tmp_ctx,
      99             :                                                       *pac_blob,
     100             :                                                       smb_krb5_context->krb5_context,
     101             :                                                       &user_info_dc,
     102             :                                                       pac_data->pac_srv_sig,
     103             :                                                       pac_data->pac_kdc_sig);
     104          90 :         if (!NT_STATUS_IS_OK(nt_status)) {
     105           0 :                 talloc_free(tmp_ctx);
     106           0 :                 return nt_status;
     107             :         }
     108             : 
     109          90 :         talloc_steal(pac_data, pac_data->pac_srv_sig);
     110          90 :         talloc_steal(pac_data, pac_data->pac_kdc_sig);
     111             : 
     112          90 :         if (!(user_info_dc->info->user_flags & NETLOGON_GUEST)) {
     113          90 :                 session_info_flags |= AUTH_SESSION_INFO_AUTHENTICATED;
     114             :         }
     115             : 
     116          90 :         session_info_flags |= AUTH_SESSION_INFO_SIMPLE_PRIVILEGES;
     117          90 :         nt_status = auth_generate_session_info(mem_ctx,
     118             :                                                NULL,
     119             :                                                NULL,
     120             :                                                user_info_dc, session_info_flags,
     121             :                                                session_info);
     122          90 :         if (!NT_STATUS_IS_OK(nt_status)) {
     123           0 :                 talloc_free(tmp_ctx);
     124           0 :                 return nt_status;
     125             :         }
     126             : 
     127          90 :         talloc_free(tmp_ctx);
     128          90 :         return nt_status;
     129             : }
     130             : 
     131             : /* Check to see if we can pass the PAC across to the NETLOGON server for validation */
     132             : 
     133         378 : static const struct PAC_BUFFER *get_pac_buffer(const struct PAC_DATA *pac_data,
     134             :                                                enum PAC_TYPE type)
     135             : {
     136         378 :         const struct PAC_BUFFER *pac_buf = NULL;
     137             :         uint32_t i;
     138             : 
     139        1882 :         for (i = 0; i < pac_data->num_buffers; ++i) {
     140        1882 :                 pac_buf = &pac_data->buffers[i];
     141             : 
     142        1882 :                 if (pac_buf->type == type) {
     143         378 :                         break;
     144             :                 }
     145             :         }
     146             : 
     147         378 :         return pac_buf;
     148             : }
     149             : 
     150             : /* Also happens to be a really good one-step verification of our Kerberos stack */
     151             : 
     152             : static bool netlogon_validate_pac(struct torture_context *tctx,
     153             :                                   struct dcerpc_pipe *p1,
     154             :                                   struct cli_credentials *server_creds,
     155             :                                   enum netr_SchannelType secure_channel_type,
     156             :                                   const char *test_machine_name,
     157             :                                   uint32_t negotiate_flags,
     158             :                                   struct pac_data *pac_data,
     159             :                                   struct auth_session_info *session_info);
     160             : 
     161          40 : static bool test_PACVerify(struct torture_context *tctx,
     162             :                            struct dcerpc_pipe *p,
     163             :                            struct cli_credentials *credentials,
     164             :                            enum netr_SchannelType secure_channel_type,
     165             :                            const char *test_machine_name,
     166             :                            uint32_t negotiate_flags)
     167             : {
     168           0 :         NTSTATUS status;
     169           0 :         bool ok;
     170          40 :         const char *pkinit_ccache = torture_setting_string(tctx, "pkinit_ccache", NULL);
     171          40 :         bool pkinit_in_use = pkinit_ccache != NULL;
     172          40 :         bool expect_pac_upn_dns_info = torture_setting_bool(tctx, "expect_pac_upn_dns_info", true);
     173           0 :         size_t num_pac_buffers;
     174           0 :         struct gensec_security *gensec_client_context;
     175           0 :         struct gensec_security *gensec_server_context;
     176           0 :         struct cli_credentials *client_creds;
     177           0 :         struct cli_credentials *server_creds;
     178             : 
     179           0 :         DATA_BLOB client_to_server, server_to_client;
     180           0 :         struct PAC_DATA pac_data_struct;
     181           0 :         enum ndr_err_code ndr_err;
     182             : 
     183           0 :         struct auth4_context *auth_context;
     184           0 :         struct auth_session_info *session_info;
     185           0 :         struct pac_data *pac_data;
     186          40 :         const struct PAC_BUFFER *pac_buf = NULL;
     187             : 
     188          40 :         TALLOC_CTX *tmp_ctx = talloc_new(tctx);
     189          40 :         torture_assert(tctx, tmp_ctx != NULL, "talloc_new() failed");
     190             : 
     191          40 :         torture_comment(tctx,
     192             :                 "Testing PAC Verify (secure_channel_type: %d, machine: %s, negotiate_flags: 0x%08x\n",
     193             :                 secure_channel_type, test_machine_name, negotiate_flags);
     194             : 
     195          40 :         if (pkinit_in_use) {
     196           8 :                 struct cli_credentials *tmp_creds = NULL;
     197           8 :                 const char *error_string = NULL;
     198           0 :                 int rc;
     199             : 
     200           8 :                 torture_comment(tctx,
     201             :                                 "Using pkinit_ccache=%s\n",
     202             :                                 pkinit_ccache);
     203             : 
     204           8 :                 tmp_creds = cli_credentials_init(tctx);
     205           8 :                 torture_assert(tctx, tmp_creds, "Failed to create credentials");
     206             : 
     207           8 :                 rc = cli_credentials_set_ccache(tmp_creds,
     208             :                                                 tctx->lp_ctx,
     209             :                                                 pkinit_ccache,
     210             :                                                 CRED_SPECIFIED,
     211             :                                                 &error_string);
     212           8 :                 torture_assert_int_equal(tctx,
     213             :                                          rc,
     214             :                                          0,
     215             :                                          "cli_credentials_set_ccache failed");
     216           8 :                 cli_credentials_set_kerberos_state(tmp_creds,
     217             :                                                    CRED_USE_KERBEROS_REQUIRED,
     218             :                                                    CRED_SPECIFIED);
     219             : 
     220             :                 /*
     221             :                  * Copy the credentials in order to use a different MEMORY krb5
     222             :                  * ccache for each client/server setup. The MEMORY cache
     223             :                  * identifier is a pointer to the creds container. If we copy
     224             :                  * it the pointer changes and we will get a new clean memory
     225             :                  * cache.
     226             :                  */
     227           0 :                 client_creds =
     228           8 :                         cli_credentials_shallow_copy(tmp_ctx, tmp_creds);
     229           8 :                 torture_assert(tctx,
     230             :                                client_creds,
     231             :                                "Failed to copy of credentials");
     232             :         } else {
     233             :                 /*
     234             :                  * Copy the credentials in order to use a different MEMORY krb5
     235             :                  * ccache for each client/server setup. The MEMORY cache
     236             :                  * identifier is a pointer to the creds container. If we copy
     237             :                  * it the pointer changes and we will get a new clean memory
     238             :                  * cache.
     239             :                  */
     240           0 :                 client_creds =
     241          32 :                         cli_credentials_shallow_copy(tmp_ctx,
     242             :                                                      samba_cmdline_get_creds());
     243          32 :                 torture_assert(tctx,
     244             :                                client_creds,
     245             :                                "Failed to copy of credentials");
     246          32 :                 cli_credentials_invalidate_ccache(client_creds, CRED_SPECIFIED);
     247             :         }
     248             : 
     249             : 
     250          40 :         server_creds = cli_credentials_shallow_copy(tmp_ctx,
     251             :                                                     credentials);
     252          40 :         torture_assert(tctx, server_creds, "Failed to copy of credentials");
     253             : 
     254          40 :         auth_context = talloc_zero(tmp_ctx, struct auth4_context);
     255          40 :         torture_assert(tctx, auth_context != NULL, "talloc_new() failed");
     256             : 
     257          40 :         auth_context->generate_session_info_pac = test_generate_session_info_pac;
     258             : 
     259          40 :         status = gensec_client_start(tctx, &gensec_client_context,
     260             :                                      lpcfg_gensec_settings(tctx, tctx->lp_ctx));
     261          40 :         torture_assert_ntstatus_ok(tctx, status, "gensec_client_start (client) failed");
     262             : 
     263          40 :         status = gensec_set_target_hostname(gensec_client_context, test_machine_name);
     264             : 
     265          40 :         status = gensec_set_credentials(gensec_client_context, client_creds);
     266          40 :         torture_assert_ntstatus_ok(tctx, status, "gensec_set_credentials (client) failed");
     267             : 
     268          40 :         status = gensec_start_mech_by_sasl_name(gensec_client_context, "GSSAPI");
     269          40 :         torture_assert_ntstatus_ok(tctx, status, "gensec_start_mech_by_sasl_name (client) failed");
     270             : 
     271          40 :         status = gensec_server_start(tctx,
     272             :                                      lpcfg_gensec_settings(tctx, tctx->lp_ctx),
     273             :                                      auth_context, &gensec_server_context);
     274          40 :         torture_assert_ntstatus_ok(tctx, status, "gensec_server_start (server) failed");
     275             : 
     276          40 :         status = gensec_set_credentials(gensec_server_context, server_creds);
     277          40 :         torture_assert_ntstatus_ok(tctx, status, "gensec_set_credentials (server) failed");
     278             : 
     279          40 :         status = gensec_start_mech_by_sasl_name(gensec_server_context, "GSSAPI");
     280          40 :         torture_assert_ntstatus_ok(tctx, status, "gensec_start_mech_by_sasl_name (server) failed");
     281             : 
     282          40 :         server_to_client = data_blob(NULL, 0);
     283             : 
     284           0 :         do {
     285             :                 /* Do a client-server update dance */
     286         120 :                 status = gensec_update(gensec_client_context, tmp_ctx, server_to_client, &client_to_server);
     287         120 :                 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {;
     288          40 :                         torture_assert_ntstatus_ok(tctx, status, "gensec_update (client) failed");
     289             :                 }
     290             : 
     291         120 :                 status = gensec_update(gensec_server_context, tmp_ctx, client_to_server, &server_to_client);
     292         120 :                 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {;
     293          40 :                         torture_assert_ntstatus_ok(tctx, status, "gensec_update (server) failed");
     294             :                 }
     295             : 
     296         120 :                 if (NT_STATUS_IS_OK(status)) {
     297          40 :                         break;
     298             :                 }
     299             :         } while (1);
     300             : 
     301             :         /* Extract the PAC using Samba's code */
     302             : 
     303          40 :         status = gensec_session_info(gensec_server_context, gensec_server_context, &session_info);
     304          40 :         torture_assert_ntstatus_ok(tctx, status, "gensec_session_info failed");
     305             : 
     306          40 :         pac_data = talloc_get_type(auth_context->private_data, struct pac_data);
     307             : 
     308          40 :         torture_assert(tctx, pac_data != NULL, "gensec_update failed to fill in pac_data in auth_context");
     309          40 :         torture_assert(tctx, pac_data->pac_srv_sig != NULL, "pac_srv_sig not present");
     310          40 :         torture_assert(tctx, pac_data->pac_kdc_sig != NULL, "pac_kdc_sig not present");
     311             : 
     312          40 :         ndr_err = ndr_pull_struct_blob(&pac_data->pac_blob, tmp_ctx, &pac_data_struct,
     313             :                                        (ndr_pull_flags_fn_t)ndr_pull_PAC_DATA);
     314          40 :         torture_assert(tctx, NDR_ERR_CODE_IS_SUCCESS(ndr_err), "ndr_pull_struct_blob of PAC_DATA structure failed");
     315             : 
     316          40 :         num_pac_buffers = 7;
     317          40 :         if (expect_pac_upn_dns_info) {
     318          40 :                 num_pac_buffers += 1;
     319             :         }
     320          40 :         if (pkinit_in_use) {
     321           8 :                 num_pac_buffers += 1;
     322             :         }
     323             : 
     324          40 :         torture_assert_int_equal(tctx, pac_data_struct.version, 0, "version");
     325          40 :         torture_assert_int_equal(tctx, pac_data_struct.num_buffers, num_pac_buffers, "num_buffers");
     326             : 
     327          40 :         pac_buf = get_pac_buffer(&pac_data_struct, PAC_TYPE_LOGON_INFO);
     328          40 :         torture_assert_not_null(tctx, pac_buf, "PAC_TYPE_LOGON_INFO");
     329          40 :         torture_assert(tctx,
     330             :                        pac_buf->info != NULL,
     331             :                        "PAC_TYPE_LOGON_INFO info");
     332             : 
     333          40 :         if (pkinit_in_use) {
     334           8 :                 pac_buf = get_pac_buffer(&pac_data_struct, PAC_TYPE_CREDENTIAL_INFO);
     335           8 :                 torture_assert_not_null(tctx, pac_buf, "PAC_TYPE_CREDENTIAL_INFO");
     336           8 :                 torture_assert(tctx,
     337             :                                pac_buf->info != NULL,
     338             :                                "PAC_TYPE_CREDENTIAL_INFO info");
     339             :         }
     340             : 
     341          40 :         pac_buf = get_pac_buffer(&pac_data_struct, PAC_TYPE_LOGON_NAME);
     342          40 :         torture_assert_not_null(tctx, pac_buf, "PAC_TYPE_LOGON_NAME");
     343          40 :         torture_assert(tctx,
     344             :                        pac_buf->info != NULL,
     345             :                        "PAC_TYPE_LOGON_NAME info");
     346             : 
     347          40 :         if (expect_pac_upn_dns_info) {
     348          40 :                 pac_buf = get_pac_buffer(&pac_data_struct, PAC_TYPE_UPN_DNS_INFO);
     349          40 :                 torture_assert_not_null(tctx, pac_buf, "PAC_TYPE_UPN_DNS_INFO");
     350          40 :                 torture_assert(tctx,
     351             :                                pac_buf->info != NULL,
     352             :                                "PAC_TYPE_UPN_DNS_INFO info");
     353             :         }
     354             : 
     355          40 :         pac_buf = get_pac_buffer(&pac_data_struct, PAC_TYPE_SRV_CHECKSUM);
     356          40 :         torture_assert_not_null(tctx, pac_buf, "PAC_TYPE_SRV_CHECKSUM");
     357          40 :         torture_assert(tctx,
     358             :                        pac_buf->info != NULL,
     359             :                        "PAC_TYPE_SRV_CHECKSUM info");
     360             : 
     361          40 :         pac_buf = get_pac_buffer(&pac_data_struct, PAC_TYPE_KDC_CHECKSUM);
     362          40 :         torture_assert_not_null(tctx, pac_buf, "PAC_TYPE_KDC_CHECKSUM");
     363          40 :         torture_assert(tctx,
     364             :                        pac_buf->info != NULL,
     365             :                        "PAC_TYPE_KDC_CHECKSUM info");
     366             : 
     367          40 :         pac_buf = get_pac_buffer(&pac_data_struct, PAC_TYPE_TICKET_CHECKSUM);
     368          40 :         torture_assert_not_null(tctx, pac_buf, "PAC_TYPE_TICKET_CHECKSUM");
     369          40 :         torture_assert(tctx,
     370             :                        pac_buf->info != NULL,
     371             :                        "PAC_TYPE_TICKET_CHECKSUM info");
     372             : 
     373          40 :         pac_buf = get_pac_buffer(&pac_data_struct, PAC_TYPE_FULL_CHECKSUM);
     374          40 :         torture_assert_not_null(tctx, pac_buf, "PAC_TYPE_FULL_CHECKSUM");
     375          40 :         torture_assert(tctx,
     376             :                        pac_buf->info != NULL,
     377             :                        "PAC_TYPE_FULL_CHECKSUM info");
     378             : 
     379          40 :         ok = netlogon_validate_pac(tctx, p, server_creds, secure_channel_type, test_machine_name,
     380             :                                    negotiate_flags, pac_data, session_info);
     381             : 
     382          40 :         talloc_free(tmp_ctx);
     383             : 
     384          40 :         return ok;
     385             : }
     386             : 
     387          50 : static bool netlogon_validate_pac(struct torture_context *tctx,
     388             :                                   struct dcerpc_pipe *p1,
     389             :                                   struct cli_credentials *server_creds,
     390             :                                   enum netr_SchannelType secure_channel_type,
     391             :                                   const char *test_machine_name,
     392             :                                   uint32_t negotiate_flags,
     393             :                                   struct pac_data *pac_data,
     394             :                                   struct auth_session_info *session_info)
     395             : {
     396           0 :         struct PAC_Validate pac_wrapped_struct;
     397          50 :         struct netlogon_creds_CredentialState *creds = NULL;
     398           0 :         struct netr_Authenticator return_authenticator;
     399           0 :         struct netr_Authenticator auth, auth2;
     400           0 :         struct netr_GenericInfo generic;
     401           0 :         struct netr_LogonSamLogon r;
     402           0 :         union netr_Validation validation;
     403           0 :         union netr_LogonLevel logon;
     404           0 :         uint8_t authoritative;
     405          50 :         struct dcerpc_pipe *p = NULL;
     406          50 :         struct dcerpc_binding_handle *b = NULL;
     407           0 :         enum ndr_err_code ndr_err;
     408           0 :         DATA_BLOB payload, pac_wrapped;
     409             : 
     410          50 :         if (!test_SetupCredentials2(p1, tctx, negotiate_flags,
     411             :                                     server_creds, secure_channel_type,
     412             :                                     &creds)) {
     413           0 :                 return false;
     414             :         }
     415          50 :         if (!test_SetupCredentialsPipe(p1, tctx, server_creds, creds,
     416             :                                        DCERPC_SIGN | DCERPC_SEAL, &p)) {
     417           0 :                 return false;
     418             :         }
     419          50 :         b = p->binding_handle;
     420             : 
     421          50 :         pac_wrapped_struct.ChecksumLength = pac_data->pac_srv_sig->signature.length;
     422          50 :         pac_wrapped_struct.SignatureType = pac_data->pac_kdc_sig->type;
     423          50 :         pac_wrapped_struct.SignatureLength = pac_data->pac_kdc_sig->signature.length;
     424          50 :         pac_wrapped_struct.ChecksumAndSignature = payload
     425          50 :                 = data_blob_talloc(tctx, NULL,
     426             :                                    pac_wrapped_struct.ChecksumLength
     427             :                                    + pac_wrapped_struct.SignatureLength);
     428          50 :         memcpy(&payload.data[0],
     429          50 :                pac_data->pac_srv_sig->signature.data,
     430          50 :                pac_wrapped_struct.ChecksumLength);
     431          50 :         memcpy(&payload.data[pac_wrapped_struct.ChecksumLength],
     432          50 :                pac_data->pac_kdc_sig->signature.data,
     433          50 :                pac_wrapped_struct.SignatureLength);
     434             : 
     435          50 :         ndr_err = ndr_push_struct_blob(&pac_wrapped, tctx, &pac_wrapped_struct,
     436             :                                        (ndr_push_flags_fn_t)ndr_push_PAC_Validate);
     437          50 :         torture_assert(tctx, NDR_ERR_CODE_IS_SUCCESS(ndr_err), "ndr_push_struct_blob of PACValidate structure failed");
     438             : 
     439          50 :         torture_assert(tctx, (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR), "not willing to even try a PACValidate without RC4 encryption");
     440          50 :         if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
     441          25 :                 netlogon_creds_aes_encrypt(creds, pac_wrapped.data, pac_wrapped.length);
     442             :         } else {
     443          25 :                 netlogon_creds_arcfour_crypt(creds, pac_wrapped.data, pac_wrapped.length);
     444             :         }
     445             : 
     446          50 :         generic.length = pac_wrapped.length;
     447          50 :         generic.data = pac_wrapped.data;
     448             : 
     449             :         /* Validate it over the netlogon pipe */
     450             : 
     451          50 :         generic.identity_info.parameter_control = 0;
     452          50 :         generic.identity_info.logon_id = 0;
     453          50 :         generic.identity_info.domain_name.string = session_info->info->domain_name;
     454          50 :         generic.identity_info.account_name.string = session_info->info->account_name;
     455          50 :         generic.identity_info.workstation.string = test_machine_name;
     456             : 
     457          50 :         generic.package_name.string = "Kerberos";
     458             : 
     459          50 :         logon.generic = &generic;
     460             : 
     461          50 :         ZERO_STRUCT(auth2);
     462          50 :         netlogon_creds_client_authenticator(creds, &auth);
     463          50 :         r.in.credential = &auth;
     464          50 :         r.in.return_authenticator = &auth2;
     465          50 :         r.in.logon = &logon;
     466          50 :         r.in.logon_level = NetlogonGenericInformation;
     467          50 :         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
     468          50 :         r.in.computer_name = cli_credentials_get_workstation(server_creds);
     469          50 :         r.in.validation_level = NetlogonValidationGenericInfo2;
     470          50 :         r.out.validation = &validation;
     471          50 :         r.out.authoritative = &authoritative;
     472          50 :         r.out.return_authenticator = &return_authenticator;
     473             : 
     474          50 :         torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogon_r(b, tctx, &r),
     475             :                 "LogonSamLogon failed");
     476             : 
     477          50 :         torture_assert_ntstatus_ok(tctx, r.out.result, "LogonSamLogon failed");
     478             : 
     479             :         /* This will break the signature nicely (even in the crypto wrapping), check we get a logon failure */
     480          50 :         generic.data[generic.length-1]++;
     481             : 
     482          50 :         logon.generic = &generic;
     483             : 
     484          50 :         ZERO_STRUCT(auth2);
     485          50 :         netlogon_creds_client_authenticator(creds, &auth);
     486          50 :         r.in.credential = &auth;
     487          50 :         r.in.return_authenticator = &auth2;
     488          50 :         r.in.logon_level = NetlogonGenericInformation;
     489          50 :         r.in.logon = &logon;
     490          50 :         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
     491          50 :         r.in.computer_name = cli_credentials_get_workstation(server_creds);
     492          50 :         r.in.validation_level = NetlogonValidationGenericInfo2;
     493             : 
     494          50 :         torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogon_r(b, tctx, &r),
     495             :                 "LogonSamLogon failed");
     496             : 
     497          50 :         torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_LOGON_FAILURE, "LogonSamLogon failed");
     498             : 
     499          50 :         torture_assert(tctx, netlogon_creds_client_check(creds, &r.out.return_authenticator->cred),
     500             :                        "Credential chaining failed");
     501             : 
     502             :         /* This will break the parsing nicely (even in the crypto wrapping), check we get INVALID_PARAMETER */
     503          50 :         generic.length--;
     504             : 
     505          50 :         logon.generic = &generic;
     506             : 
     507          50 :         ZERO_STRUCT(auth2);
     508          50 :         netlogon_creds_client_authenticator(creds, &auth);
     509          50 :         r.in.credential = &auth;
     510          50 :         r.in.return_authenticator = &auth2;
     511          50 :         r.in.logon_level = NetlogonGenericInformation;
     512          50 :         r.in.logon = &logon;
     513          50 :         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
     514          50 :         r.in.computer_name = cli_credentials_get_workstation(server_creds);
     515          50 :         r.in.validation_level = NetlogonValidationGenericInfo2;
     516             : 
     517          50 :         torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogon_r(b, tctx, &r),
     518             :                 "LogonSamLogon failed");
     519             : 
     520          50 :         torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_INVALID_PARAMETER, "LogonSamLogon failed");
     521             : 
     522          50 :         torture_assert(tctx, netlogon_creds_client_check(creds,
     523             :                                                          &r.out.return_authenticator->cred),
     524             :                        "Credential chaining failed");
     525             : 
     526          50 :         pac_wrapped_struct.ChecksumLength = pac_data->pac_srv_sig->signature.length;
     527          50 :         pac_wrapped_struct.SignatureType = pac_data->pac_kdc_sig->type;
     528             : 
     529             :         /* Break the SignatureType */
     530          50 :         pac_wrapped_struct.SignatureType++;
     531             : 
     532          50 :         pac_wrapped_struct.SignatureLength = pac_data->pac_kdc_sig->signature.length;
     533          50 :         pac_wrapped_struct.ChecksumAndSignature = payload
     534          50 :                 = data_blob_talloc(tctx, NULL,
     535             :                                    pac_wrapped_struct.ChecksumLength
     536             :                                    + pac_wrapped_struct.SignatureLength);
     537          50 :         memcpy(&payload.data[0],
     538          50 :                pac_data->pac_srv_sig->signature.data,
     539          50 :                pac_wrapped_struct.ChecksumLength);
     540          50 :         memcpy(&payload.data[pac_wrapped_struct.ChecksumLength],
     541          50 :                pac_data->pac_kdc_sig->signature.data,
     542          50 :                pac_wrapped_struct.SignatureLength);
     543             : 
     544          50 :         ndr_err = ndr_push_struct_blob(&pac_wrapped, tctx, &pac_wrapped_struct,
     545             :                                        (ndr_push_flags_fn_t)ndr_push_PAC_Validate);
     546          50 :         torture_assert(tctx, NDR_ERR_CODE_IS_SUCCESS(ndr_err), "ndr_push_struct_blob of PACValidate structure failed");
     547             : 
     548          50 :         torture_assert(tctx, (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR), "not willing to even try a PACValidate without RC4 encryption");
     549          50 :         if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
     550          25 :                 netlogon_creds_aes_encrypt(creds, pac_wrapped.data, pac_wrapped.length);
     551             :         } else {
     552          25 :                 netlogon_creds_arcfour_crypt(creds, pac_wrapped.data, pac_wrapped.length);
     553             :         }
     554             : 
     555          50 :         generic.length = pac_wrapped.length;
     556          50 :         generic.data = pac_wrapped.data;
     557             : 
     558          50 :         logon.generic = &generic;
     559             : 
     560          50 :         ZERO_STRUCT(auth2);
     561          50 :         netlogon_creds_client_authenticator(creds, &auth);
     562          50 :         r.in.credential = &auth;
     563          50 :         r.in.return_authenticator = &auth2;
     564          50 :         r.in.logon_level = NetlogonGenericInformation;
     565          50 :         r.in.logon = &logon;
     566          50 :         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
     567          50 :         r.in.computer_name = cli_credentials_get_workstation(server_creds);
     568          50 :         r.in.validation_level = NetlogonValidationGenericInfo2;
     569             : 
     570          50 :         torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogon_r(b, tctx, &r),
     571             :                 "LogonSamLogon failed");
     572             : 
     573          50 :         torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_LOGON_FAILURE, "LogonSamLogon failed");
     574             : 
     575          50 :         torture_assert(tctx, netlogon_creds_client_check(creds, &r.out.return_authenticator->cred),
     576             :                        "Credential chaining failed");
     577             : 
     578          50 :         pac_wrapped_struct.ChecksumLength = pac_data->pac_srv_sig->signature.length;
     579          50 :         pac_wrapped_struct.SignatureType = pac_data->pac_kdc_sig->type;
     580          50 :         pac_wrapped_struct.SignatureLength = pac_data->pac_kdc_sig->signature.length;
     581             : 
     582          50 :         pac_wrapped_struct.ChecksumAndSignature = payload
     583          50 :                 = data_blob_talloc(tctx, NULL,
     584             :                                    pac_wrapped_struct.ChecksumLength
     585             :                                    + pac_wrapped_struct.SignatureLength);
     586          50 :         memcpy(&payload.data[0],
     587          50 :                pac_data->pac_srv_sig->signature.data,
     588          50 :                pac_wrapped_struct.ChecksumLength);
     589          50 :         memcpy(&payload.data[pac_wrapped_struct.ChecksumLength],
     590          50 :                pac_data->pac_kdc_sig->signature.data,
     591          50 :                pac_wrapped_struct.SignatureLength);
     592             : 
     593             :         /* Break the signature length */
     594          50 :         pac_wrapped_struct.SignatureLength++;
     595             : 
     596          50 :         ndr_err = ndr_push_struct_blob(&pac_wrapped, tctx, &pac_wrapped_struct,
     597             :                                        (ndr_push_flags_fn_t)ndr_push_PAC_Validate);
     598          50 :         torture_assert(tctx, NDR_ERR_CODE_IS_SUCCESS(ndr_err), "ndr_push_struct_blob of PACValidate structure failed");
     599             : 
     600          50 :         torture_assert(tctx, (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR), "not willing to even try a PACValidate without RC4 encryption");
     601          50 :         if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
     602          25 :                 netlogon_creds_aes_encrypt(creds, pac_wrapped.data, pac_wrapped.length);
     603             :         } else {
     604          25 :                 netlogon_creds_arcfour_crypt(creds, pac_wrapped.data, pac_wrapped.length);
     605             :         }
     606             : 
     607          50 :         generic.length = pac_wrapped.length;
     608          50 :         generic.data = pac_wrapped.data;
     609             : 
     610          50 :         logon.generic = &generic;
     611             : 
     612          50 :         ZERO_STRUCT(auth2);
     613          50 :         netlogon_creds_client_authenticator(creds, &auth);
     614          50 :         r.in.credential = &auth;
     615          50 :         r.in.return_authenticator = &auth2;
     616          50 :         r.in.logon_level = NetlogonGenericInformation;
     617          50 :         r.in.logon = &logon;
     618          50 :         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
     619          50 :         r.in.computer_name = cli_credentials_get_workstation(server_creds);
     620          50 :         r.in.validation_level = NetlogonValidationGenericInfo2;
     621             : 
     622          50 :         torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogon_r(b, tctx, &r),
     623             :                 "LogonSamLogon failed");
     624             : 
     625          50 :         torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_INVALID_PARAMETER, "LogonSamLogon failed");
     626             : 
     627          50 :         torture_assert(tctx, netlogon_creds_client_check(creds, &r.out.return_authenticator->cred),
     628             :                        "Credential chaining failed");
     629             : 
     630          50 :         return true;
     631             : }
     632             : 
     633          10 : static bool test_PACVerify_bdc_arcfour(struct torture_context *tctx,
     634             :                                        struct dcerpc_pipe *p,
     635             :                                        struct cli_credentials *credentials)
     636             : {
     637          10 :         return test_PACVerify(tctx, p, credentials, SEC_CHAN_BDC,
     638             :                               TEST_MACHINE_NAME_BDC,
     639             :                               NETLOGON_NEG_AUTH2_ADS_FLAGS);
     640             : }
     641             : 
     642          10 : static bool test_PACVerify_bdc_aes(struct torture_context *tctx,
     643             :                                    struct dcerpc_pipe *p,
     644             :                                    struct cli_credentials *credentials)
     645             : {
     646          10 :         return test_PACVerify(tctx, p, credentials, SEC_CHAN_BDC,
     647             :                               TEST_MACHINE_NAME_BDC,
     648             :                               NETLOGON_NEG_AUTH2_ADS_FLAGS | NETLOGON_NEG_SUPPORTS_AES);
     649             : }
     650             : 
     651          10 : static bool test_PACVerify_workstation_arcfour(struct torture_context *tctx,
     652             :                                                struct dcerpc_pipe *p,
     653             :                                                struct cli_credentials *credentials)
     654             : {
     655          10 :         return test_PACVerify(tctx, p, credentials, SEC_CHAN_WKSTA,
     656             :                               TEST_MACHINE_NAME_WKSTA,
     657             :                               NETLOGON_NEG_AUTH2_ADS_FLAGS);
     658             : }
     659             : 
     660          10 : static bool test_PACVerify_workstation_aes(struct torture_context *tctx,
     661             :                                            struct dcerpc_pipe *p,
     662             :                                            struct cli_credentials *credentials)
     663             : {
     664          10 :         return test_PACVerify(tctx, p, credentials, SEC_CHAN_WKSTA,
     665             :                               TEST_MACHINE_NAME_WKSTA,
     666             :                               NETLOGON_NEG_AUTH2_ADS_FLAGS | NETLOGON_NEG_SUPPORTS_AES);
     667             : }
     668             : 
     669             : #ifdef SAMBA4_USES_HEIMDAL
     670          20 : static NTSTATUS check_primary_group_in_validation(TALLOC_CTX *mem_ctx,
     671             :                                                   uint16_t validation_level,
     672             :                                                   const union netr_Validation *validation)
     673             : {
     674          20 :         const struct netr_SamBaseInfo *base = NULL;
     675           0 :         int i;
     676          20 :         switch (validation_level) {
     677           0 :         case 2:
     678           0 :                 if (!validation || !validation->sam2) {
     679           0 :                         return NT_STATUS_INVALID_PARAMETER;
     680             :                 }
     681           0 :                 base = &validation->sam2->base;
     682           0 :                 break;
     683          20 :         case 3:
     684          20 :                 if (!validation || !validation->sam3) {
     685           0 :                         return NT_STATUS_INVALID_PARAMETER;
     686             :                 }
     687          20 :                 base = &validation->sam3->base;
     688          20 :                 break;
     689           0 :         case 6:
     690           0 :                 if (!validation || !validation->sam6) {
     691           0 :                         return NT_STATUS_INVALID_PARAMETER;
     692             :                 }
     693           0 :                 base = &validation->sam6->base;
     694           0 :                 break;
     695           0 :         default:
     696           0 :                 return NT_STATUS_INVALID_LEVEL;
     697             :         }
     698             : 
     699          20 :         for (i = 0; i < base->groups.count; i++) {
     700          20 :                 if (base->groups.rids[i].rid == base->primary_gid) {
     701          20 :                         return NT_STATUS_OK;
     702             :                 }
     703             :         }
     704           0 :         return NT_STATUS_INVALID_PARAMETER;
     705             : }
     706             : 
     707             : /* Check various ways to get the PAC, in particular check the group membership and
     708             :  * other details between the PAC from a normal kinit, S4U2Self and a SamLogon */
     709          20 : static bool test_S4U2Self(struct torture_context *tctx,
     710             :                           struct dcerpc_pipe *p1,
     711             :                           struct cli_credentials *credentials,
     712             :                           enum netr_SchannelType secure_channel_type,
     713             :                           const char *test_machine_name,
     714             :                           uint32_t negotiate_flags)
     715             : {
     716           0 :         NTSTATUS status;
     717          20 :         struct dcerpc_pipe *p = NULL;
     718          20 :         struct dcerpc_binding_handle *b = NULL;
     719             : 
     720           0 :         struct netr_LogonSamLogon r;
     721             : 
     722           0 :         union netr_LogonLevel logon;
     723           0 :         union netr_Validation validation;
     724           0 :         uint8_t authoritative;
     725             : 
     726           0 :         struct netr_Authenticator auth, auth2;
     727             : 
     728           0 :         DATA_BLOB client_to_server, server_to_client;
     729             : 
     730           0 :         struct netlogon_creds_CredentialState *creds;
     731           0 :         struct gensec_security *gensec_client_context;
     732           0 :         struct gensec_security *gensec_server_context;
     733           0 :         struct cli_credentials *client_creds;
     734           0 :         struct cli_credentials *server_creds;
     735             : 
     736           0 :         struct auth4_context *auth_context;
     737           0 :         struct auth_session_info *kinit_session_info;
     738           0 :         struct auth_session_info *s4u2self_session_info;
     739           0 :         struct auth_user_info_dc *netlogon_user_info_dc;
     740             : 
     741          20 :         struct netr_NetworkInfo ninfo = {};
     742           0 :         DATA_BLOB names_blob, chal, lm_resp, nt_resp;
     743           0 :         size_t i;
     744           0 :         size_t j;
     745           0 :         size_t k;
     746          20 :         int flags = CLI_CRED_NTLMv2_AUTH;
     747             : 
     748           0 :         struct dom_sid *builtin_domain;
     749             : 
     750          20 :         struct dom_sid *ai_auth_authority = NULL;
     751          20 :         struct dom_sid *ai_service = NULL;
     752          20 :         struct dom_sid *ai_claims_valid = NULL;
     753          20 :         size_t ai_auth_authority_count = 0;
     754          20 :         size_t ai_service_count = 0;
     755          20 :         size_t ai_claims_valid_count = 0;
     756          20 :         size_t kinit_asserted_identity_index = 0;
     757          20 :         size_t kinit_claims_valid_index = 0;
     758          20 :         size_t s4u2self_asserted_identity_index = 0;
     759          20 :         size_t s4u2self_claims_valid_index = 0;
     760           0 :         bool ok;
     761             : 
     762          20 :         TALLOC_CTX *tmp_ctx = talloc_new(tctx);
     763             : 
     764          20 :         torture_assert(tctx, tmp_ctx != NULL, "talloc_new() failed");
     765             : 
     766          20 :         torture_comment(tctx,
     767             :                 "Testing S4U2SELF (secure_channel_type: %d, machine: %s, negotiate_flags: 0x%08x\n",
     768             :                 secure_channel_type, test_machine_name, negotiate_flags);
     769             : 
     770             :         /*
     771             :          * Copy the credentials in order to use a different MEMORY krb5 ccache
     772             :          * for each client/server setup. The MEMORY cache identifier is a
     773             :          * pointer to the creds container. If we copy it the pointer changes and
     774             :          * we will get a new clean memory cache.
     775             :          */
     776          20 :         client_creds = cli_credentials_shallow_copy(tmp_ctx,
     777             :                                             samba_cmdline_get_creds());
     778          20 :         torture_assert(tctx, client_creds, "Failed to copy of credentials");
     779             :         /* We use cli_credentials_get_ntlm_response(), so relax krb5 requirements. */
     780          20 :         cli_credentials_set_kerberos_state(client_creds,
     781             :                                            CRED_USE_KERBEROS_DESIRED,
     782             :                                            CRED_SPECIFIED);
     783             : 
     784          20 :         server_creds = cli_credentials_shallow_copy(tmp_ctx,
     785             :                                                     credentials);
     786          20 :         torture_assert(tctx, server_creds, "Failed to copy of credentials");
     787             : 
     788          20 :         if (!test_SetupCredentials2(p1, tctx, negotiate_flags,
     789             :                                     server_creds, secure_channel_type,
     790             :                                     &creds)) {
     791           0 :                 return false;
     792             :         }
     793          20 :         if (!test_SetupCredentialsPipe(p1, tctx, server_creds, creds,
     794             :                                        DCERPC_SIGN | DCERPC_SEAL, &p)) {
     795           0 :                 return false;
     796             :         }
     797          20 :         b = p->binding_handle;
     798             : 
     799          20 :         auth_context = talloc_zero(tmp_ctx, struct auth4_context);
     800          20 :         torture_assert(tctx, auth_context != NULL, "talloc_new() failed");
     801             : 
     802          20 :         auth_context->generate_session_info_pac = test_generate_session_info_pac;
     803             : 
     804             :         /* First, do a normal Kerberos connection */
     805             : 
     806          20 :         status = gensec_client_start(tctx, &gensec_client_context,
     807             :                                      lpcfg_gensec_settings(tctx, tctx->lp_ctx));
     808          20 :         torture_assert_ntstatus_ok(tctx, status, "gensec_client_start (client) failed");
     809             : 
     810          20 :         status = gensec_set_target_hostname(gensec_client_context, test_machine_name);
     811             : 
     812          20 :         status = gensec_set_credentials(gensec_client_context, client_creds);
     813          20 :         torture_assert_ntstatus_ok(tctx, status, "gensec_set_credentials (client) failed");
     814             : 
     815          20 :         status = gensec_start_mech_by_sasl_name(gensec_client_context, "GSSAPI");
     816          20 :         torture_assert_ntstatus_ok(tctx, status, "gensec_start_mech_by_sasl_name (client) failed");
     817             : 
     818          20 :         status = gensec_server_start(tctx,
     819             :                                      lpcfg_gensec_settings(tctx, tctx->lp_ctx),
     820             :                                      auth_context, &gensec_server_context);
     821          20 :         torture_assert_ntstatus_ok(tctx, status, "gensec_server_start (server) failed");
     822             : 
     823          20 :         status = gensec_set_credentials(gensec_server_context, server_creds);
     824          20 :         torture_assert_ntstatus_ok(tctx, status, "gensec_set_credentials (server) failed");
     825             : 
     826          20 :         status = gensec_start_mech_by_sasl_name(gensec_server_context, "GSSAPI");
     827          20 :         torture_assert_ntstatus_ok(tctx, status, "gensec_start_mech_by_sasl_name (server) failed");
     828             : 
     829          20 :         server_to_client = data_blob(NULL, 0);
     830             : 
     831           0 :         do {
     832             :                 /* Do a client-server update dance */
     833          60 :                 status = gensec_update(gensec_client_context, tmp_ctx, server_to_client, &client_to_server);
     834          60 :                 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {;
     835          20 :                         torture_assert_ntstatus_ok(tctx, status, "gensec_update (client) failed");
     836             :                 }
     837             : 
     838          60 :                 status = gensec_update(gensec_server_context, tmp_ctx, client_to_server, &server_to_client);
     839          60 :                 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {;
     840          20 :                         torture_assert_ntstatus_ok(tctx, status, "gensec_update (server) failed");
     841             :                 }
     842             : 
     843          60 :                 if (NT_STATUS_IS_OK(status)) {
     844          20 :                         break;
     845             :                 }
     846             :         } while (1);
     847             : 
     848             :         /* Extract the PAC using Samba's code */
     849             : 
     850          20 :         status = gensec_session_info(gensec_server_context, gensec_server_context, &kinit_session_info);
     851          20 :         torture_assert_ntstatus_ok(tctx, status, "gensec_session_info failed");
     852             : 
     853             : 
     854             :         /* Now do the dance with S4U2Self */
     855             : 
     856             :         /* Wipe out any existing ccache */
     857          20 :         cli_credentials_invalidate_ccache(client_creds, CRED_SPECIFIED);
     858          20 :         cli_credentials_invalidate_ccache(server_creds, CRED_SPECIFIED);
     859          20 :         cli_credentials_set_impersonate_principal(server_creds,
     860          20 :                         cli_credentials_get_principal(client_creds, tmp_ctx),
     861          20 :                         talloc_asprintf(tmp_ctx, "host/%s", test_machine_name));
     862             : 
     863          20 :         status = gensec_client_start(tctx, &gensec_client_context,
     864             :                                      lpcfg_gensec_settings(tctx, tctx->lp_ctx));
     865          20 :         torture_assert_ntstatus_ok(tctx, status, "gensec_client_start (client) failed");
     866             : 
     867          20 :         status = gensec_set_target_hostname(gensec_client_context, test_machine_name);
     868             : 
     869             :         /* We now set the same credentials on both client and server contexts */
     870          20 :         status = gensec_set_credentials(gensec_client_context, server_creds);
     871          20 :         torture_assert_ntstatus_ok(tctx, status, "gensec_set_credentials (client) failed");
     872             : 
     873          20 :         status = gensec_start_mech_by_sasl_name(gensec_client_context, "GSSAPI");
     874          20 :         torture_assert_ntstatus_ok(tctx, status, "gensec_start_mech_by_sasl_name (client) failed");
     875             : 
     876          20 :         status = gensec_server_start(tctx,
     877             :                                      lpcfg_gensec_settings(tctx, tctx->lp_ctx),
     878             :                                      auth_context, &gensec_server_context);
     879          20 :         torture_assert_ntstatus_ok(tctx, status, "gensec_server_start (server) failed");
     880             : 
     881          20 :         status = gensec_set_credentials(gensec_server_context, server_creds);
     882          20 :         torture_assert_ntstatus_ok(tctx, status, "gensec_set_credentials (server) failed");
     883             : 
     884          20 :         status = gensec_start_mech_by_sasl_name(gensec_server_context, "GSSAPI");
     885          20 :         torture_assert_ntstatus_ok(tctx, status, "gensec_start_mech_by_sasl_name (server) failed");
     886             : 
     887          20 :         server_to_client = data_blob(NULL, 0);
     888             : 
     889           0 :         do {
     890             :                 /* Do a client-server update dance */
     891          60 :                 status = gensec_update(gensec_client_context, tmp_ctx, server_to_client, &client_to_server);
     892          60 :                 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {;
     893          20 :                         torture_assert_ntstatus_ok(tctx, status, "gensec_update (client) failed");
     894             :                 }
     895             : 
     896          60 :                 status = gensec_update(gensec_server_context, tmp_ctx, client_to_server, &server_to_client);
     897          60 :                 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {;
     898          20 :                         torture_assert_ntstatus_ok(tctx, status, "gensec_update (server) failed");
     899             :                 }
     900             : 
     901          60 :                 if (NT_STATUS_IS_OK(status)) {
     902          20 :                         break;
     903             :                 }
     904             :         } while (1);
     905             : 
     906             :         /* Don't pollute the remaining tests with the changed credentials */
     907          20 :         cli_credentials_invalidate_ccache(server_creds, CRED_SPECIFIED);
     908          20 :         cli_credentials_set_target_service(server_creds, NULL);
     909          20 :         cli_credentials_set_impersonate_principal(server_creds, NULL, NULL);
     910             : 
     911             :         /* Extract the PAC using Samba's code */
     912             : 
     913          20 :         status = gensec_session_info(gensec_server_context, gensec_server_context, &s4u2self_session_info);
     914          20 :         torture_assert_ntstatus_ok(tctx, status, "gensec_session_info failed");
     915             : 
     916          20 :         cli_credentials_get_ntlm_username_domain(client_creds, tctx,
     917             :                                                  &ninfo.identity_info.account_name.string,
     918             :                                                  &ninfo.identity_info.domain_name.string);
     919             : 
     920             :         /* Now try with SamLogon */
     921          20 :         generate_random_buffer(ninfo.challenge,
     922             :                                sizeof(ninfo.challenge));
     923          20 :         chal = data_blob_const(ninfo.challenge,
     924             :                                sizeof(ninfo.challenge));
     925             : 
     926          20 :         names_blob = NTLMv2_generate_names_blob(tctx, cli_credentials_get_workstation(server_creds),
     927             :                                                 cli_credentials_get_domain(server_creds));
     928             : 
     929          20 :         status = cli_credentials_get_ntlm_response(client_creds, tctx,
     930             :                                                    &flags,
     931             :                                                    chal,
     932             :                                                    NULL, /* server_timestamp */
     933             :                                                    names_blob,
     934             :                                                    &lm_resp, &nt_resp,
     935             :                                                    NULL, NULL);
     936          20 :         torture_assert_ntstatus_ok(tctx, status, "cli_credentials_get_ntlm_response failed");
     937             : 
     938          20 :         ninfo.lm.data = lm_resp.data;
     939          20 :         ninfo.lm.length = lm_resp.length;
     940             : 
     941          20 :         ninfo.nt.data = nt_resp.data;
     942          20 :         ninfo.nt.length = nt_resp.length;
     943             : 
     944          20 :         ninfo.identity_info.parameter_control = 0;
     945          20 :         ninfo.identity_info.logon_id = 0;
     946          20 :         ninfo.identity_info.workstation.string = cli_credentials_get_workstation(server_creds);
     947             : 
     948          20 :         logon.network = &ninfo;
     949             : 
     950          20 :         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
     951          20 :         r.in.computer_name = cli_credentials_get_workstation(server_creds);
     952          20 :         r.in.credential = &auth;
     953          20 :         r.in.return_authenticator = &auth2;
     954          20 :         r.in.logon_level = NetlogonNetworkInformation;
     955          20 :         r.in.logon = &logon;
     956          20 :         r.out.validation = &validation;
     957          20 :         r.out.authoritative = &authoritative;
     958             : 
     959          20 :         ZERO_STRUCT(auth2);
     960          20 :         netlogon_creds_client_authenticator(creds, &auth);
     961             : 
     962          20 :         r.in.validation_level = 3;
     963             : 
     964          20 :         status = dcerpc_netr_LogonSamLogon_r(b, tctx, &r);
     965          20 :         torture_assert_ntstatus_ok(tctx, status, "LogonSamLogon failed");
     966             : 
     967          20 :         torture_assert(tctx, netlogon_creds_client_check(creds,
     968             :                                                          &r.out.return_authenticator->cred),
     969             :                        "Credential chaining failed");
     970             : 
     971          20 :         torture_assert_ntstatus_ok(tctx, r.out.result, "LogonSamLogon failed");
     972             : 
     973          20 :         status = make_user_info_dc_netlogon_validation(tmp_ctx,
     974             :                                                       ninfo.identity_info.account_name.string,
     975          20 :                                                       r.in.validation_level,
     976          20 :                                                       r.out.validation,
     977             :                                                           true, /* This user was authenticated */
     978             :                                                       &netlogon_user_info_dc);
     979             : 
     980          20 :         torture_assert_ntstatus_ok(tctx, status, "make_user_info_dc_netlogon_validation failed");
     981             : 
     982             :         /* Check that the primary group is present in validation's RID array */
     983          20 :         status = check_primary_group_in_validation(tmp_ctx, r.in.validation_level, r.out.validation);
     984          20 :         torture_assert_ntstatus_ok(tctx, status, "check_primary_group_in_validation failed");
     985             : 
     986          20 :         torture_assert_str_equal(tctx, netlogon_user_info_dc->info->account_name == NULL ? "" : netlogon_user_info_dc->info->account_name,
     987             :                                  kinit_session_info->info->account_name, "Account name differs for kinit-based PAC");
     988          20 :         torture_assert_str_equal(tctx,netlogon_user_info_dc->info->account_name == NULL ? "" : netlogon_user_info_dc->info->account_name,
     989             :                                  s4u2self_session_info->info->account_name, "Account name differs for S4U2Self");
     990          20 :         torture_assert_str_equal(tctx, netlogon_user_info_dc->info->full_name == NULL ? "" : netlogon_user_info_dc->info->full_name, kinit_session_info->info->full_name, "Full name differs for kinit-based PAC");
     991          20 :         torture_assert_str_equal(tctx, netlogon_user_info_dc->info->full_name == NULL ? "" : netlogon_user_info_dc->info->full_name, s4u2self_session_info->info->full_name, "Full name differs for S4U2Self");
     992             : 
     993          20 :         builtin_domain = dom_sid_parse_talloc(tmp_ctx, SID_BUILTIN);
     994          20 :         torture_assert_not_null(tctx, builtin_domain, "failed to parse SID");
     995             : 
     996             :         /* KRB5 might have an additional sid, the asserted identity */
     997          20 :         ai_auth_authority = dom_sid_parse_talloc(
     998             :                         tmp_ctx,
     999             :                         SID_AUTHENTICATION_AUTHORITY_ASSERTED_IDENTITY);
    1000          20 :         torture_assert_not_null(tctx, ai_auth_authority, "failed to parse SID");
    1001             : 
    1002          20 :         ai_service = dom_sid_parse_talloc(
    1003             :                         tmp_ctx,
    1004             :                         SID_SERVICE_ASSERTED_IDENTITY);
    1005          20 :         torture_assert_not_null(tctx, ai_service, "failed to parse SID");
    1006             : 
    1007             :         /* ...and the Claims Valid SID. */
    1008          20 :         ai_claims_valid = dom_sid_parse_talloc(
    1009             :                         tmp_ctx,
    1010             :                         SID_CLAIMS_VALID);
    1011          20 :         torture_assert_not_null(tctx, ai_claims_valid, "failed to parse SID");
    1012             : 
    1013          20 :         ai_auth_authority_count = 0;
    1014          20 :         ai_service_count = 0;
    1015          20 :         ai_claims_valid_count = 0;
    1016         220 :         for (i = 0; i < kinit_session_info->torture->num_dc_sids; i++) {
    1017         200 :                 ok = dom_sid_equal(&kinit_session_info->torture->dc_sids[i].sid,
    1018             :                                    ai_auth_authority);
    1019         200 :                 if (ok) {
    1020          20 :                         ai_auth_authority_count++;
    1021          20 :                         kinit_asserted_identity_index = i;
    1022             :                 }
    1023             : 
    1024         200 :                 ok = dom_sid_equal(&kinit_session_info->torture->dc_sids[i].sid,
    1025             :                                    ai_service);
    1026         200 :                 if (ok) {
    1027           0 :                         ai_service_count++;
    1028           0 :                         kinit_asserted_identity_index = i;
    1029             :                 }
    1030             : 
    1031         200 :                 ok = dom_sid_equal(&kinit_session_info->torture->dc_sids[i].sid,
    1032             :                                    ai_claims_valid);
    1033         200 :                 if (ok) {
    1034          20 :                         ai_claims_valid_count++;
    1035          20 :                         kinit_claims_valid_index = i;
    1036             :                 }
    1037             :         }
    1038             : 
    1039          20 :         torture_assert_int_equal(tctx, ai_auth_authority_count, 1,
    1040             :                 "Kinit authority asserted identity should be (1)");
    1041          20 :         torture_assert_int_equal(tctx, ai_service_count, 0,
    1042             :                 "Kinit service asserted identity should be (0)");
    1043          20 :         torture_assert_int_equal(tctx, ai_claims_valid_count, 1,
    1044             :                 "Kinit Claims Valid should be (1)");
    1045             : 
    1046          20 :         ai_auth_authority_count = 0;
    1047          20 :         ai_service_count = 0;
    1048          20 :         ai_claims_valid_count = 0;
    1049         220 :         for (i = 0; i < s4u2self_session_info->torture->num_dc_sids; i++) {
    1050         200 :                 ok = dom_sid_equal(&s4u2self_session_info->torture->dc_sids[i].sid,
    1051             :                                    ai_auth_authority);
    1052         200 :                 if (ok) {
    1053           0 :                         ai_auth_authority_count++;
    1054           0 :                         s4u2self_asserted_identity_index = i;
    1055             :                 }
    1056             : 
    1057         200 :                 ok = dom_sid_equal(&s4u2self_session_info->torture->dc_sids[i].sid,
    1058             :                                    ai_service);
    1059         200 :                 if (ok) {
    1060          20 :                         ai_service_count++;
    1061          20 :                         s4u2self_asserted_identity_index = i;
    1062             :                 }
    1063             : 
    1064         200 :                 ok = dom_sid_equal(&s4u2self_session_info->torture->dc_sids[i].sid,
    1065             :                                    ai_claims_valid);
    1066         200 :                 if (ok) {
    1067          20 :                         ai_claims_valid_count++;
    1068          20 :                         s4u2self_claims_valid_index = i;
    1069             :                 }
    1070             :         }
    1071             : 
    1072          20 :         torture_assert_int_equal(tctx, ai_auth_authority_count, 0,
    1073             :                 "S4U2Self authority asserted identity should be (0)");
    1074          20 :         torture_assert_int_equal(tctx, ai_service_count, 1,
    1075             :                 "S4U2Self service asserted identity should be (1)");
    1076          20 :         torture_assert_int_equal(tctx, ai_claims_valid_count, 1,
    1077             :                 "S4U2Self Claims Valid should be (1)");
    1078             : 
    1079             :         /*
    1080             :          * Subtract 2 to account for the Asserted Identity and Claims Valid
    1081             :          * SIDs.
    1082             :          */
    1083          20 :         torture_assert_int_equal(tctx, netlogon_user_info_dc->num_sids, kinit_session_info->torture->num_dc_sids - 2, "Different numbers of domain groups for kinit-based PAC");
    1084          20 :         torture_assert_int_equal(tctx, netlogon_user_info_dc->num_sids, s4u2self_session_info->torture->num_dc_sids - 2, "Different numbers of domain groups for S4U2Self");
    1085             : 
    1086             :         /* Loop over all three SID arrays. */
    1087         180 :         for (i = 0, j = 0, k = 0; i < netlogon_user_info_dc->num_sids; i++, j++, k++) {
    1088         200 :                 while (j == kinit_asserted_identity_index || j == kinit_claims_valid_index) {
    1089             :                         /* Skip over the asserted identity and Claims Valid SIDs. */
    1090          40 :                         ++j;
    1091             :                 }
    1092         200 :                 while (k == s4u2self_asserted_identity_index || k == s4u2self_claims_valid_index) {
    1093             :                         /* Skip over the asserted identity and Claims Valid SIDs. */
    1094          40 :                         ++k;
    1095             :                 }
    1096         160 :                 torture_assert_sid_equal(tctx, &netlogon_user_info_dc->sids[i].sid, &kinit_session_info->torture->dc_sids[j].sid, "Different domain groups for kinit-based PAC");
    1097         160 :                 torture_assert_u32_equal(tctx, netlogon_user_info_dc->sids[i].attrs, kinit_session_info->torture->dc_sids[j].attrs, "Different domain group attrs for kinit-based PAC");
    1098         160 :                 torture_assert_sid_equal(tctx, &netlogon_user_info_dc->sids[i].sid, &s4u2self_session_info->torture->dc_sids[k].sid, "Different domain groups for S4U2Self");
    1099         160 :                 torture_assert_u32_equal(tctx, netlogon_user_info_dc->sids[i].attrs, s4u2self_session_info->torture->dc_sids[k].attrs, "Different domain group attrs for S4U2Self");
    1100         160 :                 torture_assert(tctx, !dom_sid_in_domain(builtin_domain, &s4u2self_session_info->torture->dc_sids[k].sid), "Returned BUILTIN domain in groups for S4U2Self");
    1101         160 :                 torture_assert(tctx, !dom_sid_in_domain(builtin_domain, &kinit_session_info->torture->dc_sids[j].sid), "Returned BUILTIN domain in groups kinit-based PAC");
    1102         160 :                 torture_assert(tctx, !dom_sid_in_domain(builtin_domain, &netlogon_user_info_dc->sids[i].sid), "Returned BUILTIN domain in groups from NETLOGON SamLogon reply");
    1103             :         }
    1104             : 
    1105          20 :         return true;
    1106             : }
    1107             : 
    1108           5 : static bool test_S4U2Self_bdc_arcfour(struct torture_context *tctx,
    1109             :                                       struct dcerpc_pipe *p,
    1110             :                                       struct cli_credentials *credentials)
    1111             : {
    1112           5 :         return test_S4U2Self(tctx, p, credentials, SEC_CHAN_BDC,
    1113             :                              TEST_MACHINE_NAME_S4U2SELF_BDC,
    1114             :                              NETLOGON_NEG_AUTH2_ADS_FLAGS);
    1115             : }
    1116             : 
    1117           5 : static bool test_S4U2Self_bdc_aes(struct torture_context *tctx,
    1118             :                                   struct dcerpc_pipe *p,
    1119             :                                   struct cli_credentials *credentials)
    1120             : {
    1121           5 :         return test_S4U2Self(tctx, p, credentials, SEC_CHAN_BDC,
    1122             :                              TEST_MACHINE_NAME_S4U2SELF_BDC,
    1123             :                              NETLOGON_NEG_AUTH2_ADS_FLAGS | NETLOGON_NEG_SUPPORTS_AES);
    1124             : }
    1125             : 
    1126           5 : static bool test_S4U2Self_workstation_arcfour(struct torture_context *tctx,
    1127             :                                               struct dcerpc_pipe *p,
    1128             :                                               struct cli_credentials *credentials)
    1129             : {
    1130           5 :         return test_S4U2Self(tctx, p, credentials, SEC_CHAN_WKSTA,
    1131             :                              TEST_MACHINE_NAME_S4U2SELF_WKSTA,
    1132             :                              NETLOGON_NEG_AUTH2_ADS_FLAGS);
    1133             : }
    1134             : 
    1135           5 : static bool test_S4U2Self_workstation_aes(struct torture_context *tctx,
    1136             :                                           struct dcerpc_pipe *p,
    1137             :                                           struct cli_credentials *credentials)
    1138             : {
    1139           5 :         return test_S4U2Self(tctx, p, credentials, SEC_CHAN_WKSTA,
    1140             :                              TEST_MACHINE_NAME_S4U2SELF_WKSTA,
    1141             :                              NETLOGON_NEG_AUTH2_ADS_FLAGS | NETLOGON_NEG_SUPPORTS_AES);
    1142             : }
    1143             : 
    1144          10 : static bool test_S4U2Proxy(struct torture_context *tctx,
    1145             :                            struct dcerpc_pipe *p,
    1146             :                            struct cli_credentials *credentials,
    1147             :                            enum netr_SchannelType secure_channel_type,
    1148             :                            const char *test_machine_name,
    1149             :                            uint32_t negotiate_flags)
    1150             : {
    1151           0 :         NTSTATUS status;
    1152          10 :         struct gensec_security *gensec_client_context = NULL;
    1153          10 :         struct gensec_security *gensec_server_context = NULL;
    1154          10 :         struct cli_credentials *server_creds = NULL;
    1155           0 :         size_t num_pac_buffers;
    1156          10 :         struct auth4_context *auth_context = NULL;
    1157          10 :         struct auth_session_info *session_info = NULL;
    1158          10 :         struct pac_data *pac_data = NULL;
    1159          10 :         const struct PAC_BUFFER *pac_buf = NULL;
    1160          10 :         char *impersonate_princ = NULL, *self_princ = NULL, *target_princ = NULL;
    1161           0 :         enum ndr_err_code ndr_err;
    1162           0 :         struct PAC_DATA pac_data_struct;
    1163          10 :         struct PAC_CONSTRAINED_DELEGATION *deleg = NULL;
    1164             : 
    1165           0 :         DATA_BLOB client_to_server, server_to_client;
    1166             : 
    1167          10 :         auth_context = talloc_zero(tctx, struct auth4_context);
    1168          10 :         torture_assert_not_null(tctx, auth_context, "talloc_new() failed");
    1169             : 
    1170          10 :         auth_context->generate_session_info_pac = test_generate_session_info_pac;
    1171             : 
    1172          10 :         torture_comment(tctx,
    1173             :                 "Testing S4U2Proxy (secure_channel_type: %d, machine: %s, negotiate_flags: 0x%08x\n",
    1174             :                 secure_channel_type, test_machine_name, negotiate_flags);
    1175             : 
    1176          10 :         impersonate_princ = cli_credentials_get_principal(samba_cmdline_get_creds(), tctx);
    1177          10 :         torture_assert_not_null(tctx, impersonate_princ, "Failed to get impersonate client name");
    1178             : 
    1179          10 :         server_creds = cli_credentials_shallow_copy(tctx, credentials);
    1180          10 :         torture_assert_not_null(tctx, server_creds, "Failed to copy of credentials");
    1181             : 
    1182          10 :         self_princ = talloc_asprintf(tctx, "host/%s", test_machine_name);
    1183          10 :         cli_credentials_invalidate_ccache(server_creds, CRED_SPECIFIED);
    1184          10 :         cli_credentials_set_impersonate_principal(server_creds, impersonate_princ, self_princ);
    1185             : 
    1186             :         /* Trigger S4U2Proxy by setting a target_service different than self_principal */
    1187          10 :         target_princ = talloc_asprintf(tctx, "%s$", test_machine_name);
    1188          10 :         cli_credentials_set_target_service(server_creds, target_princ);
    1189             : 
    1190          10 :         status = gensec_client_start(tctx, &gensec_client_context,
    1191             :                                      lpcfg_gensec_settings(tctx, tctx->lp_ctx));
    1192          10 :         torture_assert_ntstatus_ok(tctx, status, "gensec_client_start (client) failed");
    1193             : 
    1194          10 :         status = gensec_set_target_principal(gensec_client_context, target_princ);
    1195          10 :         torture_assert_ntstatus_ok(tctx, status, "gensec_set_target_hostname (client) failed");
    1196             : 
    1197             :         /* We now set the same credentials on both client and server contexts */
    1198          10 :         status = gensec_set_credentials(gensec_client_context, server_creds);
    1199          10 :         torture_assert_ntstatus_ok(tctx, status, "gensec_set_credentials (client) failed");
    1200             : 
    1201          10 :         status = gensec_start_mech_by_sasl_name(gensec_client_context, "GSSAPI");
    1202          10 :         torture_assert_ntstatus_ok(tctx, status, "gensec_start_mech_by_sasl_name (client) failed");
    1203             : 
    1204          10 :         status = gensec_server_start(tctx,
    1205             :                                      lpcfg_gensec_settings(tctx, tctx->lp_ctx),
    1206             :                                      auth_context, &gensec_server_context);
    1207          10 :         torture_assert_ntstatus_ok(tctx, status, "gensec_server_start (server) failed");
    1208             : 
    1209          10 :         status = gensec_set_credentials(gensec_server_context, server_creds);
    1210          10 :         torture_assert_ntstatus_ok(tctx, status, "gensec_set_credentials (server) failed");
    1211             : 
    1212          10 :         status = gensec_start_mech_by_sasl_name(gensec_server_context, "GSSAPI");
    1213          10 :         torture_assert_ntstatus_ok(tctx, status, "gensec_start_mech_by_sasl_name (server) failed");
    1214             : 
    1215          10 :         server_to_client = data_blob(NULL, 0);
    1216             : 
    1217           0 :         do {
    1218             :                 /* Do a client-server update dance */
    1219          30 :                 status = gensec_update(gensec_client_context, tctx, server_to_client, &client_to_server);
    1220          30 :                 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {;
    1221          10 :                         torture_assert_ntstatus_ok(tctx, status, "gensec_update (client) failed");
    1222             :                 }
    1223             : 
    1224          30 :                 status = gensec_update(gensec_server_context, tctx, client_to_server, &server_to_client);
    1225          30 :                 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {;
    1226          10 :                         torture_assert_ntstatus_ok(tctx, status, "gensec_update (server) failed");
    1227             :                 }
    1228             : 
    1229          30 :                 if (NT_STATUS_IS_OK(status)) {
    1230          10 :                         break;
    1231             :                 }
    1232             :         } while (1);
    1233             : 
    1234             :         /* Extract the PAC using Samba's code */
    1235             : 
    1236          10 :         status = gensec_session_info(gensec_server_context, gensec_server_context, &session_info);
    1237          10 :         torture_assert_ntstatus_ok(tctx, status, "gensec_session_info failed");
    1238             : 
    1239          10 :         pac_data = talloc_get_type(auth_context->private_data, struct pac_data);
    1240             : 
    1241          10 :         torture_assert_not_null(tctx, pac_data, "gensec_update failed to fill in pac_data in auth_context");
    1242          10 :         torture_assert_not_null(tctx, pac_data->pac_srv_sig, "pac_srv_sig not present");
    1243          10 :         torture_assert_not_null(tctx, pac_data->pac_kdc_sig, "pac_kdc_sig not present");
    1244             : 
    1245          10 :         ndr_err = ndr_pull_struct_blob(&pac_data->pac_blob, tctx, &pac_data_struct,
    1246             :                                        (ndr_pull_flags_fn_t)ndr_pull_PAC_DATA);
    1247          10 :         torture_assert(tctx, NDR_ERR_CODE_IS_SUCCESS(ndr_err), "ndr_pull_struct_blob of PAC_DATA structure failed");
    1248             : 
    1249          10 :         num_pac_buffers = 9;
    1250             : 
    1251          10 :         torture_assert_int_equal(tctx, pac_data_struct.version, 0, "version");
    1252          10 :         torture_assert_int_equal(tctx, pac_data_struct.num_buffers, num_pac_buffers, "num_buffers");
    1253             : 
    1254          10 :         pac_buf = get_pac_buffer(&pac_data_struct, PAC_TYPE_LOGON_INFO);
    1255          10 :         torture_assert_not_null(tctx, pac_buf, "PAC_TYPE_LOGON_INFO");
    1256          10 :         torture_assert_not_null(tctx, pac_buf->info, "PAC_TYPE_LOGON_INFO info");
    1257             : 
    1258          10 :         pac_buf = get_pac_buffer(&pac_data_struct, PAC_TYPE_LOGON_NAME);
    1259          10 :         torture_assert_not_null(tctx, pac_buf, "PAC_TYPE_LOGON_NAME");
    1260          10 :         torture_assert_not_null(tctx, pac_buf->info, "PAC_TYPE_LOGON_NAME info");
    1261             : 
    1262          10 :         pac_buf = get_pac_buffer(&pac_data_struct, PAC_TYPE_UPN_DNS_INFO);
    1263          10 :         torture_assert_not_null(tctx, pac_buf, "PAC_TYPE_UPN_DNS_INFO");
    1264          10 :         torture_assert_not_null(tctx, pac_buf->info, "PAC_TYPE_UPN_DNS_INFO info");
    1265             : 
    1266          10 :         pac_buf = get_pac_buffer(&pac_data_struct, PAC_TYPE_SRV_CHECKSUM);
    1267          10 :         torture_assert_not_null(tctx, pac_buf, "PAC_TYPE_SRV_CHECKSUM");
    1268          10 :         torture_assert_not_null(tctx, pac_buf->info, "PAC_TYPE_SRV_CHECKSUM info");
    1269             : 
    1270          10 :         pac_buf = get_pac_buffer(&pac_data_struct, PAC_TYPE_KDC_CHECKSUM);
    1271          10 :         torture_assert_not_null(tctx, pac_buf, "PAC_TYPE_KDC_CHECKSUM");
    1272          10 :         torture_assert_not_null(tctx, pac_buf->info, "PAC_TYPE_KDC_CHECKSUM info");
    1273             : 
    1274          10 :         pac_buf = get_pac_buffer(&pac_data_struct, PAC_TYPE_TICKET_CHECKSUM);
    1275          10 :         torture_assert_not_null(tctx, pac_buf, "PAC_TYPE_TICKET_CHECKSUM");
    1276          10 :         torture_assert_not_null(tctx, pac_buf->info, "PAC_TYPE_TICKET_CHECKSUM info");
    1277             : 
    1278          10 :         pac_buf = get_pac_buffer(&pac_data_struct, PAC_TYPE_FULL_CHECKSUM);
    1279          10 :         torture_assert_not_null(tctx, pac_buf, "PAC_TYPE_FULL_CHECKSUM");
    1280          10 :         torture_assert_not_null(tctx, pac_buf->info, "PAC_TYPE_FULL_CHECKSUM info");
    1281             : 
    1282          10 :         pac_buf = get_pac_buffer(&pac_data_struct, PAC_TYPE_CLIENT_CLAIMS_INFO);
    1283          10 :         torture_assert_not_null(tctx, pac_buf, "PAC_TYPE_CLIENT_CLAIMS_INFO");
    1284          10 :         torture_assert_not_null(tctx, pac_buf->info, "PAC_TYPE_CLIENT_CLAIMS_INFO info");
    1285             : 
    1286          10 :         pac_buf = get_pac_buffer(&pac_data_struct, PAC_TYPE_CONSTRAINED_DELEGATION);
    1287          10 :         torture_assert_not_null(tctx, pac_buf, "PAC_TYPE_CONSTRAINED_DELEGATION");
    1288          10 :         torture_assert_not_null(tctx, pac_buf->info, "PAC_TYPE_CONSTRAINED_DELEGATION info");
    1289             : 
    1290          10 :         deleg = pac_buf->info->constrained_delegation.info;
    1291          10 :         torture_assert_str_equal(tctx, deleg->proxy_target.string, target_princ, "wrong proxy_target");
    1292          10 :         torture_assert_int_equal(tctx, deleg->num_transited_services, 1, "wrong transited_services number");
    1293          10 :         torture_assert_str_equal(tctx, deleg->transited_services[0].string,
    1294             :                                  talloc_asprintf(tctx, "%s@%s", self_princ, cli_credentials_get_realm(credentials)),
    1295             :                                  "wrong transited_services[0]");
    1296             : 
    1297          10 :         return netlogon_validate_pac(tctx, p, server_creds, secure_channel_type, test_machine_name,
    1298             :                                      negotiate_flags, pac_data, session_info);
    1299             : }
    1300             : 
    1301          10 : static bool setup_constrained_delegation(struct torture_context *tctx,
    1302             :                                          struct dcerpc_pipe *p,
    1303             :                                          struct test_join *join_ctx,
    1304             :                                          const char *machine_name)
    1305             : {
    1306           0 :         struct samr_SetUserInfo r;
    1307           0 :         union samr_UserInfo user_info;
    1308          10 :         struct dcerpc_pipe *samr_pipe = torture_join_samr_pipe(join_ctx);
    1309          10 :         const char *server_dn_str = NULL;
    1310          10 :         struct ldb_context *sam_ctx = NULL;
    1311          10 :         struct ldb_dn *server_dn = NULL;
    1312          10 :         struct ldb_message *msg = NULL;
    1313          10 :         char *url = NULL;
    1314           0 :         int ret;
    1315             : 
    1316          10 :         url = talloc_asprintf(tctx, "ldap://%s", dcerpc_server_name(p));
    1317          10 :         sam_ctx = ldb_wrap_connect(tctx, tctx->ev, tctx->lp_ctx, url, NULL, samba_cmdline_get_creds(), 0);
    1318          10 :         torture_assert_not_null(tctx, sam_ctx, "Connection to the SAMDB on DC failed!");
    1319             : 
    1320          10 :         server_dn_str = samdb_search_string(sam_ctx, tctx, ldb_get_default_basedn(sam_ctx), "distinguishedName",
    1321             :                                             "samaccountname=%s$", machine_name);
    1322          10 :         torture_assert_not_null(tctx, server_dn_str, "samdb_search_string()");
    1323             : 
    1324          10 :         server_dn = ldb_dn_new(tctx, sam_ctx, server_dn_str);
    1325          10 :         torture_assert_not_null(tctx, server_dn, "ldb_dn_new()");
    1326             : 
    1327          10 :         msg = ldb_msg_new(tctx);
    1328          10 :         torture_assert_not_null(tctx, msg, "ldb_msg_new()");
    1329             : 
    1330          10 :         msg->dn = server_dn;
    1331          10 :         ret = ldb_msg_add_string(msg, "msDS-AllowedToDelegateTo", talloc_asprintf(tctx, "%s$", machine_name));
    1332          10 :         torture_assert_int_equal(tctx, ret, 0, "ldb_msg_add_string())");
    1333             : 
    1334          10 :         ret = ldb_modify(sam_ctx, msg);
    1335          10 :         torture_assert_int_equal(tctx, ret, 0, "ldb_modify()");
    1336             : 
    1337             :         /* Allow forwardable flag in S4U2Self */
    1338          10 :         user_info.info16.acct_flags = ACB_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION | ACB_WSTRUST;
    1339          10 :         r.in.user_handle = torture_join_samr_user_policy(join_ctx);
    1340          10 :         r.in.level = 16;
    1341          10 :         r.in.info = &user_info;
    1342             : 
    1343          10 :         torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetUserInfo_r(samr_pipe->binding_handle, tctx, &r),
    1344             :                 "failed to set ACB_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION info account flags");
    1345          10 :         torture_assert_ntstatus_ok(tctx, r.out.result,
    1346             :                 "failed to set ACB_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION into account flags");
    1347             : 
    1348          10 :         return true;
    1349             : }
    1350             : 
    1351           5 : static bool test_S4U2Proxy_workstation_arcfour(struct torture_context *tctx,
    1352             :                                                struct dcerpc_pipe *p,
    1353             :                                                struct cli_credentials *credentials,
    1354             :                                                struct test_join *join_ctx)
    1355             : {
    1356           5 :         torture_assert(tctx, setup_constrained_delegation(tctx, p, join_ctx,
    1357             :                                                           TEST_MACHINE_NAME_S4U2PROXY_WKSTA),
    1358             :                                                           "setup_constrained_delegation() failed");
    1359           5 :         return test_S4U2Proxy(tctx, p, credentials, SEC_CHAN_WKSTA,
    1360             :                               TEST_MACHINE_NAME_S4U2PROXY_WKSTA,
    1361             :                               NETLOGON_NEG_AUTH2_ADS_FLAGS);
    1362             : }
    1363             : 
    1364           5 : static bool test_S4U2Proxy_workstation_aes(struct torture_context *tctx,
    1365             :                                            struct dcerpc_pipe *p,
    1366             :                                            struct cli_credentials *credentials,
    1367             :                                            struct test_join *join_ctx)
    1368             : {
    1369           5 :         torture_assert(tctx, setup_constrained_delegation(tctx, p, join_ctx,
    1370             :                                                           TEST_MACHINE_NAME_S4U2PROXY_WKSTA),
    1371             :                                                           "setup_constrained_delegation() failed");
    1372           5 :         return test_S4U2Proxy(tctx, p, credentials, SEC_CHAN_WKSTA,
    1373             :                               TEST_MACHINE_NAME_S4U2PROXY_WKSTA,
    1374             :                               NETLOGON_NEG_AUTH2_ADS_FLAGS | NETLOGON_NEG_SUPPORTS_AES);
    1375             : }
    1376             : #endif
    1377             : 
    1378        2338 : struct torture_suite *torture_rpc_remote_pac(TALLOC_CTX *mem_ctx)
    1379             : {
    1380        2338 :         struct torture_suite *suite = torture_suite_create(mem_ctx, "pac");
    1381         125 :         struct torture_rpc_tcase *tcase;
    1382             : 
    1383        2338 :         tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "netr-bdc-arcfour",
    1384             :                                                               &ndr_table_netlogon, TEST_MACHINE_NAME_BDC);
    1385        2338 :         torture_rpc_tcase_add_test_creds(tcase, "verify-sig-arcfour", test_PACVerify_bdc_arcfour);
    1386             : 
    1387        2338 :         tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "netr-bdc-aes",
    1388             :                                                               &ndr_table_netlogon, TEST_MACHINE_NAME_BDC);
    1389        2338 :         torture_rpc_tcase_add_test_creds(tcase, "verify-sig-aes", test_PACVerify_bdc_aes);
    1390             : 
    1391        2338 :         tcase = torture_suite_add_machine_workstation_rpc_iface_tcase(suite, "netr-mem-arcfour",
    1392             :                                                                       &ndr_table_netlogon, TEST_MACHINE_NAME_WKSTA);
    1393        2338 :         torture_rpc_tcase_add_test_creds(tcase, "verify-sig-arcfour", test_PACVerify_workstation_arcfour);
    1394             : 
    1395        2338 :         tcase = torture_suite_add_machine_workstation_rpc_iface_tcase(suite, "netr-mem-aes",
    1396             :                                                                       &ndr_table_netlogon, TEST_MACHINE_NAME_WKSTA);
    1397        2338 :         torture_rpc_tcase_add_test_creds(tcase, "verify-sig-aes", test_PACVerify_workstation_aes);
    1398             : 
    1399             : #ifdef SAMBA4_USES_HEIMDAL
    1400        1908 :         tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "netr-bdc-arcfour",
    1401             :                                                               &ndr_table_netlogon, TEST_MACHINE_NAME_S4U2SELF_BDC);
    1402        1908 :         torture_rpc_tcase_add_test_creds(tcase, "s4u2self-arcfour", test_S4U2Self_bdc_arcfour);
    1403             : 
    1404        1908 :         tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "netr-bcd-aes",
    1405             :                                                               &ndr_table_netlogon, TEST_MACHINE_NAME_S4U2SELF_BDC);
    1406        1908 :         torture_rpc_tcase_add_test_creds(tcase, "s4u2self-aes", test_S4U2Self_bdc_aes);
    1407             : 
    1408        1908 :         tcase = torture_suite_add_machine_workstation_rpc_iface_tcase(suite, "netr-mem-arcfour",
    1409             :                                                                       &ndr_table_netlogon, TEST_MACHINE_NAME_S4U2SELF_WKSTA);
    1410        1908 :         torture_rpc_tcase_add_test_creds(tcase, "s4u2self-arcfour", test_S4U2Self_workstation_arcfour);
    1411             : 
    1412        1908 :         tcase = torture_suite_add_machine_workstation_rpc_iface_tcase(suite, "netr-mem-aes",
    1413             :                                                                       &ndr_table_netlogon, TEST_MACHINE_NAME_S4U2SELF_WKSTA);
    1414        1908 :         torture_rpc_tcase_add_test_creds(tcase, "s4u2self-aes", test_S4U2Self_workstation_aes);
    1415             : 
    1416        1908 :         tcase = torture_suite_add_machine_workstation_rpc_iface_tcase(suite, "netr-mem-arcfour",
    1417             :                                                                       &ndr_table_netlogon, TEST_MACHINE_NAME_S4U2PROXY_WKSTA);
    1418        1908 :         torture_rpc_tcase_add_test_join(tcase, "s4u2proxy-arcfour", test_S4U2Proxy_workstation_arcfour);
    1419             : 
    1420        1908 :         tcase = torture_suite_add_machine_workstation_rpc_iface_tcase(suite, "netr-mem-aes",
    1421             :                                                                       &ndr_table_netlogon, TEST_MACHINE_NAME_S4U2PROXY_WKSTA);
    1422        1908 :         torture_rpc_tcase_add_test_join(tcase, "s4u2proxy-aes", test_S4U2Proxy_workstation_aes);
    1423             : #endif
    1424        2338 :         return suite;
    1425             : }

Generated by: LCOV version 1.14