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(&cli,
139 : lp_netbios_name(),
140 : server,
141 : NULL,
142 : 0,
143 : "IPC$",
144 : "IPC",
145 : creds,
146 : flags);
147 2 : if (!NT_STATUS_IS_OK(status)) {
148 0 : DBG_ERR("Cannot connect to server: %s\n", nt_errstr(status));
149 0 : goto fail_free_messaging;
150 : }
151 :
152 2 : status = cli_rpc_pipe_open_noauth(cli, &ndr_table_mdssvc, &rpccli);
153 2 : if (!NT_STATUS_IS_OK(status)) {
154 0 : goto fail_free_messaging;
155 : }
156 :
157 2 : status = mdscli_connect(frame,
158 2 : rpccli->binding_handle,
159 : share,
160 : "/foo/bar",
161 : &mdscli_ctx);
162 2 : if (!NT_STATUS_IS_OK(status)) {
163 0 : printf("Failed to connect mdssvc\n");
164 0 : goto fail_free_messaging;
165 : }
166 :
167 2 : if (opt_path == NULL) {
168 2 : basepath = mdscli_get_basepath(frame, mdscli_ctx);
169 : } else {
170 0 : basepath = talloc_strdup(frame, opt_path);
171 : }
172 2 : if (basepath == NULL) {
173 0 : goto fail_free_messaging;
174 : }
175 :
176 2 : status = mdscli_search(frame,
177 : mdscli_ctx,
178 : mds_query,
179 : basepath,
180 : opt_live == 1 ? true : false,
181 : &search);
182 2 : if (!NT_STATUS_IS_OK(status)) {
183 0 : printf("mdscli_search failed\n");
184 0 : goto fail_free_messaging;
185 : }
186 :
187 2 : if (!opt_live) {
188 2 : sleep(1);
189 : }
190 :
191 : while (true) {
192 4 : status = mdscli_get_results(frame,
193 : search,
194 : &cnids);
195 4 : if (NT_STATUS_EQUAL(status, NT_STATUS_NO_MORE_MATCHES)) {
196 2 : if (opt_live) {
197 0 : sleep(1);
198 0 : continue;
199 : }
200 2 : break;
201 : }
202 :
203 2 : ncnids = talloc_array_length(cnids);
204 :
205 2 : if (NT_STATUS_EQUAL(status, NT_STATUS_PENDING) &&
206 : ncnids == 0)
207 : {
208 0 : sleep(1);
209 0 : continue;
210 : }
211 2 : if (!NT_STATUS_IS_OK(status)) {
212 0 : printf("mdscli_get_results failed\n");
213 0 : goto fail_free_messaging;
214 : }
215 :
216 2 : if (ncnids == 0) {
217 0 : break;
218 : }
219 :
220 6 : for (i = 0; i < ncnids; i++) {
221 4 : char *path = NULL;
222 :
223 4 : status = mdscli_get_path(frame,
224 : mdscli_ctx,
225 4 : cnids[i],
226 : &path);
227 4 : if (!NT_STATUS_IS_OK(status)) {
228 0 : printf("Get path for CNID 0x%"PRIx64" failed\n",
229 0 : cnids[i]);
230 0 : goto fail_free_messaging;
231 : }
232 4 : printf("%s\n", path);
233 4 : TALLOC_FREE(path);
234 : }
235 : }
236 :
237 2 : status = mdscli_close_search(&search);
238 2 : if (!NT_STATUS_IS_OK(status)) {
239 0 : printf("mdscli_close_search failed\n");
240 0 : goto fail_free_messaging;
241 : }
242 :
243 2 : status = mdscli_disconnect(mdscli_ctx);
244 2 : if (!NT_STATUS_IS_OK(status)) {
245 0 : printf("mdscli_disconnect failed\n");
246 0 : goto fail_free_messaging;
247 : }
248 :
249 2 : cmdline_messaging_context_free();
250 2 : TALLOC_FREE(frame);
251 2 : poptFreeContext(pc);
252 2 : return 0;
253 :
254 0 : fail_free_messaging:
255 0 : cmdline_messaging_context_free();
256 0 : fail:
257 0 : poptFreeContext(pc);
258 0 : TALLOC_FREE(frame);
259 0 : return 1;
260 : }
|