mdscli: correct handling of in-progress searches
[samba.git] / source3 / rpc_client / cli_mdssvc_util.c
1 /*
2    Unix SMB/CIFS implementation.
3    Main metadata server / Spotlight client functions
4
5    Copyright (C) Ralph Boehme 2019
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 "rpc_client.h"
23 #include "librpc/gen_ndr/mdssvc.h"
24 #include "cli_mdssvc.h"
25 #include "cli_mdssvc_private.h"
26 #include "cli_mdssvc_util.h"
27 #include "lib/util/tevent_ntstatus.h"
28 #include "rpc_server/mdssvc/dalloc.h"
29 #include "rpc_server/mdssvc/marshalling.h"
30
31 NTSTATUS mdscli_blob_fetch_props(TALLOC_CTX *mem_ctx,
32                                  struct mdscli_ctx *ctx,
33                                  struct mdssvc_blob *blob)
34 {
35         DALLOC_CTX *d = NULL;
36         uint64_t *uint64p = NULL;
37         sl_array_t *array = NULL;
38         sl_array_t *cmd_array = NULL;
39         NTSTATUS status;
40         int ret;
41
42         d = dalloc_new(mem_ctx);
43         if (d == NULL) {
44                 return NT_STATUS_NO_MEMORY;
45         }
46
47         array = dalloc_zero(d, sl_array_t);
48         if (array == NULL) {
49                 TALLOC_FREE(d);
50                 return NT_STATUS_NO_MEMORY;
51         }
52
53         ret = dalloc_add(d, array, sl_array_t);
54         if (ret != 0) {
55                 TALLOC_FREE(d);
56                 return NT_STATUS_NO_MEMORY;
57         }
58
59         cmd_array = dalloc_zero(d, sl_array_t);
60         if (cmd_array == NULL) {
61                 TALLOC_FREE(d);
62                 return NT_STATUS_NO_MEMORY;
63         }
64
65         ret = dalloc_add(array, cmd_array, sl_array_t);
66         if (ret != 0) {
67                 TALLOC_FREE(d);
68                 return NT_STATUS_NO_MEMORY;
69         }
70
71         ret = dalloc_stradd(cmd_array, "fetchPropertiesForContext:");
72         if (ret != 0) {
73                 TALLOC_FREE(d);
74                 return NT_STATUS_NO_MEMORY;
75         }
76
77         uint64p = talloc_zero_array(cmd_array, uint64_t, 2);
78         if (uint64p == NULL) {
79                 TALLOC_FREE(d);
80                 return NT_STATUS_NO_MEMORY;
81         }
82
83         talloc_set_name(uint64p, "uint64_t *");
84
85         ret = dalloc_add(cmd_array, uint64p, uint64_t *);
86         if (ret != 0) {
87                 TALLOC_FREE(d);
88                 return NT_STATUS_NO_MEMORY;
89         }
90
91         status = sl_pack_alloc(mem_ctx, d, blob, ctx->max_fragment_size);
92         TALLOC_FREE(d);
93         if (!NT_STATUS_IS_OK(status)) {
94                 return status;
95         }
96         return NT_STATUS_OK;
97 }
98
99 NTSTATUS mdscli_blob_search(TALLOC_CTX *mem_ctx,
100                             struct mdscli_search_ctx *search,
101                             struct mdssvc_blob *blob)
102 {
103         struct mdscli_ctx *ctx = search->mdscli_ctx;
104         DALLOC_CTX *d = NULL;
105         uint64_t *uint64p = NULL;
106         sl_array_t *array = NULL;
107         sl_array_t *cmd_array = NULL;
108         sl_dict_t *query_dict = NULL;
109         sl_array_t *attr_array = NULL;
110         sl_array_t *scope_array = NULL;
111         double dval;
112         uint64_t uint64val;
113         NTSTATUS status;
114         int ret;
115
116         d = dalloc_new(mem_ctx);
117         if (d == NULL) {
118                 return NT_STATUS_NO_MEMORY;
119         }
120
121         array = dalloc_zero(d, sl_array_t);
122         if (array == NULL) {
123                 TALLOC_FREE(d);
124                 return NT_STATUS_NO_MEMORY;
125         }
126
127         ret = dalloc_add(d, array, sl_array_t);
128         if (ret != 0) {
129                 TALLOC_FREE(d);
130                 return NT_STATUS_NO_MEMORY;
131         }
132
133         cmd_array = dalloc_zero(d, sl_array_t);
134         if (cmd_array == NULL) {
135                 TALLOC_FREE(d);
136                 return NT_STATUS_NO_MEMORY;
137         }
138
139         ret = dalloc_add(array, cmd_array, sl_array_t);
140         if (ret != 0) {
141                 TALLOC_FREE(d);
142                 return NT_STATUS_NO_MEMORY;
143         }
144
145         ret = dalloc_stradd(cmd_array, "openQueryWithParams:forContext:");
146         if (ret != 0) {
147                 TALLOC_FREE(d);
148                 return NT_STATUS_NO_MEMORY;
149         }
150
151         uint64p = talloc_zero_array(cmd_array, uint64_t, 2);
152         if (uint64p == NULL) {
153                 TALLOC_FREE(d);
154                 return NT_STATUS_NO_MEMORY;
155         }
156
157         talloc_set_name(uint64p, "uint64_t *");
158
159         uint64p[0] = search->ctx_id.id;
160         uint64p[1] = search->ctx_id.connection;
161
162         ret = dalloc_add(cmd_array, uint64p, uint64_t *);
163         if (ret != 0) {
164                 TALLOC_FREE(d);
165                 return NT_STATUS_NO_MEMORY;
166         }
167
168         query_dict = dalloc_zero(array, sl_dict_t);
169         if (query_dict == NULL) {
170                 TALLOC_FREE(d);
171                 return NT_STATUS_NO_MEMORY;
172         }
173
174         ret = dalloc_add(array, query_dict, sl_dict_t);
175         if (ret != 0) {
176                 TALLOC_FREE(d);
177                 return NT_STATUS_NO_MEMORY;
178         }
179
180         ret = dalloc_stradd(query_dict, "kMDQueryBatchFirstDelay");
181         if (ret != 0) {
182                 TALLOC_FREE(d);
183                 return NT_STATUS_NO_MEMORY;
184         }
185         dval = 1;
186         ret = dalloc_add_copy(query_dict, &dval, double);
187         if (ret != 0) {
188                 TALLOC_FREE(d);
189                 return NT_STATUS_NO_MEMORY;
190         }
191
192         ret = dalloc_stradd(query_dict, "kMDQueryUniqueId");
193         if (ret != 0) {
194                 TALLOC_FREE(d);
195                 return NT_STATUS_NO_MEMORY;
196         }
197         ret = dalloc_add_copy(query_dict, &search->unique_id, uint64_t);
198         if (ret != 0) {
199                 TALLOC_FREE(d);
200                 return NT_STATUS_NO_MEMORY;
201         }
202
203         ret = dalloc_stradd(query_dict, "kMDAttributeArray");
204         if (ret != 0) {
205                 TALLOC_FREE(d);
206                 return NT_STATUS_NO_MEMORY;
207         }
208         attr_array = dalloc_zero(query_dict, sl_array_t);
209         if (attr_array == NULL) {
210                 TALLOC_FREE(d);
211                 return NT_STATUS_NO_MEMORY;
212         }
213         ret = dalloc_add(query_dict, attr_array, sl_array_t);
214         if (ret != 0) {
215                 TALLOC_FREE(d);
216                 return NT_STATUS_NO_MEMORY;
217         }
218         ret = dalloc_stradd(attr_array, "kMDItemFSName");
219         if (ret != 0) {
220                 TALLOC_FREE(d);
221                 return NT_STATUS_NO_MEMORY;
222         }
223
224         ret = dalloc_stradd(query_dict, "kMDQueryBatchFirstCount");
225         if (ret != 0) {
226                 TALLOC_FREE(d);
227                 return NT_STATUS_NO_MEMORY;
228         }
229         uint64val = 10;
230         ret = dalloc_add_copy(query_dict, &uint64val, uint64_t);
231         if (ret != 0) {
232                 TALLOC_FREE(d);
233                 return NT_STATUS_NO_MEMORY;
234         }
235
236         ret = dalloc_stradd(query_dict, "kMDQueryBatchUpdateCount");
237         if (ret != 0) {
238                 TALLOC_FREE(d);
239                 return NT_STATUS_NO_MEMORY;
240         }
241         uint64val = 100;
242         ret = dalloc_add_copy(query_dict, &uint64val, uint64_t);
243         if (ret != 0) {
244                 TALLOC_FREE(d);
245                 return NT_STATUS_NO_MEMORY;
246         }
247
248         ret = dalloc_stradd(query_dict, "kMDQueryString");
249         if (ret != 0) {
250                 TALLOC_FREE(d);
251                 return NT_STATUS_NO_MEMORY;
252         }
253         ret = dalloc_stradd(query_dict, search->mds_query);
254         if (ret != 0) {
255                 TALLOC_FREE(d);
256                 return NT_STATUS_NO_MEMORY;
257         }
258
259         ret = dalloc_stradd(query_dict, "kMDScopeArray");
260         if (ret != 0) {
261                 TALLOC_FREE(d);
262                 return NT_STATUS_NO_MEMORY;
263         }
264         scope_array = dalloc_zero(query_dict, sl_array_t);
265         if (scope_array == NULL) {
266                 TALLOC_FREE(d);
267                 return NT_STATUS_NO_MEMORY;
268         }
269         ret = dalloc_add(query_dict, scope_array, sl_array_t);
270         if (ret != 0) {
271                 TALLOC_FREE(d);
272                 return NT_STATUS_NO_MEMORY;
273         }
274         ret = dalloc_stradd(scope_array, search->path_scope);
275         if (ret != 0) {
276                 TALLOC_FREE(d);
277                 return NT_STATUS_NO_MEMORY;
278         }
279
280         status = sl_pack_alloc(mem_ctx, d, blob, ctx->max_fragment_size);
281         TALLOC_FREE(d);
282         if (!NT_STATUS_IS_OK(status)) {
283                 return status;
284         }
285         return NT_STATUS_OK;
286 }
287
288 NTSTATUS mdscli_blob_get_results(TALLOC_CTX *mem_ctx,
289                                  struct mdscli_search_ctx *search,
290                                  struct mdssvc_blob *blob)
291 {
292         struct mdscli_ctx *ctx = search->mdscli_ctx;
293         DALLOC_CTX *d = NULL;
294         uint64_t *uint64p = NULL;
295         sl_array_t *array = NULL;
296         sl_array_t *cmd_array = NULL;
297         NTSTATUS status;
298         int ret;
299
300         d = dalloc_new(mem_ctx);
301         if (d == NULL) {
302                 return NT_STATUS_NO_MEMORY;
303         }
304
305         array = dalloc_zero(d, sl_array_t);
306         if (array == NULL) {
307                 TALLOC_FREE(d);
308                 return NT_STATUS_NO_MEMORY;
309         }
310
311         ret = dalloc_add(d, array, sl_array_t);
312         if (ret != 0) {
313                 TALLOC_FREE(d);
314                 return NT_STATUS_NO_MEMORY;
315         }
316
317         cmd_array = dalloc_zero(d, sl_array_t);
318         if (cmd_array == NULL) {
319                 TALLOC_FREE(d);
320                 return NT_STATUS_NO_MEMORY;
321         }
322
323         ret = dalloc_add(array, cmd_array, sl_array_t);
324         if (ret != 0) {
325                 TALLOC_FREE(d);
326                 return NT_STATUS_NO_MEMORY;
327         }
328
329         ret = dalloc_stradd(cmd_array, "fetchQueryResultsForContext:");
330         if (ret != 0) {
331                 TALLOC_FREE(d);
332                 return NT_STATUS_NO_MEMORY;
333         }
334
335         uint64p = talloc_zero_array(cmd_array, uint64_t, 2);
336         if (uint64p == NULL) {
337                 TALLOC_FREE(d);
338                 return NT_STATUS_NO_MEMORY;
339         }
340
341         talloc_set_name(uint64p, "uint64_t *");
342
343         uint64p[0] = search->ctx_id.id;
344         uint64p[1] = search->ctx_id.connection;
345
346         ret = dalloc_add(cmd_array, uint64p, uint64_t *);
347         if (ret != 0) {
348                 TALLOC_FREE(d);
349                 return NT_STATUS_NO_MEMORY;
350         }
351
352         status = sl_pack_alloc(mem_ctx, d, blob, ctx->max_fragment_size);
353         TALLOC_FREE(d);
354         if (!NT_STATUS_IS_OK(status)) {
355                 return status;
356         }
357         return NT_STATUS_OK;
358 }
359
360 NTSTATUS mdscli_blob_get_path(TALLOC_CTX *mem_ctx,
361                               struct mdscli_ctx *ctx,
362                               uint64_t cnid,
363                               struct mdssvc_blob *blob)
364 {
365         struct mdsctx_id ctx_id = mdscli_new_ctx_id(ctx);
366         DALLOC_CTX *d = NULL;
367         uint64_t *uint64var = NULL;
368         sl_array_t *array = NULL;
369         sl_array_t *cmd_array = NULL;
370         sl_array_t *attr_array = NULL;
371         sl_cnids_t *cnids = NULL;
372         NTSTATUS status;
373         int ret;
374
375         d = dalloc_new(mem_ctx);
376         if (d == NULL) {
377                 return NT_STATUS_NO_MEMORY;
378         }
379
380         array = dalloc_zero(d, sl_array_t);
381         if (array == NULL) {
382                 TALLOC_FREE(d);
383                 return NT_STATUS_NO_MEMORY;
384         }
385
386         ret = dalloc_add(d, array, sl_array_t);
387         if (ret != 0) {
388                 TALLOC_FREE(d);
389                 return NT_STATUS_NO_MEMORY;
390         }
391
392         cmd_array = dalloc_zero(d, sl_array_t);
393         if (cmd_array == NULL) {
394                 TALLOC_FREE(d);
395                 return NT_STATUS_NO_MEMORY;
396         }
397
398         ret = dalloc_add(array, cmd_array, sl_array_t);
399         if (ret != 0) {
400                 TALLOC_FREE(d);
401                 return NT_STATUS_NO_MEMORY;
402         }
403
404         ret = dalloc_stradd(cmd_array, "fetchAttributes:forOIDArray:context:");
405         if (ret != 0) {
406                 TALLOC_FREE(d);
407                 return NT_STATUS_NO_MEMORY;
408         }
409
410         uint64var = talloc_zero_array(cmd_array, uint64_t, 2);
411         if (uint64var == NULL) {
412                 TALLOC_FREE(d);
413                 return NT_STATUS_NO_MEMORY;
414         }
415
416         talloc_set_name(uint64var, "uint64_t *");
417
418         uint64var[0] = ctx_id.id;
419         uint64var[1] = 0;
420
421         ret = dalloc_add(cmd_array, &uint64var[0], uint64_t *);
422         if (ret != 0) {
423                 TALLOC_FREE(d);
424                 return NT_STATUS_NO_MEMORY;
425         }
426
427         attr_array = dalloc_zero(d, sl_array_t);
428         if (attr_array == NULL) {
429                 TALLOC_FREE(d);
430                 return NT_STATUS_NO_MEMORY;
431         }
432
433         ret = dalloc_add(array, attr_array, sl_array_t);
434         if (ret != 0) {
435                 TALLOC_FREE(d);
436                 return NT_STATUS_NO_MEMORY;
437         }
438
439         ret = dalloc_stradd(attr_array, "kMDItemPath");
440         if (ret != 0) {
441                 TALLOC_FREE(d);
442                 return NT_STATUS_NO_MEMORY;
443         }
444
445         /* CNIDs */
446         cnids = talloc_zero(array, sl_cnids_t);
447         if (cnids == NULL) {
448                 TALLOC_FREE(d);
449                 return NT_STATUS_NO_MEMORY;
450         }
451
452         cnids->ca_cnids = dalloc_new(cnids);
453         if (cnids->ca_cnids == NULL) {
454                 TALLOC_FREE(d);
455                 return NT_STATUS_NO_MEMORY;
456         }
457
458         cnids->ca_unkn1 = 0xadd;
459         cnids->ca_context = 0x6b000020;
460
461         ret = dalloc_add_copy(cnids->ca_cnids, &cnid, uint64_t);
462         if (ret != 0) {
463                 TALLOC_FREE(d);
464                 return NT_STATUS_NO_MEMORY;
465         }
466
467         ret = dalloc_add(array, cnids, sl_cnids_t);
468         if (ret != 0) {
469                 TALLOC_FREE(d);
470                 return NT_STATUS_NO_MEMORY;
471         }
472
473         status = sl_pack_alloc(mem_ctx, d, blob, ctx->max_fragment_size);
474         TALLOC_FREE(d);
475         if (!NT_STATUS_IS_OK(status)) {
476                 return status;
477         }
478         return NT_STATUS_OK;
479 }
480
481 NTSTATUS mdscli_blob_close_search(TALLOC_CTX *mem_ctx,
482                                   struct mdscli_search_ctx *search,
483                                   struct mdssvc_blob *blob)
484 {
485         struct mdscli_ctx *ctx = search->mdscli_ctx;
486         DALLOC_CTX *d = NULL;
487         uint64_t *uint64p = NULL;
488         sl_array_t *array = NULL;
489         sl_array_t *cmd_array = NULL;
490         NTSTATUS status;
491         int ret;
492
493         d = dalloc_new(mem_ctx);
494         if (d == NULL) {
495                 return NT_STATUS_NO_MEMORY;
496         }
497
498         array = dalloc_zero(d, sl_array_t);
499         if (array == NULL) {
500                 TALLOC_FREE(d);
501                 return NT_STATUS_NO_MEMORY;
502         }
503
504         ret = dalloc_add(d, array, sl_array_t);
505         if (ret != 0) {
506                 TALLOC_FREE(d);
507                 return NT_STATUS_NO_MEMORY;
508         }
509
510         cmd_array = dalloc_zero(d, sl_array_t);
511         if (cmd_array == NULL) {
512                 TALLOC_FREE(d);
513                 return NT_STATUS_NO_MEMORY;
514         }
515
516         ret = dalloc_add(array, cmd_array, sl_array_t);
517         if (ret != 0) {
518                 TALLOC_FREE(d);
519                 return NT_STATUS_NO_MEMORY;
520         }
521
522         ret = dalloc_stradd(cmd_array, "closeQueryForContext:");
523         if (ret != 0) {
524                 TALLOC_FREE(d);
525                 return NT_STATUS_NO_MEMORY;
526         }
527
528         uint64p = talloc_zero_array(cmd_array, uint64_t, 2);
529         if (uint64p == NULL) {
530                 TALLOC_FREE(d);
531                 return NT_STATUS_NO_MEMORY;
532         }
533
534         talloc_set_name(uint64p, "uint64_t *");
535
536         uint64p[0] = search->ctx_id.id;
537         uint64p[1] = search->ctx_id.connection;
538
539         ret = dalloc_add(cmd_array, uint64p, uint64_t *);
540         if (ret != 0) {
541                 TALLOC_FREE(d);
542                 return NT_STATUS_NO_MEMORY;
543         }
544
545         status = sl_pack_alloc(mem_ctx, d, blob, ctx->max_fragment_size);
546         TALLOC_FREE(d);
547         if (!NT_STATUS_IS_OK(status)) {
548                 return status;
549         }
550         return NT_STATUS_OK;
551 }