rpcclient: add some simple commands for Spotlight RPC
authorRalph Boehme <slow@samba.org>
Sun, 8 Mar 2015 06:57:57 +0000 (07:57 +0100)
committerJeremy Allison <jra@samba.org>
Thu, 8 Aug 2019 20:24:32 +0000 (20:24 +0000)
Signed-off-by: Ralph Boehme <slow@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
source3/rpcclient/cmd_spotlight.c [new file with mode: 0644]
source3/rpcclient/rpcclient.c
source3/rpcclient/wscript_build

diff --git a/source3/rpcclient/cmd_spotlight.c b/source3/rpcclient/cmd_spotlight.c
new file mode 100644 (file)
index 0000000..f8bf75e
--- /dev/null
@@ -0,0 +1,460 @@
+/*
+   Unix SMB/CIFS implementation.
+   RPC Spotlight client
+
+   Copyright (C) Ralph Boehme 2018
+
+   This program 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 3 of the License, or
+   (at your option) any later version.
+
+   This program 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 program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "includes.h"
+#include "rpcclient.h"
+#include "libsmb/libsmb.h"
+#include "../librpc/gen_ndr/ndr_mdssvc_c.h"
+#include "../rpc_server/mdssvc/mdssvc.h"
+#include "../rpc_server/mdssvc/dalloc.h"
+#include "../rpc_server/mdssvc/marshalling.h"
+
+static NTSTATUS cmd_mdssvc_fetch_properties(
+                       struct rpc_pipe_client *cli,
+                       TALLOC_CTX *mem_ctx,
+                       int argc, const char **argv)
+{
+       struct dcerpc_binding_handle *b = cli->binding_handle;
+       NTSTATUS status;
+       uint32_t device_id = 0x2f000045;
+       uint32_t unkn1 = 23;
+       uint32_t unkn2 = 0;
+       struct policy_handle share_handle;
+       char share_path[1025];
+       uint32_t mds_status;
+       uint32_t flags;      /* server always returns 0x6b000001 ? */
+       uint32_t unkn3;      /* server always returns 0 ? */
+       struct mdssvc_blob request_blob;
+       struct mdssvc_blob response_blob;
+       ssize_t len;
+       uint32_t max_fragment_size = 64 * 1024;
+       DALLOC_CTX *d, *mds_reply;
+       uint64_t *uint64var;
+       sl_array_t *array1, *array2;
+       uint32_t unkn4;
+       int result;
+       bool ok;
+
+       if (argc != 3) {
+               printf("Usage: %s SHARENAME MOUNTPATH\n", argv[0]);
+               return NT_STATUS_OK;
+       }
+
+       status = dcerpc_mdssvc_open(b, mem_ctx,
+                                   &device_id,
+                                   &unkn1,
+                                   &unkn2,
+                                   argv[2],
+                                   argv[1],
+                                   share_path,
+                                   &share_handle);
+       if (!NT_STATUS_IS_OK(status)) {
+               goto done;
+       }
+
+       status = dcerpc_mdssvc_unknown1(b, mem_ctx,
+                                       share_handle,
+                                       0,
+                                       device_id,
+                                       unkn1,
+                                       0,
+                                       geteuid(),
+                                       getegid(),
+                                       &mds_status,
+                                       &flags,
+                                       &unkn3);
+       if (!NT_STATUS_IS_OK(status)) {
+               goto done;
+       }
+
+       d = dalloc_new(mem_ctx);
+       if (d == NULL) {
+               status = NT_STATUS_NO_MEMORY;
+               goto done;
+       }
+
+       mds_reply = dalloc_new(mem_ctx);
+       if (mds_reply == NULL) {
+               status = NT_STATUS_NO_MEMORY;
+               goto done;
+       }
+
+       array1 = dalloc_zero(d, sl_array_t);
+       if (array1 == NULL) {
+               status = NT_STATUS_NO_MEMORY;
+               goto done;
+       }
+
+       array2 = dalloc_zero(d, sl_array_t);
+       if (array2 == NULL) {
+               status = NT_STATUS_NO_MEMORY;
+               goto done;
+       }
+
+       result = dalloc_stradd(array2, "fetchPropertiesForContext:");
+       if (result != 0) {
+               status = NT_STATUS_INTERNAL_ERROR;
+               goto done;
+       }
+       uint64var = talloc_zero_array(mem_ctx, uint64_t, 2);
+       if (uint64var == NULL) {
+               status = NT_STATUS_NO_MEMORY;
+               goto done;
+       }
+       talloc_set_name(uint64var, "uint64_t *");
+
+       result = dalloc_add(array2, &uint64var[0], uint64_t *);
+       if (result != 0) {
+               status = NT_STATUS_INTERNAL_ERROR;
+               goto done;
+       }
+
+       result = dalloc_add(array1, array2, sl_array_t);
+       if (result != 0) {
+               status = NT_STATUS_INTERNAL_ERROR;
+               goto done;
+       }
+       result = dalloc_add(d, array1, sl_array_t);
+       if (result != 0) {
+               status = NT_STATUS_INTERNAL_ERROR;
+               goto done;
+       }
+
+       request_blob.spotlight_blob = talloc_array(mem_ctx, uint8_t, max_fragment_size);
+       if (request_blob.spotlight_blob == NULL) {
+               status = NT_STATUS_INTERNAL_ERROR;
+               goto done;
+       }
+       request_blob.size = max_fragment_size;
+
+       response_blob.spotlight_blob = talloc_array(mem_ctx, uint8_t, max_fragment_size);
+       if (response_blob.spotlight_blob == NULL) {
+               status = NT_STATUS_INTERNAL_ERROR;
+               goto done;
+       }
+       response_blob.size = max_fragment_size;
+
+       len = sl_pack(d, (char *)request_blob.spotlight_blob, request_blob.size);
+       if (len == -1) {
+               status = NT_STATUS_INTERNAL_ERROR;
+               goto done;
+       }
+       request_blob.length = len;
+       request_blob.size = len;
+
+       status =  dcerpc_mdssvc_cmd(b, mem_ctx,
+                                   share_handle,
+                                   0,
+                                   device_id,
+                                   23,
+                                   0,
+                                   0x6b000001,
+                                   request_blob,
+                                   0,
+                                   max_fragment_size,
+                                   1,
+                                   max_fragment_size,
+                                   0,
+                                   0,
+                                   &mds_status,
+                                   &response_blob,
+                                   &unkn4);
+       if (!NT_STATUS_IS_OK(status)) {
+               goto done;
+       }
+
+       ok = sl_unpack(mds_reply, (char *)response_blob.spotlight_blob,
+                      response_blob.length);
+       if (!ok) {
+               DEBUG(1, ("error unpacking Spotlight RPC blob\n"));
+               status = NT_STATUS_INTERNAL_ERROR;
+               goto done;
+       }
+
+       DEBUG(0, ("%s", dalloc_dump(mds_reply, 0)));
+
+done:
+       return status;
+}
+
+static NTSTATUS cmd_mdssvc_fetch_attributes(
+                       struct rpc_pipe_client *cli,
+                       TALLOC_CTX *mem_ctx,
+                       int argc, const char **argv)
+{
+       struct dcerpc_binding_handle *b = cli->binding_handle;
+       NTSTATUS status;
+       uint32_t device_id = 0x2f000045;
+       uint32_t unkn1 = 23;
+       uint32_t unkn2 = 0;
+       struct policy_handle share_handle;
+       char share_path[1025];
+       uint32_t mds_status;
+       uint32_t flags;      /* server always returns 0x6b000001 ? */
+       uint32_t unkn3;      /* server always returns 0 ? */
+       struct mdssvc_blob request_blob;
+       struct mdssvc_blob response_blob;
+       ssize_t len;
+       uint32_t max_fragment_size = 64 * 1024;
+       DALLOC_CTX *d, *mds_reply;
+       uint64_t *uint64var;
+       sl_array_t *array;
+       sl_array_t *cmd_array;
+       sl_array_t *attr_array;
+       sl_cnids_t *cnids;
+       uint64_t cnid;
+       uint32_t unkn4;
+       int result;
+       bool ok;
+
+       if (argc != 4) {
+               printf("Usage: %s SHARENAME MOUNTPATH CNID\n", argv[0]);
+               return NT_STATUS_OK;
+       }
+
+       ok = conv_str_u64(argv[3], &cnid);
+       if (!ok) {
+               printf("Failed to parse: %s\n", argv[3]);
+               return NT_STATUS_INVALID_PARAMETER;
+       }
+
+       status = dcerpc_mdssvc_open(b, mem_ctx,
+                                   &device_id,
+                                   &unkn1,
+                                   &unkn2,
+                                   argv[2],
+                                   argv[1],
+                                   share_path,
+                                   &share_handle);
+       if (!NT_STATUS_IS_OK(status)) {
+               goto done;
+       }
+
+       status = dcerpc_mdssvc_unknown1(b, mem_ctx,
+                                       share_handle,
+                                       0,
+                                       device_id,
+                                       unkn1,
+                                       0,
+                                       geteuid(),
+                                       getegid(),
+                                       &mds_status,
+                                       &flags,
+                                       &unkn3);
+       if (!NT_STATUS_IS_OK(status)) {
+               goto done;
+       }
+
+       d = dalloc_new(mem_ctx);
+       if (d == NULL) {
+               status = NT_STATUS_NO_MEMORY;
+               goto done;
+       }
+
+       array = dalloc_zero(d, sl_array_t);
+       if (array == NULL) {
+               status = NT_STATUS_NO_MEMORY;
+               goto done;
+       }
+
+       result = dalloc_add(d, array, sl_array_t);
+       if (result != 0) {
+               status = NT_STATUS_INTERNAL_ERROR;
+               goto done;
+       }
+
+       cmd_array = dalloc_zero(d, sl_array_t);
+       if (cmd_array == NULL) {
+               status = NT_STATUS_NO_MEMORY;
+               goto done;
+       }
+
+       result = dalloc_add(array, cmd_array, sl_array_t);
+       if (result != 0) {
+               status = NT_STATUS_INTERNAL_ERROR;
+               goto done;
+       }
+
+       result = dalloc_stradd(cmd_array,
+                              "fetchAttributes:forOIDArray:context:");
+       if (result != 0) {
+               status = NT_STATUS_INTERNAL_ERROR;
+               goto done;
+       }
+
+       uint64var = talloc_zero_array(mem_ctx, uint64_t, 2);
+       if (uint64var == NULL) {
+               status = NT_STATUS_NO_MEMORY;
+               goto done;
+       }
+       talloc_set_name(uint64var, "uint64_t *");
+       uint64var[0] = 0x500a;
+       uint64var[1] = 0;
+
+       result = dalloc_add(cmd_array, &uint64var[0], uint64_t *);
+       if (result != 0) {
+               status = NT_STATUS_INTERNAL_ERROR;
+               goto done;
+       }
+
+       attr_array = dalloc_zero(d, sl_array_t);
+       if (attr_array == NULL) {
+               status = NT_STATUS_NO_MEMORY;
+               goto done;
+       }
+
+       result = dalloc_add(array, attr_array, sl_array_t);
+       if (result != 0) {
+               status = NT_STATUS_INTERNAL_ERROR;
+               goto done;
+       }
+
+       result = dalloc_stradd(attr_array, "kMDItemPath");
+       if (result != 0) {
+               status = NT_STATUS_INTERNAL_ERROR;
+               goto done;
+       }
+
+       /* CNIDs */
+       cnids = talloc_zero(array, sl_cnids_t);
+       if (cnids == NULL) {
+               status = NT_STATUS_INTERNAL_ERROR;
+               goto done;
+       }
+       cnids->ca_cnids = dalloc_new(cnids);
+       if (cnids->ca_cnids == NULL) {
+               status = NT_STATUS_INTERNAL_ERROR;
+               goto done;
+       }
+
+       cnids->ca_unkn1 = 0xadd;
+       cnids->ca_context = 0x6b000020;
+
+       result = dalloc_add_copy(cnids->ca_cnids, &cnid, uint64_t);
+       if (result != 0) {
+               status = NT_STATUS_INTERNAL_ERROR;
+               goto done;
+       }
+
+       result = dalloc_add(array, cnids, sl_cnids_t);
+       if (result != 0) {
+               status = NT_STATUS_INTERNAL_ERROR;
+               goto done;
+       }
+
+       request_blob.spotlight_blob = talloc_array(mem_ctx,
+                                                  uint8_t,
+                                                  max_fragment_size);
+       if (request_blob.spotlight_blob == NULL) {
+               status = NT_STATUS_INTERNAL_ERROR;
+               goto done;
+       }
+       request_blob.size = max_fragment_size;
+
+       response_blob.spotlight_blob = talloc_array(mem_ctx,
+                                                   uint8_t,
+                                                   max_fragment_size);
+       if (response_blob.spotlight_blob == NULL) {
+               status = NT_STATUS_INTERNAL_ERROR;
+               goto done;
+       }
+       response_blob.size = max_fragment_size;
+
+       len = sl_pack(d, (char *)request_blob.spotlight_blob, request_blob.size);
+       if (len == -1) {
+               status = NT_STATUS_INTERNAL_ERROR;
+               goto done;
+       }
+       request_blob.length = len;
+       request_blob.size = len;
+
+       status = dcerpc_mdssvc_cmd(b, mem_ctx,
+                                  share_handle,
+                                  0,
+                                  device_id,
+                                  23,
+                                  0,
+                                  0x6b000001,
+                                  request_blob,
+                                  0,
+                                  max_fragment_size,
+                                  1,
+                                  max_fragment_size,
+                                  0,
+                                  0,
+                                  &mds_status,
+                                  &response_blob,
+                                  &unkn4);
+       if (!NT_STATUS_IS_OK(status)) {
+               printf("dcerpc_mdssvc_cmd failed: %s\n", nt_errstr(status));
+               goto done;
+       }
+
+       if (response_blob.length == 0) {
+               printf("mdssvc returned empty response\n");
+               status = NT_STATUS_RPC_PROTOCOL_ERROR;
+               goto done;
+       }
+
+       mds_reply = dalloc_new(mem_ctx);
+       if (mds_reply == NULL) {
+               status = NT_STATUS_NO_MEMORY;
+               goto done;
+       }
+
+       ok = sl_unpack(mds_reply, (char *)response_blob.spotlight_blob,
+                      response_blob.length);
+       if (!ok) {
+               printf("Unpacking Spotlight RPC blob failed\n");
+               status = NT_STATUS_INTERNAL_ERROR;
+               goto done;
+       }
+
+       printf("%s", dalloc_dump(mds_reply, 0));
+
+done:
+       return status;
+}
+
+/* List of commands exported by this module */
+
+struct cmd_set spotlight_commands[] = {
+
+       {
+               .name = "MDSSVC"
+       },
+       {
+               .name = "fetch_properties",
+               .returntype = RPC_RTYPE_NTSTATUS,
+               .ntfn = cmd_mdssvc_fetch_properties,
+               .table = &ndr_table_mdssvc,
+               .description = "Fetch connection properties",
+               .usage = "",
+       },
+       {
+               .name = "fetch_attributes",
+               .returntype = RPC_RTYPE_NTSTATUS,
+               .ntfn = cmd_mdssvc_fetch_attributes,
+               .table = &ndr_table_mdssvc,
+               .description = "Fetch attributes for a CNID",
+               .usage = "",
+       },
+       { NULL }
+};
index fd7a4199bc2d2a22750addebc899ea76c4933877..8f1aa8d875d1310ac6b7ce9471d2a3ba264774a3 100644 (file)
@@ -798,6 +798,7 @@ extern struct cmd_set winreg_commands[];
 extern struct cmd_set fss_commands[];
 extern struct cmd_set witness_commands[];
 extern struct cmd_set clusapi_commands[];
+extern struct cmd_set spotlight_commands[];
 
 static struct cmd_set *rpcclient_command_list[] = {
        rpcclient_commands,
@@ -821,6 +822,7 @@ static struct cmd_set *rpcclient_command_list[] = {
        fss_commands,
        witness_commands,
        clusapi_commands,
+       spotlight_commands,
        NULL
 };
 
index 11a64f3248ad11dff1815bac58467cef4152a0d2..bc2eeeb8c76cc8b39b001abcc92083b0b7f61119 100644 (file)
@@ -22,6 +22,7 @@ bld.SAMBA3_BINARY('rpcclient',
                  cmd_clusapi.c
                  cmd_witness.c
                 cmd_iremotewinspool.c
+                 cmd_spotlight.c
                 ''',
                  deps='''
                  talloc
@@ -53,4 +54,6 @@ bld.SAMBA3_BINARY('rpcclient',
                  RPC_NDR_CLUSAPI
                  RPC_NDR_WITNESS
                  RPC_NDR_WINSPOOL
+                 mdssvc
+                 RPC_NDR_MDSSVC
                  ''')