2019-04-16 17:54:21 +03:00
/*
Unix SMB / CIFS implementation .
2023-08-03 16:45:20 +03:00
test suite for the mdssvc RPC service
2019-04-16 17:54:21 +03:00
Copyright ( C ) Ralph Boehme 2019
This program is free software ; you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation ; either version 3 of the License , or
( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with this program ; if not , write to the Free Software
Foundation , Inc . , 675 Mass Ave , Cambridge , MA 0213 9 , USA .
*/
# include "includes.h"
# include "torture/rpc/torture_rpc.h"
# include "librpc/gen_ndr/ndr_mdssvc_c.h"
# include "param/param.h"
2020-12-02 19:24:22 +03:00
# include "lib/cmdline/cmdline.h"
2019-04-16 17:54:21 +03:00
# include "rpc_server/mdssvc/dalloc.h"
# include "rpc_server/mdssvc/marshalling.h"
struct torture_mdsscv_state {
struct dcerpc_pipe * p ;
struct policy_handle ph ;
/* Known fields used across multiple commands */
uint32_t dev ;
uint32_t flags ;
/* cmd specific or unknown fields */
struct {
const char share_path [ 1025 ] ;
uint32_t unkn2 ;
uint32_t unkn3 ;
} mdscmd_open ;
struct {
uint32_t status ;
uint32_t unkn7 ;
} mdscmd_unknown1 ;
struct {
uint32_t fragment ;
uint32_t unkn9 ;
} mdscmd_cmd ;
struct {
uint32_t status ;
} mdscmd_close ;
} ;
static bool torture_rpc_mdssvc_setup ( struct torture_context * tctx ,
void * * data )
{
struct torture_mdsscv_state * state = NULL ;
NTSTATUS status ;
state = talloc_zero ( tctx , struct torture_mdsscv_state ) ;
if ( state = = NULL ) {
return false ;
}
* data = state ;
status = torture_rpc_connection ( tctx , & state - > p , & ndr_table_mdssvc ) ;
torture_assert_ntstatus_ok ( tctx , status , " Error connecting to server " ) ;
return true ;
}
static bool torture_rpc_mdssvc_teardown ( struct torture_context * tctx ,
void * data )
{
struct torture_mdsscv_state * state = talloc_get_type_abort (
data , struct torture_mdsscv_state ) ;
TALLOC_FREE ( state - > p ) ;
TALLOC_FREE ( state ) ;
return true ;
}
static bool torture_rpc_mdssvc_open ( struct torture_context * tctx ,
void * * data )
{
struct torture_mdsscv_state * state = NULL ;
struct dcerpc_binding_handle * b = NULL ;
const char * share_name = NULL ;
const char * share_mount_path = NULL ;
NTSTATUS status ;
bool ok = true ;
state = talloc_zero ( tctx , struct torture_mdsscv_state ) ;
if ( state = = NULL ) {
return false ;
}
* data = state ;
status = torture_rpc_connection ( tctx , & state - > p , & ndr_table_mdssvc ) ;
torture_assert_ntstatus_ok ( tctx , status , " Error connecting to server " ) ;
b = state - > p - > binding_handle ;
share_name = torture_setting_string (
tctx , " spotlight_share " , " spotlight " ) ;
share_mount_path = torture_setting_string (
tctx , " share_mount_path " , " /foo/bar " ) ;
state - > dev = generate_random ( ) ;
state - > mdscmd_open . unkn2 = 23 ;
state - > mdscmd_open . unkn3 = 0 ;
ZERO_STRUCT ( state - > ph ) ;
status = dcerpc_mdssvc_open ( b ,
state ,
& state - > dev ,
& state - > mdscmd_open . unkn2 ,
& state - > mdscmd_open . unkn3 ,
share_mount_path ,
share_name ,
state - > mdscmd_open . share_path ,
& state - > ph ) ;
torture_assert_ntstatus_ok_goto ( tctx , status , ok , done ,
" dcerpc_mdssvc_open failed \n " ) ;
status = dcerpc_mdssvc_unknown1 ( b ,
state ,
2019-08-23 19:43:02 +03:00
& state - > ph ,
2019-04-16 17:54:21 +03:00
0 ,
state - > dev ,
state - > mdscmd_open . unkn2 ,
0 ,
geteuid ( ) ,
getegid ( ) ,
& state - > mdscmd_unknown1 . status ,
& state - > flags ,
& state - > mdscmd_unknown1 . unkn7 ) ;
torture_assert_ntstatus_ok_goto ( tctx , status , ok , done ,
" dcerpc_mdssvc_unknown1 failed \n " ) ;
done :
if ( ! ok ) {
( void ) dcerpc_mdssvc_close ( b ,
state ,
2019-08-23 19:43:02 +03:00
& state - > ph ,
2019-04-16 17:54:21 +03:00
0 ,
state - > dev ,
state - > mdscmd_open . unkn2 ,
0 ,
& state - > ph ,
& state - > mdscmd_close . status ) ;
2023-04-12 01:34:22 +03:00
ZERO_STRUCTP ( state ) ;
2019-04-16 17:54:21 +03:00
}
return ok ;
}
static bool torture_rpc_mdssvc_close ( struct torture_context * tctx ,
void * data )
{
struct torture_mdsscv_state * state = talloc_get_type_abort (
data , struct torture_mdsscv_state ) ;
NTSTATUS status ;
bool ok = true ;
torture_comment ( tctx , " test_teardown_mdssvc_disconnect \n " ) ;
2023-04-11 11:57:31 +03:00
if ( state - > p = = NULL ) {
/* We have already been disconnected. */
goto done ;
}
status = dcerpc_mdssvc_close ( state - > p - > binding_handle ,
2019-04-16 17:54:21 +03:00
state ,
2019-08-23 19:43:02 +03:00
& state - > ph ,
2019-04-16 17:54:21 +03:00
0 ,
state - > dev ,
state - > mdscmd_open . unkn2 ,
0 ,
& state - > ph ,
& state - > mdscmd_close . status ) ;
torture_assert_ntstatus_ok_goto ( tctx , status , ok , done ,
" dcerpc_mdssvc_close failed \n " ) ;
2023-04-12 01:34:22 +03:00
ZERO_STRUCTP ( state ) ;
2019-04-16 17:54:21 +03:00
done :
return ok ;
}
/*
* Test unknown share name
*/
static bool test_mdssvc_open_unknown_share ( struct torture_context * tctx ,
void * data )
{
struct torture_mdsscv_state * state = talloc_get_type_abort (
data , struct torture_mdsscv_state ) ;
struct dcerpc_binding_handle * b = state - > p - > binding_handle ;
struct policy_handle ph ;
struct policy_handle nullh ;
uint32_t device_id ;
uint32_t unkn2 ;
uint32_t unkn3 ;
uint32_t device_id_out ;
uint32_t unkn2_out ;
uint32_t unkn3_out ;
const char * share_mount_path = NULL ;
const char * share_name = NULL ;
const char share_path [ 1025 ] = " X " ;
NTSTATUS status ;
bool ok = true ;
share_name = torture_setting_string (
tctx , " unknown_share " , " choukawoohoo " ) ;
share_mount_path = torture_setting_string (
tctx , " share_mount_path " , " /foo/bar " ) ;
device_id_out = device_id = generate_random ( ) ;
unkn2_out = unkn2 = generate_random ( ) ;
unkn3_out = unkn3 = generate_random ( ) ;
ZERO_STRUCT ( ph ) ;
ZERO_STRUCT ( nullh ) ;
status = dcerpc_mdssvc_open ( b ,
tctx ,
& device_id_out ,
& unkn2_out ,
& unkn3_out ,
share_mount_path ,
share_name ,
share_path ,
& ph ) ;
torture_assert_ntstatus_ok_goto ( tctx , status , ok , done ,
" dcerpc_mdssvc_open failed \n " ) ;
torture_assert_u32_equal_goto ( tctx , device_id_out , device_id , ok , done ,
" Bad device_id \n " ) ;
torture_assert_u32_equal_goto ( tctx , unkn2_out , unkn2 , ok , done ,
" Bad unkn2 \n " ) ;
torture_assert_u32_equal_goto ( tctx , unkn3_out , unkn3 , ok , done ,
" Bad unkn3 \n " ) ;
torture_assert_goto ( tctx , share_path [ 0 ] = = ' \0 ' , ok , done ,
" Expected empty string as share path \n " ) ;
torture_assert_mem_equal_goto ( tctx , & ph , & nullh ,
sizeof ( ph ) , ok , done ,
" Expected all-zero policy handle \n " ) ;
done :
return ok ;
}
/*
* Test on a share where Spotlight is not enabled
*/
static bool test_mdssvc_open_spotlight_disabled ( struct torture_context * tctx ,
void * data )
{
struct torture_mdsscv_state * state = talloc_get_type_abort (
data , struct torture_mdsscv_state ) ;
struct dcerpc_binding_handle * b = state - > p - > binding_handle ;
struct policy_handle ph ;
2022-06-07 10:52:53 +03:00
struct policy_handle nullh ;
2019-04-16 17:54:21 +03:00
uint32_t device_id ;
uint32_t unkn2 ;
uint32_t unkn3 ;
uint32_t device_id_out ;
uint32_t unkn2_out ;
uint32_t unkn3_out ;
const char * share_mount_path = NULL ;
const char * share_name = NULL ;
const char share_path [ 1025 ] = " " ;
NTSTATUS status ;
bool ok = true ;
share_name = torture_setting_string (
tctx , " no_spotlight_share " , " no_spotlight " ) ;
share_mount_path = torture_setting_string (
tctx , " share_mount_path " , " /foo/bar " ) ;
device_id_out = device_id = generate_random ( ) ;
unkn2_out = unkn2 = 23 ;
unkn3_out = unkn3 = 0 ;
ZERO_STRUCT ( ph ) ;
2022-06-07 10:52:53 +03:00
ZERO_STRUCT ( nullh ) ;
2019-04-16 17:54:21 +03:00
status = dcerpc_mdssvc_open ( b ,
tctx ,
& device_id_out ,
& unkn2_out ,
& unkn3_out ,
share_mount_path ,
share_name ,
share_path ,
& ph ) ;
torture_assert_ntstatus_ok_goto ( tctx , status , ok , done ,
" dcerpc_mdssvc_open failed \n " ) ;
torture_assert_u32_equal_goto ( tctx , device_id , device_id_out , ok , done ,
" Bad device_id \n " ) ;
torture_assert_u32_equal_goto ( tctx , unkn2 , unkn2_out ,
ok , done , " Bad unkn2 \n " ) ;
torture_assert_u32_equal_goto ( tctx , unkn3 , unkn3_out ,
ok , done , " Bad unkn3 \n " ) ;
2022-06-07 10:52:53 +03:00
torture_assert_goto ( tctx , share_path [ 0 ] = = ' \0 ' , ok , done ,
" Expected empty string as share path \n " ) ;
torture_assert_mem_equal_goto ( tctx , & ph , & nullh ,
sizeof ( ph ) , ok , done ,
" Expected all-zero policy handle \n " ) ;
2019-04-16 17:54:21 +03:00
done :
return ok ;
}
static bool test_mdssvc_close ( struct torture_context * tctx ,
void * data )
{
struct torture_mdsscv_state * state = talloc_get_type_abort (
data , struct torture_mdsscv_state ) ;
struct dcerpc_binding_handle * b = state - > p - > binding_handle ;
struct policy_handle ph ;
struct policy_handle close_ph ;
uint32_t device_id ;
uint32_t unkn2 ;
uint32_t unkn3 ;
const char * share_mount_path = NULL ;
const char * share_name = NULL ;
const char share_path [ 1025 ] = " " ;
uint32_t close_status ;
DATA_BLOB ph_blob ;
DATA_BLOB close_ph_blob ;
NTSTATUS status ;
bool ok = true ;
share_name = torture_setting_string (
tctx , " spotlight_share " , " spotlight " ) ;
share_mount_path = torture_setting_string (
tctx , " share_mount_path " , " /foo/bar " ) ;
device_id = generate_random ( ) ;
unkn2 = 23 ;
unkn3 = 0 ;
ZERO_STRUCT ( ph ) ;
ZERO_STRUCT ( close_ph ) ;
status = dcerpc_mdssvc_open ( b ,
tctx ,
& device_id ,
& unkn2 ,
& unkn3 ,
share_mount_path ,
share_name ,
share_path ,
& ph ) ;
torture_assert_ntstatus_ok_goto ( tctx , status , ok , done ,
" dcerpc_mdssvc_open failed \n " ) ;
status = dcerpc_mdssvc_close ( b ,
tctx ,
2019-08-23 19:43:02 +03:00
& ph ,
2019-04-16 17:54:21 +03:00
0 ,
device_id ,
unkn2 ,
0 ,
& close_ph ,
& close_status ) ;
torture_assert_ntstatus_ok_goto ( tctx , status , ok , done ,
" dcerpc_mdssvc_open failed \n " ) ;
ph_blob = ( DATA_BLOB ) {
. data = ( uint8_t * ) & ph ,
. length = sizeof ( struct policy_handle )
} ;
close_ph_blob = ( DATA_BLOB ) {
. data = ( uint8_t * ) & close_ph ,
. length = sizeof ( struct policy_handle ) ,
} ;
torture_assert_data_blob_equal ( tctx , close_ph_blob , ph_blob ,
" bad blob " ) ;
torture_comment ( tctx , " Test close with a all-zero handle \n " ) ;
ZERO_STRUCT ( ph ) ;
status = dcerpc_mdssvc_close ( b ,
tctx ,
2019-08-23 19:43:02 +03:00
& ph ,
2019-04-16 17:54:21 +03:00
0 ,
device_id ,
unkn2 ,
0 ,
& close_ph ,
& close_status ) ;
torture_assert_ntstatus_ok_goto ( tctx , status , ok , done ,
2019-11-04 20:39:10 +03:00
" dcerpc_mdssvc_close failed \n " ) ;
2019-04-16 17:54:21 +03:00
torture_assert_data_blob_equal ( tctx , close_ph_blob , ph_blob ,
" bad blob " ) ;
done :
return ok ;
}
static bool test_mdssvc_null_ph ( struct torture_context * tctx ,
void * data )
{
struct torture_mdsscv_state * state = talloc_get_type_abort (
data , struct torture_mdsscv_state ) ;
struct dcerpc_binding_handle * b = state - > p - > binding_handle ;
struct policy_handle nullh ;
struct policy_handle ph ;
uint32_t device_id ;
uint32_t unkn2 ;
uint32_t unkn7 ;
uint32_t cmd_status ;
uint32_t flags ;
NTSTATUS status ;
bool ok = true ;
device_id = generate_random ( ) ;
unkn2 = 23 ;
unkn7 = 0 ;
cmd_status = 0 ;
ZERO_STRUCT ( nullh ) ;
ZERO_STRUCT ( ph ) ;
status = dcerpc_mdssvc_unknown1 ( b ,
tctx ,
2019-08-23 19:43:02 +03:00
& ph ,
2019-04-16 17:54:21 +03:00
0 ,
device_id ,
unkn2 ,
0 ,
geteuid ( ) ,
getegid ( ) ,
& cmd_status ,
& flags ,
& unkn7 ) ;
torture_assert_ntstatus_ok_goto ( tctx , status , ok , done ,
" dcerpc_mdssvc_unknown1 failed \n " ) ;
torture_assert_mem_equal_goto ( tctx , & ph , & nullh ,
sizeof ( ph ) , ok , done ,
" Expected all-zero policy handle \n " ) ;
done :
return ok ;
}
static bool test_mdssvc_invalid_ph_unknown1 ( struct torture_context * tctx ,
void * data )
{
struct torture_mdsscv_state * state = talloc_get_type_abort (
data , struct torture_mdsscv_state ) ;
struct dcerpc_binding_handle * b = state - > p - > binding_handle ;
struct policy_handle ph ;
uint32_t device_id ;
uint32_t unkn2 ;
uint32_t unkn7 ;
uint32_t cmd_status ;
uint32_t flags ;
NTSTATUS status ;
bool ok = true ;
device_id = generate_random ( ) ;
unkn2 = 23 ;
unkn7 = 0 ;
cmd_status = 0 ;
ZERO_STRUCT ( ph ) ;
ph . uuid = GUID_random ( ) ;
status = dcerpc_mdssvc_unknown1 ( b ,
tctx ,
2019-08-23 19:43:02 +03:00
& ph ,
2019-04-16 17:54:21 +03:00
0 ,
device_id ,
unkn2 ,
0 ,
geteuid ( ) ,
getegid ( ) ,
& cmd_status ,
& flags ,
& unkn7 ) ;
torture_assert_ntstatus_equal_goto (
tctx , status , NT_STATUS_RPC_PROTOCOL_ERROR , ok , done ,
" dcerpc_mdssvc_unknown1 failed \n " ) ;
2023-04-11 11:57:31 +03:00
/* Free and set to NULL the no-longer-usable pipe. */
b = NULL ;
TALLOC_FREE ( state - > p ) ;
2019-04-16 17:54:21 +03:00
done :
return ok ;
}
static bool test_mdssvc_invalid_ph_cmd ( struct torture_context * tctx ,
void * data )
{
struct torture_mdsscv_state * state = talloc_get_type_abort (
data , struct torture_mdsscv_state ) ;
struct dcerpc_binding_handle * b = state - > p - > binding_handle ;
struct policy_handle ph ;
struct mdssvc_blob request_blob ;
struct mdssvc_blob response_blob ;
uint32_t device_id ;
uint32_t unkn2 ;
uint32_t unkn9 ;
uint32_t fragment ;
uint32_t flags ;
NTSTATUS status ;
bool ok = true ;
device_id = generate_random ( ) ;
unkn2 = 23 ;
unkn9 = 0 ;
fragment = 0 ;
flags = UINT32_C ( 0x6b000001 ) ;
ZERO_STRUCT ( ph ) ;
ph . uuid = GUID_random ( ) ;
request_blob . spotlight_blob = talloc_array ( state ,
uint8_t ,
0 ) ;
torture_assert_not_null_goto ( tctx , request_blob . spotlight_blob ,
ok , done , " dalloc_zero failed \n " ) ;
request_blob . size = 0 ;
request_blob . length = 0 ;
request_blob . size = 0 ;
status = dcerpc_mdssvc_cmd ( b ,
state ,
2019-08-23 19:43:02 +03:00
& ph ,
2019-04-16 17:54:21 +03:00
0 ,
device_id ,
unkn2 ,
0 ,
flags ,
request_blob ,
0 ,
64 * 1024 ,
1 ,
64 * 1024 ,
0 ,
0 ,
& fragment ,
& response_blob ,
& unkn9 ) ;
torture_assert_ntstatus_equal_goto (
tctx , status , NT_STATUS_RPC_PROTOCOL_ERROR , ok , done ,
" dcerpc_mdssvc_unknown1 failed \n " ) ;
2023-04-11 11:57:31 +03:00
/* Free and set to NULL the no-longer-usable pipe. */
b = NULL ;
TALLOC_FREE ( state - > p ) ;
2019-04-16 17:54:21 +03:00
done :
return ok ;
}
2023-05-31 16:34:26 +03:00
static uint8_t test_sl_unpack_loop_buf [ ] = {
0x34 , 0x33 , 0x32 , 0x31 , 0x33 , 0x30 , 0x64 , 0x6d ,
0x1d , 0x00 , 0x00 , 0x00 , 0x16 , 0x00 , 0x00 , 0x00 ,
0x01 , 0x00 , 0x00 , 0x02 , 0x01 , 0x00 , 0x00 , 0x00 ,
0x01 , 0x00 , 0x00 , 0x02 , 0x02 , 0x00 , 0x00 , 0x00 ,
0x01 , 0x00 , 0x00 , 0x02 , 0x03 , 0x00 , 0x00 , 0x00 ,
0x06 , 0x00 , 0x00 , 0x07 , 0x04 , 0x00 , 0x00 , 0x00 ,
0x66 , 0x65 , 0x74 , 0x63 , 0x68 , 0x41 , 0x74 , 0x74 ,
0x72 , 0x69 , 0x62 , 0x75 , 0x74 , 0x65 , 0x73 , 0x3a ,
0x66 , 0x6f , 0x72 , 0x4f , 0x49 , 0x44 , 0x41 , 0x72 ,
0x72 , 0x61 , 0x79 , 0x3a , 0x63 , 0x6f , 0x6e , 0x74 ,
0x65 , 0x78 , 0x74 , 0x3a , 0x00 , 0x00 , 0x00 , 0xea ,
0x02 , 0x00 , 0x00 , 0x84 , 0x02 , 0x00 , 0x00 , 0x00 ,
0x0a , 0x50 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x01 , 0x00 , 0x00 , 0x02 , 0x04 , 0x00 , 0x00 , 0x00 ,
0x01 , 0x00 , 0x00 , 0x02 , 0x05 , 0x00 , 0x00 , 0x00 ,
0x03 , 0x00 , 0x00 , 0x07 , 0x03 , 0x00 , 0x00 , 0x00 ,
0x6b , 0x4d , 0x44 , 0x49 , 0x74 , 0x65 , 0x6d , 0x50 ,
0x61 , 0x74 , 0x68 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x01 , 0x00 , 0x00 , 0x02 , 0x06 , 0x00 , 0x00 , 0x00 ,
0x03 , 0x00 , 0x00 , 0x87 , 0x08 , 0x00 , 0x00 , 0x00 ,
0x01 , 0x00 , 0xdd , 0x0a , 0x20 , 0x00 , 0x00 , 0x6b ,
0x01 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x07 , 0x00 , 0x00 , 0x88 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x02 , 0x00 , 0x00 , 0x0a , 0x03 , 0x00 , 0x00 , 0x00 ,
0x03 , 0x00 , 0x00 , 0x0a , 0x03 , 0x00 , 0x00 , 0x00 ,
0x04 , 0x00 , 0x00 , 0x0c , 0x04 , 0x00 , 0x00 , 0x00 ,
0x0e , 0x00 , 0x00 , 0x0a , 0x01 , 0x00 , 0x00 , 0x00 ,
0x0f , 0x00 , 0x00 , 0x0c , 0x03 , 0x00 , 0x00 , 0x00 ,
0x13 , 0x00 , 0x00 , 0x1a , 0x00 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x01 , 0x00 , 0x01 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x01 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00
} ;
static bool test_mdssvc_sl_unpack_loop ( struct torture_context * tctx ,
void * data )
{
struct torture_mdsscv_state * state = talloc_get_type_abort (
data , struct torture_mdsscv_state ) ;
struct dcerpc_binding_handle * b = state - > p - > binding_handle ;
struct mdssvc_blob request_blob ;
struct mdssvc_blob response_blob ;
uint32_t device_id ;
uint32_t unkn2 ;
uint32_t unkn9 ;
uint32_t fragment ;
uint32_t flags ;
NTSTATUS status ;
bool ok = true ;
device_id = UINT32_C ( 0x2f000045 ) ;
unkn2 = 23 ;
unkn9 = 0 ;
fragment = 0 ;
flags = UINT32_C ( 0x6b000001 ) ;
request_blob . spotlight_blob = test_sl_unpack_loop_buf ;
request_blob . size = sizeof ( test_sl_unpack_loop_buf ) ;
request_blob . length = sizeof ( test_sl_unpack_loop_buf ) ;
status = dcerpc_mdssvc_cmd ( b ,
state ,
& state - > ph ,
0 ,
device_id ,
unkn2 ,
0 ,
flags ,
request_blob ,
0 ,
64 * 1024 ,
1 ,
64 * 1024 ,
0 ,
0 ,
& fragment ,
& response_blob ,
& unkn9 ) ;
torture_assert_ntstatus_ok_goto (
tctx , status , ok , done ,
" dcerpc_mdssvc_unknown1 failed \n " ) ;
done :
return ok ;
}
2023-05-31 17:26:14 +03:00
static bool test_sl_dict_type_safety ( struct torture_context * tctx ,
void * data )
{
struct torture_mdsscv_state * state = talloc_get_type_abort (
data , struct torture_mdsscv_state ) ;
struct dcerpc_binding_handle * b = state - > p - > binding_handle ;
struct mdssvc_blob request_blob ;
struct mdssvc_blob response_blob ;
uint64_t ctx1 = 0xdeadbeef ;
uint64_t ctx2 = 0xcafebabe ;
uint32_t device_id ;
uint32_t unkn2 ;
uint32_t unkn9 ;
uint32_t fragment ;
uint32_t flags ;
DALLOC_CTX * d = NULL ;
sl_array_t * array1 = NULL , * array2 = NULL ;
sl_dict_t * arg = NULL ;
int result ;
NTSTATUS status ;
bool ok = true ;
device_id = UINT32_C ( 0x2f000045 ) ;
unkn2 = 23 ;
unkn9 = 0 ;
fragment = 0 ;
flags = UINT32_C ( 0x6b000001 ) ;
d = dalloc_new ( tctx ) ;
torture_assert_not_null_goto ( tctx , d ,
ok , done , " dalloc_new failed \n " ) ;
array1 = dalloc_zero ( d , sl_array_t ) ;
torture_assert_not_null_goto ( tctx , array1 ,
ok , done , " dalloc_zero failed \n " ) ;
array2 = dalloc_zero ( d , sl_array_t ) ;
torture_assert_not_null_goto ( tctx , array2 ,
ok , done , " dalloc_new failed \n " ) ;
result = dalloc_stradd ( array2 , " openQueryWithParams:forContext: " ) ;
torture_assert_goto ( tctx , result = = 0 ,
ok , done , " dalloc_stradd failed \n " ) ;
result = dalloc_add_copy ( array2 , & ctx1 , uint64_t ) ;
torture_assert_goto ( tctx , result = = 0 ,
ok , done , " dalloc_stradd failed \n " ) ;
result = dalloc_add_copy ( array2 , & ctx2 , uint64_t ) ;
torture_assert_goto ( tctx , result = = 0 ,
ok , done , " dalloc_stradd failed \n " ) ;
arg = dalloc_zero ( array1 , sl_dict_t ) ;
torture_assert_not_null_goto ( tctx , d ,
ok , done , " dalloc_zero failed \n " ) ;
result = dalloc_stradd ( arg , " kMDQueryString " ) ;
torture_assert_goto ( tctx , result = = 0 ,
ok , done , " dalloc_stradd failed \n " ) ;
result = dalloc_stradd ( arg , " * " ) ;
torture_assert_goto ( tctx , result = = 0 ,
ok , done , " dalloc_stradd failed \n " ) ;
result = dalloc_stradd ( arg , " kMDScopeArray " ) ;
torture_assert_goto ( tctx , result = = 0 ,
ok , done , " dalloc_stradd failed \n " ) ;
result = dalloc_stradd ( arg , " AAAABBBB " ) ;
torture_assert_goto ( tctx , result = = 0 ,
ok , done , " dalloc_stradd failed \n " ) ;
result = dalloc_add ( array1 , array2 , sl_array_t ) ;
torture_assert_goto ( tctx , result = = 0 ,
ok , done , " dalloc_add failed \n " ) ;
result = dalloc_add ( array1 , arg , sl_dict_t ) ;
torture_assert_goto ( tctx , result = = 0 ,
ok , done , " dalloc_add failed \n " ) ;
result = dalloc_add ( d , array1 , sl_array_t ) ;
torture_assert_goto ( tctx , result = = 0 ,
ok , done , " dalloc_add failed \n " ) ;
torture_comment ( tctx , " %s " , dalloc_dump ( d , 0 ) ) ;
request_blob . spotlight_blob = talloc_array ( tctx ,
uint8_t ,
64 * 1024 ) ;
torture_assert_not_null_goto ( tctx , request_blob . spotlight_blob ,
ok , done , " dalloc_new failed \n " ) ;
request_blob . size = 64 * 1024 ;
2023-06-19 19:16:57 +03:00
status = sl_pack_alloc ( tctx , d , & request_blob , 64 * 1024 ) ;
torture_assert_ntstatus_ok_goto ( tctx , status , ok , done ,
" sl_pack_alloc() failed \n " ) ;
2023-05-31 17:26:14 +03:00
status = dcerpc_mdssvc_cmd ( b ,
state ,
& state - > ph ,
0 ,
device_id ,
unkn2 ,
0 ,
flags ,
request_blob ,
0 ,
64 * 1024 ,
1 ,
64 * 1024 ,
0 ,
0 ,
& fragment ,
& response_blob ,
& unkn9 ) ;
torture_assert_ntstatus_ok_goto (
tctx , status , ok , done ,
" dcerpc_mdssvc_cmd failed \n " ) ;
done :
return ok ;
}
2019-04-16 17:54:21 +03:00
static bool test_mdssvc_invalid_ph_close ( struct torture_context * tctx ,
void * data )
{
struct torture_mdsscv_state * state = talloc_get_type_abort (
data , struct torture_mdsscv_state ) ;
struct dcerpc_binding_handle * b = state - > p - > binding_handle ;
struct policy_handle ph ;
uint32_t device_id ;
uint32_t unkn2 ;
uint32_t close_status ;
NTSTATUS status ;
bool ok = true ;
device_id = generate_random ( ) ;
unkn2 = 23 ;
close_status = 0 ;
ZERO_STRUCT ( ph ) ;
ph . uuid = GUID_random ( ) ;
status = dcerpc_mdssvc_close ( b ,
state ,
2019-08-23 19:43:02 +03:00
& ph ,
2019-04-16 17:54:21 +03:00
0 ,
device_id ,
unkn2 ,
0 ,
& ph ,
& close_status ) ;
torture_assert_ntstatus_equal_goto (
tctx , status , NT_STATUS_RPC_PROTOCOL_ERROR , ok , done ,
" dcerpc_mdssvc_unknown1 failed \n " ) ;
2023-04-11 11:57:31 +03:00
/* Free and set to NULL the no-longer-usable pipe. */
b = NULL ;
TALLOC_FREE ( state - > p ) ;
2019-04-16 17:54:21 +03:00
done :
return ok ;
}
/*
* Test fetchAttributes with unknown CNID
*/
static bool test_mdssvc_fetch_attr_unknown_cnid ( struct torture_context * tctx ,
void * data )
{
struct torture_mdsscv_state * state = talloc_get_type_abort (
data , struct torture_mdsscv_state ) ;
struct dcerpc_binding_handle * b = state - > p - > binding_handle ;
uint32_t max_fragment_size = 64 * 1024 ;
struct mdssvc_blob request_blob ;
struct mdssvc_blob response_blob ;
DALLOC_CTX * d = NULL , * mds_reply = NULL ;
uint64_t * uint64var = NULL ;
sl_array_t * array = NULL ;
sl_array_t * cmd_array = NULL ;
sl_array_t * attr_array = NULL ;
sl_cnids_t * cnids = NULL ;
void * path = NULL ;
const char * path_type = NULL ;
uint64_t ino64 ;
NTSTATUS status ;
int ret ;
bool ok = true ;
d = dalloc_new ( state ) ;
torture_assert_not_null_goto ( tctx , d , ret , done , " dalloc_new failed \n " ) ;
array = dalloc_zero ( d , sl_array_t ) ;
torture_assert_not_null_goto ( tctx , array , ret , done ,
" dalloc_zero failed \n " ) ;
ret = dalloc_add ( d , array , sl_array_t ) ;
torture_assert_goto ( tctx , ret = = 0 , ret , done , " dalloc_add failed \n " ) ;
cmd_array = dalloc_zero ( d , sl_array_t ) ;
torture_assert_not_null_goto ( tctx , cmd_array , ret , done ,
" dalloc_zero failed \n " ) ;
ret = dalloc_add ( array , cmd_array , sl_array_t ) ;
torture_assert_goto ( tctx , ret = = 0 , ret , done , " dalloc_add failed \n " ) ;
ret = dalloc_stradd ( cmd_array , " fetchAttributes:forOIDArray:context: " ) ;
torture_assert_goto ( tctx , ret = = 0 , ret , done , " dalloc_stradd failed \n " ) ;
uint64var = talloc_zero_array ( cmd_array , uint64_t , 2 ) ;
torture_assert_not_null_goto ( tctx , uint64var , ret , done ,
" talloc_zero_array failed \n " ) ;
talloc_set_name ( uint64var , " uint64_t * " ) ;
uint64var [ 0 ] = 0x500a ;
uint64var [ 1 ] = 0 ;
ret = dalloc_add ( cmd_array , & uint64var [ 0 ] , uint64_t * ) ;
torture_assert_goto ( tctx , ret = = 0 , ret , done , " dalloc_add failed \n " ) ;
attr_array = dalloc_zero ( d , sl_array_t ) ;
torture_assert_not_null_goto ( tctx , attr_array , ret , done ,
" dalloc_zero failed \n " ) ;
ret = dalloc_add ( array , attr_array , sl_array_t ) ;
torture_assert_goto ( tctx , ret = = 0 , ret , done , " dalloc_add failed \n " ) ;
ret = dalloc_stradd ( attr_array , " kMDItemPath " ) ;
torture_assert_goto ( tctx , ret = = 0 , ret , done , " dalloc_stradd failed \n " ) ;
/* CNIDs */
cnids = talloc_zero ( array , sl_cnids_t ) ;
torture_assert_not_null_goto ( tctx , cnids , ret , done ,
" talloc_zero failed \n " ) ;
cnids - > ca_cnids = dalloc_new ( cnids ) ;
torture_assert_not_null_goto ( tctx , cnids - > ca_cnids , ret , done ,
" dalloc_new failed \n " ) ;
cnids - > ca_unkn1 = 0xadd ;
cnids - > ca_context = 0x6b000020 ;
ino64 = UINT64_C ( 64382947389618974 ) ;
ret = dalloc_add_copy ( cnids - > ca_cnids , & ino64 , uint64_t ) ;
torture_assert_goto ( tctx , ret = = 0 , ret , done ,
" dalloc_add_copy failed \n " ) ;
ret = dalloc_add ( array , cnids , sl_cnids_t ) ;
torture_assert_goto ( tctx , ret = = 0 , ret , done , " dalloc_add failed \n " ) ;
2023-06-19 19:16:57 +03:00
status = sl_pack_alloc ( tctx , d , & request_blob , max_fragment_size ) ;
torture_assert_ntstatus_ok_goto ( tctx , status , ok , done ,
" sl_pack_alloc() failed \n " ) ;
2019-04-16 17:54:21 +03:00
status = dcerpc_mdssvc_cmd ( b ,
state ,
2019-08-23 19:43:02 +03:00
& state - > ph ,
2019-04-16 17:54:21 +03:00
0 ,
state - > dev ,
state - > mdscmd_open . unkn2 ,
0 ,
state - > flags ,
request_blob ,
0 ,
max_fragment_size ,
1 ,
max_fragment_size ,
0 ,
0 ,
& state - > mdscmd_cmd . fragment ,
& response_blob ,
& state - > mdscmd_cmd . unkn9 ) ;
torture_assert_ntstatus_ok_goto ( tctx , status , ret , done ,
" dcerpc_mdssvc_cmd failed \n " ) ;
mds_reply = dalloc_new ( state ) ;
torture_assert_not_null_goto ( tctx , mds_reply , ret , done ,
" dalloc_zero failed \n " ) ;
ok = sl_unpack ( mds_reply ,
( char * ) response_blob . spotlight_blob ,
response_blob . length ) ;
torture_assert_goto ( tctx , ok , ret , done , " dalloc_add failed \n " ) ;
torture_comment ( tctx , " %s " , dalloc_dump ( mds_reply , 0 ) ) ;
path = dalloc_get ( mds_reply ,
" DALLOC_CTX " , 0 ,
" DALLOC_CTX " , 2 ,
" DALLOC_CTX " , 0 ,
" sl_nil_t " , 1 ) ;
torture_assert_not_null_goto ( tctx , path , ret , done ,
" dalloc_get path failed \n " ) ;
path_type = talloc_get_name ( path ) ;
torture_assert_str_equal_goto ( tctx , path_type , " sl_nil_t " , ret , done ,
" Wrong dalloc object type \n " ) ;
done :
return ok ;
}
struct torture_suite * torture_rpc_mdssvc ( TALLOC_CTX * mem_ctx )
{
struct torture_suite * suite = torture_suite_create (
mem_ctx , " mdssvc " ) ;
struct torture_tcase * tcase = NULL ;
tcase = torture_suite_add_tcase ( suite , " rpccmd " ) ;
if ( tcase = = NULL ) {
return NULL ;
}
torture_tcase_set_fixture ( tcase ,
torture_rpc_mdssvc_setup ,
torture_rpc_mdssvc_teardown ) ;
torture_tcase_add_simple_test ( tcase ,
" open_unknown_share " ,
test_mdssvc_open_unknown_share ) ;
torture_tcase_add_simple_test ( tcase ,
" open_spotlight_disabled " ,
test_mdssvc_open_spotlight_disabled ) ;
torture_tcase_add_simple_test ( tcase ,
" close " ,
test_mdssvc_close ) ;
torture_tcase_add_simple_test ( tcase ,
" null_ph " ,
test_mdssvc_null_ph ) ;
tcase = torture_suite_add_tcase ( suite , " disconnect1 " ) ;
if ( tcase = = NULL ) {
return NULL ;
}
torture_tcase_set_fixture ( tcase ,
torture_rpc_mdssvc_open ,
torture_rpc_mdssvc_close ) ;
torture_tcase_add_simple_test ( tcase ,
" invalid_ph_unknown1 " ,
test_mdssvc_invalid_ph_unknown1 ) ;
tcase = torture_suite_add_tcase ( suite , " disconnect2 " ) ;
if ( tcase = = NULL ) {
return NULL ;
}
torture_tcase_set_fixture ( tcase ,
torture_rpc_mdssvc_open ,
torture_rpc_mdssvc_close ) ;
torture_tcase_add_simple_test ( tcase ,
" invalid_ph_cmd " ,
test_mdssvc_invalid_ph_cmd ) ;
tcase = torture_suite_add_tcase ( suite , " disconnect3 " ) ;
if ( tcase = = NULL ) {
return NULL ;
}
torture_tcase_set_fixture ( tcase ,
torture_rpc_mdssvc_open ,
torture_rpc_mdssvc_close ) ;
torture_tcase_add_simple_test ( tcase ,
" invalid_ph_close " ,
test_mdssvc_invalid_ph_close ) ;
tcase = torture_suite_add_tcase ( suite , " mdscmd " ) ;
if ( tcase = = NULL ) {
return NULL ;
}
torture_tcase_set_fixture ( tcase ,
torture_rpc_mdssvc_open ,
torture_rpc_mdssvc_close ) ;
torture_tcase_add_simple_test ( tcase ,
" fetch_unknown_cnid " ,
test_mdssvc_fetch_attr_unknown_cnid ) ;
2023-05-31 16:34:26 +03:00
torture_tcase_add_simple_test ( tcase ,
" mdssvc_sl_unpack_loop " ,
test_mdssvc_sl_unpack_loop ) ;
2023-05-31 17:26:14 +03:00
torture_tcase_add_simple_test ( tcase ,
" sl_dict_type_safety " ,
test_sl_dict_type_safety ) ;
2019-04-16 17:54:21 +03:00
return suite ;
}