ctdb-scripts: Support storing statd-callout state in cluster filesystem
[samba4-gss.git] / source4 / torture / rpc / mdssvc.c
blob2096ed7b9c753a35e3ab0e9e5c098d6d62710cc9
1 /*
2 Unix SMB/CIFS implementation.
3 test suite for the mdssvc RPC service
5 Copyright (C) Ralph Boehme 2019
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 #include "includes.h"
23 #include "torture/rpc/torture_rpc.h"
24 #include "librpc/gen_ndr/ndr_mdssvc_c.h"
25 #include "param/param.h"
26 #include "lib/cmdline/cmdline.h"
27 #include "rpc_server/mdssvc/dalloc.h"
28 #include "rpc_server/mdssvc/marshalling.h"
30 struct torture_mdsscv_state {
31 struct dcerpc_pipe *p;
32 struct policy_handle ph;
34 /* Known fields used across multiple commands */
35 uint32_t dev;
36 uint32_t flags;
38 /* cmd specific or unknown fields */
39 struct {
40 const char share_path[1025];
41 uint32_t unkn2;
42 uint32_t unkn3;
43 } mdscmd_open;
44 struct {
45 uint32_t status;
46 uint32_t unkn7;
47 } mdscmd_unknown1;
48 struct {
49 uint32_t fragment;
50 uint32_t unkn9;
51 } mdscmd_cmd;
52 struct {
53 uint32_t status;
54 } mdscmd_close;
57 static bool torture_rpc_mdssvc_setup(struct torture_context *tctx,
58 void **data)
60 struct torture_mdsscv_state *state = NULL;
61 NTSTATUS status;
63 state = talloc_zero(tctx, struct torture_mdsscv_state);
64 if (state == NULL) {
65 return false;
67 *data = state;
69 status = torture_rpc_connection(tctx, &state->p, &ndr_table_mdssvc);
70 torture_assert_ntstatus_ok(tctx, status, "Error connecting to server");
72 return true;
75 static bool torture_rpc_mdssvc_teardown(struct torture_context *tctx,
76 void *data)
78 struct torture_mdsscv_state *state = talloc_get_type_abort(
79 data, struct torture_mdsscv_state);
81 TALLOC_FREE(state->p);
82 TALLOC_FREE(state);
83 return true;
86 static bool torture_rpc_mdssvc_open(struct torture_context *tctx,
87 void **data)
89 struct torture_mdsscv_state *state = NULL;
90 struct dcerpc_binding_handle *b = NULL;
91 const char *share_name = NULL;
92 const char *share_mount_path = NULL;
93 NTSTATUS status;
94 bool ok = true;
96 state = talloc_zero(tctx, struct torture_mdsscv_state);
97 if (state == NULL) {
98 return false;
100 *data = state;
102 status = torture_rpc_connection(tctx, &state->p, &ndr_table_mdssvc);
103 torture_assert_ntstatus_ok(tctx, status, "Error connecting to server");
104 b = state->p->binding_handle;
106 share_name = torture_setting_string(
107 tctx, "spotlight_share", "spotlight");
108 share_mount_path = torture_setting_string(
109 tctx, "share_mount_path", "/foo/bar");
111 state->dev = generate_random();
112 state->mdscmd_open.unkn2 = 23;
113 state->mdscmd_open.unkn3 = 0;
115 ZERO_STRUCT(state->ph);
117 status = dcerpc_mdssvc_open(b,
118 state,
119 &state->dev,
120 &state->mdscmd_open.unkn2,
121 &state->mdscmd_open.unkn3,
122 share_mount_path,
123 share_name,
124 state->mdscmd_open.share_path,
125 &state->ph);
126 torture_assert_ntstatus_ok_goto(tctx, status, ok, done,
127 "dcerpc_mdssvc_open failed\n");
129 status = dcerpc_mdssvc_unknown1(b,
130 state,
131 &state->ph,
133 state->dev,
134 state->mdscmd_open.unkn2,
136 geteuid(),
137 getegid(),
138 &state->mdscmd_unknown1.status,
139 &state->flags,
140 &state->mdscmd_unknown1.unkn7);
141 torture_assert_ntstatus_ok_goto(tctx, status, ok, done,
142 "dcerpc_mdssvc_unknown1 failed\n");
144 done:
145 if (!ok) {
146 (void)dcerpc_mdssvc_close(b,
147 state,
148 &state->ph,
150 state->dev,
151 state->mdscmd_open.unkn2,
153 &state->ph,
154 &state->mdscmd_close.status);
155 ZERO_STRUCTP(state);
157 return ok;
160 static bool torture_rpc_mdssvc_close(struct torture_context *tctx,
161 void *data)
163 struct torture_mdsscv_state *state = talloc_get_type_abort(
164 data, struct torture_mdsscv_state);
165 NTSTATUS status;
166 bool ok = true;
168 torture_comment(tctx, "test_teardown_mdssvc_disconnect\n");
170 if (state->p == NULL) {
171 /* We have already been disconnected. */
172 goto done;
175 status = dcerpc_mdssvc_close(state->p->binding_handle,
176 state,
177 &state->ph,
179 state->dev,
180 state->mdscmd_open.unkn2,
182 &state->ph,
183 &state->mdscmd_close.status);
184 torture_assert_ntstatus_ok_goto(tctx, status, ok, done,
185 "dcerpc_mdssvc_close failed\n");
187 ZERO_STRUCTP(state);
189 done:
190 return ok;
194 * Test unknown share name
196 static bool test_mdssvc_open_unknown_share(struct torture_context *tctx,
197 void *data)
199 struct torture_mdsscv_state *state = talloc_get_type_abort(
200 data, struct torture_mdsscv_state);
201 struct dcerpc_binding_handle *b = state->p->binding_handle;
202 struct policy_handle ph;
203 struct policy_handle nullh;
204 uint32_t device_id;
205 uint32_t unkn2;
206 uint32_t unkn3;
207 uint32_t device_id_out;
208 uint32_t unkn2_out;
209 uint32_t unkn3_out;
210 const char *share_mount_path = NULL;
211 const char *share_name = NULL;
212 const char share_path[1025] = "X";
213 NTSTATUS status;
214 bool ok = true;
216 share_name = torture_setting_string(
217 tctx, "unknown_share", "choukawoohoo");
218 share_mount_path = torture_setting_string(
219 tctx, "share_mount_path", "/foo/bar");
221 device_id_out = device_id = generate_random();
222 unkn2_out = unkn2 = generate_random();
223 unkn3_out = unkn3 = generate_random();
225 ZERO_STRUCT(ph);
226 ZERO_STRUCT(nullh);
228 status = dcerpc_mdssvc_open(b,
229 tctx,
230 &device_id_out,
231 &unkn2_out,
232 &unkn3_out,
233 share_mount_path,
234 share_name,
235 share_path,
236 &ph);
238 torture_assert_ntstatus_ok_goto(tctx, status, ok, done,
239 "dcerpc_mdssvc_open failed\n");
241 torture_assert_u32_equal_goto(tctx, device_id_out, device_id, ok, done,
242 "Bad device_id\n");
244 torture_assert_u32_equal_goto(tctx, unkn2_out, unkn2, ok, done,
245 "Bad unkn2\n");
247 torture_assert_u32_equal_goto(tctx, unkn3_out, unkn3, ok, done,
248 "Bad unkn3\n");
250 torture_assert_goto(tctx, share_path[0] == '\0', ok, done,
251 "Expected empty string as share path\n");
253 torture_assert_mem_equal_goto(tctx, &ph, &nullh,
254 sizeof(ph), ok, done,
255 "Expected all-zero policy handle\n");
257 done:
258 return ok;
262 * Test on a share where Spotlight is not enabled
264 static bool test_mdssvc_open_spotlight_disabled(struct torture_context *tctx,
265 void *data)
267 struct torture_mdsscv_state *state = talloc_get_type_abort(
268 data, struct torture_mdsscv_state);
269 struct dcerpc_binding_handle *b = state->p->binding_handle;
270 struct policy_handle ph;
271 struct policy_handle nullh;
272 uint32_t device_id;
273 uint32_t unkn2;
274 uint32_t unkn3;
275 uint32_t device_id_out;
276 uint32_t unkn2_out;
277 uint32_t unkn3_out;
278 const char *share_mount_path = NULL;
279 const char *share_name = NULL;
280 const char share_path[1025] = "";
281 NTSTATUS status;
282 bool ok = true;
284 share_name = torture_setting_string(
285 tctx, "no_spotlight_share", "no_spotlight");
286 share_mount_path = torture_setting_string(
287 tctx, "share_mount_path", "/foo/bar");
289 device_id_out = device_id = generate_random();
290 unkn2_out = unkn2 = 23;
291 unkn3_out = unkn3 = 0;
293 ZERO_STRUCT(ph);
294 ZERO_STRUCT(nullh);
296 status = dcerpc_mdssvc_open(b,
297 tctx,
298 &device_id_out,
299 &unkn2_out,
300 &unkn3_out,
301 share_mount_path,
302 share_name,
303 share_path,
304 &ph);
305 torture_assert_ntstatus_ok_goto(tctx, status, ok, done,
306 "dcerpc_mdssvc_open failed\n");
308 torture_assert_u32_equal_goto(tctx, device_id, device_id_out, ok, done,
309 "Bad device_id\n");
311 torture_assert_u32_equal_goto(tctx, unkn2, unkn2_out,
312 ok, done, "Bad unkn2\n");
314 torture_assert_u32_equal_goto(tctx, unkn3, unkn3_out,
315 ok, done, "Bad unkn3\n");
317 torture_assert_goto(tctx, share_path[0] == '\0', ok, done,
318 "Expected empty string as share path\n");
320 torture_assert_mem_equal_goto(tctx, &ph, &nullh,
321 sizeof(ph), ok, done,
322 "Expected all-zero policy handle\n");
324 done:
325 return ok;
328 static bool test_mdssvc_close(struct torture_context *tctx,
329 void *data)
331 struct torture_mdsscv_state *state = talloc_get_type_abort(
332 data, struct torture_mdsscv_state);
333 struct dcerpc_binding_handle *b = state->p->binding_handle;
334 struct policy_handle ph;
335 struct policy_handle close_ph;
336 uint32_t device_id;
337 uint32_t unkn2;
338 uint32_t unkn3;
339 const char *share_mount_path = NULL;
340 const char *share_name = NULL;
341 const char share_path[1025] = "";
342 uint32_t close_status;
343 DATA_BLOB ph_blob;
344 DATA_BLOB close_ph_blob;
345 NTSTATUS status;
346 bool ok = true;
348 share_name = torture_setting_string(
349 tctx, "spotlight_share", "spotlight");
350 share_mount_path = torture_setting_string(
351 tctx, "share_mount_path", "/foo/bar");
353 device_id = generate_random();
354 unkn2 = 23;
355 unkn3 = 0;
357 ZERO_STRUCT(ph);
358 ZERO_STRUCT(close_ph);
360 status = dcerpc_mdssvc_open(b,
361 tctx,
362 &device_id,
363 &unkn2,
364 &unkn3,
365 share_mount_path,
366 share_name,
367 share_path,
368 &ph);
369 torture_assert_ntstatus_ok_goto(tctx, status, ok, done,
370 "dcerpc_mdssvc_open failed\n");
372 status = dcerpc_mdssvc_close(b,
373 tctx,
374 &ph,
376 device_id,
377 unkn2,
379 &close_ph,
380 &close_status);
381 torture_assert_ntstatus_ok_goto(tctx, status, ok, done,
382 "dcerpc_mdssvc_open failed\n");
384 ph_blob = (DATA_BLOB) {
385 .data = (uint8_t *)&ph,
386 .length = sizeof(struct policy_handle)
388 close_ph_blob = (DATA_BLOB) {
389 .data = (uint8_t *)&close_ph,
390 .length = sizeof(struct policy_handle),
393 torture_assert_data_blob_equal(tctx, close_ph_blob, ph_blob,
394 "bad blob");
396 torture_comment(tctx, "Test close with a all-zero handle\n");
398 ZERO_STRUCT(ph);
399 status = dcerpc_mdssvc_close(b,
400 tctx,
401 &ph,
403 device_id,
404 unkn2,
406 &close_ph,
407 &close_status);
408 torture_assert_ntstatus_ok_goto(tctx, status, ok, done,
409 "dcerpc_mdssvc_close failed\n");
411 torture_assert_data_blob_equal(tctx, close_ph_blob, ph_blob,
412 "bad blob");
414 done:
415 return ok;
418 static bool test_mdssvc_null_ph(struct torture_context *tctx,
419 void *data)
421 struct torture_mdsscv_state *state = talloc_get_type_abort(
422 data, struct torture_mdsscv_state);
423 struct dcerpc_binding_handle *b = state->p->binding_handle;
424 struct policy_handle nullh;
425 struct policy_handle ph;
426 uint32_t device_id;
427 uint32_t unkn2;
428 uint32_t unkn7;
429 uint32_t cmd_status;
430 uint32_t flags;
431 NTSTATUS status;
432 bool ok = true;
434 device_id = generate_random();
435 unkn2 = 23;
436 unkn7 = 0;
437 cmd_status = 0;
439 ZERO_STRUCT(nullh);
440 ZERO_STRUCT(ph);
442 status = dcerpc_mdssvc_unknown1(b,
443 tctx,
444 &ph,
446 device_id,
447 unkn2,
449 geteuid(),
450 getegid(),
451 &cmd_status,
452 &flags,
453 &unkn7);
454 torture_assert_ntstatus_ok_goto(tctx, status, ok, done,
455 "dcerpc_mdssvc_unknown1 failed\n");
457 torture_assert_mem_equal_goto(tctx, &ph, &nullh,
458 sizeof(ph), ok, done,
459 "Expected all-zero policy handle\n");
461 done:
462 return ok;
465 static bool test_mdssvc_invalid_ph_unknown1(struct torture_context *tctx,
466 void *data)
468 struct torture_mdsscv_state *state = talloc_get_type_abort(
469 data, struct torture_mdsscv_state);
470 struct dcerpc_binding_handle *b = state->p->binding_handle;
471 struct policy_handle ph;
472 uint32_t device_id;
473 uint32_t unkn2;
474 uint32_t unkn7;
475 uint32_t cmd_status;
476 uint32_t flags;
477 NTSTATUS status;
478 bool ok = true;
480 device_id = generate_random();
481 unkn2 = 23;
482 unkn7 = 0;
483 cmd_status = 0;
485 ZERO_STRUCT(ph);
486 ph.uuid = GUID_random();
488 status = dcerpc_mdssvc_unknown1(b,
489 tctx,
490 &ph,
492 device_id,
493 unkn2,
495 geteuid(),
496 getegid(),
497 &cmd_status,
498 &flags,
499 &unkn7);
500 torture_assert_ntstatus_equal_goto(
501 tctx, status, NT_STATUS_RPC_PROTOCOL_ERROR, ok, done,
502 "dcerpc_mdssvc_unknown1 failed\n");
504 /* Free and set to NULL the no-longer-usable pipe. */
505 b = NULL;
506 TALLOC_FREE(state->p);
508 done:
509 return ok;
512 static bool test_mdssvc_invalid_ph_cmd(struct torture_context *tctx,
513 void *data)
515 struct torture_mdsscv_state *state = talloc_get_type_abort(
516 data, struct torture_mdsscv_state);
517 struct dcerpc_binding_handle *b = state->p->binding_handle;
518 struct policy_handle ph;
519 struct mdssvc_blob request_blob;
520 struct mdssvc_blob response_blob;
521 uint32_t device_id;
522 uint32_t unkn2;
523 uint32_t unkn9;
524 uint32_t fragment;
525 uint32_t flags;
526 NTSTATUS status;
527 bool ok = true;
529 device_id = generate_random();
530 unkn2 = 23;
531 unkn9 = 0;
532 fragment = 0;
533 flags = UINT32_C(0x6b000001);
535 ZERO_STRUCT(ph);
536 ph.uuid = GUID_random();
538 request_blob.spotlight_blob = talloc_array(state,
539 uint8_t,
541 torture_assert_not_null_goto(tctx, request_blob.spotlight_blob,
542 ok, done, "dalloc_zero failed\n");
543 request_blob.size = 0;
544 request_blob.length = 0;
545 request_blob.size = 0;
547 status = dcerpc_mdssvc_cmd(b,
548 state,
549 &ph,
551 device_id,
552 unkn2,
554 flags,
555 request_blob,
557 64 * 1024,
559 64 * 1024,
562 &fragment,
563 &response_blob,
564 &unkn9);
565 torture_assert_ntstatus_equal_goto(
566 tctx, status, NT_STATUS_RPC_PROTOCOL_ERROR, ok, done,
567 "dcerpc_mdssvc_unknown1 failed\n");
569 /* Free and set to NULL the no-longer-usable pipe. */
570 b = NULL;
571 TALLOC_FREE(state->p);
573 done:
574 return ok;
577 static uint8_t test_sl_unpack_loop_buf[] = {
578 0x34, 0x33, 0x32, 0x31, 0x33, 0x30, 0x64, 0x6d,
579 0x1d, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00,
580 0x01, 0x00, 0x00, 0x02, 0x01, 0x00, 0x00, 0x00,
581 0x01, 0x00, 0x00, 0x02, 0x02, 0x00, 0x00, 0x00,
582 0x01, 0x00, 0x00, 0x02, 0x03, 0x00, 0x00, 0x00,
583 0x06, 0x00, 0x00, 0x07, 0x04, 0x00, 0x00, 0x00,
584 0x66, 0x65, 0x74, 0x63, 0x68, 0x41, 0x74, 0x74,
585 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x3a,
586 0x66, 0x6f, 0x72, 0x4f, 0x49, 0x44, 0x41, 0x72,
587 0x72, 0x61, 0x79, 0x3a, 0x63, 0x6f, 0x6e, 0x74,
588 0x65, 0x78, 0x74, 0x3a, 0x00, 0x00, 0x00, 0xea,
589 0x02, 0x00, 0x00, 0x84, 0x02, 0x00, 0x00, 0x00,
590 0x0a, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
591 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
592 0x01, 0x00, 0x00, 0x02, 0x04, 0x00, 0x00, 0x00,
593 0x01, 0x00, 0x00, 0x02, 0x05, 0x00, 0x00, 0x00,
594 0x03, 0x00, 0x00, 0x07, 0x03, 0x00, 0x00, 0x00,
595 0x6b, 0x4d, 0x44, 0x49, 0x74, 0x65, 0x6d, 0x50,
596 0x61, 0x74, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00,
597 0x01, 0x00, 0x00, 0x02, 0x06, 0x00, 0x00, 0x00,
598 0x03, 0x00, 0x00, 0x87, 0x08, 0x00, 0x00, 0x00,
599 0x01, 0x00, 0xdd, 0x0a, 0x20, 0x00, 0x00, 0x6b,
600 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
601 0x07, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00, 0x00,
602 0x02, 0x00, 0x00, 0x0a, 0x03, 0x00, 0x00, 0x00,
603 0x03, 0x00, 0x00, 0x0a, 0x03, 0x00, 0x00, 0x00,
604 0x04, 0x00, 0x00, 0x0c, 0x04, 0x00, 0x00, 0x00,
605 0x0e, 0x00, 0x00, 0x0a, 0x01, 0x00, 0x00, 0x00,
606 0x0f, 0x00, 0x00, 0x0c, 0x03, 0x00, 0x00, 0x00,
607 0x13, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x00,
608 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
609 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00,
610 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
611 0x00, 0x00, 0x00, 0x00
614 static bool test_mdssvc_sl_unpack_loop(struct torture_context *tctx,
615 void *data)
617 struct torture_mdsscv_state *state = talloc_get_type_abort(
618 data, struct torture_mdsscv_state);
619 struct dcerpc_binding_handle *b = state->p->binding_handle;
620 struct mdssvc_blob request_blob;
621 struct mdssvc_blob response_blob;
622 uint32_t device_id;
623 uint32_t unkn2;
624 uint32_t unkn9;
625 uint32_t fragment;
626 uint32_t flags;
627 NTSTATUS status;
628 bool ok = true;
630 device_id = UINT32_C(0x2f000045);
631 unkn2 = 23;
632 unkn9 = 0;
633 fragment = 0;
634 flags = UINT32_C(0x6b000001);
636 request_blob.spotlight_blob = test_sl_unpack_loop_buf;
637 request_blob.size = sizeof(test_sl_unpack_loop_buf);
638 request_blob.length = sizeof(test_sl_unpack_loop_buf);
640 status = dcerpc_mdssvc_cmd(b,
641 state,
642 &state->ph,
644 device_id,
645 unkn2,
647 flags,
648 request_blob,
650 64 * 1024,
652 64 * 1024,
655 &fragment,
656 &response_blob,
657 &unkn9);
658 torture_assert_ntstatus_ok_goto(
659 tctx, status, ok, done,
660 "dcerpc_mdssvc_unknown1 failed\n");
662 done:
663 return ok;
666 static bool test_sl_dict_type_safety(struct torture_context *tctx,
667 void *data)
669 struct torture_mdsscv_state *state = talloc_get_type_abort(
670 data, struct torture_mdsscv_state);
671 struct dcerpc_binding_handle *b = state->p->binding_handle;
672 struct mdssvc_blob request_blob;
673 struct mdssvc_blob response_blob;
674 uint64_t ctx1 = 0xdeadbeef;
675 uint64_t ctx2 = 0xcafebabe;
676 uint32_t device_id;
677 uint32_t unkn2;
678 uint32_t unkn9;
679 uint32_t fragment;
680 uint32_t flags;
681 DALLOC_CTX *d = NULL;
682 sl_array_t *array1 = NULL, *array2 = NULL;
683 sl_dict_t *arg = NULL;
684 int result;
685 NTSTATUS status;
686 bool ok = true;
688 device_id = UINT32_C(0x2f000045);
689 unkn2 = 23;
690 unkn9 = 0;
691 fragment = 0;
692 flags = UINT32_C(0x6b000001);
694 d = dalloc_new(tctx);
695 torture_assert_not_null_goto(tctx, d,
696 ok, done, "dalloc_new failed\n");
698 array1 = dalloc_zero(d, sl_array_t);
699 torture_assert_not_null_goto(tctx, array1,
700 ok, done, "dalloc_zero failed\n");
702 array2 = dalloc_zero(d, sl_array_t);
703 torture_assert_not_null_goto(tctx, array2,
704 ok, done, "dalloc_new failed\n");
706 result = dalloc_stradd(array2, "openQueryWithParams:forContext:");
707 torture_assert_goto(tctx, result == 0,
708 ok, done, "dalloc_stradd failed\n");
710 result = dalloc_add_copy(array2, &ctx1, uint64_t);
711 torture_assert_goto(tctx, result == 0,
712 ok, done, "dalloc_stradd failed\n");
714 result = dalloc_add_copy(array2, &ctx2, uint64_t);
715 torture_assert_goto(tctx, result == 0,
716 ok, done, "dalloc_stradd failed\n");
718 arg = dalloc_zero(array1, sl_dict_t);
719 torture_assert_not_null_goto(tctx, d,
720 ok, done, "dalloc_zero failed\n");
722 result = dalloc_stradd(arg, "kMDQueryString");
723 torture_assert_goto(tctx, result == 0,
724 ok, done, "dalloc_stradd failed\n");
726 result = dalloc_stradd(arg, "*");
727 torture_assert_goto(tctx, result == 0,
728 ok, done, "dalloc_stradd failed\n");
730 result = dalloc_stradd(arg, "kMDScopeArray");
731 torture_assert_goto(tctx, result == 0,
732 ok, done, "dalloc_stradd failed\n");
734 result = dalloc_stradd(arg, "AAAABBBB");
735 torture_assert_goto(tctx, result == 0,
736 ok, done, "dalloc_stradd failed\n");
738 result = dalloc_add(array1, array2, sl_array_t);
739 torture_assert_goto(tctx, result == 0,
740 ok, done, "dalloc_add failed\n");
742 result = dalloc_add(array1, arg, sl_dict_t);
743 torture_assert_goto(tctx, result == 0,
744 ok, done, "dalloc_add failed\n");
746 result = dalloc_add(d, array1, sl_array_t);
747 torture_assert_goto(tctx, result == 0,
748 ok, done, "dalloc_add failed\n");
750 torture_comment(tctx, "%s", dalloc_dump(d, 0));
752 request_blob.spotlight_blob = talloc_array(tctx,
753 uint8_t,
754 64 * 1024);
755 torture_assert_not_null_goto(tctx, request_blob.spotlight_blob,
756 ok, done, "dalloc_new failed\n");
757 request_blob.size = 64 * 1024;
759 status = sl_pack_alloc(tctx, d, &request_blob, 64 * 1024);
760 torture_assert_ntstatus_ok_goto(tctx, status, ok, done,
761 "sl_pack_alloc() failed\n");
763 status = dcerpc_mdssvc_cmd(b,
764 state,
765 &state->ph,
767 device_id,
768 unkn2,
770 flags,
771 request_blob,
773 64 * 1024,
775 64 * 1024,
778 &fragment,
779 &response_blob,
780 &unkn9);
781 torture_assert_ntstatus_ok_goto(
782 tctx, status, ok, done,
783 "dcerpc_mdssvc_cmd failed\n");
785 done:
786 return ok;
789 static bool test_mdssvc_invalid_ph_close(struct torture_context *tctx,
790 void *data)
792 struct torture_mdsscv_state *state = talloc_get_type_abort(
793 data, struct torture_mdsscv_state);
794 struct dcerpc_binding_handle *b = state->p->binding_handle;
795 struct policy_handle ph;
796 uint32_t device_id;
797 uint32_t unkn2;
798 uint32_t close_status;
799 NTSTATUS status;
800 bool ok = true;
802 device_id = generate_random();
803 unkn2 = 23;
804 close_status = 0;
806 ZERO_STRUCT(ph);
807 ph.uuid = GUID_random();
809 status = dcerpc_mdssvc_close(b,
810 state,
811 &ph,
813 device_id,
814 unkn2,
816 &ph,
817 &close_status);
818 torture_assert_ntstatus_equal_goto(
819 tctx, status, NT_STATUS_RPC_PROTOCOL_ERROR, ok, done,
820 "dcerpc_mdssvc_unknown1 failed\n");
822 /* Free and set to NULL the no-longer-usable pipe. */
823 b = NULL;
824 TALLOC_FREE(state->p);
826 done:
827 return ok;
831 * Test fetchAttributes with unknown CNID
833 static bool test_mdssvc_fetch_attr_unknown_cnid(struct torture_context *tctx,
834 void *data)
836 struct torture_mdsscv_state *state = talloc_get_type_abort(
837 data, struct torture_mdsscv_state);
838 struct dcerpc_binding_handle *b = state->p->binding_handle;
839 uint32_t max_fragment_size = 64 * 1024;
840 struct mdssvc_blob request_blob;
841 struct mdssvc_blob response_blob;
842 DALLOC_CTX *d = NULL, *mds_reply = NULL;
843 uint64_t *uint64var = NULL;
844 sl_array_t *array = NULL;
845 sl_array_t *cmd_array = NULL;
846 sl_array_t *attr_array = NULL;
847 sl_cnids_t *cnids = NULL;
848 void *path = NULL;
849 const char *path_type = NULL;
850 uint64_t ino64;
851 NTSTATUS status;
852 int ret;
853 bool ok = true;
855 d = dalloc_new(state);
856 torture_assert_not_null_goto(tctx, d, ret, done, "dalloc_new failed\n");
858 array = dalloc_zero(d, sl_array_t);
859 torture_assert_not_null_goto(tctx, array, ret, done,
860 "dalloc_zero failed\n");
862 ret = dalloc_add(d, array, sl_array_t);
863 torture_assert_goto(tctx, ret == 0, ret, done, "dalloc_add failed\n");
865 cmd_array = dalloc_zero(d, sl_array_t);
866 torture_assert_not_null_goto(tctx, cmd_array, ret, done,
867 "dalloc_zero failed\n");
869 ret = dalloc_add(array, cmd_array, sl_array_t);
870 torture_assert_goto(tctx, ret == 0, ret, done, "dalloc_add failed\n");
872 ret = dalloc_stradd(cmd_array, "fetchAttributes:forOIDArray:context:");
873 torture_assert_goto(tctx, ret == 0, ret, done, "dalloc_stradd failed\n");
875 uint64var = talloc_zero_array(cmd_array, uint64_t, 2);
876 torture_assert_not_null_goto(tctx, uint64var, ret, done,
877 "talloc_zero_array failed\n");
878 talloc_set_name(uint64var, "uint64_t *");
880 uint64var[0] = 0x500a;
881 uint64var[1] = 0;
883 ret = dalloc_add(cmd_array, &uint64var[0], uint64_t *);
884 torture_assert_goto(tctx, ret == 0, ret, done, "dalloc_add failed\n");
886 attr_array = dalloc_zero(d, sl_array_t);
887 torture_assert_not_null_goto(tctx, attr_array, ret, done,
888 "dalloc_zero failed\n");
890 ret = dalloc_add(array, attr_array, sl_array_t);
891 torture_assert_goto(tctx, ret == 0, ret, done, "dalloc_add failed\n");
893 ret = dalloc_stradd(attr_array, "kMDItemPath");
894 torture_assert_goto(tctx, ret == 0, ret, done, "dalloc_stradd failed\n");
896 /* CNIDs */
897 cnids = talloc_zero(array, sl_cnids_t);
898 torture_assert_not_null_goto(tctx, cnids, ret, done,
899 "talloc_zero failed\n");
901 cnids->ca_cnids = dalloc_new(cnids);
902 torture_assert_not_null_goto(tctx, cnids->ca_cnids, ret, done,
903 "dalloc_new failed\n");
905 cnids->ca_unkn1 = 0xadd;
906 cnids->ca_context = 0x6b000020;
908 ino64 = UINT64_C(64382947389618974);
909 ret = dalloc_add_copy(cnids->ca_cnids, &ino64, uint64_t);
910 torture_assert_goto(tctx, ret == 0, ret, done,
911 "dalloc_add_copy failed\n");
913 ret = dalloc_add(array, cnids, sl_cnids_t);
914 torture_assert_goto(tctx, ret == 0, ret, done, "dalloc_add failed\n");
916 status = sl_pack_alloc(tctx, d, &request_blob, max_fragment_size);
917 torture_assert_ntstatus_ok_goto(tctx, status, ok, done,
918 "sl_pack_alloc() failed\n");
920 status = dcerpc_mdssvc_cmd(b,
921 state,
922 &state->ph,
924 state->dev,
925 state->mdscmd_open.unkn2,
927 state->flags,
928 request_blob,
930 max_fragment_size,
932 max_fragment_size,
935 &state->mdscmd_cmd.fragment,
936 &response_blob,
937 &state->mdscmd_cmd.unkn9);
938 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
939 "dcerpc_mdssvc_cmd failed\n");
941 mds_reply = dalloc_new(state);
942 torture_assert_not_null_goto(tctx, mds_reply, ret, done,
943 "dalloc_zero failed\n");
945 ok = sl_unpack(mds_reply,
946 (char *)response_blob.spotlight_blob,
947 response_blob.length);
948 torture_assert_goto(tctx, ok, ret, done, "dalloc_add failed\n");
950 torture_comment(tctx, "%s", dalloc_dump(mds_reply, 0));
952 path = dalloc_get(mds_reply,
953 "DALLOC_CTX", 0,
954 "DALLOC_CTX", 2,
955 "DALLOC_CTX", 0,
956 "sl_nil_t", 1);
957 torture_assert_not_null_goto(tctx, path, ret, done,
958 "dalloc_get path failed\n");
960 path_type = talloc_get_name(path);
962 torture_assert_str_equal_goto(tctx, path_type, "sl_nil_t", ret, done,
963 "Wrong dalloc object type\n");
965 done:
966 return ok;
969 struct torture_suite *torture_rpc_mdssvc(TALLOC_CTX *mem_ctx)
971 struct torture_suite *suite = torture_suite_create(
972 mem_ctx, "mdssvc");
973 struct torture_tcase *tcase = NULL;
975 tcase = torture_suite_add_tcase(suite, "rpccmd");
976 if (tcase == NULL) {
977 return NULL;
979 torture_tcase_set_fixture(tcase,
980 torture_rpc_mdssvc_setup,
981 torture_rpc_mdssvc_teardown);
983 torture_tcase_add_simple_test(tcase,
984 "open_unknown_share",
985 test_mdssvc_open_unknown_share);
987 torture_tcase_add_simple_test(tcase,
988 "open_spotlight_disabled",
989 test_mdssvc_open_spotlight_disabled);
991 torture_tcase_add_simple_test(tcase,
992 "close",
993 test_mdssvc_close);
995 torture_tcase_add_simple_test(tcase,
996 "null_ph",
997 test_mdssvc_null_ph);
999 tcase = torture_suite_add_tcase(suite, "disconnect1");
1000 if (tcase == NULL) {
1001 return NULL;
1003 torture_tcase_set_fixture(tcase,
1004 torture_rpc_mdssvc_open,
1005 torture_rpc_mdssvc_close);
1007 torture_tcase_add_simple_test(tcase,
1008 "invalid_ph_unknown1",
1009 test_mdssvc_invalid_ph_unknown1);
1011 tcase = torture_suite_add_tcase(suite, "disconnect2");
1012 if (tcase == NULL) {
1013 return NULL;
1015 torture_tcase_set_fixture(tcase,
1016 torture_rpc_mdssvc_open,
1017 torture_rpc_mdssvc_close);
1019 torture_tcase_add_simple_test(tcase,
1020 "invalid_ph_cmd",
1021 test_mdssvc_invalid_ph_cmd);
1023 tcase = torture_suite_add_tcase(suite, "disconnect3");
1024 if (tcase == NULL) {
1025 return NULL;
1027 torture_tcase_set_fixture(tcase,
1028 torture_rpc_mdssvc_open,
1029 torture_rpc_mdssvc_close);
1031 torture_tcase_add_simple_test(tcase,
1032 "invalid_ph_close",
1033 test_mdssvc_invalid_ph_close);
1035 tcase = torture_suite_add_tcase(suite, "mdscmd");
1036 if (tcase == NULL) {
1037 return NULL;
1039 torture_tcase_set_fixture(tcase,
1040 torture_rpc_mdssvc_open,
1041 torture_rpc_mdssvc_close);
1043 torture_tcase_add_simple_test(tcase,
1044 "fetch_unknown_cnid",
1045 test_mdssvc_fetch_attr_unknown_cnid);
1047 torture_tcase_add_simple_test(tcase,
1048 "mdssvc_sl_unpack_loop",
1049 test_mdssvc_sl_unpack_loop);
1051 torture_tcase_add_simple_test(tcase,
1052 "sl_dict_type_safety",
1053 test_sl_dict_type_safety);
1055 return suite;