summaryrefslogtreecommitdiffstats
path: root/source3/utils/mdsearch.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--source3/utils/mdsearch.c248
1 files changed, 248 insertions, 0 deletions
diff --git a/source3/utils/mdsearch.c b/source3/utils/mdsearch.c
new file mode 100644
index 0000000..ab48e36
--- /dev/null
+++ b/source3/utils/mdsearch.c
@@ -0,0 +1,248 @@
+/*
+ * Copyright (C) 2019, Ralph Boehme <slow@samba.org.>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "includes.h"
+#include "lib/util/debug.h"
+#include "lib/cmdline/cmdline.h"
+#include "lib/cmdline_contexts.h"
+#include "param.h"
+#include "client.h"
+#include "libsmb/proto.h"
+#include "librpc/rpc/rpc_common.h"
+#include "rpc_client/cli_pipe.h"
+#include "rpc_client/cli_mdssvc.h"
+#include "librpc/gen_ndr/ndr_mdssvc_c.h"
+
+static char *opt_path;
+static int opt_live;
+
+int main(int argc, char **argv)
+{
+ const char **const_argv = discard_const_p(const char *, argv);
+ TALLOC_CTX *frame = talloc_stackframe();
+ struct tevent_context *ev = NULL;
+ struct cli_credentials *creds = NULL;
+ struct rpc_pipe_client *rpccli = NULL;
+ struct mdscli_ctx *mdscli_ctx = NULL;
+ struct mdscli_search_ctx *search = NULL;
+ const char *server = NULL;
+ const char *share = NULL;
+ const char *mds_query = NULL;
+ struct cli_state *cli = NULL;
+ char *basepath = NULL;
+ uint32_t flags = CLI_FULL_CONNECTION_IPC;
+ uint64_t *cnids = NULL;
+ size_t ncnids;
+ size_t i;
+ int opt;
+ poptContext pc;
+ NTSTATUS status;
+ bool ok;
+
+ struct poptOption long_options[] = {
+ POPT_AUTOHELP
+ {
+ .longName = "path",
+ .shortName = 'p',
+ .argInfo = POPT_ARG_STRING,
+ .arg = &opt_path,
+ .descrip = "Server-relative search path",
+ },
+ {
+ .longName = "live",
+ .shortName = 'L',
+ .argInfo = POPT_ARG_NONE,
+ .arg = &opt_live,
+ .descrip = "live query",
+ },
+ POPT_COMMON_SAMBA
+ POPT_COMMON_CREDENTIALS
+ POPT_LEGACY_S3
+ POPT_COMMON_VERSION
+ POPT_TABLEEND
+ };
+
+ smb_init_locale();
+
+ ok = samba_cmdline_init(frame,
+ SAMBA_CMDLINE_CONFIG_CLIENT,
+ false /* require_smbconf */);
+ if (!ok) {
+ DBG_ERR("Failed to init cmdline parser!\n");
+ TALLOC_FREE(frame);
+ exit(1);
+ }
+ lp_set_cmdline("log level", "1");
+
+ pc = samba_popt_get_context(getprogname(),
+ argc,
+ const_argv,
+ long_options,
+ POPT_CONTEXT_KEEP_FIRST);
+
+ poptSetOtherOptionHelp(pc, "mdsearch [OPTIONS] <server> <share> <query>\n");
+
+ while ((opt = poptGetNextOpt(pc)) != -1) {
+ DBG_ERR("Invalid option %s: %s\n",
+ poptBadOption(pc, 0),
+ poptStrerror(opt));
+ poptPrintHelp(pc, stderr, 0);
+ goto fail;
+ }
+
+ poptGetArg(pc); /* Drop argv[0], the program name */
+ server = poptGetArg(pc);
+ share = poptGetArg(pc);
+ mds_query = poptGetArg(pc);
+
+ if (server == NULL || mds_query == NULL) {
+ poptPrintHelp(pc, stderr, 0);
+ goto fail;
+ }
+
+ samba_cmdline_burn(argc, argv);
+
+ if ((server[0] == '/' && server[1] == '/') ||
+ (server[0] == '\\' && server[1] == '\\'))
+ {
+ server += 2;
+ }
+
+ ev = samba_tevent_context_init(frame);
+ if (ev == NULL) {
+ goto fail;
+ }
+
+ cmdline_messaging_context(get_dyn_CONFIGFILE());
+
+ creds = samba_cmdline_get_creds();
+
+ status = cli_full_connection_creds(&cli,
+ lp_netbios_name(),
+ server,
+ NULL,
+ 0,
+ "IPC$",
+ "IPC",
+ creds,
+ flags);
+ if (!NT_STATUS_IS_OK(status)) {
+ DBG_ERR("Cannot connect to server: %s\n", nt_errstr(status));
+ goto fail;
+ }
+
+ status = cli_rpc_pipe_open_noauth(cli, &ndr_table_mdssvc, &rpccli);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto fail;
+ }
+
+ status = mdscli_connect(frame,
+ rpccli->binding_handle,
+ share,
+ "/foo/bar",
+ &mdscli_ctx);
+ if (!NT_STATUS_IS_OK(status)) {
+ printf("Failed to connect mdssvc\n");
+ goto fail;
+ }
+
+ if (opt_path == NULL) {
+ basepath = mdscli_get_basepath(frame, mdscli_ctx);
+ } else {
+ basepath = talloc_strdup(frame, opt_path);
+ }
+ if (basepath == NULL) {
+ goto fail;
+ }
+
+ status = mdscli_search(frame,
+ mdscli_ctx,
+ mds_query,
+ basepath,
+ opt_live == 1 ? true : false,
+ &search);
+ if (!NT_STATUS_IS_OK(status)) {
+ printf("mdscli_search failed\n");
+ goto fail;
+ }
+
+ if (!opt_live) {
+ sleep(1);
+ }
+
+ while (true) {
+ status = mdscli_get_results(frame,
+ search,
+ &cnids);
+ if (NT_STATUS_EQUAL(status, NT_STATUS_NO_MORE_MATCHES)) {
+ if (opt_live) {
+ sleep(1);
+ continue;
+ }
+ break;
+ }
+ if (!NT_STATUS_IS_OK(status)) {
+ printf("mdscli_get_results failed\n");
+ goto fail;
+ }
+
+ ncnids = talloc_array_length(cnids);
+ if (ncnids == 0) {
+ break;
+ }
+
+ for (i = 0; i < ncnids; i++) {
+ char *path = NULL;
+
+ status = mdscli_get_path(frame,
+ mdscli_ctx,
+ cnids[i],
+ &path);
+ if (!NT_STATUS_IS_OK(status)) {
+ printf("Get path for CNID 0x%"PRIx64" failed\n",
+ cnids[i]);
+ goto fail;
+ }
+ printf("%s\n", path);
+ TALLOC_FREE(path);
+ }
+ }
+
+ status = mdscli_close_search(&search);
+ if (!NT_STATUS_IS_OK(status)) {
+ printf("mdscli_close_search failed\n");
+ goto fail;
+ }
+
+ status = mdscli_disconnect(mdscli_ctx);
+ if (!NT_STATUS_IS_OK(status)) {
+ printf("mdscli_disconnect failed\n");
+ goto fail;
+ }
+
+ cmdline_messaging_context_free();
+ TALLOC_FREE(frame);
+ poptFreeContext(pc);
+ return 0;
+
+fail:
+ poptFreeContext(pc);
+ TALLOC_FREE(frame);
+ return 1;
+}