LCOV - code coverage report
Current view: top level - source4/torture/rpc - mdssvc.c (source / functions) Hit Total Coverage
Test: coverage report for abartlet/fix-coverage dd10fb34 Lines: 305 319 95.6 %
Date: 2021-09-23 10:06:22 Functions: 13 13 100.0 %

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

Generated by: LCOV version 1.13