Line data Source code
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 "lib/cmdline/cmdline.h"
23 : #include "lib/cmdline_contexts.h"
24 : #include "param.h"
25 : #include "client.h"
26 : #include "libsmb/proto.h"
27 : #include "librpc/rpc/rpc_common.h"
28 : #include "rpc_client/cli_pipe.h"
29 : #include "rpc_client/cli_mdssvc.h"
30 : #include "librpc/gen_ndr/ndr_mdssvc_c.h"
31 :
32 : static char *opt_path;
33 : static int opt_live;
34 :
35 2 : int main(int argc, char **argv)
36 : {
37 2 : const char **const_argv = discard_const_p(const char *, argv);
38 2 : TALLOC_CTX *frame = talloc_stackframe();
39 2 : struct loadparm_context *lp_ctx = NULL;
40 2 : struct tevent_context *ev = NULL;
41 2 : struct cli_credentials *creds = NULL;
42 2 : struct rpc_pipe_client *rpccli = NULL;
43 2 : struct mdscli_ctx *mdscli_ctx = NULL;
44 2 : struct mdscli_search_ctx *search = NULL;
45 2 : const char *server = NULL;
46 2 : const char *share = NULL;
47 2 : const char *mds_query = NULL;
48 2 : struct cli_state *cli = NULL;
49 2 : char *basepath = NULL;
50 2 : uint32_t flags = CLI_FULL_CONNECTION_IPC;
51 2 : uint64_t *cnids = NULL;
52 : size_t ncnids;
53 : size_t i;
54 : int opt;
55 : poptContext pc;
56 : NTSTATUS status;
57 : bool ok;
58 :
59 10 : struct poptOption long_options[] = {
60 : POPT_AUTOHELP
61 : {
62 : .longName = "path",
63 : .shortName = 'p',
64 : .argInfo = POPT_ARG_STRING,
65 : .arg = &opt_path,
66 : .descrip = "Server-relative search path",
67 : },
68 : {
69 : .longName = "live",
70 : .shortName = 'L',
71 : .argInfo = POPT_ARG_NONE,
72 : .arg = &opt_live,
73 : .descrip = "live query",
74 : },
75 2 : POPT_COMMON_SAMBA
76 2 : POPT_COMMON_CREDENTIALS
77 2 : POPT_LEGACY_S3
78 2 : POPT_COMMON_VERSION
79 : POPT_TABLEEND
80 : };
81 :
82 2 : smb_init_locale();
83 :
84 2 : ok = samba_cmdline_init(frame,
85 : SAMBA_CMDLINE_CONFIG_CLIENT,
86 : false /* require_smbconf */);
87 2 : if (!ok) {
88 0 : DBG_ERR("Failed to init cmdline parser!\n");
89 0 : TALLOC_FREE(frame);
90 0 : exit(1);
91 : }
92 2 : lp_ctx = samba_cmdline_get_lp_ctx();
93 2 : lpcfg_set_cmdline(lp_ctx, "log level", "1");
94 :
95 2 : pc = samba_popt_get_context(getprogname(),
96 : argc,
97 : const_argv,
98 : long_options,
99 : POPT_CONTEXT_KEEP_FIRST);
100 :
101 2 : poptSetOtherOptionHelp(pc, "mdsearch [OPTIONS] <server> <share> <query>\n");
102 :
103 2 : while ((opt = poptGetNextOpt(pc)) != -1) {
104 0 : DBG_ERR("Invalid option %s: %s\n",
105 : poptBadOption(pc, 0),
106 : poptStrerror(opt));
107 0 : poptPrintHelp(pc, stderr, 0);
108 0 : goto fail;
109 : }
110 :
111 2 : poptGetArg(pc); /* Drop argv[0], the program name */
112 2 : server = poptGetArg(pc);
113 2 : share = poptGetArg(pc);
114 2 : mds_query = poptGetArg(pc);
115 :
116 2 : if (server == NULL || mds_query == NULL) {
117 0 : poptPrintHelp(pc, stderr, 0);
118 0 : goto fail;
119 : }
120 :
121 2 : samba_cmdline_burn(argc, argv);
122 :
123 2 : if ((server[0] == '/' && server[1] == '/') ||
124 2 : (server[0] == '\\' && server[1] == '\\'))
125 : {
126 0 : server += 2;
127 : }
128 :
129 2 : ev = samba_tevent_context_init(frame);
130 2 : if (ev == NULL) {
131 0 : goto fail;
132 : }
133 :
134 2 : cmdline_messaging_context(get_dyn_CONFIGFILE());
135 :
136 2 : creds = samba_cmdline_get_creds();
137 :
138 2 : status = cli_full_connection_creds(frame,
139 : &cli,
140 : lp_netbios_name(),
141 : server,
142 : NULL,
143 : 0,
144 : "IPC$",
145 : "IPC",
146 : creds,
147 : flags);
148 2 : if (!NT_STATUS_IS_OK(status)) {
149 0 : DBG_ERR("Cannot connect to server: %s\n", nt_errstr(status));
150 0 : goto fail_free_messaging;
151 : }
152 :
153 2 : status = cli_rpc_pipe_open_noauth(cli, &ndr_table_mdssvc, &rpccli);
154 2 : if (!NT_STATUS_IS_OK(status)) {
155 0 : goto fail_free_messaging;
156 : }
157 :
158 2 : status = mdscli_connect(frame,
159 2 : rpccli->binding_handle,
160 : share,
161 : "/foo/bar",
162 : &mdscli_ctx);
163 2 : if (!NT_STATUS_IS_OK(status)) {
164 0 : printf("Failed to connect mdssvc\n");
165 0 : goto fail_free_messaging;
166 : }
167 :
168 2 : if (opt_path == NULL) {
169 2 : basepath = mdscli_get_basepath(frame, mdscli_ctx);
170 : } else {
171 0 : basepath = talloc_strdup(frame, opt_path);
172 : }
173 2 : if (basepath == NULL) {
174 0 : goto fail_free_messaging;
175 : }
176 :
177 2 : status = mdscli_search(frame,
178 : mdscli_ctx,
179 : mds_query,
180 : basepath,
181 : opt_live == 1 ? true : false,
182 : &search);
183 2 : if (!NT_STATUS_IS_OK(status)) {
184 0 : printf("mdscli_search failed\n");
185 0 : goto fail_free_messaging;
186 : }
187 :
188 2 : if (!opt_live) {
189 2 : sleep(1);
190 : }
191 :
192 : while (true) {
193 4 : status = mdscli_get_results(frame,
194 : search,
195 : &cnids);
196 4 : if (NT_STATUS_EQUAL(status, NT_STATUS_NO_MORE_MATCHES)) {
197 2 : if (opt_live) {
198 0 : sleep(1);
199 0 : continue;
200 : }
201 2 : break;
202 : }
203 :
204 2 : ncnids = talloc_array_length(cnids);
205 :
206 2 : if (NT_STATUS_EQUAL(status, NT_STATUS_PENDING) &&
207 : ncnids == 0)
208 : {
209 0 : sleep(1);
210 0 : continue;
211 : }
212 2 : if (!NT_STATUS_IS_OK(status)) {
213 0 : printf("mdscli_get_results failed\n");
214 0 : goto fail_free_messaging;
215 : }
216 :
217 2 : if (ncnids == 0) {
218 0 : break;
219 : }
220 :
221 6 : for (i = 0; i < ncnids; i++) {
222 4 : char *path = NULL;
223 :
224 4 : status = mdscli_get_path(frame,
225 : mdscli_ctx,
226 4 : cnids[i],
227 : &path);
228 4 : if (!NT_STATUS_IS_OK(status)) {
229 0 : printf("Get path for CNID 0x%"PRIx64" failed\n",
230 0 : cnids[i]);
231 0 : goto fail_free_messaging;
232 : }
233 4 : printf("%s\n", path);
234 4 : TALLOC_FREE(path);
235 : }
236 : }
237 :
238 2 : status = mdscli_close_search(&search);
239 2 : if (!NT_STATUS_IS_OK(status)) {
240 0 : printf("mdscli_close_search failed\n");
241 0 : goto fail_free_messaging;
242 : }
243 :
244 2 : status = mdscli_disconnect(mdscli_ctx);
245 2 : if (!NT_STATUS_IS_OK(status)) {
246 0 : printf("mdscli_disconnect failed\n");
247 0 : goto fail_free_messaging;
248 : }
249 :
250 2 : cmdline_messaging_context_free();
251 2 : TALLOC_FREE(frame);
252 2 : poptFreeContext(pc);
253 2 : return 0;
254 :
255 0 : fail_free_messaging:
256 0 : cmdline_messaging_context_free();
257 0 : fail:
258 0 : poptFreeContext(pc);
259 0 : TALLOC_FREE(frame);
260 0 : return 1;
261 : }
|