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