LCOV - code coverage report
Current view: top level - source4/torture/rpc - mdssvc.c (source / functions) Hit Total Coverage
Test: coverage report for v4-17-test 1498b464 Lines: 29 377 7.7 %
Date: 2024-06-13 04:01:37 Functions: 1 15 6.7 %

          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             : }

Generated by: LCOV version 1.13