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 0 : static bool torture_rpc_mdssvc_setup(struct torture_context *tctx,
58 : void **data)
59 : {
60 0 : struct torture_mdsscv_state *state = NULL;
61 : NTSTATUS status;
62 :
63 0 : state = talloc_zero(tctx, struct torture_mdsscv_state);
64 0 : if (state == NULL) {
65 0 : return false;
66 : }
67 0 : *data = state;
68 :
69 0 : status = torture_rpc_connection(tctx, &state->p, &ndr_table_mdssvc);
70 0 : torture_assert_ntstatus_ok(tctx, status, "Error connecting to server");
71 :
72 0 : return true;
73 : }
74 :
75 0 : static bool torture_rpc_mdssvc_teardown(struct torture_context *tctx,
76 : void *data)
77 : {
78 0 : struct torture_mdsscv_state *state = talloc_get_type_abort(
79 : data, struct torture_mdsscv_state);
80 :
81 0 : TALLOC_FREE(state->p);
82 0 : TALLOC_FREE(state);
83 0 : return true;
84 : }
85 :
86 0 : static bool torture_rpc_mdssvc_open(struct torture_context *tctx,
87 : void **data)
88 : {
89 0 : struct torture_mdsscv_state *state = NULL;
90 0 : struct dcerpc_binding_handle *b = NULL;
91 0 : const char *share_name = NULL;
92 0 : const char *share_mount_path = NULL;
93 : NTSTATUS status;
94 0 : bool ok = true;
95 :
96 0 : state = talloc_zero(tctx, struct torture_mdsscv_state);
97 0 : if (state == NULL) {
98 0 : return false;
99 : }
100 0 : *data = state;
101 :
102 0 : status = torture_rpc_connection(tctx, &state->p, &ndr_table_mdssvc);
103 0 : torture_assert_ntstatus_ok(tctx, status, "Error connecting to server");
104 0 : b = state->p->binding_handle;
105 :
106 0 : share_name = torture_setting_string(
107 : tctx, "spotlight_share", "spotlight");
108 0 : share_mount_path = torture_setting_string(
109 : tctx, "share_mount_path", "/foo/bar");
110 :
111 0 : state->dev = generate_random();
112 0 : state->mdscmd_open.unkn2 = 23;
113 0 : state->mdscmd_open.unkn3 = 0;
114 :
115 0 : ZERO_STRUCT(state->ph);
116 :
117 0 : status = dcerpc_mdssvc_open(b,
118 : state,
119 0 : &state->dev,
120 0 : &state->mdscmd_open.unkn2,
121 0 : &state->mdscmd_open.unkn3,
122 : share_mount_path,
123 : share_name,
124 0 : state->mdscmd_open.share_path,
125 0 : &state->ph);
126 0 : torture_assert_ntstatus_ok_goto(tctx, status, ok, done,
127 : "dcerpc_mdssvc_open failed\n");
128 :
129 0 : status = dcerpc_mdssvc_unknown1(b,
130 : state,
131 0 : &state->ph,
132 : 0,
133 0 : state->dev,
134 0 : state->mdscmd_open.unkn2,
135 : 0,
136 : geteuid(),
137 : getegid(),
138 0 : &state->mdscmd_unknown1.status,
139 0 : &state->flags,
140 0 : &state->mdscmd_unknown1.unkn7);
141 0 : torture_assert_ntstatus_ok_goto(tctx, status, ok, done,
142 : "dcerpc_mdssvc_unknown1 failed\n");
143 :
144 0 : done:
145 0 : 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 0 : return ok;
158 : }
159 :
160 0 : static bool torture_rpc_mdssvc_close(struct torture_context *tctx,
161 : void *data)
162 : {
163 0 : struct torture_mdsscv_state *state = talloc_get_type_abort(
164 : data, struct torture_mdsscv_state);
165 0 : struct dcerpc_binding_handle *b = state->p->binding_handle;
166 : NTSTATUS status;
167 0 : bool ok = true;
168 :
169 0 : torture_comment(tctx, "test_teardown_mdssvc_disconnect\n");
170 :
171 0 : status = dcerpc_mdssvc_close(b,
172 : state,
173 0 : &state->ph,
174 : 0,
175 0 : state->dev,
176 0 : state->mdscmd_open.unkn2,
177 : 0,
178 0 : &state->ph,
179 0 : &state->mdscmd_close.status);
180 0 : torture_assert_ntstatus_ok_goto(tctx, status, ok, done,
181 : "dcerpc_mdssvc_close failed\n");
182 :
183 0 : ZERO_STRUCT(state);
184 :
185 0 : done:
186 0 : return ok;
187 : }
188 :
189 : /*
190 : * Test unknown share name
191 : */
192 0 : static bool test_mdssvc_open_unknown_share(struct torture_context *tctx,
193 : void *data)
194 : {
195 0 : struct torture_mdsscv_state *state = talloc_get_type_abort(
196 : data, struct torture_mdsscv_state);
197 0 : 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 0 : const char *share_mount_path = NULL;
207 0 : const char *share_name = NULL;
208 0 : const char share_path[1025] = "X";
209 : NTSTATUS status;
210 0 : bool ok = true;
211 :
212 0 : share_name = torture_setting_string(
213 : tctx, "unknown_share", "choukawoohoo");
214 0 : share_mount_path = torture_setting_string(
215 : tctx, "share_mount_path", "/foo/bar");
216 :
217 0 : device_id_out = device_id = generate_random();
218 0 : unkn2_out = unkn2 = generate_random();
219 0 : unkn3_out = unkn3 = generate_random();
220 :
221 0 : ZERO_STRUCT(ph);
222 0 : ZERO_STRUCT(nullh);
223 :
224 0 : 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 0 : torture_assert_ntstatus_ok_goto(tctx, status, ok, done,
235 : "dcerpc_mdssvc_open failed\n");
236 :
237 0 : torture_assert_u32_equal_goto(tctx, device_id_out, device_id, ok, done,
238 : "Bad device_id\n");
239 :
240 0 : torture_assert_u32_equal_goto(tctx, unkn2_out, unkn2, ok, done,
241 : "Bad unkn2\n");
242 :
243 0 : torture_assert_u32_equal_goto(tctx, unkn3_out, unkn3, ok, done,
244 : "Bad unkn3\n");
245 :
246 0 : torture_assert_goto(tctx, share_path[0] == '\0', ok, done,
247 : "Expected empty string as share path\n");
248 :
249 0 : torture_assert_mem_equal_goto(tctx, &ph, &nullh,
250 : sizeof(ph), ok, done,
251 : "Expected all-zero policy handle\n");
252 :
253 0 : done:
254 0 : return ok;
255 : }
256 :
257 : /*
258 : * Test on a share where Spotlight is not enabled
259 : */
260 0 : static bool test_mdssvc_open_spotlight_disabled(struct torture_context *tctx,
261 : void *data)
262 : {
263 0 : struct torture_mdsscv_state *state = talloc_get_type_abort(
264 : data, struct torture_mdsscv_state);
265 0 : struct dcerpc_binding_handle *b = state->p->binding_handle;
266 : struct policy_handle ph;
267 : struct policy_handle nullh;
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 0 : const char *share_mount_path = NULL;
275 0 : const char *share_name = NULL;
276 0 : const char share_path[1025] = "";
277 : NTSTATUS status;
278 0 : bool ok = true;
279 :
280 0 : share_name = torture_setting_string(
281 : tctx, "no_spotlight_share", "no_spotlight");
282 0 : share_mount_path = torture_setting_string(
283 : tctx, "share_mount_path", "/foo/bar");
284 :
285 0 : device_id_out = device_id = generate_random();
286 0 : unkn2_out = unkn2 = 23;
287 0 : unkn3_out = unkn3 = 0;
288 :
289 0 : ZERO_STRUCT(ph);
290 0 : ZERO_STRUCT(nullh);
291 :
292 0 : status = dcerpc_mdssvc_open(b,
293 : tctx,
294 : &device_id_out,
295 : &unkn2_out,
296 : &unkn3_out,
297 : share_mount_path,
298 : share_name,
299 : share_path,
300 : &ph);
301 0 : torture_assert_ntstatus_ok_goto(tctx, status, ok, done,
302 : "dcerpc_mdssvc_open failed\n");
303 :
304 0 : torture_assert_u32_equal_goto(tctx, device_id, device_id_out, ok, done,
305 : "Bad device_id\n");
306 :
307 0 : torture_assert_u32_equal_goto(tctx, unkn2, unkn2_out,
308 : ok, done, "Bad unkn2\n");
309 :
310 0 : torture_assert_u32_equal_goto(tctx, unkn3, unkn3_out,
311 : ok, done, "Bad unkn3\n");
312 :
313 0 : torture_assert_goto(tctx, share_path[0] == '\0', ok, done,
314 : "Expected empty string as share path\n");
315 :
316 0 : torture_assert_mem_equal_goto(tctx, &ph, &nullh,
317 : sizeof(ph), ok, done,
318 : "Expected all-zero policy handle\n");
319 :
320 0 : done:
321 0 : return ok;
322 : }
323 :
324 0 : static bool test_mdssvc_close(struct torture_context *tctx,
325 : void *data)
326 : {
327 0 : struct torture_mdsscv_state *state = talloc_get_type_abort(
328 : data, struct torture_mdsscv_state);
329 0 : struct dcerpc_binding_handle *b = state->p->binding_handle;
330 : struct policy_handle ph;
331 : struct policy_handle close_ph;
332 : uint32_t device_id;
333 : uint32_t unkn2;
334 : uint32_t unkn3;
335 0 : const char *share_mount_path = NULL;
336 0 : const char *share_name = NULL;
337 0 : const char share_path[1025] = "";
338 : uint32_t close_status;
339 : DATA_BLOB ph_blob;
340 : DATA_BLOB close_ph_blob;
341 : NTSTATUS status;
342 0 : bool ok = true;
343 :
344 0 : share_name = torture_setting_string(
345 : tctx, "spotlight_share", "spotlight");
346 0 : share_mount_path = torture_setting_string(
347 : tctx, "share_mount_path", "/foo/bar");
348 :
349 0 : device_id = generate_random();
350 0 : unkn2 = 23;
351 0 : unkn3 = 0;
352 :
353 0 : ZERO_STRUCT(ph);
354 0 : ZERO_STRUCT(close_ph);
355 :
356 0 : status = dcerpc_mdssvc_open(b,
357 : tctx,
358 : &device_id,
359 : &unkn2,
360 : &unkn3,
361 : share_mount_path,
362 : share_name,
363 : share_path,
364 : &ph);
365 0 : torture_assert_ntstatus_ok_goto(tctx, status, ok, done,
366 : "dcerpc_mdssvc_open failed\n");
367 :
368 0 : status = dcerpc_mdssvc_close(b,
369 : tctx,
370 : &ph,
371 : 0,
372 : device_id,
373 : unkn2,
374 : 0,
375 : &close_ph,
376 : &close_status);
377 0 : torture_assert_ntstatus_ok_goto(tctx, status, ok, done,
378 : "dcerpc_mdssvc_open failed\n");
379 :
380 0 : ph_blob = (DATA_BLOB) {
381 : .data = (uint8_t *)&ph,
382 : .length = sizeof(struct policy_handle)
383 : };
384 0 : close_ph_blob = (DATA_BLOB) {
385 : .data = (uint8_t *)&close_ph,
386 : .length = sizeof(struct policy_handle),
387 : };
388 :
389 0 : torture_assert_data_blob_equal(tctx, close_ph_blob, ph_blob,
390 : "bad blob");
391 :
392 0 : torture_comment(tctx, "Test close with a all-zero handle\n");
393 :
394 0 : ZERO_STRUCT(ph);
395 0 : status = dcerpc_mdssvc_close(b,
396 : tctx,
397 : &ph,
398 : 0,
399 : device_id,
400 : unkn2,
401 : 0,
402 : &close_ph,
403 : &close_status);
404 0 : torture_assert_ntstatus_ok_goto(tctx, status, ok, done,
405 : "dcerpc_mdssvc_close failed\n");
406 :
407 0 : torture_assert_data_blob_equal(tctx, close_ph_blob, ph_blob,
408 : "bad blob");
409 :
410 0 : done:
411 0 : return ok;
412 : }
413 :
414 0 : static bool test_mdssvc_null_ph(struct torture_context *tctx,
415 : void *data)
416 : {
417 0 : struct torture_mdsscv_state *state = talloc_get_type_abort(
418 : data, struct torture_mdsscv_state);
419 0 : struct dcerpc_binding_handle *b = state->p->binding_handle;
420 : struct policy_handle nullh;
421 : struct policy_handle ph;
422 : uint32_t device_id;
423 : uint32_t unkn2;
424 : uint32_t unkn7;
425 : uint32_t cmd_status;
426 : uint32_t flags;
427 : NTSTATUS status;
428 0 : bool ok = true;
429 :
430 0 : device_id = generate_random();
431 0 : unkn2 = 23;
432 0 : unkn7 = 0;
433 0 : cmd_status = 0;
434 :
435 0 : ZERO_STRUCT(nullh);
436 0 : ZERO_STRUCT(ph);
437 :
438 0 : status = dcerpc_mdssvc_unknown1(b,
439 : tctx,
440 : &ph,
441 : 0,
442 : device_id,
443 : unkn2,
444 : 0,
445 : geteuid(),
446 : getegid(),
447 : &cmd_status,
448 : &flags,
449 : &unkn7);
450 0 : torture_assert_ntstatus_ok_goto(tctx, status, ok, done,
451 : "dcerpc_mdssvc_unknown1 failed\n");
452 :
453 0 : torture_assert_mem_equal_goto(tctx, &ph, &nullh,
454 : sizeof(ph), ok, done,
455 : "Expected all-zero policy handle\n");
456 :
457 0 : done:
458 0 : return ok;
459 : }
460 :
461 0 : static bool test_mdssvc_invalid_ph_unknown1(struct torture_context *tctx,
462 : void *data)
463 : {
464 0 : struct torture_mdsscv_state *state = talloc_get_type_abort(
465 : data, struct torture_mdsscv_state);
466 0 : struct dcerpc_binding_handle *b = state->p->binding_handle;
467 : struct policy_handle ph;
468 : uint32_t device_id;
469 : uint32_t unkn2;
470 : uint32_t unkn7;
471 : uint32_t cmd_status;
472 : uint32_t flags;
473 : NTSTATUS status;
474 0 : bool ok = true;
475 :
476 0 : device_id = generate_random();
477 0 : unkn2 = 23;
478 0 : unkn7 = 0;
479 0 : cmd_status = 0;
480 :
481 0 : ZERO_STRUCT(ph);
482 0 : ph.uuid = GUID_random();
483 :
484 0 : status = dcerpc_mdssvc_unknown1(b,
485 : tctx,
486 : &ph,
487 : 0,
488 : device_id,
489 : unkn2,
490 : 0,
491 : geteuid(),
492 : getegid(),
493 : &cmd_status,
494 : &flags,
495 : &unkn7);
496 0 : torture_assert_ntstatus_equal_goto(
497 : tctx, status, NT_STATUS_RPC_PROTOCOL_ERROR, ok, done,
498 : "dcerpc_mdssvc_unknown1 failed\n");
499 :
500 0 : done:
501 0 : return ok;
502 : }
503 :
504 0 : static bool test_mdssvc_invalid_ph_cmd(struct torture_context *tctx,
505 : void *data)
506 : {
507 0 : struct torture_mdsscv_state *state = talloc_get_type_abort(
508 : data, struct torture_mdsscv_state);
509 0 : struct dcerpc_binding_handle *b = state->p->binding_handle;
510 : struct policy_handle ph;
511 : struct mdssvc_blob request_blob;
512 : struct mdssvc_blob response_blob;
513 : uint32_t device_id;
514 : uint32_t unkn2;
515 : uint32_t unkn9;
516 : uint32_t fragment;
517 : uint32_t flags;
518 : NTSTATUS status;
519 0 : bool ok = true;
520 :
521 0 : device_id = generate_random();
522 0 : unkn2 = 23;
523 0 : unkn9 = 0;
524 0 : fragment = 0;
525 0 : flags = UINT32_C(0x6b000001);
526 :
527 0 : ZERO_STRUCT(ph);
528 0 : ph.uuid = GUID_random();
529 :
530 0 : request_blob.spotlight_blob = talloc_array(state,
531 : uint8_t,
532 : 0);
533 0 : torture_assert_not_null_goto(tctx, request_blob.spotlight_blob,
534 : ok, done, "dalloc_zero failed\n");
535 0 : request_blob.size = 0;
536 0 : request_blob.length = 0;
537 0 : request_blob.size = 0;
538 :
539 0 : status = dcerpc_mdssvc_cmd(b,
540 : state,
541 : &ph,
542 : 0,
543 : device_id,
544 : unkn2,
545 : 0,
546 : flags,
547 : request_blob,
548 : 0,
549 : 64 * 1024,
550 : 1,
551 : 64 * 1024,
552 : 0,
553 : 0,
554 : &fragment,
555 : &response_blob,
556 : &unkn9);
557 0 : torture_assert_ntstatus_equal_goto(
558 : tctx, status, NT_STATUS_RPC_PROTOCOL_ERROR, ok, done,
559 : "dcerpc_mdssvc_unknown1 failed\n");
560 :
561 0 : done:
562 0 : return ok;
563 : }
564 :
565 : static uint8_t test_sl_unpack_loop_buf[] = {
566 : 0x34, 0x33, 0x32, 0x31, 0x33, 0x30, 0x64, 0x6d,
567 : 0x1d, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00,
568 : 0x01, 0x00, 0x00, 0x02, 0x01, 0x00, 0x00, 0x00,
569 : 0x01, 0x00, 0x00, 0x02, 0x02, 0x00, 0x00, 0x00,
570 : 0x01, 0x00, 0x00, 0x02, 0x03, 0x00, 0x00, 0x00,
571 : 0x06, 0x00, 0x00, 0x07, 0x04, 0x00, 0x00, 0x00,
572 : 0x66, 0x65, 0x74, 0x63, 0x68, 0x41, 0x74, 0x74,
573 : 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x3a,
574 : 0x66, 0x6f, 0x72, 0x4f, 0x49, 0x44, 0x41, 0x72,
575 : 0x72, 0x61, 0x79, 0x3a, 0x63, 0x6f, 0x6e, 0x74,
576 : 0x65, 0x78, 0x74, 0x3a, 0x00, 0x00, 0x00, 0xea,
577 : 0x02, 0x00, 0x00, 0x84, 0x02, 0x00, 0x00, 0x00,
578 : 0x0a, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
579 : 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
580 : 0x01, 0x00, 0x00, 0x02, 0x04, 0x00, 0x00, 0x00,
581 : 0x01, 0x00, 0x00, 0x02, 0x05, 0x00, 0x00, 0x00,
582 : 0x03, 0x00, 0x00, 0x07, 0x03, 0x00, 0x00, 0x00,
583 : 0x6b, 0x4d, 0x44, 0x49, 0x74, 0x65, 0x6d, 0x50,
584 : 0x61, 0x74, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00,
585 : 0x01, 0x00, 0x00, 0x02, 0x06, 0x00, 0x00, 0x00,
586 : 0x03, 0x00, 0x00, 0x87, 0x08, 0x00, 0x00, 0x00,
587 : 0x01, 0x00, 0xdd, 0x0a, 0x20, 0x00, 0x00, 0x6b,
588 : 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
589 : 0x07, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00, 0x00,
590 : 0x02, 0x00, 0x00, 0x0a, 0x03, 0x00, 0x00, 0x00,
591 : 0x03, 0x00, 0x00, 0x0a, 0x03, 0x00, 0x00, 0x00,
592 : 0x04, 0x00, 0x00, 0x0c, 0x04, 0x00, 0x00, 0x00,
593 : 0x0e, 0x00, 0x00, 0x0a, 0x01, 0x00, 0x00, 0x00,
594 : 0x0f, 0x00, 0x00, 0x0c, 0x03, 0x00, 0x00, 0x00,
595 : 0x13, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x00,
596 : 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
597 : 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00,
598 : 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
599 : 0x00, 0x00, 0x00, 0x00
600 : };
601 :
602 0 : static bool test_mdssvc_sl_unpack_loop(struct torture_context *tctx,
603 : void *data)
604 : {
605 0 : struct torture_mdsscv_state *state = talloc_get_type_abort(
606 : data, struct torture_mdsscv_state);
607 0 : struct dcerpc_binding_handle *b = state->p->binding_handle;
608 : struct mdssvc_blob request_blob;
609 : struct mdssvc_blob response_blob;
610 : uint32_t device_id;
611 : uint32_t unkn2;
612 : uint32_t unkn9;
613 : uint32_t fragment;
614 : uint32_t flags;
615 : NTSTATUS status;
616 0 : bool ok = true;
617 :
618 0 : device_id = UINT32_C(0x2f000045);
619 0 : unkn2 = 23;
620 0 : unkn9 = 0;
621 0 : fragment = 0;
622 0 : flags = UINT32_C(0x6b000001);
623 :
624 0 : request_blob.spotlight_blob = test_sl_unpack_loop_buf;
625 0 : request_blob.size = sizeof(test_sl_unpack_loop_buf);
626 0 : request_blob.length = sizeof(test_sl_unpack_loop_buf);
627 :
628 0 : status = dcerpc_mdssvc_cmd(b,
629 : state,
630 : &state->ph,
631 : 0,
632 : device_id,
633 : unkn2,
634 : 0,
635 : flags,
636 : request_blob,
637 : 0,
638 : 64 * 1024,
639 : 1,
640 : 64 * 1024,
641 : 0,
642 : 0,
643 : &fragment,
644 : &response_blob,
645 : &unkn9);
646 0 : torture_assert_ntstatus_ok_goto(
647 : tctx, status, ok, done,
648 : "dcerpc_mdssvc_unknown1 failed\n");
649 :
650 0 : done:
651 0 : return ok;
652 : }
653 :
654 0 : static bool test_sl_dict_type_safety(struct torture_context *tctx,
655 : void *data)
656 : {
657 0 : struct torture_mdsscv_state *state = talloc_get_type_abort(
658 : data, struct torture_mdsscv_state);
659 0 : struct dcerpc_binding_handle *b = state->p->binding_handle;
660 : struct mdssvc_blob request_blob;
661 : struct mdssvc_blob response_blob;
662 0 : uint64_t ctx1 = 0xdeadbeef;
663 0 : uint64_t ctx2 = 0xcafebabe;
664 : uint32_t device_id;
665 : uint32_t unkn2;
666 : uint32_t unkn9;
667 : uint32_t fragment;
668 : uint32_t flags;
669 0 : DALLOC_CTX *d = NULL;
670 0 : sl_array_t *array1 = NULL, *array2 = NULL;
671 0 : sl_dict_t *arg = NULL;
672 : int result;
673 : NTSTATUS status;
674 0 : bool ok = true;
675 :
676 0 : device_id = UINT32_C(0x2f000045);
677 0 : unkn2 = 23;
678 0 : unkn9 = 0;
679 0 : fragment = 0;
680 0 : flags = UINT32_C(0x6b000001);
681 :
682 0 : d = dalloc_new(tctx);
683 0 : torture_assert_not_null_goto(tctx, d,
684 : ok, done, "dalloc_new failed\n");
685 :
686 0 : array1 = dalloc_zero(d, sl_array_t);
687 0 : torture_assert_not_null_goto(tctx, array1,
688 : ok, done, "dalloc_zero failed\n");
689 :
690 0 : array2 = dalloc_zero(d, sl_array_t);
691 0 : torture_assert_not_null_goto(tctx, array2,
692 : ok, done, "dalloc_new failed\n");
693 :
694 0 : result = dalloc_stradd(array2, "openQueryWithParams:forContext:");
695 0 : torture_assert_goto(tctx, result == 0,
696 : ok, done, "dalloc_stradd failed\n");
697 :
698 0 : result = dalloc_add_copy(array2, &ctx1, uint64_t);
699 0 : torture_assert_goto(tctx, result == 0,
700 : ok, done, "dalloc_stradd failed\n");
701 :
702 0 : result = dalloc_add_copy(array2, &ctx2, uint64_t);
703 0 : torture_assert_goto(tctx, result == 0,
704 : ok, done, "dalloc_stradd failed\n");
705 :
706 0 : arg = dalloc_zero(array1, sl_dict_t);
707 0 : torture_assert_not_null_goto(tctx, d,
708 : ok, done, "dalloc_zero failed\n");
709 :
710 0 : result = dalloc_stradd(arg, "kMDQueryString");
711 0 : torture_assert_goto(tctx, result == 0,
712 : ok, done, "dalloc_stradd failed\n");
713 :
714 0 : result = dalloc_stradd(arg, "*");
715 0 : torture_assert_goto(tctx, result == 0,
716 : ok, done, "dalloc_stradd failed\n");
717 :
718 0 : result = dalloc_stradd(arg, "kMDScopeArray");
719 0 : torture_assert_goto(tctx, result == 0,
720 : ok, done, "dalloc_stradd failed\n");
721 :
722 0 : result = dalloc_stradd(arg, "AAAABBBB");
723 0 : torture_assert_goto(tctx, result == 0,
724 : ok, done, "dalloc_stradd failed\n");
725 :
726 0 : result = dalloc_add(array1, array2, sl_array_t);
727 0 : torture_assert_goto(tctx, result == 0,
728 : ok, done, "dalloc_add failed\n");
729 :
730 0 : result = dalloc_add(array1, arg, sl_dict_t);
731 0 : torture_assert_goto(tctx, result == 0,
732 : ok, done, "dalloc_add failed\n");
733 :
734 0 : result = dalloc_add(d, array1, sl_array_t);
735 0 : torture_assert_goto(tctx, result == 0,
736 : ok, done, "dalloc_add failed\n");
737 :
738 0 : torture_comment(tctx, "%s", dalloc_dump(d, 0));
739 :
740 0 : request_blob.spotlight_blob = talloc_array(tctx,
741 : uint8_t,
742 : 64 * 1024);
743 0 : torture_assert_not_null_goto(tctx, request_blob.spotlight_blob,
744 : ok, done, "dalloc_new failed\n");
745 0 : request_blob.size = 64 * 1024;
746 :
747 0 : status = sl_pack_alloc(tctx, d, &request_blob, 64 * 1024);
748 0 : torture_assert_ntstatus_ok_goto(tctx, status, ok, done,
749 : "sl_pack_alloc() failed\n");
750 :
751 0 : status = dcerpc_mdssvc_cmd(b,
752 : state,
753 : &state->ph,
754 : 0,
755 : device_id,
756 : unkn2,
757 : 0,
758 : flags,
759 : request_blob,
760 : 0,
761 : 64 * 1024,
762 : 1,
763 : 64 * 1024,
764 : 0,
765 : 0,
766 : &fragment,
767 : &response_blob,
768 : &unkn9);
769 0 : torture_assert_ntstatus_ok_goto(
770 : tctx, status, ok, done,
771 : "dcerpc_mdssvc_cmd failed\n");
772 :
773 0 : done:
774 0 : return ok;
775 : }
776 :
777 0 : static bool test_mdssvc_invalid_ph_close(struct torture_context *tctx,
778 : void *data)
779 : {
780 0 : struct torture_mdsscv_state *state = talloc_get_type_abort(
781 : data, struct torture_mdsscv_state);
782 0 : struct dcerpc_binding_handle *b = state->p->binding_handle;
783 : struct policy_handle ph;
784 : uint32_t device_id;
785 : uint32_t unkn2;
786 : uint32_t close_status;
787 : NTSTATUS status;
788 0 : bool ok = true;
789 :
790 0 : device_id = generate_random();
791 0 : unkn2 = 23;
792 0 : close_status = 0;
793 :
794 0 : ZERO_STRUCT(ph);
795 0 : ph.uuid = GUID_random();
796 :
797 0 : status = dcerpc_mdssvc_close(b,
798 : state,
799 : &ph,
800 : 0,
801 : device_id,
802 : unkn2,
803 : 0,
804 : &ph,
805 : &close_status);
806 0 : torture_assert_ntstatus_equal_goto(
807 : tctx, status, NT_STATUS_RPC_PROTOCOL_ERROR, ok, done,
808 : "dcerpc_mdssvc_unknown1 failed\n");
809 :
810 0 : done:
811 0 : return ok;
812 : }
813 :
814 : /*
815 : * Test fetchAttributes with unknown CNID
816 : */
817 0 : static bool test_mdssvc_fetch_attr_unknown_cnid(struct torture_context *tctx,
818 : void *data)
819 : {
820 0 : struct torture_mdsscv_state *state = talloc_get_type_abort(
821 : data, struct torture_mdsscv_state);
822 0 : struct dcerpc_binding_handle *b = state->p->binding_handle;
823 0 : uint32_t max_fragment_size = 64 * 1024;
824 : struct mdssvc_blob request_blob;
825 : struct mdssvc_blob response_blob;
826 0 : DALLOC_CTX *d = NULL, *mds_reply = NULL;
827 0 : uint64_t *uint64var = NULL;
828 0 : sl_array_t *array = NULL;
829 0 : sl_array_t *cmd_array = NULL;
830 0 : sl_array_t *attr_array = NULL;
831 0 : sl_cnids_t *cnids = NULL;
832 0 : void *path = NULL;
833 0 : const char *path_type = NULL;
834 : uint64_t ino64;
835 : NTSTATUS status;
836 : int ret;
837 0 : bool ok = true;
838 :
839 0 : d = dalloc_new(state);
840 0 : torture_assert_not_null_goto(tctx, d, ret, done, "dalloc_new failed\n");
841 :
842 0 : array = dalloc_zero(d, sl_array_t);
843 0 : torture_assert_not_null_goto(tctx, array, ret, done,
844 : "dalloc_zero failed\n");
845 :
846 0 : ret = dalloc_add(d, array, sl_array_t);
847 0 : torture_assert_goto(tctx, ret == 0, ret, done, "dalloc_add failed\n");
848 :
849 0 : cmd_array = dalloc_zero(d, sl_array_t);
850 0 : torture_assert_not_null_goto(tctx, cmd_array, ret, done,
851 : "dalloc_zero failed\n");
852 :
853 0 : ret = dalloc_add(array, cmd_array, sl_array_t);
854 0 : torture_assert_goto(tctx, ret == 0, ret, done, "dalloc_add failed\n");
855 :
856 0 : ret = dalloc_stradd(cmd_array, "fetchAttributes:forOIDArray:context:");
857 0 : torture_assert_goto(tctx, ret == 0, ret, done, "dalloc_stradd failed\n");
858 :
859 0 : uint64var = talloc_zero_array(cmd_array, uint64_t, 2);
860 0 : torture_assert_not_null_goto(tctx, uint64var, ret, done,
861 : "talloc_zero_array failed\n");
862 0 : talloc_set_name(uint64var, "uint64_t *");
863 :
864 0 : uint64var[0] = 0x500a;
865 0 : uint64var[1] = 0;
866 :
867 0 : ret = dalloc_add(cmd_array, &uint64var[0], uint64_t *);
868 0 : torture_assert_goto(tctx, ret == 0, ret, done, "dalloc_add failed\n");
869 :
870 0 : attr_array = dalloc_zero(d, sl_array_t);
871 0 : torture_assert_not_null_goto(tctx, attr_array, ret, done,
872 : "dalloc_zero failed\n");
873 :
874 0 : ret = dalloc_add(array, attr_array, sl_array_t);
875 0 : torture_assert_goto(tctx, ret == 0, ret, done, "dalloc_add failed\n");
876 :
877 0 : ret = dalloc_stradd(attr_array, "kMDItemPath");
878 0 : torture_assert_goto(tctx, ret == 0, ret, done, "dalloc_stradd failed\n");
879 :
880 : /* CNIDs */
881 0 : cnids = talloc_zero(array, sl_cnids_t);
882 0 : torture_assert_not_null_goto(tctx, cnids, ret, done,
883 : "talloc_zero failed\n");
884 :
885 0 : cnids->ca_cnids = dalloc_new(cnids);
886 0 : torture_assert_not_null_goto(tctx, cnids->ca_cnids, ret, done,
887 : "dalloc_new failed\n");
888 :
889 0 : cnids->ca_unkn1 = 0xadd;
890 0 : cnids->ca_context = 0x6b000020;
891 :
892 0 : ino64 = UINT64_C(64382947389618974);
893 0 : ret = dalloc_add_copy(cnids->ca_cnids, &ino64, uint64_t);
894 0 : torture_assert_goto(tctx, ret == 0, ret, done,
895 : "dalloc_add_copy failed\n");
896 :
897 0 : ret = dalloc_add(array, cnids, sl_cnids_t);
898 0 : torture_assert_goto(tctx, ret == 0, ret, done, "dalloc_add failed\n");
899 :
900 0 : status = sl_pack_alloc(tctx, d, &request_blob, max_fragment_size);
901 0 : torture_assert_ntstatus_ok_goto(tctx, status, ok, done,
902 : "sl_pack_alloc() failed\n");
903 :
904 0 : status = dcerpc_mdssvc_cmd(b,
905 : state,
906 : &state->ph,
907 : 0,
908 : state->dev,
909 : state->mdscmd_open.unkn2,
910 : 0,
911 : state->flags,
912 : request_blob,
913 : 0,
914 : max_fragment_size,
915 : 1,
916 : max_fragment_size,
917 : 0,
918 : 0,
919 : &state->mdscmd_cmd.fragment,
920 : &response_blob,
921 : &state->mdscmd_cmd.unkn9);
922 0 : torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
923 : "dcerpc_mdssvc_cmd failed\n");
924 :
925 0 : mds_reply = dalloc_new(state);
926 0 : torture_assert_not_null_goto(tctx, mds_reply, ret, done,
927 : "dalloc_zero failed\n");
928 :
929 0 : ok = sl_unpack(mds_reply,
930 0 : (char *)response_blob.spotlight_blob,
931 0 : response_blob.length);
932 0 : torture_assert_goto(tctx, ok, ret, done, "dalloc_add failed\n");
933 :
934 0 : torture_comment(tctx, "%s", dalloc_dump(mds_reply, 0));
935 :
936 0 : path = dalloc_get(mds_reply,
937 : "DALLOC_CTX", 0,
938 : "DALLOC_CTX", 2,
939 : "DALLOC_CTX", 0,
940 : "sl_nil_t", 1);
941 0 : torture_assert_not_null_goto(tctx, path, ret, done,
942 : "dalloc_get path failed\n");
943 :
944 0 : path_type = talloc_get_name(path);
945 :
946 0 : torture_assert_str_equal_goto(tctx, path_type, "sl_nil_t", ret, done,
947 : "Wrong dalloc object type\n");
948 :
949 0 : done:
950 0 : return ok;
951 : }
952 :
953 964 : struct torture_suite *torture_rpc_mdssvc(TALLOC_CTX *mem_ctx)
954 : {
955 964 : struct torture_suite *suite = torture_suite_create(
956 : mem_ctx, "mdssvc");
957 964 : struct torture_tcase *tcase = NULL;
958 :
959 964 : tcase = torture_suite_add_tcase(suite, "rpccmd");
960 964 : if (tcase == NULL) {
961 0 : return NULL;
962 : }
963 964 : torture_tcase_set_fixture(tcase,
964 : torture_rpc_mdssvc_setup,
965 : torture_rpc_mdssvc_teardown);
966 :
967 964 : torture_tcase_add_simple_test(tcase,
968 : "open_unknown_share",
969 : test_mdssvc_open_unknown_share);
970 :
971 964 : torture_tcase_add_simple_test(tcase,
972 : "open_spotlight_disabled",
973 : test_mdssvc_open_spotlight_disabled);
974 :
975 964 : torture_tcase_add_simple_test(tcase,
976 : "close",
977 : test_mdssvc_close);
978 :
979 964 : torture_tcase_add_simple_test(tcase,
980 : "null_ph",
981 : test_mdssvc_null_ph);
982 :
983 964 : tcase = torture_suite_add_tcase(suite, "disconnect1");
984 964 : if (tcase == NULL) {
985 0 : return NULL;
986 : }
987 964 : torture_tcase_set_fixture(tcase,
988 : torture_rpc_mdssvc_open,
989 : torture_rpc_mdssvc_close);
990 :
991 964 : torture_tcase_add_simple_test(tcase,
992 : "invalid_ph_unknown1",
993 : test_mdssvc_invalid_ph_unknown1);
994 :
995 964 : tcase = torture_suite_add_tcase(suite, "disconnect2");
996 964 : if (tcase == NULL) {
997 0 : return NULL;
998 : }
999 964 : torture_tcase_set_fixture(tcase,
1000 : torture_rpc_mdssvc_open,
1001 : torture_rpc_mdssvc_close);
1002 :
1003 964 : torture_tcase_add_simple_test(tcase,
1004 : "invalid_ph_cmd",
1005 : test_mdssvc_invalid_ph_cmd);
1006 :
1007 964 : tcase = torture_suite_add_tcase(suite, "disconnect3");
1008 964 : if (tcase == NULL) {
1009 0 : return NULL;
1010 : }
1011 964 : torture_tcase_set_fixture(tcase,
1012 : torture_rpc_mdssvc_open,
1013 : torture_rpc_mdssvc_close);
1014 :
1015 964 : torture_tcase_add_simple_test(tcase,
1016 : "invalid_ph_close",
1017 : test_mdssvc_invalid_ph_close);
1018 :
1019 964 : tcase = torture_suite_add_tcase(suite, "mdscmd");
1020 964 : if (tcase == NULL) {
1021 0 : return NULL;
1022 : }
1023 964 : torture_tcase_set_fixture(tcase,
1024 : torture_rpc_mdssvc_open,
1025 : torture_rpc_mdssvc_close);
1026 :
1027 964 : torture_tcase_add_simple_test(tcase,
1028 : "fetch_unknown_cnid",
1029 : test_mdssvc_fetch_attr_unknown_cnid);
1030 :
1031 964 : torture_tcase_add_simple_test(tcase,
1032 : "mdssvc_sl_unpack_loop",
1033 : test_mdssvc_sl_unpack_loop);
1034 :
1035 964 : torture_tcase_add_simple_test(tcase,
1036 : "sl_dict_type_safety",
1037 : test_sl_dict_type_safety);
1038 :
1039 964 : return suite;
1040 : }
|