From: Ralph Boehme Date: Thu, 2 May 2019 19:33:46 +0000 (+0200) Subject: s3:utils: add mdfind X-Git-Tag: talloc-2.3.1~439 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=c85cd5c4311512fff18b04267408eb60d7c8ecdf;p=thirdparty%2Fsamba.git s3:utils: add mdfind A small command line tool to run macOS Spotlight searches against an SMB server that runs the Spotlight mdssvc RPC service, including macOS and Samba. Signed-off-by: Ralph Boehme Reviewed-by: Noel Power --- diff --git a/docs-xml/manpages/mdfind.1.xml b/docs-xml/manpages/mdfind.1.xml new file mode 100644 index 00000000000..0deef066059 --- /dev/null +++ b/docs-xml/manpages/mdfind.1.xml @@ -0,0 +1,148 @@ + + + + + + mdfind + 1 + Samba + User Commands + &doc.version; + + + + mdfind + Run Spotlight searches against an SMB server + + + + + mvxattr + server + sharename + query + -p, --path + -L, --live + + + + + DESCRIPTION + + This tool is part of the samba + 1 suite. + + mdfind is a simple utility to run Spotlight searches against an SMB server + that runs the Spotlight mdssvc RPC service. + + + + OPTIONS + + + + server + + The SMB server name or IP address to connect to. + + + + + sharename + + The name of a share on the server. + + + + + query + + The query expression syntax is a simplified form of filename + globbing familiar to shell users. Queries have the following + format: + + attribute=="value" + + For queries against a Samba server with Spotlight enabled using + the Elasticsearch backend, the list of supported metadata attributes + is given by the JSON attribute mapping file, typically installed at + /usr/share/samba/mdssvc/elasticsearch_mappings.json + + + + + + -p PATH, --path=PATH + + Server side path to search, defaults to + "/" + + + + + -L, --live + Query remains running. + + + + + + + EXAMPLES + + Search all indexed metadata attributes, exact match: + + '*=="Samba"' + + + Search all indexed metadata attributes, prefix match: + + '*=="Samba*"' + + + Search by filename: + + 'kMDItemFSName=="Samba*"' + + + Search by date: + + 'kMDItemFSContentChangeDate<$time.iso(2018-10-01T10:00:00Z)' + + + Search files's content: + + 'kMDItemTextContent=="Samba*"' + + + Expressions: + + kMDItemFSName=="Samba*"||kMDItemTextContent=="Tango*"' + + + + + SEE ALSO + + File Metadata Search Programming Guide + + https://developer.apple.com/library/archive/documentation/Carbon/Conceptual/SpotlightQuery/Concepts/Introduction.html + + + + + VERSION + + This man page is part of version &doc.version; of the Samba suite. + + + + AUTHOR + + The original Samba software and related utilities were created by + Andrew Tridgell. Samba is now developed by the Samba Team as an Open + Source project similar to the way the Linux kernel is developed. + + The mdfind manpage was written by Ralph Boehme. + + diff --git a/docs-xml/wscript_build b/docs-xml/wscript_build index b85309d4ead..70f5b43dd33 100644 --- a/docs-xml/wscript_build +++ b/docs-xml/wscript_build @@ -19,6 +19,7 @@ manpages=''' manpages/libsmbclient.7 manpages/lmhosts.5 manpages/log2pcap.1 + manpages/mdfind.1 manpages/mvxattr.1 manpages/net.8 manpages/nmbd.8 diff --git a/source3/utils/mdfind.c b/source3/utils/mdfind.c new file mode 100644 index 00000000000..d8ede525103 --- /dev/null +++ b/source3/utils/mdfind.c @@ -0,0 +1,290 @@ +/* + * Copyright (C) 2019, Ralph Boehme + * + * 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 "popt_common.h" +#include "popt_common_cmdline.h" +#include "lib/cmdline_contexts.h" +#include "param.h" +#include "auth_info.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; + +static 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_TABLEEND +}; + +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 user_auth_info *auth = NULL; + struct rpc_pipe_client *rpccli = NULL; + struct mdscli_ctx *mdscli_ctx = NULL; + struct mdscli_search_ctx *search = NULL; + const char *auth_username = NULL; + const char *auth_passwd = NULL; + const char *auth_domain = 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 = 0; + int signing_state = SMB_SIGNING_IPC_DEFAULT; + uint64_t *cnids = NULL; + size_t ncnids; + size_t i; + int opt; + poptContext pc; + NTSTATUS status; + bool ok; + + setup_logging(argv[0], DEBUG_STDERR); + smb_init_locale(); + lp_set_cmdline("log level", "1"); + + pc = poptGetContext(argv[0], + argc, + const_argv, + long_options, + POPT_CONTEXT_KEEP_FIRST); + + poptSetOtherOptionHelp(pc, "mdfind [OPTIONS] \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; + } + + popt_burn_cmdline_password(argc, argv); + + if ((server[0] == '/' && server[1] == '/') || + (server[0] == '\\' && server[1] == '\\')) + { + server += 2; + } + + auth = popt_get_cmdline_auth_info(); + auth_username = get_cmdline_auth_info_username(auth); + auth_passwd = get_cmdline_auth_info_password(auth); + auth_domain = get_cmdline_auth_info_domain(auth); + + signing_state = get_cmdline_auth_info_signing_state(auth); + switch (signing_state) { + case SMB_SIGNING_OFF: + lp_set_cmdline("client ipc signing", "no"); + break; + case SMB_SIGNING_REQUIRED: + lp_set_cmdline("client ipc signing", "required"); + break; + } + + if (get_cmdline_auth_info_use_kerberos(auth)) { + flags |= CLI_FULL_CONNECTION_USE_KERBEROS | + CLI_FULL_CONNECTION_FALLBACK_AFTER_KERBEROS; + } + if (get_cmdline_auth_info_use_ccache(auth)) { + flags |= CLI_FULL_CONNECTION_USE_CCACHE; + } + if (get_cmdline_auth_info_use_pw_nt_hash(auth)) { + flags |= CLI_FULL_CONNECTION_USE_NT_HASH; + } + + ev = samba_tevent_context_init(frame); + if (ev == NULL) { + goto fail; + } + + cmdline_messaging_context(get_dyn_CONFIGFILE()); + + ok = lp_load_client(get_dyn_CONFIGFILE()); + if (!ok) { + fprintf(stderr, "ERROR: Can't load %s\n", + get_dyn_CONFIGFILE()); + exit(1); + } + + status = cli_full_connection(&cli, + lp_netbios_name(), + server, + NULL, + 0, + "IPC$", + "IPC", + auth_username, + auth_domain, + auth_passwd, + flags, + SMB_SIGNING_IPC_DEFAULT); + if (!NT_STATUS_IS_OK(status)) { + DBG_ERR("Cannot connect to server: %s\n", nt_errstr(status)); + goto fail; + } + + if (get_cmdline_auth_info_smb_encrypt(auth)) { + status = cli_cm_force_encryption(cli, + auth_username, + auth_passwd, + auth_domain, + "IPC$"); + if (!NT_STATUS_IS_OK(status)) { + goto fail; + } + } + + status = cli_rpc_pipe_open_noauth_transport(cli, + NCACN_NP, + &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; + } + + TALLOC_FREE(frame); + poptFreeContext(pc); + return 0; + +fail: + TALLOC_FREE(frame); + return 1; +} diff --git a/source3/utils/wscript_build b/source3/utils/wscript_build index b6ff3697ca0..3e0539b2cea 100644 --- a/source3/utils/wscript_build +++ b/source3/utils/wscript_build @@ -310,3 +310,17 @@ bld.SAMBA3_BINARY('smbstatus', PROFILE CONN_TDB ''') + +bld.SAMBA3_BINARY('mdfind', + source='mdfind.c', + deps=''' + talloc + tevent + smbconf + popt_samba3 + popt_samba3_cmdline + libsmb + msrpc3 + RPCCLI_MDSSVC + mdssvc + ''')