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
;
46 uint32_t max_fragment_size
= 64 * 1024;
47 DALLOC_CTX
*d
, *mds_reply
;
49 sl_array_t
*array1
, *array2
;
55 printf("Usage: %s SHARENAME MOUNTPATH\n", argv
[0]);
59 status
= dcerpc_mdssvc_open(b
, mem_ctx
,
67 if (!NT_STATUS_IS_OK(status
)) {
71 status
= dcerpc_mdssvc_unknown1(b
, mem_ctx
,
82 if (!NT_STATUS_IS_OK(status
)) {
86 d
= dalloc_new(mem_ctx
);
88 status
= NT_STATUS_NO_MEMORY
;
92 mds_reply
= dalloc_new(mem_ctx
);
93 if (mds_reply
== NULL
) {
94 status
= NT_STATUS_NO_MEMORY
;
98 array1
= dalloc_zero(d
, sl_array_t
);
100 status
= NT_STATUS_NO_MEMORY
;
104 array2
= dalloc_zero(d
, sl_array_t
);
105 if (array2
== NULL
) {
106 status
= NT_STATUS_NO_MEMORY
;
110 result
= dalloc_stradd(array2
, "fetchPropertiesForContext:");
112 status
= NT_STATUS_INTERNAL_ERROR
;
115 uint64var
= talloc_zero_array(mem_ctx
, uint64_t, 2);
116 if (uint64var
== NULL
) {
117 status
= NT_STATUS_NO_MEMORY
;
120 talloc_set_name(uint64var
, "uint64_t *");
122 result
= dalloc_add(array2
, &uint64var
[0], uint64_t *);
124 status
= NT_STATUS_INTERNAL_ERROR
;
128 result
= dalloc_add(array1
, array2
, sl_array_t
);
130 status
= NT_STATUS_INTERNAL_ERROR
;
133 result
= dalloc_add(d
, array1
, sl_array_t
);
135 status
= NT_STATUS_INTERNAL_ERROR
;
139 status
= sl_pack_alloc(mem_ctx
, d
, &request_blob
, max_fragment_size
);
140 if (!NT_STATUS_IS_OK(status
)) {
144 status
= dcerpc_mdssvc_cmd(b
, mem_ctx
,
161 if (!NT_STATUS_IS_OK(status
)) {
165 ok
= sl_unpack(mds_reply
, (char *)response_blob
.spotlight_blob
,
166 response_blob
.length
);
168 DEBUG(1, ("error unpacking Spotlight RPC blob\n"));
169 status
= NT_STATUS_INTERNAL_ERROR
;
173 DEBUG(0, ("%s", dalloc_dump(mds_reply
, 0)));
179 static NTSTATUS
cmd_mdssvc_fetch_attributes(
180 struct rpc_pipe_client
*cli
,
182 int argc
, const char **argv
)
184 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
186 uint32_t device_id
= 0x2f000045;
189 struct policy_handle share_handle
;
190 char share_path
[1025];
192 uint32_t flags
; /* server always returns 0x6b000001 ? */
193 uint32_t unkn3
; /* server always returns 0 ? */
194 struct mdssvc_blob request_blob
;
195 struct mdssvc_blob response_blob
;
196 uint32_t max_fragment_size
= 64 * 1024;
197 DALLOC_CTX
*d
, *mds_reply
;
200 sl_array_t
*cmd_array
;
201 sl_array_t
*attr_array
;
209 printf("Usage: %s SHARENAME MOUNTPATH CNID\n", argv
[0]);
213 ok
= conv_str_u64(argv
[3], &cnid
);
215 printf("Failed to parse: %s\n", argv
[3]);
216 return NT_STATUS_INVALID_PARAMETER
;
219 status
= dcerpc_mdssvc_open(b
, mem_ctx
,
227 if (!NT_STATUS_IS_OK(status
)) {
231 status
= dcerpc_mdssvc_unknown1(b
, mem_ctx
,
242 if (!NT_STATUS_IS_OK(status
)) {
246 d
= dalloc_new(mem_ctx
);
248 status
= NT_STATUS_NO_MEMORY
;
252 array
= dalloc_zero(d
, sl_array_t
);
254 status
= NT_STATUS_NO_MEMORY
;
258 result
= dalloc_add(d
, array
, sl_array_t
);
260 status
= NT_STATUS_INTERNAL_ERROR
;
264 cmd_array
= dalloc_zero(d
, sl_array_t
);
265 if (cmd_array
== NULL
) {
266 status
= NT_STATUS_NO_MEMORY
;
270 result
= dalloc_add(array
, cmd_array
, sl_array_t
);
272 status
= NT_STATUS_INTERNAL_ERROR
;
276 result
= dalloc_stradd(cmd_array
,
277 "fetchAttributes:forOIDArray:context:");
279 status
= NT_STATUS_INTERNAL_ERROR
;
283 uint64var
= talloc_zero_array(mem_ctx
, uint64_t, 2);
284 if (uint64var
== NULL
) {
285 status
= NT_STATUS_NO_MEMORY
;
288 talloc_set_name(uint64var
, "uint64_t *");
289 uint64var
[0] = 0x500a;
292 result
= dalloc_add(cmd_array
, &uint64var
[0], uint64_t *);
294 status
= NT_STATUS_INTERNAL_ERROR
;
298 attr_array
= dalloc_zero(d
, sl_array_t
);
299 if (attr_array
== NULL
) {
300 status
= NT_STATUS_NO_MEMORY
;
304 result
= dalloc_add(array
, attr_array
, sl_array_t
);
306 status
= NT_STATUS_INTERNAL_ERROR
;
310 result
= dalloc_stradd(attr_array
, "kMDItemPath");
312 status
= NT_STATUS_INTERNAL_ERROR
;
317 cnids
= talloc_zero(array
, sl_cnids_t
);
319 status
= NT_STATUS_INTERNAL_ERROR
;
322 cnids
->ca_cnids
= dalloc_new(cnids
);
323 if (cnids
->ca_cnids
== NULL
) {
324 status
= NT_STATUS_INTERNAL_ERROR
;
328 cnids
->ca_unkn1
= 0xadd;
329 cnids
->ca_context
= 0x6b000020;
331 result
= dalloc_add_copy(cnids
->ca_cnids
, &cnid
, uint64_t);
333 status
= NT_STATUS_INTERNAL_ERROR
;
337 result
= dalloc_add(array
, cnids
, sl_cnids_t
);
339 status
= NT_STATUS_INTERNAL_ERROR
;
343 status
= sl_pack_alloc(mem_ctx
, d
, &request_blob
, max_fragment_size
);
344 if (!NT_STATUS_IS_OK(status
)) {
348 status
= dcerpc_mdssvc_cmd(b
, mem_ctx
,
365 if (!NT_STATUS_IS_OK(status
)) {
366 printf("dcerpc_mdssvc_cmd failed: %s\n", nt_errstr(status
));
370 if (response_blob
.length
== 0) {
371 printf("mdssvc returned empty response\n");
372 status
= NT_STATUS_RPC_PROTOCOL_ERROR
;
376 mds_reply
= dalloc_new(mem_ctx
);
377 if (mds_reply
== NULL
) {
378 status
= NT_STATUS_NO_MEMORY
;
382 ok
= sl_unpack(mds_reply
, (char *)response_blob
.spotlight_blob
,
383 response_blob
.length
);
385 printf("Unpacking Spotlight RPC blob failed\n");
386 status
= NT_STATUS_INTERNAL_ERROR
;
390 printf("%s", dalloc_dump(mds_reply
, 0));
396 /* List of commands exported by this module */
398 struct cmd_set spotlight_commands
[] = {
404 .name
= "fetch_properties",
405 .returntype
= RPC_RTYPE_NTSTATUS
,
406 .ntfn
= cmd_mdssvc_fetch_properties
,
407 .table
= &ndr_table_mdssvc
,
408 .description
= "Fetch connection properties",
412 .name
= "fetch_attributes",
413 .returntype
= RPC_RTYPE_NTSTATUS
,
414 .ntfn
= cmd_mdssvc_fetch_attributes
,
415 .table
= &ndr_table_mdssvc
,
416 .description
= "Fetch attributes for a CNID",