build: Notice if flex is missing at configure time
[bbaumbach/samba-autobuild/.git] / source3 / utils / mdfind.c
1 /*
2  * Copyright (C) 2019, Ralph Boehme <slow@samba.org.>
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17  * Boston, MA  02110-1301, USA.
18  */
19
20 #include "includes.h"
21 #include "lib/util/debug.h"
22 #include "popt_common.h"
23 #include "popt_common_cmdline.h"
24 #include "lib/cmdline_contexts.h"
25 #include "param.h"
26 #include "auth_info.h"
27 #include "client.h"
28 #include "libsmb/proto.h"
29 #include "librpc/rpc/rpc_common.h"
30 #include "rpc_client/cli_pipe.h"
31 #include "rpc_client/cli_mdssvc.h"
32 #include "librpc/gen_ndr/ndr_mdssvc_c.h"
33
34 static char *opt_path;
35 static int opt_live;
36
37 static struct poptOption long_options[] = {
38         POPT_AUTOHELP
39         {
40                 .longName  = "path",
41                 .shortName = 'p',
42                 .argInfo   = POPT_ARG_STRING,
43                 .arg       = &opt_path,
44                 .descrip   = "Server-relative search path",
45         },
46         {
47                 .longName  = "live",
48                 .shortName = 'L',
49                 .argInfo   = POPT_ARG_NONE,
50                 .arg       = &opt_live,
51                 .descrip   = "live query",
52         },
53         POPT_COMMON_SAMBA
54         POPT_COMMON_CREDENTIALS
55         POPT_TABLEEND
56 };
57
58 int main(int argc, char **argv)
59 {
60         const char **const_argv = discard_const_p(const char *, argv);
61         TALLOC_CTX *frame = talloc_stackframe();
62         struct tevent_context *ev = NULL;
63         struct user_auth_info *auth = NULL;
64         struct cli_credentials *creds = NULL;
65         struct rpc_pipe_client *rpccli = NULL;
66         struct mdscli_ctx *mdscli_ctx = NULL;
67         struct mdscli_search_ctx *search = NULL;
68         const char *server = NULL;
69         const char *share = NULL;
70         const char *mds_query = NULL;
71         struct cli_state *cli = NULL;
72         char *basepath = NULL;
73         uint32_t flags = CLI_FULL_CONNECTION_IPC;
74         int signing_state = SMB_SIGNING_IPC_DEFAULT;
75         uint64_t *cnids = NULL;
76         size_t ncnids;
77         size_t i;
78         int opt;
79         poptContext pc;
80         NTSTATUS status;
81         bool ok;
82
83         setup_logging(argv[0], DEBUG_STDERR);
84         smb_init_locale();
85         lp_set_cmdline("log level", "1");
86
87         pc = poptGetContext(argv[0],
88                             argc,
89                             const_argv,
90                             long_options,
91                             POPT_CONTEXT_KEEP_FIRST);
92
93         poptSetOtherOptionHelp(pc, "mdfind [OPTIONS] <server> <share> <query>\n");
94
95         while ((opt = poptGetNextOpt(pc)) != -1) {
96                 DBG_ERR("Invalid option %s: %s\n",
97                         poptBadOption(pc, 0),
98                         poptStrerror(opt));
99                 poptPrintHelp(pc, stderr, 0);
100                 goto fail;
101         }
102
103         poptGetArg(pc); /* Drop argv[0], the program name */
104         server = poptGetArg(pc);
105         share = poptGetArg(pc);
106         mds_query = poptGetArg(pc);
107
108         if (server == NULL || mds_query == NULL) {
109                 poptPrintHelp(pc, stderr, 0);
110                 goto fail;
111         }
112
113         popt_burn_cmdline_password(argc, argv);
114
115         if ((server[0] == '/' && server[1] == '/') ||
116             (server[0] == '\\' && server[1] ==  '\\'))
117         {
118                 server += 2;
119         }
120
121         auth = popt_get_cmdline_auth_info();
122         creds = get_cmdline_auth_info_creds(auth);
123
124         signing_state = get_cmdline_auth_info_signing_state(auth);
125         switch (signing_state) {
126         case SMB_SIGNING_OFF:
127                 lp_set_cmdline("client ipc signing", "no");
128                 break;
129         case SMB_SIGNING_REQUIRED:
130                 lp_set_cmdline("client ipc signing", "required");
131                 break;
132         }
133
134         ev = samba_tevent_context_init(frame);
135         if (ev == NULL) {
136                 goto fail;
137         }
138
139         cmdline_messaging_context(get_dyn_CONFIGFILE());
140
141         ok = lp_load_client(get_dyn_CONFIGFILE());
142         if (!ok) {
143                 fprintf(stderr, "ERROR: Can't load %s\n",
144                         get_dyn_CONFIGFILE());
145                 exit(1);
146         }
147
148         status = cli_full_connection_creds(&cli,
149                                            lp_netbios_name(),
150                                            server,
151                                            NULL,
152                                            0,
153                                            "IPC$",
154                                            "IPC",
155                                            creds,
156                                            flags);
157         if (!NT_STATUS_IS_OK(status)) {
158                 DBG_ERR("Cannot connect to server: %s\n", nt_errstr(status));
159                 goto fail;
160         }
161
162         status = cli_rpc_pipe_open_noauth(cli, &ndr_table_mdssvc, &rpccli);
163         if (!NT_STATUS_IS_OK(status)) {
164                 goto fail;
165         }
166
167         status = mdscli_connect(frame,
168                                 rpccli->binding_handle,
169                                 share,
170                                 "/foo/bar",
171                                 &mdscli_ctx);
172         if (!NT_STATUS_IS_OK(status)) {
173                 printf("Failed to connect mdssvc\n");
174                 goto fail;
175         }
176
177         if (opt_path == NULL) {
178                 basepath = mdscli_get_basepath(frame, mdscli_ctx);
179         } else {
180                 basepath = talloc_strdup(frame, opt_path);
181         }
182         if (basepath == NULL) {
183                 goto fail;
184         }
185
186         status = mdscli_search(frame,
187                                mdscli_ctx,
188                                mds_query,
189                                basepath,
190                                opt_live == 1 ? true : false,
191                                &search);
192         if (!NT_STATUS_IS_OK(status)) {
193                 printf("mdscli_search failed\n");
194                 goto fail;
195         }
196
197         if (!opt_live) {
198                 sleep(1);
199         }
200
201         while (true) {
202                 status = mdscli_get_results(frame,
203                                             search,
204                                             &cnids);
205                 if (NT_STATUS_EQUAL(status, NT_STATUS_NO_MORE_MATCHES)) {
206                         if (opt_live) {
207                                 sleep(1);
208                                 continue;
209                         }
210                         break;
211                 }
212                 if (!NT_STATUS_IS_OK(status)) {
213                         printf("mdscli_get_results failed\n");
214                         goto fail;
215                 }
216
217                 ncnids = talloc_array_length(cnids);
218                 if (ncnids == 0) {
219                         break;
220                 }
221
222                 for (i = 0; i < ncnids; i++) {
223                         char *path = NULL;
224
225                         status = mdscli_get_path(frame,
226                                                  mdscli_ctx,
227                                                  cnids[i],
228                                                  &path);
229                         if (!NT_STATUS_IS_OK(status)) {
230                                 printf("Get path for CNID 0x%"PRIx64" failed\n",
231                                        cnids[i]);
232                                 goto fail;
233                         }
234                         printf("%s\n", path);
235                         TALLOC_FREE(path);
236                 }
237         }
238
239         status = mdscli_close_search(&search);
240         if (!NT_STATUS_IS_OK(status)) {
241                 printf("mdscli_close_search failed\n");
242                 goto fail;
243         }
244
245         status = mdscli_disconnect(mdscli_ctx);
246         if (!NT_STATUS_IS_OK(status)) {
247                 printf("mdscli_disconnect failed\n");
248                 goto fail;
249         }
250
251         cmdline_messaging_context_free();
252         TALLOC_FREE(frame);
253         poptFreeContext(pc);
254         return 0;
255
256 fail:
257         TALLOC_FREE(frame);
258         return 1;
259 }