From c8f178055e45835a470f2452366df03796dc4d5c Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Mon, 10 May 2021 11:04:38 +0200 Subject: [PATCH 1/8] mdssvc: use a helper variable in mds_add_result() No change in behaviour. BUG: https://bugzilla.samba.org/show_bug.cgi?id=14740 Signed-off-by: Ralph Boehme Reviewed-by: Jeremy Allison (cherry picked from commit e2486d76b611f07b85b26c54fe14da7b76bd01c2) --- source3/rpc_server/mdssvc/mdssvc.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/source3/rpc_server/mdssvc/mdssvc.c b/source3/rpc_server/mdssvc/mdssvc.c index 8e98276d642..22495acf502 100644 --- a/source3/rpc_server/mdssvc/mdssvc.c +++ b/source3/rpc_server/mdssvc/mdssvc.c @@ -553,17 +553,19 @@ bool mds_add_result(struct sl_query *slq, const char *path) ino64 = sb.st_ex_ino; if (slq->cnids) { + bool found; + /* * Check whether the found element is in the requested * set of IDs. Note that we're faking CNIDs by using * filesystem inode numbers here */ - ok = bsearch(&ino64, - slq->cnids, - slq->cnids_num, - sizeof(uint64_t), - cnid_comp_fn); - if (!ok) { + found = bsearch(&ino64, + slq->cnids, + slq->cnids_num, + sizeof(uint64_t), + cnid_comp_fn); + if (!found) { return false; } } -- 2.31.1 From 5eadc21fb01e3d3b18d8b1a0fef0f6ca3f46a271 Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Mon, 10 May 2021 11:07:27 +0200 Subject: [PATCH 2/8] mdssvc: don't fail mds_add_result() if result is not found in CNID set Just skip adding the result to the pending results set, don't return an error. Returning an error triggers an error at the MDSSVC RPC error which is NOT what we want here. BUG: https://bugzilla.samba.org/show_bug.cgi?id=14740 Signed-off-by: Ralph Boehme Reviewed-by: Jeremy Allison (cherry picked from commit 8847f46f75ac5c1a753a0e7da88c522be25ef681) --- source3/rpc_server/mdssvc/mdssvc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/rpc_server/mdssvc/mdssvc.c b/source3/rpc_server/mdssvc/mdssvc.c index 22495acf502..48912669916 100644 --- a/source3/rpc_server/mdssvc/mdssvc.c +++ b/source3/rpc_server/mdssvc/mdssvc.c @@ -566,7 +566,7 @@ bool mds_add_result(struct sl_query *slq, const char *path) sizeof(uint64_t), cnid_comp_fn); if (!found) { - return false; + return true; } } -- 2.31.1 From 7705f4623639f348d16cd95fba3d9cf8f57ef939 Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Mon, 10 May 2021 12:08:17 +0200 Subject: [PATCH 3/8] mdssvc: pass messaging context to mds_init_ctx() This is needed in a subsequent commit. Note that I prefer to do the event context unwrapping in the caller and pass both the event and messaging context explicitly to mds_init_ctx(). BUG: https://bugzilla.samba.org/show_bug.cgi?id=14740 Signed-off-by: Ralph Boehme Reviewed-by: Jeremy Allison (cherry picked from commit 1ef2828e1025e4c89292df1dfa6161c4453b3afe) --- source3/rpc_server/mdssvc/mdssvc.c | 1 + source3/rpc_server/mdssvc/mdssvc.h | 1 + source3/rpc_server/mdssvc/srv_mdssvc_nt.c | 1 + 3 files changed, 3 insertions(+) diff --git a/source3/rpc_server/mdssvc/mdssvc.c b/source3/rpc_server/mdssvc/mdssvc.c index 48912669916..cdb0eaafd80 100644 --- a/source3/rpc_server/mdssvc/mdssvc.c +++ b/source3/rpc_server/mdssvc/mdssvc.c @@ -1524,6 +1524,7 @@ static int mds_ctx_destructor_cb(struct mds_ctx *mds_ctx) **/ struct mds_ctx *mds_init_ctx(TALLOC_CTX *mem_ctx, struct tevent_context *ev, + struct messaging_context *msg_ctx, struct auth_session_info *session_info, int snum, const char *sharename, diff --git a/source3/rpc_server/mdssvc/mdssvc.h b/source3/rpc_server/mdssvc/mdssvc.h index 7d9a902a80b..d37f6846711 100644 --- a/source3/rpc_server/mdssvc/mdssvc.h +++ b/source3/rpc_server/mdssvc/mdssvc.h @@ -150,6 +150,7 @@ extern bool mds_init(struct messaging_context *msg_ctx); extern bool mds_shutdown(void); struct mds_ctx *mds_init_ctx(TALLOC_CTX *mem_ctx, struct tevent_context *ev, + struct messaging_context *msg_ctx, struct auth_session_info *session_info, int snum, const char *sharename, diff --git a/source3/rpc_server/mdssvc/srv_mdssvc_nt.c b/source3/rpc_server/mdssvc/srv_mdssvc_nt.c index b9607262216..40e37cb3b85 100644 --- a/source3/rpc_server/mdssvc/srv_mdssvc_nt.c +++ b/source3/rpc_server/mdssvc/srv_mdssvc_nt.c @@ -95,6 +95,7 @@ static NTSTATUS create_mdssvc_policy_handle(TALLOC_CTX *mem_ctx, mds_ctx = mds_init_ctx(mem_ctx, messaging_tevent_context(p->msg_ctx), + p->msg_ctx, p->session_info, snum, sharename, -- 2.31.1 From 94b6d62e6896cdf68140cfa93181ef584af9d15b Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Tue, 15 Jun 2021 11:17:57 +0200 Subject: [PATCH 4/8] smbd: pass tevent context to create_conn_struct_as_root() The next commit will add another caller of create_conn_struct_as_root() that is going to pass a long-lived tevent context. BUG: https://bugzilla.samba.org/show_bug.cgi?id=14740 Signed-off-by: Ralph Boehme Reviewed-by: Jeremy Allison (cherry picked from commit 16c39b81d6f2c7d75cfe72bbbe2f6a5bde42c7b0) --- source3/smbd/msdfs.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/source3/smbd/msdfs.c b/source3/smbd/msdfs.c index 9e1127c339c..dacb83b3a46 100644 --- a/source3/smbd/msdfs.c +++ b/source3/smbd/msdfs.c @@ -243,6 +243,7 @@ static NTSTATUS parse_dfs_path(connection_struct *conn, *********************************************************/ static NTSTATUS create_conn_struct_as_root(TALLOC_CTX *ctx, + struct tevent_context *ev, struct messaging_context *msg, connection_struct **pconn, int snum, @@ -261,12 +262,7 @@ static NTSTATUS create_conn_struct_as_root(TALLOC_CTX *ctx, return NT_STATUS_NO_MEMORY; } - sconn->ev_ctx = samba_tevent_context_init(sconn); - if (sconn->ev_ctx == NULL) { - TALLOC_FREE(sconn); - return NT_STATUS_NO_MEMORY; - } - + sconn->ev_ctx = ev; sconn->msg_ctx = msg; conn = conn_new(sconn); @@ -402,6 +398,7 @@ NTSTATUS create_conn_struct_tos(struct messaging_context *msg, struct conn_struct_tos **_c) { struct conn_struct_tos *c = NULL; + struct tevent_context *ev = NULL; NTSTATUS status; *_c = NULL; @@ -411,8 +408,15 @@ NTSTATUS create_conn_struct_tos(struct messaging_context *msg, return NT_STATUS_NO_MEMORY; } + ev = samba_tevent_context_init(c); + if (ev == NULL) { + TALLOC_FREE(c); + return NT_STATUS_NO_MEMORY; + } + become_root(); status = create_conn_struct_as_root(c, + ev, msg, &c->conn, snum, -- 2.31.1 From 82f21e2e6960968f28fa5704b8d4275d32208c15 Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Fri, 28 May 2021 09:25:22 +0200 Subject: [PATCH 5/8] smbd: add create_conn_struct_cwd() Compared to create_conn_struct_tos_cwd() this takes a TALLOC_CTX and tevent_context as additional arguments and the resulting connection_struct is stable across the lifetime of mem_ctx and ev. BUG: https://bugzilla.samba.org/show_bug.cgi?id=14740 Signed-off-by: Ralph Boehme Reviewed-by: Jeremy Allison (cherry picked from commit 9a2d6bcfd5797dd4db764921548c8dca6dd0eb21) --- source3/smbd/msdfs.c | 38 ++++++++++++++++++++++++++++++++++++++ source3/smbd/proto.h | 8 ++++++++ 2 files changed, 46 insertions(+) diff --git a/source3/smbd/msdfs.c b/source3/smbd/msdfs.c index dacb83b3a46..54a421640a6 100644 --- a/source3/smbd/msdfs.c +++ b/source3/smbd/msdfs.c @@ -496,6 +496,44 @@ NTSTATUS create_conn_struct_tos_cwd(struct messaging_context *msg, return NT_STATUS_OK; } +/******************************************************** + Fake up a connection struct for the VFS layer. + This takes an TALLOC_CTX and tevent_context from the + caller and the resulting connection_struct is stable + across the lifetime of mem_ctx and ev. + + Note: this performs a vfs connect and changes cwd. + + See also the comment for create_conn_struct_tos() above! +*********************************************************/ + +NTSTATUS create_conn_struct_cwd(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct messaging_context *msg, + const struct auth_session_info *session_info, + int snum, + const char *path, + struct connection_struct **c) +{ + NTSTATUS status; + + become_root(); + status = create_conn_struct_as_root(mem_ctx, + ev, + msg, + c, + snum, + path, + session_info); + unbecome_root(); + if (!NT_STATUS_IS_OK(status)) { + TALLOC_FREE(c); + return status; + } + + return NT_STATUS_OK; +} + static void shuffle_strlist(char **list, int count) { int i; diff --git a/source3/smbd/proto.h b/source3/smbd/proto.h index ae5f82c2de5..f22cbe0d55f 100644 --- a/source3/smbd/proto.h +++ b/source3/smbd/proto.h @@ -561,6 +561,14 @@ NTSTATUS resolve_dfspath_wcard(TALLOC_CTX *ctx, bool *ppath_contains_wcard); struct connection_struct; struct smb_filename; + +NTSTATUS create_conn_struct_cwd(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct messaging_context *msg, + const struct auth_session_info *session_info, + int snum, + const char *path, + struct connection_struct **c); struct conn_struct_tos { struct connection_struct *conn; struct smb_filename *oldcwd_fname; -- 2.31.1 From 90bff4ecd05c14aee678c9cbff990b71bb5bf770 Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Mon, 10 May 2021 12:10:08 +0200 Subject: [PATCH 6/8] mdssvc: maintain a connection struct in the mds_ctx BUG: https://bugzilla.samba.org/show_bug.cgi?id=14740 Signed-off-by: Ralph Boehme Reviewed-by: Jeremy Allison (cherry picked from commit 8b681cfb5d9b1ece03f7e7b9d3a08ae6c461d679) --- source3/rpc_server/mdssvc/mdssvc.c | 30 ++++++++++++++++++++++++++++++ source3/rpc_server/mdssvc/mdssvc.h | 1 + 2 files changed, 31 insertions(+) diff --git a/source3/rpc_server/mdssvc/mdssvc.c b/source3/rpc_server/mdssvc/mdssvc.c index cdb0eaafd80..c0a59ebd3ab 100644 --- a/source3/rpc_server/mdssvc/mdssvc.c +++ b/source3/rpc_server/mdssvc/mdssvc.c @@ -19,6 +19,7 @@ */ #include "includes.h" +#include "smbd/proto.h" #include "librpc/gen_ndr/auth.h" #include "dbwrap/dbwrap.h" #include "lib/util/dlinklist.h" @@ -1530,10 +1531,15 @@ struct mds_ctx *mds_init_ctx(TALLOC_CTX *mem_ctx, const char *sharename, const char *path) { + const struct loadparm_substitution *lp_sub = + loadparm_s3_global_substitution(); + struct smb_filename conn_basedir; struct mds_ctx *mds_ctx; int backend; + int ret; bool ok; smb_iconv_t iconv_hnd = (smb_iconv_t)-1; + NTSTATUS status; mds_ctx = talloc_zero(mem_ctx, struct mds_ctx); if (mds_ctx == NULL) { @@ -1615,6 +1621,30 @@ struct mds_ctx *mds_init_ctx(TALLOC_CTX *mem_ctx, goto error; } + status = create_conn_struct_cwd(mds_ctx, + ev, + msg_ctx, + session_info, + snum, + lp_path(talloc_tos(), lp_sub, snum), + &mds_ctx->conn); + if (!NT_STATUS_IS_OK(status)) { + DBG_ERR("failed to create conn for vfs: %s\n", + nt_errstr(status)); + goto error; + } + + conn_basedir = (struct smb_filename) { + .base_name = mds_ctx->conn->connectpath, + }; + + ret = vfs_ChDir(mds_ctx->conn, &conn_basedir); + if (ret != 0) { + DBG_ERR("vfs_ChDir [%s] failed: %s\n", + conn_basedir.base_name, strerror(errno)); + goto error; + } + ok = mds_ctx->backend->connect(mds_ctx); if (!ok) { DBG_ERR("backend connect failed\n"); diff --git a/source3/rpc_server/mdssvc/mdssvc.h b/source3/rpc_server/mdssvc/mdssvc.h index d37f6846711..392482767dd 100644 --- a/source3/rpc_server/mdssvc/mdssvc.h +++ b/source3/rpc_server/mdssvc/mdssvc.h @@ -126,6 +126,7 @@ struct mds_ctx { int snum; const char *sharename; const char *spath; + struct connection_struct *conn; struct sl_query *query_list; /* list of active queries */ struct db_context *ino_path_map; /* dbwrap rbt for storing inode->path mappings */ }; -- 2.31.1 From dce1376c057e27712132da726d83c1d5cdc019b3 Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Tue, 15 Jun 2021 14:14:52 +0200 Subject: [PATCH 7/8] mdssvc: chdir() to the conn of the RPC request In preperation of calling VFS functions. BUG: https://bugzilla.samba.org/show_bug.cgi?id=14740 Reviewed-by: Ralph Boehme Reviewed-by: Jeremy Allison (cherry picked from commit 6de3a88494b5932d0fd10f5c8c8ec57916aeefc5) --- source3/rpc_server/mdssvc/mdssvc.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/source3/rpc_server/mdssvc/mdssvc.c b/source3/rpc_server/mdssvc/mdssvc.c index c0a59ebd3ab..a425e658f14 100644 --- a/source3/rpc_server/mdssvc/mdssvc.c +++ b/source3/rpc_server/mdssvc/mdssvc.c @@ -1673,11 +1673,15 @@ bool mds_dispatch(struct mds_ctx *mds_ctx, struct mdssvc_blob *response_blob) { bool ok; + int ret; ssize_t len; DALLOC_CTX *query = NULL; DALLOC_CTX *reply = NULL; char *rpccmd; const struct slrpc_cmd *slcmd; + const struct smb_filename conn_basedir = { + .base_name = mds_ctx->conn->connectpath, + }; if (CHECK_DEBUGLVL(10)) { const struct sl_query *slq; @@ -1729,6 +1733,14 @@ bool mds_dispatch(struct mds_ctx *mds_ctx, goto cleanup; } + ret = vfs_ChDir(mds_ctx->conn, &conn_basedir); + if (ret != 0) { + DBG_ERR("vfs_ChDir [%s] failed: %s\n", + conn_basedir.base_name, strerror(errno)); + ok = false; + goto cleanup; + } + ok = slcmd->function(mds_ctx, query, reply); if (ok) { DBG_DEBUG("%s", dalloc_dump(reply, 0)); -- 2.31.1 From ae59e5f0c262aea00d72f505e3802b8374354b38 Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Mon, 10 May 2021 12:34:32 +0200 Subject: [PATCH 8/8] mdssvc: avoid direct filesystem access, use the VFS MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This ensures mdssvc uses the same FileIDs as the fileserver as well as Spotlight can be used working on a virtual filesystem like GlusterFS. BUG: https://bugzilla.samba.org/show_bug.cgi?id=14740 Signed-off-by: Ralph Boehme Reviewed-by: Jeremy Allison Autobuild-User(master): Ralph Böhme Autobuild-Date(master): Wed Jun 16 05:59:13 UTC 2021 on sn-devel-184 (backported from commit 620b99144359f45aa69c13731db8d793cfbba197) [slow@samba.org: use path based VFS functions, not the handle based ones] --- source3/rpc_server/mdssvc/mdssvc.c | 68 +++++++++++++++++++++++++++--- 1 file changed, 61 insertions(+), 7 deletions(-) diff --git a/source3/rpc_server/mdssvc/mdssvc.c b/source3/rpc_server/mdssvc/mdssvc.c index a425e658f14..2b243d64e99 100644 --- a/source3/rpc_server/mdssvc/mdssvc.c +++ b/source3/rpc_server/mdssvc/mdssvc.c @@ -27,6 +27,7 @@ #include "lib/util/time_basic.h" #include "lib/dbwrap/dbwrap_rbt.h" #include "libcli/security/dom_sid.h" +#include "libcli/security/security.h" #include "mdssvc.h" #include "mdssvc_noindex.h" #ifdef HAVE_SPOTLIGHT_BACKEND_TRACKER @@ -513,11 +514,25 @@ static bool inode_map_add(struct sl_query *slq, uint64_t ino, const char *path) bool mds_add_result(struct sl_query *slq, const char *path) { + struct smb_filename *smb_fname = NULL; struct stat_ex sb; + uint32_t attr; uint64_t ino64; int result; + NTSTATUS status; bool ok; + smb_fname = synthetic_smb_fname(talloc_tos(), + path, + NULL, + NULL, + 0, + 0); + if (smb_fname == NULL) { + DBG_ERR("synthetic_smb_fname() failed\n"); + return false; + } + /* * We're in a tevent callback which means in the case of * running as external RPC service we're running as root and @@ -539,20 +554,44 @@ bool mds_add_result(struct sl_query *slq, const char *path) * any function exit below must ensure we switch back */ - result = sys_stat(path, &sb, false); + result = SMB_VFS_STAT(slq->mds_ctx->conn, smb_fname); if (result != 0) { + DBG_DEBUG("SMB_VFS_STAT [%s] failed: %s\n", + smb_fname_str_dbg(smb_fname), + strerror(errno)); unbecome_authenticated_pipe_user(); + TALLOC_FREE(smb_fname); return true; } - result = access(path, R_OK); - if (result != 0) { + + status = smbd_check_access_rights(slq->mds_ctx->conn, + slq->mds_ctx->conn->cwd_fsp, + smb_fname, + false, + FILE_READ_DATA); + if (!NT_STATUS_IS_OK(status)) { unbecome_authenticated_pipe_user(); + TALLOC_FREE(smb_fname); return true; } + /* This is needed to fetch the itime from the DOS attribute blob */ + status = SMB_VFS_GET_DOS_ATTRIBUTES(slq->mds_ctx->conn, + smb_fname, + &attr); + if (!NT_STATUS_IS_OK(status)) { + /* Ignore the error, likely no DOS attr xattr */ + DBG_DEBUG("SMB_VFS_FGET_DOS_ATTRIBUTES [%s]: %s\n", + smb_fname_str_dbg(smb_fname), + nt_errstr(status)); + } + unbecome_authenticated_pipe_user(); - ino64 = sb.st_ex_ino; + sb = smb_fname->st; + TALLOC_FREE(smb_fname); + ino64 = SMB_VFS_FS_FILE_ID(slq->mds_ctx->conn, &sb); + if (slq->cnids) { bool found; @@ -1233,7 +1272,7 @@ static bool slrpc_fetch_attributes(struct mds_ctx *mds_ctx, sl_array_t *fm_array; sl_nil_t nil; char *path = NULL; - struct stat_ex sb = {0}; + struct smb_filename *smb_fname = NULL; struct stat_ex *sp = NULL; struct sl_inode_path_map *elem = NULL; void *p; @@ -1302,11 +1341,23 @@ static bool slrpc_fetch_attributes(struct mds_ctx *mds_ctx, elem = talloc_get_type_abort(p, struct sl_inode_path_map); path = elem->path; - result = sys_stat(path, &sb, false); + smb_fname = synthetic_smb_fname(talloc_tos(), + path, + NULL, + NULL, + 0, + 0); + if (smb_fname == NULL) { + DBG_ERR("synthetic_smb_fname() failed\n"); + goto error; + } + + result = SMB_VFS_STAT(mds_ctx->conn, smb_fname); if (result != 0) { goto error; } - sp = &sb; + + sp = &smb_fname->st; } ok = add_filemeta(mds_ctx, reqinfo, fm_array, path, sp); @@ -1336,9 +1387,12 @@ static bool slrpc_fetch_attributes(struct mds_ctx *mds_ctx, goto error; } + TALLOC_FREE(smb_fname); return true; error: + + TALLOC_FREE(smb_fname); sl_result = UINT64_MAX; result = dalloc_add_copy(array, &sl_result, uint64_t); if (result != 0) { -- 2.31.1