rpc_server3: Use fdopen_keepfd()
[Samba.git] / source3 / rpcclient / cmd_spotlight.c
blobba3f61fd4b0603f167b605d348d446a3bcffd8fb
1 /*
2 Unix SMB/CIFS implementation.
3 RPC Spotlight client
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/>.
21 #include "includes.h"
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,
31 TALLOC_CTX *mem_ctx,
32 int argc, const char **argv)
34 struct dcerpc_binding_handle *b = cli->binding_handle;
35 NTSTATUS status;
36 uint32_t device_id = 0x2f000045;
37 uint32_t unkn1 = 23;
38 uint32_t unkn2 = 0;
39 struct policy_handle share_handle;
40 char share_path[1025] = { 0 };
41 uint32_t mds_status;
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;
48 uint64_t *uint64var;
49 sl_array_t *array1, *array2;
50 uint32_t unkn4;
51 int result;
52 bool ok;
54 if (argc != 3) {
55 printf("Usage: %s SHARENAME MOUNTPATH\n", argv[0]);
56 return NT_STATUS_OK;
59 status = dcerpc_mdssvc_open(b, mem_ctx,
60 &device_id,
61 &unkn1,
62 &unkn2,
63 argv[2],
64 argv[1],
65 share_path,
66 &share_handle);
67 if (!NT_STATUS_IS_OK(status)) {
68 goto done;
71 status = dcerpc_mdssvc_unknown1(b, mem_ctx,
72 &share_handle,
74 device_id,
75 unkn1,
77 geteuid(),
78 getegid(),
79 &mds_status,
80 &flags,
81 &unkn3);
82 if (!NT_STATUS_IS_OK(status)) {
83 goto done;
86 d = dalloc_new(mem_ctx);
87 if (d == NULL) {
88 status = NT_STATUS_NO_MEMORY;
89 goto done;
92 mds_reply = dalloc_new(mem_ctx);
93 if (mds_reply == NULL) {
94 status = NT_STATUS_NO_MEMORY;
95 goto done;
98 array1 = dalloc_zero(d, sl_array_t);
99 if (array1 == NULL) {
100 status = NT_STATUS_NO_MEMORY;
101 goto done;
104 array2 = dalloc_zero(d, sl_array_t);
105 if (array2 == NULL) {
106 status = NT_STATUS_NO_MEMORY;
107 goto done;
110 result = dalloc_stradd(array2, "fetchPropertiesForContext:");
111 if (result != 0) {
112 status = NT_STATUS_INTERNAL_ERROR;
113 goto done;
115 uint64var = talloc_zero_array(mem_ctx, uint64_t, 2);
116 if (uint64var == NULL) {
117 status = NT_STATUS_NO_MEMORY;
118 goto done;
120 talloc_set_name(uint64var, "uint64_t *");
122 result = dalloc_add(array2, &uint64var[0], uint64_t *);
123 if (result != 0) {
124 status = NT_STATUS_INTERNAL_ERROR;
125 goto done;
128 result = dalloc_add(array1, array2, sl_array_t);
129 if (result != 0) {
130 status = NT_STATUS_INTERNAL_ERROR;
131 goto done;
133 result = dalloc_add(d, array1, sl_array_t);
134 if (result != 0) {
135 status = NT_STATUS_INTERNAL_ERROR;
136 goto done;
139 status = sl_pack_alloc(mem_ctx, d, &request_blob, max_fragment_size);
140 if (!NT_STATUS_IS_OK(status)) {
141 goto done;
144 status = dcerpc_mdssvc_cmd(b, mem_ctx,
145 &share_handle,
147 device_id,
150 0x6b000001,
151 request_blob,
153 max_fragment_size,
155 max_fragment_size,
158 &mds_status,
159 &response_blob,
160 &unkn4);
161 if (!NT_STATUS_IS_OK(status)) {
162 goto done;
165 ok = sl_unpack(mds_reply, (char *)response_blob.spotlight_blob,
166 response_blob.length);
167 if (!ok) {
168 DEBUG(1, ("error unpacking Spotlight RPC blob\n"));
169 status = NT_STATUS_INTERNAL_ERROR;
170 goto done;
173 DEBUG(0, ("%s", dalloc_dump(mds_reply, 0)));
175 done:
176 return status;
179 static NTSTATUS cmd_mdssvc_fetch_attributes(
180 struct rpc_pipe_client *cli,
181 TALLOC_CTX *mem_ctx,
182 int argc, const char **argv)
184 struct dcerpc_binding_handle *b = cli->binding_handle;
185 NTSTATUS status;
186 uint32_t device_id = 0x2f000045;
187 uint32_t unkn1 = 23;
188 uint32_t unkn2 = 0;
189 struct policy_handle share_handle;
190 char share_path[1025];
191 uint32_t mds_status;
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;
198 uint64_t *uint64var;
199 sl_array_t *array;
200 sl_array_t *cmd_array;
201 sl_array_t *attr_array;
202 sl_cnids_t *cnids;
203 uint64_t cnid;
204 uint32_t unkn4;
205 int result;
206 bool ok;
208 if (argc != 4) {
209 printf("Usage: %s SHARENAME MOUNTPATH CNID\n", argv[0]);
210 return NT_STATUS_OK;
213 ok = conv_str_u64(argv[3], &cnid);
214 if (!ok) {
215 printf("Failed to parse: %s\n", argv[3]);
216 return NT_STATUS_INVALID_PARAMETER;
219 status = dcerpc_mdssvc_open(b, mem_ctx,
220 &device_id,
221 &unkn1,
222 &unkn2,
223 argv[2],
224 argv[1],
225 share_path,
226 &share_handle);
227 if (!NT_STATUS_IS_OK(status)) {
228 goto done;
231 status = dcerpc_mdssvc_unknown1(b, mem_ctx,
232 &share_handle,
234 device_id,
235 unkn1,
237 geteuid(),
238 getegid(),
239 &mds_status,
240 &flags,
241 &unkn3);
242 if (!NT_STATUS_IS_OK(status)) {
243 goto done;
246 d = dalloc_new(mem_ctx);
247 if (d == NULL) {
248 status = NT_STATUS_NO_MEMORY;
249 goto done;
252 array = dalloc_zero(d, sl_array_t);
253 if (array == NULL) {
254 status = NT_STATUS_NO_MEMORY;
255 goto done;
258 result = dalloc_add(d, array, sl_array_t);
259 if (result != 0) {
260 status = NT_STATUS_INTERNAL_ERROR;
261 goto done;
264 cmd_array = dalloc_zero(d, sl_array_t);
265 if (cmd_array == NULL) {
266 status = NT_STATUS_NO_MEMORY;
267 goto done;
270 result = dalloc_add(array, cmd_array, sl_array_t);
271 if (result != 0) {
272 status = NT_STATUS_INTERNAL_ERROR;
273 goto done;
276 result = dalloc_stradd(cmd_array,
277 "fetchAttributes:forOIDArray:context:");
278 if (result != 0) {
279 status = NT_STATUS_INTERNAL_ERROR;
280 goto done;
283 uint64var = talloc_zero_array(mem_ctx, uint64_t, 2);
284 if (uint64var == NULL) {
285 status = NT_STATUS_NO_MEMORY;
286 goto done;
288 talloc_set_name(uint64var, "uint64_t *");
289 uint64var[0] = 0x500a;
290 uint64var[1] = 0;
292 result = dalloc_add(cmd_array, &uint64var[0], uint64_t *);
293 if (result != 0) {
294 status = NT_STATUS_INTERNAL_ERROR;
295 goto done;
298 attr_array = dalloc_zero(d, sl_array_t);
299 if (attr_array == NULL) {
300 status = NT_STATUS_NO_MEMORY;
301 goto done;
304 result = dalloc_add(array, attr_array, sl_array_t);
305 if (result != 0) {
306 status = NT_STATUS_INTERNAL_ERROR;
307 goto done;
310 result = dalloc_stradd(attr_array, "kMDItemPath");
311 if (result != 0) {
312 status = NT_STATUS_INTERNAL_ERROR;
313 goto done;
316 /* CNIDs */
317 cnids = talloc_zero(array, sl_cnids_t);
318 if (cnids == NULL) {
319 status = NT_STATUS_INTERNAL_ERROR;
320 goto done;
322 cnids->ca_cnids = dalloc_new(cnids);
323 if (cnids->ca_cnids == NULL) {
324 status = NT_STATUS_INTERNAL_ERROR;
325 goto done;
328 cnids->ca_unkn1 = 0xadd;
329 cnids->ca_context = 0x6b000020;
331 result = dalloc_add_copy(cnids->ca_cnids, &cnid, uint64_t);
332 if (result != 0) {
333 status = NT_STATUS_INTERNAL_ERROR;
334 goto done;
337 result = dalloc_add(array, cnids, sl_cnids_t);
338 if (result != 0) {
339 status = NT_STATUS_INTERNAL_ERROR;
340 goto done;
343 status = sl_pack_alloc(mem_ctx, d, &request_blob, max_fragment_size);
344 if (!NT_STATUS_IS_OK(status)) {
345 goto done;
348 status = dcerpc_mdssvc_cmd(b, mem_ctx,
349 &share_handle,
351 device_id,
354 0x6b000001,
355 request_blob,
357 max_fragment_size,
359 max_fragment_size,
362 &mds_status,
363 &response_blob,
364 &unkn4);
365 if (!NT_STATUS_IS_OK(status)) {
366 printf("dcerpc_mdssvc_cmd failed: %s\n", nt_errstr(status));
367 goto done;
370 if (response_blob.length == 0) {
371 printf("mdssvc returned empty response\n");
372 status = NT_STATUS_RPC_PROTOCOL_ERROR;
373 goto done;
376 mds_reply = dalloc_new(mem_ctx);
377 if (mds_reply == NULL) {
378 status = NT_STATUS_NO_MEMORY;
379 goto done;
382 ok = sl_unpack(mds_reply, (char *)response_blob.spotlight_blob,
383 response_blob.length);
384 if (!ok) {
385 printf("Unpacking Spotlight RPC blob failed\n");
386 status = NT_STATUS_INTERNAL_ERROR;
387 goto done;
390 printf("%s", dalloc_dump(mds_reply, 0));
392 done:
393 return status;
396 /* List of commands exported by this module */
398 struct cmd_set spotlight_commands[] = {
401 .name = "MDSSVC"
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",
409 .usage = "",
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",
417 .usage = "",