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 123 : 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 0 : struct dcerpc_pipe *result;
64 0 : NTSTATUS status;
65 :
66 123 : if (!(result = dcerpc_pipe_init(mem_ctx, tctx->ev))) {
67 0 : return NT_STATUS_NO_MEMORY;
68 : }
69 :
70 123 : status = dcerpc_pipe_open_smb(result, tree, pipe_name);
71 123 : 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 123 : status = dcerpc_bind_auth_none(result, iface);
79 123 : 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 123 : *p = result;
86 123 : return NT_STATUS_OK;
87 : }
88 :
89 14 : 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 0 : struct dcerpc_pipe *result;
97 0 : NTSTATUS status;
98 :
99 14 : if (!(result = dcerpc_pipe_init(mem_ctx, tctx->ev))) {
100 0 : return NT_STATUS_NO_MEMORY;
101 : }
102 :
103 14 : status = dcerpc_pipe_open_smb2(result, tree, pipe_name);
104 14 : 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 14 : status = dcerpc_bind_auth_none(result, iface);
112 14 : if (!NT_STATUS_IS_OK(status)) {
113 12 : torture_comment(tctx, "dcerpc_bind_auth_none failed: %s\n", nt_errstr(status));
114 12 : talloc_free(result);
115 12 : return status;
116 : }
117 :
118 2 : *p = result;
119 2 : return NT_STATUS_OK;
120 : }
121 :
122 32 : 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 0 : struct dcerpc_pipe *result;
133 0 : NTSTATUS status;
134 :
135 32 : if (!(result = dcerpc_pipe_init(mem_ctx, tctx->ev))) {
136 0 : return NT_STATUS_NO_MEMORY;
137 : }
138 :
139 32 : status = dcerpc_pipe_open_smb(result, tree, pipe_name);
140 32 : 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 32 : status = dcerpc_bind_auth(result, iface, creds,
148 32 : lpcfg_gensec_settings(tctx->lp_ctx, tctx->lp_ctx),
149 : auth_type, auth_level, NULL);
150 32 : 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 32 : *p = result;
157 32 : return NT_STATUS_OK;
158 : }
159 :
160 : /*
161 : * This tests a RPC call using an invalid vuid
162 : */
163 :
164 19 : bool torture_bind_authcontext(struct torture_context *torture)
165 : {
166 0 : TALLOC_CTX *mem_ctx;
167 0 : NTSTATUS status;
168 19 : bool ret = false;
169 0 : struct lsa_ObjectAttribute objectattr;
170 0 : struct lsa_OpenPolicy2 openpolicy;
171 0 : struct policy_handle handle;
172 0 : struct lsa_Close close_handle;
173 0 : struct smbcli_session *tmp;
174 0 : uint16_t tmp_vuid;
175 0 : struct smbcli_session *session2;
176 0 : struct smbcli_state *cli;
177 0 : struct dcerpc_pipe *lsa_pipe;
178 0 : struct dcerpc_binding_handle *lsa_handle;
179 0 : struct cli_credentials *anon_creds;
180 0 : struct smb_composite_sesssetup setup;
181 0 : struct smbcli_options options;
182 0 : struct smbcli_session_options session_options;
183 :
184 19 : mem_ctx = talloc_init("torture_bind_authcontext");
185 :
186 19 : if (mem_ctx == NULL) {
187 0 : torture_comment(torture, "talloc_init failed\n");
188 0 : return false;
189 : }
190 :
191 19 : lpcfg_smbcli_options(torture->lp_ctx, &options);
192 19 : lpcfg_smbcli_session_options(torture->lp_ctx, &session_options);
193 :
194 19 : 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 19 : 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 19 : status = pipe_bind_smb(torture, mem_ctx, cli->tree, "\\lsarpc",
210 : &ndr_table_lsarpc, &lsa_pipe);
211 19 : torture_assert_ntstatus_ok_goto(torture, status, ret, done,
212 : "pipe_bind_smb failed");
213 19 : lsa_handle = lsa_pipe->binding_handle;
214 :
215 19 : openpolicy.in.system_name =talloc_asprintf(
216 : mem_ctx, "\\\\%s", dcerpc_server_name(lsa_pipe));
217 19 : ZERO_STRUCT(objectattr);
218 19 : openpolicy.in.attr = &objectattr;
219 19 : openpolicy.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
220 19 : openpolicy.out.handle = &handle;
221 :
222 19 : status = dcerpc_lsa_OpenPolicy2_r(lsa_handle, mem_ctx, &openpolicy);
223 :
224 19 : 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 19 : 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 19 : close_handle.in.handle = &handle;
236 19 : close_handle.out.handle = &handle;
237 :
238 19 : status = dcerpc_lsa_Close_r(lsa_handle, mem_ctx, &close_handle);
239 19 : 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 19 : 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 19 : session2 = smbcli_session_init(cli->transport, mem_ctx, false, session_options);
251 19 : if (session2 == NULL) {
252 0 : torture_comment(torture, "smbcli_session_init failed\n");
253 0 : goto done;
254 : }
255 :
256 19 : 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 19 : setup.in.sesskey = cli->transport->negotiate.sesskey;
262 19 : setup.in.capabilities = cli->transport->negotiate.capabilities;
263 19 : setup.in.workgroup = "";
264 19 : setup.in.credentials = anon_creds;
265 19 : setup.in.gensec_settings = lpcfg_gensec_settings(torture, torture->lp_ctx);
266 :
267 19 : status = smb_composite_sesssetup(session2, &setup);
268 19 : 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 19 : session2->vuid = setup.out.vuid;
274 :
275 19 : tmp = cli->tree->session;
276 19 : tmp_vuid = smb1cli_session_current_id(tmp->smbXcli);
277 19 : smb1cli_session_set_id(tmp->smbXcli, session2->vuid);
278 19 : cli->tree->session = session2;
279 :
280 19 : status = dcerpc_lsa_OpenPolicy2_r(lsa_handle, mem_ctx, &openpolicy);
281 :
282 19 : torture_assert(torture, smbXcli_conn_is_connected(cli->transport->conn),
283 : "smb still connected");
284 19 : torture_assert(torture, !dcerpc_binding_handle_is_connected(lsa_handle),
285 : "dcerpc disconnected");
286 :
287 19 : 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 19 : 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 19 : torture_assert_ntstatus_equal(torture, status, NT_STATUS_CONNECTION_DISCONNECTED,
301 : "lsa connection disconnected");
302 :
303 19 : smb1cli_session_set_id(tmp->smbXcli, tmp_vuid);
304 19 : cli->tree->session = tmp;
305 19 : talloc_free(lsa_pipe);
306 19 : lsa_pipe = NULL;
307 :
308 19 : ret = true;
309 19 : done:
310 19 : talloc_free(mem_ctx);
311 19 : return ret;
312 : }
313 :
314 : /*
315 : * Bind to lsa using a specific auth method
316 : */
317 :
318 16 : 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 0 : TALLOC_CTX *mem_ctx;
324 16 : bool ret = false;
325 0 : NTSTATUS status;
326 :
327 0 : struct dcerpc_pipe *lsa_pipe;
328 0 : struct dcerpc_binding_handle *lsa_handle;
329 0 : struct lsa_ObjectAttribute objectattr;
330 0 : struct lsa_OpenPolicy2 openpolicy;
331 0 : struct lsa_QueryInfoPolicy query;
332 16 : union lsa_PolicyInformation *info = NULL;
333 0 : struct policy_handle handle;
334 0 : struct lsa_Close close_handle;
335 :
336 16 : if ((mem_ctx = talloc_init("bindtest")) == NULL) {
337 0 : torture_comment(tctx, "talloc_init failed\n");
338 0 : return false;
339 : }
340 :
341 16 : status = pipe_bind_smb_auth(tctx, mem_ctx, cli->tree,
342 : credentials, auth_type, auth_level,
343 : "\\lsarpc", &ndr_table_lsarpc, &lsa_pipe);
344 16 : torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
345 : "pipe_bind_smb_auth failed");
346 16 : lsa_handle = lsa_pipe->binding_handle;
347 :
348 16 : openpolicy.in.system_name =talloc_asprintf(
349 : mem_ctx, "\\\\%s", dcerpc_server_name(lsa_pipe));
350 16 : ZERO_STRUCT(objectattr);
351 16 : openpolicy.in.attr = &objectattr;
352 16 : openpolicy.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
353 16 : openpolicy.out.handle = &handle;
354 :
355 16 : status = dcerpc_lsa_OpenPolicy2_r(lsa_handle, mem_ctx, &openpolicy);
356 :
357 16 : 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 16 : 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 16 : query.in.handle = &handle;
369 16 : query.in.level = LSA_POLICY_INFO_DOMAIN;
370 16 : query.out.info = &info;
371 :
372 16 : status = dcerpc_lsa_QueryInfoPolicy_r(lsa_handle, mem_ctx, &query);
373 16 : 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 16 : 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 16 : close_handle.in.handle = &handle;
385 16 : close_handle.out.handle = &handle;
386 :
387 16 : status = dcerpc_lsa_Close_r(lsa_handle, mem_ctx, &close_handle);
388 16 : 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 16 : 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 16 : ret = true;
401 16 : done:
402 16 : talloc_free(mem_ctx);
403 16 : return ret;
404 : }
405 :
406 : /*
407 : * test authenticated RPC binds with the variants Samba3 does support
408 : */
409 :
410 4 : static bool torture_bind_samba3(struct torture_context *torture)
411 : {
412 0 : TALLOC_CTX *mem_ctx;
413 0 : NTSTATUS status;
414 4 : bool ret = false;
415 0 : struct smbcli_state *cli;
416 0 : struct smbcli_options options;
417 0 : struct smbcli_session_options session_options;
418 :
419 4 : mem_ctx = talloc_init("torture_bind_authcontext");
420 :
421 4 : if (mem_ctx == NULL) {
422 0 : torture_comment(torture, "talloc_init failed\n");
423 0 : return false;
424 : }
425 :
426 4 : lpcfg_smbcli_options(torture->lp_ctx, &options);
427 4 : lpcfg_smbcli_session_options(torture->lp_ctx, &session_options);
428 :
429 4 : 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 4 : 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 4 : ret = true;
445 :
446 4 : ret &= bindtest(torture, cli, samba_cmdline_get_creds(),
447 : DCERPC_AUTH_TYPE_NTLMSSP,
448 : DCERPC_AUTH_LEVEL_INTEGRITY);
449 4 : ret &= bindtest(torture, cli, samba_cmdline_get_creds(),
450 : DCERPC_AUTH_TYPE_NTLMSSP,
451 : DCERPC_AUTH_LEVEL_PRIVACY);
452 4 : ret &= bindtest(torture, cli, samba_cmdline_get_creds(),
453 : DCERPC_AUTH_TYPE_SPNEGO,
454 : DCERPC_AUTH_LEVEL_INTEGRITY);
455 4 : ret &= bindtest(torture, cli, samba_cmdline_get_creds(),
456 : DCERPC_AUTH_TYPE_SPNEGO,
457 : DCERPC_AUTH_LEVEL_PRIVACY);
458 :
459 4 : done:
460 4 : talloc_free(mem_ctx);
461 4 : return ret;
462 : }
463 :
464 : /*
465 : * Lookup or create a user and return all necessary info
466 : */
467 :
468 32 : 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 0 : struct dcerpc_pipe *samr_pipe;
481 0 : struct dcerpc_binding_handle *samr_handle;
482 0 : NTSTATUS status;
483 0 : struct policy_handle conn_handle;
484 0 : struct policy_handle domain_handle;
485 0 : struct policy_handle *user_handle;
486 0 : struct samr_Connect2 conn;
487 0 : struct samr_EnumDomains enumdom;
488 32 : uint32_t resume_handle = 0;
489 32 : uint32_t num_entries = 0;
490 32 : struct samr_SamArray *sam = NULL;
491 0 : struct samr_LookupDomain l;
492 32 : struct dom_sid2 *sid = NULL;
493 0 : int dom_idx;
494 0 : struct lsa_String domain_name;
495 0 : struct lsa_String user_name;
496 0 : struct samr_OpenDomain o;
497 0 : struct samr_CreateUser2 c;
498 0 : uint32_t user_rid,access_granted;
499 :
500 32 : 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 32 : status = pipe_bind_smb(tctx, mem_ctx, cli->tree,
508 : "\\samr", &ndr_table_samr, &samr_pipe);
509 32 : 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 32 : samr_handle = samr_pipe->binding_handle;
515 :
516 32 : conn.in.system_name = talloc_asprintf(
517 : mem_ctx, "\\\\%s", dcerpc_server_name(samr_pipe));
518 32 : conn.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
519 32 : conn.out.connect_handle = &conn_handle;
520 :
521 32 : torture_assert_ntstatus_ok(tctx,
522 : dcerpc_samr_Connect2_r(samr_handle, mem_ctx, &conn),
523 : "samr_Connect2 failed");
524 32 : torture_assert_ntstatus_ok(tctx, conn.out.result,
525 : "samr_Connect2 failed");
526 :
527 32 : enumdom.in.connect_handle = &conn_handle;
528 32 : enumdom.in.resume_handle = &resume_handle;
529 32 : enumdom.in.buf_size = (uint32_t)-1;
530 32 : enumdom.out.resume_handle = &resume_handle;
531 32 : enumdom.out.num_entries = &num_entries;
532 32 : enumdom.out.sam = &sam;
533 :
534 32 : torture_assert_ntstatus_ok(tctx,
535 : dcerpc_samr_EnumDomains_r(samr_handle, mem_ctx, &enumdom),
536 : "samr_EnumDomains failed");
537 32 : torture_assert_ntstatus_ok(tctx, enumdom.out.result,
538 : "samr_EnumDomains failed");
539 :
540 32 : torture_assert_int_equal(tctx, *enumdom.out.num_entries, 2,
541 : "samr_EnumDomains returned unexpected num_entries");
542 :
543 32 : dom_idx = strequal(sam->entries[0].name.string,
544 32 : "builtin") ? 1:0;
545 :
546 32 : l.in.connect_handle = &conn_handle;
547 32 : domain_name.string = sam->entries[dom_idx].name.string;
548 32 : *domain = talloc_strdup(mem_ctx, domain_name.string);
549 32 : l.in.domain_name = &domain_name;
550 32 : l.out.sid = &sid;
551 :
552 32 : torture_assert_ntstatus_ok(tctx,
553 : dcerpc_samr_LookupDomain_r(samr_handle, mem_ctx, &l),
554 : "samr_LookupDomain failed");
555 32 : torture_assert_ntstatus_ok(tctx, l.out.result,
556 : "samr_LookupDomain failed");
557 :
558 32 : o.in.connect_handle = &conn_handle;
559 32 : o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
560 32 : o.in.sid = *l.out.sid;
561 32 : o.out.domain_handle = &domain_handle;
562 :
563 32 : torture_assert_ntstatus_ok(tctx,
564 : dcerpc_samr_OpenDomain_r(samr_handle, mem_ctx, &o),
565 : "samr_OpenDomain failed");
566 32 : torture_assert_ntstatus_ok(tctx, o.out.result,
567 : "samr_OpenDomain failed");
568 :
569 32 : c.in.domain_handle = &domain_handle;
570 32 : user_name.string = username;
571 32 : c.in.account_name = &user_name;
572 32 : c.in.acct_flags = ACB_NORMAL;
573 32 : c.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
574 32 : user_handle = talloc(mem_ctx, struct policy_handle);
575 32 : c.out.user_handle = user_handle;
576 32 : c.out.access_granted = &access_granted;
577 32 : c.out.rid = &user_rid;
578 :
579 32 : torture_assert_ntstatus_ok(tctx,
580 : dcerpc_samr_CreateUser2_r(samr_handle, mem_ctx, &c),
581 : "samr_CreateUser2 failed");
582 :
583 32 : if (NT_STATUS_EQUAL(c.out.result, NT_STATUS_USER_EXISTS)) {
584 0 : struct samr_LookupNames ln;
585 0 : struct samr_OpenUser ou;
586 0 : struct samr_Ids rids, types;
587 :
588 16 : ln.in.domain_handle = &domain_handle;
589 16 : ln.in.num_names = 1;
590 16 : ln.in.names = &user_name;
591 16 : ln.out.rids = &rids;
592 16 : ln.out.types = &types;
593 :
594 16 : torture_assert_ntstatus_ok(tctx,
595 : dcerpc_samr_LookupNames_r(samr_handle, mem_ctx, &ln),
596 : "samr_LookupNames failed");
597 16 : torture_assert_ntstatus_ok(tctx, ln.out.result,
598 : "samr_LookupNames failed");
599 :
600 16 : ou.in.domain_handle = &domain_handle;
601 16 : ou.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
602 16 : user_rid = ou.in.rid = ln.out.rids->ids[0];
603 16 : ou.out.user_handle = user_handle;
604 :
605 16 : torture_assert_ntstatus_ok(tctx,
606 : dcerpc_samr_OpenUser_r(samr_handle, mem_ctx, &ou),
607 : "samr_OpenUser failed");
608 16 : status = ou.out.result;
609 : } else {
610 16 : status = c.out.result;
611 : }
612 :
613 32 : torture_assert_ntstatus_ok(tctx, status,
614 : "samr_CreateUser failed");
615 :
616 32 : *result_pipe = samr_pipe;
617 32 : *result_handle = user_handle;
618 32 : if (sid_p != NULL) {
619 4 : *sid_p = dom_sid_add_rid(mem_ctx, *l.out.sid, user_rid);
620 : }
621 32 : return true;
622 :
623 : }
624 :
625 : /*
626 : * Create a test user
627 : */
628 :
629 4 : 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 0 : TALLOC_CTX *tmp_ctx;
637 0 : NTSTATUS status;
638 0 : struct dcerpc_pipe *samr_pipe;
639 0 : struct dcerpc_binding_handle *samr_handle;
640 0 : struct policy_handle *wks_handle;
641 4 : bool ret = false;
642 :
643 4 : if (!(tmp_ctx = talloc_new(mem_ctx))) {
644 0 : torture_comment(tctx, "talloc_init failed\n");
645 0 : return false;
646 : }
647 :
648 4 : 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 4 : if (ret == false) {
654 0 : torture_comment(tctx, "get_usr_handle failed\n");
655 0 : goto done;
656 : }
657 4 : samr_handle = samr_pipe->binding_handle;
658 :
659 : {
660 0 : struct samr_SetUserInfo2 sui2;
661 0 : struct samr_SetUserInfo sui;
662 0 : struct samr_QueryUserInfo qui;
663 0 : union samr_UserInfo u_info;
664 0 : union samr_UserInfo *info;
665 0 : DATA_BLOB session_key;
666 :
667 4 : ZERO_STRUCT(u_info);
668 4 : encode_pw_buffer(u_info.info23.password.data, password,
669 : STR_UNICODE);
670 :
671 4 : status = dcerpc_fetch_session_key(samr_pipe, &session_key);
672 4 : if (!NT_STATUS_IS_OK(status)) {
673 0 : torture_comment(tctx, "dcerpc_fetch_session_key failed\n");
674 0 : goto done;
675 : }
676 :
677 4 : status = init_samr_CryptPassword(password,
678 : &session_key,
679 : &u_info.info23.password);
680 4 : if (!NT_STATUS_IS_OK(status)) {
681 0 : torture_comment(tctx, "init_samr_CryptPassword failed\n");
682 0 : goto done;
683 : }
684 :
685 4 : u_info.info23.info.password_expired = 0;
686 4 : u_info.info23.info.fields_present = SAMR_FIELD_NT_PASSWORD_PRESENT |
687 : SAMR_FIELD_LM_PASSWORD_PRESENT |
688 : SAMR_FIELD_EXPIRED_FLAG;
689 4 : sui2.in.user_handle = wks_handle;
690 4 : sui2.in.info = &u_info;
691 4 : sui2.in.level = 23;
692 :
693 4 : status = dcerpc_samr_SetUserInfo2_r(samr_handle, tmp_ctx, &sui2);
694 4 : 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 4 : 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 4 : u_info.info16.acct_flags = ACB_NORMAL;
706 4 : sui.in.user_handle = wks_handle;
707 4 : sui.in.info = &u_info;
708 4 : sui.in.level = 16;
709 :
710 4 : status = dcerpc_samr_SetUserInfo_r(samr_handle, tmp_ctx, &sui);
711 4 : 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 4 : qui.in.user_handle = wks_handle;
717 4 : qui.in.level = 21;
718 4 : qui.out.info = &info;
719 :
720 4 : status = dcerpc_samr_QueryUserInfo_r(samr_handle, tmp_ctx, &qui);
721 4 : 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 4 : info->info21.allow_password_change = 0;
727 4 : info->info21.force_password_change = 0;
728 4 : info->info21.account_name.string = NULL;
729 4 : info->info21.rid = 0;
730 4 : info->info21.acct_expiry = 0;
731 4 : info->info21.fields_present = 0x81827fa; /* copy usrmgr.exe */
732 :
733 4 : u_info.info21 = info->info21;
734 4 : sui.in.user_handle = wks_handle;
735 4 : sui.in.info = &u_info;
736 4 : sui.in.level = 21;
737 :
738 4 : status = dcerpc_samr_SetUserInfo_r(samr_handle, tmp_ctx, &sui);
739 4 : 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 4 : *domain_name= talloc_steal(mem_ctx, *domain_name);
746 4 : *user_sid = talloc_steal(mem_ctx, *user_sid);
747 4 : ret = true;
748 4 : done:
749 4 : talloc_free(tmp_ctx);
750 4 : return ret;
751 : }
752 :
753 : /*
754 : * Delete a test user
755 : */
756 :
757 16 : 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 0 : TALLOC_CTX *mem_ctx;
763 0 : NTSTATUS status;
764 0 : char *dom_name;
765 0 : struct dcerpc_pipe *samr_pipe;
766 0 : struct dcerpc_binding_handle *samr_handle;
767 0 : struct policy_handle *user_handle;
768 16 : bool ret = false;
769 :
770 16 : if ((mem_ctx = talloc_init("leave")) == NULL) {
771 0 : torture_comment(tctx, "talloc_init failed\n");
772 0 : return false;
773 : }
774 :
775 16 : 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 16 : if (ret == false) {
781 0 : torture_comment(tctx, "get_wks_handle failed\n");
782 0 : goto done;
783 : }
784 16 : samr_handle = samr_pipe->binding_handle;
785 :
786 : {
787 0 : struct samr_DeleteUser d;
788 :
789 16 : d.in.user_handle = user_handle;
790 16 : d.out.user_handle = user_handle;
791 :
792 16 : status = dcerpc_samr_DeleteUser_r(samr_handle, mem_ctx, &d);
793 16 : 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 16 : 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 16 : ret = true;
805 :
806 16 : done:
807 16 : talloc_free(mem_ctx);
808 16 : return ret;
809 : }
810 :
811 : /*
812 : * Do a Samba3-style join
813 : */
814 :
815 12 : 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 0 : TALLOC_CTX *mem_ctx;
822 0 : NTSTATUS status;
823 0 : char *dom_name;
824 0 : struct dcerpc_pipe *samr_pipe;
825 0 : struct dcerpc_binding_handle *samr_handle;
826 0 : struct policy_handle *wks_handle;
827 12 : bool ret = false;
828 0 : NTTIME last_password_change;
829 :
830 12 : if ((mem_ctx = talloc_init("join3")) == NULL) {
831 0 : torture_comment(tctx, "talloc_init failed\n");
832 0 : return false;
833 : }
834 :
835 12 : ret = get_usr_handle(
836 : tctx, cli, mem_ctx, admin_creds,
837 : DCERPC_AUTH_TYPE_NTLMSSP,
838 : DCERPC_AUTH_LEVEL_PRIVACY,
839 12 : talloc_asprintf(mem_ctx, "%s$",
840 : cli_credentials_get_workstation(wks_creds)),
841 : &dom_name, &samr_pipe, &wks_handle, NULL);
842 12 : if (ret == false) {
843 0 : torture_comment(tctx, "get_wks_handle failed\n");
844 0 : goto done;
845 : }
846 12 : samr_handle = samr_pipe->binding_handle;
847 12 : ret = false;
848 : {
849 0 : struct samr_QueryUserInfo q;
850 0 : union samr_UserInfo *info;
851 :
852 12 : q.in.user_handle = wks_handle;
853 12 : q.in.level = 21;
854 12 : q.out.info = &info;
855 :
856 12 : status = dcerpc_samr_QueryUserInfo_r(samr_handle, mem_ctx, &q);
857 12 : 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 12 : 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 12 : last_password_change = info->info21.last_password_change;
870 : }
871 :
872 12 : cli_credentials_set_domain(wks_creds, dom_name, CRED_SPECIFIED);
873 :
874 12 : if (use_level25) {
875 0 : struct samr_SetUserInfo2 sui2;
876 0 : union samr_UserInfo u_info;
877 4 : struct samr_UserInfo21 *i21 = &u_info.info25.info;
878 0 : DATA_BLOB session_key;
879 :
880 4 : ZERO_STRUCT(u_info);
881 :
882 4 : i21->full_name.string = talloc_asprintf(
883 : mem_ctx, "%s$",
884 : cli_credentials_get_workstation(wks_creds));
885 4 : i21->acct_flags = ACB_WSTRUST;
886 4 : 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 4 : status = dcerpc_fetch_session_key(samr_pipe, &session_key);
894 4 : 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 4 : status = init_samr_CryptPasswordEx(cli_credentials_get_password(wks_creds),
901 : &session_key,
902 : &u_info.info25.password);
903 :
904 4 : sui2.in.user_handle = wks_handle;
905 4 : sui2.in.level = 25;
906 4 : sui2.in.info = &u_info;
907 :
908 4 : status = dcerpc_samr_SetUserInfo2_r(samr_handle, mem_ctx, &sui2);
909 4 : 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 4 : 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 0 : struct samr_SetUserInfo2 sui2;
921 0 : struct samr_SetUserInfo sui;
922 0 : union samr_UserInfo u_info;
923 0 : DATA_BLOB session_key;
924 :
925 8 : 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 8 : u_info.info24.password_expired = 1;
930 :
931 8 : status = dcerpc_fetch_session_key(samr_pipe, &session_key);
932 8 : if (!NT_STATUS_IS_OK(status)) {
933 0 : torture_comment(tctx, "dcerpc_fetch_session_key failed\n");
934 0 : goto done;
935 : }
936 :
937 8 : status = init_samr_CryptPassword(cli_credentials_get_password(wks_creds),
938 : &session_key,
939 : &u_info.info24.password);
940 :
941 8 : sui2.in.user_handle = wks_handle;
942 8 : sui2.in.info = &u_info;
943 8 : sui2.in.level = 24;
944 :
945 8 : status = dcerpc_samr_SetUserInfo2_r(samr_handle, mem_ctx, &sui2);
946 8 : 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 8 : 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 8 : u_info.info16.acct_flags = ACB_WSTRUST;
958 8 : sui.in.user_handle = wks_handle;
959 8 : sui.in.info = &u_info;
960 8 : sui.in.level = 16;
961 :
962 8 : status = dcerpc_samr_SetUserInfo_r(samr_handle, mem_ctx, &sui);
963 8 : 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 0 : struct samr_QueryUserInfo q;
971 0 : union samr_UserInfo *info;
972 :
973 12 : q.in.user_handle = wks_handle;
974 12 : q.in.level = 21;
975 12 : q.out.info = &info;
976 :
977 12 : status = dcerpc_samr_QueryUserInfo_r(samr_handle, mem_ctx, &q);
978 12 : 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 12 : 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 12 : if (use_level25) {
990 4 : if (last_password_change
991 4 : == 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 8 : if (last_password_change
1000 8 : != 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 12 : ret = true;
1010 :
1011 12 : done:
1012 12 : talloc_free(mem_ctx);
1013 12 : return ret;
1014 : }
1015 :
1016 : /*
1017 : * Do a ReqChallenge/Auth2 and get the wks creds
1018 : */
1019 :
1020 16 : static bool auth2(struct torture_context *tctx,
1021 : struct smbcli_state *cli,
1022 : struct cli_credentials *wks_cred)
1023 : {
1024 0 : TALLOC_CTX *mem_ctx;
1025 0 : struct dcerpc_pipe *net_pipe;
1026 0 : struct dcerpc_binding_handle *net_handle;
1027 16 : bool result = false;
1028 0 : NTSTATUS status;
1029 0 : struct netr_ServerReqChallenge r;
1030 0 : struct netr_Credential netr_cli_creds;
1031 0 : struct netr_Credential netr_srv_creds;
1032 0 : uint32_t negotiate_flags;
1033 0 : struct netr_ServerAuthenticate2 a;
1034 0 : struct netlogon_creds_CredentialState *creds_state;
1035 0 : struct netr_Credential netr_cred;
1036 0 : struct samr_Password mach_pw;
1037 :
1038 16 : mem_ctx = talloc_new(NULL);
1039 16 : if (mem_ctx == NULL) {
1040 0 : torture_comment(tctx, "talloc_new failed\n");
1041 0 : return false;
1042 : }
1043 :
1044 16 : status = pipe_bind_smb(tctx, mem_ctx, cli->tree, "\\netlogon",
1045 : &ndr_table_netlogon, &net_pipe);
1046 16 : torture_assert_ntstatus_ok_goto(tctx, status, result, done,
1047 : "pipe_bind_smb failed");
1048 16 : net_handle = net_pipe->binding_handle;
1049 :
1050 16 : r.in.computer_name = cli_credentials_get_workstation(wks_cred);
1051 16 : r.in.server_name = talloc_asprintf(
1052 : mem_ctx, "\\\\%s", dcerpc_server_name(net_pipe));
1053 16 : if (r.in.server_name == NULL) {
1054 0 : torture_comment(tctx, "talloc_asprintf failed\n");
1055 0 : goto done;
1056 : }
1057 16 : generate_random_buffer(netr_cli_creds.data,
1058 : sizeof(netr_cli_creds.data));
1059 16 : r.in.credentials = &netr_cli_creds;
1060 16 : r.out.return_credentials = &netr_srv_creds;
1061 :
1062 16 : status = dcerpc_netr_ServerReqChallenge_r(net_handle, mem_ctx, &r);
1063 16 : 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 16 : 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 16 : negotiate_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS | NETLOGON_NEG_SUPPORTS_AES;
1075 16 : E_md4hash(cli_credentials_get_password(wks_cred), mach_pw.hash);
1076 :
1077 16 : a.in.server_name = talloc_asprintf(
1078 : mem_ctx, "\\\\%s", dcerpc_server_name(net_pipe));
1079 16 : a.in.account_name = talloc_asprintf(
1080 : mem_ctx, "%s$", cli_credentials_get_workstation(wks_cred));
1081 16 : a.in.computer_name = cli_credentials_get_workstation(wks_cred);
1082 16 : a.in.secure_channel_type = SEC_CHAN_WKSTA;
1083 16 : a.in.negotiate_flags = &negotiate_flags;
1084 16 : a.out.negotiate_flags = &negotiate_flags;
1085 16 : a.in.credentials = &netr_cred;
1086 16 : a.out.return_credentials = &netr_cred;
1087 :
1088 16 : creds_state = netlogon_creds_client_init(mem_ctx,
1089 : a.in.account_name,
1090 : a.in.computer_name,
1091 16 : a.in.secure_channel_type,
1092 16 : r.in.credentials,
1093 16 : r.out.return_credentials, &mach_pw,
1094 : &netr_cred, negotiate_flags);
1095 16 : torture_assert(tctx, (creds_state != NULL), "memory allocation failed");
1096 :
1097 16 : status = dcerpc_netr_ServerAuthenticate2_r(net_handle, mem_ctx, &a);
1098 16 : 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 16 : 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 16 : 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 16 : cli_credentials_set_netlogon_creds(wks_cred, creds_state);
1115 :
1116 16 : result = true;
1117 :
1118 16 : done:
1119 16 : talloc_free(mem_ctx);
1120 16 : 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 16 : 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 0 : TALLOC_CTX *mem_ctx;
1134 0 : NTSTATUS status;
1135 16 : bool ret = false;
1136 0 : struct dcerpc_pipe *net_pipe;
1137 0 : struct dcerpc_binding_handle *net_handle;
1138 0 : int i;
1139 :
1140 16 : mem_ctx = talloc_new(NULL);
1141 16 : if (mem_ctx == NULL) {
1142 0 : torture_comment(tctx, "talloc_new failed\n");
1143 0 : return false;
1144 : }
1145 :
1146 : #if 1
1147 16 : 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 16 : torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
1153 : "pipe_bind_smb_auth failed");
1154 16 : 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 16 : net_handle = net_pipe->binding_handle;
1166 :
1167 :
1168 48 : for (i=2; i<4; i++) {
1169 0 : int flags;
1170 0 : DATA_BLOB chal, nt_resp, lm_resp, names_blob;
1171 0 : struct netlogon_creds_CredentialState *creds_state;
1172 0 : struct netr_Authenticator netr_auth, netr_auth2;
1173 0 : struct netr_NetworkInfo ninfo;
1174 0 : struct netr_PasswordInfo pinfo;
1175 0 : struct netr_LogonSamLogon r;
1176 0 : union netr_LogonLevel logon;
1177 0 : union netr_Validation validation;
1178 0 : uint8_t authoritative;
1179 0 : struct netr_Authenticator return_authenticator;
1180 :
1181 32 : flags = CLI_CRED_LANMAN_AUTH | CLI_CRED_NTLM_AUTH |
1182 : CLI_CRED_NTLMv2_AUTH;
1183 :
1184 32 : chal = data_blob_talloc(mem_ctx, NULL, 8);
1185 32 : if (chal.data == NULL) {
1186 0 : torture_comment(tctx, "data_blob_talloc failed\n");
1187 0 : goto done;
1188 : }
1189 :
1190 32 : generate_random_buffer(chal.data, chal.length);
1191 32 : names_blob = NTLMv2_generate_names_blob(
1192 : mem_ctx,
1193 : cli_credentials_get_workstation(wks_creds),
1194 : cli_credentials_get_domain(wks_creds));
1195 32 : status = cli_credentials_get_ntlm_response(
1196 : user_creds, mem_ctx, &flags, chal, NULL, names_blob,
1197 : &lm_resp, &nt_resp, NULL, NULL);
1198 32 : 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 32 : creds_state = cli_credentials_get_netlogon_creds(wks_creds);
1205 32 : netlogon_creds_client_authenticator(creds_state, &netr_auth);
1206 :
1207 32 : ninfo.identity_info.account_name.string =
1208 32 : cli_credentials_get_username(user_creds);
1209 32 : ninfo.identity_info.domain_name.string =
1210 32 : cli_credentials_get_domain(user_creds);
1211 32 : ninfo.identity_info.parameter_control = 0;
1212 32 : ninfo.identity_info.logon_id = 0;
1213 32 : ninfo.identity_info.workstation.string =
1214 32 : cli_credentials_get_workstation(user_creds);
1215 32 : memcpy(ninfo.challenge, chal.data, sizeof(ninfo.challenge));
1216 32 : ninfo.nt.length = nt_resp.length;
1217 32 : ninfo.nt.data = nt_resp.data;
1218 32 : ninfo.lm.length = lm_resp.length;
1219 32 : ninfo.lm.data = lm_resp.data;
1220 :
1221 32 : logon.network = &ninfo;
1222 :
1223 32 : r.in.server_name = talloc_asprintf(
1224 : mem_ctx, "\\\\%s", dcerpc_server_name(net_pipe));
1225 32 : ZERO_STRUCT(netr_auth2);
1226 32 : r.in.computer_name =
1227 32 : cli_credentials_get_workstation(wks_creds);
1228 32 : r.in.credential = &netr_auth;
1229 32 : r.in.return_authenticator = &netr_auth2;
1230 32 : r.in.logon_level = NetlogonNetworkInformation;
1231 32 : r.in.validation_level = i;
1232 32 : r.in.logon = &logon;
1233 32 : r.out.validation = &validation;
1234 32 : r.out.authoritative = &authoritative;
1235 32 : r.out.return_authenticator = &return_authenticator;
1236 :
1237 32 : status = dcerpc_netr_LogonSamLogon_r(net_handle, mem_ctx, &r);
1238 32 : 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 32 : 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 32 : if ((r.out.return_authenticator == NULL) ||
1250 32 : (!netlogon_creds_client_check(creds_state,
1251 32 : &r.out.return_authenticator->cred))) {
1252 0 : torture_comment(tctx, "Credentials check failed!\n");
1253 0 : goto done;
1254 : }
1255 :
1256 32 : netlogon_creds_client_authenticator(creds_state, &netr_auth);
1257 :
1258 32 : pinfo.identity_info = ninfo.identity_info;
1259 32 : ZERO_STRUCT(pinfo.lmpassword.hash);
1260 32 : E_md4hash(cli_credentials_get_password(user_creds),
1261 : pinfo.ntpassword.hash);
1262 :
1263 32 : 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 32 : netlogon_creds_aes_encrypt(creds_state, pinfo.ntpassword.hash, 16);
1275 :
1276 32 : r.in.logon_level = NetlogonInteractiveInformation;
1277 32 : r.in.logon = &logon;
1278 32 : r.out.return_authenticator = &return_authenticator;
1279 :
1280 32 : status = dcerpc_netr_LogonSamLogon_r(net_handle, mem_ctx, &r);
1281 32 : 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 32 : 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 32 : if ((r.out.return_authenticator == NULL) ||
1293 32 : (!netlogon_creds_client_check(creds_state,
1294 32 : &r.out.return_authenticator->cred))) {
1295 0 : torture_comment(tctx, "Credentials check failed!\n");
1296 0 : goto done;
1297 : }
1298 : }
1299 :
1300 : {
1301 0 : struct netr_ServerPasswordSet s;
1302 16 : char *password = generate_random_password(wks_creds, 8, 255);
1303 0 : struct netlogon_creds_CredentialState *creds_state;
1304 0 : struct netr_Authenticator credential, return_authenticator;
1305 0 : struct samr_Password new_password;
1306 :
1307 16 : s.in.server_name = talloc_asprintf(
1308 : mem_ctx, "\\\\%s", dcerpc_server_name(net_pipe));
1309 16 : s.in.computer_name = cli_credentials_get_workstation(wks_creds);
1310 16 : s.in.account_name = talloc_asprintf(
1311 : mem_ctx, "%s$", s.in.computer_name);
1312 16 : s.in.secure_channel_type = SEC_CHAN_WKSTA;
1313 16 : s.in.credential = &credential;
1314 16 : s.in.new_password = &new_password;
1315 16 : s.out.return_authenticator = &return_authenticator;
1316 :
1317 16 : E_md4hash(password, new_password.hash);
1318 :
1319 16 : creds_state = cli_credentials_get_netlogon_creds(wks_creds);
1320 16 : netlogon_creds_des_encrypt(creds_state, &new_password);
1321 16 : netlogon_creds_client_authenticator(creds_state, &credential);
1322 :
1323 16 : status = dcerpc_netr_ServerPasswordSet_r(net_handle, mem_ctx, &s);
1324 16 : if (!NT_STATUS_IS_OK(status)) {
1325 0 : torture_comment(tctx, "ServerPasswordSet - %s\n", nt_errstr(status));
1326 0 : goto done;
1327 : }
1328 16 : 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 16 : if (!netlogon_creds_client_check(creds_state,
1334 16 : &s.out.return_authenticator->cred)) {
1335 0 : torture_comment(tctx, "Credential chaining failed\n");
1336 : }
1337 :
1338 16 : cli_credentials_set_password(wks_creds, password,
1339 : CRED_SPECIFIED);
1340 : }
1341 :
1342 16 : ret = true;
1343 16 : done:
1344 16 : talloc_free(mem_ctx);
1345 16 : return ret;
1346 : }
1347 :
1348 : /*
1349 : * Delete the wks account again
1350 : */
1351 :
1352 12 : 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 12 : char *wks_name = talloc_asprintf(
1358 : NULL, "%s$", cli_credentials_get_workstation(wks_creds));
1359 0 : bool ret;
1360 :
1361 12 : ret = delete_user(tctx, cli, admin_creds, wks_name);
1362 12 : talloc_free(wks_name);
1363 12 : return ret;
1364 : }
1365 :
1366 : /*
1367 : * Test the Samba3 DC code a bit. Join, do some schan netlogon ops, leave
1368 : */
1369 :
1370 4 : static bool torture_netlogon_samba3(struct torture_context *torture)
1371 : {
1372 0 : NTSTATUS status;
1373 0 : struct smbcli_state *cli;
1374 0 : struct cli_credentials *wks_creds;
1375 0 : const char *wks_name;
1376 0 : int i;
1377 0 : struct smbcli_options options;
1378 0 : struct smbcli_session_options session_options;
1379 :
1380 4 : wks_name = torture_setting_string(torture, "wksname", NULL);
1381 4 : torture_assert(torture, wks_name != NULL, "wksname not set");
1382 :
1383 4 : lpcfg_smbcli_options(torture->lp_ctx, &options);
1384 4 : lpcfg_smbcli_session_options(torture->lp_ctx, &session_options);
1385 :
1386 4 : 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 4 : torture_assert_ntstatus_ok(torture, status, "smbcli_full_connection failed\n");
1396 :
1397 4 : wks_creds = cli_credentials_init(torture);
1398 4 : if (wks_creds == NULL) {
1399 0 : torture_fail(torture, "cli_credentials_init failed\n");
1400 : }
1401 :
1402 4 : cli_credentials_set_conf(wks_creds, torture->lp_ctx);
1403 4 : cli_credentials_set_secure_channel_type(wks_creds, SEC_CHAN_WKSTA);
1404 4 : cli_credentials_set_username(wks_creds, wks_name, CRED_SPECIFIED);
1405 4 : cli_credentials_set_workstation(wks_creds, wks_name, CRED_SPECIFIED);
1406 4 : cli_credentials_set_password(wks_creds,
1407 4 : generate_random_password(wks_creds, 8, 255),
1408 : CRED_SPECIFIED);
1409 :
1410 4 : torture_assert(torture,
1411 : join3(torture, cli, false, NULL, wks_creds),
1412 : "join failed");
1413 :
1414 4 : cli_credentials_set_domain(
1415 : samba_cmdline_get_creds(),
1416 : cli_credentials_get_domain(wks_creds),
1417 : CRED_SPECIFIED);
1418 :
1419 12 : 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 0 : int j;
1426 :
1427 8 : torture_assert(torture,
1428 : auth2(torture, cli, wks_creds),
1429 : "auth2 failed");
1430 :
1431 24 : for (j=0; j<2; j++) {
1432 16 : torture_assert(torture,
1433 : schan(torture, cli, wks_creds,
1434 : samba_cmdline_get_creds()),
1435 : "schan failed");
1436 : }
1437 : }
1438 :
1439 4 : torture_assert(torture,
1440 : leave(torture, cli, NULL, wks_creds),
1441 : "leave failed");
1442 :
1443 4 : return true;
1444 : }
1445 :
1446 : /*
1447 : * Do a simple join, testjoin and leave using specified smb and samr
1448 : * credentials
1449 : */
1450 :
1451 8 : 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 0 : NTSTATUS status;
1458 0 : struct smbcli_state *cli;
1459 0 : struct cli_credentials *wks_creds;
1460 0 : struct smbcli_options options;
1461 0 : struct smbcli_session_options session_options;
1462 :
1463 8 : lpcfg_smbcli_options(tctx->lp_ctx, &options);
1464 8 : lpcfg_smbcli_session_options(tctx->lp_ctx, &session_options);
1465 :
1466 8 : 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 8 : torture_assert_ntstatus_ok(tctx, status,
1474 : "smbcli_full_connection failed");
1475 :
1476 8 : wks_creds = cli_credentials_init(cli);
1477 8 : torture_assert(tctx, wks_creds, "cli_credentials_init failed");
1478 :
1479 8 : cli_credentials_set_conf(wks_creds, tctx->lp_ctx);
1480 8 : cli_credentials_set_secure_channel_type(wks_creds, SEC_CHAN_WKSTA);
1481 8 : cli_credentials_set_username(wks_creds, wks_name, CRED_SPECIFIED);
1482 8 : cli_credentials_set_workstation(wks_creds, wks_name, CRED_SPECIFIED);
1483 8 : cli_credentials_set_password(wks_creds,
1484 8 : generate_random_password(wks_creds, 8, 255),
1485 : CRED_SPECIFIED);
1486 :
1487 8 : torture_assert(tctx,
1488 : join3(tctx, cli, use_level25, samr_creds, wks_creds),
1489 : "join failed");
1490 :
1491 8 : cli_credentials_set_domain(
1492 : samba_cmdline_get_creds(),
1493 : cli_credentials_get_domain(wks_creds),
1494 : CRED_SPECIFIED);
1495 :
1496 8 : torture_assert(tctx,
1497 : auth2(tctx, cli, wks_creds),
1498 : "auth2 failed");
1499 :
1500 8 : torture_assert(tctx,
1501 : leave(tctx, cli, samr_creds, wks_creds),
1502 : "leave failed");
1503 :
1504 8 : talloc_free(cli);
1505 :
1506 8 : 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 4 : static bool torture_samba3_sessionkey(struct torture_context *torture)
1515 : {
1516 0 : struct cli_credentials *anon_creds;
1517 0 : const char *wks_name;
1518 :
1519 :
1520 4 : wks_name = torture_setting_string(torture, "wksname", NULL);
1521 4 : torture_assert(torture, wks_name != NULL, "wksname not set");
1522 :
1523 4 : if (!(anon_creds = cli_credentials_init_anon(torture))) {
1524 0 : torture_fail(torture, "create_anon_creds failed\n");
1525 : }
1526 :
1527 4 : cli_credentials_set_workstation(anon_creds, wks_name, CRED_SPECIFIED);
1528 :
1529 :
1530 4 : 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 4 : 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 4 : 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 4 : return true;
1556 : }
1557 :
1558 : /*
1559 : * Sane wrapper around lsa_LookupNames
1560 : */
1561 :
1562 20 : 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 0 : struct lsa_ObjectAttribute attr;
1569 0 : struct lsa_QosInfo qos;
1570 0 : struct lsa_OpenPolicy2 r;
1571 0 : struct lsa_Close c;
1572 0 : NTSTATUS status;
1573 0 : struct policy_handle handle;
1574 0 : struct lsa_LookupNames l;
1575 0 : struct lsa_TransSidArray sids;
1576 20 : struct lsa_RefDomainList *domains = NULL;
1577 0 : struct lsa_String lsa_name;
1578 20 : uint32_t count = 0;
1579 0 : struct dom_sid *result;
1580 0 : TALLOC_CTX *tmp_ctx;
1581 20 : struct dcerpc_binding_handle *b = p->binding_handle;
1582 :
1583 20 : if (!(tmp_ctx = talloc_new(mem_ctx))) {
1584 0 : return NULL;
1585 : }
1586 :
1587 20 : qos.len = 0;
1588 20 : qos.impersonation_level = 2;
1589 20 : qos.context_mode = 1;
1590 20 : qos.effective_only = 0;
1591 :
1592 20 : attr.len = 0;
1593 20 : attr.root_dir = NULL;
1594 20 : attr.object_name = NULL;
1595 20 : attr.attributes = 0;
1596 20 : attr.sec_desc = NULL;
1597 20 : attr.sec_qos = &qos;
1598 :
1599 20 : r.in.system_name = "\\";
1600 20 : r.in.attr = &attr;
1601 20 : r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1602 20 : r.out.handle = &handle;
1603 :
1604 20 : status = dcerpc_lsa_OpenPolicy2_r(b, tmp_ctx, &r);
1605 20 : 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 20 : 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 20 : sids.count = 0;
1617 20 : sids.sids = NULL;
1618 :
1619 20 : lsa_name.string = talloc_asprintf(tmp_ctx, "%s\\%s", domain, name);
1620 :
1621 20 : l.in.handle = &handle;
1622 20 : l.in.num_names = 1;
1623 20 : l.in.names = &lsa_name;
1624 20 : l.in.sids = &sids;
1625 20 : l.in.level = 1;
1626 20 : l.in.count = &count;
1627 20 : l.out.count = &count;
1628 20 : l.out.sids = &sids;
1629 20 : l.out.domains = &domains;
1630 :
1631 20 : status = dcerpc_lsa_LookupNames_r(b, tmp_ctx, &l);
1632 20 : 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 20 : 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 20 : result = dom_sid_add_rid(mem_ctx, domains->domains[0].sid,
1646 20 : l.out.sids->sids[0].rid);
1647 :
1648 20 : c.in.handle = &handle;
1649 20 : c.out.handle = &handle;
1650 :
1651 20 : status = dcerpc_lsa_Close_r(b, tmp_ctx, &c);
1652 20 : 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 20 : 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 20 : talloc_free(tmp_ctx);
1664 20 : return result;
1665 : }
1666 :
1667 : /*
1668 : * Find out the user SID on this connection
1669 : */
1670 :
1671 20 : static struct dom_sid *whoami(struct torture_context *tctx,
1672 : TALLOC_CTX *mem_ctx,
1673 : struct smbcli_tree *tree)
1674 : {
1675 0 : struct dcerpc_pipe *lsa;
1676 0 : struct dcerpc_binding_handle *lsa_handle;
1677 0 : struct lsa_GetUserName r;
1678 0 : NTSTATUS status;
1679 20 : struct lsa_String *authority_name_p = NULL;
1680 20 : struct lsa_String *account_name_p = NULL;
1681 0 : struct dom_sid *result;
1682 :
1683 20 : status = pipe_bind_smb(tctx, mem_ctx, tree, "\\pipe\\lsarpc",
1684 : &ndr_table_lsarpc, &lsa);
1685 20 : 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 20 : lsa_handle = lsa->binding_handle;
1691 :
1692 20 : r.in.system_name = "\\";
1693 20 : r.in.account_name = &account_name_p;
1694 20 : r.in.authority_name = &authority_name_p;
1695 20 : r.out.account_name = &account_name_p;
1696 :
1697 20 : status = dcerpc_lsa_GetUserName_r(lsa_handle, mem_ctx, &r);
1698 :
1699 20 : authority_name_p = *r.out.authority_name;
1700 :
1701 20 : 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 20 : 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 20 : result = name2sid(tctx, mem_ctx, lsa, account_name_p->string,
1715 20 : authority_name_p->string);
1716 :
1717 20 : talloc_free(lsa);
1718 20 : return result;
1719 : }
1720 :
1721 52 : static int destroy_tree(struct smbcli_tree *tree)
1722 : {
1723 52 : smb_tree_disconnect(tree);
1724 52 : return 0;
1725 : }
1726 :
1727 : /*
1728 : * Do a tcon, given a session
1729 : */
1730 :
1731 56 : 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 0 : struct smbcli_tree *result;
1738 0 : TALLOC_CTX *tmp_ctx;
1739 0 : union smb_tcon tcon;
1740 0 : NTSTATUS status;
1741 :
1742 56 : if (!(tmp_ctx = talloc_new(mem_ctx))) {
1743 0 : return NT_STATUS_NO_MEMORY;
1744 : }
1745 :
1746 56 : 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 56 : tcon.generic.level = RAW_TCON_TCONX;
1752 56 : tcon.tconx.in.flags = TCONX_FLAG_EXTENDED_RESPONSE;
1753 56 : tcon.tconx.in.flags |= TCONX_FLAG_EXTENDED_SIGNATURES;
1754 56 : tcon.tconx.in.password = data_blob(NULL, 0);
1755 56 : tcon.tconx.in.path = sharename;
1756 56 : tcon.tconx.in.device = "?????";
1757 :
1758 56 : status = smb_raw_tcon(result, tmp_ctx, &tcon);
1759 56 : if (!NT_STATUS_IS_OK(status)) {
1760 4 : torture_warning(tctx, "smb_raw_tcon failed: %s\n",
1761 : nt_errstr(status));
1762 4 : talloc_free(tmp_ctx);
1763 4 : return status;
1764 : }
1765 :
1766 52 : result->tid = tcon.tconx.out.tid;
1767 :
1768 52 : if (tcon.tconx.out.options & SMB_EXTENDED_SIGNATURES) {
1769 4 : smb1cli_session_protect_session_key(result->session->smbXcli);
1770 : }
1771 :
1772 52 : result = talloc_steal(mem_ctx, result);
1773 52 : talloc_set_destructor(result, destroy_tree);
1774 52 : talloc_free(tmp_ctx);
1775 52 : *res = result;
1776 52 : return NT_STATUS_OK;
1777 : }
1778 :
1779 : /*
1780 : * Test the getusername behaviour
1781 : */
1782 :
1783 4 : static bool torture_samba3_rpc_getusername(struct torture_context *torture)
1784 : {
1785 0 : NTSTATUS status;
1786 0 : struct smbcli_state *cli;
1787 4 : bool ret = true;
1788 0 : struct dom_sid *user_sid;
1789 0 : struct dom_sid *created_sid;
1790 0 : struct cli_credentials *anon_creds;
1791 0 : struct cli_credentials *user_creds;
1792 0 : char *domain_name;
1793 0 : struct smbcli_options options;
1794 0 : struct smbcli_session_options session_options;
1795 :
1796 4 : lpcfg_smbcli_options(torture->lp_ctx, &options);
1797 4 : lpcfg_smbcli_session_options(torture->lp_ctx, &session_options);
1798 :
1799 4 : if (!(anon_creds = cli_credentials_init_anon(torture))) {
1800 0 : torture_fail(torture, "create_anon_creds failed\n");
1801 : }
1802 :
1803 4 : 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 4 : torture_assert_ntstatus_ok(torture, status, "anon smbcli_full_connection failed\n");
1811 :
1812 4 : if (!(user_sid = whoami(torture, torture, cli->tree))) {
1813 0 : torture_fail(torture, "whoami on anon connection failed\n");
1814 : }
1815 :
1816 4 : 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 4 : talloc_free(cli);
1820 :
1821 4 : 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 4 : torture_assert_ntstatus_ok(torture, status, "smbcli_full_connection failed\n");
1829 :
1830 4 : if (!(user_sid = whoami(torture, torture, cli->tree))) {
1831 0 : torture_fail(torture, "whoami on auth'ed connection failed\n");
1832 : }
1833 :
1834 4 : if (!(user_creds = cli_credentials_init(torture))) {
1835 0 : torture_fail(torture, "cli_credentials_init failed\n");
1836 : }
1837 :
1838 4 : cli_credentials_set_conf(user_creds, torture->lp_ctx);
1839 4 : cli_credentials_set_username(user_creds, "torture_username",
1840 : CRED_SPECIFIED);
1841 4 : cli_credentials_set_password(user_creds,
1842 4 : generate_random_password(user_creds, 8, 255),
1843 : CRED_SPECIFIED);
1844 :
1845 4 : 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 4 : cli_credentials_set_domain(user_creds, domain_name,
1853 : CRED_SPECIFIED);
1854 :
1855 : {
1856 0 : struct smbcli_session *session2;
1857 0 : struct smb_composite_sesssetup setup;
1858 0 : struct smbcli_tree *tree;
1859 :
1860 4 : session2 = smbcli_session_init(cli->transport, torture, false, session_options);
1861 4 : if (session2 == NULL) {
1862 0 : torture_fail(torture, "smbcli_session_init failed\n");
1863 : }
1864 :
1865 4 : setup.in.sesskey = cli->transport->negotiate.sesskey;
1866 4 : setup.in.capabilities = cli->transport->negotiate.capabilities;
1867 4 : setup.in.workgroup = "";
1868 4 : setup.in.credentials = user_creds;
1869 4 : setup.in.gensec_settings = lpcfg_gensec_settings(torture, torture->lp_ctx);
1870 :
1871 4 : status = smb_composite_sesssetup(session2, &setup);
1872 4 : torture_assert_ntstatus_ok(torture, status, "session setup with new user failed");
1873 :
1874 4 : session2->vuid = setup.out.vuid;
1875 :
1876 4 : 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 4 : 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 4 : talloc_free(tree);
1888 : }
1889 :
1890 4 : torture_comment(torture, "Created %s, found %s\n",
1891 : dom_sid_string(torture, created_sid),
1892 : dom_sid_string(torture, user_sid));
1893 :
1894 4 : if (!dom_sid_equal(created_sid, user_sid)) {
1895 0 : ret = false;
1896 : }
1897 :
1898 4 : del:
1899 4 : 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 4 : return ret;
1906 : }
1907 :
1908 4 : static bool test_NetShareGetInfo(struct torture_context *tctx,
1909 : struct dcerpc_pipe *p,
1910 : const char *sharename)
1911 : {
1912 0 : NTSTATUS status;
1913 0 : struct srvsvc_NetShareGetInfo r;
1914 0 : union srvsvc_NetShareInfo info;
1915 4 : uint32_t levels[] = { 0, 1, 2, 501, 502, 1004, 1005, 1006, 1007, 1501 };
1916 0 : int i;
1917 4 : bool ret = true;
1918 4 : struct dcerpc_binding_handle *b = p->binding_handle;
1919 :
1920 4 : r.in.server_unc = talloc_asprintf(tctx, "\\\\%s",
1921 : dcerpc_server_name(p));
1922 4 : r.in.share_name = sharename;
1923 4 : r.out.info = &info;
1924 :
1925 44 : for (i=0;i<ARRAY_SIZE(levels);i++) {
1926 40 : r.in.level = levels[i];
1927 :
1928 40 : torture_comment(tctx, "Testing NetShareGetInfo level %u on share '%s'\n",
1929 : r.in.level, r.in.share_name);
1930 :
1931 40 : status = dcerpc_srvsvc_NetShareGetInfo_r(b, tctx, &r);
1932 40 : 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 40 : 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 4 : return ret;
1949 : }
1950 :
1951 4 : static bool test_NetShareEnum(struct torture_context *tctx,
1952 : struct dcerpc_pipe *p,
1953 : const char **one_sharename)
1954 : {
1955 0 : NTSTATUS status;
1956 0 : struct srvsvc_NetShareEnum r;
1957 0 : struct srvsvc_NetShareInfoCtr info_ctr;
1958 0 : struct srvsvc_NetShareCtr0 c0;
1959 0 : struct srvsvc_NetShareCtr1 c1;
1960 0 : struct srvsvc_NetShareCtr2 c2;
1961 0 : struct srvsvc_NetShareCtr501 c501;
1962 0 : struct srvsvc_NetShareCtr502 c502;
1963 0 : struct srvsvc_NetShareCtr1004 c1004;
1964 0 : struct srvsvc_NetShareCtr1005 c1005;
1965 0 : struct srvsvc_NetShareCtr1006 c1006;
1966 0 : struct srvsvc_NetShareCtr1007 c1007;
1967 4 : uint32_t totalentries = 0;
1968 4 : uint32_t levels[] = { 0, 1, 2, 501, 502, 1004, 1005, 1006, 1007 };
1969 0 : int i;
1970 4 : bool ret = true;
1971 4 : struct dcerpc_binding_handle *b = p->binding_handle;
1972 :
1973 4 : ZERO_STRUCT(info_ctr);
1974 :
1975 4 : r.in.server_unc = talloc_asprintf(tctx,"\\\\%s",dcerpc_server_name(p));
1976 4 : r.in.info_ctr = &info_ctr;
1977 4 : r.in.max_buffer = (uint32_t)-1;
1978 4 : r.in.resume_handle = NULL;
1979 4 : r.out.totalentries = &totalentries;
1980 4 : r.out.info_ctr = &info_ctr;
1981 :
1982 40 : for (i=0;i<ARRAY_SIZE(levels);i++) {
1983 36 : info_ctr.level = levels[i];
1984 :
1985 36 : switch (info_ctr.level) {
1986 4 : case 0:
1987 4 : ZERO_STRUCT(c0);
1988 4 : info_ctr.ctr.ctr0 = &c0;
1989 4 : break;
1990 4 : case 1:
1991 4 : ZERO_STRUCT(c1);
1992 4 : info_ctr.ctr.ctr1 = &c1;
1993 4 : break;
1994 4 : case 2:
1995 4 : ZERO_STRUCT(c2);
1996 4 : info_ctr.ctr.ctr2 = &c2;
1997 4 : break;
1998 4 : case 501:
1999 4 : ZERO_STRUCT(c501);
2000 4 : info_ctr.ctr.ctr501 = &c501;
2001 4 : break;
2002 4 : case 502:
2003 4 : ZERO_STRUCT(c502);
2004 4 : info_ctr.ctr.ctr502 = &c502;
2005 4 : break;
2006 4 : case 1004:
2007 4 : ZERO_STRUCT(c1004);
2008 4 : info_ctr.ctr.ctr1004 = &c1004;
2009 4 : break;
2010 4 : case 1005:
2011 4 : ZERO_STRUCT(c1005);
2012 4 : info_ctr.ctr.ctr1005 = &c1005;
2013 4 : break;
2014 4 : case 1006:
2015 4 : ZERO_STRUCT(c1006);
2016 4 : info_ctr.ctr.ctr1006 = &c1006;
2017 4 : break;
2018 4 : case 1007:
2019 4 : ZERO_STRUCT(c1007);
2020 4 : info_ctr.ctr.ctr1007 = &c1007;
2021 4 : break;
2022 : }
2023 :
2024 36 : torture_comment(tctx, "Testing NetShareEnum level %u\n", info_ctr.level);
2025 :
2026 36 : status = dcerpc_srvsvc_NetShareEnum_r(b, tctx, &r);
2027 36 : 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 36 : 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 36 : if (info_ctr.level == 0) {
2039 4 : struct srvsvc_NetShareCtr0 *ctr = r.out.info_ctr->ctr.ctr0;
2040 4 : if (ctr->count > 0) {
2041 4 : *one_sharename = ctr->array[0].name;
2042 : }
2043 : }
2044 : }
2045 :
2046 4 : return ret;
2047 : }
2048 :
2049 4 : static bool torture_samba3_rpc_srvsvc(struct torture_context *torture)
2050 : {
2051 0 : struct dcerpc_pipe *p;
2052 4 : const char *sharename = NULL;
2053 4 : bool ret = true;
2054 :
2055 4 : torture_assert_ntstatus_ok(torture,
2056 : torture_rpc_connection(torture, &p, &ndr_table_srvsvc),
2057 : "failed to open srvsvc");
2058 :
2059 4 : ret &= test_NetShareEnum(torture, p, &sharename);
2060 4 : if (sharename == NULL) {
2061 0 : torture_comment(torture, "did not get sharename\n");
2062 : } else {
2063 4 : ret &= test_NetShareGetInfo(torture, p, sharename);
2064 : }
2065 :
2066 4 : 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 0 : TALLOC_CTX *mem_ctx;
2077 0 : struct dcerpc_pipe *net_pipe;
2078 0 : struct dcerpc_binding_handle *net_handle;
2079 0 : char *wksname;
2080 0 : bool result = false;
2081 0 : NTSTATUS status;
2082 0 : struct netr_ServerReqChallenge r;
2083 0 : struct netr_Credential netr_cli_creds;
2084 0 : struct netr_Credential netr_srv_creds;
2085 0 : uint32_t negotiate_flags;
2086 0 : struct netr_ServerAuthenticate2 a;
2087 0 : struct netlogon_creds_CredentialState *creds_state;
2088 0 : struct netr_Credential netr_cred;
2089 0 : struct samr_Password mach_pw;
2090 0 : 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 4 : 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 0 : struct smbcli_tree *tree;
2187 0 : TALLOC_CTX *tmp_ctx;
2188 0 : struct dcerpc_pipe *p;
2189 0 : struct dcerpc_binding_handle *b;
2190 0 : NTSTATUS status;
2191 0 : struct srvsvc_NetShareGetInfo r;
2192 0 : union srvsvc_NetShareInfo info;
2193 0 : struct security_descriptor *result;
2194 :
2195 4 : if (!(tmp_ctx = talloc_new(mem_ctx))) {
2196 0 : torture_comment(tctx, "talloc_new failed\n");
2197 0 : return NULL;
2198 : }
2199 :
2200 4 : 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 4 : status = pipe_bind_smb(tctx, mem_ctx, tree, "\\pipe\\srvsvc",
2207 : &ndr_table_srvsvc, &p);
2208 4 : 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 4 : b = p->binding_handle;
2215 :
2216 : #if 0
2217 : p->conn->flags |= DCERPC_DEBUG_PRINT_IN | DCERPC_DEBUG_PRINT_OUT;
2218 : #endif
2219 :
2220 4 : r.in.server_unc = talloc_asprintf(tmp_ctx, "\\\\%s",
2221 : dcerpc_server_name(p));
2222 4 : r.in.share_name = sharename;
2223 4 : r.in.level = 502;
2224 4 : r.out.info = &info;
2225 :
2226 4 : status = dcerpc_srvsvc_NetShareGetInfo_r(b, tmp_ctx, &r);
2227 4 : 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 4 : 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 4 : result = talloc_steal(mem_ctx, info.info502->sd_buf.sd);
2241 4 : talloc_free(tmp_ctx);
2242 4 : return result;
2243 : }
2244 :
2245 24 : 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 0 : struct smbcli_tree *tree;
2252 0 : TALLOC_CTX *tmp_ctx;
2253 0 : struct dcerpc_pipe *p;
2254 0 : struct dcerpc_binding_handle *b;
2255 0 : NTSTATUS status;
2256 0 : struct sec_desc_buf i;
2257 0 : struct srvsvc_NetShareSetInfo r;
2258 0 : union srvsvc_NetShareInfo info;
2259 24 : uint32_t error = 0;
2260 :
2261 24 : 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 24 : 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 24 : status = pipe_bind_smb(tctx, mem_ctx, tree, "\\pipe\\srvsvc",
2273 : &ndr_table_srvsvc, &p);
2274 24 : 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 24 : b = p->binding_handle;
2281 :
2282 : #if 0
2283 : p->conn->flags |= DCERPC_DEBUG_PRINT_IN | DCERPC_DEBUG_PRINT_OUT;
2284 : #endif
2285 :
2286 24 : r.in.server_unc = talloc_asprintf(tmp_ctx, "\\\\%s",
2287 : dcerpc_server_name(p));
2288 24 : r.in.share_name = sharename;
2289 24 : r.in.level = 1501;
2290 24 : i.sd = sd;
2291 24 : info.info1501 = &i;
2292 24 : r.in.info = &info;
2293 24 : r.in.parm_error = &error;
2294 :
2295 24 : status = dcerpc_srvsvc_NetShareSetInfo_r(b, tmp_ctx, &r);
2296 24 : if (!NT_STATUS_IS_OK(status)) {
2297 0 : torture_comment(tctx, "srvsvc_NetShareSetInfo failed: %s\n",
2298 : nt_errstr(status));
2299 : }
2300 24 : 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 24 : talloc_free(tmp_ctx);
2306 24 : return status;
2307 : }
2308 :
2309 12 : 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 0 : TALLOC_CTX *tmp_ctx;
2318 0 : struct smbcli_tree *rmdir_tree, *tree;
2319 0 : struct dom_sid *domain_sid;
2320 0 : uint32_t rid;
2321 0 : struct security_descriptor *sd;
2322 0 : NTSTATUS status;
2323 12 : bool ret = true;
2324 :
2325 12 : if (!(tmp_ctx = talloc_new(mem_ctx))) {
2326 0 : torture_comment(tctx, "talloc_new failed\n");
2327 0 : return false;
2328 : }
2329 :
2330 12 : status = secondary_tcon(tctx, tmp_ctx, session, sharename, &rmdir_tree);
2331 12 : 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 12 : smbcli_rmdir(rmdir_tree, "sharesec_testdir");
2338 :
2339 12 : 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 24 : sd = security_descriptor_dacl_create(
2347 : tmp_ctx, 0, "S-1-5-32-544",
2348 12 : 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 12 : 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 12 : status = set_sharesec(tctx, mem_ctx, session, sharename, sd);
2359 12 : 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 12 : status = secondary_tcon(tctx, tmp_ctx, session, sharename, &tree);
2367 12 : 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 12 : if (!NT_STATUS_IS_OK(status)) {
2375 : /* An expected non-access, no point in trying to write */
2376 4 : goto done;
2377 : }
2378 :
2379 8 : status = smbcli_mkdir(tree, "sharesec_testdir");
2380 8 : 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 8 : done:
2387 12 : smbcli_rmdir(rmdir_tree, "sharesec_testdir");
2388 :
2389 12 : status = set_sharesec(tctx, mem_ctx, session, sharename, orig_sd);
2390 12 : 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 12 : talloc_free(tmp_ctx);
2398 12 : return ret;
2399 : }
2400 :
2401 4 : static bool torture_samba3_rpc_sharesec(struct torture_context *torture)
2402 : {
2403 4 : struct smbcli_state *cli = NULL;
2404 4 : struct security_descriptor *sd = NULL;
2405 4 : struct dom_sid *user_sid = NULL;
2406 4 : const char *testuser_passwd = NULL;
2407 4 : struct cli_credentials *test_credentials = NULL;
2408 0 : struct smbcli_options options;
2409 0 : struct smbcli_session_options session_options;
2410 0 : NTSTATUS status;
2411 4 : struct test_join *tj = NULL;
2412 4 : struct dcerpc_pipe *lsa_pipe = NULL;
2413 0 : 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 4 : tj = torture_create_testuser(torture,
2418 : "sharesec_user",
2419 : torture_setting_string(torture, "workgroup", NULL),
2420 : ACB_NORMAL,
2421 : &testuser_passwd);
2422 4 : if (!tj) {
2423 0 : torture_fail(torture, "Creating sharesec_user failed\n");
2424 : }
2425 :
2426 : /* Give them SeDiskOperatorPrivilege but no other privs. */
2427 4 : status = torture_rpc_connection(torture, &lsa_pipe, &ndr_table_lsarpc);
2428 4 : 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 4 : priv_array[0] = "SeDiskOperatorPrivilege";
2435 4 : 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 4 : talloc_free(lsa_pipe);
2446 :
2447 4 : test_credentials = cli_credentials_init(torture);
2448 4 : cli_credentials_set_workstation(test_credentials, "localhost", CRED_SPECIFIED);
2449 4 : cli_credentials_set_domain(test_credentials, lpcfg_workgroup(torture->lp_ctx),
2450 : CRED_SPECIFIED);
2451 4 : cli_credentials_set_username(test_credentials, "sharesec_user", CRED_SPECIFIED);
2452 4 : cli_credentials_set_password(test_credentials, testuser_passwd, CRED_SPECIFIED);
2453 :
2454 4 : ZERO_STRUCT(options);
2455 4 : ZERO_STRUCT(session_options);
2456 4 : lpcfg_smbcli_options(torture->lp_ctx, &options);
2457 4 : lpcfg_smbcli_session_options(torture->lp_ctx, &session_options);
2458 :
2459 4 : 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 4 : 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 4 : 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 4 : sd = get_sharesec(torture, torture, cli->session,
2487 : torture_setting_string(torture, "share", NULL));
2488 :
2489 4 : if (!try_tcon(torture, torture, sd, cli->session,
2490 : torture_setting_string(torture, "share", NULL),
2491 4 : 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 4 : if (!try_tcon(torture, torture, sd, cli->session,
2499 : torture_setting_string(torture, "share", NULL),
2500 4 : user_sid, SEC_FILE_READ_DATA, NT_STATUS_OK,
2501 4 : 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 4 : talloc_free(cli);
2512 4 : cli = NULL;
2513 4 : torture_delete_testuser(torture, tj, "sharesec_user");
2514 4 : talloc_free(tj);
2515 4 : tj = NULL;
2516 :
2517 4 : 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 4 : if (!(user_sid = whoami(torture, torture, cli->tree))) {
2524 0 : torture_fail(torture, "whoami failed\n");
2525 : }
2526 4 : 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 4 : return true;
2533 : }
2534 :
2535 0 : static bool torture_samba3_rpc_lsa(struct torture_context *torture)
2536 : {
2537 0 : struct dcerpc_pipe *p;
2538 0 : struct dcerpc_binding_handle *b;
2539 0 : 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 0 : struct lsa_ObjectAttribute attr;
2549 0 : 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 0 : int i;
2566 0 : int levels[] = { 2,3,5,6 };
2567 :
2568 0 : for (i=0; i<ARRAY_SIZE(levels); i++) {
2569 0 : 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 8 : static NTSTATUS get_servername(TALLOC_CTX *mem_ctx, struct smbcli_tree *tree,
2587 : char **name)
2588 : {
2589 0 : struct rap_WserverGetInfo r;
2590 0 : NTSTATUS status;
2591 0 : char servername[17];
2592 0 : size_t converted_size;
2593 :
2594 8 : r.in.level = 0;
2595 8 : r.in.bufsize = 0xffff;
2596 :
2597 8 : status = smbcli_rap_netservergetinfo(tree, mem_ctx, &r);
2598 8 : if (!NT_STATUS_IS_OK(status)) {
2599 0 : return status;
2600 : }
2601 :
2602 8 : memcpy(servername, r.out.info.info0.name, 16);
2603 8 : servername[16] = '\0';
2604 :
2605 8 : if (!pull_ascii_talloc(mem_ctx, name, servername, &converted_size)) {
2606 0 : return NT_STATUS_NO_MEMORY;
2607 : }
2608 :
2609 8 : return NT_STATUS_OK;
2610 : }
2611 :
2612 8 : static bool rap_get_servername(struct torture_context *tctx,
2613 : char **servername)
2614 : {
2615 0 : struct smbcli_state *cli;
2616 :
2617 8 : 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 8 : torture_assert_ntstatus_ok(tctx,
2623 : get_servername(tctx, cli->tree, servername),
2624 : "get_servername failed");
2625 :
2626 8 : talloc_free(cli);
2627 :
2628 8 : return true;
2629 : }
2630 :
2631 4 : static bool find_printers(struct torture_context *tctx,
2632 : struct dcerpc_pipe *p,
2633 : const char ***printers,
2634 : size_t *num_printers)
2635 : {
2636 0 : struct srvsvc_NetShareEnum r;
2637 0 : struct srvsvc_NetShareInfoCtr info_ctr;
2638 0 : struct srvsvc_NetShareCtr1 c1_in;
2639 0 : struct srvsvc_NetShareCtr1 *c1;
2640 4 : uint32_t totalentries = 0;
2641 0 : int i;
2642 4 : struct dcerpc_binding_handle *b = p->binding_handle;
2643 :
2644 4 : ZERO_STRUCT(c1_in);
2645 4 : info_ctr.level = 1;
2646 4 : info_ctr.ctr.ctr1 = &c1_in;
2647 :
2648 4 : r.in.server_unc = talloc_asprintf(
2649 : tctx, "\\\\%s", dcerpc_server_name(p));
2650 4 : r.in.info_ctr = &info_ctr;
2651 4 : r.in.max_buffer = (uint32_t)-1;
2652 4 : r.in.resume_handle = NULL;
2653 4 : r.out.totalentries = &totalentries;
2654 4 : r.out.info_ctr = &info_ctr;
2655 :
2656 4 : torture_assert_ntstatus_ok(tctx,
2657 : dcerpc_srvsvc_NetShareEnum_r(b, tctx, &r),
2658 : "NetShareEnum level 1 failed");
2659 4 : torture_assert_werr_ok(tctx, r.out.result,
2660 : "NetShareEnum level 1 failed");
2661 :
2662 4 : *printers = NULL;
2663 4 : *num_printers = 0;
2664 4 : c1 = r.out.info_ctr->ctr.ctr1;
2665 260 : for (i=0; i<c1->count; i++) {
2666 256 : if (c1->array[i].type != STYPE_PRINTQ) {
2667 236 : continue;
2668 : }
2669 20 : if (!add_string_to_array(tctx, c1->array[i].name,
2670 : printers, num_printers)) {
2671 0 : return false;
2672 : }
2673 : }
2674 :
2675 4 : return true;
2676 : }
2677 :
2678 8 : static bool enumprinters(struct torture_context *tctx,
2679 : struct dcerpc_binding_handle *b,
2680 : const char *servername, int level, int *num_printers)
2681 : {
2682 0 : struct spoolss_EnumPrinters r;
2683 0 : DATA_BLOB blob;
2684 0 : uint32_t needed;
2685 0 : uint32_t count;
2686 0 : union spoolss_PrinterInfo *info;
2687 :
2688 8 : r.in.flags = PRINTER_ENUM_LOCAL;
2689 8 : r.in.server = talloc_asprintf(tctx, "\\\\%s", servername);
2690 8 : r.in.level = level;
2691 8 : r.in.buffer = NULL;
2692 8 : r.in.offered = 0;
2693 8 : r.out.needed = &needed;
2694 8 : r.out.count = &count;
2695 8 : r.out.info = &info;
2696 :
2697 8 : torture_assert_ntstatus_ok(tctx,
2698 : dcerpc_spoolss_EnumPrinters_r(b, tctx, &r),
2699 : "dcerpc_spoolss_EnumPrinters failed");
2700 8 : torture_assert_werr_equal(tctx, r.out.result, WERR_INSUFFICIENT_BUFFER,
2701 : "EnumPrinters unexpected return code should be WERR_INSUFFICIENT_BUFFER");
2702 :
2703 8 : blob = data_blob_talloc_zero(tctx, needed);
2704 8 : if (blob.data == NULL) {
2705 0 : return false;
2706 : }
2707 :
2708 8 : r.in.buffer = &blob;
2709 8 : r.in.offered = needed;
2710 :
2711 8 : torture_assert_ntstatus_ok(tctx,
2712 : dcerpc_spoolss_EnumPrinters_r(b, tctx, &r),
2713 : "dcerpc_spoolss_EnumPrinters failed");
2714 8 : torture_assert_werr_ok(tctx, r.out.result,
2715 : "dcerpc_spoolss_EnumPrinters failed");
2716 :
2717 8 : *num_printers = count;
2718 :
2719 8 : return true;
2720 : }
2721 :
2722 32 : 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 0 : struct spoolss_GetPrinter r;
2728 0 : DATA_BLOB blob;
2729 0 : uint32_t needed;
2730 :
2731 32 : r.in.handle = handle;
2732 32 : r.in.level = level;
2733 32 : r.in.buffer = NULL;
2734 32 : r.in.offered = 0;
2735 32 : r.out.needed = &needed;
2736 :
2737 32 : torture_assert_ntstatus_ok(tctx,
2738 : dcerpc_spoolss_GetPrinter_r(b, tctx, &r),
2739 : "dcerpc_spoolss_GetPrinter failed");
2740 32 : torture_assert_werr_equal(tctx, r.out.result, WERR_INSUFFICIENT_BUFFER,
2741 : "GetPrinter unexpected return code should be WERR_INSUFFICIENT_BUFFER");
2742 :
2743 32 : r.in.handle = handle;
2744 32 : r.in.level = level;
2745 32 : blob = data_blob_talloc_zero(tctx, needed);
2746 32 : if (blob.data == NULL) {
2747 0 : return false;
2748 : }
2749 32 : r.in.buffer = &blob;
2750 32 : r.in.offered = needed;
2751 :
2752 32 : torture_assert_ntstatus_ok(tctx,
2753 : dcerpc_spoolss_GetPrinter_r(b, tctx, &r),
2754 : "dcerpc_spoolss_GetPrinter failed");
2755 32 : torture_assert_werr_ok(tctx, r.out.result,
2756 : "dcerpc_spoolss_GetPrinter failed");
2757 :
2758 32 : if (res != NULL) {
2759 0 : *res = talloc_steal(tctx, r.out.info);
2760 : }
2761 :
2762 32 : return true;
2763 : }
2764 :
2765 4 : static bool torture_samba3_rpc_spoolss(struct torture_context *torture)
2766 : {
2767 0 : struct dcerpc_pipe *p, *p2;
2768 0 : struct dcerpc_binding_handle *b;
2769 0 : struct policy_handle server_handle, printer_handle;
2770 0 : const char **printers;
2771 0 : size_t num_printers;
2772 0 : struct spoolss_UserLevel1 userlevel1;
2773 0 : char *servername;
2774 :
2775 4 : torture_assert(torture,
2776 : rap_get_servername(torture, &servername),
2777 : "failed to rap servername");
2778 :
2779 4 : torture_assert_ntstatus_ok(torture,
2780 : torture_rpc_connection(torture, &p2, &ndr_table_srvsvc),
2781 : "failed to setup srvsvc");
2782 :
2783 4 : torture_assert(torture,
2784 : find_printers(torture, p2, &printers, &num_printers),
2785 : "failed to find printers via srvsvc");
2786 :
2787 4 : talloc_free(p2);
2788 :
2789 4 : if (num_printers == 0) {
2790 0 : torture_skip(torture, "Did not find printers\n");
2791 : return true;
2792 : }
2793 :
2794 4 : torture_assert_ntstatus_ok(torture,
2795 : torture_rpc_connection(torture, &p, &ndr_table_spoolss),
2796 : "failed to setup spoolss");
2797 :
2798 4 : b = p->binding_handle;
2799 :
2800 4 : ZERO_STRUCT(userlevel1);
2801 4 : userlevel1.client = talloc_asprintf(
2802 : torture, "\\\\%s", lpcfg_netbios_name(torture->lp_ctx));
2803 4 : userlevel1.user = cli_credentials_get_username(
2804 : samba_cmdline_get_creds());
2805 4 : userlevel1.build = 2600;
2806 4 : userlevel1.major = 3;
2807 4 : userlevel1.minor = 0;
2808 4 : userlevel1.processor = 0;
2809 :
2810 : {
2811 0 : struct spoolss_OpenPrinterEx r;
2812 :
2813 4 : ZERO_STRUCT(r);
2814 4 : r.in.printername = talloc_asprintf(torture, "\\\\%s",
2815 : servername);
2816 4 : r.in.datatype = NULL;
2817 4 : r.in.access_mask = 0;
2818 4 : r.in.userlevel_ctr.level = 1;
2819 4 : r.in.userlevel_ctr.user_info.level1 = &userlevel1;
2820 4 : r.out.handle = &server_handle;
2821 :
2822 4 : torture_assert_ntstatus_ok(torture,
2823 : dcerpc_spoolss_OpenPrinterEx_r(b, torture, &r),
2824 : "dcerpc_spoolss_OpenPrinterEx failed");
2825 4 : torture_assert_werr_ok(torture, r.out.result,
2826 : "dcerpc_spoolss_OpenPrinterEx failed");
2827 : }
2828 :
2829 : {
2830 0 : struct spoolss_ClosePrinter r;
2831 :
2832 4 : r.in.handle = &server_handle;
2833 4 : r.out.handle = &server_handle;
2834 :
2835 4 : torture_assert_ntstatus_ok(torture,
2836 : dcerpc_spoolss_ClosePrinter_r(b, torture, &r),
2837 : "dcerpc_spoolss_ClosePrinter failed");
2838 4 : torture_assert_werr_ok(torture, r.out.result,
2839 : "dcerpc_spoolss_ClosePrinter failed");
2840 : }
2841 :
2842 : {
2843 0 : struct spoolss_OpenPrinterEx r;
2844 :
2845 4 : ZERO_STRUCT(r);
2846 4 : r.in.printername = talloc_asprintf(
2847 : torture, "\\\\%s\\%s", servername, printers[0]);
2848 4 : r.in.datatype = NULL;
2849 4 : r.in.access_mask = 0;
2850 4 : r.in.userlevel_ctr.level = 1;
2851 4 : r.in.userlevel_ctr.user_info.level1 = &userlevel1;
2852 4 : r.out.handle = &printer_handle;
2853 :
2854 4 : torture_assert_ntstatus_ok(torture,
2855 : dcerpc_spoolss_OpenPrinterEx_r(b, torture, &r),
2856 : "dcerpc_spoolss_OpenPrinterEx failed");
2857 4 : torture_assert_werr_ok(torture, r.out.result,
2858 : "dcerpc_spoolss_OpenPrinterEx failed");
2859 : }
2860 :
2861 : {
2862 0 : int i;
2863 :
2864 36 : for (i=0; i<8; i++) {
2865 32 : torture_assert(torture,
2866 : getprinterinfo(torture, b, &printer_handle, i, NULL),
2867 : talloc_asprintf(torture, "getprinterinfo %d failed", i));
2868 : }
2869 : }
2870 :
2871 : {
2872 0 : struct spoolss_ClosePrinter r;
2873 :
2874 4 : r.in.handle = &printer_handle;
2875 4 : r.out.handle = &printer_handle;
2876 :
2877 4 : torture_assert_ntstatus_ok(torture,
2878 : dcerpc_spoolss_ClosePrinter_r(b, torture, &r),
2879 : "dcerpc_spoolss_ClosePrinter failed");
2880 4 : torture_assert_werr_ok(torture, r.out.result,
2881 : "dcerpc_spoolss_ClosePrinter failed");
2882 : }
2883 :
2884 : {
2885 0 : int num_enumerated;
2886 :
2887 4 : torture_assert(torture,
2888 : enumprinters(torture, b, servername, 1, &num_enumerated),
2889 : "enumprinters failed");
2890 :
2891 4 : torture_assert_int_equal(torture, num_printers, num_enumerated,
2892 : "netshareenum / enumprinters lvl 1 numprinter mismatch");
2893 : }
2894 :
2895 : {
2896 0 : int num_enumerated;
2897 :
2898 4 : torture_assert(torture,
2899 : enumprinters(torture, b, servername, 2, &num_enumerated),
2900 : "enumprinters failed");
2901 :
2902 4 : torture_assert_int_equal(torture, num_printers, num_enumerated,
2903 : "netshareenum / enumprinters lvl 2 numprinter mismatch");
2904 : }
2905 :
2906 4 : return true;
2907 : }
2908 :
2909 4 : static bool torture_samba3_rpc_wkssvc(struct torture_context *torture)
2910 : {
2911 0 : struct dcerpc_pipe *p;
2912 0 : struct dcerpc_binding_handle *b;
2913 0 : char *servername;
2914 :
2915 4 : torture_assert(torture,
2916 : rap_get_servername(torture, &servername),
2917 : "failed to rap servername");
2918 :
2919 4 : torture_assert_ntstatus_ok(torture,
2920 : torture_rpc_connection(torture, &p, &ndr_table_wkssvc),
2921 : "failed to setup wkssvc");
2922 :
2923 4 : b = p->binding_handle;
2924 :
2925 : {
2926 0 : struct wkssvc_NetWkstaInfo100 wks100;
2927 0 : union wkssvc_NetWkstaInfo info;
2928 0 : struct wkssvc_NetWkstaGetInfo r;
2929 :
2930 4 : r.in.server_name = "\\foo";
2931 4 : r.in.level = 100;
2932 4 : info.info100 = &wks100;
2933 4 : r.out.info = &info;
2934 :
2935 4 : torture_assert_ntstatus_ok(torture,
2936 : dcerpc_wkssvc_NetWkstaGetInfo_r(b, torture, &r),
2937 : "dcerpc_wkssvc_NetWksGetInfo failed");
2938 4 : torture_assert_werr_ok(torture, r.out.result,
2939 : "dcerpc_wkssvc_NetWksGetInfo failed");
2940 :
2941 4 : torture_assert_str_equal(torture, servername, r.out.info->info100->server_name,
2942 : "servername RAP / DCERPC inconsistency");
2943 : }
2944 :
2945 4 : return true;
2946 : }
2947 :
2948 300 : static bool winreg_close(struct torture_context *tctx,
2949 : struct dcerpc_binding_handle *b,
2950 : struct policy_handle *handle)
2951 : {
2952 0 : struct winreg_CloseKey c;
2953 :
2954 300 : c.in.handle = c.out.handle = handle;
2955 :
2956 300 : torture_assert_ntstatus_ok(tctx,
2957 : dcerpc_winreg_CloseKey_r(b, tctx, &c),
2958 : "winreg_CloseKey failed");
2959 300 : torture_assert_werr_ok(tctx, c.out.result,
2960 : "winreg_CloseKey failed");
2961 :
2962 300 : return true;
2963 : }
2964 :
2965 296 : static bool enumvalues(struct torture_context *tctx,
2966 : struct dcerpc_binding_handle *b,
2967 : struct policy_handle *handle)
2968 : {
2969 296 : uint32_t enum_index = 0;
2970 :
2971 932 : while (1) {
2972 0 : struct winreg_EnumValue r;
2973 0 : struct winreg_ValNameBuf name;
2974 1228 : enum winreg_Type type = 0;
2975 0 : uint8_t buf8[1024];
2976 0 : NTSTATUS status;
2977 0 : uint32_t size, length;
2978 :
2979 1228 : ZERO_STRUCT(buf8);
2980 1228 : r.in.handle = handle;
2981 1228 : r.in.enum_index = enum_index;
2982 1228 : name.name = "";
2983 1228 : name.size = 1024;
2984 1228 : r.in.name = r.out.name = &name;
2985 1228 : size = 1024;
2986 1228 : length = 5;
2987 1228 : r.in.type = &type;
2988 1228 : r.in.value = buf8;
2989 1228 : r.in.size = &size;
2990 1228 : r.in.length = &length;
2991 :
2992 1228 : status = dcerpc_winreg_EnumValue_r(b, tctx, &r);
2993 1228 : if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(r.out.result)) {
2994 296 : return true;
2995 : }
2996 932 : enum_index += 1;
2997 : }
2998 : }
2999 :
3000 300 : static bool enumkeys(struct torture_context *tctx,
3001 : struct dcerpc_binding_handle *b,
3002 : struct policy_handle *handle,
3003 : int depth)
3004 : {
3005 0 : struct winreg_EnumKey r;
3006 0 : struct winreg_StringBuf kclass, name;
3007 0 : NTSTATUS status;
3008 300 : NTTIME t = 0;
3009 :
3010 300 : if (depth <= 0) {
3011 248 : return true;
3012 : }
3013 :
3014 52 : kclass.name = "";
3015 52 : kclass.size = 1024;
3016 :
3017 52 : r.in.handle = handle;
3018 52 : r.in.enum_index = 0;
3019 52 : r.in.name = &name;
3020 52 : r.in.keyclass = &kclass;
3021 52 : r.out.name = &name;
3022 52 : r.in.last_changed_time = &t;
3023 :
3024 296 : do {
3025 0 : struct winreg_OpenKey o;
3026 0 : struct policy_handle key_handle;
3027 0 : int i;
3028 :
3029 348 : name.name = NULL;
3030 348 : name.size = 1024;
3031 :
3032 348 : status = dcerpc_winreg_EnumKey_r(b, tctx, &r);
3033 348 : if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(r.out.result)) {
3034 : /* We're done enumerating */
3035 52 : return true;
3036 : }
3037 :
3038 2880 : for (i=0; i<10-depth; i++) {
3039 2584 : torture_comment(tctx, " ");
3040 : }
3041 296 : torture_comment(tctx, "%s\n", r.out.name->name);
3042 :
3043 296 : o.in.parent_handle = handle;
3044 296 : o.in.keyname.name = r.out.name->name;
3045 296 : o.in.options = 0;
3046 296 : o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3047 296 : o.out.handle = &key_handle;
3048 :
3049 296 : status = dcerpc_winreg_OpenKey_r(b, tctx, &o);
3050 296 : if (NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(o.out.result)) {
3051 296 : enumkeys(tctx, b, &key_handle, depth-1);
3052 296 : enumvalues(tctx, b, &key_handle);
3053 296 : torture_assert(tctx, winreg_close(tctx, b, &key_handle), "");
3054 : }
3055 :
3056 296 : 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 4 : 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 0 : struct policy_handle handle;
3069 0 : struct winreg_OpenHKLM r;
3070 :
3071 4 : r.in.system_name = 0;
3072 4 : r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3073 4 : r.out.handle = &handle;
3074 :
3075 4 : torture_assert_ntstatus_ok(tctx,
3076 : open_fn(b, tctx, &r),
3077 : talloc_asprintf(tctx, "%s failed", name));
3078 4 : torture_assert_werr_ok(tctx, r.out.result,
3079 : talloc_asprintf(tctx, "%s failed", name));
3080 :
3081 4 : enumkeys(tctx, b, &handle, 4);
3082 :
3083 4 : torture_assert(tctx,
3084 : winreg_close(tctx, b, &handle),
3085 : "dcerpc_CloseKey failed");
3086 :
3087 4 : return true;
3088 : }
3089 :
3090 4 : static bool torture_samba3_rpc_winreg(struct torture_context *torture)
3091 : {
3092 0 : struct dcerpc_pipe *p;
3093 0 : struct dcerpc_binding_handle *b;
3094 4 : bool ret = true;
3095 0 : struct {
3096 : const char *name;
3097 : winreg_open_fn fn;
3098 4 : } 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 4 : torture_assert_ntstatus_ok(torture,
3109 : torture_rpc_connection(torture, &p, &ndr_table_winreg),
3110 : "failed to setup winreg");
3111 :
3112 4 : b = p->binding_handle;
3113 :
3114 : #if 1
3115 4 : 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 4 : 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 0 : struct srvsvc_NetShareGetInfo r;
3132 0 : 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 0 : struct winreg_OpenHKLM r;
3159 0 : 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 0 : struct policy_handle hklm;
3181 0 : struct policy_handle new_handle;
3182 0 : struct winreg_CreateKey c;
3183 0 : 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 0 : struct policy_handle hklm;
3227 0 : 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 0 : struct policy_handle hklm, key_handle;
3254 0 : struct winreg_OpenKey o;
3255 0 : struct winreg_SetValue s;
3256 0 : uint32_t type;
3257 0 : 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 0 : 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 4 : bool torture_samba3_getaliasmembership_0(struct torture_context *torture)
3339 : {
3340 0 : struct dcerpc_pipe *p;
3341 0 : struct dcerpc_binding_handle *b;
3342 0 : struct samr_Connect2 c;
3343 0 : struct samr_OpenDomain o;
3344 0 : struct dom_sid sid;
3345 0 : struct lsa_SidPtr ptr;
3346 0 : struct lsa_SidArray sids;
3347 0 : struct samr_GetAliasMembership g;
3348 0 : struct samr_Ids rids;
3349 0 : struct policy_handle samr, domain;
3350 :
3351 4 : torture_assert_ntstatus_ok(torture,
3352 : torture_rpc_connection(torture, &p, &ndr_table_samr),
3353 : "failed to setup samr");
3354 :
3355 4 : b = p->binding_handle;
3356 :
3357 4 : c.in.system_name = NULL;
3358 4 : c.in.access_mask = SAMR_ACCESS_LOOKUP_DOMAIN;
3359 4 : c.out.connect_handle = &samr;
3360 4 : torture_assert_ntstatus_ok(torture,
3361 : dcerpc_samr_Connect2_r(b, torture, &c),
3362 : "");
3363 4 : torture_assert_ntstatus_ok(torture, c.out.result,
3364 : "");
3365 4 : dom_sid_parse("S-1-5-32", &sid);
3366 4 : o.in.connect_handle = &samr;
3367 4 : o.in.access_mask = SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS;
3368 4 : o.in.sid = &sid;
3369 4 : o.out.domain_handle = &domain;
3370 4 : torture_assert_ntstatus_ok(torture,
3371 : dcerpc_samr_OpenDomain_r(b, torture, &o),
3372 : "");
3373 4 : torture_assert_ntstatus_ok(torture, o.out.result,
3374 : "");
3375 4 : dom_sid_parse("S-1-2-3-4-5", &sid);
3376 4 : ptr.sid = &sid;
3377 4 : sids.num_sids = 1;
3378 4 : sids.sids = &ptr;
3379 4 : g.in.domain_handle = &domain;
3380 4 : g.in.sids = &sids;
3381 4 : g.out.rids = &rids;
3382 4 : torture_assert_ntstatus_ok(torture,
3383 : dcerpc_samr_GetAliasMembership_r(b, torture, &g),
3384 : "");
3385 4 : torture_assert_ntstatus_ok(torture, g.out.result,
3386 : "");
3387 4 : 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 4 : return true;
3395 : }
3396 :
3397 : /**
3398 : * Test smb reauthentication while rpc pipe is in use.
3399 : */
3400 4 : static bool torture_rpc_smb_reauth1(struct torture_context *torture)
3401 : {
3402 0 : TALLOC_CTX *mem_ctx;
3403 0 : NTSTATUS status;
3404 4 : bool ret = false;
3405 0 : struct smbcli_state *cli;
3406 0 : struct smbcli_options options;
3407 0 : struct smbcli_session_options session_options;
3408 :
3409 0 : struct dcerpc_pipe *lsa_pipe;
3410 0 : struct dcerpc_binding_handle *lsa_handle;
3411 0 : struct lsa_GetUserName r;
3412 4 : struct lsa_String *authority_name_p = NULL;
3413 4 : char *authority_name_saved = NULL;
3414 4 : struct lsa_String *account_name_p = NULL;
3415 4 : char *account_name_saved = NULL;
3416 4 : struct cli_credentials *anon_creds = NULL;
3417 0 : struct smb_composite_sesssetup io;
3418 :
3419 4 : mem_ctx = talloc_init("torture_samba3_reauth");
3420 4 : torture_assert(torture, (mem_ctx != NULL), "talloc_init failed");
3421 :
3422 4 : lpcfg_smbcli_options(torture->lp_ctx, &options);
3423 4 : lpcfg_smbcli_session_options(torture->lp_ctx, &session_options);
3424 :
3425 4 : 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 4 : torture_assert_ntstatus_ok_goto(torture, status, ret, done,
3435 : "smbcli_full_connection failed");
3436 :
3437 4 : status = pipe_bind_smb(torture, mem_ctx, cli->tree, "\\lsarpc",
3438 : &ndr_table_lsarpc, &lsa_pipe);
3439 4 : torture_assert_ntstatus_ok_goto(torture, status, ret, done,
3440 : "pipe_bind_smb failed");
3441 4 : lsa_handle = lsa_pipe->binding_handle;
3442 :
3443 : /* lsa getusername */
3444 :
3445 4 : ZERO_STRUCT(r);
3446 4 : r.in.system_name = "\\";
3447 4 : r.in.account_name = &account_name_p;
3448 4 : r.in.authority_name = &authority_name_p;
3449 4 : r.out.account_name = &account_name_p;
3450 :
3451 4 : status = dcerpc_lsa_GetUserName_r(lsa_handle, mem_ctx, &r);
3452 :
3453 4 : authority_name_p = *r.out.authority_name;
3454 :
3455 4 : torture_assert_ntstatus_ok_goto(torture, status, ret, done,
3456 : "GetUserName failed");
3457 4 : torture_assert_ntstatus_ok_goto(torture, r.out.result, ret, done,
3458 : "GetUserName failed");
3459 :
3460 4 : torture_comment(torture, "lsa_GetUserName gave '%s\\%s'\n",
3461 4 : authority_name_p->string,
3462 4 : account_name_p->string);
3463 :
3464 4 : account_name_saved = talloc_strdup(mem_ctx, account_name_p->string);
3465 4 : torture_assert_goto(torture, (account_name_saved != NULL), ret, done,
3466 : "talloc failed");
3467 4 : authority_name_saved = talloc_strdup(mem_ctx, authority_name_p->string);
3468 4 : torture_assert_goto(torture, (authority_name_saved != NULL), ret, done,
3469 : "talloc failed");
3470 :
3471 : /* smb re-authenticate as anonymous */
3472 :
3473 4 : anon_creds = cli_credentials_init_anon(mem_ctx);
3474 :
3475 4 : ZERO_STRUCT(io);
3476 4 : io.in.sesskey = cli->transport->negotiate.sesskey;
3477 4 : io.in.capabilities = cli->transport->negotiate.capabilities;
3478 4 : io.in.credentials = anon_creds;
3479 4 : io.in.workgroup = lpcfg_workgroup(torture->lp_ctx);
3480 4 : io.in.gensec_settings = lpcfg_gensec_settings(torture, torture->lp_ctx);
3481 :
3482 4 : status = smb_composite_sesssetup(cli->session, &io);
3483 4 : 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 4 : TALLOC_FREE(authority_name_p);
3489 4 : TALLOC_FREE(account_name_p);
3490 4 : ZERO_STRUCT(r);
3491 4 : r.in.system_name = "\\";
3492 4 : r.in.account_name = &account_name_p;
3493 4 : r.in.authority_name = &authority_name_p;
3494 4 : r.out.account_name = &account_name_p;
3495 :
3496 4 : status = dcerpc_lsa_GetUserName_r(lsa_handle, mem_ctx, &r);
3497 :
3498 4 : authority_name_p = *r.out.authority_name;
3499 :
3500 4 : torture_assert_ntstatus_ok_goto(torture, status, ret, done,
3501 : "GetUserName failed");
3502 4 : torture_assert_ntstatus_ok_goto(torture, r.out.result, ret, done,
3503 : "GetUserName failed");
3504 :
3505 4 : 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 4 : 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 4 : ZERO_STRUCT(io);
3513 4 : io.in.sesskey = cli->transport->negotiate.sesskey;
3514 4 : io.in.capabilities = cli->transport->negotiate.capabilities;
3515 4 : io.in.credentials = samba_cmdline_get_creds();
3516 4 : io.in.workgroup = lpcfg_workgroup(torture->lp_ctx);
3517 4 : io.in.gensec_settings = lpcfg_gensec_settings(torture, torture->lp_ctx);
3518 :
3519 4 : status = smb_composite_sesssetup(cli->session, &io);
3520 4 : torture_assert_ntstatus_ok_goto(torture, status, ret, done,
3521 : "session reauth to anon failed");
3522 :
3523 : /* re-do lsa getusername */
3524 :
3525 4 : TALLOC_FREE(authority_name_p);
3526 4 : TALLOC_FREE(account_name_p);
3527 4 : ZERO_STRUCT(r);
3528 4 : r.in.system_name = "\\";
3529 4 : r.in.account_name = &account_name_p;
3530 4 : r.in.authority_name = &authority_name_p;
3531 4 : r.out.account_name = &account_name_p;
3532 :
3533 4 : status = dcerpc_lsa_GetUserName_r(lsa_handle, mem_ctx, &r);
3534 :
3535 4 : authority_name_p = *r.out.authority_name;
3536 :
3537 4 : torture_assert_ntstatus_ok_goto(torture, status, ret, done,
3538 : "GetUserName failed");
3539 4 : torture_assert_ntstatus_ok_goto(torture, r.out.result, ret, done,
3540 : "GetUserName failed");
3541 :
3542 4 : 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 4 : 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 4 : ret = true;
3548 :
3549 4 : done:
3550 4 : talloc_free(mem_ctx);
3551 4 : 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 4 : static bool torture_rpc_smb_reauth2(struct torture_context *torture)
3560 : {
3561 0 : TALLOC_CTX *mem_ctx;
3562 0 : NTSTATUS status;
3563 4 : bool ret = false;
3564 0 : struct smbcli_state *cli;
3565 0 : struct smbcli_options options;
3566 0 : struct smbcli_session_options session_options;
3567 :
3568 0 : struct dcerpc_pipe *lsa_pipe;
3569 0 : struct dcerpc_binding_handle *lsa_handle;
3570 0 : struct lsa_GetUserName r;
3571 4 : struct lsa_String *authority_name_p = NULL;
3572 4 : char *authority_name_saved = NULL;
3573 4 : struct lsa_String *account_name_p = NULL;
3574 4 : char *account_name_saved = NULL;
3575 4 : struct cli_credentials *anon_creds = NULL;
3576 0 : struct smb_composite_sesssetup io;
3577 :
3578 4 : mem_ctx = talloc_init("torture_samba3_reauth");
3579 4 : torture_assert(torture, (mem_ctx != NULL), "talloc_init failed");
3580 :
3581 4 : lpcfg_smbcli_options(torture->lp_ctx, &options);
3582 4 : lpcfg_smbcli_session_options(torture->lp_ctx, &session_options);
3583 :
3584 4 : 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 4 : torture_assert_ntstatus_ok_goto(torture, status, ret, done,
3594 : "smbcli_full_connection failed");
3595 :
3596 : /* smb re-authenticate as anonymous */
3597 :
3598 4 : anon_creds = cli_credentials_init_anon(mem_ctx);
3599 :
3600 4 : ZERO_STRUCT(io);
3601 4 : io.in.sesskey = cli->transport->negotiate.sesskey;
3602 4 : io.in.capabilities = cli->transport->negotiate.capabilities;
3603 4 : io.in.credentials = anon_creds;
3604 4 : io.in.workgroup = lpcfg_workgroup(torture->lp_ctx);
3605 4 : io.in.gensec_settings = lpcfg_gensec_settings(torture, torture->lp_ctx);
3606 :
3607 4 : status = smb_composite_sesssetup(cli->session, &io);
3608 4 : torture_assert_ntstatus_ok_goto(torture, status, ret, done,
3609 : "session reauth to anon failed");
3610 :
3611 : /* open the lsa pipe */
3612 :
3613 4 : status = pipe_bind_smb(torture, mem_ctx, cli->tree, "\\lsarpc",
3614 : &ndr_table_lsarpc, &lsa_pipe);
3615 4 : torture_assert_ntstatus_ok_goto(torture, status, ret, done,
3616 : "pipe_bind_smb failed");
3617 4 : lsa_handle = lsa_pipe->binding_handle;
3618 :
3619 : /* lsa getusername */
3620 :
3621 4 : ZERO_STRUCT(r);
3622 4 : r.in.system_name = "\\";
3623 4 : r.in.account_name = &account_name_p;
3624 4 : r.in.authority_name = &authority_name_p;
3625 4 : r.out.account_name = &account_name_p;
3626 :
3627 4 : status = dcerpc_lsa_GetUserName_r(lsa_handle, mem_ctx, &r);
3628 :
3629 4 : authority_name_p = *r.out.authority_name;
3630 :
3631 4 : torture_assert_ntstatus_ok_goto(torture, status, ret, done,
3632 : "GetUserName failed");
3633 4 : torture_assert_ntstatus_ok_goto(torture, r.out.result, ret, done,
3634 : "GetUserName failed");
3635 :
3636 4 : torture_comment(torture, "lsa_GetUserName gave '%s\\%s'\n",
3637 4 : authority_name_p->string,
3638 4 : account_name_p->string);
3639 :
3640 4 : account_name_saved = talloc_strdup(mem_ctx, account_name_p->string);
3641 4 : torture_assert_goto(torture, (account_name_saved != NULL), ret, done,
3642 : "talloc failed");
3643 4 : authority_name_saved = talloc_strdup(mem_ctx, authority_name_p->string);
3644 4 : 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 4 : ZERO_STRUCT(io);
3650 4 : io.in.sesskey = cli->transport->negotiate.sesskey;
3651 4 : io.in.capabilities = cli->transport->negotiate.capabilities;
3652 4 : io.in.credentials = samba_cmdline_get_creds();
3653 4 : io.in.workgroup = lpcfg_workgroup(torture->lp_ctx);
3654 4 : io.in.gensec_settings = lpcfg_gensec_settings(torture, torture->lp_ctx);
3655 :
3656 4 : status = smb_composite_sesssetup(cli->session, &io);
3657 4 : 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 4 : TALLOC_FREE(authority_name_p);
3663 4 : TALLOC_FREE(account_name_p);
3664 4 : ZERO_STRUCT(r);
3665 4 : r.in.system_name = "\\";
3666 4 : r.in.account_name = &account_name_p;
3667 4 : r.in.authority_name = &authority_name_p;
3668 4 : r.out.account_name = &account_name_p;
3669 :
3670 4 : status = dcerpc_lsa_GetUserName_r(lsa_handle, mem_ctx, &r);
3671 :
3672 4 : authority_name_p = *r.out.authority_name;
3673 :
3674 4 : torture_assert_ntstatus_ok_goto(torture, status, ret, done,
3675 : "GetUserName failed");
3676 4 : torture_assert_ntstatus_ok_goto(torture, r.out.result, ret, done,
3677 : "GetUserName failed");
3678 :
3679 4 : 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 4 : 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 4 : ret = true;
3685 :
3686 4 : done:
3687 4 : talloc_free(mem_ctx);
3688 4 : 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 0 : TALLOC_CTX *mem_ctx;
3697 0 : NTSTATUS status;
3698 0 : bool ret = false;
3699 0 : struct smbcli_options options;
3700 :
3701 0 : struct dcerpc_pipe *lsa_pipe;
3702 0 : struct dcerpc_binding_handle *lsa_handle;
3703 0 : 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 0 : 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 0 : TALLOC_CTX *mem_ctx;
3847 0 : NTSTATUS status;
3848 0 : bool ret = false;
3849 0 : struct smbcli_options options;
3850 :
3851 0 : struct dcerpc_pipe *lsa_pipe;
3852 0 : struct dcerpc_binding_handle *lsa_handle;
3853 0 : 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 0 : 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 4 : static bool torture_rpc_smb1_pipe_name(struct torture_context *torture)
3968 : {
3969 0 : TALLOC_CTX *mem_ctx;
3970 0 : NTSTATUS status;
3971 4 : bool ret = false;
3972 0 : struct smbcli_state *cli;
3973 0 : struct smbcli_options options;
3974 0 : struct smbcli_session_options session_options;
3975 0 : union smb_open io;
3976 0 : union smb_close cl;
3977 0 : uint16_t fnum;
3978 :
3979 4 : mem_ctx = talloc_init("torture_samba3_smb1_pipe_name");
3980 4 : torture_assert(torture, (mem_ctx != NULL), "talloc_init failed");
3981 :
3982 4 : lpcfg_smbcli_options(torture->lp_ctx, &options);
3983 4 : lpcfg_smbcli_session_options(torture->lp_ctx, &session_options);
3984 :
3985 4 : 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 4 : torture_assert_ntstatus_ok_goto(torture, status, ret, done,
3995 : "smbcli_full_connection failed");
3996 :
3997 4 : ZERO_STRUCT(io);
3998 4 : io.generic.level = RAW_OPEN_NTCREATEX;
3999 4 : io.ntcreatex.in.access_mask = DESIRED_ACCESS_PIPE;
4000 4 : io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
4001 : NTCREATEX_SHARE_ACCESS_WRITE;
4002 4 : io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
4003 4 : io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_IMPERSONATION;
4004 4 : io.ntcreatex.in.security_flags = 0;
4005 :
4006 4 : io.ntcreatex.in.fname = "__none__";
4007 4 : status = smb_raw_open(cli->tree, torture, &io);
4008 4 : torture_assert_ntstatus_equal_goto(torture, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
4009 : ret, done,
4010 : "smb_raw_open for '__none__'");
4011 :
4012 4 : io.ntcreatex.in.fname = "pipe\\srvsvc";
4013 4 : status = smb_raw_open(cli->tree, torture, &io);
4014 4 : 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 4 : io.ntcreatex.in.fname = "\\pipe\\srvsvc";
4019 4 : status = smb_raw_open(cli->tree, torture, &io);
4020 4 : 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 4 : io.ntcreatex.in.fname = "srvsvc";
4025 4 : status = smb_raw_open(cli->tree, torture, &io);
4026 4 : torture_assert_ntstatus_ok_goto(torture, status, ret, done,
4027 : "smb2_create failed for 'srvsvc'");
4028 4 : fnum = io.ntcreatex.out.file.fnum;
4029 4 : ZERO_STRUCT(cl);
4030 4 : cl.generic.level = RAW_CLOSE_CLOSE;
4031 4 : cl.close.in.file.fnum = fnum;
4032 4 : status = smb_raw_close(cli->tree, &cl);
4033 4 : torture_assert_ntstatus_ok_goto(torture, status, ret, done,
4034 : "smb_raw_close failed");
4035 :
4036 4 : io.ntcreatex.in.fname = "\\srvsvc";
4037 4 : status = smb_raw_open(cli->tree, torture, &io);
4038 4 : torture_assert_ntstatus_ok_goto(torture, status, ret, done,
4039 : "smb2_create failed for '\\srvsvc'");
4040 4 : fnum = io.ntcreatex.out.file.fnum;
4041 4 : ZERO_STRUCT(cl);
4042 4 : cl.generic.level = RAW_CLOSE_CLOSE;
4043 4 : cl.close.in.file.fnum = fnum;
4044 4 : status = smb_raw_close(cli->tree, &cl);
4045 4 : torture_assert_ntstatus_ok_goto(torture, status, ret, done,
4046 : "smb_raw_close failed");
4047 :
4048 4 : io.ntcreatex.in.fname = "\\\\\\\\\\srvsvc";
4049 4 : status = smb_raw_open(cli->tree, torture, &io);
4050 4 : torture_assert_ntstatus_ok_goto(torture, status, ret, done,
4051 : "smb2_create failed for '\\\\\\\\\\srvsvc'");
4052 4 : fnum = io.ntcreatex.out.file.fnum;
4053 4 : ZERO_STRUCT(cl);
4054 4 : cl.generic.level = RAW_CLOSE_CLOSE;
4055 4 : cl.close.in.file.fnum = fnum;
4056 4 : status = smb_raw_close(cli->tree, &cl);
4057 4 : torture_assert_ntstatus_ok_goto(torture, status, ret, done,
4058 : "smb_raw_close failed");
4059 :
4060 4 : ZERO_STRUCT(io);
4061 4 : io.generic.level = RAW_OPEN_NTTRANS_CREATE;
4062 4 : io.nttrans.in.access_mask = DESIRED_ACCESS_PIPE;
4063 4 : io.nttrans.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
4064 : NTCREATEX_SHARE_ACCESS_WRITE;
4065 4 : io.nttrans.in.open_disposition = NTCREATEX_DISP_OPEN;
4066 4 : io.nttrans.in.impersonation = NTCREATEX_IMPERSONATION_IMPERSONATION;
4067 4 : io.nttrans.in.security_flags = 0;
4068 :
4069 4 : io.nttrans.in.fname = "__none__";
4070 4 : status = smb_raw_open(cli->tree, torture, &io);
4071 4 : torture_assert_ntstatus_equal_goto(torture, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
4072 : ret, done,
4073 : "smb_raw_open for '__none__'");
4074 :
4075 4 : io.nttrans.in.fname = "pipe\\srvsvc";
4076 4 : status = smb_raw_open(cli->tree, torture, &io);
4077 4 : 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 4 : io.nttrans.in.fname = "\\pipe\\srvsvc";
4082 4 : status = smb_raw_open(cli->tree, torture, &io);
4083 4 : 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 4 : io.nttrans.in.fname = "srvsvc";
4088 4 : status = smb_raw_open(cli->tree, torture, &io);
4089 4 : torture_assert_ntstatus_ok_goto(torture, status, ret, done,
4090 : "smb2_create failed for 'srvsvc'");
4091 4 : fnum = io.nttrans.out.file.fnum;
4092 4 : ZERO_STRUCT(cl);
4093 4 : cl.generic.level = RAW_CLOSE_CLOSE;
4094 4 : cl.close.in.file.fnum = fnum;
4095 4 : status = smb_raw_close(cli->tree, &cl);
4096 4 : torture_assert_ntstatus_ok_goto(torture, status, ret, done,
4097 : "smb_raw_close failed");
4098 :
4099 4 : io.nttrans.in.fname = "\\srvsvc";
4100 4 : status = smb_raw_open(cli->tree, torture, &io);
4101 4 : torture_assert_ntstatus_ok_goto(torture, status, ret, done,
4102 : "smb2_create failed for '\\srvsvc'");
4103 4 : fnum = io.nttrans.out.file.fnum;
4104 4 : ZERO_STRUCT(cl);
4105 4 : cl.generic.level = RAW_CLOSE_CLOSE;
4106 4 : cl.close.in.file.fnum = fnum;
4107 4 : status = smb_raw_close(cli->tree, &cl);
4108 4 : torture_assert_ntstatus_ok_goto(torture, status, ret, done,
4109 : "smb_raw_close failed");
4110 :
4111 4 : io.nttrans.in.fname = "\\\\\\\\\\srvsvc";
4112 4 : status = smb_raw_open(cli->tree, torture, &io);
4113 4 : torture_assert_ntstatus_ok_goto(torture, status, ret, done,
4114 : "smb2_create failed for '\\\\\\\\\\srvsvc'");
4115 4 : fnum = io.nttrans.out.file.fnum;
4116 4 : ZERO_STRUCT(cl);
4117 4 : cl.generic.level = RAW_CLOSE_CLOSE;
4118 4 : cl.close.in.file.fnum = fnum;
4119 4 : status = smb_raw_close(cli->tree, &cl);
4120 4 : torture_assert_ntstatus_ok_goto(torture, status, ret, done,
4121 : "smb_raw_close failed");
4122 :
4123 4 : ZERO_STRUCT(io);
4124 4 : io.generic.level = RAW_OPEN_OPENX;
4125 4 : io.openx.in.open_mode = OPENX_MODE_ACCESS_RDWR;
4126 4 : io.openx.in.open_func = OPENX_OPEN_FUNC_OPEN;
4127 :
4128 4 : io.openx.in.fname = "__none__";
4129 4 : status = smb_raw_open(cli->tree, torture, &io);
4130 4 : torture_assert_ntstatus_equal_goto(torture, status, NT_STATUS_OBJECT_PATH_SYNTAX_BAD,
4131 : ret, done,
4132 : "smb_raw_open for '__none__'");
4133 :
4134 4 : io.openx.in.fname = "srvsvc";
4135 4 : status = smb_raw_open(cli->tree, torture, &io);
4136 4 : torture_assert_ntstatus_equal_goto(torture, status, NT_STATUS_OBJECT_PATH_SYNTAX_BAD,
4137 : ret, done,
4138 : "smb_raw_open for 'srvsvc'");
4139 :
4140 4 : io.openx.in.fname = "\\srvsvc";
4141 4 : status = smb_raw_open(cli->tree, torture, &io);
4142 4 : torture_assert_ntstatus_equal_goto(torture, status, NT_STATUS_OBJECT_PATH_SYNTAX_BAD,
4143 : ret, done,
4144 : "smb_raw_open for '\\srvsvc'");
4145 :
4146 4 : io.openx.in.fname = "\\pipesrvsvc";
4147 4 : status = smb_raw_open(cli->tree, torture, &io);
4148 4 : torture_assert_ntstatus_equal_goto(torture, status, NT_STATUS_OBJECT_PATH_SYNTAX_BAD,
4149 : ret, done,
4150 : "smb_raw_open for '\\pipesrvsvc'");
4151 :
4152 4 : io.openx.in.fname = "pipe\\__none__";
4153 4 : status = smb_raw_open(cli->tree, torture, &io);
4154 4 : 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 4 : io.openx.in.fname = "\\pipe\\__none__";
4159 4 : status = smb_raw_open(cli->tree, torture, &io);
4160 4 : 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 4 : io.openx.in.fname = "pipe\\srvsvc";
4165 4 : status = smb_raw_open(cli->tree, torture, &io);
4166 4 : torture_assert_ntstatus_ok_goto(torture, status, ret, done,
4167 : "smb2_create failed for 'pipe\\srvsvc'");
4168 4 : fnum = io.openx.out.file.fnum;
4169 4 : ZERO_STRUCT(cl);
4170 4 : cl.generic.level = RAW_CLOSE_CLOSE;
4171 4 : cl.close.in.file.fnum = fnum;
4172 4 : status = smb_raw_close(cli->tree, &cl);
4173 4 : torture_assert_ntstatus_ok_goto(torture, status, ret, done,
4174 : "smb_raw_close failed");
4175 :
4176 4 : io.openx.in.fname = "\\pipe\\srvsvc";
4177 4 : status = smb_raw_open(cli->tree, torture, &io);
4178 4 : torture_assert_ntstatus_ok_goto(torture, status, ret, done,
4179 : "smb2_create failed for '\\pipe\\srvsvc'");
4180 4 : fnum = io.openx.out.file.fnum;
4181 4 : ZERO_STRUCT(cl);
4182 4 : cl.generic.level = RAW_CLOSE_CLOSE;
4183 4 : cl.close.in.file.fnum = fnum;
4184 4 : status = smb_raw_close(cli->tree, &cl);
4185 4 : torture_assert_ntstatus_ok_goto(torture, status, ret, done,
4186 : "smb_raw_close failed");
4187 :
4188 4 : io.openx.in.fname = "\\\\\\\\\\pipe\\srvsvc";
4189 4 : status = smb_raw_open(cli->tree, torture, &io);
4190 4 : torture_assert_ntstatus_ok_goto(torture, status, ret, done,
4191 : "smb2_create failed for '\\\\\\\\\\pipe\\srvsvc'");
4192 4 : fnum = io.openx.out.file.fnum;
4193 4 : ZERO_STRUCT(cl);
4194 4 : cl.generic.level = RAW_CLOSE_CLOSE;
4195 4 : cl.close.in.file.fnum = fnum;
4196 4 : status = smb_raw_close(cli->tree, &cl);
4197 4 : torture_assert_ntstatus_ok_goto(torture, status, ret, done,
4198 : "smb_raw_close failed");
4199 :
4200 4 : io.openx.in.fname = "\\\\\\\\\\pipe\\\\\\\\\\srvsvc";
4201 4 : status = smb_raw_open(cli->tree, torture, &io);
4202 4 : torture_assert_ntstatus_ok_goto(torture, status, ret, done,
4203 : "smb2_create failed for '\\\\\\\\\\pipe\\\\\\\\\\srvsvc'");
4204 4 : fnum = io.openx.out.file.fnum;
4205 4 : ZERO_STRUCT(cl);
4206 4 : cl.generic.level = RAW_CLOSE_CLOSE;
4207 4 : cl.close.in.file.fnum = fnum;
4208 4 : status = smb_raw_close(cli->tree, &cl);
4209 4 : torture_assert_ntstatus_ok_goto(torture, status, ret, done,
4210 : "smb_raw_close failed");
4211 4 : ret = true;
4212 :
4213 4 : done:
4214 4 : talloc_free(mem_ctx);
4215 4 : return ret;
4216 : }
4217 :
4218 4 : static bool torture_rpc_smb2_pipe_name(struct torture_context *torture)
4219 : {
4220 0 : TALLOC_CTX *mem_ctx;
4221 0 : NTSTATUS status;
4222 4 : bool ret = false;
4223 0 : struct smbcli_options options;
4224 4 : const char *host = torture_setting_string(torture, "host", NULL);
4225 0 : struct smb2_tree *tree;
4226 0 : struct smb2_handle h;
4227 0 : struct smb2_create io;
4228 :
4229 4 : mem_ctx = talloc_init("torture_samba3_smb2_pipe_name");
4230 4 : torture_assert(torture, (mem_ctx != NULL), "talloc_init failed");
4231 :
4232 4 : lpcfg_smbcli_options(torture->lp_ctx, &options);
4233 :
4234 4 : 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 4 : torture_assert_ntstatus_ok_goto(torture, status, ret, done,
4247 : "smb2_connect failed");
4248 :
4249 4 : ZERO_STRUCT(io);
4250 4 : io.in.oplock_level = 0;
4251 4 : io.in.desired_access = DESIRED_ACCESS_PIPE;
4252 4 : io.in.impersonation_level = SMB2_IMPERSONATION_IMPERSONATION;
4253 4 : io.in.file_attributes = 0;
4254 4 : io.in.create_disposition = NTCREATEX_DISP_OPEN;
4255 4 : io.in.share_access =
4256 : NTCREATEX_SHARE_ACCESS_READ|
4257 : NTCREATEX_SHARE_ACCESS_WRITE;
4258 4 : io.in.create_options = 0;
4259 :
4260 4 : io.in.fname = "__none__";
4261 4 : status = smb2_create(tree, tree, &io);
4262 4 : torture_assert_ntstatus_equal_goto(torture, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
4263 : ret, done,
4264 : "smb2_create for '__none__'");
4265 :
4266 4 : io.in.fname = "\\srvsvc";
4267 4 : status = smb2_create(tree, tree, &io);
4268 4 : torture_assert_ntstatus_equal_goto(torture, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
4269 : ret, done,
4270 : "smb2_create for '\\srvsvc'");
4271 :
4272 4 : io.in.fname = "\\pipe\\srvsvc";
4273 4 : status = smb2_create(tree, tree, &io);
4274 4 : torture_assert_ntstatus_equal_goto(torture, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
4275 : ret, done,
4276 : "smb2_create for '\\pipe\\srvsvc'");
4277 :
4278 4 : io.in.fname = "pipe\\srvsvc";
4279 4 : status = smb2_create(tree, tree, &io);
4280 4 : torture_assert_ntstatus_equal_goto(torture, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
4281 : ret, done,
4282 : "smb2_create for 'pipe\\srvsvc'");
4283 :
4284 4 : io.in.fname = "srvsvc";
4285 4 : status = smb2_create(tree, tree, &io);
4286 4 : torture_assert_ntstatus_ok_goto(torture, status, ret, done,
4287 : "smb2_create failed for 'srvsvc'");
4288 :
4289 4 : h = io.out.file.handle;
4290 :
4291 4 : status = smb2_util_close(tree, h);
4292 4 : torture_assert_ntstatus_ok_goto(torture, status, ret, done,
4293 : "smb2_util_close failed");
4294 :
4295 4 : ret = true;
4296 4 : done:
4297 4 : talloc_free(mem_ctx);
4298 4 : 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 0 : TALLOC_CTX *mem_ctx;
4313 0 : NTSTATUS status;
4314 0 : bool ret = false;
4315 0 : struct smbcli_options options;
4316 0 : const char *host = torture_setting_string(torture, "host", NULL);
4317 0 : struct smb2_tree *tree;
4318 0 : struct smb2_handle h;
4319 0 : struct smb2_request *smb2req;
4320 0 : struct smb2_create io;
4321 0 : 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 0 : TALLOC_CTX *mem_ctx;
4397 0 : NTSTATUS status;
4398 0 : bool ret = false;
4399 0 : struct smbcli_options options;
4400 0 : const char *host = torture_setting_string(torture, "host", NULL);
4401 0 : struct smb2_tree *tree;
4402 0 : struct smb2_handle h;
4403 0 : struct smb2_request *smb2req;
4404 0 : struct smb2_create io;
4405 0 : 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 0 : TALLOC_CTX *mem_ctx;
4481 0 : NTSTATUS status;
4482 0 : bool ret = false;
4483 0 : struct smbcli_options options;
4484 0 : const char *host = torture_setting_string(torture, "host", NULL);
4485 0 : struct smb2_tree *tree;
4486 0 : struct smb2_handle h;
4487 0 : struct smb2_request *smb2req;
4488 0 : struct smb2_create io;
4489 0 : 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 2 : static bool torture_rpc_lsa_over_netlogon(struct torture_context *torture)
4554 : {
4555 0 : TALLOC_CTX *mem_ctx;
4556 0 : NTSTATUS status;
4557 2 : bool ret = false;
4558 0 : struct smbcli_options options;
4559 0 : struct smb2_tree *tree;
4560 0 : struct dcerpc_pipe *netlogon_pipe;
4561 0 : struct dcerpc_binding_handle *lsa_handle;
4562 0 : struct lsa_ObjectAttribute attr;
4563 0 : struct lsa_QosInfo qos;
4564 0 : struct lsa_OpenPolicy2 o;
4565 0 : struct policy_handle handle;
4566 :
4567 2 : torture_comment(torture, "Testing if we can access LSA server over "
4568 : "\\\\pipe\\netlogon rather than \\\\pipe\\lsarpc\n");
4569 :
4570 2 : mem_ctx = talloc_init("torture_samba3_rpc_lsa_over_netlogon");
4571 2 : torture_assert(torture, (mem_ctx != NULL), "talloc_init failed");
4572 :
4573 2 : lpcfg_smbcli_options(torture->lp_ctx, &options);
4574 :
4575 2 : 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 2 : torture_assert_ntstatus_ok_goto(torture, status, ret, done,
4588 : "smb2_connect failed");
4589 :
4590 2 : status = pipe_bind_smb2(torture, mem_ctx, tree, "netlogon",
4591 : &ndr_table_lsarpc, &netlogon_pipe);
4592 2 : torture_assert_ntstatus_ok_goto(torture, status, ret, done,
4593 : "pipe_bind_smb2 failed");
4594 2 : lsa_handle = netlogon_pipe->binding_handle;
4595 :
4596 2 : qos.len = 0;
4597 2 : qos.impersonation_level = 2;
4598 2 : qos.context_mode = 1;
4599 2 : qos.effective_only = 0;
4600 :
4601 2 : attr.len = 0;
4602 2 : attr.root_dir = NULL;
4603 2 : attr.object_name = NULL;
4604 2 : attr.attributes = 0;
4605 2 : attr.sec_desc = NULL;
4606 2 : attr.sec_qos = &qos;
4607 :
4608 2 : o.in.system_name = "\\";
4609 2 : o.in.attr = &attr;
4610 2 : o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4611 2 : o.out.handle = &handle;
4612 :
4613 2 : torture_assert_ntstatus_ok(torture,
4614 : dcerpc_lsa_OpenPolicy2_r(lsa_handle, torture, &o),
4615 : "OpenPolicy2 failed");
4616 2 : torture_assert_ntstatus_ok(torture,
4617 : o.out.result,
4618 : "OpenPolicy2 failed");
4619 :
4620 2 : ret = true;
4621 2 : done:
4622 2 : talloc_free(mem_ctx);
4623 2 : return ret;
4624 : }
4625 :
4626 4 : static bool torture_rpc_pipes_supported_interfaces(
4627 : struct torture_context *torture)
4628 : {
4629 0 : TALLOC_CTX *mem_ctx;
4630 0 : NTSTATUS status;
4631 4 : bool ret = false;
4632 0 : struct smbcli_options options;
4633 0 : struct smb2_tree *tree;
4634 0 : struct dcerpc_pipe *pipe1;
4635 0 : struct dcerpc_pipe *pipe2;
4636 0 : struct dcerpc_pipe *pipe3;
4637 :
4638 4 : torture_comment(torture, "Testing only appropriate interfaces are "
4639 : "available in smb pipes\n");
4640 :
4641 4 : mem_ctx = talloc_init("torture_samba3_rpc_pipes_supported_interfaces");
4642 4 : torture_assert(torture, (mem_ctx != NULL), "talloc_init failed");
4643 :
4644 4 : lpcfg_smbcli_options(torture->lp_ctx, &options);
4645 :
4646 4 : 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 4 : 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 4 : status = pipe_bind_smb2(torture, mem_ctx, tree, "winreg",
4664 : &ndr_table_svcctl, &pipe1);
4665 4 : 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 4 : status = pipe_bind_smb2(torture, mem_ctx, tree, "srvsvc",
4672 : &ndr_table_samr, &pipe2);
4673 4 : 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 4 : status = pipe_bind_smb2(torture, mem_ctx, tree, "samr",
4681 : &ndr_table_lsarpc, &pipe3);
4682 4 : torture_assert_ntstatus_equal(torture,
4683 : status,
4684 : NT_STATUS_RPC_UNSUPPORTED_NAME_SYNTAX,
4685 : "lsarpc interface not supported in samr pipe");
4686 :
4687 4 : ret = true;
4688 4 : done:
4689 4 : talloc_free(mem_ctx);
4690 4 : return ret;
4691 : }
4692 :
4693 2354 : struct torture_suite *torture_rpc_samba3(TALLOC_CTX *mem_ctx)
4694 : {
4695 2354 : struct torture_suite *suite = torture_suite_create(mem_ctx, "samba3");
4696 :
4697 2354 : torture_suite_add_simple_test(suite, "bind", torture_bind_samba3);
4698 2354 : torture_suite_add_simple_test(suite, "netlogon", torture_netlogon_samba3);
4699 2354 : torture_suite_add_simple_test(suite, "sessionkey", torture_samba3_sessionkey);
4700 2354 : torture_suite_add_simple_test(suite, "srvsvc", torture_samba3_rpc_srvsvc);
4701 2354 : torture_suite_add_simple_test(suite, "sharesec", torture_samba3_rpc_sharesec);
4702 2354 : torture_suite_add_simple_test(suite, "getusername", torture_samba3_rpc_getusername);
4703 2354 : torture_suite_add_simple_test(suite, "randomauth2", torture_samba3_rpc_randomauth2);
4704 2354 : torture_suite_add_simple_test(suite, "lsa", torture_samba3_rpc_lsa);
4705 2354 : torture_suite_add_simple_test(suite, "spoolss", torture_samba3_rpc_spoolss);
4706 2354 : torture_suite_add_simple_test(suite, "wkssvc", torture_samba3_rpc_wkssvc);
4707 2354 : torture_suite_add_simple_test(suite, "winreg", torture_samba3_rpc_winreg);
4708 2354 : torture_suite_add_simple_test(suite, "getaliasmembership-0", torture_samba3_getaliasmembership_0);
4709 2354 : torture_suite_add_simple_test(suite, "regconfig", torture_samba3_regconfig);
4710 2354 : torture_suite_add_simple_test(suite, "smb-reauth1", torture_rpc_smb_reauth1);
4711 2354 : torture_suite_add_simple_test(suite, "smb-reauth2", torture_rpc_smb_reauth2);
4712 2354 : torture_suite_add_simple_test(suite, "smb2-reauth1", torture_rpc_smb2_reauth1);
4713 2354 : torture_suite_add_simple_test(suite, "smb2-reauth2", torture_rpc_smb2_reauth2);
4714 2354 : torture_suite_add_simple_test(suite, "smb1-pipe-name", torture_rpc_smb1_pipe_name);
4715 2354 : torture_suite_add_simple_test(suite, "smb2-pipe-name", torture_rpc_smb2_pipe_name);
4716 2354 : torture_suite_add_simple_test(suite, "smb2-pipe-read-close", torture_rpc_smb2_pipe_read_close);
4717 2354 : torture_suite_add_simple_test(suite, "smb2-pipe-read-tdis", torture_rpc_smb2_pipe_read_tdis);
4718 2354 : torture_suite_add_simple_test(suite, "smb2-pipe-read-logoff", torture_rpc_smb2_pipe_read_logoff);
4719 2354 : torture_suite_add_simple_test(suite,
4720 : "lsa_over_netlogon",
4721 : torture_rpc_lsa_over_netlogon);
4722 2354 : torture_suite_add_simple_test(suite,
4723 : "pipes_supported_interfaces",
4724 : torture_rpc_pipes_supported_interfaces);
4725 :
4726 2354 : suite->description = talloc_strdup(suite, "samba3 DCERPC interface tests");
4727 :
4728 2354 : return suite;
4729 : }
|