Line data Source code
1 : /*
2 : Unix SMB/CIFS implementation.
3 :
4 : dcerpc torture tests, designed to walk Samba3 code paths
5 :
6 : Copyright (C) Volker Lendecke 2006
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 "libcli/raw/libcliraw.h"
24 : #include "libcli/raw/raw_proto.h"
25 : #include "torture/util.h"
26 : #include "libcli/rap/rap.h"
27 : #include "librpc/gen_ndr/ndr_lsa_c.h"
28 : #include "librpc/gen_ndr/ndr_samr_c.h"
29 : #include "librpc/gen_ndr/ndr_netlogon_c.h"
30 : #include "librpc/gen_ndr/ndr_srvsvc_c.h"
31 : #include "librpc/gen_ndr/ndr_spoolss_c.h"
32 : #include "librpc/gen_ndr/ndr_winreg_c.h"
33 : #include "librpc/gen_ndr/ndr_wkssvc_c.h"
34 : #include "librpc/gen_ndr/ndr_svcctl_c.h"
35 : #include "lib/cmdline/cmdline.h"
36 : #include "torture/rpc/torture_rpc.h"
37 : #include "libcli/libcli.h"
38 : #include "libcli/smb_composite/smb_composite.h"
39 : #include "libcli/auth/libcli_auth.h"
40 : #include "libcli/security/security.h"
41 : #include "param/param.h"
42 : #include "lib/registry/registry.h"
43 : #include "libcli/resolve/resolve.h"
44 : #include "torture/ndr/ndr.h"
45 : #include "libcli/smb2/smb2.h"
46 : #include "libcli/smb2/smb2_calls.h"
47 : #include "librpc/rpc/dcerpc.h"
48 : #include "librpc/rpc/dcerpc_proto.h"
49 : #include "libcli/smb/smbXcli_base.h"
50 : #include "source3/rpc_client/init_samr.h"
51 :
52 : /*
53 : * open pipe and bind, given an IPC$ context
54 : */
55 :
56 9 : static NTSTATUS pipe_bind_smb(struct torture_context *tctx,
57 : TALLOC_CTX *mem_ctx,
58 : struct smbcli_tree *tree,
59 : const char *pipe_name,
60 : const struct ndr_interface_table *iface,
61 : struct dcerpc_pipe **p)
62 : {
63 : struct dcerpc_pipe *result;
64 : NTSTATUS status;
65 :
66 9 : if (!(result = dcerpc_pipe_init(mem_ctx, tctx->ev))) {
67 0 : return NT_STATUS_NO_MEMORY;
68 : }
69 :
70 9 : status = dcerpc_pipe_open_smb(result, tree, pipe_name);
71 9 : if (!NT_STATUS_IS_OK(status)) {
72 0 : torture_comment(tctx, "dcerpc_pipe_open_smb failed: %s\n",
73 : nt_errstr(status));
74 0 : talloc_free(result);
75 0 : return status;
76 : }
77 :
78 9 : status = dcerpc_bind_auth_none(result, iface);
79 9 : if (!NT_STATUS_IS_OK(status)) {
80 0 : torture_comment(tctx, "dcerpc_bind_auth_none failed: %s\n", nt_errstr(status));
81 0 : talloc_free(result);
82 0 : return status;
83 : }
84 :
85 9 : *p = result;
86 9 : return NT_STATUS_OK;
87 : }
88 :
89 0 : static NTSTATUS pipe_bind_smb2(struct torture_context *tctx,
90 : TALLOC_CTX *mem_ctx,
91 : struct smb2_tree *tree,
92 : const char *pipe_name,
93 : const struct ndr_interface_table *iface,
94 : struct dcerpc_pipe **p)
95 : {
96 : struct dcerpc_pipe *result;
97 : NTSTATUS status;
98 :
99 0 : if (!(result = dcerpc_pipe_init(mem_ctx, tctx->ev))) {
100 0 : return NT_STATUS_NO_MEMORY;
101 : }
102 :
103 0 : status = dcerpc_pipe_open_smb2(result, tree, pipe_name);
104 0 : if (!NT_STATUS_IS_OK(status)) {
105 0 : torture_comment(tctx, "dcerpc_pipe_open_smb2 failed: %s\n",
106 : nt_errstr(status));
107 0 : talloc_free(result);
108 0 : return status;
109 : }
110 :
111 0 : status = dcerpc_bind_auth_none(result, iface);
112 0 : if (!NT_STATUS_IS_OK(status)) {
113 0 : torture_comment(tctx, "dcerpc_bind_auth_none failed: %s\n", nt_errstr(status));
114 0 : talloc_free(result);
115 0 : return status;
116 : }
117 :
118 0 : *p = result;
119 0 : return NT_STATUS_OK;
120 : }
121 :
122 0 : static NTSTATUS pipe_bind_smb_auth(struct torture_context *tctx,
123 : TALLOC_CTX *mem_ctx,
124 : struct smbcli_tree *tree,
125 : struct cli_credentials *creds,
126 : uint8_t auth_type,
127 : uint8_t auth_level,
128 : const char *pipe_name,
129 : const struct ndr_interface_table *iface,
130 : struct dcerpc_pipe **p)
131 : {
132 : struct dcerpc_pipe *result;
133 : NTSTATUS status;
134 :
135 0 : if (!(result = dcerpc_pipe_init(mem_ctx, tctx->ev))) {
136 0 : return NT_STATUS_NO_MEMORY;
137 : }
138 :
139 0 : status = dcerpc_pipe_open_smb(result, tree, pipe_name);
140 0 : if (!NT_STATUS_IS_OK(status)) {
141 0 : torture_comment(tctx, "dcerpc_pipe_open_smb failed: %s\n",
142 : nt_errstr(status));
143 0 : talloc_free(result);
144 0 : return status;
145 : }
146 :
147 0 : status = dcerpc_bind_auth(result, iface, creds,
148 0 : lpcfg_gensec_settings(tctx->lp_ctx, tctx->lp_ctx),
149 : auth_type, auth_level, NULL);
150 0 : if (!NT_STATUS_IS_OK(status)) {
151 0 : torture_comment(tctx, "dcerpc_bind_auth failed: %s\n", nt_errstr(status));
152 0 : talloc_free(result);
153 0 : return status;
154 : }
155 :
156 0 : *p = result;
157 0 : return NT_STATUS_OK;
158 : }
159 :
160 : /*
161 : * This tests a RPC call using an invalid vuid
162 : */
163 :
164 9 : bool torture_bind_authcontext(struct torture_context *torture)
165 : {
166 : TALLOC_CTX *mem_ctx;
167 : NTSTATUS status;
168 9 : bool ret = false;
169 : struct lsa_ObjectAttribute objectattr;
170 : struct lsa_OpenPolicy2 openpolicy;
171 : struct policy_handle handle;
172 : struct lsa_Close close_handle;
173 : struct smbcli_session *tmp;
174 : uint16_t tmp_vuid;
175 : struct smbcli_session *session2;
176 : struct smbcli_state *cli;
177 : struct dcerpc_pipe *lsa_pipe;
178 : struct dcerpc_binding_handle *lsa_handle;
179 : struct cli_credentials *anon_creds;
180 : struct smb_composite_sesssetup setup;
181 : struct smbcli_options options;
182 : struct smbcli_session_options session_options;
183 :
184 9 : mem_ctx = talloc_init("torture_bind_authcontext");
185 :
186 9 : if (mem_ctx == NULL) {
187 0 : torture_comment(torture, "talloc_init failed\n");
188 0 : return false;
189 : }
190 :
191 9 : lpcfg_smbcli_options(torture->lp_ctx, &options);
192 9 : lpcfg_smbcli_session_options(torture->lp_ctx, &session_options);
193 :
194 9 : status = smbcli_full_connection(mem_ctx, &cli,
195 : torture_setting_string(torture, "host", NULL),
196 : lpcfg_smb_ports(torture->lp_ctx),
197 : "IPC$", NULL,
198 : lpcfg_socket_options(torture->lp_ctx),
199 : samba_cmdline_get_creds(),
200 : lpcfg_resolve_context(torture->lp_ctx),
201 : torture->ev, &options, &session_options,
202 : lpcfg_gensec_settings(torture, torture->lp_ctx));
203 9 : if (!NT_STATUS_IS_OK(status)) {
204 0 : torture_comment(torture, "smbcli_full_connection failed: %s\n",
205 : nt_errstr(status));
206 0 : goto done;
207 : }
208 :
209 9 : status = pipe_bind_smb(torture, mem_ctx, cli->tree, "\\lsarpc",
210 : &ndr_table_lsarpc, &lsa_pipe);
211 9 : torture_assert_ntstatus_ok_goto(torture, status, ret, done,
212 : "pipe_bind_smb failed");
213 9 : lsa_handle = lsa_pipe->binding_handle;
214 :
215 9 : openpolicy.in.system_name =talloc_asprintf(
216 : mem_ctx, "\\\\%s", dcerpc_server_name(lsa_pipe));
217 9 : ZERO_STRUCT(objectattr);
218 9 : openpolicy.in.attr = &objectattr;
219 9 : openpolicy.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
220 9 : openpolicy.out.handle = &handle;
221 :
222 9 : status = dcerpc_lsa_OpenPolicy2_r(lsa_handle, mem_ctx, &openpolicy);
223 :
224 9 : if (!NT_STATUS_IS_OK(status)) {
225 0 : torture_comment(torture, "dcerpc_lsa_OpenPolicy2 failed: %s\n",
226 : nt_errstr(status));
227 0 : goto done;
228 : }
229 9 : if (!NT_STATUS_IS_OK(openpolicy.out.result)) {
230 0 : torture_comment(torture, "dcerpc_lsa_OpenPolicy2 failed: %s\n",
231 : nt_errstr(openpolicy.out.result));
232 0 : goto done;
233 : }
234 :
235 9 : close_handle.in.handle = &handle;
236 9 : close_handle.out.handle = &handle;
237 :
238 9 : status = dcerpc_lsa_Close_r(lsa_handle, mem_ctx, &close_handle);
239 9 : if (!NT_STATUS_IS_OK(status)) {
240 0 : torture_comment(torture, "dcerpc_lsa_Close failed: %s\n",
241 : nt_errstr(status));
242 0 : goto done;
243 : }
244 9 : if (!NT_STATUS_IS_OK(close_handle.out.result)) {
245 0 : torture_comment(torture, "dcerpc_lsa_Close failed: %s\n",
246 : nt_errstr(close_handle.out.result));
247 0 : goto done;
248 : }
249 :
250 9 : session2 = smbcli_session_init(cli->transport, mem_ctx, false, session_options);
251 9 : if (session2 == NULL) {
252 0 : torture_comment(torture, "smbcli_session_init failed\n");
253 0 : goto done;
254 : }
255 :
256 9 : if (!(anon_creds = cli_credentials_init_anon(mem_ctx))) {
257 0 : torture_comment(torture, "create_anon_creds failed\n");
258 0 : goto done;
259 : }
260 :
261 9 : setup.in.sesskey = cli->transport->negotiate.sesskey;
262 9 : setup.in.capabilities = cli->transport->negotiate.capabilities;
263 9 : setup.in.workgroup = "";
264 9 : setup.in.credentials = anon_creds;
265 9 : setup.in.gensec_settings = lpcfg_gensec_settings(torture, torture->lp_ctx);
266 :
267 9 : status = smb_composite_sesssetup(session2, &setup);
268 9 : if (!NT_STATUS_IS_OK(status)) {
269 0 : torture_comment(torture, "anon session setup failed: %s\n",
270 : nt_errstr(status));
271 0 : goto done;
272 : }
273 9 : session2->vuid = setup.out.vuid;
274 :
275 9 : tmp = cli->tree->session;
276 9 : tmp_vuid = smb1cli_session_current_id(tmp->smbXcli);
277 9 : smb1cli_session_set_id(tmp->smbXcli, session2->vuid);
278 9 : cli->tree->session = session2;
279 :
280 9 : status = dcerpc_lsa_OpenPolicy2_r(lsa_handle, mem_ctx, &openpolicy);
281 :
282 9 : torture_assert(torture, smbXcli_conn_is_connected(cli->transport->conn),
283 : "smb still connected");
284 9 : torture_assert(torture, !dcerpc_binding_handle_is_connected(lsa_handle),
285 : "dcerpc disonnected");
286 :
287 9 : if (NT_STATUS_EQUAL(status, NT_STATUS_INVALID_HANDLE)) {
288 0 : torture_comment(torture, "dcerpc_lsa_OpenPolicy2 with wrong vuid gave %s, "
289 : "expected NT_STATUS_CONNECTION_DISCONNECTED\n",
290 : nt_errstr(status));
291 0 : status = NT_STATUS_CONNECTION_DISCONNECTED;
292 : }
293 9 : if (NT_STATUS_EQUAL(status, NT_STATUS_IO_DEVICE_ERROR)) {
294 0 : torture_comment(torture, "dcerpc_lsa_OpenPolicy2 with wrong vuid gave %s, "
295 : "expected NT_STATUS_CONNECTION_DISCONNECTED\n",
296 : nt_errstr(status));
297 0 : status = NT_STATUS_CONNECTION_DISCONNECTED;
298 : }
299 :
300 9 : torture_assert_ntstatus_equal(torture, status, NT_STATUS_CONNECTION_DISCONNECTED,
301 : "lsa connection disconnected");
302 :
303 9 : smb1cli_session_set_id(tmp->smbXcli, tmp_vuid);
304 9 : cli->tree->session = tmp;
305 9 : talloc_free(lsa_pipe);
306 9 : lsa_pipe = NULL;
307 :
308 9 : ret = true;
309 9 : done:
310 9 : talloc_free(mem_ctx);
311 9 : return ret;
312 : }
313 :
314 : /*
315 : * Bind to lsa using a specific auth method
316 : */
317 :
318 0 : static bool bindtest(struct torture_context *tctx,
319 : struct smbcli_state *cli,
320 : struct cli_credentials *credentials,
321 : uint8_t auth_type, uint8_t auth_level)
322 : {
323 : TALLOC_CTX *mem_ctx;
324 0 : bool ret = false;
325 : NTSTATUS status;
326 :
327 : struct dcerpc_pipe *lsa_pipe;
328 : struct dcerpc_binding_handle *lsa_handle;
329 : struct lsa_ObjectAttribute objectattr;
330 : struct lsa_OpenPolicy2 openpolicy;
331 : struct lsa_QueryInfoPolicy query;
332 0 : union lsa_PolicyInformation *info = NULL;
333 : struct policy_handle handle;
334 : struct lsa_Close close_handle;
335 :
336 0 : if ((mem_ctx = talloc_init("bindtest")) == NULL) {
337 0 : torture_comment(tctx, "talloc_init failed\n");
338 0 : return false;
339 : }
340 :
341 0 : status = pipe_bind_smb_auth(tctx, mem_ctx, cli->tree,
342 : credentials, auth_type, auth_level,
343 : "\\lsarpc", &ndr_table_lsarpc, &lsa_pipe);
344 0 : torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
345 : "pipe_bind_smb_auth failed");
346 0 : lsa_handle = lsa_pipe->binding_handle;
347 :
348 0 : openpolicy.in.system_name =talloc_asprintf(
349 : mem_ctx, "\\\\%s", dcerpc_server_name(lsa_pipe));
350 0 : ZERO_STRUCT(objectattr);
351 0 : openpolicy.in.attr = &objectattr;
352 0 : openpolicy.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
353 0 : openpolicy.out.handle = &handle;
354 :
355 0 : status = dcerpc_lsa_OpenPolicy2_r(lsa_handle, mem_ctx, &openpolicy);
356 :
357 0 : if (!NT_STATUS_IS_OK(status)) {
358 0 : torture_comment(tctx, "dcerpc_lsa_OpenPolicy2 failed: %s\n",
359 : nt_errstr(status));
360 0 : goto done;
361 : }
362 0 : if (!NT_STATUS_IS_OK(openpolicy.out.result)) {
363 0 : torture_comment(tctx, "dcerpc_lsa_OpenPolicy2 failed: %s\n",
364 : nt_errstr(openpolicy.out.result));
365 0 : goto done;
366 : }
367 :
368 0 : query.in.handle = &handle;
369 0 : query.in.level = LSA_POLICY_INFO_DOMAIN;
370 0 : query.out.info = &info;
371 :
372 0 : status = dcerpc_lsa_QueryInfoPolicy_r(lsa_handle, mem_ctx, &query);
373 0 : if (!NT_STATUS_IS_OK(status)) {
374 0 : torture_comment(tctx, "dcerpc_lsa_QueryInfoPolicy failed: %s\n",
375 : nt_errstr(status));
376 0 : goto done;
377 : }
378 0 : if (!NT_STATUS_IS_OK(query.out.result)) {
379 0 : torture_comment(tctx, "dcerpc_lsa_QueryInfoPolicy failed: %s\n",
380 : nt_errstr(query.out.result));
381 0 : goto done;
382 : }
383 :
384 0 : close_handle.in.handle = &handle;
385 0 : close_handle.out.handle = &handle;
386 :
387 0 : status = dcerpc_lsa_Close_r(lsa_handle, mem_ctx, &close_handle);
388 0 : if (!NT_STATUS_IS_OK(status)) {
389 0 : torture_comment(tctx, "dcerpc_lsa_Close failed: %s\n",
390 : nt_errstr(status));
391 0 : goto done;
392 : }
393 0 : if (!NT_STATUS_IS_OK(close_handle.out.result)) {
394 0 : torture_comment(tctx, "dcerpc_lsa_Close failed: %s\n",
395 : nt_errstr(close_handle.out.result));
396 0 : goto done;
397 : }
398 :
399 :
400 0 : ret = true;
401 0 : done:
402 0 : talloc_free(mem_ctx);
403 0 : return ret;
404 : }
405 :
406 : /*
407 : * test authenticated RPC binds with the variants Samba3 does support
408 : */
409 :
410 0 : static bool torture_bind_samba3(struct torture_context *torture)
411 : {
412 : TALLOC_CTX *mem_ctx;
413 : NTSTATUS status;
414 0 : bool ret = false;
415 : struct smbcli_state *cli;
416 : struct smbcli_options options;
417 : struct smbcli_session_options session_options;
418 :
419 0 : mem_ctx = talloc_init("torture_bind_authcontext");
420 :
421 0 : if (mem_ctx == NULL) {
422 0 : torture_comment(torture, "talloc_init failed\n");
423 0 : return false;
424 : }
425 :
426 0 : lpcfg_smbcli_options(torture->lp_ctx, &options);
427 0 : lpcfg_smbcli_session_options(torture->lp_ctx, &session_options);
428 :
429 0 : status = smbcli_full_connection(mem_ctx, &cli,
430 : torture_setting_string(torture, "host", NULL),
431 : lpcfg_smb_ports(torture->lp_ctx),
432 : "IPC$", NULL,
433 : lpcfg_socket_options(torture->lp_ctx),
434 : samba_cmdline_get_creds(),
435 : lpcfg_resolve_context(torture->lp_ctx),
436 : torture->ev, &options, &session_options,
437 : lpcfg_gensec_settings(torture, torture->lp_ctx));
438 0 : if (!NT_STATUS_IS_OK(status)) {
439 0 : torture_comment(torture, "smbcli_full_connection failed: %s\n",
440 : nt_errstr(status));
441 0 : goto done;
442 : }
443 :
444 0 : ret = true;
445 :
446 0 : ret &= bindtest(torture, cli, samba_cmdline_get_creds(),
447 : DCERPC_AUTH_TYPE_NTLMSSP,
448 : DCERPC_AUTH_LEVEL_INTEGRITY);
449 0 : ret &= bindtest(torture, cli, samba_cmdline_get_creds(),
450 : DCERPC_AUTH_TYPE_NTLMSSP,
451 : DCERPC_AUTH_LEVEL_PRIVACY);
452 0 : ret &= bindtest(torture, cli, samba_cmdline_get_creds(),
453 : DCERPC_AUTH_TYPE_SPNEGO,
454 : DCERPC_AUTH_LEVEL_INTEGRITY);
455 0 : ret &= bindtest(torture, cli, samba_cmdline_get_creds(),
456 : DCERPC_AUTH_TYPE_SPNEGO,
457 : DCERPC_AUTH_LEVEL_PRIVACY);
458 :
459 0 : done:
460 0 : talloc_free(mem_ctx);
461 0 : return ret;
462 : }
463 :
464 : /*
465 : * Lookup or create a user and return all necessary info
466 : */
467 :
468 0 : static bool get_usr_handle(struct torture_context *tctx,
469 : struct smbcli_state *cli,
470 : TALLOC_CTX *mem_ctx,
471 : struct cli_credentials *admin_creds,
472 : uint8_t auth_type,
473 : uint8_t auth_level,
474 : const char *username,
475 : char **domain,
476 : struct dcerpc_pipe **result_pipe,
477 : struct policy_handle **result_handle,
478 : struct dom_sid **sid_p)
479 : {
480 : struct dcerpc_pipe *samr_pipe;
481 : struct dcerpc_binding_handle *samr_handle;
482 : NTSTATUS status;
483 : struct policy_handle conn_handle;
484 : struct policy_handle domain_handle;
485 : struct policy_handle *user_handle;
486 : struct samr_Connect2 conn;
487 : struct samr_EnumDomains enumdom;
488 0 : uint32_t resume_handle = 0;
489 0 : uint32_t num_entries = 0;
490 0 : struct samr_SamArray *sam = NULL;
491 : struct samr_LookupDomain l;
492 0 : struct dom_sid2 *sid = NULL;
493 : int dom_idx;
494 : struct lsa_String domain_name;
495 : struct lsa_String user_name;
496 : struct samr_OpenDomain o;
497 : struct samr_CreateUser2 c;
498 : uint32_t user_rid,access_granted;
499 :
500 0 : if (admin_creds != NULL) {
501 0 : status = pipe_bind_smb_auth(tctx, mem_ctx, cli->tree,
502 : admin_creds, auth_type, auth_level,
503 : "\\samr", &ndr_table_samr, &samr_pipe);
504 0 : torture_assert_ntstatus_ok(tctx, status, "pipe_bind_smb_auth failed");
505 : } else {
506 : /* We must have an authenticated SMB connection */
507 0 : status = pipe_bind_smb(tctx, mem_ctx, cli->tree,
508 : "\\samr", &ndr_table_samr, &samr_pipe);
509 0 : torture_assert_ntstatus_ok(tctx, status, "pipe_bind_smb_auth failed");
510 : }
511 : #if 0
512 : samr_pipe->conn->flags |= DCERPC_DEBUG_PRINT_IN | DCERPC_DEBUG_PRINT_OUT;
513 : #endif
514 0 : samr_handle = samr_pipe->binding_handle;
515 :
516 0 : conn.in.system_name = talloc_asprintf(
517 : mem_ctx, "\\\\%s", dcerpc_server_name(samr_pipe));
518 0 : conn.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
519 0 : conn.out.connect_handle = &conn_handle;
520 :
521 0 : torture_assert_ntstatus_ok(tctx,
522 : dcerpc_samr_Connect2_r(samr_handle, mem_ctx, &conn),
523 : "samr_Connect2 failed");
524 0 : torture_assert_ntstatus_ok(tctx, conn.out.result,
525 : "samr_Connect2 failed");
526 :
527 0 : enumdom.in.connect_handle = &conn_handle;
528 0 : enumdom.in.resume_handle = &resume_handle;
529 0 : enumdom.in.buf_size = (uint32_t)-1;
530 0 : enumdom.out.resume_handle = &resume_handle;
531 0 : enumdom.out.num_entries = &num_entries;
532 0 : enumdom.out.sam = &sam;
533 :
534 0 : torture_assert_ntstatus_ok(tctx,
535 : dcerpc_samr_EnumDomains_r(samr_handle, mem_ctx, &enumdom),
536 : "samr_EnumDomains failed");
537 0 : torture_assert_ntstatus_ok(tctx, enumdom.out.result,
538 : "samr_EnumDomains failed");
539 :
540 0 : torture_assert_int_equal(tctx, *enumdom.out.num_entries, 2,
541 : "samr_EnumDomains returned unexpected num_entries");
542 :
543 0 : dom_idx = strequal(sam->entries[0].name.string,
544 0 : "builtin") ? 1:0;
545 :
546 0 : l.in.connect_handle = &conn_handle;
547 0 : domain_name.string = sam->entries[dom_idx].name.string;
548 0 : *domain = talloc_strdup(mem_ctx, domain_name.string);
549 0 : l.in.domain_name = &domain_name;
550 0 : l.out.sid = &sid;
551 :
552 0 : torture_assert_ntstatus_ok(tctx,
553 : dcerpc_samr_LookupDomain_r(samr_handle, mem_ctx, &l),
554 : "samr_LookupDomain failed");
555 0 : torture_assert_ntstatus_ok(tctx, l.out.result,
556 : "samr_LookupDomain failed");
557 :
558 0 : o.in.connect_handle = &conn_handle;
559 0 : o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
560 0 : o.in.sid = *l.out.sid;
561 0 : o.out.domain_handle = &domain_handle;
562 :
563 0 : torture_assert_ntstatus_ok(tctx,
564 : dcerpc_samr_OpenDomain_r(samr_handle, mem_ctx, &o),
565 : "samr_OpenDomain failed");
566 0 : torture_assert_ntstatus_ok(tctx, o.out.result,
567 : "samr_OpenDomain failed");
568 :
569 0 : c.in.domain_handle = &domain_handle;
570 0 : user_name.string = username;
571 0 : c.in.account_name = &user_name;
572 0 : c.in.acct_flags = ACB_NORMAL;
573 0 : c.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
574 0 : user_handle = talloc(mem_ctx, struct policy_handle);
575 0 : c.out.user_handle = user_handle;
576 0 : c.out.access_granted = &access_granted;
577 0 : c.out.rid = &user_rid;
578 :
579 0 : torture_assert_ntstatus_ok(tctx,
580 : dcerpc_samr_CreateUser2_r(samr_handle, mem_ctx, &c),
581 : "samr_CreateUser2 failed");
582 :
583 0 : if (NT_STATUS_EQUAL(c.out.result, NT_STATUS_USER_EXISTS)) {
584 : struct samr_LookupNames ln;
585 : struct samr_OpenUser ou;
586 : struct samr_Ids rids, types;
587 :
588 0 : ln.in.domain_handle = &domain_handle;
589 0 : ln.in.num_names = 1;
590 0 : ln.in.names = &user_name;
591 0 : ln.out.rids = &rids;
592 0 : ln.out.types = &types;
593 :
594 0 : torture_assert_ntstatus_ok(tctx,
595 : dcerpc_samr_LookupNames_r(samr_handle, mem_ctx, &ln),
596 : "samr_LookupNames failed");
597 0 : torture_assert_ntstatus_ok(tctx, ln.out.result,
598 : "samr_LookupNames failed");
599 :
600 0 : ou.in.domain_handle = &domain_handle;
601 0 : ou.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
602 0 : user_rid = ou.in.rid = ln.out.rids->ids[0];
603 0 : ou.out.user_handle = user_handle;
604 :
605 0 : torture_assert_ntstatus_ok(tctx,
606 : dcerpc_samr_OpenUser_r(samr_handle, mem_ctx, &ou),
607 : "samr_OpenUser failed");
608 0 : status = ou.out.result;
609 : } else {
610 0 : status = c.out.result;
611 : }
612 :
613 0 : torture_assert_ntstatus_ok(tctx, status,
614 : "samr_CreateUser failed");
615 :
616 0 : *result_pipe = samr_pipe;
617 0 : *result_handle = user_handle;
618 0 : if (sid_p != NULL) {
619 0 : *sid_p = dom_sid_add_rid(mem_ctx, *l.out.sid, user_rid);
620 : }
621 0 : return true;
622 :
623 : }
624 :
625 : /*
626 : * Create a test user
627 : */
628 :
629 0 : static bool create_user(struct torture_context *tctx,
630 : TALLOC_CTX *mem_ctx, struct smbcli_state *cli,
631 : struct cli_credentials *admin_creds,
632 : const char *username, const char *password,
633 : char **domain_name,
634 : struct dom_sid **user_sid)
635 : {
636 : TALLOC_CTX *tmp_ctx;
637 : NTSTATUS status;
638 : struct dcerpc_pipe *samr_pipe;
639 : struct dcerpc_binding_handle *samr_handle;
640 : struct policy_handle *wks_handle;
641 0 : bool ret = false;
642 :
643 0 : if (!(tmp_ctx = talloc_new(mem_ctx))) {
644 0 : torture_comment(tctx, "talloc_init failed\n");
645 0 : return false;
646 : }
647 :
648 0 : ret = get_usr_handle(tctx, cli, tmp_ctx, admin_creds,
649 : DCERPC_AUTH_TYPE_NTLMSSP,
650 : DCERPC_AUTH_LEVEL_INTEGRITY,
651 : username, domain_name, &samr_pipe, &wks_handle,
652 : user_sid);
653 0 : if (ret == false) {
654 0 : torture_comment(tctx, "get_usr_handle failed\n");
655 0 : goto done;
656 : }
657 0 : samr_handle = samr_pipe->binding_handle;
658 :
659 : {
660 : struct samr_SetUserInfo2 sui2;
661 : struct samr_SetUserInfo sui;
662 : struct samr_QueryUserInfo qui;
663 : union samr_UserInfo u_info;
664 : union samr_UserInfo *info;
665 : DATA_BLOB session_key;
666 :
667 0 : ZERO_STRUCT(u_info);
668 0 : encode_pw_buffer(u_info.info23.password.data, password,
669 : STR_UNICODE);
670 :
671 0 : status = dcerpc_fetch_session_key(samr_pipe, &session_key);
672 0 : if (!NT_STATUS_IS_OK(status)) {
673 0 : torture_comment(tctx, "dcerpc_fetch_session_key failed\n");
674 0 : goto done;
675 : }
676 :
677 0 : status = init_samr_CryptPassword(password,
678 : &session_key,
679 : &u_info.info23.password);
680 0 : if (!NT_STATUS_IS_OK(status)) {
681 0 : torture_comment(tctx, "init_samr_CryptPassword failed\n");
682 0 : goto done;
683 : }
684 :
685 0 : u_info.info23.info.password_expired = 0;
686 0 : u_info.info23.info.fields_present = SAMR_FIELD_NT_PASSWORD_PRESENT |
687 : SAMR_FIELD_LM_PASSWORD_PRESENT |
688 : SAMR_FIELD_EXPIRED_FLAG;
689 0 : sui2.in.user_handle = wks_handle;
690 0 : sui2.in.info = &u_info;
691 0 : sui2.in.level = 23;
692 :
693 0 : status = dcerpc_samr_SetUserInfo2_r(samr_handle, tmp_ctx, &sui2);
694 0 : if (!NT_STATUS_IS_OK(status)) {
695 0 : torture_comment(tctx, "samr_SetUserInfo(23) failed: %s\n",
696 : nt_errstr(status));
697 0 : goto done;
698 : }
699 0 : if (!NT_STATUS_IS_OK(sui2.out.result)) {
700 0 : torture_comment(tctx, "samr_SetUserInfo(23) failed: %s\n",
701 : nt_errstr(sui2.out.result));
702 0 : goto done;
703 : }
704 :
705 0 : u_info.info16.acct_flags = ACB_NORMAL;
706 0 : sui.in.user_handle = wks_handle;
707 0 : sui.in.info = &u_info;
708 0 : sui.in.level = 16;
709 :
710 0 : status = dcerpc_samr_SetUserInfo_r(samr_handle, tmp_ctx, &sui);
711 0 : if (!NT_STATUS_IS_OK(status) || !NT_STATUS_IS_OK(sui.out.result)) {
712 0 : torture_comment(tctx, "samr_SetUserInfo(16) failed\n");
713 0 : goto done;
714 : }
715 :
716 0 : qui.in.user_handle = wks_handle;
717 0 : qui.in.level = 21;
718 0 : qui.out.info = &info;
719 :
720 0 : status = dcerpc_samr_QueryUserInfo_r(samr_handle, tmp_ctx, &qui);
721 0 : if (!NT_STATUS_IS_OK(status) || !NT_STATUS_IS_OK(qui.out.result)) {
722 0 : torture_comment(tctx, "samr_QueryUserInfo(21) failed\n");
723 0 : goto done;
724 : }
725 :
726 0 : info->info21.allow_password_change = 0;
727 0 : info->info21.force_password_change = 0;
728 0 : info->info21.account_name.string = NULL;
729 0 : info->info21.rid = 0;
730 0 : info->info21.acct_expiry = 0;
731 0 : info->info21.fields_present = 0x81827fa; /* copy usrmgr.exe */
732 :
733 0 : u_info.info21 = info->info21;
734 0 : sui.in.user_handle = wks_handle;
735 0 : sui.in.info = &u_info;
736 0 : sui.in.level = 21;
737 :
738 0 : status = dcerpc_samr_SetUserInfo_r(samr_handle, tmp_ctx, &sui);
739 0 : if (!NT_STATUS_IS_OK(status) || !NT_STATUS_IS_OK(sui.out.result)) {
740 0 : torture_comment(tctx, "samr_SetUserInfo(21) failed\n");
741 0 : goto done;
742 : }
743 : }
744 :
745 0 : *domain_name= talloc_steal(mem_ctx, *domain_name);
746 0 : *user_sid = talloc_steal(mem_ctx, *user_sid);
747 0 : ret = true;
748 0 : done:
749 0 : talloc_free(tmp_ctx);
750 0 : return ret;
751 : }
752 :
753 : /*
754 : * Delete a test user
755 : */
756 :
757 0 : static bool delete_user(struct torture_context *tctx,
758 : struct smbcli_state *cli,
759 : struct cli_credentials *admin_creds,
760 : const char *username)
761 : {
762 : TALLOC_CTX *mem_ctx;
763 : NTSTATUS status;
764 : char *dom_name;
765 : struct dcerpc_pipe *samr_pipe;
766 : struct dcerpc_binding_handle *samr_handle;
767 : struct policy_handle *user_handle;
768 0 : bool ret = false;
769 :
770 0 : if ((mem_ctx = talloc_init("leave")) == NULL) {
771 0 : torture_comment(tctx, "talloc_init failed\n");
772 0 : return false;
773 : }
774 :
775 0 : ret = get_usr_handle(tctx, cli, mem_ctx, admin_creds,
776 : DCERPC_AUTH_TYPE_NTLMSSP,
777 : DCERPC_AUTH_LEVEL_INTEGRITY,
778 : username, &dom_name, &samr_pipe,
779 : &user_handle, NULL);
780 0 : if (ret == false) {
781 0 : torture_comment(tctx, "get_wks_handle failed\n");
782 0 : goto done;
783 : }
784 0 : samr_handle = samr_pipe->binding_handle;
785 :
786 : {
787 : struct samr_DeleteUser d;
788 :
789 0 : d.in.user_handle = user_handle;
790 0 : d.out.user_handle = user_handle;
791 :
792 0 : status = dcerpc_samr_DeleteUser_r(samr_handle, mem_ctx, &d);
793 0 : if (!NT_STATUS_IS_OK(status)) {
794 0 : torture_comment(tctx, "samr_DeleteUser failed %s\n", nt_errstr(status));
795 0 : goto done;
796 : }
797 0 : if (!NT_STATUS_IS_OK(d.out.result)) {
798 0 : torture_comment(tctx, "samr_DeleteUser failed %s\n", nt_errstr(d.out.result));
799 0 : goto done;
800 : }
801 :
802 : }
803 :
804 0 : ret = true;
805 :
806 0 : done:
807 0 : talloc_free(mem_ctx);
808 0 : return ret;
809 : }
810 :
811 : /*
812 : * Do a Samba3-style join
813 : */
814 :
815 0 : static bool join3(struct torture_context *tctx,
816 : struct smbcli_state *cli,
817 : bool use_level25,
818 : struct cli_credentials *admin_creds,
819 : struct cli_credentials *wks_creds)
820 : {
821 : TALLOC_CTX *mem_ctx;
822 : NTSTATUS status;
823 : char *dom_name;
824 : struct dcerpc_pipe *samr_pipe;
825 : struct dcerpc_binding_handle *samr_handle;
826 : struct policy_handle *wks_handle;
827 0 : bool ret = false;
828 : NTTIME last_password_change;
829 :
830 0 : if ((mem_ctx = talloc_init("join3")) == NULL) {
831 0 : torture_comment(tctx, "talloc_init failed\n");
832 0 : return false;
833 : }
834 :
835 0 : ret = get_usr_handle(
836 : tctx, cli, mem_ctx, admin_creds,
837 : DCERPC_AUTH_TYPE_NTLMSSP,
838 : DCERPC_AUTH_LEVEL_PRIVACY,
839 0 : talloc_asprintf(mem_ctx, "%s$",
840 : cli_credentials_get_workstation(wks_creds)),
841 : &dom_name, &samr_pipe, &wks_handle, NULL);
842 0 : if (ret == false) {
843 0 : torture_comment(tctx, "get_wks_handle failed\n");
844 0 : goto done;
845 : }
846 0 : samr_handle = samr_pipe->binding_handle;
847 0 : ret = false;
848 : {
849 : struct samr_QueryUserInfo q;
850 : union samr_UserInfo *info;
851 :
852 0 : q.in.user_handle = wks_handle;
853 0 : q.in.level = 21;
854 0 : q.out.info = &info;
855 :
856 0 : status = dcerpc_samr_QueryUserInfo_r(samr_handle, mem_ctx, &q);
857 0 : if (!NT_STATUS_IS_OK(status)) {
858 0 : torture_warning(tctx, "QueryUserInfo failed: %s\n",
859 : nt_errstr(status));
860 0 : goto done;
861 : }
862 0 : if (!NT_STATUS_IS_OK(q.out.result)) {
863 0 : torture_warning(tctx, "QueryUserInfo failed: %s\n",
864 : nt_errstr(q.out.result));
865 0 : goto done;
866 : }
867 :
868 :
869 0 : last_password_change = info->info21.last_password_change;
870 : }
871 :
872 0 : cli_credentials_set_domain(wks_creds, dom_name, CRED_SPECIFIED);
873 :
874 0 : if (use_level25) {
875 : struct samr_SetUserInfo2 sui2;
876 : union samr_UserInfo u_info;
877 0 : struct samr_UserInfo21 *i21 = &u_info.info25.info;
878 : DATA_BLOB session_key;
879 :
880 0 : ZERO_STRUCT(u_info);
881 :
882 0 : i21->full_name.string = talloc_asprintf(
883 : mem_ctx, "%s$",
884 : cli_credentials_get_workstation(wks_creds));
885 0 : i21->acct_flags = ACB_WSTRUST;
886 0 : i21->fields_present = SAMR_FIELD_FULL_NAME |
887 : SAMR_FIELD_ACCT_FLAGS | SAMR_FIELD_NT_PASSWORD_PRESENT;
888 : /* this would break the test result expectations
889 : i21->fields_present |= SAMR_FIELD_EXPIRED_FLAG;
890 : i21->password_expired = 1;
891 : */
892 :
893 0 : status = dcerpc_fetch_session_key(samr_pipe, &session_key);
894 0 : if (!NT_STATUS_IS_OK(status)) {
895 0 : torture_comment(tctx, "dcerpc_fetch_session_key failed: %s\n",
896 : nt_errstr(status));
897 0 : goto done;
898 : }
899 :
900 0 : status = init_samr_CryptPasswordEx(cli_credentials_get_password(wks_creds),
901 : &session_key,
902 : &u_info.info25.password);
903 :
904 0 : sui2.in.user_handle = wks_handle;
905 0 : sui2.in.level = 25;
906 0 : sui2.in.info = &u_info;
907 :
908 0 : status = dcerpc_samr_SetUserInfo2_r(samr_handle, mem_ctx, &sui2);
909 0 : if (!NT_STATUS_IS_OK(status)) {
910 0 : torture_comment(tctx, "samr_SetUserInfo2(25) failed: %s\n",
911 : nt_errstr(status));
912 0 : goto done;
913 : }
914 0 : if (!NT_STATUS_IS_OK(sui2.out.result)) {
915 0 : torture_comment(tctx, "samr_SetUserInfo2(25) failed: %s\n",
916 : nt_errstr(sui2.out.result));
917 0 : goto done;
918 : }
919 : } else {
920 : struct samr_SetUserInfo2 sui2;
921 : struct samr_SetUserInfo sui;
922 : union samr_UserInfo u_info;
923 : DATA_BLOB session_key;
924 :
925 0 : encode_pw_buffer(u_info.info24.password.data,
926 : cli_credentials_get_password(wks_creds),
927 : STR_UNICODE);
928 : /* just to make this test pass */
929 0 : u_info.info24.password_expired = 1;
930 :
931 0 : status = dcerpc_fetch_session_key(samr_pipe, &session_key);
932 0 : if (!NT_STATUS_IS_OK(status)) {
933 0 : torture_comment(tctx, "dcerpc_fetch_session_key failed\n");
934 0 : goto done;
935 : }
936 :
937 0 : status = init_samr_CryptPassword(cli_credentials_get_password(wks_creds),
938 : &session_key,
939 : &u_info.info24.password);
940 :
941 0 : sui2.in.user_handle = wks_handle;
942 0 : sui2.in.info = &u_info;
943 0 : sui2.in.level = 24;
944 :
945 0 : status = dcerpc_samr_SetUserInfo2_r(samr_handle, mem_ctx, &sui2);
946 0 : if (!NT_STATUS_IS_OK(status)) {
947 0 : torture_comment(tctx, "samr_SetUserInfo(24) failed: %s\n",
948 : nt_errstr(status));
949 0 : goto done;
950 : }
951 0 : if (!NT_STATUS_IS_OK(sui2.out.result)) {
952 0 : torture_comment(tctx, "samr_SetUserInfo(24) failed: %s\n",
953 : nt_errstr(sui2.out.result));
954 0 : goto done;
955 : }
956 :
957 0 : u_info.info16.acct_flags = ACB_WSTRUST;
958 0 : sui.in.user_handle = wks_handle;
959 0 : sui.in.info = &u_info;
960 0 : sui.in.level = 16;
961 :
962 0 : status = dcerpc_samr_SetUserInfo_r(samr_handle, mem_ctx, &sui);
963 0 : if (!NT_STATUS_IS_OK(status) || !NT_STATUS_IS_OK(sui.out.result)) {
964 0 : torture_comment(tctx, "samr_SetUserInfo(16) failed\n");
965 0 : goto done;
966 : }
967 : }
968 :
969 : {
970 : struct samr_QueryUserInfo q;
971 : union samr_UserInfo *info;
972 :
973 0 : q.in.user_handle = wks_handle;
974 0 : q.in.level = 21;
975 0 : q.out.info = &info;
976 :
977 0 : status = dcerpc_samr_QueryUserInfo_r(samr_handle, mem_ctx, &q);
978 0 : if (!NT_STATUS_IS_OK(status)) {
979 0 : torture_warning(tctx, "QueryUserInfo failed: %s\n",
980 : nt_errstr(status));
981 0 : goto done;
982 : }
983 0 : if (!NT_STATUS_IS_OK(q.out.result)) {
984 0 : torture_warning(tctx, "QueryUserInfo failed: %s\n",
985 : nt_errstr(q.out.result));
986 0 : goto done;
987 : }
988 :
989 0 : if (use_level25) {
990 0 : if (last_password_change
991 0 : == info->info21.last_password_change) {
992 0 : torture_warning(tctx, "last_password_change unchanged "
993 : "during join, level25 must change "
994 : "it\n");
995 0 : goto done;
996 : }
997 : }
998 : else {
999 0 : if (last_password_change
1000 0 : != info->info21.last_password_change) {
1001 0 : torture_warning(tctx, "last_password_change changed "
1002 : "during join, level24 doesn't "
1003 : "change it\n");
1004 0 : goto done;
1005 : }
1006 : }
1007 : }
1008 :
1009 0 : ret = true;
1010 :
1011 0 : done:
1012 0 : talloc_free(mem_ctx);
1013 0 : return ret;
1014 : }
1015 :
1016 : /*
1017 : * Do a ReqChallenge/Auth2 and get the wks creds
1018 : */
1019 :
1020 0 : static bool auth2(struct torture_context *tctx,
1021 : struct smbcli_state *cli,
1022 : struct cli_credentials *wks_cred)
1023 : {
1024 : TALLOC_CTX *mem_ctx;
1025 : struct dcerpc_pipe *net_pipe;
1026 : struct dcerpc_binding_handle *net_handle;
1027 0 : bool result = false;
1028 : NTSTATUS status;
1029 : struct netr_ServerReqChallenge r;
1030 : struct netr_Credential netr_cli_creds;
1031 : struct netr_Credential netr_srv_creds;
1032 : uint32_t negotiate_flags;
1033 : struct netr_ServerAuthenticate2 a;
1034 : struct netlogon_creds_CredentialState *creds_state;
1035 : struct netr_Credential netr_cred;
1036 : struct samr_Password mach_pw;
1037 :
1038 0 : mem_ctx = talloc_new(NULL);
1039 0 : if (mem_ctx == NULL) {
1040 0 : torture_comment(tctx, "talloc_new failed\n");
1041 0 : return false;
1042 : }
1043 :
1044 0 : status = pipe_bind_smb(tctx, mem_ctx, cli->tree, "\\netlogon",
1045 : &ndr_table_netlogon, &net_pipe);
1046 0 : torture_assert_ntstatus_ok_goto(tctx, status, result, done,
1047 : "pipe_bind_smb failed");
1048 0 : net_handle = net_pipe->binding_handle;
1049 :
1050 0 : r.in.computer_name = cli_credentials_get_workstation(wks_cred);
1051 0 : r.in.server_name = talloc_asprintf(
1052 : mem_ctx, "\\\\%s", dcerpc_server_name(net_pipe));
1053 0 : if (r.in.server_name == NULL) {
1054 0 : torture_comment(tctx, "talloc_asprintf failed\n");
1055 0 : goto done;
1056 : }
1057 0 : generate_random_buffer(netr_cli_creds.data,
1058 : sizeof(netr_cli_creds.data));
1059 0 : r.in.credentials = &netr_cli_creds;
1060 0 : r.out.return_credentials = &netr_srv_creds;
1061 :
1062 0 : status = dcerpc_netr_ServerReqChallenge_r(net_handle, mem_ctx, &r);
1063 0 : if (!NT_STATUS_IS_OK(status)) {
1064 0 : torture_comment(tctx, "netr_ServerReqChallenge failed: %s\n",
1065 : nt_errstr(status));
1066 0 : goto done;
1067 : }
1068 0 : if (!NT_STATUS_IS_OK(r.out.result)) {
1069 0 : torture_comment(tctx, "netr_ServerReqChallenge failed: %s\n",
1070 : nt_errstr(r.out.result));
1071 0 : goto done;
1072 : }
1073 :
1074 0 : negotiate_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS | NETLOGON_NEG_SUPPORTS_AES;
1075 0 : E_md4hash(cli_credentials_get_password(wks_cred), mach_pw.hash);
1076 :
1077 0 : a.in.server_name = talloc_asprintf(
1078 : mem_ctx, "\\\\%s", dcerpc_server_name(net_pipe));
1079 0 : a.in.account_name = talloc_asprintf(
1080 : mem_ctx, "%s$", cli_credentials_get_workstation(wks_cred));
1081 0 : a.in.computer_name = cli_credentials_get_workstation(wks_cred);
1082 0 : a.in.secure_channel_type = SEC_CHAN_WKSTA;
1083 0 : a.in.negotiate_flags = &negotiate_flags;
1084 0 : a.out.negotiate_flags = &negotiate_flags;
1085 0 : a.in.credentials = &netr_cred;
1086 0 : a.out.return_credentials = &netr_cred;
1087 :
1088 0 : creds_state = netlogon_creds_client_init(mem_ctx,
1089 : a.in.account_name,
1090 : a.in.computer_name,
1091 0 : a.in.secure_channel_type,
1092 0 : r.in.credentials,
1093 0 : r.out.return_credentials, &mach_pw,
1094 : &netr_cred, negotiate_flags);
1095 0 : torture_assert(tctx, (creds_state != NULL), "memory allocation failed");
1096 :
1097 0 : status = dcerpc_netr_ServerAuthenticate2_r(net_handle, mem_ctx, &a);
1098 0 : if (!NT_STATUS_IS_OK(status)) {
1099 0 : torture_comment(tctx, "netr_ServerServerAuthenticate2 failed: %s\n",
1100 : nt_errstr(status));
1101 0 : goto done;
1102 : }
1103 0 : if (!NT_STATUS_IS_OK(a.out.result)) {
1104 0 : torture_comment(tctx, "netr_ServerServerAuthenticate2 failed: %s\n",
1105 : nt_errstr(a.out.result));
1106 0 : goto done;
1107 : }
1108 :
1109 0 : if (!netlogon_creds_client_check(creds_state, a.out.return_credentials)) {
1110 0 : torture_comment(tctx, "creds_client_check failed\n");
1111 0 : goto done;
1112 : }
1113 :
1114 0 : cli_credentials_set_netlogon_creds(wks_cred, creds_state);
1115 :
1116 0 : result = true;
1117 :
1118 0 : done:
1119 0 : talloc_free(mem_ctx);
1120 0 : return result;
1121 : }
1122 :
1123 : /*
1124 : * Do a couple of schannel protected Netlogon ops: Interactive and Network
1125 : * login, and change the wks password
1126 : */
1127 :
1128 0 : static bool schan(struct torture_context *tctx,
1129 : struct smbcli_state *cli,
1130 : struct cli_credentials *wks_creds,
1131 : struct cli_credentials *user_creds)
1132 : {
1133 : TALLOC_CTX *mem_ctx;
1134 : NTSTATUS status;
1135 0 : bool ret = false;
1136 : struct dcerpc_pipe *net_pipe;
1137 : struct dcerpc_binding_handle *net_handle;
1138 : int i;
1139 :
1140 0 : mem_ctx = talloc_new(NULL);
1141 0 : if (mem_ctx == NULL) {
1142 0 : torture_comment(tctx, "talloc_new failed\n");
1143 0 : return false;
1144 : }
1145 :
1146 : #if 1
1147 0 : status = pipe_bind_smb_auth(tctx, mem_ctx, cli->tree,
1148 : wks_creds,
1149 : DCERPC_AUTH_TYPE_SCHANNEL,
1150 : DCERPC_AUTH_LEVEL_PRIVACY,
1151 : "\\netlogon", &ndr_table_netlogon, &net_pipe);
1152 0 : torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
1153 : "pipe_bind_smb_auth failed");
1154 0 : net_pipe->conn->flags |= (DCERPC_SIGN | DCERPC_SEAL);
1155 : #else
1156 : status = pipe_bind_smb(tctx, mem_ctx, cli->tree,
1157 : "\\netlogon", &ndr_table_netlogon, &net_pipe);
1158 : torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
1159 : "pipe_bind_smb failed");
1160 : #endif
1161 : #if 0
1162 : net_pipe->conn->flags |= DCERPC_DEBUG_PRINT_IN |
1163 : DCERPC_DEBUG_PRINT_OUT;
1164 : #endif
1165 0 : net_handle = net_pipe->binding_handle;
1166 :
1167 :
1168 0 : for (i=2; i<4; i++) {
1169 : int flags;
1170 : DATA_BLOB chal, nt_resp, lm_resp, names_blob;
1171 : struct netlogon_creds_CredentialState *creds_state;
1172 : struct netr_Authenticator netr_auth, netr_auth2;
1173 : struct netr_NetworkInfo ninfo;
1174 : struct netr_PasswordInfo pinfo;
1175 : struct netr_LogonSamLogon r;
1176 : union netr_LogonLevel logon;
1177 : union netr_Validation validation;
1178 : uint8_t authoritative;
1179 : struct netr_Authenticator return_authenticator;
1180 :
1181 0 : flags = CLI_CRED_LANMAN_AUTH | CLI_CRED_NTLM_AUTH |
1182 : CLI_CRED_NTLMv2_AUTH;
1183 :
1184 0 : chal = data_blob_talloc(mem_ctx, NULL, 8);
1185 0 : if (chal.data == NULL) {
1186 0 : torture_comment(tctx, "data_blob_talloc failed\n");
1187 0 : goto done;
1188 : }
1189 :
1190 0 : generate_random_buffer(chal.data, chal.length);
1191 0 : names_blob = NTLMv2_generate_names_blob(
1192 : mem_ctx,
1193 : cli_credentials_get_workstation(wks_creds),
1194 : cli_credentials_get_domain(wks_creds));
1195 0 : status = cli_credentials_get_ntlm_response(
1196 : user_creds, mem_ctx, &flags, chal, NULL, names_blob,
1197 : &lm_resp, &nt_resp, NULL, NULL);
1198 0 : if (!NT_STATUS_IS_OK(status)) {
1199 0 : torture_comment(tctx, "cli_credentials_get_ntlm_response failed:"
1200 : " %s\n", nt_errstr(status));
1201 0 : goto done;
1202 : }
1203 :
1204 0 : creds_state = cli_credentials_get_netlogon_creds(wks_creds);
1205 0 : netlogon_creds_client_authenticator(creds_state, &netr_auth);
1206 :
1207 0 : ninfo.identity_info.account_name.string =
1208 0 : cli_credentials_get_username(user_creds);
1209 0 : ninfo.identity_info.domain_name.string =
1210 0 : cli_credentials_get_domain(user_creds);
1211 0 : ninfo.identity_info.parameter_control = 0;
1212 0 : ninfo.identity_info.logon_id = 0;
1213 0 : ninfo.identity_info.workstation.string =
1214 0 : cli_credentials_get_workstation(user_creds);
1215 0 : memcpy(ninfo.challenge, chal.data, sizeof(ninfo.challenge));
1216 0 : ninfo.nt.length = nt_resp.length;
1217 0 : ninfo.nt.data = nt_resp.data;
1218 0 : ninfo.lm.length = lm_resp.length;
1219 0 : ninfo.lm.data = lm_resp.data;
1220 :
1221 0 : logon.network = &ninfo;
1222 :
1223 0 : r.in.server_name = talloc_asprintf(
1224 : mem_ctx, "\\\\%s", dcerpc_server_name(net_pipe));
1225 0 : ZERO_STRUCT(netr_auth2);
1226 0 : r.in.computer_name =
1227 0 : cli_credentials_get_workstation(wks_creds);
1228 0 : r.in.credential = &netr_auth;
1229 0 : r.in.return_authenticator = &netr_auth2;
1230 0 : r.in.logon_level = NetlogonNetworkInformation;
1231 0 : r.in.validation_level = i;
1232 0 : r.in.logon = &logon;
1233 0 : r.out.validation = &validation;
1234 0 : r.out.authoritative = &authoritative;
1235 0 : r.out.return_authenticator = &return_authenticator;
1236 :
1237 0 : status = dcerpc_netr_LogonSamLogon_r(net_handle, mem_ctx, &r);
1238 0 : if (!NT_STATUS_IS_OK(status)) {
1239 0 : torture_comment(tctx, "netr_LogonSamLogon failed: %s\n",
1240 : nt_errstr(status));
1241 0 : goto done;
1242 : }
1243 0 : if (!NT_STATUS_IS_OK(r.out.result)) {
1244 0 : torture_comment(tctx, "netr_LogonSamLogon failed: %s\n",
1245 : nt_errstr(r.out.result));
1246 0 : goto done;
1247 : }
1248 :
1249 0 : if ((r.out.return_authenticator == NULL) ||
1250 0 : (!netlogon_creds_client_check(creds_state,
1251 0 : &r.out.return_authenticator->cred))) {
1252 0 : torture_comment(tctx, "Credentials check failed!\n");
1253 0 : goto done;
1254 : }
1255 :
1256 0 : netlogon_creds_client_authenticator(creds_state, &netr_auth);
1257 :
1258 0 : pinfo.identity_info = ninfo.identity_info;
1259 0 : ZERO_STRUCT(pinfo.lmpassword.hash);
1260 0 : E_md4hash(cli_credentials_get_password(user_creds),
1261 : pinfo.ntpassword.hash);
1262 :
1263 0 : logon.password = &pinfo;
1264 :
1265 : /*
1266 : * We don't use this here:
1267 : *
1268 : * netlogon_creds_encrypt_samlogon_logon(creds_state,
1269 : * NetlogonInteractiveInformation,
1270 : * &logon);
1271 : *
1272 : * in order to detect bugs
1273 : */
1274 0 : netlogon_creds_aes_encrypt(creds_state, pinfo.ntpassword.hash, 16);
1275 :
1276 0 : r.in.logon_level = NetlogonInteractiveInformation;
1277 0 : r.in.logon = &logon;
1278 0 : r.out.return_authenticator = &return_authenticator;
1279 :
1280 0 : status = dcerpc_netr_LogonSamLogon_r(net_handle, mem_ctx, &r);
1281 0 : if (!NT_STATUS_IS_OK(status)) {
1282 0 : torture_comment(tctx, "netr_LogonSamLogon failed: %s\n",
1283 : nt_errstr(status));
1284 0 : goto done;
1285 : }
1286 0 : if (!NT_STATUS_IS_OK(r.out.result)) {
1287 0 : torture_comment(tctx, "netr_LogonSamLogon failed: %s\n",
1288 : nt_errstr(r.out.result));
1289 0 : goto done;
1290 : }
1291 :
1292 0 : if ((r.out.return_authenticator == NULL) ||
1293 0 : (!netlogon_creds_client_check(creds_state,
1294 0 : &r.out.return_authenticator->cred))) {
1295 0 : torture_comment(tctx, "Credentials check failed!\n");
1296 0 : goto done;
1297 : }
1298 : }
1299 :
1300 : {
1301 : struct netr_ServerPasswordSet s;
1302 0 : char *password = generate_random_password(wks_creds, 8, 255);
1303 : struct netlogon_creds_CredentialState *creds_state;
1304 : struct netr_Authenticator credential, return_authenticator;
1305 : struct samr_Password new_password;
1306 :
1307 0 : s.in.server_name = talloc_asprintf(
1308 : mem_ctx, "\\\\%s", dcerpc_server_name(net_pipe));
1309 0 : s.in.computer_name = cli_credentials_get_workstation(wks_creds);
1310 0 : s.in.account_name = talloc_asprintf(
1311 : mem_ctx, "%s$", s.in.computer_name);
1312 0 : s.in.secure_channel_type = SEC_CHAN_WKSTA;
1313 0 : s.in.credential = &credential;
1314 0 : s.in.new_password = &new_password;
1315 0 : s.out.return_authenticator = &return_authenticator;
1316 :
1317 0 : E_md4hash(password, new_password.hash);
1318 :
1319 0 : creds_state = cli_credentials_get_netlogon_creds(wks_creds);
1320 0 : netlogon_creds_des_encrypt(creds_state, &new_password);
1321 0 : netlogon_creds_client_authenticator(creds_state, &credential);
1322 :
1323 0 : status = dcerpc_netr_ServerPasswordSet_r(net_handle, mem_ctx, &s);
1324 0 : if (!NT_STATUS_IS_OK(status)) {
1325 0 : torture_comment(tctx, "ServerPasswordSet - %s\n", nt_errstr(status));
1326 0 : goto done;
1327 : }
1328 0 : if (!NT_STATUS_IS_OK(s.out.result)) {
1329 0 : torture_comment(tctx, "ServerPasswordSet - %s\n", nt_errstr(s.out.result));
1330 0 : goto done;
1331 : }
1332 :
1333 0 : if (!netlogon_creds_client_check(creds_state,
1334 0 : &s.out.return_authenticator->cred)) {
1335 0 : torture_comment(tctx, "Credential chaining failed\n");
1336 : }
1337 :
1338 0 : cli_credentials_set_password(wks_creds, password,
1339 : CRED_SPECIFIED);
1340 : }
1341 :
1342 0 : ret = true;
1343 0 : done:
1344 0 : talloc_free(mem_ctx);
1345 0 : return ret;
1346 : }
1347 :
1348 : /*
1349 : * Delete the wks account again
1350 : */
1351 :
1352 0 : static bool leave(struct torture_context *tctx,
1353 : struct smbcli_state *cli,
1354 : struct cli_credentials *admin_creds,
1355 : struct cli_credentials *wks_creds)
1356 : {
1357 0 : char *wks_name = talloc_asprintf(
1358 : NULL, "%s$", cli_credentials_get_workstation(wks_creds));
1359 : bool ret;
1360 :
1361 0 : ret = delete_user(tctx, cli, admin_creds, wks_name);
1362 0 : talloc_free(wks_name);
1363 0 : return ret;
1364 : }
1365 :
1366 : /*
1367 : * Test the Samba3 DC code a bit. Join, do some schan netlogon ops, leave
1368 : */
1369 :
1370 0 : static bool torture_netlogon_samba3(struct torture_context *torture)
1371 : {
1372 : NTSTATUS status;
1373 : struct smbcli_state *cli;
1374 : struct cli_credentials *wks_creds;
1375 : const char *wks_name;
1376 : int i;
1377 : struct smbcli_options options;
1378 : struct smbcli_session_options session_options;
1379 :
1380 0 : wks_name = torture_setting_string(torture, "wksname", NULL);
1381 0 : torture_assert(torture, wks_name != NULL, "wksname not set");
1382 :
1383 0 : lpcfg_smbcli_options(torture->lp_ctx, &options);
1384 0 : lpcfg_smbcli_session_options(torture->lp_ctx, &session_options);
1385 :
1386 0 : status = smbcli_full_connection(torture, &cli,
1387 : torture_setting_string(torture, "host", NULL),
1388 : lpcfg_smb_ports(torture->lp_ctx),
1389 : "IPC$", NULL,
1390 : lpcfg_socket_options(torture->lp_ctx),
1391 : samba_cmdline_get_creds(),
1392 : lpcfg_resolve_context(torture->lp_ctx),
1393 : torture->ev, &options, &session_options,
1394 : lpcfg_gensec_settings(torture, torture->lp_ctx));
1395 0 : torture_assert_ntstatus_ok(torture, status, "smbcli_full_connection failed\n");
1396 :
1397 0 : wks_creds = cli_credentials_init(torture);
1398 0 : if (wks_creds == NULL) {
1399 0 : torture_fail(torture, "cli_credentials_init failed\n");
1400 : }
1401 :
1402 0 : cli_credentials_set_conf(wks_creds, torture->lp_ctx);
1403 0 : cli_credentials_set_secure_channel_type(wks_creds, SEC_CHAN_WKSTA);
1404 0 : cli_credentials_set_username(wks_creds, wks_name, CRED_SPECIFIED);
1405 0 : cli_credentials_set_workstation(wks_creds, wks_name, CRED_SPECIFIED);
1406 0 : cli_credentials_set_password(wks_creds,
1407 0 : generate_random_password(wks_creds, 8, 255),
1408 : CRED_SPECIFIED);
1409 :
1410 0 : torture_assert(torture,
1411 : join3(torture, cli, false, NULL, wks_creds),
1412 : "join failed");
1413 :
1414 0 : cli_credentials_set_domain(
1415 : samba_cmdline_get_creds(),
1416 : cli_credentials_get_domain(wks_creds),
1417 : CRED_SPECIFIED);
1418 :
1419 0 : for (i=0; i<2; i++) {
1420 :
1421 : /* Do this more than once, the routine "schan" changes
1422 : * the workstation password using the netlogon
1423 : * password change routine */
1424 :
1425 : int j;
1426 :
1427 0 : torture_assert(torture,
1428 : auth2(torture, cli, wks_creds),
1429 : "auth2 failed");
1430 :
1431 0 : for (j=0; j<2; j++) {
1432 0 : torture_assert(torture,
1433 : schan(torture, cli, wks_creds,
1434 : samba_cmdline_get_creds()),
1435 : "schan failed");
1436 : }
1437 : }
1438 :
1439 0 : torture_assert(torture,
1440 : leave(torture, cli, NULL, wks_creds),
1441 : "leave failed");
1442 :
1443 0 : return true;
1444 : }
1445 :
1446 : /*
1447 : * Do a simple join, testjoin and leave using specified smb and samr
1448 : * credentials
1449 : */
1450 :
1451 0 : static bool test_join3(struct torture_context *tctx,
1452 : bool use_level25,
1453 : struct cli_credentials *smb_creds,
1454 : struct cli_credentials *samr_creds,
1455 : const char *wks_name)
1456 : {
1457 : NTSTATUS status;
1458 : struct smbcli_state *cli;
1459 : struct cli_credentials *wks_creds;
1460 : struct smbcli_options options;
1461 : struct smbcli_session_options session_options;
1462 :
1463 0 : lpcfg_smbcli_options(tctx->lp_ctx, &options);
1464 0 : lpcfg_smbcli_session_options(tctx->lp_ctx, &session_options);
1465 :
1466 0 : status = smbcli_full_connection(tctx, &cli,
1467 : torture_setting_string(tctx, "host", NULL),
1468 : lpcfg_smb_ports(tctx->lp_ctx),
1469 : "IPC$", NULL, lpcfg_socket_options(tctx->lp_ctx),
1470 : smb_creds, lpcfg_resolve_context(tctx->lp_ctx),
1471 : tctx->ev, &options, &session_options,
1472 : lpcfg_gensec_settings(tctx, tctx->lp_ctx));
1473 0 : torture_assert_ntstatus_ok(tctx, status,
1474 : "smbcli_full_connection failed");
1475 :
1476 0 : wks_creds = cli_credentials_init(cli);
1477 0 : torture_assert(tctx, wks_creds, "cli_credentials_init failed");
1478 :
1479 0 : cli_credentials_set_conf(wks_creds, tctx->lp_ctx);
1480 0 : cli_credentials_set_secure_channel_type(wks_creds, SEC_CHAN_WKSTA);
1481 0 : cli_credentials_set_username(wks_creds, wks_name, CRED_SPECIFIED);
1482 0 : cli_credentials_set_workstation(wks_creds, wks_name, CRED_SPECIFIED);
1483 0 : cli_credentials_set_password(wks_creds,
1484 0 : generate_random_password(wks_creds, 8, 255),
1485 : CRED_SPECIFIED);
1486 :
1487 0 : torture_assert(tctx,
1488 : join3(tctx, cli, use_level25, samr_creds, wks_creds),
1489 : "join failed");
1490 :
1491 0 : cli_credentials_set_domain(
1492 : samba_cmdline_get_creds(),
1493 : cli_credentials_get_domain(wks_creds),
1494 : CRED_SPECIFIED);
1495 :
1496 0 : torture_assert(tctx,
1497 : auth2(tctx, cli, wks_creds),
1498 : "auth2 failed");
1499 :
1500 0 : torture_assert(tctx,
1501 : leave(tctx, cli, samr_creds, wks_creds),
1502 : "leave failed");
1503 :
1504 0 : talloc_free(cli);
1505 :
1506 0 : return true;
1507 : }
1508 :
1509 : /*
1510 : * Test the different session key variants. Do it by joining, this uses the
1511 : * session key in the setpassword routine. Test the join by doing the auth2.
1512 : */
1513 :
1514 0 : static bool torture_samba3_sessionkey(struct torture_context *torture)
1515 : {
1516 : struct cli_credentials *anon_creds;
1517 : const char *wks_name;
1518 :
1519 :
1520 0 : wks_name = torture_setting_string(torture, "wksname", NULL);
1521 0 : torture_assert(torture, wks_name != NULL, "wksname not set");
1522 :
1523 0 : if (!(anon_creds = cli_credentials_init_anon(torture))) {
1524 0 : torture_fail(torture, "create_anon_creds failed\n");
1525 : }
1526 :
1527 0 : cli_credentials_set_workstation(anon_creds, wks_name, CRED_SPECIFIED);
1528 :
1529 :
1530 0 : if (!torture_setting_bool(torture, "samba3", false)) {
1531 :
1532 : /* Samba3 in the build farm right now does this happily. Need
1533 : * to fix :-) */
1534 :
1535 0 : if (test_join3(torture, false, anon_creds, NULL, wks_name)) {
1536 0 : torture_fail(torture, "join using anonymous bind on an anonymous smb "
1537 : "connection succeeded -- HUH??\n");
1538 : }
1539 : }
1540 :
1541 0 : torture_assert(torture,
1542 : test_join3(torture, false, samba_cmdline_get_creds(),
1543 : NULL, wks_name),
1544 : "join using anonymous bind on an authenticated smb connection failed");
1545 :
1546 : /*
1547 : * The following two are tests for setuserinfolevel 25
1548 : */
1549 :
1550 0 : torture_assert(torture,
1551 : test_join3(torture, true, samba_cmdline_get_creds(),
1552 : NULL, wks_name),
1553 : "join using anonymous bind on an authenticated smb connection failed");
1554 :
1555 0 : return true;
1556 : }
1557 :
1558 : /*
1559 : * Sane wrapper around lsa_LookupNames
1560 : */
1561 :
1562 0 : static struct dom_sid *name2sid(struct torture_context *tctx,
1563 : TALLOC_CTX *mem_ctx,
1564 : struct dcerpc_pipe *p,
1565 : const char *name,
1566 : const char *domain)
1567 : {
1568 : struct lsa_ObjectAttribute attr;
1569 : struct lsa_QosInfo qos;
1570 : struct lsa_OpenPolicy2 r;
1571 : struct lsa_Close c;
1572 : NTSTATUS status;
1573 : struct policy_handle handle;
1574 : struct lsa_LookupNames l;
1575 : struct lsa_TransSidArray sids;
1576 0 : struct lsa_RefDomainList *domains = NULL;
1577 : struct lsa_String lsa_name;
1578 0 : uint32_t count = 0;
1579 : struct dom_sid *result;
1580 : TALLOC_CTX *tmp_ctx;
1581 0 : struct dcerpc_binding_handle *b = p->binding_handle;
1582 :
1583 0 : if (!(tmp_ctx = talloc_new(mem_ctx))) {
1584 0 : return NULL;
1585 : }
1586 :
1587 0 : qos.len = 0;
1588 0 : qos.impersonation_level = 2;
1589 0 : qos.context_mode = 1;
1590 0 : qos.effective_only = 0;
1591 :
1592 0 : attr.len = 0;
1593 0 : attr.root_dir = NULL;
1594 0 : attr.object_name = NULL;
1595 0 : attr.attributes = 0;
1596 0 : attr.sec_desc = NULL;
1597 0 : attr.sec_qos = &qos;
1598 :
1599 0 : r.in.system_name = "\\";
1600 0 : r.in.attr = &attr;
1601 0 : r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1602 0 : r.out.handle = &handle;
1603 :
1604 0 : status = dcerpc_lsa_OpenPolicy2_r(b, tmp_ctx, &r);
1605 0 : if (!NT_STATUS_IS_OK(status)) {
1606 0 : torture_comment(tctx, "OpenPolicy2 failed - %s\n", nt_errstr(status));
1607 0 : talloc_free(tmp_ctx);
1608 0 : return NULL;
1609 : }
1610 0 : if (!NT_STATUS_IS_OK(r.out.result)) {
1611 0 : torture_comment(tctx, "OpenPolicy2 failed - %s\n", nt_errstr(r.out.result));
1612 0 : talloc_free(tmp_ctx);
1613 0 : return NULL;
1614 : }
1615 :
1616 0 : sids.count = 0;
1617 0 : sids.sids = NULL;
1618 :
1619 0 : lsa_name.string = talloc_asprintf(tmp_ctx, "%s\\%s", domain, name);
1620 :
1621 0 : l.in.handle = &handle;
1622 0 : l.in.num_names = 1;
1623 0 : l.in.names = &lsa_name;
1624 0 : l.in.sids = &sids;
1625 0 : l.in.level = 1;
1626 0 : l.in.count = &count;
1627 0 : l.out.count = &count;
1628 0 : l.out.sids = &sids;
1629 0 : l.out.domains = &domains;
1630 :
1631 0 : status = dcerpc_lsa_LookupNames_r(b, tmp_ctx, &l);
1632 0 : if (!NT_STATUS_IS_OK(status)) {
1633 0 : torture_comment(tctx, "LookupNames of %s failed - %s\n", lsa_name.string,
1634 : nt_errstr(status));
1635 0 : talloc_free(tmp_ctx);
1636 0 : return NULL;
1637 : }
1638 0 : if (!NT_STATUS_IS_OK(l.out.result)) {
1639 0 : torture_comment(tctx, "LookupNames of %s failed - %s\n", lsa_name.string,
1640 : nt_errstr(l.out.result));
1641 0 : talloc_free(tmp_ctx);
1642 0 : return NULL;
1643 : }
1644 :
1645 0 : result = dom_sid_add_rid(mem_ctx, domains->domains[0].sid,
1646 0 : l.out.sids->sids[0].rid);
1647 :
1648 0 : c.in.handle = &handle;
1649 0 : c.out.handle = &handle;
1650 :
1651 0 : status = dcerpc_lsa_Close_r(b, tmp_ctx, &c);
1652 0 : if (!NT_STATUS_IS_OK(status)) {
1653 0 : torture_comment(tctx, "dcerpc_lsa_Close failed - %s\n", nt_errstr(status));
1654 0 : talloc_free(tmp_ctx);
1655 0 : return NULL;
1656 : }
1657 0 : if (!NT_STATUS_IS_OK(c.out.result)) {
1658 0 : torture_comment(tctx, "dcerpc_lsa_Close failed - %s\n", nt_errstr(c.out.result));
1659 0 : talloc_free(tmp_ctx);
1660 0 : return NULL;
1661 : }
1662 :
1663 0 : talloc_free(tmp_ctx);
1664 0 : return result;
1665 : }
1666 :
1667 : /*
1668 : * Find out the user SID on this connection
1669 : */
1670 :
1671 0 : static struct dom_sid *whoami(struct torture_context *tctx,
1672 : TALLOC_CTX *mem_ctx,
1673 : struct smbcli_tree *tree)
1674 : {
1675 : struct dcerpc_pipe *lsa;
1676 : struct dcerpc_binding_handle *lsa_handle;
1677 : struct lsa_GetUserName r;
1678 : NTSTATUS status;
1679 0 : struct lsa_String *authority_name_p = NULL;
1680 0 : struct lsa_String *account_name_p = NULL;
1681 : struct dom_sid *result;
1682 :
1683 0 : status = pipe_bind_smb(tctx, mem_ctx, tree, "\\pipe\\lsarpc",
1684 : &ndr_table_lsarpc, &lsa);
1685 0 : if (!NT_STATUS_IS_OK(status)) {
1686 0 : torture_warning(tctx, "Could not bind to LSA: %s\n",
1687 : nt_errstr(status));
1688 0 : return NULL;
1689 : }
1690 0 : lsa_handle = lsa->binding_handle;
1691 :
1692 0 : r.in.system_name = "\\";
1693 0 : r.in.account_name = &account_name_p;
1694 0 : r.in.authority_name = &authority_name_p;
1695 0 : r.out.account_name = &account_name_p;
1696 :
1697 0 : status = dcerpc_lsa_GetUserName_r(lsa_handle, mem_ctx, &r);
1698 :
1699 0 : authority_name_p = *r.out.authority_name;
1700 :
1701 0 : if (!NT_STATUS_IS_OK(status)) {
1702 0 : torture_warning(tctx, "GetUserName failed - %s\n",
1703 : nt_errstr(status));
1704 0 : talloc_free(lsa);
1705 0 : return NULL;
1706 : }
1707 0 : if (!NT_STATUS_IS_OK(r.out.result)) {
1708 0 : torture_warning(tctx, "GetUserName failed - %s\n",
1709 : nt_errstr(r.out.result));
1710 0 : talloc_free(lsa);
1711 0 : return NULL;
1712 : }
1713 :
1714 0 : result = name2sid(tctx, mem_ctx, lsa, account_name_p->string,
1715 0 : authority_name_p->string);
1716 :
1717 0 : talloc_free(lsa);
1718 0 : return result;
1719 : }
1720 :
1721 0 : static int destroy_tree(struct smbcli_tree *tree)
1722 : {
1723 0 : smb_tree_disconnect(tree);
1724 0 : return 0;
1725 : }
1726 :
1727 : /*
1728 : * Do a tcon, given a session
1729 : */
1730 :
1731 0 : static NTSTATUS secondary_tcon(struct torture_context *tctx,
1732 : TALLOC_CTX *mem_ctx,
1733 : struct smbcli_session *session,
1734 : const char *sharename,
1735 : struct smbcli_tree **res)
1736 : {
1737 : struct smbcli_tree *result;
1738 : TALLOC_CTX *tmp_ctx;
1739 : union smb_tcon tcon;
1740 : NTSTATUS status;
1741 :
1742 0 : if (!(tmp_ctx = talloc_new(mem_ctx))) {
1743 0 : return NT_STATUS_NO_MEMORY;
1744 : }
1745 :
1746 0 : if (!(result = smbcli_tree_init(session, mem_ctx, false))) {
1747 0 : talloc_free(tmp_ctx);
1748 0 : return NT_STATUS_NO_MEMORY;
1749 : }
1750 :
1751 0 : tcon.generic.level = RAW_TCON_TCONX;
1752 0 : tcon.tconx.in.flags = TCONX_FLAG_EXTENDED_RESPONSE;
1753 0 : tcon.tconx.in.flags |= TCONX_FLAG_EXTENDED_SIGNATURES;
1754 0 : tcon.tconx.in.password = data_blob(NULL, 0);
1755 0 : tcon.tconx.in.path = sharename;
1756 0 : tcon.tconx.in.device = "?????";
1757 :
1758 0 : status = smb_raw_tcon(result, tmp_ctx, &tcon);
1759 0 : if (!NT_STATUS_IS_OK(status)) {
1760 0 : torture_warning(tctx, "smb_raw_tcon failed: %s\n",
1761 : nt_errstr(status));
1762 0 : talloc_free(tmp_ctx);
1763 0 : return status;
1764 : }
1765 :
1766 0 : result->tid = tcon.tconx.out.tid;
1767 :
1768 0 : if (tcon.tconx.out.options & SMB_EXTENDED_SIGNATURES) {
1769 0 : smb1cli_session_protect_session_key(result->session->smbXcli);
1770 : }
1771 :
1772 0 : result = talloc_steal(mem_ctx, result);
1773 0 : talloc_set_destructor(result, destroy_tree);
1774 0 : talloc_free(tmp_ctx);
1775 0 : *res = result;
1776 0 : return NT_STATUS_OK;
1777 : }
1778 :
1779 : /*
1780 : * Test the getusername behaviour
1781 : */
1782 :
1783 0 : static bool torture_samba3_rpc_getusername(struct torture_context *torture)
1784 : {
1785 : NTSTATUS status;
1786 : struct smbcli_state *cli;
1787 0 : bool ret = true;
1788 : struct dom_sid *user_sid;
1789 : struct dom_sid *created_sid;
1790 : struct cli_credentials *anon_creds;
1791 : struct cli_credentials *user_creds;
1792 : char *domain_name;
1793 : struct smbcli_options options;
1794 : struct smbcli_session_options session_options;
1795 :
1796 0 : lpcfg_smbcli_options(torture->lp_ctx, &options);
1797 0 : lpcfg_smbcli_session_options(torture->lp_ctx, &session_options);
1798 :
1799 0 : if (!(anon_creds = cli_credentials_init_anon(torture))) {
1800 0 : torture_fail(torture, "create_anon_creds failed\n");
1801 : }
1802 :
1803 0 : status = smbcli_full_connection(
1804 : torture, &cli, torture_setting_string(torture, "host", NULL),
1805 : lpcfg_smb_ports(torture->lp_ctx), "IPC$", NULL,
1806 : lpcfg_socket_options(torture->lp_ctx), anon_creds,
1807 : lpcfg_resolve_context(torture->lp_ctx),
1808 : torture->ev, &options, &session_options,
1809 : lpcfg_gensec_settings(torture, torture->lp_ctx));
1810 0 : torture_assert_ntstatus_ok(torture, status, "anon smbcli_full_connection failed\n");
1811 :
1812 0 : if (!(user_sid = whoami(torture, torture, cli->tree))) {
1813 0 : torture_fail(torture, "whoami on anon connection failed\n");
1814 : }
1815 :
1816 0 : torture_assert_sid_equal(torture, user_sid, dom_sid_parse_talloc(torture, "s-1-5-7"),
1817 : "Anon lsa_GetUserName returned unexpected SID");
1818 :
1819 0 : talloc_free(cli);
1820 :
1821 0 : status = smbcli_full_connection(
1822 : torture, &cli, torture_setting_string(torture, "host", NULL),
1823 : lpcfg_smb_ports(torture->lp_ctx),
1824 : "IPC$", NULL, lpcfg_socket_options(torture->lp_ctx),
1825 : samba_cmdline_get_creds(),
1826 : lpcfg_resolve_context(torture->lp_ctx), torture->ev, &options,
1827 : &session_options, lpcfg_gensec_settings(torture, torture->lp_ctx));
1828 0 : torture_assert_ntstatus_ok(torture, status, "smbcli_full_connection failed\n");
1829 :
1830 0 : if (!(user_sid = whoami(torture, torture, cli->tree))) {
1831 0 : torture_fail(torture, "whoami on auth'ed connection failed\n");
1832 : }
1833 :
1834 0 : if (!(user_creds = cli_credentials_init(torture))) {
1835 0 : torture_fail(torture, "cli_credentials_init failed\n");
1836 : }
1837 :
1838 0 : cli_credentials_set_conf(user_creds, torture->lp_ctx);
1839 0 : cli_credentials_set_username(user_creds, "torture_username",
1840 : CRED_SPECIFIED);
1841 0 : cli_credentials_set_password(user_creds,
1842 0 : generate_random_password(user_creds, 8, 255),
1843 : CRED_SPECIFIED);
1844 :
1845 0 : if (!create_user(torture, torture, cli, NULL,
1846 : cli_credentials_get_username(user_creds),
1847 : cli_credentials_get_password(user_creds),
1848 : &domain_name, &created_sid)) {
1849 0 : torture_fail(torture, "create_user failed\n");
1850 : }
1851 :
1852 0 : cli_credentials_set_domain(user_creds, domain_name,
1853 : CRED_SPECIFIED);
1854 :
1855 : {
1856 : struct smbcli_session *session2;
1857 : struct smb_composite_sesssetup setup;
1858 : struct smbcli_tree *tree;
1859 :
1860 0 : session2 = smbcli_session_init(cli->transport, torture, false, session_options);
1861 0 : if (session2 == NULL) {
1862 0 : torture_fail(torture, "smbcli_session_init failed\n");
1863 : }
1864 :
1865 0 : setup.in.sesskey = cli->transport->negotiate.sesskey;
1866 0 : setup.in.capabilities = cli->transport->negotiate.capabilities;
1867 0 : setup.in.workgroup = "";
1868 0 : setup.in.credentials = user_creds;
1869 0 : setup.in.gensec_settings = lpcfg_gensec_settings(torture, torture->lp_ctx);
1870 :
1871 0 : status = smb_composite_sesssetup(session2, &setup);
1872 0 : torture_assert_ntstatus_ok(torture, status, "session setup with new user failed");
1873 :
1874 0 : session2->vuid = setup.out.vuid;
1875 :
1876 0 : if (!NT_STATUS_IS_OK(secondary_tcon(torture, torture, session2,
1877 : "IPC$", &tree))) {
1878 0 : torture_fail(torture, "secondary_tcon failed\n");
1879 : }
1880 :
1881 0 : if (!(user_sid = whoami(torture, torture, tree))) {
1882 0 : torture_fail_goto(torture, del, "whoami on user connection failed\n");
1883 : ret = false;
1884 : goto del;
1885 : }
1886 :
1887 0 : talloc_free(tree);
1888 : }
1889 :
1890 0 : torture_comment(torture, "Created %s, found %s\n",
1891 : dom_sid_string(torture, created_sid),
1892 : dom_sid_string(torture, user_sid));
1893 :
1894 0 : if (!dom_sid_equal(created_sid, user_sid)) {
1895 0 : ret = false;
1896 : }
1897 :
1898 0 : del:
1899 0 : if (!delete_user(torture, cli,
1900 : NULL,
1901 : cli_credentials_get_username(user_creds))) {
1902 0 : torture_fail(torture, "delete_user failed\n");
1903 : }
1904 :
1905 0 : return ret;
1906 : }
1907 :
1908 0 : static bool test_NetShareGetInfo(struct torture_context *tctx,
1909 : struct dcerpc_pipe *p,
1910 : const char *sharename)
1911 : {
1912 : NTSTATUS status;
1913 : struct srvsvc_NetShareGetInfo r;
1914 : union srvsvc_NetShareInfo info;
1915 0 : uint32_t levels[] = { 0, 1, 2, 501, 502, 1004, 1005, 1006, 1007, 1501 };
1916 : int i;
1917 0 : bool ret = true;
1918 0 : struct dcerpc_binding_handle *b = p->binding_handle;
1919 :
1920 0 : r.in.server_unc = talloc_asprintf(tctx, "\\\\%s",
1921 : dcerpc_server_name(p));
1922 0 : r.in.share_name = sharename;
1923 0 : r.out.info = &info;
1924 :
1925 0 : for (i=0;i<ARRAY_SIZE(levels);i++) {
1926 0 : r.in.level = levels[i];
1927 :
1928 0 : torture_comment(tctx, "Testing NetShareGetInfo level %u on share '%s'\n",
1929 : r.in.level, r.in.share_name);
1930 :
1931 0 : status = dcerpc_srvsvc_NetShareGetInfo_r(b, tctx, &r);
1932 0 : if (!NT_STATUS_IS_OK(status)) {
1933 0 : torture_warning(tctx, "NetShareGetInfo level %u on share '%s' failed"
1934 : " - %s\n", r.in.level, r.in.share_name,
1935 : nt_errstr(status));
1936 0 : ret = false;
1937 0 : continue;
1938 : }
1939 0 : if (!W_ERROR_IS_OK(r.out.result)) {
1940 0 : torture_warning(tctx, "NetShareGetInfo level %u on share '%s' failed "
1941 : "- %s\n", r.in.level, r.in.share_name,
1942 : win_errstr(r.out.result));
1943 0 : ret = false;
1944 0 : continue;
1945 : }
1946 : }
1947 :
1948 0 : return ret;
1949 : }
1950 :
1951 0 : static bool test_NetShareEnum(struct torture_context *tctx,
1952 : struct dcerpc_pipe *p,
1953 : const char **one_sharename)
1954 : {
1955 : NTSTATUS status;
1956 : struct srvsvc_NetShareEnum r;
1957 : struct srvsvc_NetShareInfoCtr info_ctr;
1958 : struct srvsvc_NetShareCtr0 c0;
1959 : struct srvsvc_NetShareCtr1 c1;
1960 : struct srvsvc_NetShareCtr2 c2;
1961 : struct srvsvc_NetShareCtr501 c501;
1962 : struct srvsvc_NetShareCtr502 c502;
1963 : struct srvsvc_NetShareCtr1004 c1004;
1964 : struct srvsvc_NetShareCtr1005 c1005;
1965 : struct srvsvc_NetShareCtr1006 c1006;
1966 : struct srvsvc_NetShareCtr1007 c1007;
1967 0 : uint32_t totalentries = 0;
1968 0 : uint32_t levels[] = { 0, 1, 2, 501, 502, 1004, 1005, 1006, 1007 };
1969 : int i;
1970 0 : bool ret = true;
1971 0 : struct dcerpc_binding_handle *b = p->binding_handle;
1972 :
1973 0 : ZERO_STRUCT(info_ctr);
1974 :
1975 0 : r.in.server_unc = talloc_asprintf(tctx,"\\\\%s",dcerpc_server_name(p));
1976 0 : r.in.info_ctr = &info_ctr;
1977 0 : r.in.max_buffer = (uint32_t)-1;
1978 0 : r.in.resume_handle = NULL;
1979 0 : r.out.totalentries = &totalentries;
1980 0 : r.out.info_ctr = &info_ctr;
1981 :
1982 0 : for (i=0;i<ARRAY_SIZE(levels);i++) {
1983 0 : info_ctr.level = levels[i];
1984 :
1985 0 : switch (info_ctr.level) {
1986 0 : case 0:
1987 0 : ZERO_STRUCT(c0);
1988 0 : info_ctr.ctr.ctr0 = &c0;
1989 0 : break;
1990 0 : case 1:
1991 0 : ZERO_STRUCT(c1);
1992 0 : info_ctr.ctr.ctr1 = &c1;
1993 0 : break;
1994 0 : case 2:
1995 0 : ZERO_STRUCT(c2);
1996 0 : info_ctr.ctr.ctr2 = &c2;
1997 0 : break;
1998 0 : case 501:
1999 0 : ZERO_STRUCT(c501);
2000 0 : info_ctr.ctr.ctr501 = &c501;
2001 0 : break;
2002 0 : case 502:
2003 0 : ZERO_STRUCT(c502);
2004 0 : info_ctr.ctr.ctr502 = &c502;
2005 0 : break;
2006 0 : case 1004:
2007 0 : ZERO_STRUCT(c1004);
2008 0 : info_ctr.ctr.ctr1004 = &c1004;
2009 0 : break;
2010 0 : case 1005:
2011 0 : ZERO_STRUCT(c1005);
2012 0 : info_ctr.ctr.ctr1005 = &c1005;
2013 0 : break;
2014 0 : case 1006:
2015 0 : ZERO_STRUCT(c1006);
2016 0 : info_ctr.ctr.ctr1006 = &c1006;
2017 0 : break;
2018 0 : case 1007:
2019 0 : ZERO_STRUCT(c1007);
2020 0 : info_ctr.ctr.ctr1007 = &c1007;
2021 0 : break;
2022 : }
2023 :
2024 0 : torture_comment(tctx, "Testing NetShareEnum level %u\n", info_ctr.level);
2025 :
2026 0 : status = dcerpc_srvsvc_NetShareEnum_r(b, tctx, &r);
2027 0 : if (!NT_STATUS_IS_OK(status)) {
2028 0 : torture_warning(tctx, "NetShareEnum level %u failed - %s\n",
2029 : info_ctr.level, nt_errstr(status));
2030 0 : ret = false;
2031 0 : continue;
2032 : }
2033 0 : if (!W_ERROR_IS_OK(r.out.result)) {
2034 0 : torture_warning(tctx, "NetShareEnum level %u failed - %s\n",
2035 : info_ctr.level, win_errstr(r.out.result));
2036 0 : continue;
2037 : }
2038 0 : if (info_ctr.level == 0) {
2039 0 : struct srvsvc_NetShareCtr0 *ctr = r.out.info_ctr->ctr.ctr0;
2040 0 : if (ctr->count > 0) {
2041 0 : *one_sharename = ctr->array[0].name;
2042 : }
2043 : }
2044 : }
2045 :
2046 0 : return ret;
2047 : }
2048 :
2049 0 : static bool torture_samba3_rpc_srvsvc(struct torture_context *torture)
2050 : {
2051 : struct dcerpc_pipe *p;
2052 0 : const char *sharename = NULL;
2053 0 : bool ret = true;
2054 :
2055 0 : torture_assert_ntstatus_ok(torture,
2056 : torture_rpc_connection(torture, &p, &ndr_table_srvsvc),
2057 : "failed to open srvsvc");
2058 :
2059 0 : ret &= test_NetShareEnum(torture, p, &sharename);
2060 0 : if (sharename == NULL) {
2061 0 : torture_comment(torture, "did not get sharename\n");
2062 : } else {
2063 0 : ret &= test_NetShareGetInfo(torture, p, sharename);
2064 : }
2065 :
2066 0 : return ret;
2067 : }
2068 :
2069 : /*
2070 : * Do a ReqChallenge/Auth2 with a random wks name, make sure it returns
2071 : * NT_STATUS_NO_SAM_ACCOUNT
2072 : */
2073 :
2074 0 : static bool torture_samba3_rpc_randomauth2(struct torture_context *torture)
2075 : {
2076 : TALLOC_CTX *mem_ctx;
2077 : struct dcerpc_pipe *net_pipe;
2078 : struct dcerpc_binding_handle *net_handle;
2079 : char *wksname;
2080 0 : bool result = false;
2081 : NTSTATUS status;
2082 : struct netr_ServerReqChallenge r;
2083 : struct netr_Credential netr_cli_creds;
2084 : struct netr_Credential netr_srv_creds;
2085 : uint32_t negotiate_flags;
2086 : struct netr_ServerAuthenticate2 a;
2087 : struct netlogon_creds_CredentialState *creds_state;
2088 : struct netr_Credential netr_cred;
2089 : struct samr_Password mach_pw;
2090 : struct smbcli_state *cli;
2091 :
2092 0 : if (!(mem_ctx = talloc_new(torture))) {
2093 0 : torture_comment(torture, "talloc_new failed\n");
2094 0 : return false;
2095 : }
2096 :
2097 0 : if (!(wksname = generate_random_str_list(
2098 : mem_ctx, 14, "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"))) {
2099 0 : torture_comment(torture, "generate_random_str_list failed\n");
2100 0 : goto done;
2101 : }
2102 :
2103 0 : if (!(torture_open_connection_share(
2104 : mem_ctx, &cli,
2105 : torture, torture_setting_string(torture, "host", NULL),
2106 : "IPC$", torture->ev))) {
2107 0 : torture_comment(torture, "IPC$ connection failed\n");
2108 0 : goto done;
2109 : }
2110 :
2111 0 : status = pipe_bind_smb(torture, mem_ctx, cli->tree, "\\netlogon",
2112 : &ndr_table_netlogon, &net_pipe);
2113 0 : torture_assert_ntstatus_ok_goto(torture, status, result, done,
2114 : "pipe_bind_smb failed");
2115 0 : net_handle = net_pipe->binding_handle;
2116 :
2117 0 : r.in.computer_name = wksname;
2118 0 : r.in.server_name = talloc_asprintf(
2119 : mem_ctx, "\\\\%s", dcerpc_server_name(net_pipe));
2120 0 : if (r.in.server_name == NULL) {
2121 0 : torture_comment(torture, "talloc_asprintf failed\n");
2122 0 : goto done;
2123 : }
2124 0 : generate_random_buffer(netr_cli_creds.data,
2125 : sizeof(netr_cli_creds.data));
2126 0 : r.in.credentials = &netr_cli_creds;
2127 0 : r.out.return_credentials = &netr_srv_creds;
2128 :
2129 0 : status = dcerpc_netr_ServerReqChallenge_r(net_handle, mem_ctx, &r);
2130 0 : if (!NT_STATUS_IS_OK(status)) {
2131 0 : torture_comment(torture, "netr_ServerReqChallenge failed: %s\n",
2132 : nt_errstr(status));
2133 0 : goto done;
2134 : }
2135 0 : if (!NT_STATUS_IS_OK(r.out.result)) {
2136 0 : torture_comment(torture, "netr_ServerReqChallenge failed: %s\n",
2137 : nt_errstr(r.out.result));
2138 0 : goto done;
2139 : }
2140 :
2141 0 : negotiate_flags = NETLOGON_NEG_AUTH2_FLAGS;
2142 0 : E_md4hash("foobar", mach_pw.hash);
2143 :
2144 0 : a.in.server_name = talloc_asprintf(
2145 : mem_ctx, "\\\\%s", dcerpc_server_name(net_pipe));
2146 0 : a.in.account_name = talloc_asprintf(
2147 : mem_ctx, "%s$", wksname);
2148 0 : a.in.computer_name = wksname;
2149 0 : a.in.secure_channel_type = SEC_CHAN_WKSTA;
2150 0 : a.in.negotiate_flags = &negotiate_flags;
2151 0 : a.out.negotiate_flags = &negotiate_flags;
2152 0 : a.in.credentials = &netr_cred;
2153 0 : a.out.return_credentials = &netr_cred;
2154 :
2155 0 : creds_state = netlogon_creds_client_init(mem_ctx,
2156 : a.in.account_name,
2157 : a.in.computer_name,
2158 0 : a.in.secure_channel_type,
2159 0 : r.in.credentials,
2160 0 : r.out.return_credentials, &mach_pw,
2161 : &netr_cred, negotiate_flags);
2162 0 : torture_assert(torture, (creds_state != NULL), "memory allocation failed");
2163 :
2164 0 : status = dcerpc_netr_ServerAuthenticate2_r(net_handle, mem_ctx, &a);
2165 0 : if (!NT_STATUS_IS_OK(status)) {
2166 0 : goto done;
2167 : }
2168 0 : if (!NT_STATUS_EQUAL(a.out.result, NT_STATUS_NO_TRUST_SAM_ACCOUNT)) {
2169 0 : torture_comment(torture, "dcerpc_netr_ServerAuthenticate2 returned %s, "
2170 : "expected NT_STATUS_NO_TRUST_SAM_ACCOUNT\n",
2171 : nt_errstr(a.out.result));
2172 0 : goto done;
2173 : }
2174 :
2175 0 : result = true;
2176 0 : done:
2177 0 : talloc_free(mem_ctx);
2178 0 : return result;
2179 : }
2180 :
2181 0 : static struct security_descriptor *get_sharesec(struct torture_context *tctx,
2182 : TALLOC_CTX *mem_ctx,
2183 : struct smbcli_session *sess,
2184 : const char *sharename)
2185 : {
2186 : struct smbcli_tree *tree;
2187 : TALLOC_CTX *tmp_ctx;
2188 : struct dcerpc_pipe *p;
2189 : struct dcerpc_binding_handle *b;
2190 : NTSTATUS status;
2191 : struct srvsvc_NetShareGetInfo r;
2192 : union srvsvc_NetShareInfo info;
2193 : struct security_descriptor *result;
2194 :
2195 0 : if (!(tmp_ctx = talloc_new(mem_ctx))) {
2196 0 : torture_comment(tctx, "talloc_new failed\n");
2197 0 : return NULL;
2198 : }
2199 :
2200 0 : if (!NT_STATUS_IS_OK(secondary_tcon(tctx, tmp_ctx, sess, "IPC$", &tree))) {
2201 0 : torture_comment(tctx, "secondary_tcon failed\n");
2202 0 : talloc_free(tmp_ctx);
2203 0 : return NULL;
2204 : }
2205 :
2206 0 : status = pipe_bind_smb(tctx, mem_ctx, tree, "\\pipe\\srvsvc",
2207 : &ndr_table_srvsvc, &p);
2208 0 : if (!NT_STATUS_IS_OK(status)) {
2209 0 : torture_warning(tctx, "could not bind to srvsvc pipe: %s\n",
2210 : nt_errstr(status));
2211 0 : talloc_free(tmp_ctx);
2212 0 : return NULL;
2213 : }
2214 0 : b = p->binding_handle;
2215 :
2216 : #if 0
2217 : p->conn->flags |= DCERPC_DEBUG_PRINT_IN | DCERPC_DEBUG_PRINT_OUT;
2218 : #endif
2219 :
2220 0 : r.in.server_unc = talloc_asprintf(tmp_ctx, "\\\\%s",
2221 : dcerpc_server_name(p));
2222 0 : r.in.share_name = sharename;
2223 0 : r.in.level = 502;
2224 0 : r.out.info = &info;
2225 :
2226 0 : status = dcerpc_srvsvc_NetShareGetInfo_r(b, tmp_ctx, &r);
2227 0 : if (!NT_STATUS_IS_OK(status)) {
2228 0 : torture_comment(tctx, "srvsvc_NetShareGetInfo failed: %s\n",
2229 : nt_errstr(status));
2230 0 : talloc_free(tmp_ctx);
2231 0 : return NULL;
2232 : }
2233 0 : if (!W_ERROR_IS_OK(r.out.result)) {
2234 0 : torture_comment(tctx, "srvsvc_NetShareGetInfo failed: %s\n",
2235 : win_errstr(r.out.result));
2236 0 : talloc_free(tmp_ctx);
2237 0 : return NULL;
2238 : }
2239 :
2240 0 : result = talloc_steal(mem_ctx, info.info502->sd_buf.sd);
2241 0 : talloc_free(tmp_ctx);
2242 0 : return result;
2243 : }
2244 :
2245 0 : static NTSTATUS set_sharesec(struct torture_context *tctx,
2246 : TALLOC_CTX *mem_ctx,
2247 : struct smbcli_session *sess,
2248 : const char *sharename,
2249 : struct security_descriptor *sd)
2250 : {
2251 : struct smbcli_tree *tree;
2252 : TALLOC_CTX *tmp_ctx;
2253 : struct dcerpc_pipe *p;
2254 : struct dcerpc_binding_handle *b;
2255 : NTSTATUS status;
2256 : struct sec_desc_buf i;
2257 : struct srvsvc_NetShareSetInfo r;
2258 : union srvsvc_NetShareInfo info;
2259 0 : uint32_t error = 0;
2260 :
2261 0 : if (!(tmp_ctx = talloc_new(mem_ctx))) {
2262 0 : torture_comment(tctx, "talloc_new failed\n");
2263 0 : return NT_STATUS_NO_MEMORY;
2264 : }
2265 :
2266 0 : if (!NT_STATUS_IS_OK(secondary_tcon(tctx, tmp_ctx, sess, "IPC$", &tree))) {
2267 0 : torture_comment(tctx, "secondary_tcon failed\n");
2268 0 : talloc_free(tmp_ctx);
2269 0 : return NT_STATUS_UNSUCCESSFUL;
2270 : }
2271 :
2272 0 : status = pipe_bind_smb(tctx, mem_ctx, tree, "\\pipe\\srvsvc",
2273 : &ndr_table_srvsvc, &p);
2274 0 : if (!NT_STATUS_IS_OK(status)) {
2275 0 : torture_warning(tctx, "could not bind to srvsvc pipe: %s\n",
2276 : nt_errstr(status));
2277 0 : talloc_free(tmp_ctx);
2278 0 : return NT_STATUS_UNSUCCESSFUL;
2279 : }
2280 0 : b = p->binding_handle;
2281 :
2282 : #if 0
2283 : p->conn->flags |= DCERPC_DEBUG_PRINT_IN | DCERPC_DEBUG_PRINT_OUT;
2284 : #endif
2285 :
2286 0 : r.in.server_unc = talloc_asprintf(tmp_ctx, "\\\\%s",
2287 : dcerpc_server_name(p));
2288 0 : r.in.share_name = sharename;
2289 0 : r.in.level = 1501;
2290 0 : i.sd = sd;
2291 0 : info.info1501 = &i;
2292 0 : r.in.info = &info;
2293 0 : r.in.parm_error = &error;
2294 :
2295 0 : status = dcerpc_srvsvc_NetShareSetInfo_r(b, tmp_ctx, &r);
2296 0 : if (!NT_STATUS_IS_OK(status)) {
2297 0 : torture_comment(tctx, "srvsvc_NetShareSetInfo failed: %s\n",
2298 : nt_errstr(status));
2299 : }
2300 0 : if (!W_ERROR_IS_OK(r.out.result)) {
2301 0 : torture_comment(tctx, "srvsvc_NetShareSetInfo failed: %s\n",
2302 : win_errstr(r.out.result));
2303 0 : status = werror_to_ntstatus(r.out.result);
2304 : }
2305 0 : talloc_free(tmp_ctx);
2306 0 : return status;
2307 : }
2308 :
2309 0 : bool try_tcon(struct torture_context *tctx,
2310 : TALLOC_CTX *mem_ctx,
2311 : struct security_descriptor *orig_sd,
2312 : struct smbcli_session *session,
2313 : const char *sharename, const struct dom_sid *user_sid,
2314 : unsigned int access_mask, NTSTATUS expected_tcon,
2315 : NTSTATUS expected_mkdir)
2316 : {
2317 : TALLOC_CTX *tmp_ctx;
2318 : struct smbcli_tree *rmdir_tree, *tree;
2319 : struct dom_sid *domain_sid;
2320 : uint32_t rid;
2321 : struct security_descriptor *sd;
2322 : NTSTATUS status;
2323 0 : bool ret = true;
2324 :
2325 0 : if (!(tmp_ctx = talloc_new(mem_ctx))) {
2326 0 : torture_comment(tctx, "talloc_new failed\n");
2327 0 : return false;
2328 : }
2329 :
2330 0 : status = secondary_tcon(tctx, tmp_ctx, session, sharename, &rmdir_tree);
2331 0 : if (!NT_STATUS_IS_OK(status)) {
2332 0 : torture_comment(tctx, "first tcon to delete dir failed\n");
2333 0 : talloc_free(tmp_ctx);
2334 0 : return false;
2335 : }
2336 :
2337 0 : smbcli_rmdir(rmdir_tree, "sharesec_testdir");
2338 :
2339 0 : if (!NT_STATUS_IS_OK(dom_sid_split_rid(tmp_ctx, user_sid,
2340 : &domain_sid, &rid))) {
2341 0 : torture_comment(tctx, "dom_sid_split_rid failed\n");
2342 0 : talloc_free(tmp_ctx);
2343 0 : return false;
2344 : }
2345 :
2346 0 : sd = security_descriptor_dacl_create(
2347 : tmp_ctx, 0, "S-1-5-32-544",
2348 0 : dom_sid_string(mem_ctx, dom_sid_add_rid(mem_ctx, domain_sid,
2349 : DOMAIN_RID_USERS)),
2350 : dom_sid_string(mem_ctx, user_sid),
2351 : SEC_ACE_TYPE_ACCESS_ALLOWED, access_mask, 0, NULL);
2352 0 : if (sd == NULL) {
2353 0 : torture_comment(tctx, "security_descriptor_dacl_create failed\n");
2354 0 : talloc_free(tmp_ctx);
2355 0 : return false;
2356 : }
2357 :
2358 0 : status = set_sharesec(tctx, mem_ctx, session, sharename, sd);
2359 0 : if (!NT_STATUS_IS_OK(status)) {
2360 0 : torture_comment(tctx, "custom set_sharesec failed: %s\n",
2361 : nt_errstr(status));
2362 0 : talloc_free(tmp_ctx);
2363 0 : return false;
2364 : }
2365 :
2366 0 : status = secondary_tcon(tctx, tmp_ctx, session, sharename, &tree);
2367 0 : if (!NT_STATUS_EQUAL(status, expected_tcon)) {
2368 0 : torture_comment(tctx, "Expected %s, got %s\n", nt_errstr(expected_tcon),
2369 : nt_errstr(status));
2370 0 : ret = false;
2371 0 : goto done;
2372 : }
2373 :
2374 0 : if (!NT_STATUS_IS_OK(status)) {
2375 : /* An expected non-access, no point in trying to write */
2376 0 : goto done;
2377 : }
2378 :
2379 0 : status = smbcli_mkdir(tree, "sharesec_testdir");
2380 0 : if (!NT_STATUS_EQUAL(status, expected_mkdir)) {
2381 0 : torture_warning(tctx, "Expected %s, got %s\n",
2382 : nt_errstr(expected_mkdir), nt_errstr(status));
2383 0 : ret = false;
2384 : }
2385 :
2386 0 : done:
2387 0 : smbcli_rmdir(rmdir_tree, "sharesec_testdir");
2388 :
2389 0 : status = set_sharesec(tctx, mem_ctx, session, sharename, orig_sd);
2390 0 : if (!NT_STATUS_IS_OK(status)) {
2391 0 : torture_comment(tctx, "custom set_sharesec failed: %s\n",
2392 : nt_errstr(status));
2393 0 : talloc_free(tmp_ctx);
2394 0 : return false;
2395 : }
2396 :
2397 0 : talloc_free(tmp_ctx);
2398 0 : return ret;
2399 : }
2400 :
2401 0 : static bool torture_samba3_rpc_sharesec(struct torture_context *torture)
2402 : {
2403 0 : struct smbcli_state *cli = NULL;
2404 0 : struct security_descriptor *sd = NULL;
2405 0 : struct dom_sid *user_sid = NULL;
2406 0 : const char *testuser_passwd = NULL;
2407 0 : struct cli_credentials *test_credentials = NULL;
2408 : struct smbcli_options options;
2409 : struct smbcli_session_options session_options;
2410 : NTSTATUS status;
2411 0 : struct test_join *tj = NULL;
2412 0 : struct dcerpc_pipe *lsa_pipe = NULL;
2413 : const char *priv_array[1];
2414 :
2415 : /* Create a new user. The normal user has SeBackup and SeRestore
2416 : privs so we can't lock them out with a share security descriptor. */
2417 0 : tj = torture_create_testuser(torture,
2418 : "sharesec_user",
2419 : torture_setting_string(torture, "workgroup", NULL),
2420 : ACB_NORMAL,
2421 : &testuser_passwd);
2422 0 : if (!tj) {
2423 0 : torture_fail(torture, "Creating sharesec_user failed\n");
2424 : }
2425 :
2426 : /* Give them SeDiskOperatorPrivilege but no other privs. */
2427 0 : status = torture_rpc_connection(torture, &lsa_pipe, &ndr_table_lsarpc);
2428 0 : if (!NT_STATUS_IS_OK(status)) {
2429 0 : torture_delete_testuser(torture, tj, "sharesec_user");
2430 0 : talloc_free(tj);
2431 0 : torture_fail(torture, "Error connecting to LSA pipe");
2432 : }
2433 :
2434 0 : priv_array[0] = "SeDiskOperatorPrivilege";
2435 0 : if (!torture_setup_privs(torture,
2436 : lsa_pipe,
2437 : 1,
2438 : priv_array,
2439 : torture_join_user_sid(tj))) {
2440 0 : talloc_free(lsa_pipe);
2441 0 : torture_delete_testuser(torture, tj, "sharesec_user");
2442 0 : talloc_free(tj);
2443 0 : torture_fail(torture, "Failed to setup privs\n");
2444 : }
2445 0 : talloc_free(lsa_pipe);
2446 :
2447 0 : test_credentials = cli_credentials_init(torture);
2448 0 : cli_credentials_set_workstation(test_credentials, "localhost", CRED_SPECIFIED);
2449 0 : cli_credentials_set_domain(test_credentials, lpcfg_workgroup(torture->lp_ctx),
2450 : CRED_SPECIFIED);
2451 0 : cli_credentials_set_username(test_credentials, "sharesec_user", CRED_SPECIFIED);
2452 0 : cli_credentials_set_password(test_credentials, testuser_passwd, CRED_SPECIFIED);
2453 :
2454 0 : ZERO_STRUCT(options);
2455 0 : ZERO_STRUCT(session_options);
2456 0 : lpcfg_smbcli_options(torture->lp_ctx, &options);
2457 0 : lpcfg_smbcli_session_options(torture->lp_ctx, &session_options);
2458 :
2459 0 : status = smbcli_full_connection(torture,
2460 : &cli,
2461 : torture_setting_string(torture, "host", NULL),
2462 : lpcfg_smb_ports(torture->lp_ctx),
2463 : "IPC$",
2464 : NULL,
2465 : lpcfg_socket_options(torture->lp_ctx),
2466 : test_credentials,
2467 : lpcfg_resolve_context(torture->lp_ctx),
2468 : torture->ev,
2469 : &options,
2470 : &session_options,
2471 : lpcfg_gensec_settings(torture, torture->lp_ctx));
2472 0 : if (!NT_STATUS_IS_OK(status)) {
2473 0 : talloc_free(cli);
2474 0 : torture_delete_testuser(torture, tj, "sharesec_user");
2475 0 : talloc_free(tj);
2476 0 : torture_fail(torture, "Failed to open connection\n");
2477 : }
2478 :
2479 0 : if (!(user_sid = whoami(torture, torture, cli->tree))) {
2480 0 : talloc_free(cli);
2481 0 : torture_delete_testuser(torture, tj, "sharesec_user");
2482 0 : talloc_free(tj);
2483 0 : torture_fail(torture, "whoami failed\n");
2484 : }
2485 :
2486 0 : sd = get_sharesec(torture, torture, cli->session,
2487 : torture_setting_string(torture, "share", NULL));
2488 :
2489 0 : if (!try_tcon(torture, torture, sd, cli->session,
2490 : torture_setting_string(torture, "share", NULL),
2491 0 : user_sid, 0, NT_STATUS_ACCESS_DENIED, NT_STATUS_OK)) {
2492 0 : talloc_free(cli);
2493 0 : torture_delete_testuser(torture, tj, "sharesec_user");
2494 0 : talloc_free(tj);
2495 0 : torture_fail(torture, "failed to test tcon with 0 access_mask");
2496 : }
2497 :
2498 0 : if (!try_tcon(torture, torture, sd, cli->session,
2499 : torture_setting_string(torture, "share", NULL),
2500 0 : user_sid, SEC_FILE_READ_DATA, NT_STATUS_OK,
2501 0 : NT_STATUS_MEDIA_WRITE_PROTECTED)) {
2502 0 : talloc_free(cli);
2503 0 : torture_delete_testuser(torture, tj, "sharesec_user");
2504 0 : talloc_free(tj);
2505 0 : torture_fail(torture, "failed to test tcon with SEC_FILE_READ_DATA access_mask");
2506 : }
2507 :
2508 : /* sharesec_user doesn't have any rights on the underlying file system.
2509 : Go back to the normal user. */
2510 :
2511 0 : talloc_free(cli);
2512 0 : cli = NULL;
2513 0 : torture_delete_testuser(torture, tj, "sharesec_user");
2514 0 : talloc_free(tj);
2515 0 : tj = NULL;
2516 :
2517 0 : if (!(torture_open_connection_share(
2518 : torture, &cli, torture, torture_setting_string(torture, "host", NULL),
2519 : "IPC$", torture->ev))) {
2520 0 : torture_fail(torture, "IPC$ connection failed\n");
2521 : }
2522 :
2523 0 : if (!(user_sid = whoami(torture, torture, cli->tree))) {
2524 0 : torture_fail(torture, "whoami failed\n");
2525 : }
2526 0 : torture_assert(torture, try_tcon(
2527 : torture, torture, sd, cli->session,
2528 : torture_setting_string(torture, "share", NULL),
2529 : user_sid, SEC_FILE_ALL, NT_STATUS_OK, NT_STATUS_OK),
2530 : "failed to test tcon with SEC_FILE_ALL access_mask");
2531 :
2532 0 : return true;
2533 : }
2534 :
2535 0 : static bool torture_samba3_rpc_lsa(struct torture_context *torture)
2536 : {
2537 : struct dcerpc_pipe *p;
2538 : struct dcerpc_binding_handle *b;
2539 : struct policy_handle lsa_handle;
2540 :
2541 0 : torture_assert_ntstatus_ok(torture,
2542 : torture_rpc_connection(torture, &p, &ndr_table_lsarpc),
2543 : "failed to setup lsarpc");
2544 :
2545 0 : b = p->binding_handle;
2546 :
2547 : {
2548 : struct lsa_ObjectAttribute attr;
2549 : struct lsa_OpenPolicy2 o;
2550 0 : o.in.system_name = talloc_asprintf(
2551 : torture, "\\\\%s", dcerpc_server_name(p));
2552 0 : ZERO_STRUCT(attr);
2553 0 : o.in.attr = &attr;
2554 0 : o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2555 0 : o.out.handle = &lsa_handle;
2556 :
2557 0 : torture_assert_ntstatus_ok(torture,
2558 : dcerpc_lsa_OpenPolicy2_r(b, torture, &o),
2559 : "dcerpc_lsa_OpenPolicy2 failed");
2560 0 : torture_assert_ntstatus_ok(torture, o.out.result,
2561 : "dcerpc_lsa_OpenPolicy2 failed");
2562 : }
2563 :
2564 : {
2565 : int i;
2566 0 : int levels[] = { 2,3,5,6 };
2567 :
2568 0 : for (i=0; i<ARRAY_SIZE(levels); i++) {
2569 : struct lsa_QueryInfoPolicy r;
2570 0 : union lsa_PolicyInformation *info = NULL;
2571 0 : r.in.handle = &lsa_handle;
2572 0 : r.in.level = levels[i];
2573 0 : r.out.info = &info;
2574 :
2575 0 : torture_assert_ntstatus_ok(torture,
2576 : dcerpc_lsa_QueryInfoPolicy_r(b, torture, &r),
2577 : talloc_asprintf(torture, "dcerpc_lsa_QueryInfoPolicy level %d failed", levels[i]));
2578 0 : torture_assert_ntstatus_ok(torture, r.out.result,
2579 : talloc_asprintf(torture, "dcerpc_lsa_QueryInfoPolicy level %d failed", levels[i]));
2580 : }
2581 : }
2582 :
2583 0 : return true;
2584 : }
2585 :
2586 0 : static NTSTATUS get_servername(TALLOC_CTX *mem_ctx, struct smbcli_tree *tree,
2587 : char **name)
2588 : {
2589 : struct rap_WserverGetInfo r;
2590 : NTSTATUS status;
2591 : char servername[17];
2592 : size_t converted_size;
2593 :
2594 0 : r.in.level = 0;
2595 0 : r.in.bufsize = 0xffff;
2596 :
2597 0 : status = smbcli_rap_netservergetinfo(tree, mem_ctx, &r);
2598 0 : if (!NT_STATUS_IS_OK(status)) {
2599 0 : return status;
2600 : }
2601 :
2602 0 : memcpy(servername, r.out.info.info0.name, 16);
2603 0 : servername[16] = '\0';
2604 :
2605 0 : if (!pull_ascii_talloc(mem_ctx, name, servername, &converted_size)) {
2606 0 : return NT_STATUS_NO_MEMORY;
2607 : }
2608 :
2609 0 : return NT_STATUS_OK;
2610 : }
2611 :
2612 0 : static bool rap_get_servername(struct torture_context *tctx,
2613 : char **servername)
2614 : {
2615 : struct smbcli_state *cli;
2616 :
2617 0 : torture_assert(tctx,
2618 : torture_open_connection_share(tctx, &cli, tctx, torture_setting_string(tctx, "host", NULL),
2619 : "IPC$", tctx->ev),
2620 : "IPC$ connection failed");
2621 :
2622 0 : torture_assert_ntstatus_ok(tctx,
2623 : get_servername(tctx, cli->tree, servername),
2624 : "get_servername failed");
2625 :
2626 0 : talloc_free(cli);
2627 :
2628 0 : return true;
2629 : }
2630 :
2631 0 : static bool find_printers(struct torture_context *tctx,
2632 : struct dcerpc_pipe *p,
2633 : const char ***printers,
2634 : size_t *num_printers)
2635 : {
2636 : struct srvsvc_NetShareEnum r;
2637 : struct srvsvc_NetShareInfoCtr info_ctr;
2638 : struct srvsvc_NetShareCtr1 c1_in;
2639 : struct srvsvc_NetShareCtr1 *c1;
2640 0 : uint32_t totalentries = 0;
2641 : int i;
2642 0 : struct dcerpc_binding_handle *b = p->binding_handle;
2643 :
2644 0 : ZERO_STRUCT(c1_in);
2645 0 : info_ctr.level = 1;
2646 0 : info_ctr.ctr.ctr1 = &c1_in;
2647 :
2648 0 : r.in.server_unc = talloc_asprintf(
2649 : tctx, "\\\\%s", dcerpc_server_name(p));
2650 0 : r.in.info_ctr = &info_ctr;
2651 0 : r.in.max_buffer = (uint32_t)-1;
2652 0 : r.in.resume_handle = NULL;
2653 0 : r.out.totalentries = &totalentries;
2654 0 : r.out.info_ctr = &info_ctr;
2655 :
2656 0 : torture_assert_ntstatus_ok(tctx,
2657 : dcerpc_srvsvc_NetShareEnum_r(b, tctx, &r),
2658 : "NetShareEnum level 1 failed");
2659 0 : torture_assert_werr_ok(tctx, r.out.result,
2660 : "NetShareEnum level 1 failed");
2661 :
2662 0 : *printers = NULL;
2663 0 : *num_printers = 0;
2664 0 : c1 = r.out.info_ctr->ctr.ctr1;
2665 0 : for (i=0; i<c1->count; i++) {
2666 0 : if (c1->array[i].type != STYPE_PRINTQ) {
2667 0 : continue;
2668 : }
2669 0 : if (!add_string_to_array(tctx, c1->array[i].name,
2670 : printers, num_printers)) {
2671 0 : return false;
2672 : }
2673 : }
2674 :
2675 0 : return true;
2676 : }
2677 :
2678 0 : static bool enumprinters(struct torture_context *tctx,
2679 : struct dcerpc_binding_handle *b,
2680 : const char *servername, int level, int *num_printers)
2681 : {
2682 : struct spoolss_EnumPrinters r;
2683 : DATA_BLOB blob;
2684 : uint32_t needed;
2685 : uint32_t count;
2686 : union spoolss_PrinterInfo *info;
2687 :
2688 0 : r.in.flags = PRINTER_ENUM_LOCAL;
2689 0 : r.in.server = talloc_asprintf(tctx, "\\\\%s", servername);
2690 0 : r.in.level = level;
2691 0 : r.in.buffer = NULL;
2692 0 : r.in.offered = 0;
2693 0 : r.out.needed = &needed;
2694 0 : r.out.count = &count;
2695 0 : r.out.info = &info;
2696 :
2697 0 : torture_assert_ntstatus_ok(tctx,
2698 : dcerpc_spoolss_EnumPrinters_r(b, tctx, &r),
2699 : "dcerpc_spoolss_EnumPrinters failed");
2700 0 : torture_assert_werr_equal(tctx, r.out.result, WERR_INSUFFICIENT_BUFFER,
2701 : "EnumPrinters unexpected return code should be WERR_INSUFFICIENT_BUFFER");
2702 :
2703 0 : blob = data_blob_talloc_zero(tctx, needed);
2704 0 : if (blob.data == NULL) {
2705 0 : return false;
2706 : }
2707 :
2708 0 : r.in.buffer = &blob;
2709 0 : r.in.offered = needed;
2710 :
2711 0 : torture_assert_ntstatus_ok(tctx,
2712 : dcerpc_spoolss_EnumPrinters_r(b, tctx, &r),
2713 : "dcerpc_spoolss_EnumPrinters failed");
2714 0 : torture_assert_werr_ok(tctx, r.out.result,
2715 : "dcerpc_spoolss_EnumPrinters failed");
2716 :
2717 0 : *num_printers = count;
2718 :
2719 0 : return true;
2720 : }
2721 :
2722 0 : static bool getprinterinfo(struct torture_context *tctx,
2723 : struct dcerpc_binding_handle *b,
2724 : struct policy_handle *handle, int level,
2725 : union spoolss_PrinterInfo **res)
2726 : {
2727 : struct spoolss_GetPrinter r;
2728 : DATA_BLOB blob;
2729 : uint32_t needed;
2730 :
2731 0 : r.in.handle = handle;
2732 0 : r.in.level = level;
2733 0 : r.in.buffer = NULL;
2734 0 : r.in.offered = 0;
2735 0 : r.out.needed = &needed;
2736 :
2737 0 : torture_assert_ntstatus_ok(tctx,
2738 : dcerpc_spoolss_GetPrinter_r(b, tctx, &r),
2739 : "dcerpc_spoolss_GetPrinter failed");
2740 0 : torture_assert_werr_equal(tctx, r.out.result, WERR_INSUFFICIENT_BUFFER,
2741 : "GetPrinter unexpected return code should be WERR_INSUFFICIENT_BUFFER");
2742 :
2743 0 : r.in.handle = handle;
2744 0 : r.in.level = level;
2745 0 : blob = data_blob_talloc_zero(tctx, needed);
2746 0 : if (blob.data == NULL) {
2747 0 : return false;
2748 : }
2749 0 : r.in.buffer = &blob;
2750 0 : r.in.offered = needed;
2751 :
2752 0 : torture_assert_ntstatus_ok(tctx,
2753 : dcerpc_spoolss_GetPrinter_r(b, tctx, &r),
2754 : "dcerpc_spoolss_GetPrinter failed");
2755 0 : torture_assert_werr_ok(tctx, r.out.result,
2756 : "dcerpc_spoolss_GetPrinter failed");
2757 :
2758 0 : if (res != NULL) {
2759 0 : *res = talloc_steal(tctx, r.out.info);
2760 : }
2761 :
2762 0 : return true;
2763 : }
2764 :
2765 0 : static bool torture_samba3_rpc_spoolss(struct torture_context *torture)
2766 : {
2767 : struct dcerpc_pipe *p, *p2;
2768 : struct dcerpc_binding_handle *b;
2769 : struct policy_handle server_handle, printer_handle;
2770 : const char **printers;
2771 : size_t num_printers;
2772 : struct spoolss_UserLevel1 userlevel1;
2773 : char *servername;
2774 :
2775 0 : torture_assert(torture,
2776 : rap_get_servername(torture, &servername),
2777 : "failed to rap servername");
2778 :
2779 0 : torture_assert_ntstatus_ok(torture,
2780 : torture_rpc_connection(torture, &p2, &ndr_table_srvsvc),
2781 : "failed to setup srvsvc");
2782 :
2783 0 : torture_assert(torture,
2784 : find_printers(torture, p2, &printers, &num_printers),
2785 : "failed to find printers via srvsvc");
2786 :
2787 0 : talloc_free(p2);
2788 :
2789 0 : if (num_printers == 0) {
2790 0 : torture_skip(torture, "Did not find printers\n");
2791 : return true;
2792 : }
2793 :
2794 0 : torture_assert_ntstatus_ok(torture,
2795 : torture_rpc_connection(torture, &p, &ndr_table_spoolss),
2796 : "failed to setup spoolss");
2797 :
2798 0 : b = p->binding_handle;
2799 :
2800 0 : ZERO_STRUCT(userlevel1);
2801 0 : userlevel1.client = talloc_asprintf(
2802 : torture, "\\\\%s", lpcfg_netbios_name(torture->lp_ctx));
2803 0 : userlevel1.user = cli_credentials_get_username(
2804 : samba_cmdline_get_creds());
2805 0 : userlevel1.build = 2600;
2806 0 : userlevel1.major = 3;
2807 0 : userlevel1.minor = 0;
2808 0 : userlevel1.processor = 0;
2809 :
2810 : {
2811 : struct spoolss_OpenPrinterEx r;
2812 :
2813 0 : ZERO_STRUCT(r);
2814 0 : r.in.printername = talloc_asprintf(torture, "\\\\%s",
2815 : servername);
2816 0 : r.in.datatype = NULL;
2817 0 : r.in.access_mask = 0;
2818 0 : r.in.userlevel_ctr.level = 1;
2819 0 : r.in.userlevel_ctr.user_info.level1 = &userlevel1;
2820 0 : r.out.handle = &server_handle;
2821 :
2822 0 : torture_assert_ntstatus_ok(torture,
2823 : dcerpc_spoolss_OpenPrinterEx_r(b, torture, &r),
2824 : "dcerpc_spoolss_OpenPrinterEx failed");
2825 0 : torture_assert_werr_ok(torture, r.out.result,
2826 : "dcerpc_spoolss_OpenPrinterEx failed");
2827 : }
2828 :
2829 : {
2830 : struct spoolss_ClosePrinter r;
2831 :
2832 0 : r.in.handle = &server_handle;
2833 0 : r.out.handle = &server_handle;
2834 :
2835 0 : torture_assert_ntstatus_ok(torture,
2836 : dcerpc_spoolss_ClosePrinter_r(b, torture, &r),
2837 : "dcerpc_spoolss_ClosePrinter failed");
2838 0 : torture_assert_werr_ok(torture, r.out.result,
2839 : "dcerpc_spoolss_ClosePrinter failed");
2840 : }
2841 :
2842 : {
2843 : struct spoolss_OpenPrinterEx r;
2844 :
2845 0 : ZERO_STRUCT(r);
2846 0 : r.in.printername = talloc_asprintf(
2847 : torture, "\\\\%s\\%s", servername, printers[0]);
2848 0 : r.in.datatype = NULL;
2849 0 : r.in.access_mask = 0;
2850 0 : r.in.userlevel_ctr.level = 1;
2851 0 : r.in.userlevel_ctr.user_info.level1 = &userlevel1;
2852 0 : r.out.handle = &printer_handle;
2853 :
2854 0 : torture_assert_ntstatus_ok(torture,
2855 : dcerpc_spoolss_OpenPrinterEx_r(b, torture, &r),
2856 : "dcerpc_spoolss_OpenPrinterEx failed");
2857 0 : torture_assert_werr_ok(torture, r.out.result,
2858 : "dcerpc_spoolss_OpenPrinterEx failed");
2859 : }
2860 :
2861 : {
2862 : int i;
2863 :
2864 0 : for (i=0; i<8; i++) {
2865 0 : torture_assert(torture,
2866 : getprinterinfo(torture, b, &printer_handle, i, NULL),
2867 : talloc_asprintf(torture, "getprinterinfo %d failed", i));
2868 : }
2869 : }
2870 :
2871 : {
2872 : struct spoolss_ClosePrinter r;
2873 :
2874 0 : r.in.handle = &printer_handle;
2875 0 : r.out.handle = &printer_handle;
2876 :
2877 0 : torture_assert_ntstatus_ok(torture,
2878 : dcerpc_spoolss_ClosePrinter_r(b, torture, &r),
2879 : "dcerpc_spoolss_ClosePrinter failed");
2880 0 : torture_assert_werr_ok(torture, r.out.result,
2881 : "dcerpc_spoolss_ClosePrinter failed");
2882 : }
2883 :
2884 : {
2885 : int num_enumerated;
2886 :
2887 0 : torture_assert(torture,
2888 : enumprinters(torture, b, servername, 1, &num_enumerated),
2889 : "enumprinters failed");
2890 :
2891 0 : torture_assert_int_equal(torture, num_printers, num_enumerated,
2892 : "netshareenum / enumprinters lvl 1 numprinter mismatch");
2893 : }
2894 :
2895 : {
2896 : int num_enumerated;
2897 :
2898 0 : torture_assert(torture,
2899 : enumprinters(torture, b, servername, 2, &num_enumerated),
2900 : "enumprinters failed");
2901 :
2902 0 : torture_assert_int_equal(torture, num_printers, num_enumerated,
2903 : "netshareenum / enumprinters lvl 2 numprinter mismatch");
2904 : }
2905 :
2906 0 : return true;
2907 : }
2908 :
2909 0 : static bool torture_samba3_rpc_wkssvc(struct torture_context *torture)
2910 : {
2911 : struct dcerpc_pipe *p;
2912 : struct dcerpc_binding_handle *b;
2913 : char *servername;
2914 :
2915 0 : torture_assert(torture,
2916 : rap_get_servername(torture, &servername),
2917 : "failed to rap servername");
2918 :
2919 0 : torture_assert_ntstatus_ok(torture,
2920 : torture_rpc_connection(torture, &p, &ndr_table_wkssvc),
2921 : "failed to setup wkssvc");
2922 :
2923 0 : b = p->binding_handle;
2924 :
2925 : {
2926 : struct wkssvc_NetWkstaInfo100 wks100;
2927 : union wkssvc_NetWkstaInfo info;
2928 : struct wkssvc_NetWkstaGetInfo r;
2929 :
2930 0 : r.in.server_name = "\\foo";
2931 0 : r.in.level = 100;
2932 0 : info.info100 = &wks100;
2933 0 : r.out.info = &info;
2934 :
2935 0 : torture_assert_ntstatus_ok(torture,
2936 : dcerpc_wkssvc_NetWkstaGetInfo_r(b, torture, &r),
2937 : "dcerpc_wkssvc_NetWksGetInfo failed");
2938 0 : torture_assert_werr_ok(torture, r.out.result,
2939 : "dcerpc_wkssvc_NetWksGetInfo failed");
2940 :
2941 0 : torture_assert_str_equal(torture, servername, r.out.info->info100->server_name,
2942 : "servername RAP / DCERPC inconsistency");
2943 : }
2944 :
2945 0 : return true;
2946 : }
2947 :
2948 0 : static bool winreg_close(struct torture_context *tctx,
2949 : struct dcerpc_binding_handle *b,
2950 : struct policy_handle *handle)
2951 : {
2952 : struct winreg_CloseKey c;
2953 :
2954 0 : c.in.handle = c.out.handle = handle;
2955 :
2956 0 : torture_assert_ntstatus_ok(tctx,
2957 : dcerpc_winreg_CloseKey_r(b, tctx, &c),
2958 : "winreg_CloseKey failed");
2959 0 : torture_assert_werr_ok(tctx, c.out.result,
2960 : "winreg_CloseKey failed");
2961 :
2962 0 : return true;
2963 : }
2964 :
2965 0 : static bool enumvalues(struct torture_context *tctx,
2966 : struct dcerpc_binding_handle *b,
2967 : struct policy_handle *handle)
2968 : {
2969 0 : uint32_t enum_index = 0;
2970 :
2971 0 : while (1) {
2972 : struct winreg_EnumValue r;
2973 : struct winreg_ValNameBuf name;
2974 0 : enum winreg_Type type = 0;
2975 : uint8_t buf8[1024];
2976 : NTSTATUS status;
2977 : uint32_t size, length;
2978 :
2979 0 : ZERO_STRUCT(buf8);
2980 0 : r.in.handle = handle;
2981 0 : r.in.enum_index = enum_index;
2982 0 : name.name = "";
2983 0 : name.size = 1024;
2984 0 : r.in.name = r.out.name = &name;
2985 0 : size = 1024;
2986 0 : length = 5;
2987 0 : r.in.type = &type;
2988 0 : r.in.value = buf8;
2989 0 : r.in.size = &size;
2990 0 : r.in.length = &length;
2991 :
2992 0 : status = dcerpc_winreg_EnumValue_r(b, tctx, &r);
2993 0 : if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(r.out.result)) {
2994 0 : return true;
2995 : }
2996 0 : enum_index += 1;
2997 : }
2998 : }
2999 :
3000 0 : static bool enumkeys(struct torture_context *tctx,
3001 : struct dcerpc_binding_handle *b,
3002 : struct policy_handle *handle,
3003 : int depth)
3004 : {
3005 : struct winreg_EnumKey r;
3006 : struct winreg_StringBuf kclass, name;
3007 : NTSTATUS status;
3008 0 : NTTIME t = 0;
3009 :
3010 0 : if (depth <= 0) {
3011 0 : return true;
3012 : }
3013 :
3014 0 : kclass.name = "";
3015 0 : kclass.size = 1024;
3016 :
3017 0 : r.in.handle = handle;
3018 0 : r.in.enum_index = 0;
3019 0 : r.in.name = &name;
3020 0 : r.in.keyclass = &kclass;
3021 0 : r.out.name = &name;
3022 0 : r.in.last_changed_time = &t;
3023 :
3024 0 : do {
3025 : struct winreg_OpenKey o;
3026 : struct policy_handle key_handle;
3027 : int i;
3028 :
3029 0 : name.name = NULL;
3030 0 : name.size = 1024;
3031 :
3032 0 : status = dcerpc_winreg_EnumKey_r(b, tctx, &r);
3033 0 : if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(r.out.result)) {
3034 : /* We're done enumerating */
3035 0 : return true;
3036 : }
3037 :
3038 0 : for (i=0; i<10-depth; i++) {
3039 0 : torture_comment(tctx, " ");
3040 : }
3041 0 : torture_comment(tctx, "%s\n", r.out.name->name);
3042 :
3043 0 : o.in.parent_handle = handle;
3044 0 : o.in.keyname.name = r.out.name->name;
3045 0 : o.in.options = 0;
3046 0 : o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3047 0 : o.out.handle = &key_handle;
3048 :
3049 0 : status = dcerpc_winreg_OpenKey_r(b, tctx, &o);
3050 0 : if (NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(o.out.result)) {
3051 0 : enumkeys(tctx, b, &key_handle, depth-1);
3052 0 : enumvalues(tctx, b, &key_handle);
3053 0 : torture_assert(tctx, winreg_close(tctx, b, &key_handle), "");
3054 : }
3055 :
3056 0 : r.in.enum_index += 1;
3057 : } while(true);
3058 :
3059 : return true;
3060 : }
3061 :
3062 : typedef NTSTATUS (*winreg_open_fn)(struct dcerpc_binding_handle *, TALLOC_CTX *, void *);
3063 :
3064 0 : static bool test_Open3(struct torture_context *tctx,
3065 : struct dcerpc_binding_handle *b,
3066 : const char *name, winreg_open_fn open_fn)
3067 : {
3068 : struct policy_handle handle;
3069 : struct winreg_OpenHKLM r;
3070 :
3071 0 : r.in.system_name = 0;
3072 0 : r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3073 0 : r.out.handle = &handle;
3074 :
3075 0 : torture_assert_ntstatus_ok(tctx,
3076 : open_fn(b, tctx, &r),
3077 : talloc_asprintf(tctx, "%s failed", name));
3078 0 : torture_assert_werr_ok(tctx, r.out.result,
3079 : talloc_asprintf(tctx, "%s failed", name));
3080 :
3081 0 : enumkeys(tctx, b, &handle, 4);
3082 :
3083 0 : torture_assert(tctx,
3084 : winreg_close(tctx, b, &handle),
3085 : "dcerpc_CloseKey failed");
3086 :
3087 0 : return true;
3088 : }
3089 :
3090 0 : static bool torture_samba3_rpc_winreg(struct torture_context *torture)
3091 : {
3092 : struct dcerpc_pipe *p;
3093 : struct dcerpc_binding_handle *b;
3094 0 : bool ret = true;
3095 : struct {
3096 : const char *name;
3097 : winreg_open_fn fn;
3098 0 : } open_fns[] = {
3099 : {"OpenHKLM", (winreg_open_fn)dcerpc_winreg_OpenHKLM_r },
3100 : {"OpenHKU", (winreg_open_fn)dcerpc_winreg_OpenHKU_r },
3101 : {"OpenHKPD", (winreg_open_fn)dcerpc_winreg_OpenHKPD_r },
3102 : {"OpenHKPT", (winreg_open_fn)dcerpc_winreg_OpenHKPT_r },
3103 : {"OpenHKCR", (winreg_open_fn)dcerpc_winreg_OpenHKCR_r }};
3104 : #if 0
3105 : int i;
3106 : #endif
3107 :
3108 0 : torture_assert_ntstatus_ok(torture,
3109 : torture_rpc_connection(torture, &p, &ndr_table_winreg),
3110 : "failed to setup winreg");
3111 :
3112 0 : b = p->binding_handle;
3113 :
3114 : #if 1
3115 0 : ret = test_Open3(torture, b, open_fns[0].name, open_fns[0].fn);
3116 : #else
3117 : for (i = 0; i < ARRAY_SIZE(open_fns); i++) {
3118 : if (!test_Open3(torture, b, open_fns[i].name, open_fns[i].fn))
3119 : ret = false;
3120 : }
3121 : #endif
3122 0 : return ret;
3123 : }
3124 :
3125 0 : static bool get_shareinfo(struct torture_context *tctx,
3126 : struct dcerpc_binding_handle *b,
3127 : const char *servername,
3128 : const char *share,
3129 : struct srvsvc_NetShareInfo502 **info502)
3130 : {
3131 : struct srvsvc_NetShareGetInfo r;
3132 : union srvsvc_NetShareInfo info;
3133 :
3134 0 : r.in.server_unc = talloc_asprintf(tctx, "\\\\%s", servername);
3135 0 : r.in.share_name = share;
3136 0 : r.in.level = 502;
3137 0 : r.out.info = &info;
3138 :
3139 0 : torture_assert_ntstatus_ok(tctx,
3140 : dcerpc_srvsvc_NetShareGetInfo_r(b, tctx, &r),
3141 : "srvsvc_NetShareGetInfo failed");
3142 0 : torture_assert_werr_ok(tctx, r.out.result,
3143 : "srvsvc_NetShareGetInfo failed");
3144 :
3145 0 : *info502 = talloc_move(tctx, &info.info502);
3146 :
3147 0 : return true;
3148 : }
3149 :
3150 : /*
3151 : * Get us a handle on HKLM\
3152 : */
3153 :
3154 0 : static bool get_hklm_handle(struct torture_context *tctx,
3155 : struct dcerpc_binding_handle *b,
3156 : struct policy_handle *handle)
3157 : {
3158 : struct winreg_OpenHKLM r;
3159 : struct policy_handle result;
3160 :
3161 0 : r.in.system_name = 0;
3162 0 : r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3163 0 : r.out.handle = &result;
3164 :
3165 0 : torture_assert_ntstatus_ok(tctx,
3166 : dcerpc_winreg_OpenHKLM_r(b, tctx, &r),
3167 : "OpenHKLM failed");
3168 0 : torture_assert_werr_ok(tctx, r.out.result,
3169 : "OpenHKLM failed");
3170 :
3171 0 : *handle = result;
3172 :
3173 0 : return true;
3174 : }
3175 :
3176 0 : static bool torture_samba3_createshare(struct torture_context *tctx,
3177 : struct dcerpc_binding_handle *b,
3178 : const char *sharename)
3179 : {
3180 : struct policy_handle hklm;
3181 : struct policy_handle new_handle;
3182 : struct winreg_CreateKey c;
3183 : struct winreg_CloseKey cl;
3184 0 : enum winreg_CreateAction action_taken = REG_ACTION_NONE;
3185 :
3186 0 : ZERO_STRUCT(c);
3187 0 : ZERO_STRUCT(cl);
3188 0 : ZERO_STRUCT(hklm);
3189 0 : ZERO_STRUCT(new_handle);
3190 :
3191 0 : c.in.handle = &hklm;
3192 0 : c.in.name.name = talloc_asprintf(
3193 : tctx, "software\\samba\\smbconf\\%s", sharename);
3194 0 : torture_assert(tctx, c.in.name.name, "talloc_asprintf failed");
3195 :
3196 0 : c.in.keyclass.name = "";
3197 0 : c.in.options = 0;
3198 0 : c.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3199 0 : c.in.secdesc = NULL;
3200 0 : c.in.action_taken = &action_taken;
3201 0 : c.out.new_handle = &new_handle;
3202 0 : c.out.action_taken = &action_taken;
3203 :
3204 0 : torture_assert_ntstatus_ok(tctx,
3205 : dcerpc_winreg_CreateKey_r(b, tctx, &c),
3206 : "OpenKey failed");
3207 0 : torture_assert_werr_ok(tctx, c.out.result,
3208 : "OpenKey failed");
3209 :
3210 0 : cl.in.handle = &new_handle;
3211 0 : cl.out.handle = &new_handle;
3212 :
3213 0 : torture_assert_ntstatus_ok(tctx,
3214 : dcerpc_winreg_CloseKey_r(b, tctx, &cl),
3215 : "CloseKey failed");
3216 0 : torture_assert_werr_ok(tctx, cl.out.result,
3217 : "CloseKey failed");
3218 :
3219 0 : return true;
3220 : }
3221 :
3222 0 : static bool torture_samba3_deleteshare(struct torture_context *tctx,
3223 : struct dcerpc_binding_handle *b,
3224 : const char *sharename)
3225 : {
3226 : struct policy_handle hklm;
3227 : struct winreg_DeleteKey d;
3228 :
3229 0 : torture_assert(tctx,
3230 : get_hklm_handle(tctx, b, &hklm),
3231 : "get_hklm_handle failed");
3232 :
3233 0 : d.in.handle = &hklm;
3234 0 : d.in.key.name = talloc_asprintf(
3235 : tctx, "software\\samba\\smbconf\\%s", sharename);
3236 0 : torture_assert(tctx, d.in.key.name, "talloc_asprintf failed");
3237 :
3238 0 : torture_assert_ntstatus_ok(tctx,
3239 : dcerpc_winreg_DeleteKey_r(b, tctx, &d),
3240 : "DeleteKey failed");
3241 0 : torture_assert_werr_ok(tctx, d.out.result,
3242 : "DeleteKey failed");
3243 :
3244 0 : return true;
3245 : }
3246 :
3247 0 : static bool torture_samba3_setconfig(struct torture_context *tctx,
3248 : struct dcerpc_binding_handle *b,
3249 : const char *sharename,
3250 : const char *parameter,
3251 : const char *value)
3252 : {
3253 : struct policy_handle hklm, key_handle;
3254 : struct winreg_OpenKey o;
3255 : struct winreg_SetValue s;
3256 : uint32_t type;
3257 : DATA_BLOB val;
3258 :
3259 0 : torture_assert(tctx,
3260 : get_hklm_handle(tctx, b, &hklm),
3261 : "get_hklm_handle failed");
3262 :
3263 0 : o.in.parent_handle = &hklm;
3264 0 : o.in.keyname.name = talloc_asprintf(
3265 : tctx, "software\\samba\\smbconf\\%s", sharename);
3266 0 : torture_assert(tctx, o.in.keyname.name, "talloc_asprintf failed");
3267 :
3268 0 : o.in.options = 0;
3269 0 : o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3270 0 : o.out.handle = &key_handle;
3271 :
3272 0 : torture_assert_ntstatus_ok(tctx,
3273 : dcerpc_winreg_OpenKey_r(b, tctx, &o),
3274 : "OpenKey failed");
3275 0 : torture_assert_werr_ok(tctx, o.out.result,
3276 : "OpenKey failed");
3277 :
3278 0 : torture_assert(tctx,
3279 : reg_string_to_val(tctx, "REG_SZ", value, &type, &val),
3280 : "reg_string_to_val failed");
3281 :
3282 0 : s.in.handle = &key_handle;
3283 0 : s.in.name.name = parameter;
3284 0 : s.in.type = type;
3285 0 : s.in.data = val.data;
3286 0 : s.in.size = val.length;
3287 :
3288 0 : torture_assert_ntstatus_ok(tctx,
3289 : dcerpc_winreg_SetValue_r(b, tctx, &s),
3290 : "SetValue failed");
3291 0 : torture_assert_werr_ok(tctx, s.out.result,
3292 : "SetValue failed");
3293 :
3294 0 : return true;
3295 : }
3296 :
3297 0 : static bool torture_samba3_regconfig(struct torture_context *torture)
3298 : {
3299 0 : struct srvsvc_NetShareInfo502 *i = NULL;
3300 0 : const char *comment = "Dummer Kommentar";
3301 : struct dcerpc_pipe *srvsvc_pipe, *winreg_pipe;
3302 :
3303 0 : torture_assert_ntstatus_ok(torture,
3304 : torture_rpc_connection(torture, &srvsvc_pipe, &ndr_table_srvsvc),
3305 : "failed to setup srvsvc");
3306 :
3307 0 : torture_assert_ntstatus_ok(torture,
3308 : torture_rpc_connection(torture, &winreg_pipe, &ndr_table_winreg),
3309 : "failed to setup winreg");
3310 :
3311 0 : torture_assert(torture,
3312 : torture_samba3_createshare(torture, winreg_pipe->binding_handle, "blubber"),
3313 : "torture_samba3_createshare failed");
3314 :
3315 0 : torture_assert(torture,
3316 : torture_samba3_setconfig(torture, winreg_pipe->binding_handle, "blubber", "comment", comment),
3317 : "torture_samba3_setconfig failed");
3318 :
3319 0 : torture_assert(torture,
3320 : get_shareinfo(torture, srvsvc_pipe->binding_handle, dcerpc_server_name(srvsvc_pipe), "blubber", &i),
3321 : "get_shareinfo failed");
3322 :
3323 0 : torture_assert_str_equal(torture, comment, i->comment,
3324 : "got unexpected comment");
3325 :
3326 0 : torture_assert(torture,
3327 : torture_samba3_deleteshare(torture, winreg_pipe->binding_handle, "blubber"),
3328 : "torture_samba3_deleteshare failed");
3329 :
3330 0 : return true;
3331 : }
3332 :
3333 : /*
3334 : * Test that even with a result of 0 rids the array is returned as a
3335 : * non-NULL pointer. Yes, XP does notice.
3336 : */
3337 :
3338 0 : bool torture_samba3_getaliasmembership_0(struct torture_context *torture)
3339 : {
3340 : struct dcerpc_pipe *p;
3341 : struct dcerpc_binding_handle *b;
3342 : struct samr_Connect2 c;
3343 : struct samr_OpenDomain o;
3344 : struct dom_sid sid;
3345 : struct lsa_SidPtr ptr;
3346 : struct lsa_SidArray sids;
3347 : struct samr_GetAliasMembership g;
3348 : struct samr_Ids rids;
3349 : struct policy_handle samr, domain;
3350 :
3351 0 : torture_assert_ntstatus_ok(torture,
3352 : torture_rpc_connection(torture, &p, &ndr_table_samr),
3353 : "failed to setup samr");
3354 :
3355 0 : b = p->binding_handle;
3356 :
3357 0 : c.in.system_name = NULL;
3358 0 : c.in.access_mask = SAMR_ACCESS_LOOKUP_DOMAIN;
3359 0 : c.out.connect_handle = &samr;
3360 0 : torture_assert_ntstatus_ok(torture,
3361 : dcerpc_samr_Connect2_r(b, torture, &c),
3362 : "");
3363 0 : torture_assert_ntstatus_ok(torture, c.out.result,
3364 : "");
3365 0 : dom_sid_parse("S-1-5-32", &sid);
3366 0 : o.in.connect_handle = &samr;
3367 0 : o.in.access_mask = SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS;
3368 0 : o.in.sid = &sid;
3369 0 : o.out.domain_handle = &domain;
3370 0 : torture_assert_ntstatus_ok(torture,
3371 : dcerpc_samr_OpenDomain_r(b, torture, &o),
3372 : "");
3373 0 : torture_assert_ntstatus_ok(torture, o.out.result,
3374 : "");
3375 0 : dom_sid_parse("S-1-2-3-4-5", &sid);
3376 0 : ptr.sid = &sid;
3377 0 : sids.num_sids = 1;
3378 0 : sids.sids = &ptr;
3379 0 : g.in.domain_handle = &domain;
3380 0 : g.in.sids = &sids;
3381 0 : g.out.rids = &rids;
3382 0 : torture_assert_ntstatus_ok(torture,
3383 : dcerpc_samr_GetAliasMembership_r(b, torture, &g),
3384 : "");
3385 0 : torture_assert_ntstatus_ok(torture, g.out.result,
3386 : "");
3387 0 : if (rids.ids == NULL) {
3388 : /* This is the piece to test here */
3389 0 : torture_fail(torture,
3390 : "torture_samba3_getaliasmembership_0: "
3391 : "Server returns NULL rids array\n");
3392 : }
3393 :
3394 0 : return true;
3395 : }
3396 :
3397 : /**
3398 : * Test smb reauthentication while rpc pipe is in use.
3399 : */
3400 0 : static bool torture_rpc_smb_reauth1(struct torture_context *torture)
3401 : {
3402 : TALLOC_CTX *mem_ctx;
3403 : NTSTATUS status;
3404 0 : bool ret = false;
3405 : struct smbcli_state *cli;
3406 : struct smbcli_options options;
3407 : struct smbcli_session_options session_options;
3408 :
3409 : struct dcerpc_pipe *lsa_pipe;
3410 : struct dcerpc_binding_handle *lsa_handle;
3411 : struct lsa_GetUserName r;
3412 0 : struct lsa_String *authority_name_p = NULL;
3413 0 : char *authority_name_saved = NULL;
3414 0 : struct lsa_String *account_name_p = NULL;
3415 0 : char *account_name_saved = NULL;
3416 0 : struct cli_credentials *anon_creds = NULL;
3417 : struct smb_composite_sesssetup io;
3418 :
3419 0 : mem_ctx = talloc_init("torture_samba3_reauth");
3420 0 : torture_assert(torture, (mem_ctx != NULL), "talloc_init failed");
3421 :
3422 0 : lpcfg_smbcli_options(torture->lp_ctx, &options);
3423 0 : lpcfg_smbcli_session_options(torture->lp_ctx, &session_options);
3424 :
3425 0 : status = smbcli_full_connection(mem_ctx, &cli,
3426 : torture_setting_string(torture, "host", NULL),
3427 : lpcfg_smb_ports(torture->lp_ctx),
3428 : "IPC$", NULL,
3429 : lpcfg_socket_options(torture->lp_ctx),
3430 : samba_cmdline_get_creds(),
3431 : lpcfg_resolve_context(torture->lp_ctx),
3432 : torture->ev, &options, &session_options,
3433 : lpcfg_gensec_settings(torture, torture->lp_ctx));
3434 0 : torture_assert_ntstatus_ok_goto(torture, status, ret, done,
3435 : "smbcli_full_connection failed");
3436 :
3437 0 : status = pipe_bind_smb(torture, mem_ctx, cli->tree, "\\lsarpc",
3438 : &ndr_table_lsarpc, &lsa_pipe);
3439 0 : torture_assert_ntstatus_ok_goto(torture, status, ret, done,
3440 : "pipe_bind_smb failed");
3441 0 : lsa_handle = lsa_pipe->binding_handle;
3442 :
3443 : /* lsa getusername */
3444 :
3445 0 : ZERO_STRUCT(r);
3446 0 : r.in.system_name = "\\";
3447 0 : r.in.account_name = &account_name_p;
3448 0 : r.in.authority_name = &authority_name_p;
3449 0 : r.out.account_name = &account_name_p;
3450 :
3451 0 : status = dcerpc_lsa_GetUserName_r(lsa_handle, mem_ctx, &r);
3452 :
3453 0 : authority_name_p = *r.out.authority_name;
3454 :
3455 0 : torture_assert_ntstatus_ok_goto(torture, status, ret, done,
3456 : "GetUserName failed");
3457 0 : torture_assert_ntstatus_ok_goto(torture, r.out.result, ret, done,
3458 : "GetUserName failed");
3459 :
3460 0 : torture_comment(torture, "lsa_GetUserName gave '%s\\%s'\n",
3461 0 : authority_name_p->string,
3462 0 : account_name_p->string);
3463 :
3464 0 : account_name_saved = talloc_strdup(mem_ctx, account_name_p->string);
3465 0 : torture_assert_goto(torture, (account_name_saved != NULL), ret, done,
3466 : "talloc failed");
3467 0 : authority_name_saved = talloc_strdup(mem_ctx, authority_name_p->string);
3468 0 : torture_assert_goto(torture, (authority_name_saved != NULL), ret, done,
3469 : "talloc failed");
3470 :
3471 : /* smb re-authenticate as anonymous */
3472 :
3473 0 : anon_creds = cli_credentials_init_anon(mem_ctx);
3474 :
3475 0 : ZERO_STRUCT(io);
3476 0 : io.in.sesskey = cli->transport->negotiate.sesskey;
3477 0 : io.in.capabilities = cli->transport->negotiate.capabilities;
3478 0 : io.in.credentials = anon_creds;
3479 0 : io.in.workgroup = lpcfg_workgroup(torture->lp_ctx);
3480 0 : io.in.gensec_settings = lpcfg_gensec_settings(torture, torture->lp_ctx);
3481 :
3482 0 : status = smb_composite_sesssetup(cli->session, &io);
3483 0 : torture_assert_ntstatus_ok_goto(torture, status, ret, done,
3484 : "session reauth to anon failed");
3485 :
3486 : /* re-do lsa getusername after reauth */
3487 :
3488 0 : TALLOC_FREE(authority_name_p);
3489 0 : TALLOC_FREE(account_name_p);
3490 0 : ZERO_STRUCT(r);
3491 0 : r.in.system_name = "\\";
3492 0 : r.in.account_name = &account_name_p;
3493 0 : r.in.authority_name = &authority_name_p;
3494 0 : r.out.account_name = &account_name_p;
3495 :
3496 0 : status = dcerpc_lsa_GetUserName_r(lsa_handle, mem_ctx, &r);
3497 :
3498 0 : authority_name_p = *r.out.authority_name;
3499 :
3500 0 : torture_assert_ntstatus_ok_goto(torture, status, ret, done,
3501 : "GetUserName failed");
3502 0 : torture_assert_ntstatus_ok_goto(torture, r.out.result, ret, done,
3503 : "GetUserName failed");
3504 :
3505 0 : torture_assert_goto(torture, (strcmp(authority_name_p->string, authority_name_saved) == 0),
3506 : ret, done, "authority_name not equal after reauth to anon");
3507 0 : torture_assert_goto(torture, (strcmp(account_name_p->string, account_name_saved) == 0),
3508 : ret, done, "account_name not equal after reauth to anon");
3509 :
3510 : /* smb re-auth again to the original user */
3511 :
3512 0 : ZERO_STRUCT(io);
3513 0 : io.in.sesskey = cli->transport->negotiate.sesskey;
3514 0 : io.in.capabilities = cli->transport->negotiate.capabilities;
3515 0 : io.in.credentials = samba_cmdline_get_creds();
3516 0 : io.in.workgroup = lpcfg_workgroup(torture->lp_ctx);
3517 0 : io.in.gensec_settings = lpcfg_gensec_settings(torture, torture->lp_ctx);
3518 :
3519 0 : status = smb_composite_sesssetup(cli->session, &io);
3520 0 : torture_assert_ntstatus_ok_goto(torture, status, ret, done,
3521 : "session reauth to anon failed");
3522 :
3523 : /* re-do lsa getusername */
3524 :
3525 0 : TALLOC_FREE(authority_name_p);
3526 0 : TALLOC_FREE(account_name_p);
3527 0 : ZERO_STRUCT(r);
3528 0 : r.in.system_name = "\\";
3529 0 : r.in.account_name = &account_name_p;
3530 0 : r.in.authority_name = &authority_name_p;
3531 0 : r.out.account_name = &account_name_p;
3532 :
3533 0 : status = dcerpc_lsa_GetUserName_r(lsa_handle, mem_ctx, &r);
3534 :
3535 0 : authority_name_p = *r.out.authority_name;
3536 :
3537 0 : torture_assert_ntstatus_ok_goto(torture, status, ret, done,
3538 : "GetUserName failed");
3539 0 : torture_assert_ntstatus_ok_goto(torture, r.out.result, ret, done,
3540 : "GetUserName failed");
3541 :
3542 0 : torture_assert_goto(torture, (strcmp(authority_name_p->string, authority_name_saved) == 0),
3543 : ret, done, "authority_name not equal after reauth to anon");
3544 0 : torture_assert_goto(torture, (strcmp(account_name_p->string, account_name_saved) == 0),
3545 : ret, done, "account_name not equal after reauth to anon");
3546 :
3547 0 : ret = true;
3548 :
3549 0 : done:
3550 0 : talloc_free(mem_ctx);
3551 0 : return ret;
3552 : }
3553 :
3554 : /**
3555 : * Test smb reauthentication while rpc pipe is in use.
3556 : * Open a second lsa bind after reauth to anon.
3557 : * Do lsa getusername on that second bind.
3558 : */
3559 0 : static bool torture_rpc_smb_reauth2(struct torture_context *torture)
3560 : {
3561 : TALLOC_CTX *mem_ctx;
3562 : NTSTATUS status;
3563 0 : bool ret = false;
3564 : struct smbcli_state *cli;
3565 : struct smbcli_options options;
3566 : struct smbcli_session_options session_options;
3567 :
3568 : struct dcerpc_pipe *lsa_pipe;
3569 : struct dcerpc_binding_handle *lsa_handle;
3570 : struct lsa_GetUserName r;
3571 0 : struct lsa_String *authority_name_p = NULL;
3572 0 : char *authority_name_saved = NULL;
3573 0 : struct lsa_String *account_name_p = NULL;
3574 0 : char *account_name_saved = NULL;
3575 0 : struct cli_credentials *anon_creds = NULL;
3576 : struct smb_composite_sesssetup io;
3577 :
3578 0 : mem_ctx = talloc_init("torture_samba3_reauth");
3579 0 : torture_assert(torture, (mem_ctx != NULL), "talloc_init failed");
3580 :
3581 0 : lpcfg_smbcli_options(torture->lp_ctx, &options);
3582 0 : lpcfg_smbcli_session_options(torture->lp_ctx, &session_options);
3583 :
3584 0 : status = smbcli_full_connection(mem_ctx, &cli,
3585 : torture_setting_string(torture, "host", NULL),
3586 : lpcfg_smb_ports(torture->lp_ctx),
3587 : "IPC$", NULL,
3588 : lpcfg_socket_options(torture->lp_ctx),
3589 : samba_cmdline_get_creds(),
3590 : lpcfg_resolve_context(torture->lp_ctx),
3591 : torture->ev, &options, &session_options,
3592 : lpcfg_gensec_settings(torture, torture->lp_ctx));
3593 0 : torture_assert_ntstatus_ok_goto(torture, status, ret, done,
3594 : "smbcli_full_connection failed");
3595 :
3596 : /* smb re-authenticate as anonymous */
3597 :
3598 0 : anon_creds = cli_credentials_init_anon(mem_ctx);
3599 :
3600 0 : ZERO_STRUCT(io);
3601 0 : io.in.sesskey = cli->transport->negotiate.sesskey;
3602 0 : io.in.capabilities = cli->transport->negotiate.capabilities;
3603 0 : io.in.credentials = anon_creds;
3604 0 : io.in.workgroup = lpcfg_workgroup(torture->lp_ctx);
3605 0 : io.in.gensec_settings = lpcfg_gensec_settings(torture, torture->lp_ctx);
3606 :
3607 0 : status = smb_composite_sesssetup(cli->session, &io);
3608 0 : torture_assert_ntstatus_ok_goto(torture, status, ret, done,
3609 : "session reauth to anon failed");
3610 :
3611 : /* open the lsa pipe */
3612 :
3613 0 : status = pipe_bind_smb(torture, mem_ctx, cli->tree, "\\lsarpc",
3614 : &ndr_table_lsarpc, &lsa_pipe);
3615 0 : torture_assert_ntstatus_ok_goto(torture, status, ret, done,
3616 : "pipe_bind_smb failed");
3617 0 : lsa_handle = lsa_pipe->binding_handle;
3618 :
3619 : /* lsa getusername */
3620 :
3621 0 : ZERO_STRUCT(r);
3622 0 : r.in.system_name = "\\";
3623 0 : r.in.account_name = &account_name_p;
3624 0 : r.in.authority_name = &authority_name_p;
3625 0 : r.out.account_name = &account_name_p;
3626 :
3627 0 : status = dcerpc_lsa_GetUserName_r(lsa_handle, mem_ctx, &r);
3628 :
3629 0 : authority_name_p = *r.out.authority_name;
3630 :
3631 0 : torture_assert_ntstatus_ok_goto(torture, status, ret, done,
3632 : "GetUserName failed");
3633 0 : torture_assert_ntstatus_ok_goto(torture, r.out.result, ret, done,
3634 : "GetUserName failed");
3635 :
3636 0 : torture_comment(torture, "lsa_GetUserName gave '%s\\%s'\n",
3637 0 : authority_name_p->string,
3638 0 : account_name_p->string);
3639 :
3640 0 : account_name_saved = talloc_strdup(mem_ctx, account_name_p->string);
3641 0 : torture_assert_goto(torture, (account_name_saved != NULL), ret, done,
3642 : "talloc failed");
3643 0 : authority_name_saved = talloc_strdup(mem_ctx, authority_name_p->string);
3644 0 : torture_assert_goto(torture, (authority_name_saved != NULL), ret, done,
3645 : "talloc failed");
3646 :
3647 : /* smb re-auth again to the original user */
3648 :
3649 0 : ZERO_STRUCT(io);
3650 0 : io.in.sesskey = cli->transport->negotiate.sesskey;
3651 0 : io.in.capabilities = cli->transport->negotiate.capabilities;
3652 0 : io.in.credentials = samba_cmdline_get_creds();
3653 0 : io.in.workgroup = lpcfg_workgroup(torture->lp_ctx);
3654 0 : io.in.gensec_settings = lpcfg_gensec_settings(torture, torture->lp_ctx);
3655 :
3656 0 : status = smb_composite_sesssetup(cli->session, &io);
3657 0 : torture_assert_ntstatus_ok_goto(torture, status, ret, done,
3658 : "session reauth to anon failed");
3659 :
3660 : /* re-do lsa getusername after reauth */
3661 :
3662 0 : TALLOC_FREE(authority_name_p);
3663 0 : TALLOC_FREE(account_name_p);
3664 0 : ZERO_STRUCT(r);
3665 0 : r.in.system_name = "\\";
3666 0 : r.in.account_name = &account_name_p;
3667 0 : r.in.authority_name = &authority_name_p;
3668 0 : r.out.account_name = &account_name_p;
3669 :
3670 0 : status = dcerpc_lsa_GetUserName_r(lsa_handle, mem_ctx, &r);
3671 :
3672 0 : authority_name_p = *r.out.authority_name;
3673 :
3674 0 : torture_assert_ntstatus_ok_goto(torture, status, ret, done,
3675 : "GetUserName failed");
3676 0 : torture_assert_ntstatus_ok_goto(torture, r.out.result, ret, done,
3677 : "GetUserName failed");
3678 :
3679 0 : torture_assert_goto(torture, (strcmp(authority_name_p->string, authority_name_saved) == 0),
3680 : ret, done, "authority_name not equal after reauth to anon");
3681 0 : torture_assert_goto(torture, (strcmp(account_name_p->string, account_name_saved) == 0),
3682 : ret, done, "account_name not equal after reauth to anon");
3683 :
3684 0 : ret = true;
3685 :
3686 0 : done:
3687 0 : talloc_free(mem_ctx);
3688 0 : return ret;
3689 : }
3690 :
3691 : /**
3692 : * Test smb2 reauthentication while rpc pipe is in use.
3693 : */
3694 0 : static bool torture_rpc_smb2_reauth1(struct torture_context *torture)
3695 : {
3696 : TALLOC_CTX *mem_ctx;
3697 : NTSTATUS status;
3698 0 : bool ret = false;
3699 : struct smbcli_options options;
3700 :
3701 : struct dcerpc_pipe *lsa_pipe;
3702 : struct dcerpc_binding_handle *lsa_handle;
3703 : struct lsa_GetUserName r;
3704 0 : struct lsa_String *authority_name_p = NULL;
3705 0 : char *authority_name_saved = NULL;
3706 0 : struct lsa_String *account_name_p = NULL;
3707 0 : char *account_name_saved = NULL;
3708 0 : struct cli_credentials *anon_creds = NULL;
3709 0 : const char *host = torture_setting_string(torture, "host", NULL);
3710 : struct smb2_tree *tree;
3711 :
3712 0 : mem_ctx = talloc_init("torture_samba3_reauth");
3713 0 : torture_assert(torture, (mem_ctx != NULL), "talloc_init failed");
3714 :
3715 0 : lpcfg_smbcli_options(torture->lp_ctx, &options);
3716 :
3717 0 : status = smb2_connect(mem_ctx,
3718 : host,
3719 : lpcfg_smb_ports(torture->lp_ctx),
3720 : "IPC$",
3721 : lpcfg_resolve_context(torture->lp_ctx),
3722 : samba_cmdline_get_creds(),
3723 : &tree,
3724 : torture->ev,
3725 : &options,
3726 : lpcfg_socket_options(torture->lp_ctx),
3727 : lpcfg_gensec_settings(torture, torture->lp_ctx)
3728 : );
3729 0 : torture_assert_ntstatus_ok_goto(torture, status, ret, done,
3730 : "smb2_connect failed");
3731 :
3732 0 : status = pipe_bind_smb2(torture, mem_ctx, tree, "lsarpc",
3733 : &ndr_table_lsarpc, &lsa_pipe);
3734 0 : torture_assert_ntstatus_ok_goto(torture, status, ret, done,
3735 : "pipe_bind_smb2 failed");
3736 0 : lsa_handle = lsa_pipe->binding_handle;
3737 :
3738 : /* lsa getusername */
3739 :
3740 0 : ZERO_STRUCT(r);
3741 0 : r.in.system_name = "\\";
3742 0 : r.in.account_name = &account_name_p;
3743 0 : r.in.authority_name = &authority_name_p;
3744 0 : r.out.account_name = &account_name_p;
3745 :
3746 0 : status = dcerpc_lsa_GetUserName_r(lsa_handle, mem_ctx, &r);
3747 :
3748 0 : authority_name_p = *r.out.authority_name;
3749 :
3750 0 : torture_assert_ntstatus_ok_goto(torture, status, ret, done,
3751 : "GetUserName failed");
3752 0 : torture_assert_ntstatus_ok_goto(torture, r.out.result, ret, done,
3753 : "GetUserName failed");
3754 :
3755 0 : torture_comment(torture, "lsa_GetUserName gave '%s\\%s'\n",
3756 0 : authority_name_p->string,
3757 0 : account_name_p->string);
3758 :
3759 0 : account_name_saved = talloc_strdup(mem_ctx, account_name_p->string);
3760 0 : torture_assert_goto(torture, (account_name_saved != NULL), ret, done,
3761 : "talloc failed");
3762 0 : authority_name_saved = talloc_strdup(mem_ctx, authority_name_p->string);
3763 0 : torture_assert_goto(torture, (authority_name_saved != NULL), ret, done,
3764 : "talloc failed");
3765 :
3766 : /* smb re-authenticate as anonymous */
3767 :
3768 0 : anon_creds = cli_credentials_init_anon(mem_ctx);
3769 :
3770 0 : status = smb2_session_setup_spnego(tree->session,
3771 : anon_creds,
3772 : 0 /* previous_session_id */);
3773 0 : torture_assert_ntstatus_ok_goto(torture, status, ret, done,
3774 : "session reauth to anon failed");
3775 :
3776 : /* re-do lsa getusername after reauth */
3777 :
3778 0 : TALLOC_FREE(authority_name_p);
3779 0 : TALLOC_FREE(account_name_p);
3780 0 : ZERO_STRUCT(r);
3781 0 : r.in.system_name = "\\";
3782 0 : r.in.account_name = &account_name_p;
3783 0 : r.in.authority_name = &authority_name_p;
3784 0 : r.out.account_name = &account_name_p;
3785 :
3786 0 : status = dcerpc_lsa_GetUserName_r(lsa_handle, mem_ctx, &r);
3787 :
3788 0 : authority_name_p = *r.out.authority_name;
3789 :
3790 0 : torture_assert_ntstatus_ok_goto(torture, status, ret, done,
3791 : "GetUserName failed");
3792 0 : torture_assert_ntstatus_ok_goto(torture, r.out.result, ret, done,
3793 : "GetUserName failed");
3794 :
3795 0 : torture_assert_goto(torture, (strcmp(authority_name_p->string, authority_name_saved) == 0),
3796 : ret, done, "authority_name not equal after reauth to anon");
3797 0 : torture_assert_goto(torture, (strcmp(account_name_p->string, account_name_saved) == 0),
3798 : ret, done, "account_name not equal after reauth to anon");
3799 :
3800 : /* smb re-auth again to the original user */
3801 :
3802 0 : status = smb2_session_setup_spnego(tree->session,
3803 : samba_cmdline_get_creds(),
3804 : 0 /* previous_session_id */);
3805 0 : torture_assert_ntstatus_ok_goto(torture, status, ret, done,
3806 : "session reauth to anon failed");
3807 :
3808 : /* re-do lsa getusername */
3809 :
3810 0 : TALLOC_FREE(authority_name_p);
3811 0 : TALLOC_FREE(account_name_p);
3812 0 : ZERO_STRUCT(r);
3813 0 : r.in.system_name = "\\";
3814 0 : r.in.account_name = &account_name_p;
3815 0 : r.in.authority_name = &authority_name_p;
3816 0 : r.out.account_name = &account_name_p;
3817 :
3818 0 : status = dcerpc_lsa_GetUserName_r(lsa_handle, mem_ctx, &r);
3819 :
3820 0 : authority_name_p = *r.out.authority_name;
3821 :
3822 0 : torture_assert_ntstatus_ok_goto(torture, status, ret, done,
3823 : "GetUserName failed");
3824 0 : torture_assert_ntstatus_ok_goto(torture, r.out.result, ret, done,
3825 : "GetUserName failed");
3826 :
3827 0 : torture_assert_goto(torture, (strcmp(authority_name_p->string, authority_name_saved) == 0),
3828 : ret, done, "authority_name not equal after reauth to anon");
3829 0 : torture_assert_goto(torture, (strcmp(account_name_p->string, account_name_saved) == 0),
3830 : ret, done, "account_name not equal after reauth to anon");
3831 :
3832 0 : ret = true;
3833 :
3834 0 : done:
3835 0 : talloc_free(mem_ctx);
3836 0 : return ret;
3837 : }
3838 :
3839 : /**
3840 : * Test smb2 reauthentication while rpc pipe is in use.
3841 : * Open a second lsa bind after reauth to anon.
3842 : * Do lsa getusername on that second bind.
3843 : */
3844 0 : static bool torture_rpc_smb2_reauth2(struct torture_context *torture)
3845 : {
3846 : TALLOC_CTX *mem_ctx;
3847 : NTSTATUS status;
3848 0 : bool ret = false;
3849 : struct smbcli_options options;
3850 :
3851 : struct dcerpc_pipe *lsa_pipe;
3852 : struct dcerpc_binding_handle *lsa_handle;
3853 : struct lsa_GetUserName r;
3854 0 : struct lsa_String *authority_name_p = NULL;
3855 0 : char *authority_name_saved = NULL;
3856 0 : struct lsa_String *account_name_p = NULL;
3857 0 : char *account_name_saved = NULL;
3858 0 : struct cli_credentials *anon_creds = NULL;
3859 0 : const char *host = torture_setting_string(torture, "host", NULL);
3860 : struct smb2_tree *tree;
3861 :
3862 0 : mem_ctx = talloc_init("torture_samba3_reauth");
3863 0 : torture_assert(torture, (mem_ctx != NULL), "talloc_init failed");
3864 :
3865 0 : lpcfg_smbcli_options(torture->lp_ctx, &options);
3866 :
3867 0 : status = smb2_connect(mem_ctx,
3868 : host,
3869 : lpcfg_smb_ports(torture->lp_ctx),
3870 : "IPC$",
3871 : lpcfg_resolve_context(torture->lp_ctx),
3872 : samba_cmdline_get_creds(),
3873 : &tree,
3874 : torture->ev,
3875 : &options,
3876 : lpcfg_socket_options(torture->lp_ctx),
3877 : lpcfg_gensec_settings(torture, torture->lp_ctx)
3878 : );
3879 0 : torture_assert_ntstatus_ok_goto(torture, status, ret, done,
3880 : "smb2_connect failed");
3881 :
3882 : /* smb re-authenticate as anonymous */
3883 :
3884 0 : anon_creds = cli_credentials_init_anon(mem_ctx);
3885 :
3886 0 : status = smb2_session_setup_spnego(tree->session,
3887 : anon_creds,
3888 : 0 /* previous_session_id */);
3889 0 : torture_assert_ntstatus_ok_goto(torture, status, ret, done,
3890 : "session reauth to anon failed");
3891 :
3892 : /* open the lsa pipe */
3893 :
3894 0 : status = pipe_bind_smb2(torture, mem_ctx, tree, "lsarpc",
3895 : &ndr_table_lsarpc, &lsa_pipe);
3896 0 : torture_assert_ntstatus_ok_goto(torture, status, ret, done,
3897 : "pipe_bind_smb2 failed");
3898 0 : lsa_handle = lsa_pipe->binding_handle;
3899 :
3900 : /* lsa getusername */
3901 :
3902 0 : ZERO_STRUCT(r);
3903 0 : r.in.system_name = "\\";
3904 0 : r.in.account_name = &account_name_p;
3905 0 : r.in.authority_name = &authority_name_p;
3906 0 : r.out.account_name = &account_name_p;
3907 :
3908 0 : status = dcerpc_lsa_GetUserName_r(lsa_handle, mem_ctx, &r);
3909 :
3910 0 : authority_name_p = *r.out.authority_name;
3911 :
3912 0 : torture_assert_ntstatus_ok_goto(torture, status, ret, done,
3913 : "GetUserName failed");
3914 0 : torture_assert_ntstatus_ok_goto(torture, r.out.result, ret, done,
3915 : "GetUserName failed");
3916 :
3917 0 : torture_comment(torture, "lsa_GetUserName gave '%s\\%s'\n",
3918 0 : authority_name_p->string,
3919 0 : account_name_p->string);
3920 :
3921 0 : account_name_saved = talloc_strdup(mem_ctx, account_name_p->string);
3922 0 : torture_assert_goto(torture, (account_name_saved != NULL), ret, done,
3923 : "talloc failed");
3924 0 : authority_name_saved = talloc_strdup(mem_ctx, authority_name_p->string);
3925 0 : torture_assert_goto(torture, (authority_name_saved != NULL), ret, done,
3926 : "talloc failed");
3927 :
3928 : /* smb re-auth again to the original user */
3929 :
3930 0 : status = smb2_session_setup_spnego(tree->session,
3931 : samba_cmdline_get_creds(),
3932 : 0 /* previous_session_id */);
3933 0 : torture_assert_ntstatus_ok_goto(torture, status, ret, done,
3934 : "session reauth to anon failed");
3935 :
3936 : /* re-do lsa getusername */
3937 :
3938 0 : TALLOC_FREE(authority_name_p);
3939 0 : TALLOC_FREE(account_name_p);
3940 0 : ZERO_STRUCT(r);
3941 0 : r.in.system_name = "\\";
3942 0 : r.in.account_name = &account_name_p;
3943 0 : r.in.authority_name = &authority_name_p;
3944 0 : r.out.account_name = &account_name_p;
3945 :
3946 0 : status = dcerpc_lsa_GetUserName_r(lsa_handle, mem_ctx, &r);
3947 :
3948 0 : authority_name_p = *r.out.authority_name;
3949 :
3950 0 : torture_assert_ntstatus_ok_goto(torture, status, ret, done,
3951 : "GetUserName failed");
3952 0 : torture_assert_ntstatus_ok_goto(torture, r.out.result, ret, done,
3953 : "GetUserName failed");
3954 :
3955 0 : torture_assert_goto(torture, (strcmp(authority_name_p->string, authority_name_saved) == 0),
3956 : ret, done, "authority_name not equal after reauth to anon");
3957 0 : torture_assert_goto(torture, (strcmp(account_name_p->string, account_name_saved) == 0),
3958 : ret, done, "account_name not equal after reauth to anon");
3959 :
3960 0 : ret = true;
3961 :
3962 0 : done:
3963 0 : talloc_free(mem_ctx);
3964 0 : return ret;
3965 : }
3966 :
3967 0 : static bool torture_rpc_smb1_pipe_name(struct torture_context *torture)
3968 : {
3969 : TALLOC_CTX *mem_ctx;
3970 : NTSTATUS status;
3971 0 : bool ret = false;
3972 : struct smbcli_state *cli;
3973 : struct smbcli_options options;
3974 : struct smbcli_session_options session_options;
3975 : union smb_open io;
3976 : union smb_close cl;
3977 : uint16_t fnum;
3978 :
3979 0 : mem_ctx = talloc_init("torture_samba3_smb1_pipe_name");
3980 0 : torture_assert(torture, (mem_ctx != NULL), "talloc_init failed");
3981 :
3982 0 : lpcfg_smbcli_options(torture->lp_ctx, &options);
3983 0 : lpcfg_smbcli_session_options(torture->lp_ctx, &session_options);
3984 :
3985 0 : status = smbcli_full_connection(mem_ctx, &cli,
3986 : torture_setting_string(torture, "host", NULL),
3987 : lpcfg_smb_ports(torture->lp_ctx),
3988 : "IPC$", NULL,
3989 : lpcfg_socket_options(torture->lp_ctx),
3990 : samba_cmdline_get_creds(),
3991 : lpcfg_resolve_context(torture->lp_ctx),
3992 : torture->ev, &options, &session_options,
3993 : lpcfg_gensec_settings(torture, torture->lp_ctx));
3994 0 : torture_assert_ntstatus_ok_goto(torture, status, ret, done,
3995 : "smbcli_full_connection failed");
3996 :
3997 0 : ZERO_STRUCT(io);
3998 0 : io.generic.level = RAW_OPEN_NTCREATEX;
3999 0 : io.ntcreatex.in.access_mask = DESIRED_ACCESS_PIPE;
4000 0 : io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
4001 : NTCREATEX_SHARE_ACCESS_WRITE;
4002 0 : io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
4003 0 : io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_IMPERSONATION;
4004 0 : io.ntcreatex.in.security_flags = 0;
4005 :
4006 0 : io.ntcreatex.in.fname = "__none__";
4007 0 : status = smb_raw_open(cli->tree, torture, &io);
4008 0 : torture_assert_ntstatus_equal_goto(torture, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
4009 : ret, done,
4010 : "smb_raw_open for '__none__'");
4011 :
4012 0 : io.ntcreatex.in.fname = "pipe\\srvsvc";
4013 0 : status = smb_raw_open(cli->tree, torture, &io);
4014 0 : torture_assert_ntstatus_equal_goto(torture, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
4015 : ret, done,
4016 : "smb_raw_open for 'pipe\\srvsvc'");
4017 :
4018 0 : io.ntcreatex.in.fname = "\\pipe\\srvsvc";
4019 0 : status = smb_raw_open(cli->tree, torture, &io);
4020 0 : torture_assert_ntstatus_equal_goto(torture, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
4021 : ret, done,
4022 : "smb_raw_open for '\\pipe\\srvsvc'");
4023 :
4024 0 : io.ntcreatex.in.fname = "srvsvc";
4025 0 : status = smb_raw_open(cli->tree, torture, &io);
4026 0 : torture_assert_ntstatus_ok_goto(torture, status, ret, done,
4027 : "smb2_create failed for 'srvsvc'");
4028 0 : fnum = io.ntcreatex.out.file.fnum;
4029 0 : ZERO_STRUCT(cl);
4030 0 : cl.generic.level = RAW_CLOSE_CLOSE;
4031 0 : cl.close.in.file.fnum = fnum;
4032 0 : status = smb_raw_close(cli->tree, &cl);
4033 0 : torture_assert_ntstatus_ok_goto(torture, status, ret, done,
4034 : "smb_raw_close failed");
4035 :
4036 0 : io.ntcreatex.in.fname = "\\srvsvc";
4037 0 : status = smb_raw_open(cli->tree, torture, &io);
4038 0 : torture_assert_ntstatus_ok_goto(torture, status, ret, done,
4039 : "smb2_create failed for '\\srvsvc'");
4040 0 : fnum = io.ntcreatex.out.file.fnum;
4041 0 : ZERO_STRUCT(cl);
4042 0 : cl.generic.level = RAW_CLOSE_CLOSE;
4043 0 : cl.close.in.file.fnum = fnum;
4044 0 : status = smb_raw_close(cli->tree, &cl);
4045 0 : torture_assert_ntstatus_ok_goto(torture, status, ret, done,
4046 : "smb_raw_close failed");
4047 :
4048 0 : io.ntcreatex.in.fname = "\\\\\\\\\\srvsvc";
4049 0 : status = smb_raw_open(cli->tree, torture, &io);
4050 0 : torture_assert_ntstatus_ok_goto(torture, status, ret, done,
4051 : "smb2_create failed for '\\\\\\\\\\srvsvc'");
4052 0 : fnum = io.ntcreatex.out.file.fnum;
4053 0 : ZERO_STRUCT(cl);
4054 0 : cl.generic.level = RAW_CLOSE_CLOSE;
4055 0 : cl.close.in.file.fnum = fnum;
4056 0 : status = smb_raw_close(cli->tree, &cl);
4057 0 : torture_assert_ntstatus_ok_goto(torture, status, ret, done,
4058 : "smb_raw_close failed");
4059 :
4060 0 : ZERO_STRUCT(io);
4061 0 : io.generic.level = RAW_OPEN_NTTRANS_CREATE;
4062 0 : io.nttrans.in.access_mask = DESIRED_ACCESS_PIPE;
4063 0 : io.nttrans.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
4064 : NTCREATEX_SHARE_ACCESS_WRITE;
4065 0 : io.nttrans.in.open_disposition = NTCREATEX_DISP_OPEN;
4066 0 : io.nttrans.in.impersonation = NTCREATEX_IMPERSONATION_IMPERSONATION;
4067 0 : io.nttrans.in.security_flags = 0;
4068 :
4069 0 : io.nttrans.in.fname = "__none__";
4070 0 : status = smb_raw_open(cli->tree, torture, &io);
4071 0 : torture_assert_ntstatus_equal_goto(torture, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
4072 : ret, done,
4073 : "smb_raw_open for '__none__'");
4074 :
4075 0 : io.nttrans.in.fname = "pipe\\srvsvc";
4076 0 : status = smb_raw_open(cli->tree, torture, &io);
4077 0 : torture_assert_ntstatus_equal_goto(torture, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
4078 : ret, done,
4079 : "smb_raw_open for 'pipe\\srvsvc'");
4080 :
4081 0 : io.nttrans.in.fname = "\\pipe\\srvsvc";
4082 0 : status = smb_raw_open(cli->tree, torture, &io);
4083 0 : torture_assert_ntstatus_equal_goto(torture, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
4084 : ret, done,
4085 : "smb_raw_open for '\\pipe\\srvsvc'");
4086 :
4087 0 : io.nttrans.in.fname = "srvsvc";
4088 0 : status = smb_raw_open(cli->tree, torture, &io);
4089 0 : torture_assert_ntstatus_ok_goto(torture, status, ret, done,
4090 : "smb2_create failed for 'srvsvc'");
4091 0 : fnum = io.nttrans.out.file.fnum;
4092 0 : ZERO_STRUCT(cl);
4093 0 : cl.generic.level = RAW_CLOSE_CLOSE;
4094 0 : cl.close.in.file.fnum = fnum;
4095 0 : status = smb_raw_close(cli->tree, &cl);
4096 0 : torture_assert_ntstatus_ok_goto(torture, status, ret, done,
4097 : "smb_raw_close failed");
4098 :
4099 0 : io.nttrans.in.fname = "\\srvsvc";
4100 0 : status = smb_raw_open(cli->tree, torture, &io);
4101 0 : torture_assert_ntstatus_ok_goto(torture, status, ret, done,
4102 : "smb2_create failed for '\\srvsvc'");
4103 0 : fnum = io.nttrans.out.file.fnum;
4104 0 : ZERO_STRUCT(cl);
4105 0 : cl.generic.level = RAW_CLOSE_CLOSE;
4106 0 : cl.close.in.file.fnum = fnum;
4107 0 : status = smb_raw_close(cli->tree, &cl);
4108 0 : torture_assert_ntstatus_ok_goto(torture, status, ret, done,
4109 : "smb_raw_close failed");
4110 :
4111 0 : io.nttrans.in.fname = "\\\\\\\\\\srvsvc";
4112 0 : status = smb_raw_open(cli->tree, torture, &io);
4113 0 : torture_assert_ntstatus_ok_goto(torture, status, ret, done,
4114 : "smb2_create failed for '\\\\\\\\\\srvsvc'");
4115 0 : fnum = io.nttrans.out.file.fnum;
4116 0 : ZERO_STRUCT(cl);
4117 0 : cl.generic.level = RAW_CLOSE_CLOSE;
4118 0 : cl.close.in.file.fnum = fnum;
4119 0 : status = smb_raw_close(cli->tree, &cl);
4120 0 : torture_assert_ntstatus_ok_goto(torture, status, ret, done,
4121 : "smb_raw_close failed");
4122 :
4123 0 : ZERO_STRUCT(io);
4124 0 : io.generic.level = RAW_OPEN_OPENX;
4125 0 : io.openx.in.open_mode = OPENX_MODE_ACCESS_RDWR;
4126 0 : io.openx.in.open_func = OPENX_OPEN_FUNC_OPEN;
4127 :
4128 0 : io.openx.in.fname = "__none__";
4129 0 : status = smb_raw_open(cli->tree, torture, &io);
4130 0 : torture_assert_ntstatus_equal_goto(torture, status, NT_STATUS_OBJECT_PATH_SYNTAX_BAD,
4131 : ret, done,
4132 : "smb_raw_open for '__none__'");
4133 :
4134 0 : io.openx.in.fname = "srvsvc";
4135 0 : status = smb_raw_open(cli->tree, torture, &io);
4136 0 : torture_assert_ntstatus_equal_goto(torture, status, NT_STATUS_OBJECT_PATH_SYNTAX_BAD,
4137 : ret, done,
4138 : "smb_raw_open for 'srvsvc'");
4139 :
4140 0 : io.openx.in.fname = "\\srvsvc";
4141 0 : status = smb_raw_open(cli->tree, torture, &io);
4142 0 : torture_assert_ntstatus_equal_goto(torture, status, NT_STATUS_OBJECT_PATH_SYNTAX_BAD,
4143 : ret, done,
4144 : "smb_raw_open for '\\srvsvc'");
4145 :
4146 0 : io.openx.in.fname = "\\pipesrvsvc";
4147 0 : status = smb_raw_open(cli->tree, torture, &io);
4148 0 : torture_assert_ntstatus_equal_goto(torture, status, NT_STATUS_OBJECT_PATH_SYNTAX_BAD,
4149 : ret, done,
4150 : "smb_raw_open for '\\pipesrvsvc'");
4151 :
4152 0 : io.openx.in.fname = "pipe\\__none__";
4153 0 : status = smb_raw_open(cli->tree, torture, &io);
4154 0 : torture_assert_ntstatus_equal_goto(torture, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
4155 : ret, done,
4156 : "smb_raw_open for 'pipe\\__none__'");
4157 :
4158 0 : io.openx.in.fname = "\\pipe\\__none__";
4159 0 : status = smb_raw_open(cli->tree, torture, &io);
4160 0 : torture_assert_ntstatus_equal_goto(torture, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
4161 : ret, done,
4162 : "smb_raw_open for '\\pipe\\__none__'");
4163 :
4164 0 : io.openx.in.fname = "pipe\\srvsvc";
4165 0 : status = smb_raw_open(cli->tree, torture, &io);
4166 0 : torture_assert_ntstatus_ok_goto(torture, status, ret, done,
4167 : "smb2_create failed for 'pipe\\srvsvc'");
4168 0 : fnum = io.openx.out.file.fnum;
4169 0 : ZERO_STRUCT(cl);
4170 0 : cl.generic.level = RAW_CLOSE_CLOSE;
4171 0 : cl.close.in.file.fnum = fnum;
4172 0 : status = smb_raw_close(cli->tree, &cl);
4173 0 : torture_assert_ntstatus_ok_goto(torture, status, ret, done,
4174 : "smb_raw_close failed");
4175 :
4176 0 : io.openx.in.fname = "\\pipe\\srvsvc";
4177 0 : status = smb_raw_open(cli->tree, torture, &io);
4178 0 : torture_assert_ntstatus_ok_goto(torture, status, ret, done,
4179 : "smb2_create failed for '\\pipe\\srvsvc'");
4180 0 : fnum = io.openx.out.file.fnum;
4181 0 : ZERO_STRUCT(cl);
4182 0 : cl.generic.level = RAW_CLOSE_CLOSE;
4183 0 : cl.close.in.file.fnum = fnum;
4184 0 : status = smb_raw_close(cli->tree, &cl);
4185 0 : torture_assert_ntstatus_ok_goto(torture, status, ret, done,
4186 : "smb_raw_close failed");
4187 :
4188 0 : io.openx.in.fname = "\\\\\\\\\\pipe\\srvsvc";
4189 0 : status = smb_raw_open(cli->tree, torture, &io);
4190 0 : torture_assert_ntstatus_ok_goto(torture, status, ret, done,
4191 : "smb2_create failed for '\\\\\\\\\\pipe\\srvsvc'");
4192 0 : fnum = io.openx.out.file.fnum;
4193 0 : ZERO_STRUCT(cl);
4194 0 : cl.generic.level = RAW_CLOSE_CLOSE;
4195 0 : cl.close.in.file.fnum = fnum;
4196 0 : status = smb_raw_close(cli->tree, &cl);
4197 0 : torture_assert_ntstatus_ok_goto(torture, status, ret, done,
4198 : "smb_raw_close failed");
4199 :
4200 0 : io.openx.in.fname = "\\\\\\\\\\pipe\\\\\\\\\\srvsvc";
4201 0 : status = smb_raw_open(cli->tree, torture, &io);
4202 0 : torture_assert_ntstatus_ok_goto(torture, status, ret, done,
4203 : "smb2_create failed for '\\\\\\\\\\pipe\\\\\\\\\\srvsvc'");
4204 0 : fnum = io.openx.out.file.fnum;
4205 0 : ZERO_STRUCT(cl);
4206 0 : cl.generic.level = RAW_CLOSE_CLOSE;
4207 0 : cl.close.in.file.fnum = fnum;
4208 0 : status = smb_raw_close(cli->tree, &cl);
4209 0 : torture_assert_ntstatus_ok_goto(torture, status, ret, done,
4210 : "smb_raw_close failed");
4211 0 : ret = true;
4212 :
4213 0 : done:
4214 0 : talloc_free(mem_ctx);
4215 0 : return ret;
4216 : }
4217 :
4218 0 : static bool torture_rpc_smb2_pipe_name(struct torture_context *torture)
4219 : {
4220 : TALLOC_CTX *mem_ctx;
4221 : NTSTATUS status;
4222 0 : bool ret = false;
4223 : struct smbcli_options options;
4224 0 : const char *host = torture_setting_string(torture, "host", NULL);
4225 : struct smb2_tree *tree;
4226 : struct smb2_handle h;
4227 : struct smb2_create io;
4228 :
4229 0 : mem_ctx = talloc_init("torture_samba3_smb2_pipe_name");
4230 0 : torture_assert(torture, (mem_ctx != NULL), "talloc_init failed");
4231 :
4232 0 : lpcfg_smbcli_options(torture->lp_ctx, &options);
4233 :
4234 0 : status = smb2_connect(mem_ctx,
4235 : host,
4236 : lpcfg_smb_ports(torture->lp_ctx),
4237 : "IPC$",
4238 : lpcfg_resolve_context(torture->lp_ctx),
4239 : samba_cmdline_get_creds(),
4240 : &tree,
4241 : torture->ev,
4242 : &options,
4243 : lpcfg_socket_options(torture->lp_ctx),
4244 : lpcfg_gensec_settings(torture, torture->lp_ctx)
4245 : );
4246 0 : torture_assert_ntstatus_ok_goto(torture, status, ret, done,
4247 : "smb2_connect failed");
4248 :
4249 0 : ZERO_STRUCT(io);
4250 0 : io.in.oplock_level = 0;
4251 0 : io.in.desired_access = DESIRED_ACCESS_PIPE;
4252 0 : io.in.impersonation_level = SMB2_IMPERSONATION_IMPERSONATION;
4253 0 : io.in.file_attributes = 0;
4254 0 : io.in.create_disposition = NTCREATEX_DISP_OPEN;
4255 0 : io.in.share_access =
4256 : NTCREATEX_SHARE_ACCESS_READ|
4257 : NTCREATEX_SHARE_ACCESS_WRITE;
4258 0 : io.in.create_options = 0;
4259 :
4260 0 : io.in.fname = "__none__";
4261 0 : status = smb2_create(tree, tree, &io);
4262 0 : torture_assert_ntstatus_equal_goto(torture, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
4263 : ret, done,
4264 : "smb2_create for '__none__'");
4265 :
4266 0 : io.in.fname = "\\srvsvc";
4267 0 : status = smb2_create(tree, tree, &io);
4268 0 : torture_assert_ntstatus_equal_goto(torture, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
4269 : ret, done,
4270 : "smb2_create for '\\srvsvc'");
4271 :
4272 0 : io.in.fname = "\\pipe\\srvsvc";
4273 0 : status = smb2_create(tree, tree, &io);
4274 0 : torture_assert_ntstatus_equal_goto(torture, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
4275 : ret, done,
4276 : "smb2_create for '\\pipe\\srvsvc'");
4277 :
4278 0 : io.in.fname = "pipe\\srvsvc";
4279 0 : status = smb2_create(tree, tree, &io);
4280 0 : torture_assert_ntstatus_equal_goto(torture, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
4281 : ret, done,
4282 : "smb2_create for 'pipe\\srvsvc'");
4283 :
4284 0 : io.in.fname = "srvsvc";
4285 0 : status = smb2_create(tree, tree, &io);
4286 0 : torture_assert_ntstatus_ok_goto(torture, status, ret, done,
4287 : "smb2_create failed for 'srvsvc'");
4288 :
4289 0 : h = io.out.file.handle;
4290 :
4291 0 : status = smb2_util_close(tree, h);
4292 0 : torture_assert_ntstatus_ok_goto(torture, status, ret, done,
4293 : "smb2_util_close failed");
4294 :
4295 0 : ret = true;
4296 0 : done:
4297 0 : talloc_free(mem_ctx);
4298 0 : return ret;
4299 : }
4300 :
4301 : /**
4302 : * Test behaviour of a waiting read call on a pipe when
4303 : * the pipe handle is closed:
4304 : * - open a pipe via smb2
4305 : * - trigger a read which hangs since there is nothing to read
4306 : * - close the pipe file handle
4307 : * - wait for the read to return and check the status
4308 : * (STATUS_PIPE_BROKEN)
4309 : */
4310 0 : static bool torture_rpc_smb2_pipe_read_close(struct torture_context *torture)
4311 : {
4312 : TALLOC_CTX *mem_ctx;
4313 : NTSTATUS status;
4314 0 : bool ret = false;
4315 : struct smbcli_options options;
4316 0 : const char *host = torture_setting_string(torture, "host", NULL);
4317 : struct smb2_tree *tree;
4318 : struct smb2_handle h;
4319 : struct smb2_request *smb2req;
4320 : struct smb2_create io;
4321 : struct smb2_read rd;
4322 :
4323 0 : mem_ctx = talloc_init("torture_samba3_pipe_read_close");
4324 0 : torture_assert(torture, (mem_ctx != NULL), "talloc_init failed");
4325 :
4326 0 : lpcfg_smbcli_options(torture->lp_ctx, &options);
4327 :
4328 0 : status = smb2_connect(mem_ctx,
4329 : host,
4330 : lpcfg_smb_ports(torture->lp_ctx),
4331 : "IPC$",
4332 : lpcfg_resolve_context(torture->lp_ctx),
4333 : samba_cmdline_get_creds(),
4334 : &tree,
4335 : torture->ev,
4336 : &options,
4337 : lpcfg_socket_options(torture->lp_ctx),
4338 : lpcfg_gensec_settings(torture, torture->lp_ctx)
4339 : );
4340 0 : torture_assert_ntstatus_ok_goto(torture, status, ret, done,
4341 : "smb2_connect failed");
4342 :
4343 0 : ZERO_STRUCT(io);
4344 0 : io.in.oplock_level = 0;
4345 0 : io.in.desired_access = DESIRED_ACCESS_PIPE;
4346 0 : io.in.impersonation_level = SMB2_IMPERSONATION_IMPERSONATION;
4347 0 : io.in.file_attributes = 0;
4348 0 : io.in.create_disposition = NTCREATEX_DISP_OPEN;
4349 0 : io.in.share_access =
4350 : NTCREATEX_SHARE_ACCESS_READ|
4351 : NTCREATEX_SHARE_ACCESS_WRITE;
4352 0 : io.in.create_options = 0;
4353 0 : io.in.fname = "lsarpc";
4354 :
4355 0 : status = smb2_create(tree, tree, &io);
4356 0 : torture_assert_ntstatus_ok_goto(torture, status, ret, done,
4357 : "smb2_create failed for 'lsarpc'");
4358 :
4359 0 : h = io.out.file.handle;
4360 :
4361 0 : ZERO_STRUCT(rd);
4362 0 : rd.in.file.handle = h;
4363 0 : rd.in.length = 1024;
4364 0 : rd.in.offset = 0;
4365 0 : rd.in.min_count = 0;
4366 :
4367 0 : smb2req = smb2_read_send(tree, &rd);
4368 0 : torture_assert_goto(torture, (smb2req != NULL), ret, done,
4369 : "smb2_read_send failed");
4370 :
4371 0 : status = smb2_util_close(tree, h);
4372 0 : torture_assert_ntstatus_ok_goto(torture, status, ret, done,
4373 : "smb2_util_close failed");
4374 :
4375 0 : status = smb2_read_recv(smb2req, mem_ctx, &rd);
4376 0 : torture_assert_ntstatus_equal_goto(torture, status, NT_STATUS_PIPE_BROKEN, ret, done,
4377 : "smb2_read_recv: unexpected return code");
4378 :
4379 0 : ret = true;
4380 0 : done:
4381 0 : talloc_free(mem_ctx);
4382 0 : return ret;
4383 : }
4384 :
4385 : /**
4386 : * Test behaviour of a waiting read call on a pipe when
4387 : * the tree is disconnected.
4388 : * - open a pipe via smb2
4389 : * - trigger a read which hangs since there is nothing to read
4390 : * - do a tree disconnect
4391 : * - wait for the read to return and check the status
4392 : * (STATUS_PIPE_BROKEN)
4393 : */
4394 0 : static bool torture_rpc_smb2_pipe_read_tdis(struct torture_context *torture)
4395 : {
4396 : TALLOC_CTX *mem_ctx;
4397 : NTSTATUS status;
4398 0 : bool ret = false;
4399 : struct smbcli_options options;
4400 0 : const char *host = torture_setting_string(torture, "host", NULL);
4401 : struct smb2_tree *tree;
4402 : struct smb2_handle h;
4403 : struct smb2_request *smb2req;
4404 : struct smb2_create io;
4405 : struct smb2_read rd;
4406 :
4407 0 : mem_ctx = talloc_init("torture_samba3_pipe_read_tdis");
4408 0 : torture_assert(torture, (mem_ctx != NULL), "talloc_init failed");
4409 :
4410 0 : lpcfg_smbcli_options(torture->lp_ctx, &options);
4411 :
4412 0 : status = smb2_connect(mem_ctx,
4413 : host,
4414 : lpcfg_smb_ports(torture->lp_ctx),
4415 : "IPC$",
4416 : lpcfg_resolve_context(torture->lp_ctx),
4417 : samba_cmdline_get_creds(),
4418 : &tree,
4419 : torture->ev,
4420 : &options,
4421 : lpcfg_socket_options(torture->lp_ctx),
4422 : lpcfg_gensec_settings(torture, torture->lp_ctx)
4423 : );
4424 0 : torture_assert_ntstatus_ok_goto(torture, status, ret, done,
4425 : "smb2_connect failed");
4426 :
4427 0 : ZERO_STRUCT(io);
4428 0 : io.in.oplock_level = 0;
4429 0 : io.in.desired_access = DESIRED_ACCESS_PIPE;
4430 0 : io.in.impersonation_level = SMB2_IMPERSONATION_IMPERSONATION;
4431 0 : io.in.file_attributes = 0;
4432 0 : io.in.create_disposition = NTCREATEX_DISP_OPEN;
4433 0 : io.in.share_access =
4434 : NTCREATEX_SHARE_ACCESS_READ|
4435 : NTCREATEX_SHARE_ACCESS_WRITE;
4436 0 : io.in.create_options = 0;
4437 0 : io.in.fname = "lsarpc";
4438 :
4439 0 : status = smb2_create(tree, tree, &io);
4440 0 : torture_assert_ntstatus_ok_goto(torture, status, ret, done,
4441 : "smb2_create failed for 'lsarpc'");
4442 :
4443 0 : h = io.out.file.handle;
4444 :
4445 0 : ZERO_STRUCT(rd);
4446 0 : rd.in.file.handle = h;
4447 0 : rd.in.length = 1024;
4448 0 : rd.in.offset = 0;
4449 0 : rd.in.min_count = 0;
4450 :
4451 0 : smb2req = smb2_read_send(tree, &rd);
4452 0 : torture_assert_goto(torture, (smb2req != NULL), ret, done,
4453 : "smb2_read_send failed");
4454 :
4455 0 : status = smb2_tdis(tree);
4456 0 : torture_assert_ntstatus_ok_goto(torture, status, ret, done,
4457 : "smb2_tdis failed");
4458 :
4459 0 : status = smb2_read_recv(smb2req, mem_ctx, &rd);
4460 0 : torture_assert_ntstatus_equal_goto(torture, status, NT_STATUS_PIPE_BROKEN, ret, done,
4461 : "smb2_read_recv: unexpected return code");
4462 :
4463 0 : ret = true;
4464 0 : done:
4465 0 : talloc_free(mem_ctx);
4466 0 : return ret;
4467 : }
4468 :
4469 : /**
4470 : * Test behaviour of a waiting read call on a pipe when
4471 : * the user logs off
4472 : * - open a pipe via smb2
4473 : * - trigger a read which hangs since there is nothing to read
4474 : * - do a logoff
4475 : * - wait for the read to return and check the status
4476 : * (STATUS_PIPE_BROKEN)
4477 : */
4478 0 : static bool torture_rpc_smb2_pipe_read_logoff(struct torture_context *torture)
4479 : {
4480 : TALLOC_CTX *mem_ctx;
4481 : NTSTATUS status;
4482 0 : bool ret = false;
4483 : struct smbcli_options options;
4484 0 : const char *host = torture_setting_string(torture, "host", NULL);
4485 : struct smb2_tree *tree;
4486 : struct smb2_handle h;
4487 : struct smb2_request *smb2req;
4488 : struct smb2_create io;
4489 : struct smb2_read rd;
4490 :
4491 0 : mem_ctx = talloc_init("torture_samba3_pipe_read_tdis");
4492 0 : torture_assert(torture, (mem_ctx != NULL), "talloc_init failed");
4493 :
4494 0 : lpcfg_smbcli_options(torture->lp_ctx, &options);
4495 :
4496 0 : status = smb2_connect(mem_ctx,
4497 : host,
4498 : lpcfg_smb_ports(torture->lp_ctx),
4499 : "IPC$",
4500 : lpcfg_resolve_context(torture->lp_ctx),
4501 : samba_cmdline_get_creds(),
4502 : &tree,
4503 : torture->ev,
4504 : &options,
4505 : lpcfg_socket_options(torture->lp_ctx),
4506 : lpcfg_gensec_settings(torture, torture->lp_ctx)
4507 : );
4508 0 : torture_assert_ntstatus_ok_goto(torture, status, ret, done,
4509 : "smb2_connect failed");
4510 :
4511 0 : ZERO_STRUCT(io);
4512 0 : io.in.oplock_level = 0;
4513 0 : io.in.desired_access = DESIRED_ACCESS_PIPE;
4514 0 : io.in.impersonation_level = SMB2_IMPERSONATION_IMPERSONATION;
4515 0 : io.in.file_attributes = 0;
4516 0 : io.in.create_disposition = NTCREATEX_DISP_OPEN;
4517 0 : io.in.share_access =
4518 : NTCREATEX_SHARE_ACCESS_READ|
4519 : NTCREATEX_SHARE_ACCESS_WRITE;
4520 0 : io.in.create_options = 0;
4521 0 : io.in.fname = "lsarpc";
4522 :
4523 0 : status = smb2_create(tree, tree, &io);
4524 0 : torture_assert_ntstatus_ok_goto(torture, status, ret, done,
4525 : "smb2_create failed for 'lsarpc'");
4526 :
4527 0 : h = io.out.file.handle;
4528 :
4529 0 : ZERO_STRUCT(rd);
4530 0 : rd.in.file.handle = h;
4531 0 : rd.in.length = 1024;
4532 0 : rd.in.offset = 0;
4533 0 : rd.in.min_count = 0;
4534 :
4535 0 : smb2req = smb2_read_send(tree, &rd);
4536 0 : torture_assert_goto(torture, (smb2req != NULL), ret, done,
4537 : "smb2_read_send failed");
4538 :
4539 0 : status = smb2_logoff(tree->session);
4540 0 : torture_assert_ntstatus_ok_goto(torture, status, ret, done,
4541 : "smb2_logoff failed");
4542 :
4543 0 : status = smb2_read_recv(smb2req, mem_ctx, &rd);
4544 0 : torture_assert_ntstatus_equal_goto(torture, status, NT_STATUS_PIPE_BROKEN, ret, done,
4545 : "smb2_read_recv: unexpected return code");
4546 :
4547 0 : ret = true;
4548 0 : done:
4549 0 : talloc_free(mem_ctx);
4550 0 : return ret;
4551 : }
4552 :
4553 0 : static bool torture_rpc_lsa_over_netlogon(struct torture_context *torture)
4554 : {
4555 : TALLOC_CTX *mem_ctx;
4556 : NTSTATUS status;
4557 0 : bool ret = false;
4558 : struct smbcli_options options;
4559 : struct smb2_tree *tree;
4560 : struct dcerpc_pipe *netlogon_pipe;
4561 : struct dcerpc_binding_handle *lsa_handle;
4562 : struct lsa_ObjectAttribute attr;
4563 : struct lsa_QosInfo qos;
4564 : struct lsa_OpenPolicy2 o;
4565 : struct policy_handle handle;
4566 :
4567 0 : torture_comment(torture, "Testing if we can access LSA server over "
4568 : "\\\\pipe\\netlogon rather than \\\\pipe\\lsarpc\n");
4569 :
4570 0 : mem_ctx = talloc_init("torture_samba3_rpc_lsa_over_netlogon");
4571 0 : torture_assert(torture, (mem_ctx != NULL), "talloc_init failed");
4572 :
4573 0 : lpcfg_smbcli_options(torture->lp_ctx, &options);
4574 :
4575 0 : status = smb2_connect(mem_ctx,
4576 : torture_setting_string(torture, "host", NULL),
4577 : lpcfg_smb_ports(torture->lp_ctx),
4578 : "IPC$",
4579 : lpcfg_resolve_context(torture->lp_ctx),
4580 : samba_cmdline_get_creds(),
4581 : &tree,
4582 : torture->ev,
4583 : &options,
4584 : lpcfg_socket_options(torture->lp_ctx),
4585 : lpcfg_gensec_settings(torture, torture->lp_ctx)
4586 : );
4587 0 : torture_assert_ntstatus_ok_goto(torture, status, ret, done,
4588 : "smb2_connect failed");
4589 :
4590 0 : status = pipe_bind_smb2(torture, mem_ctx, tree, "netlogon",
4591 : &ndr_table_lsarpc, &netlogon_pipe);
4592 0 : torture_assert_ntstatus_ok_goto(torture, status, ret, done,
4593 : "pipe_bind_smb2 failed");
4594 0 : lsa_handle = netlogon_pipe->binding_handle;
4595 :
4596 0 : qos.len = 0;
4597 0 : qos.impersonation_level = 2;
4598 0 : qos.context_mode = 1;
4599 0 : qos.effective_only = 0;
4600 :
4601 0 : attr.len = 0;
4602 0 : attr.root_dir = NULL;
4603 0 : attr.object_name = NULL;
4604 0 : attr.attributes = 0;
4605 0 : attr.sec_desc = NULL;
4606 0 : attr.sec_qos = &qos;
4607 :
4608 0 : o.in.system_name = "\\";
4609 0 : o.in.attr = &attr;
4610 0 : o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4611 0 : o.out.handle = &handle;
4612 :
4613 0 : torture_assert_ntstatus_ok(torture,
4614 : dcerpc_lsa_OpenPolicy2_r(lsa_handle, torture, &o),
4615 : "OpenPolicy2 failed");
4616 0 : torture_assert_ntstatus_ok(torture,
4617 : o.out.result,
4618 : "OpenPolicy2 failed");
4619 :
4620 0 : ret = true;
4621 0 : done:
4622 0 : talloc_free(mem_ctx);
4623 0 : return ret;
4624 : }
4625 :
4626 0 : static bool torture_rpc_pipes_supported_interfaces(
4627 : struct torture_context *torture)
4628 : {
4629 : TALLOC_CTX *mem_ctx;
4630 : NTSTATUS status;
4631 0 : bool ret = false;
4632 : struct smbcli_options options;
4633 : struct smb2_tree *tree;
4634 : struct dcerpc_pipe *pipe1;
4635 : struct dcerpc_pipe *pipe2;
4636 : struct dcerpc_pipe *pipe3;
4637 :
4638 0 : torture_comment(torture, "Testing only appropriate interfaces are "
4639 : "available in smb pipes\n");
4640 :
4641 0 : mem_ctx = talloc_init("torture_samba3_rpc_pipes_supported_interfaces");
4642 0 : torture_assert(torture, (mem_ctx != NULL), "talloc_init failed");
4643 :
4644 0 : lpcfg_smbcli_options(torture->lp_ctx, &options);
4645 :
4646 0 : status = smb2_connect(mem_ctx,
4647 : torture_setting_string(torture, "host", NULL),
4648 : lpcfg_smb_ports(torture->lp_ctx),
4649 : "IPC$",
4650 : lpcfg_resolve_context(torture->lp_ctx),
4651 : samba_cmdline_get_creds(),
4652 : &tree,
4653 : torture->ev,
4654 : &options,
4655 : lpcfg_socket_options(torture->lp_ctx),
4656 : lpcfg_gensec_settings(torture, torture->lp_ctx)
4657 : );
4658 0 : torture_assert_ntstatus_ok_goto(torture, status, ret, done,
4659 : "smb2_connect failed");
4660 :
4661 : /* Test embedded services pipes. The svcctl interface is
4662 : * not available if we open the winreg pipe. */
4663 0 : status = pipe_bind_smb2(torture, mem_ctx, tree, "winreg",
4664 : &ndr_table_svcctl, &pipe1);
4665 0 : torture_assert_ntstatus_equal(torture,
4666 : status,
4667 : NT_STATUS_RPC_UNSUPPORTED_NAME_SYNTAX,
4668 : "svcctl interface not supported in winreg pipe");
4669 :
4670 : /* Test it is not possible to bind to S4 server provided services */
4671 0 : status = pipe_bind_smb2(torture, mem_ctx, tree, "srvsvc",
4672 : &ndr_table_samr, &pipe2);
4673 0 : torture_assert_ntstatus_equal(torture,
4674 : status,
4675 : NT_STATUS_RPC_UNSUPPORTED_NAME_SYNTAX,
4676 : "samr interface not supported in srvsvc pipe");
4677 :
4678 : /* Test pipes in forked daemons like lsassd. The lsarpc interface is
4679 : * not available if we open the SAMR pipe. */
4680 0 : status = pipe_bind_smb2(torture, mem_ctx, tree, "samr",
4681 : &ndr_table_lsarpc, &pipe3);
4682 0 : torture_assert_ntstatus_equal(torture,
4683 : status,
4684 : NT_STATUS_RPC_UNSUPPORTED_NAME_SYNTAX,
4685 : "lsarpc interface not supported in samr pipe");
4686 :
4687 0 : ret = true;
4688 0 : done:
4689 0 : talloc_free(mem_ctx);
4690 0 : return ret;
4691 : }
4692 :
4693 964 : struct torture_suite *torture_rpc_samba3(TALLOC_CTX *mem_ctx)
4694 : {
4695 964 : struct torture_suite *suite = torture_suite_create(mem_ctx, "samba3");
4696 :
4697 964 : torture_suite_add_simple_test(suite, "bind", torture_bind_samba3);
4698 964 : torture_suite_add_simple_test(suite, "netlogon", torture_netlogon_samba3);
4699 964 : torture_suite_add_simple_test(suite, "sessionkey", torture_samba3_sessionkey);
4700 964 : torture_suite_add_simple_test(suite, "srvsvc", torture_samba3_rpc_srvsvc);
4701 964 : torture_suite_add_simple_test(suite, "sharesec", torture_samba3_rpc_sharesec);
4702 964 : torture_suite_add_simple_test(suite, "getusername", torture_samba3_rpc_getusername);
4703 964 : torture_suite_add_simple_test(suite, "randomauth2", torture_samba3_rpc_randomauth2);
4704 964 : torture_suite_add_simple_test(suite, "lsa", torture_samba3_rpc_lsa);
4705 964 : torture_suite_add_simple_test(suite, "spoolss", torture_samba3_rpc_spoolss);
4706 964 : torture_suite_add_simple_test(suite, "wkssvc", torture_samba3_rpc_wkssvc);
4707 964 : torture_suite_add_simple_test(suite, "winreg", torture_samba3_rpc_winreg);
4708 964 : torture_suite_add_simple_test(suite, "getaliasmembership-0", torture_samba3_getaliasmembership_0);
4709 964 : torture_suite_add_simple_test(suite, "regconfig", torture_samba3_regconfig);
4710 964 : torture_suite_add_simple_test(suite, "smb-reauth1", torture_rpc_smb_reauth1);
4711 964 : torture_suite_add_simple_test(suite, "smb-reauth2", torture_rpc_smb_reauth2);
4712 964 : torture_suite_add_simple_test(suite, "smb2-reauth1", torture_rpc_smb2_reauth1);
4713 964 : torture_suite_add_simple_test(suite, "smb2-reauth2", torture_rpc_smb2_reauth2);
4714 964 : torture_suite_add_simple_test(suite, "smb1-pipe-name", torture_rpc_smb1_pipe_name);
4715 964 : torture_suite_add_simple_test(suite, "smb2-pipe-name", torture_rpc_smb2_pipe_name);
4716 964 : torture_suite_add_simple_test(suite, "smb2-pipe-read-close", torture_rpc_smb2_pipe_read_close);
4717 964 : torture_suite_add_simple_test(suite, "smb2-pipe-read-tdis", torture_rpc_smb2_pipe_read_tdis);
4718 964 : torture_suite_add_simple_test(suite, "smb2-pipe-read-logoff", torture_rpc_smb2_pipe_read_logoff);
4719 964 : torture_suite_add_simple_test(suite,
4720 : "lsa_over_netlogon",
4721 : torture_rpc_lsa_over_netlogon);
4722 964 : torture_suite_add_simple_test(suite,
4723 : "pipes_supported_interfaces",
4724 : torture_rpc_pipes_supported_interfaces);
4725 :
4726 964 : suite->description = talloc_strdup(suite, "samba3 DCERPC interface tests");
4727 :
4728 964 : return suite;
4729 : }
|