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

Generated by: LCOV version 1.13