WHATSNEW: Automatic keytab update after machine password changes
[samba.git] / source3 / utils / mdsearch.c
blob99e67d54e0a22cadb007afd1581a73b7a3d4e202
1 /*
2 * Copyright (C) 2019, Ralph Boehme <slow@samba.org.>
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.
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.
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.
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"
32 static char *opt_path;
33 static int opt_live;
35 int main(int argc, char **argv)
37 const char **const_argv = discard_const_p(const char *, argv);
38 TALLOC_CTX *frame = talloc_stackframe();
39 struct loadparm_context *lp_ctx = NULL;
40 struct tevent_context *ev = NULL;
41 struct cli_credentials *creds = NULL;
42 struct rpc_pipe_client *rpccli = NULL;
43 struct mdscli_ctx *mdscli_ctx = NULL;
44 struct mdscli_search_ctx *search = NULL;
45 const char *server = NULL;
46 const char *share = NULL;
47 const char *mds_query = NULL;
48 struct cli_state *cli = NULL;
49 char *basepath = NULL;
50 uint32_t flags = CLI_FULL_CONNECTION_IPC;
51 uint64_t *cnids = NULL;
52 size_t ncnids;
53 size_t i;
54 int opt;
55 poptContext pc;
56 NTSTATUS status;
57 bool ok;
59 struct poptOption long_options[] = {
60 POPT_AUTOHELP
62 .longName = "path",
63 .shortName = 'p',
64 .argInfo = POPT_ARG_STRING,
65 .arg = &opt_path,
66 .descrip = "Server-relative search path",
69 .longName = "live",
70 .shortName = 'L',
71 .argInfo = POPT_ARG_NONE,
72 .arg = &opt_live,
73 .descrip = "live query",
75 POPT_COMMON_SAMBA
76 POPT_COMMON_CREDENTIALS
77 POPT_LEGACY_S3
78 POPT_COMMON_VERSION
79 POPT_TABLEEND
82 smb_init_locale();
84 ok = samba_cmdline_init(frame,
85 SAMBA_CMDLINE_CONFIG_CLIENT,
86 false /* require_smbconf */);
87 if (!ok) {
88 DBG_ERR("Failed to init cmdline parser!\n");
89 TALLOC_FREE(frame);
90 exit(1);
92 lp_ctx = samba_cmdline_get_lp_ctx();
93 lpcfg_set_cmdline(lp_ctx, "log level", "1");
95 pc = samba_popt_get_context(getprogname(),
96 argc,
97 const_argv,
98 long_options,
99 POPT_CONTEXT_KEEP_FIRST);
101 poptSetOtherOptionHelp(pc, "mdsearch [OPTIONS] <server> <share> <query>\n");
103 while ((opt = poptGetNextOpt(pc)) != -1) {
104 DBG_ERR("Invalid option %s: %s\n",
105 poptBadOption(pc, 0),
106 poptStrerror(opt));
107 poptPrintHelp(pc, stderr, 0);
108 goto fail;
111 poptGetArg(pc); /* Drop argv[0], the program name */
112 server = poptGetArg(pc);
113 share = poptGetArg(pc);
114 mds_query = poptGetArg(pc);
116 if (server == NULL || mds_query == NULL) {
117 poptPrintHelp(pc, stderr, 0);
118 goto fail;
121 samba_cmdline_burn(argc, argv);
123 if ((server[0] == '/' && server[1] == '/') ||
124 (server[0] == '\\' && server[1] == '\\'))
126 server += 2;
129 ev = samba_tevent_context_init(frame);
130 if (ev == NULL) {
131 goto fail;
134 cmdline_messaging_context(get_dyn_CONFIGFILE());
136 creds = samba_cmdline_get_creds();
138 status = cli_full_connection_creds(frame,
139 &cli,
140 lp_netbios_name(),
141 server,
142 NULL,
144 "IPC$",
145 "IPC",
146 creds,
147 flags);
148 if (!NT_STATUS_IS_OK(status)) {
149 DBG_ERR("Cannot connect to server: %s\n", nt_errstr(status));
150 goto fail_free_messaging;
153 status = cli_rpc_pipe_open_noauth(cli, &ndr_table_mdssvc, &rpccli);
154 if (!NT_STATUS_IS_OK(status)) {
155 goto fail_free_messaging;
158 status = mdscli_connect(frame,
159 rpccli->binding_handle,
160 share,
161 "/foo/bar",
162 &mdscli_ctx);
163 if (!NT_STATUS_IS_OK(status)) {
164 printf("Failed to connect mdssvc\n");
165 goto fail_free_messaging;
168 if (opt_path == NULL) {
169 basepath = mdscli_get_basepath(frame, mdscli_ctx);
170 } else {
171 basepath = talloc_strdup(frame, opt_path);
173 if (basepath == NULL) {
174 goto fail_free_messaging;
177 status = mdscli_search(frame,
178 mdscli_ctx,
179 mds_query,
180 basepath,
181 opt_live == 1 ? true : false,
182 &search);
183 if (!NT_STATUS_IS_OK(status)) {
184 printf("mdscli_search failed\n");
185 goto fail_free_messaging;
188 if (!opt_live) {
189 sleep(1);
192 while (true) {
193 status = mdscli_get_results(frame,
194 search,
195 &cnids);
196 if (NT_STATUS_EQUAL(status, NT_STATUS_NO_MORE_MATCHES)) {
197 if (opt_live) {
198 sleep(1);
199 continue;
201 break;
204 ncnids = talloc_array_length(cnids);
206 if (NT_STATUS_EQUAL(status, NT_STATUS_PENDING) &&
207 ncnids == 0)
209 sleep(1);
210 continue;
212 if (!NT_STATUS_IS_OK(status)) {
213 printf("mdscli_get_results failed\n");
214 goto fail_free_messaging;
217 if (ncnids == 0) {
218 break;
221 for (i = 0; i < ncnids; i++) {
222 char *path = NULL;
224 status = mdscli_get_path(frame,
225 mdscli_ctx,
226 cnids[i],
227 &path);
228 if (!NT_STATUS_IS_OK(status)) {
229 printf("Get path for CNID 0x%"PRIx64" failed\n",
230 cnids[i]);
231 goto fail_free_messaging;
233 printf("%s\n", path);
234 TALLOC_FREE(path);
238 status = mdscli_close_search(&search);
239 if (!NT_STATUS_IS_OK(status)) {
240 printf("mdscli_close_search failed\n");
241 goto fail_free_messaging;
244 status = mdscli_disconnect(mdscli_ctx);
245 if (!NT_STATUS_IS_OK(status)) {
246 printf("mdscli_disconnect failed\n");
247 goto fail_free_messaging;
250 cmdline_messaging_context_free();
251 TALLOC_FREE(frame);
252 poptFreeContext(pc);
253 return 0;
255 fail_free_messaging:
256 cmdline_messaging_context_free();
257 fail:
258 poptFreeContext(pc);
259 TALLOC_FREE(frame);
260 return 1;