2 Unix SMB/CIFS implementation.
5 Copyright (C) Ralph Boehme 2018
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.
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.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>.
22 #include "rpcclient.h"
23 #include "libsmb/libsmb.h"
24 #include "../librpc/gen_ndr/ndr_mdssvc_c.h"
25 #include "../rpc_server/mdssvc/mdssvc.h"
26 #include "../rpc_server/mdssvc/dalloc.h"
27 #include "../rpc_server/mdssvc/marshalling.h"
29 static NTSTATUS
cmd_mdssvc_fetch_properties(
30 struct rpc_pipe_client
*cli
,
32 int argc
, const char **argv
)
34 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
36 uint32_t device_id
= 0x2f000045;
39 struct policy_handle share_handle
;
40 char share_path
[1025] = { 0 };
42 uint32_t flags
; /* server always returns 0x6b000001 ? */
43 uint32_t unkn3
; /* server always returns 0 ? */
44 struct mdssvc_blob request_blob
;
45 struct mdssvc_blob response_blob
;
47 uint32_t max_fragment_size
= 64 * 1024;
48 DALLOC_CTX
*d
, *mds_reply
;
50 sl_array_t
*array1
, *array2
;
56 printf("Usage: %s SHARENAME MOUNTPATH\n", argv
[0]);
60 status
= dcerpc_mdssvc_open(b
, mem_ctx
,
68 if (!NT_STATUS_IS_OK(status
)) {
72 status
= dcerpc_mdssvc_unknown1(b
, mem_ctx
,
83 if (!NT_STATUS_IS_OK(status
)) {
87 d
= dalloc_new(mem_ctx
);
89 status
= NT_STATUS_NO_MEMORY
;
93 mds_reply
= dalloc_new(mem_ctx
);
94 if (mds_reply
== NULL
) {
95 status
= NT_STATUS_NO_MEMORY
;
99 array1
= dalloc_zero(d
, sl_array_t
);
100 if (array1
== NULL
) {
101 status
= NT_STATUS_NO_MEMORY
;
105 array2
= dalloc_zero(d
, sl_array_t
);
106 if (array2
== NULL
) {
107 status
= NT_STATUS_NO_MEMORY
;
111 result
= dalloc_stradd(array2
, "fetchPropertiesForContext:");
113 status
= NT_STATUS_INTERNAL_ERROR
;
116 uint64var
= talloc_zero_array(mem_ctx
, uint64_t, 2);
117 if (uint64var
== NULL
) {
118 status
= NT_STATUS_NO_MEMORY
;
121 talloc_set_name(uint64var
, "uint64_t *");
123 result
= dalloc_add(array2
, &uint64var
[0], uint64_t *);
125 status
= NT_STATUS_INTERNAL_ERROR
;
129 result
= dalloc_add(array1
, array2
, sl_array_t
);
131 status
= NT_STATUS_INTERNAL_ERROR
;
134 result
= dalloc_add(d
, array1
, sl_array_t
);
136 status
= NT_STATUS_INTERNAL_ERROR
;
140 request_blob
.spotlight_blob
= talloc_array(mem_ctx
, uint8_t, max_fragment_size
);
141 if (request_blob
.spotlight_blob
== NULL
) {
142 status
= NT_STATUS_INTERNAL_ERROR
;
145 request_blob
.size
= max_fragment_size
;
147 response_blob
.spotlight_blob
= talloc_array(mem_ctx
, uint8_t, max_fragment_size
);
148 if (response_blob
.spotlight_blob
== NULL
) {
149 status
= NT_STATUS_INTERNAL_ERROR
;
152 response_blob
.size
= max_fragment_size
;
154 len
= sl_pack(d
, (char *)request_blob
.spotlight_blob
, request_blob
.size
);
156 status
= NT_STATUS_INTERNAL_ERROR
;
159 request_blob
.length
= len
;
160 request_blob
.size
= len
;
162 status
= dcerpc_mdssvc_cmd(b
, mem_ctx
,
179 if (!NT_STATUS_IS_OK(status
)) {
183 ok
= sl_unpack(mds_reply
, (char *)response_blob
.spotlight_blob
,
184 response_blob
.length
);
186 DEBUG(1, ("error unpacking Spotlight RPC blob\n"));
187 status
= NT_STATUS_INTERNAL_ERROR
;
191 DEBUG(0, ("%s", dalloc_dump(mds_reply
, 0)));
197 static NTSTATUS
cmd_mdssvc_fetch_attributes(
198 struct rpc_pipe_client
*cli
,
200 int argc
, const char **argv
)
202 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
204 uint32_t device_id
= 0x2f000045;
207 struct policy_handle share_handle
;
208 char share_path
[1025];
210 uint32_t flags
; /* server always returns 0x6b000001 ? */
211 uint32_t unkn3
; /* server always returns 0 ? */
212 struct mdssvc_blob request_blob
;
213 struct mdssvc_blob response_blob
;
215 uint32_t max_fragment_size
= 64 * 1024;
216 DALLOC_CTX
*d
, *mds_reply
;
219 sl_array_t
*cmd_array
;
220 sl_array_t
*attr_array
;
228 printf("Usage: %s SHARENAME MOUNTPATH CNID\n", argv
[0]);
232 ok
= conv_str_u64(argv
[3], &cnid
);
234 printf("Failed to parse: %s\n", argv
[3]);
235 return NT_STATUS_INVALID_PARAMETER
;
238 status
= dcerpc_mdssvc_open(b
, mem_ctx
,
246 if (!NT_STATUS_IS_OK(status
)) {
250 status
= dcerpc_mdssvc_unknown1(b
, mem_ctx
,
261 if (!NT_STATUS_IS_OK(status
)) {
265 d
= dalloc_new(mem_ctx
);
267 status
= NT_STATUS_NO_MEMORY
;
271 array
= dalloc_zero(d
, sl_array_t
);
273 status
= NT_STATUS_NO_MEMORY
;
277 result
= dalloc_add(d
, array
, sl_array_t
);
279 status
= NT_STATUS_INTERNAL_ERROR
;
283 cmd_array
= dalloc_zero(d
, sl_array_t
);
284 if (cmd_array
== NULL
) {
285 status
= NT_STATUS_NO_MEMORY
;
289 result
= dalloc_add(array
, cmd_array
, sl_array_t
);
291 status
= NT_STATUS_INTERNAL_ERROR
;
295 result
= dalloc_stradd(cmd_array
,
296 "fetchAttributes:forOIDArray:context:");
298 status
= NT_STATUS_INTERNAL_ERROR
;
302 uint64var
= talloc_zero_array(mem_ctx
, uint64_t, 2);
303 if (uint64var
== NULL
) {
304 status
= NT_STATUS_NO_MEMORY
;
307 talloc_set_name(uint64var
, "uint64_t *");
308 uint64var
[0] = 0x500a;
311 result
= dalloc_add(cmd_array
, &uint64var
[0], uint64_t *);
313 status
= NT_STATUS_INTERNAL_ERROR
;
317 attr_array
= dalloc_zero(d
, sl_array_t
);
318 if (attr_array
== NULL
) {
319 status
= NT_STATUS_NO_MEMORY
;
323 result
= dalloc_add(array
, attr_array
, sl_array_t
);
325 status
= NT_STATUS_INTERNAL_ERROR
;
329 result
= dalloc_stradd(attr_array
, "kMDItemPath");
331 status
= NT_STATUS_INTERNAL_ERROR
;
336 cnids
= talloc_zero(array
, sl_cnids_t
);
338 status
= NT_STATUS_INTERNAL_ERROR
;
341 cnids
->ca_cnids
= dalloc_new(cnids
);
342 if (cnids
->ca_cnids
== NULL
) {
343 status
= NT_STATUS_INTERNAL_ERROR
;
347 cnids
->ca_unkn1
= 0xadd;
348 cnids
->ca_context
= 0x6b000020;
350 result
= dalloc_add_copy(cnids
->ca_cnids
, &cnid
, uint64_t);
352 status
= NT_STATUS_INTERNAL_ERROR
;
356 result
= dalloc_add(array
, cnids
, sl_cnids_t
);
358 status
= NT_STATUS_INTERNAL_ERROR
;
362 request_blob
.spotlight_blob
= talloc_array(mem_ctx
,
365 if (request_blob
.spotlight_blob
== NULL
) {
366 status
= NT_STATUS_INTERNAL_ERROR
;
369 request_blob
.size
= max_fragment_size
;
371 response_blob
.spotlight_blob
= talloc_array(mem_ctx
,
374 if (response_blob
.spotlight_blob
== NULL
) {
375 status
= NT_STATUS_INTERNAL_ERROR
;
378 response_blob
.size
= max_fragment_size
;
380 len
= sl_pack(d
, (char *)request_blob
.spotlight_blob
, request_blob
.size
);
382 status
= NT_STATUS_INTERNAL_ERROR
;
385 request_blob
.length
= len
;
386 request_blob
.size
= len
;
388 status
= dcerpc_mdssvc_cmd(b
, mem_ctx
,
405 if (!NT_STATUS_IS_OK(status
)) {
406 printf("dcerpc_mdssvc_cmd failed: %s\n", nt_errstr(status
));
410 if (response_blob
.length
== 0) {
411 printf("mdssvc returned empty response\n");
412 status
= NT_STATUS_RPC_PROTOCOL_ERROR
;
416 mds_reply
= dalloc_new(mem_ctx
);
417 if (mds_reply
== NULL
) {
418 status
= NT_STATUS_NO_MEMORY
;
422 ok
= sl_unpack(mds_reply
, (char *)response_blob
.spotlight_blob
,
423 response_blob
.length
);
425 printf("Unpacking Spotlight RPC blob failed\n");
426 status
= NT_STATUS_INTERNAL_ERROR
;
430 printf("%s", dalloc_dump(mds_reply
, 0));
436 /* List of commands exported by this module */
438 struct cmd_set spotlight_commands
[] = {
444 .name
= "fetch_properties",
445 .returntype
= RPC_RTYPE_NTSTATUS
,
446 .ntfn
= cmd_mdssvc_fetch_properties
,
447 .table
= &ndr_table_mdssvc
,
448 .description
= "Fetch connection properties",
452 .name
= "fetch_attributes",
453 .returntype
= RPC_RTYPE_NTSTATUS
,
454 .ntfn
= cmd_mdssvc_fetch_attributes
,
455 .table
= &ndr_table_mdssvc
,
456 .description
= "Fetch attributes for a CNID",