s4:torture: Don't try to close the connection after running disconnect tests
[ab/samba-autobuild/.git] / source4 / torture / rpc / mdssvc.c
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 static bool torture_rpc_mdssvc_setup(struct torture_context *tctx,
58                                      void **data)
59 {
60         struct torture_mdsscv_state *state = NULL;
61         NTSTATUS status;
62
63         state = talloc_zero(tctx, struct torture_mdsscv_state);
64         if (state == NULL) {
65                 return false;
66         }
67         *data = state;
68
69         status = torture_rpc_connection(tctx, &state->p, &ndr_table_mdssvc);
70         torture_assert_ntstatus_ok(tctx, status,  "Error connecting to server");
71
72         return true;
73 }
74
75 static bool torture_rpc_mdssvc_teardown(struct torture_context *tctx,
76                                         void *data)
77 {
78         struct torture_mdsscv_state *state = talloc_get_type_abort(
79                 data, struct torture_mdsscv_state);
80
81         TALLOC_FREE(state->p);
82         TALLOC_FREE(state);
83         return true;
84 }
85
86 static bool torture_rpc_mdssvc_open(struct torture_context *tctx,
87                                     void **data)
88 {
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;
95
96         state = talloc_zero(tctx, struct torture_mdsscv_state);
97         if (state == NULL) {
98                 return false;
99         }
100         *data = state;
101
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;
105
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");
110
111         state->dev = generate_random();
112         state->mdscmd_open.unkn2 = 23;
113         state->mdscmd_open.unkn3 = 0;
114
115         ZERO_STRUCT(state->ph);
116
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");
128
129         status = dcerpc_mdssvc_unknown1(b,
130                                         state,
131                                         &state->ph,
132                                         0,
133                                         state->dev,
134                                         state->mdscmd_open.unkn2,
135                                         0,
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");
143
144 done:
145         if (!ok) {
146                 (void)dcerpc_mdssvc_close(b,
147                                           state,
148                                           &state->ph,
149                                           0,
150                                           state->dev,
151                                           state->mdscmd_open.unkn2,
152                                           0,
153                                           &state->ph,
154                                           &state->mdscmd_close.status);
155                 ZERO_STRUCTP(state);
156         }
157         return ok;
158 }
159
160 static bool torture_rpc_mdssvc_close(struct torture_context *tctx,
161                                      void *data)
162 {
163         struct torture_mdsscv_state *state = talloc_get_type_abort(
164                 data, struct torture_mdsscv_state);
165         NTSTATUS status;
166         bool ok = true;
167
168         torture_comment(tctx, "test_teardown_mdssvc_disconnect\n");
169
170         if (state->p == NULL) {
171                 /* We have already been disconnected. */
172                 goto done;
173         }
174
175         status = dcerpc_mdssvc_close(state->p->binding_handle,
176                                      state,
177                                      &state->ph,
178                                      0,
179                                      state->dev,
180                                      state->mdscmd_open.unkn2,
181                                      0,
182                                      &state->ph,
183                                      &state->mdscmd_close.status);
184         torture_assert_ntstatus_ok_goto(tctx, status, ok, done,
185                                         "dcerpc_mdssvc_close failed\n");
186
187         ZERO_STRUCTP(state);
188
189 done:
190         return ok;
191 }
192
193 /*
194  * Test unknown share name
195  */
196 static bool test_mdssvc_open_unknown_share(struct torture_context *tctx,
197                                            void *data)
198 {
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;
215
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");
220
221         device_id_out = device_id = generate_random();
222         unkn2_out = unkn2 = generate_random();
223         unkn3_out = unkn3 = generate_random();
224
225         ZERO_STRUCT(ph);
226         ZERO_STRUCT(nullh);
227
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);
237
238         torture_assert_ntstatus_ok_goto(tctx, status, ok, done,
239                                         "dcerpc_mdssvc_open failed\n");
240
241         torture_assert_u32_equal_goto(tctx, device_id_out, device_id, ok, done,
242                                       "Bad device_id\n");
243
244         torture_assert_u32_equal_goto(tctx, unkn2_out, unkn2, ok, done,
245                                       "Bad unkn2\n");
246
247         torture_assert_u32_equal_goto(tctx, unkn3_out, unkn3, ok, done,
248                                       "Bad unkn3\n");
249
250         torture_assert_goto(tctx, share_path[0] == '\0', ok, done,
251                             "Expected empty string as share path\n");
252
253         torture_assert_mem_equal_goto(tctx, &ph, &nullh,
254                                       sizeof(ph), ok, done,
255                                       "Expected all-zero policy handle\n");
256
257 done:
258         return ok;
259 }
260
261 /*
262  * Test on a share where Spotlight is not enabled
263  */
264 static bool test_mdssvc_open_spotlight_disabled(struct torture_context *tctx,
265                                                 void *data)
266 {
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;
283
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");
288
289         device_id_out = device_id = generate_random();
290         unkn2_out = unkn2 = 23;
291         unkn3_out = unkn3 = 0;
292
293         ZERO_STRUCT(ph);
294         ZERO_STRUCT(nullh);
295
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");
307
308         torture_assert_u32_equal_goto(tctx, device_id, device_id_out, ok, done,
309                                       "Bad device_id\n");
310
311         torture_assert_u32_equal_goto(tctx, unkn2, unkn2_out,
312                                       ok, done, "Bad unkn2\n");
313
314         torture_assert_u32_equal_goto(tctx, unkn3, unkn3_out,
315                                       ok, done, "Bad unkn3\n");
316
317         torture_assert_goto(tctx, share_path[0] == '\0', ok, done,
318                             "Expected empty string as share path\n");
319
320         torture_assert_mem_equal_goto(tctx, &ph, &nullh,
321                                       sizeof(ph), ok, done,
322                                       "Expected all-zero policy handle\n");
323
324 done:
325         return ok;
326 }
327
328 static bool test_mdssvc_close(struct torture_context *tctx,
329                               void *data)
330 {
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;
347
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");
352
353         device_id = generate_random();
354         unkn2 = 23;
355         unkn3 = 0;
356
357         ZERO_STRUCT(ph);
358         ZERO_STRUCT(close_ph);
359
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");
371
372         status = dcerpc_mdssvc_close(b,
373                                      tctx,
374                                      &ph,
375                                      0,
376                                      device_id,
377                                      unkn2,
378                                      0,
379                                      &close_ph,
380                                      &close_status);
381         torture_assert_ntstatus_ok_goto(tctx, status, ok, done,
382                                         "dcerpc_mdssvc_open failed\n");
383
384         ph_blob = (DATA_BLOB) {
385                 .data = (uint8_t *)&ph,
386                 .length = sizeof(struct policy_handle)
387         };
388         close_ph_blob = (DATA_BLOB) {
389                 .data = (uint8_t *)&close_ph,
390                 .length = sizeof(struct policy_handle),
391         };
392
393         torture_assert_data_blob_equal(tctx, close_ph_blob, ph_blob,
394                                        "bad blob");
395
396         torture_comment(tctx, "Test close with a all-zero handle\n");
397
398         ZERO_STRUCT(ph);
399         status = dcerpc_mdssvc_close(b,
400                                      tctx,
401                                      &ph,
402                                      0,
403                                      device_id,
404                                      unkn2,
405                                      0,
406                                      &close_ph,
407                                      &close_status);
408         torture_assert_ntstatus_ok_goto(tctx, status, ok, done,
409                                         "dcerpc_mdssvc_close failed\n");
410
411         torture_assert_data_blob_equal(tctx, close_ph_blob, ph_blob,
412                                        "bad blob");
413
414 done:
415         return ok;
416 }
417
418 static bool test_mdssvc_null_ph(struct torture_context *tctx,
419                                 void *data)
420 {
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;
433
434         device_id = generate_random();
435         unkn2 = 23;
436         unkn7 = 0;
437         cmd_status = 0;
438
439         ZERO_STRUCT(nullh);
440         ZERO_STRUCT(ph);
441
442         status = dcerpc_mdssvc_unknown1(b,
443                                         tctx,
444                                         &ph,
445                                         0,
446                                         device_id,
447                                         unkn2,
448                                         0,
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");
456
457         torture_assert_mem_equal_goto(tctx, &ph, &nullh,
458                                       sizeof(ph), ok, done,
459                                       "Expected all-zero policy handle\n");
460
461 done:
462         return ok;
463 }
464
465 static bool test_mdssvc_invalid_ph_unknown1(struct torture_context *tctx,
466                                             void *data)
467 {
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;
479
480         device_id = generate_random();
481         unkn2 = 23;
482         unkn7 = 0;
483         cmd_status = 0;
484
485         ZERO_STRUCT(ph);
486         ph.uuid = GUID_random();
487
488         status = dcerpc_mdssvc_unknown1(b,
489                                         tctx,
490                                         &ph,
491                                         0,
492                                         device_id,
493                                         unkn2,
494                                         0,
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");
503
504         /* Free and set to NULL the no-longer-usable pipe. */
505         b = NULL;
506         TALLOC_FREE(state->p);
507
508 done:
509         return ok;
510 }
511
512 static bool test_mdssvc_invalid_ph_cmd(struct torture_context *tctx,
513                                        void *data)
514 {
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;
528
529         device_id = generate_random();
530         unkn2 = 23;
531         unkn9 = 0;
532         fragment = 0;
533         flags = UINT32_C(0x6b000001);
534
535         ZERO_STRUCT(ph);
536         ph.uuid = GUID_random();
537
538         request_blob.spotlight_blob = talloc_array(state,
539                                                    uint8_t,
540                                                    0);
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;
546
547         response_blob.spotlight_blob = talloc_array(state,
548                                                     uint8_t,
549                                                     0);
550         torture_assert_not_null_goto(tctx, response_blob.spotlight_blob,
551                                      ok, done, "dalloc_zero failed\n");
552         response_blob.size = 0;
553
554         status =  dcerpc_mdssvc_cmd(b,
555                                     state,
556                                     &ph,
557                                     0,
558                                     device_id,
559                                     unkn2,
560                                     0,
561                                     flags,
562                                     request_blob,
563                                     0,
564                                     64 * 1024,
565                                     1,
566                                     64 * 1024,
567                                     0,
568                                     0,
569                                     &fragment,
570                                     &response_blob,
571                                     &unkn9);
572         torture_assert_ntstatus_equal_goto(
573                 tctx, status, NT_STATUS_RPC_PROTOCOL_ERROR, ok, done,
574                 "dcerpc_mdssvc_unknown1 failed\n");
575
576         /* Free and set to NULL the no-longer-usable pipe. */
577         b = NULL;
578         TALLOC_FREE(state->p);
579
580 done:
581         return ok;
582 }
583
584 static bool test_mdssvc_invalid_ph_close(struct torture_context *tctx,
585                                          void *data)
586 {
587         struct torture_mdsscv_state *state = talloc_get_type_abort(
588                 data, struct torture_mdsscv_state);
589         struct dcerpc_binding_handle *b = state->p->binding_handle;
590         struct policy_handle ph;
591         uint32_t device_id;
592         uint32_t unkn2;
593         uint32_t close_status;
594         NTSTATUS status;
595         bool ok = true;
596
597         device_id = generate_random();
598         unkn2 = 23;
599         close_status = 0;
600
601         ZERO_STRUCT(ph);
602         ph.uuid = GUID_random();
603
604         status = dcerpc_mdssvc_close(b,
605                                      state,
606                                      &ph,
607                                      0,
608                                      device_id,
609                                      unkn2,
610                                      0,
611                                      &ph,
612                                      &close_status);
613         torture_assert_ntstatus_equal_goto(
614                 tctx, status, NT_STATUS_RPC_PROTOCOL_ERROR, ok, done,
615                 "dcerpc_mdssvc_unknown1 failed\n");
616
617         /* Free and set to NULL the no-longer-usable pipe. */
618         b = NULL;
619         TALLOC_FREE(state->p);
620
621 done:
622         return ok;
623 }
624
625 /*
626  * Test fetchAttributes with unknown CNID
627  */
628 static bool test_mdssvc_fetch_attr_unknown_cnid(struct torture_context *tctx,
629                                                 void *data)
630 {
631         struct torture_mdsscv_state *state = talloc_get_type_abort(
632                 data, struct torture_mdsscv_state);
633         struct dcerpc_binding_handle *b = state->p->binding_handle;
634         uint32_t max_fragment_size = 64 * 1024;
635         struct mdssvc_blob request_blob;
636         struct mdssvc_blob response_blob;
637         DALLOC_CTX *d = NULL, *mds_reply = NULL;
638         uint64_t *uint64var = NULL;
639         sl_array_t *array = NULL;
640         sl_array_t *cmd_array = NULL;
641         sl_array_t *attr_array = NULL;
642         sl_cnids_t *cnids = NULL;
643         void *path = NULL;
644         const char *path_type = NULL;
645         uint64_t ino64;
646         NTSTATUS status;
647         ssize_t len;
648         int ret;
649         bool ok = true;
650
651         d = dalloc_new(state);
652         torture_assert_not_null_goto(tctx, d, ret, done, "dalloc_new failed\n");
653
654         array = dalloc_zero(d, sl_array_t);
655         torture_assert_not_null_goto(tctx, array, ret, done,
656                                      "dalloc_zero failed\n");
657
658         ret = dalloc_add(d, array, sl_array_t);
659         torture_assert_goto(tctx, ret == 0, ret, done, "dalloc_add failed\n");
660
661         cmd_array = dalloc_zero(d, sl_array_t);
662         torture_assert_not_null_goto(tctx, cmd_array, ret, done,
663                                      "dalloc_zero failed\n");
664
665         ret = dalloc_add(array, cmd_array, sl_array_t);
666         torture_assert_goto(tctx, ret == 0, ret, done, "dalloc_add failed\n");
667
668         ret = dalloc_stradd(cmd_array, "fetchAttributes:forOIDArray:context:");
669         torture_assert_goto(tctx, ret == 0, ret, done, "dalloc_stradd failed\n");
670
671         uint64var = talloc_zero_array(cmd_array, uint64_t, 2);
672         torture_assert_not_null_goto(tctx, uint64var, ret, done,
673                                      "talloc_zero_array failed\n");
674         talloc_set_name(uint64var, "uint64_t *");
675
676         uint64var[0] = 0x500a;
677         uint64var[1] = 0;
678
679         ret = dalloc_add(cmd_array, &uint64var[0], uint64_t *);
680         torture_assert_goto(tctx, ret == 0, ret, done, "dalloc_add failed\n");
681
682         attr_array = dalloc_zero(d, sl_array_t);
683         torture_assert_not_null_goto(tctx, attr_array, ret, done,
684                                      "dalloc_zero failed\n");
685
686         ret = dalloc_add(array, attr_array, sl_array_t);
687         torture_assert_goto(tctx, ret == 0, ret, done, "dalloc_add failed\n");
688
689         ret = dalloc_stradd(attr_array, "kMDItemPath");
690         torture_assert_goto(tctx, ret == 0, ret, done, "dalloc_stradd failed\n");
691
692         /* CNIDs */
693         cnids = talloc_zero(array, sl_cnids_t);
694         torture_assert_not_null_goto(tctx, cnids, ret, done,
695                                      "talloc_zero failed\n");
696
697         cnids->ca_cnids = dalloc_new(cnids);
698         torture_assert_not_null_goto(tctx, cnids->ca_cnids, ret, done,
699                                      "dalloc_new failed\n");
700
701         cnids->ca_unkn1 = 0xadd;
702         cnids->ca_context = 0x6b000020;
703
704         ino64 = UINT64_C(64382947389618974);
705         ret = dalloc_add_copy(cnids->ca_cnids, &ino64, uint64_t);
706         torture_assert_goto(tctx, ret == 0, ret, done,
707                             "dalloc_add_copy failed\n");
708
709         ret = dalloc_add(array, cnids, sl_cnids_t);
710         torture_assert_goto(tctx, ret == 0, ret, done, "dalloc_add failed\n");
711
712         request_blob.spotlight_blob = talloc_array(state,
713                                                    uint8_t,
714                                                    max_fragment_size);
715         torture_assert_not_null_goto(tctx, request_blob.spotlight_blob,
716                                      ret, done, "dalloc_zero failed\n");
717         request_blob.size = max_fragment_size;
718
719         response_blob.spotlight_blob = talloc_array(state,
720                                                     uint8_t,
721                                                     max_fragment_size);
722         torture_assert_not_null_goto(tctx, response_blob.spotlight_blob,
723                                      ret, done, "dalloc_zero failed\n");
724         response_blob.size = max_fragment_size;
725
726         len = sl_pack(d, (char *)request_blob.spotlight_blob, request_blob.size);
727         torture_assert_goto(tctx, len != -1, ret, done, "sl_pack failed\n");
728
729         request_blob.length = len;
730         request_blob.size = len;
731
732         status =  dcerpc_mdssvc_cmd(b,
733                                     state,
734                                     &state->ph,
735                                     0,
736                                     state->dev,
737                                     state->mdscmd_open.unkn2,
738                                     0,
739                                     state->flags,
740                                     request_blob,
741                                     0,
742                                     max_fragment_size,
743                                     1,
744                                     max_fragment_size,
745                                     0,
746                                     0,
747                                     &state->mdscmd_cmd.fragment,
748                                     &response_blob,
749                                     &state->mdscmd_cmd.unkn9);
750         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
751                                         "dcerpc_mdssvc_cmd failed\n");
752
753         mds_reply = dalloc_new(state);
754         torture_assert_not_null_goto(tctx, mds_reply, ret, done,
755                                      "dalloc_zero failed\n");
756
757         ok = sl_unpack(mds_reply,
758                        (char *)response_blob.spotlight_blob,
759                        response_blob.length);
760         torture_assert_goto(tctx, ok, ret, done, "dalloc_add failed\n");
761
762         torture_comment(tctx, "%s", dalloc_dump(mds_reply, 0));
763
764         path = dalloc_get(mds_reply,
765                           "DALLOC_CTX", 0,
766                           "DALLOC_CTX", 2,
767                           "DALLOC_CTX", 0,
768                           "sl_nil_t", 1);
769         torture_assert_not_null_goto(tctx, path, ret, done,
770                                      "dalloc_get path failed\n");
771
772         path_type = talloc_get_name(path);
773
774         torture_assert_str_equal_goto(tctx, path_type, "sl_nil_t", ret, done,
775                                       "Wrong dalloc object type\n");
776
777 done:
778         return ok;
779 }
780
781 struct torture_suite *torture_rpc_mdssvc(TALLOC_CTX *mem_ctx)
782 {
783         struct torture_suite *suite = torture_suite_create(
784                 mem_ctx, "mdssvc");
785         struct torture_tcase *tcase = NULL;
786
787         tcase = torture_suite_add_tcase(suite, "rpccmd");
788         if (tcase == NULL) {
789                 return NULL;
790         }
791         torture_tcase_set_fixture(tcase,
792                                   torture_rpc_mdssvc_setup,
793                                   torture_rpc_mdssvc_teardown);
794
795         torture_tcase_add_simple_test(tcase,
796                                       "open_unknown_share",
797                                       test_mdssvc_open_unknown_share);
798
799         torture_tcase_add_simple_test(tcase,
800                                       "open_spotlight_disabled",
801                                       test_mdssvc_open_spotlight_disabled);
802
803         torture_tcase_add_simple_test(tcase,
804                                       "close",
805                                       test_mdssvc_close);
806
807         torture_tcase_add_simple_test(tcase,
808                                       "null_ph",
809                                       test_mdssvc_null_ph);
810
811         tcase = torture_suite_add_tcase(suite, "disconnect1");
812         if (tcase == NULL) {
813                 return NULL;
814         }
815         torture_tcase_set_fixture(tcase,
816                                   torture_rpc_mdssvc_open,
817                                   torture_rpc_mdssvc_close);
818
819         torture_tcase_add_simple_test(tcase,
820                                       "invalid_ph_unknown1",
821                                       test_mdssvc_invalid_ph_unknown1);
822
823         tcase = torture_suite_add_tcase(suite, "disconnect2");
824         if (tcase == NULL) {
825                 return NULL;
826         }
827         torture_tcase_set_fixture(tcase,
828                                   torture_rpc_mdssvc_open,
829                                   torture_rpc_mdssvc_close);
830
831         torture_tcase_add_simple_test(tcase,
832                                       "invalid_ph_cmd",
833                                       test_mdssvc_invalid_ph_cmd);
834
835         tcase = torture_suite_add_tcase(suite, "disconnect3");
836         if (tcase == NULL) {
837                 return NULL;
838         }
839         torture_tcase_set_fixture(tcase,
840                                   torture_rpc_mdssvc_open,
841                                   torture_rpc_mdssvc_close);
842
843         torture_tcase_add_simple_test(tcase,
844                                       "invalid_ph_close",
845                                       test_mdssvc_invalid_ph_close);
846
847         tcase = torture_suite_add_tcase(suite, "mdscmd");
848         if (tcase == NULL) {
849                 return NULL;
850         }
851         torture_tcase_set_fixture(tcase,
852                                   torture_rpc_mdssvc_open,
853                                   torture_rpc_mdssvc_close);
854
855         torture_tcase_add_simple_test(tcase,
856                                       "fetch_unknown_cnid",
857                                       test_mdssvc_fetch_attr_unknown_cnid);
858
859         return suite;
860 }