Line data Source code
1 : /*
2 : Unix SMB/CIFS implementation.
3 : RPC Spotlight client
4 :
5 : Copyright (C) Ralph Boehme 2018
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, see <http://www.gnu.org/licenses/>.
19 : */
20 :
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"
28 :
29 0 : static NTSTATUS cmd_mdssvc_fetch_properties(
30 : struct rpc_pipe_client *cli,
31 : TALLOC_CTX *mem_ctx,
32 : int argc, const char **argv)
33 : {
34 0 : struct dcerpc_binding_handle *b = cli->binding_handle;
35 : NTSTATUS status;
36 0 : uint32_t device_id = 0x2f000045;
37 0 : uint32_t unkn1 = 23;
38 0 : uint32_t unkn2 = 0;
39 : struct policy_handle share_handle;
40 0 : 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 0 : 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;
53 :
54 0 : if (argc != 3) {
55 0 : printf("Usage: %s SHARENAME MOUNTPATH\n", argv[0]);
56 0 : return NT_STATUS_OK;
57 : }
58 :
59 0 : status = dcerpc_mdssvc_open(b, mem_ctx,
60 : &device_id,
61 : &unkn1,
62 : &unkn2,
63 0 : argv[2],
64 0 : argv[1],
65 : share_path,
66 : &share_handle);
67 0 : if (!NT_STATUS_IS_OK(status)) {
68 0 : goto done;
69 : }
70 :
71 0 : status = dcerpc_mdssvc_unknown1(b, mem_ctx,
72 : &share_handle,
73 : 0,
74 : device_id,
75 : unkn1,
76 : 0,
77 : geteuid(),
78 : getegid(),
79 : &mds_status,
80 : &flags,
81 : &unkn3);
82 0 : if (!NT_STATUS_IS_OK(status)) {
83 0 : goto done;
84 : }
85 :
86 0 : d = dalloc_new(mem_ctx);
87 0 : if (d == NULL) {
88 0 : status = NT_STATUS_NO_MEMORY;
89 0 : goto done;
90 : }
91 :
92 0 : mds_reply = dalloc_new(mem_ctx);
93 0 : if (mds_reply == NULL) {
94 0 : status = NT_STATUS_NO_MEMORY;
95 0 : goto done;
96 : }
97 :
98 0 : array1 = dalloc_zero(d, sl_array_t);
99 0 : if (array1 == NULL) {
100 0 : status = NT_STATUS_NO_MEMORY;
101 0 : goto done;
102 : }
103 :
104 0 : array2 = dalloc_zero(d, sl_array_t);
105 0 : if (array2 == NULL) {
106 0 : status = NT_STATUS_NO_MEMORY;
107 0 : goto done;
108 : }
109 :
110 0 : result = dalloc_stradd(array2, "fetchPropertiesForContext:");
111 0 : if (result != 0) {
112 0 : status = NT_STATUS_INTERNAL_ERROR;
113 0 : goto done;
114 : }
115 0 : uint64var = talloc_zero_array(mem_ctx, uint64_t, 2);
116 0 : if (uint64var == NULL) {
117 0 : status = NT_STATUS_NO_MEMORY;
118 0 : goto done;
119 : }
120 0 : talloc_set_name(uint64var, "uint64_t *");
121 :
122 0 : result = dalloc_add(array2, &uint64var[0], uint64_t *);
123 0 : if (result != 0) {
124 0 : status = NT_STATUS_INTERNAL_ERROR;
125 0 : goto done;
126 : }
127 :
128 0 : result = dalloc_add(array1, array2, sl_array_t);
129 0 : if (result != 0) {
130 0 : status = NT_STATUS_INTERNAL_ERROR;
131 0 : goto done;
132 : }
133 0 : result = dalloc_add(d, array1, sl_array_t);
134 0 : if (result != 0) {
135 0 : status = NT_STATUS_INTERNAL_ERROR;
136 0 : goto done;
137 : }
138 :
139 0 : status = sl_pack_alloc(mem_ctx, d, &request_blob, max_fragment_size);
140 0 : if (!NT_STATUS_IS_OK(status)) {
141 0 : goto done;
142 : }
143 :
144 0 : status = dcerpc_mdssvc_cmd(b, mem_ctx,
145 : &share_handle,
146 : 0,
147 : device_id,
148 : 23,
149 : 0,
150 : 0x6b000001,
151 : request_blob,
152 : 0,
153 : max_fragment_size,
154 : 1,
155 : max_fragment_size,
156 : 0,
157 : 0,
158 : &mds_status,
159 : &response_blob,
160 : &unkn4);
161 0 : if (!NT_STATUS_IS_OK(status)) {
162 0 : goto done;
163 : }
164 :
165 0 : ok = sl_unpack(mds_reply, (char *)response_blob.spotlight_blob,
166 0 : response_blob.length);
167 0 : if (!ok) {
168 0 : DEBUG(1, ("error unpacking Spotlight RPC blob\n"));
169 0 : status = NT_STATUS_INTERNAL_ERROR;
170 0 : goto done;
171 : }
172 :
173 0 : DEBUG(0, ("%s", dalloc_dump(mds_reply, 0)));
174 :
175 0 : done:
176 0 : return status;
177 : }
178 :
179 0 : static NTSTATUS cmd_mdssvc_fetch_attributes(
180 : struct rpc_pipe_client *cli,
181 : TALLOC_CTX *mem_ctx,
182 : int argc, const char **argv)
183 : {
184 0 : struct dcerpc_binding_handle *b = cli->binding_handle;
185 : NTSTATUS status;
186 0 : uint32_t device_id = 0x2f000045;
187 0 : uint32_t unkn1 = 23;
188 0 : 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 0 : 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;
207 :
208 0 : if (argc != 4) {
209 0 : printf("Usage: %s SHARENAME MOUNTPATH CNID\n", argv[0]);
210 0 : return NT_STATUS_OK;
211 : }
212 :
213 0 : ok = conv_str_u64(argv[3], &cnid);
214 0 : if (!ok) {
215 0 : printf("Failed to parse: %s\n", argv[3]);
216 0 : return NT_STATUS_INVALID_PARAMETER;
217 : }
218 :
219 0 : status = dcerpc_mdssvc_open(b, mem_ctx,
220 : &device_id,
221 : &unkn1,
222 : &unkn2,
223 0 : argv[2],
224 0 : argv[1],
225 : share_path,
226 : &share_handle);
227 0 : if (!NT_STATUS_IS_OK(status)) {
228 0 : goto done;
229 : }
230 :
231 0 : status = dcerpc_mdssvc_unknown1(b, mem_ctx,
232 : &share_handle,
233 : 0,
234 : device_id,
235 : unkn1,
236 : 0,
237 : geteuid(),
238 : getegid(),
239 : &mds_status,
240 : &flags,
241 : &unkn3);
242 0 : if (!NT_STATUS_IS_OK(status)) {
243 0 : goto done;
244 : }
245 :
246 0 : d = dalloc_new(mem_ctx);
247 0 : if (d == NULL) {
248 0 : status = NT_STATUS_NO_MEMORY;
249 0 : goto done;
250 : }
251 :
252 0 : array = dalloc_zero(d, sl_array_t);
253 0 : if (array == NULL) {
254 0 : status = NT_STATUS_NO_MEMORY;
255 0 : goto done;
256 : }
257 :
258 0 : result = dalloc_add(d, array, sl_array_t);
259 0 : if (result != 0) {
260 0 : status = NT_STATUS_INTERNAL_ERROR;
261 0 : goto done;
262 : }
263 :
264 0 : cmd_array = dalloc_zero(d, sl_array_t);
265 0 : if (cmd_array == NULL) {
266 0 : status = NT_STATUS_NO_MEMORY;
267 0 : goto done;
268 : }
269 :
270 0 : result = dalloc_add(array, cmd_array, sl_array_t);
271 0 : if (result != 0) {
272 0 : status = NT_STATUS_INTERNAL_ERROR;
273 0 : goto done;
274 : }
275 :
276 0 : result = dalloc_stradd(cmd_array,
277 : "fetchAttributes:forOIDArray:context:");
278 0 : if (result != 0) {
279 0 : status = NT_STATUS_INTERNAL_ERROR;
280 0 : goto done;
281 : }
282 :
283 0 : uint64var = talloc_zero_array(mem_ctx, uint64_t, 2);
284 0 : if (uint64var == NULL) {
285 0 : status = NT_STATUS_NO_MEMORY;
286 0 : goto done;
287 : }
288 0 : talloc_set_name(uint64var, "uint64_t *");
289 0 : uint64var[0] = 0x500a;
290 0 : uint64var[1] = 0;
291 :
292 0 : result = dalloc_add(cmd_array, &uint64var[0], uint64_t *);
293 0 : if (result != 0) {
294 0 : status = NT_STATUS_INTERNAL_ERROR;
295 0 : goto done;
296 : }
297 :
298 0 : attr_array = dalloc_zero(d, sl_array_t);
299 0 : if (attr_array == NULL) {
300 0 : status = NT_STATUS_NO_MEMORY;
301 0 : goto done;
302 : }
303 :
304 0 : result = dalloc_add(array, attr_array, sl_array_t);
305 0 : if (result != 0) {
306 0 : status = NT_STATUS_INTERNAL_ERROR;
307 0 : goto done;
308 : }
309 :
310 0 : result = dalloc_stradd(attr_array, "kMDItemPath");
311 0 : if (result != 0) {
312 0 : status = NT_STATUS_INTERNAL_ERROR;
313 0 : goto done;
314 : }
315 :
316 : /* CNIDs */
317 0 : cnids = talloc_zero(array, sl_cnids_t);
318 0 : if (cnids == NULL) {
319 0 : status = NT_STATUS_INTERNAL_ERROR;
320 0 : goto done;
321 : }
322 0 : cnids->ca_cnids = dalloc_new(cnids);
323 0 : if (cnids->ca_cnids == NULL) {
324 0 : status = NT_STATUS_INTERNAL_ERROR;
325 0 : goto done;
326 : }
327 :
328 0 : cnids->ca_unkn1 = 0xadd;
329 0 : cnids->ca_context = 0x6b000020;
330 :
331 0 : result = dalloc_add_copy(cnids->ca_cnids, &cnid, uint64_t);
332 0 : if (result != 0) {
333 0 : status = NT_STATUS_INTERNAL_ERROR;
334 0 : goto done;
335 : }
336 :
337 0 : result = dalloc_add(array, cnids, sl_cnids_t);
338 0 : if (result != 0) {
339 0 : status = NT_STATUS_INTERNAL_ERROR;
340 0 : goto done;
341 : }
342 :
343 0 : status = sl_pack_alloc(mem_ctx, d, &request_blob, max_fragment_size);
344 0 : if (!NT_STATUS_IS_OK(status)) {
345 0 : goto done;
346 : }
347 :
348 0 : status = dcerpc_mdssvc_cmd(b, mem_ctx,
349 : &share_handle,
350 : 0,
351 : device_id,
352 : 23,
353 : 0,
354 : 0x6b000001,
355 : request_blob,
356 : 0,
357 : max_fragment_size,
358 : 1,
359 : max_fragment_size,
360 : 0,
361 : 0,
362 : &mds_status,
363 : &response_blob,
364 : &unkn4);
365 0 : if (!NT_STATUS_IS_OK(status)) {
366 0 : printf("dcerpc_mdssvc_cmd failed: %s\n", nt_errstr(status));
367 0 : goto done;
368 : }
369 :
370 0 : if (response_blob.length == 0) {
371 0 : printf("mdssvc returned empty response\n");
372 0 : status = NT_STATUS_RPC_PROTOCOL_ERROR;
373 0 : goto done;
374 : }
375 :
376 0 : mds_reply = dalloc_new(mem_ctx);
377 0 : if (mds_reply == NULL) {
378 0 : status = NT_STATUS_NO_MEMORY;
379 0 : goto done;
380 : }
381 :
382 0 : ok = sl_unpack(mds_reply, (char *)response_blob.spotlight_blob,
383 0 : response_blob.length);
384 0 : if (!ok) {
385 0 : printf("Unpacking Spotlight RPC blob failed\n");
386 0 : status = NT_STATUS_INTERNAL_ERROR;
387 0 : goto done;
388 : }
389 :
390 0 : printf("%s", dalloc_dump(mds_reply, 0));
391 :
392 0 : done:
393 0 : return status;
394 : }
395 :
396 : /* List of commands exported by this module */
397 :
398 : struct cmd_set spotlight_commands[] = {
399 :
400 : {
401 : .name = "MDSSVC"
402 : },
403 : {
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 = "",
410 : },
411 : {
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 = "",
418 : },
419 : {0}
420 : };
|