mirror of
https://github.com/samba-team/samba.git
synced 2025-02-18 17:57:55 +03:00
Implement all Spotlight RPC commands with the Tracker SPARQL async query API. Tracker uses glib for implemeting async tasks, we thus have to use a glib mainloop for processing sheduled tasks in threads. Signed-off-by: Ralph Boehme <slow@samba.org> Reviewed-by: Stefan Metzmacher <metze@samba.org>
214 lines
5.3 KiB
C
214 lines
5.3 KiB
C
/*
|
|
* Unix SMB/CIFS implementation.
|
|
* RPC Pipe client / server routines for mdssvc
|
|
* Copyright (C) Ralph Boehme 2014
|
|
*
|
|
* 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 "ntdomain.h"
|
|
#include "rpc_server/mdssvc/srv_mdssvc_nt.h"
|
|
#include "../librpc/gen_ndr/srv_mdssvc.h"
|
|
#include "libcli/security/security_token.h"
|
|
#include "gen_ndr/auth.h"
|
|
#include "mdssvc.h"
|
|
|
|
#undef DBGC_CLASS
|
|
#define DBGC_CLASS DBGC_RPC_SRV
|
|
|
|
bool init_service_mdssvc(struct messaging_context *msg_ctx)
|
|
{
|
|
return mds_init(msg_ctx);
|
|
}
|
|
|
|
bool shutdown_service_mdssvc(void)
|
|
{
|
|
return mds_shutdown();
|
|
}
|
|
|
|
static NTSTATUS create_mdssvc_policy_handle(TALLOC_CTX *mem_ctx,
|
|
struct pipes_struct *p,
|
|
const char *path,
|
|
struct policy_handle *handle)
|
|
{
|
|
struct mds_ctx *mds_ctx;
|
|
|
|
ZERO_STRUCTP(handle);
|
|
|
|
mds_ctx = mds_init_ctx(mem_ctx, p->session_info, path);
|
|
if (mds_ctx == NULL) {
|
|
DEBUG(1, ("error in mds_init_ctx for: %s\n", path));
|
|
return NT_STATUS_UNSUCCESSFUL;
|
|
}
|
|
|
|
if (!create_policy_hnd(p, handle, mds_ctx)) {
|
|
talloc_free(mds_ctx);
|
|
ZERO_STRUCTP(handle);
|
|
return NT_STATUS_NO_MEMORY;
|
|
}
|
|
|
|
return NT_STATUS_OK;
|
|
}
|
|
|
|
void _mdssvc_open(struct pipes_struct *p, struct mdssvc_open *r)
|
|
{
|
|
int snum;
|
|
char *path;
|
|
NTSTATUS status;
|
|
|
|
DEBUG(10, ("%s: [%s]\n", __func__, r->in.share_name));
|
|
|
|
snum = lp_servicenumber(r->in.share_name);
|
|
if (!VALID_SNUM(snum)) {
|
|
p->fault_state = DCERPC_FAULT_CANT_PERFORM;
|
|
return;
|
|
}
|
|
|
|
if (lp_spotlight(snum)) {
|
|
DEBUG(10, ("Spotlight enabled: %s\n", r->in.share_name));
|
|
|
|
path = lp_path(talloc_tos(), snum);
|
|
if (path == NULL) {
|
|
DEBUG(1, ("Couldn't create policy handle for %s\n",
|
|
r->in.share_name));
|
|
p->fault_state = DCERPC_FAULT_CANT_PERFORM;
|
|
return;
|
|
}
|
|
|
|
status = create_mdssvc_policy_handle(p->mem_ctx, p, path,
|
|
r->out.handle);
|
|
if (!NT_STATUS_IS_OK(status)) {
|
|
DEBUG(1, ("Couldn't create policy handle for %s\n",
|
|
r->in.share_name));
|
|
talloc_free(path);
|
|
p->fault_state = DCERPC_FAULT_CANT_PERFORM;
|
|
return;
|
|
}
|
|
|
|
strlcpy(discard_const_p(char, r->out.share_path), path, 1024);
|
|
talloc_free(path);
|
|
*r->out.device_id = *r->in.device_id;
|
|
}
|
|
|
|
*r->out.unkn2 = 0x17;
|
|
*r->out.unkn3 = 0;
|
|
|
|
return;
|
|
}
|
|
|
|
void _mdssvc_unknown1(struct pipes_struct *p, struct mdssvc_unknown1 *r)
|
|
{
|
|
struct mds_ctx *mds_ctx;
|
|
|
|
if (!find_policy_by_hnd(p, &r->in.handle, (void **)(void *)&mds_ctx)) {
|
|
DEBUG(1, ("%s: invalid handle\n", __func__));
|
|
return;
|
|
}
|
|
|
|
DEBUG(10, ("%s: path: %s\n", __func__, mds_ctx->spath));
|
|
|
|
*r->out.status = 0;
|
|
*r->out.flags = 0x6b000001;
|
|
*r->out.unkn7 = 0;
|
|
|
|
return;
|
|
}
|
|
|
|
void _mdssvc_cmd(struct pipes_struct *p, struct mdssvc_cmd *r)
|
|
{
|
|
bool ok;
|
|
char *rbuf;
|
|
struct mds_ctx *mds_ctx;
|
|
|
|
if (!find_policy_by_hnd(p, &r->in.handle, (void **)(void *)&mds_ctx)) {
|
|
DEBUG(1, ("%s: invalid handle\n", __func__));
|
|
return;
|
|
}
|
|
|
|
DEBUG(10, ("%s: path: %s\n", __func__, mds_ctx->spath));
|
|
|
|
ok = security_token_is_sid(p->session_info->security_token,
|
|
&mds_ctx->sid);
|
|
if (!ok) {
|
|
DEBUG(1,("%s: not the same sid: %s\n", __func__,
|
|
sid_string_tos(&mds_ctx->sid)));
|
|
p->fault_state = DCERPC_FAULT_ACCESS_DENIED;
|
|
return;
|
|
}
|
|
|
|
if (geteuid() != mds_ctx->uid) {
|
|
DEBUG(0, ("uid mismatch: %d/%d\n", geteuid(), mds_ctx->uid));
|
|
smb_panic("uid mismatch");
|
|
}
|
|
|
|
if (r->in.request_blob.size > MAX_SL_FRAGMENT_SIZE) {
|
|
DEBUG(1, ("%s: request size too large\n", __func__));
|
|
p->fault_state = DCERPC_FAULT_CANT_PERFORM;
|
|
return;
|
|
}
|
|
|
|
if (r->in.request_blob.length > MAX_SL_FRAGMENT_SIZE) {
|
|
DEBUG(1, ("%s: request length too large\n", __func__));
|
|
p->fault_state = DCERPC_FAULT_CANT_PERFORM;
|
|
return;
|
|
}
|
|
|
|
if (r->in.max_fragment_size1 > MAX_SL_FRAGMENT_SIZE) {
|
|
DEBUG(1, ("%s: request fragment size too large: %u\n",
|
|
__func__, (unsigned)r->in.max_fragment_size1));
|
|
p->fault_state = DCERPC_FAULT_CANT_PERFORM;
|
|
return;
|
|
}
|
|
|
|
rbuf = talloc_zero_array(p->mem_ctx, char, r->in.max_fragment_size1);
|
|
if (rbuf == NULL) {
|
|
p->fault_state = DCERPC_FAULT_CANT_PERFORM;
|
|
return;
|
|
}
|
|
r->out.response_blob->spotlight_blob = (uint8_t *)rbuf;
|
|
r->out.response_blob->size = r->in.max_fragment_size1;
|
|
|
|
ok = mds_dispatch(mds_ctx, &r->in.request_blob, r->out.response_blob);
|
|
if (ok) {
|
|
*r->out.status = 0;
|
|
*r->out.unkn9 = 0;
|
|
} else {
|
|
/* FIXME: just interpolating from AFP, needs verification */
|
|
*r->out.status = UINT32_MAX;
|
|
*r->out.unkn9 = UINT32_MAX;
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
void _mdssvc_close(struct pipes_struct *p, struct mdssvc_close *r)
|
|
{
|
|
struct mds_ctx *mds_ctx;
|
|
|
|
if (!find_policy_by_hnd(p, &r->in.in_handle, (void **)(void *)&mds_ctx)) {
|
|
DEBUG(1, ("%s: invalid handle\n", __func__));
|
|
return;
|
|
}
|
|
|
|
DEBUG(10, ("%s: path: %s\n", __func__, mds_ctx->spath));
|
|
|
|
close_policy_hnd(p, &r->in.in_handle);
|
|
|
|
ZERO_STRUCTP(r->out.out_handle);
|
|
*r->out.status = 0;
|
|
|
|
return;
|
|
}
|