Line data Source code
1 : /*
2 : Unix SMB/CIFS implementation.
3 : test suite for the mdssvc RPC serice
4 :
5 : Copyright (C) Ralph Boehme 2019
6 :
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.
11 :
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.
16 :
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.
20 : */
21 :
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"
29 :
30 : struct torture_mdsscv_state {
31 : struct dcerpc_pipe *p;
32 : struct policy_handle ph;
33 :
34 : /* Known fields used across multiple commands */
35 : uint32_t dev;
36 : uint32_t flags;
37 :
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;
55 : };
56 :
57 2 : static bool torture_rpc_mdssvc_setup(struct torture_context *tctx,
58 : void **data)
59 : {
60 2 : struct torture_mdsscv_state *state = NULL;
61 : NTSTATUS status;
62 :
63 2 : state = talloc_zero(tctx, struct torture_mdsscv_state);
64 2 : if (state == NULL) {
65 0 : return false;
66 : }
67 2 : *data = state;
68 :
69 2 : status = torture_rpc_connection(tctx, &state->p, &ndr_table_mdssvc);
70 2 : torture_assert_ntstatus_ok(tctx, status, "Error connecting to server");
71 :
72 2 : return true;
73 : }
74 :
75 2 : static bool torture_rpc_mdssvc_teardown(struct torture_context *tctx,
76 : void *data)
77 : {
78 2 : struct torture_mdsscv_state *state = talloc_get_type_abort(
79 : data, struct torture_mdsscv_state);
80 :
81 2 : TALLOC_FREE(state->p);
82 2 : TALLOC_FREE(state);
83 2 : return true;
84 : }
85 :
86 8 : static bool torture_rpc_mdssvc_open(struct torture_context *tctx,
87 : void **data)
88 : {
89 8 : struct torture_mdsscv_state *state = NULL;
90 8 : struct dcerpc_binding_handle *b = NULL;
91 8 : const char *share_name = NULL;
92 8 : const char *share_mount_path = NULL;
93 : NTSTATUS status;
94 8 : bool ok = true;
95 :
96 8 : state = talloc_zero(tctx, struct torture_mdsscv_state);
97 8 : if (state == NULL) {
98 0 : return false;
99 : }
100 8 : *data = state;
101 :
102 8 : status = torture_rpc_connection(tctx, &state->p, &ndr_table_mdssvc);
103 8 : torture_assert_ntstatus_ok(tctx, status, "Error connecting to server");
104 8 : b = state->p->binding_handle;
105 :
106 8 : share_name = torture_setting_string(
107 : tctx, "spotlight_share", "spotlight");
108 8 : share_mount_path = torture_setting_string(
109 : tctx, "share_mount_path", "/foo/bar");
110 :
111 8 : state->dev = generate_random();
112 8 : state->mdscmd_open.unkn2 = 23;
113 8 : state->mdscmd_open.unkn3 = 0;
114 :
115 8 : ZERO_STRUCT(state->ph);
116 :
117 32 : status = dcerpc_mdssvc_open(b,
118 : state,
119 8 : &state->dev,
120 8 : &state->mdscmd_open.unkn2,
121 8 : &state->mdscmd_open.unkn3,
122 : share_mount_path,
123 : share_name,
124 8 : state->mdscmd_open.share_path,
125 8 : &state->ph);
126 8 : torture_assert_ntstatus_ok_goto(tctx, status, ok, done,
127 : "dcerpc_mdssvc_open failed\n");
128 :
129 48 : status = dcerpc_mdssvc_unknown1(b,
130 : state,
131 8 : &state->ph,
132 : 0,
133 8 : state->dev,
134 8 : state->mdscmd_open.unkn2,
135 : 0,
136 : geteuid(),
137 : getegid(),
138 8 : &state->mdscmd_unknown1.status,
139 8 : &state->flags,
140 8 : &state->mdscmd_unknown1.unkn7);
141 8 : torture_assert_ntstatus_ok_goto(tctx, status, ok, done,
142 : "dcerpc_mdssvc_unknown1 failed\n");
143 :
144 8 : done:
145 8 : if (!ok) {
146 0 : (void)dcerpc_mdssvc_close(b,
147 : state,
148 0 : &state->ph,
149 : 0,
150 0 : state->dev,
151 0 : state->mdscmd_open.unkn2,
152 : 0,
153 0 : &state->ph,
154 0 : &state->mdscmd_close.status);
155 0 : ZERO_STRUCT(state);
156 : }
157 8 : return ok;
158 : }
159 :
160 8 : static bool torture_rpc_mdssvc_close(struct torture_context *tctx,
161 : void *data)
162 : {
163 8 : struct torture_mdsscv_state *state = talloc_get_type_abort(
164 : data, struct torture_mdsscv_state);
165 8 : struct dcerpc_binding_handle *b = state->p->binding_handle;
166 : NTSTATUS status;
167 8 : bool ok = true;
168 :
169 8 : torture_comment(tctx, "test_teardown_mdssvc_disconnect\n");
170 :
171 40 : status = dcerpc_mdssvc_close(b,
172 : state,
173 8 : &state->ph,
174 : 0,
175 8 : state->dev,
176 8 : state->mdscmd_open.unkn2,
177 : 0,
178 8 : &state->ph,
179 8 : &state->mdscmd_close.status);
180 8 : torture_assert_ntstatus_ok_goto(tctx, status, ok, done,
181 : "dcerpc_mdssvc_close failed\n");
182 :
183 2 : ZERO_STRUCT(state);
184 :
185 8 : done:
186 8 : return ok;
187 : }
188 :
189 : /*
190 : * Test unknown share name
191 : */
192 2 : static bool test_mdssvc_open_unknown_share(struct torture_context *tctx,
193 : void *data)
194 : {
195 2 : struct torture_mdsscv_state *state = talloc_get_type_abort(
196 : data, struct torture_mdsscv_state);
197 2 : struct dcerpc_binding_handle *b = state->p->binding_handle;
198 : struct policy_handle ph;
199 : struct policy_handle nullh;
200 : uint32_t device_id;
201 : uint32_t unkn2;
202 : uint32_t unkn3;
203 : uint32_t device_id_out;
204 : uint32_t unkn2_out;
205 : uint32_t unkn3_out;
206 2 : const char *share_mount_path = NULL;
207 2 : const char *share_name = NULL;
208 2 : const char share_path[1025] = "X";
209 : NTSTATUS status;
210 2 : bool ok = true;
211 :
212 2 : share_name = torture_setting_string(
213 : tctx, "unknown_share", "choukawoohoo");
214 2 : share_mount_path = torture_setting_string(
215 : tctx, "share_mount_path", "/foo/bar");
216 :
217 2 : device_id_out = device_id = generate_random();
218 2 : unkn2_out = unkn2 = generate_random();
219 2 : unkn3_out = unkn3 = generate_random();
220 :
221 2 : ZERO_STRUCT(ph);
222 2 : ZERO_STRUCT(nullh);
223 :
224 2 : status = dcerpc_mdssvc_open(b,
225 : tctx,
226 : &device_id_out,
227 : &unkn2_out,
228 : &unkn3_out,
229 : share_mount_path,
230 : share_name,
231 : share_path,
232 : &ph);
233 :
234 2 : torture_assert_ntstatus_ok_goto(tctx, status, ok, done,
235 : "dcerpc_mdssvc_open failed\n");
236 :
237 2 : torture_assert_u32_equal_goto(tctx, device_id_out, device_id, ok, done,
238 : "Bad device_id\n");
239 :
240 2 : torture_assert_u32_equal_goto(tctx, unkn2_out, unkn2, ok, done,
241 : "Bad unkn2\n");
242 :
243 2 : torture_assert_u32_equal_goto(tctx, unkn3_out, unkn3, ok, done,
244 : "Bad unkn3\n");
245 :
246 2 : torture_assert_goto(tctx, share_path[0] == '\0', ok, done,
247 : "Expected empty string as share path\n");
248 :
249 2 : torture_assert_mem_equal_goto(tctx, &ph, &nullh,
250 : sizeof(ph), ok, done,
251 : "Expected all-zero policy handle\n");
252 :
253 4 : done:
254 2 : return ok;
255 : }
256 :
257 : /*
258 : * Test on a share where Spotlight is not enabled
259 : */
260 2 : static bool test_mdssvc_open_spotlight_disabled(struct torture_context *tctx,
261 : void *data)
262 : {
263 2 : struct torture_mdsscv_state *state = talloc_get_type_abort(
264 : data, struct torture_mdsscv_state);
265 2 : struct dcerpc_binding_handle *b = state->p->binding_handle;
266 : struct policy_handle ph;
267 2 : const char *localdir = NULL;
268 : uint32_t device_id;
269 : uint32_t unkn2;
270 : uint32_t unkn3;
271 : uint32_t device_id_out;
272 : uint32_t unkn2_out;
273 : uint32_t unkn3_out;
274 2 : const char *share_mount_path = NULL;
275 2 : const char *share_name = NULL;
276 2 : const char share_path[1025] = "";
277 : NTSTATUS status;
278 2 : bool ok = true;
279 :
280 2 : share_name = torture_setting_string(
281 : tctx, "no_spotlight_share", "no_spotlight");
282 2 : share_mount_path = torture_setting_string(
283 : tctx, "share_mount_path", "/foo/bar");
284 :
285 2 : localdir = torture_setting_string(
286 : tctx, "no_spotlight_localdir", NULL);
287 2 : torture_assert_not_null_goto(
288 : tctx, localdir, ok, done,
289 : "need 'no_spotlight_localdir' torture option \n");
290 :
291 2 : device_id_out = device_id = generate_random();
292 2 : unkn2_out = unkn2 = 23;
293 2 : unkn3_out = unkn3 = 0;
294 :
295 2 : ZERO_STRUCT(ph);
296 :
297 2 : status = dcerpc_mdssvc_open(b,
298 : tctx,
299 : &device_id_out,
300 : &unkn2_out,
301 : &unkn3_out,
302 : share_mount_path,
303 : share_name,
304 : share_path,
305 : &ph);
306 2 : torture_assert_ntstatus_ok_goto(tctx, status, ok, done,
307 : "dcerpc_mdssvc_open failed\n");
308 :
309 2 : torture_assert_u32_equal_goto(tctx, device_id, device_id_out, ok, done,
310 : "Bad device_id\n");
311 :
312 2 : torture_assert_u32_equal_goto(tctx, unkn2, unkn2_out,
313 : ok, done, "Bad unkn2\n");
314 :
315 2 : torture_assert_u32_equal_goto(tctx, unkn3, unkn3_out,
316 : ok, done, "Bad unkn3\n");
317 :
318 2 : torture_assert_str_equal_goto(tctx, share_path, localdir, ok, done,
319 : "Wrong share path\n");
320 :
321 4 : done:
322 2 : return ok;
323 : }
324 :
325 2 : static bool test_mdssvc_close(struct torture_context *tctx,
326 : void *data)
327 : {
328 2 : struct torture_mdsscv_state *state = talloc_get_type_abort(
329 : data, struct torture_mdsscv_state);
330 2 : struct dcerpc_binding_handle *b = state->p->binding_handle;
331 : struct policy_handle ph;
332 : struct policy_handle close_ph;
333 : uint32_t device_id;
334 : uint32_t unkn2;
335 : uint32_t unkn3;
336 2 : const char *share_mount_path = NULL;
337 2 : const char *share_name = NULL;
338 2 : const char share_path[1025] = "";
339 : uint32_t close_status;
340 : DATA_BLOB ph_blob;
341 : DATA_BLOB close_ph_blob;
342 : NTSTATUS status;
343 2 : bool ok = true;
344 :
345 2 : share_name = torture_setting_string(
346 : tctx, "spotlight_share", "spotlight");
347 2 : share_mount_path = torture_setting_string(
348 : tctx, "share_mount_path", "/foo/bar");
349 :
350 2 : device_id = generate_random();
351 2 : unkn2 = 23;
352 2 : unkn3 = 0;
353 :
354 2 : ZERO_STRUCT(ph);
355 2 : ZERO_STRUCT(close_ph);
356 :
357 2 : status = dcerpc_mdssvc_open(b,
358 : tctx,
359 : &device_id,
360 : &unkn2,
361 : &unkn3,
362 : share_mount_path,
363 : share_name,
364 : share_path,
365 : &ph);
366 2 : torture_assert_ntstatus_ok_goto(tctx, status, ok, done,
367 : "dcerpc_mdssvc_open failed\n");
368 :
369 2 : status = dcerpc_mdssvc_close(b,
370 : tctx,
371 : &ph,
372 : 0,
373 : device_id,
374 : unkn2,
375 : 0,
376 : &close_ph,
377 : &close_status);
378 2 : torture_assert_ntstatus_ok_goto(tctx, status, ok, done,
379 : "dcerpc_mdssvc_open failed\n");
380 :
381 2 : ph_blob = (DATA_BLOB) {
382 : .data = (uint8_t *)&ph,
383 : .length = sizeof(struct policy_handle)
384 : };
385 2 : close_ph_blob = (DATA_BLOB) {
386 : .data = (uint8_t *)&close_ph,
387 : .length = sizeof(struct policy_handle),
388 : };
389 :
390 2 : torture_assert_data_blob_equal(tctx, close_ph_blob, ph_blob,
391 : "bad blob");
392 :
393 2 : torture_comment(tctx, "Test close with a all-zero handle\n");
394 :
395 2 : ZERO_STRUCT(ph);
396 2 : status = dcerpc_mdssvc_close(b,
397 : tctx,
398 : &ph,
399 : 0,
400 : device_id,
401 : unkn2,
402 : 0,
403 : &close_ph,
404 : &close_status);
405 2 : torture_assert_ntstatus_ok_goto(tctx, status, ok, done,
406 : "dcerpc_mdssvc_close failed\n");
407 :
408 2 : torture_assert_data_blob_equal(tctx, close_ph_blob, ph_blob,
409 : "bad blob");
410 :
411 2 : done:
412 2 : return ok;
413 : }
414 :
415 2 : static bool test_mdssvc_null_ph(struct torture_context *tctx,
416 : void *data)
417 : {
418 2 : struct torture_mdsscv_state *state = talloc_get_type_abort(
419 : data, struct torture_mdsscv_state);
420 2 : struct dcerpc_binding_handle *b = state->p->binding_handle;
421 : struct policy_handle nullh;
422 : struct policy_handle ph;
423 : uint32_t device_id;
424 : uint32_t unkn2;
425 : uint32_t unkn7;
426 : uint32_t cmd_status;
427 : uint32_t flags;
428 : NTSTATUS status;
429 2 : bool ok = true;
430 :
431 2 : device_id = generate_random();
432 2 : unkn2 = 23;
433 2 : unkn7 = 0;
434 2 : cmd_status = 0;
435 :
436 2 : ZERO_STRUCT(nullh);
437 2 : ZERO_STRUCT(ph);
438 :
439 2 : status = dcerpc_mdssvc_unknown1(b,
440 : tctx,
441 : &ph,
442 : 0,
443 : device_id,
444 : unkn2,
445 : 0,
446 : geteuid(),
447 : getegid(),
448 : &cmd_status,
449 : &flags,
450 : &unkn7);
451 2 : torture_assert_ntstatus_ok_goto(tctx, status, ok, done,
452 : "dcerpc_mdssvc_unknown1 failed\n");
453 :
454 2 : torture_assert_mem_equal_goto(tctx, &ph, &nullh,
455 : sizeof(ph), ok, done,
456 : "Expected all-zero policy handle\n");
457 :
458 4 : done:
459 2 : return ok;
460 : }
461 :
462 2 : static bool test_mdssvc_invalid_ph_unknown1(struct torture_context *tctx,
463 : void *data)
464 : {
465 2 : struct torture_mdsscv_state *state = talloc_get_type_abort(
466 : data, struct torture_mdsscv_state);
467 2 : struct dcerpc_binding_handle *b = state->p->binding_handle;
468 : struct policy_handle ph;
469 : uint32_t device_id;
470 : uint32_t unkn2;
471 : uint32_t unkn7;
472 : uint32_t cmd_status;
473 : uint32_t flags;
474 : NTSTATUS status;
475 2 : bool ok = true;
476 :
477 2 : device_id = generate_random();
478 2 : unkn2 = 23;
479 2 : unkn7 = 0;
480 2 : cmd_status = 0;
481 :
482 2 : ZERO_STRUCT(ph);
483 2 : ph.uuid = GUID_random();
484 :
485 2 : status = dcerpc_mdssvc_unknown1(b,
486 : tctx,
487 : &ph,
488 : 0,
489 : device_id,
490 : unkn2,
491 : 0,
492 : geteuid(),
493 : getegid(),
494 : &cmd_status,
495 : &flags,
496 : &unkn7);
497 2 : torture_assert_ntstatus_equal_goto(
498 : tctx, status, NT_STATUS_RPC_PROTOCOL_ERROR, ok, done,
499 : "dcerpc_mdssvc_unknown1 failed\n");
500 :
501 2 : done:
502 2 : return ok;
503 : }
504 :
505 2 : static bool test_mdssvc_invalid_ph_cmd(struct torture_context *tctx,
506 : void *data)
507 : {
508 2 : struct torture_mdsscv_state *state = talloc_get_type_abort(
509 : data, struct torture_mdsscv_state);
510 2 : struct dcerpc_binding_handle *b = state->p->binding_handle;
511 : struct policy_handle ph;
512 : struct mdssvc_blob request_blob;
513 : struct mdssvc_blob response_blob;
514 : uint32_t device_id;
515 : uint32_t unkn2;
516 : uint32_t unkn9;
517 : uint32_t fragment;
518 : uint32_t flags;
519 : NTSTATUS status;
520 2 : bool ok = true;
521 :
522 2 : device_id = generate_random();
523 2 : unkn2 = 23;
524 2 : unkn9 = 0;
525 2 : fragment = 0;
526 2 : flags = UINT32_C(0x6b000001);
527 :
528 2 : ZERO_STRUCT(ph);
529 2 : ph.uuid = GUID_random();
530 :
531 2 : request_blob.spotlight_blob = talloc_array(state,
532 : uint8_t,
533 : 0);
534 2 : torture_assert_not_null_goto(tctx, request_blob.spotlight_blob,
535 : ok, done, "dalloc_zero failed\n");
536 2 : request_blob.size = 0;
537 2 : request_blob.length = 0;
538 2 : request_blob.size = 0;
539 :
540 2 : response_blob.spotlight_blob = talloc_array(state,
541 : uint8_t,
542 : 0);
543 2 : torture_assert_not_null_goto(tctx, response_blob.spotlight_blob,
544 : ok, done, "dalloc_zero failed\n");
545 2 : response_blob.size = 0;
546 :
547 2 : status = dcerpc_mdssvc_cmd(b,
548 : state,
549 : &ph,
550 : 0,
551 : device_id,
552 : unkn2,
553 : 0,
554 : flags,
555 : request_blob,
556 : 0,
557 : 64 * 1024,
558 : 1,
559 : 64 * 1024,
560 : 0,
561 : 0,
562 : &fragment,
563 : &response_blob,
564 : &unkn9);
565 2 : torture_assert_ntstatus_equal_goto(
566 : tctx, status, NT_STATUS_RPC_PROTOCOL_ERROR, ok, done,
567 : "dcerpc_mdssvc_unknown1 failed\n");
568 :
569 2 : done:
570 2 : return ok;
571 : }
572 :
573 2 : static bool test_mdssvc_invalid_ph_close(struct torture_context *tctx,
574 : void *data)
575 : {
576 2 : struct torture_mdsscv_state *state = talloc_get_type_abort(
577 : data, struct torture_mdsscv_state);
578 2 : struct dcerpc_binding_handle *b = state->p->binding_handle;
579 : struct policy_handle ph;
580 : uint32_t device_id;
581 : uint32_t unkn2;
582 : uint32_t close_status;
583 : NTSTATUS status;
584 2 : bool ok = true;
585 :
586 2 : device_id = generate_random();
587 2 : unkn2 = 23;
588 2 : close_status = 0;
589 :
590 2 : ZERO_STRUCT(ph);
591 2 : ph.uuid = GUID_random();
592 :
593 2 : status = dcerpc_mdssvc_close(b,
594 : state,
595 : &ph,
596 : 0,
597 : device_id,
598 : unkn2,
599 : 0,
600 : &ph,
601 : &close_status);
602 2 : torture_assert_ntstatus_equal_goto(
603 : tctx, status, NT_STATUS_RPC_PROTOCOL_ERROR, ok, done,
604 : "dcerpc_mdssvc_unknown1 failed\n");
605 :
606 2 : done:
607 2 : return ok;
608 : }
609 :
610 : /*
611 : * Test fetchAttributes with unknown CNID
612 : */
613 2 : static bool test_mdssvc_fetch_attr_unknown_cnid(struct torture_context *tctx,
614 : void *data)
615 : {
616 2 : struct torture_mdsscv_state *state = talloc_get_type_abort(
617 : data, struct torture_mdsscv_state);
618 2 : struct dcerpc_binding_handle *b = state->p->binding_handle;
619 2 : uint32_t max_fragment_size = 64 * 1024;
620 : struct mdssvc_blob request_blob;
621 : struct mdssvc_blob response_blob;
622 2 : DALLOC_CTX *d = NULL, *mds_reply = NULL;
623 2 : uint64_t *uint64var = NULL;
624 2 : sl_array_t *array = NULL;
625 2 : sl_array_t *cmd_array = NULL;
626 2 : sl_array_t *attr_array = NULL;
627 2 : sl_cnids_t *cnids = NULL;
628 2 : void *path = NULL;
629 2 : const char *path_type = NULL;
630 : uint64_t ino64;
631 : NTSTATUS status;
632 : ssize_t len;
633 : int ret;
634 2 : bool ok = true;
635 :
636 2 : d = dalloc_new(state);
637 2 : torture_assert_not_null_goto(tctx, d, ret, done, "dalloc_new failed\n");
638 :
639 2 : array = dalloc_zero(d, sl_array_t);
640 2 : torture_assert_not_null_goto(tctx, array, ret, done,
641 : "dalloc_zero failed\n");
642 :
643 2 : ret = dalloc_add(d, array, sl_array_t);
644 2 : torture_assert_goto(tctx, ret == 0, ret, done, "dalloc_add failed\n");
645 :
646 2 : cmd_array = dalloc_zero(d, sl_array_t);
647 2 : torture_assert_not_null_goto(tctx, cmd_array, ret, done,
648 : "dalloc_zero failed\n");
649 :
650 2 : ret = dalloc_add(array, cmd_array, sl_array_t);
651 2 : torture_assert_goto(tctx, ret == 0, ret, done, "dalloc_add failed\n");
652 :
653 2 : ret = dalloc_stradd(cmd_array, "fetchAttributes:forOIDArray:context:");
654 2 : torture_assert_goto(tctx, ret == 0, ret, done, "dalloc_stradd failed\n");
655 :
656 2 : uint64var = talloc_zero_array(cmd_array, uint64_t, 2);
657 2 : torture_assert_not_null_goto(tctx, uint64var, ret, done,
658 : "talloc_zero_array failed\n");
659 2 : talloc_set_name(uint64var, "uint64_t *");
660 :
661 2 : uint64var[0] = 0x500a;
662 2 : uint64var[1] = 0;
663 :
664 2 : ret = dalloc_add(cmd_array, &uint64var[0], uint64_t *);
665 2 : torture_assert_goto(tctx, ret == 0, ret, done, "dalloc_add failed\n");
666 :
667 2 : attr_array = dalloc_zero(d, sl_array_t);
668 2 : torture_assert_not_null_goto(tctx, attr_array, ret, done,
669 : "dalloc_zero failed\n");
670 :
671 2 : ret = dalloc_add(array, attr_array, sl_array_t);
672 2 : torture_assert_goto(tctx, ret == 0, ret, done, "dalloc_add failed\n");
673 :
674 2 : ret = dalloc_stradd(attr_array, "kMDItemPath");
675 2 : torture_assert_goto(tctx, ret == 0, ret, done, "dalloc_stradd failed\n");
676 :
677 : /* CNIDs */
678 2 : cnids = talloc_zero(array, sl_cnids_t);
679 2 : torture_assert_not_null_goto(tctx, cnids, ret, done,
680 : "talloc_zero failed\n");
681 :
682 2 : cnids->ca_cnids = dalloc_new(cnids);
683 2 : torture_assert_not_null_goto(tctx, cnids->ca_cnids, ret, done,
684 : "dalloc_new failed\n");
685 :
686 2 : cnids->ca_unkn1 = 0xadd;
687 2 : cnids->ca_context = 0x6b000020;
688 :
689 2 : ino64 = UINT64_C(64382947389618974);
690 2 : ret = dalloc_add_copy(cnids->ca_cnids, &ino64, uint64_t);
691 2 : torture_assert_goto(tctx, ret == 0, ret, done,
692 : "dalloc_add_copy failed\n");
693 :
694 2 : ret = dalloc_add(array, cnids, sl_cnids_t);
695 2 : torture_assert_goto(tctx, ret == 0, ret, done, "dalloc_add failed\n");
696 :
697 2 : request_blob.spotlight_blob = talloc_array(state,
698 : uint8_t,
699 : max_fragment_size);
700 2 : torture_assert_not_null_goto(tctx, request_blob.spotlight_blob,
701 : ret, done, "dalloc_zero failed\n");
702 2 : request_blob.size = max_fragment_size;
703 :
704 2 : response_blob.spotlight_blob = talloc_array(state,
705 : uint8_t,
706 : max_fragment_size);
707 2 : torture_assert_not_null_goto(tctx, response_blob.spotlight_blob,
708 : ret, done, "dalloc_zero failed\n");
709 2 : response_blob.size = max_fragment_size;
710 :
711 2 : len = sl_pack(d, (char *)request_blob.spotlight_blob, request_blob.size);
712 2 : torture_assert_goto(tctx, len != -1, ret, done, "sl_pack failed\n");
713 :
714 2 : request_blob.length = len;
715 2 : request_blob.size = len;
716 :
717 2 : status = dcerpc_mdssvc_cmd(b,
718 : state,
719 : &state->ph,
720 : 0,
721 : state->dev,
722 : state->mdscmd_open.unkn2,
723 : 0,
724 : state->flags,
725 : request_blob,
726 : 0,
727 : max_fragment_size,
728 : 1,
729 : max_fragment_size,
730 : 0,
731 : 0,
732 : &state->mdscmd_cmd.fragment,
733 : &response_blob,
734 : &state->mdscmd_cmd.unkn9);
735 2 : torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
736 : "dcerpc_mdssvc_cmd failed\n");
737 :
738 2 : mds_reply = dalloc_new(state);
739 2 : torture_assert_not_null_goto(tctx, mds_reply, ret, done,
740 : "dalloc_zero failed\n");
741 :
742 4 : ok = sl_unpack(mds_reply,
743 2 : (char *)response_blob.spotlight_blob,
744 2 : response_blob.length);
745 2 : torture_assert_goto(tctx, ok, ret, done, "dalloc_add failed\n");
746 :
747 2 : torture_comment(tctx, "%s", dalloc_dump(mds_reply, 0));
748 :
749 2 : path = dalloc_get(mds_reply,
750 : "DALLOC_CTX", 0,
751 : "DALLOC_CTX", 2,
752 : "DALLOC_CTX", 0,
753 : "sl_nil_t", 1);
754 2 : torture_assert_not_null_goto(tctx, path, ret, done,
755 : "dalloc_get path failed\n");
756 :
757 2 : path_type = talloc_get_name(path);
758 :
759 2 : torture_assert_str_equal_goto(tctx, path_type, "sl_nil_t", ret, done,
760 : "Wrong dalloc object type\n");
761 :
762 4 : done:
763 2 : return ok;
764 : }
765 :
766 2355 : struct torture_suite *torture_rpc_mdssvc(TALLOC_CTX *mem_ctx)
767 : {
768 2355 : struct torture_suite *suite = torture_suite_create(
769 : mem_ctx, "mdssvc");
770 2355 : struct torture_tcase *tcase = NULL;
771 :
772 2355 : tcase = torture_suite_add_tcase(suite, "rpccmd");
773 2355 : if (tcase == NULL) {
774 0 : return NULL;
775 : }
776 2355 : torture_tcase_set_fixture(tcase,
777 : torture_rpc_mdssvc_setup,
778 : torture_rpc_mdssvc_teardown);
779 :
780 2355 : torture_tcase_add_simple_test(tcase,
781 : "open_unknown_share",
782 : test_mdssvc_open_unknown_share);
783 :
784 2355 : torture_tcase_add_simple_test(tcase,
785 : "open_spotlight_disabled",
786 : test_mdssvc_open_spotlight_disabled);
787 :
788 2355 : torture_tcase_add_simple_test(tcase,
789 : "close",
790 : test_mdssvc_close);
791 :
792 2355 : torture_tcase_add_simple_test(tcase,
793 : "null_ph",
794 : test_mdssvc_null_ph);
795 :
796 2355 : tcase = torture_suite_add_tcase(suite, "disconnect1");
797 2355 : if (tcase == NULL) {
798 0 : return NULL;
799 : }
800 2355 : torture_tcase_set_fixture(tcase,
801 : torture_rpc_mdssvc_open,
802 : torture_rpc_mdssvc_close);
803 :
804 2355 : torture_tcase_add_simple_test(tcase,
805 : "invalid_ph_unknown1",
806 : test_mdssvc_invalid_ph_unknown1);
807 :
808 2355 : tcase = torture_suite_add_tcase(suite, "disconnect2");
809 2355 : if (tcase == NULL) {
810 0 : return NULL;
811 : }
812 2355 : torture_tcase_set_fixture(tcase,
813 : torture_rpc_mdssvc_open,
814 : torture_rpc_mdssvc_close);
815 :
816 2355 : torture_tcase_add_simple_test(tcase,
817 : "invalid_ph_cmd",
818 : test_mdssvc_invalid_ph_cmd);
819 :
820 2355 : tcase = torture_suite_add_tcase(suite, "disconnect3");
821 2355 : if (tcase == NULL) {
822 0 : return NULL;
823 : }
824 2355 : torture_tcase_set_fixture(tcase,
825 : torture_rpc_mdssvc_open,
826 : torture_rpc_mdssvc_close);
827 :
828 2355 : torture_tcase_add_simple_test(tcase,
829 : "invalid_ph_close",
830 : test_mdssvc_invalid_ph_close);
831 :
832 2355 : tcase = torture_suite_add_tcase(suite, "mdscmd");
833 2355 : if (tcase == NULL) {
834 0 : return NULL;
835 : }
836 2355 : torture_tcase_set_fixture(tcase,
837 : torture_rpc_mdssvc_open,
838 : torture_rpc_mdssvc_close);
839 :
840 2355 : torture_tcase_add_simple_test(tcase,
841 : "fetch_unknown_cnid",
842 : test_mdssvc_fetch_attr_unknown_cnid);
843 :
844 2355 : return suite;
845 : }
|