diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-05 17:47:29 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-05 17:47:29 +0000 |
commit | 4f5791ebd03eaec1c7da0865a383175b05102712 (patch) | |
tree | 8ce7b00f7a76baa386372422adebbe64510812d4 /source3/rpcclient/cmd_spotlight.c | |
parent | Initial commit. (diff) | |
download | samba-4f5791ebd03eaec1c7da0865a383175b05102712.tar.xz samba-4f5791ebd03eaec1c7da0865a383175b05102712.zip |
Adding upstream version 2:4.17.12+dfsg.upstream/2%4.17.12+dfsgupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'source3/rpcclient/cmd_spotlight.c')
-rw-r--r-- | source3/rpcclient/cmd_spotlight.c | 420 |
1 files changed, 420 insertions, 0 deletions
diff --git a/source3/rpcclient/cmd_spotlight.c b/source3/rpcclient/cmd_spotlight.c new file mode 100644 index 0000000..ba3f61f --- /dev/null +++ b/source3/rpcclient/cmd_spotlight.c @@ -0,0 +1,420 @@ +/* + 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] = { 0 }; + 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; + 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; + } + + status = sl_pack_alloc(mem_ctx, d, &request_blob, max_fragment_size); + if (!NT_STATUS_IS_OK(status)) { + goto done; + } + + 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; + 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; + } + + status = sl_pack_alloc(mem_ctx, d, &request_blob, max_fragment_size); + if (!NT_STATUS_IS_OK(status)) { + goto done; + } + + 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 = "", + }, + {0} +}; |