From 1d74c26c09957d1f42c7f5e76fdb23a5dd517cb8 Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Wed, 25 May 2022 17:26:29 +0200 Subject: [PATCH 1/3] mdssvc: convert mds_init_ctx() to return NTSTATUS No change in behavour. In preperation for returning a special error to signal the caller that spotlight is disabled for a share. Bug: https://bugzilla.samba.org/show_bug.cgi?id=15086 Signed-off-by: Ralph Boehme Reviewed-by: Noel Power (cherry picked from commit 72468166b250de26747071cbbf3613c016ebfd42) --- source3/rpc_server/mdssvc/mdssvc.c | 33 +++++++++++++++-------- source3/rpc_server/mdssvc/mdssvc.h | 15 ++++++----- source3/rpc_server/mdssvc/srv_mdssvc_nt.c | 23 +++++++++------- 3 files changed, 43 insertions(+), 28 deletions(-) diff --git a/source3/rpc_server/mdssvc/mdssvc.c b/source3/rpc_server/mdssvc/mdssvc.c index 956e097eaf4b..fc6931f227e2 100644 --- a/source3/rpc_server/mdssvc/mdssvc.c +++ b/source3/rpc_server/mdssvc/mdssvc.c @@ -1585,13 +1585,14 @@ static int mds_ctx_destructor_cb(struct mds_ctx *mds_ctx) * This ends up being called for every tcon, because the client does a * RPC bind for every tcon, so this is acually a per tcon context. **/ -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, - const char *path) +NTSTATUS 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, + const char *path, + struct mds_ctx **_mds_ctx) { const struct loadparm_substitution *lp_sub = loadparm_s3_global_substitution(); @@ -1605,13 +1606,13 @@ struct mds_ctx *mds_init_ctx(TALLOC_CTX *mem_ctx, mds_ctx = talloc_zero(mem_ctx, struct mds_ctx); if (mds_ctx == NULL) { - return NULL; + return NT_STATUS_NO_MEMORY; } talloc_set_destructor(mds_ctx, mds_ctx_destructor_cb); mds_ctx->mdssvc_ctx = mdssvc_init(ev); if (mds_ctx->mdssvc_ctx == NULL) { - goto error; + return NT_STATUS_NO_MEMORY; } backend = lp_spotlight_backend(snum); @@ -1637,6 +1638,7 @@ struct mds_ctx *mds_init_ctx(TALLOC_CTX *mem_ctx, default: DBG_ERR("Unknown backend %d\n", backend); TALLOC_FREE(mdssvc_ctx); + status = NT_STATUS_INTERNAL_ERROR; goto error; } @@ -1645,6 +1647,7 @@ struct mds_ctx *mds_init_ctx(TALLOC_CTX *mem_ctx, "UTF8-NFC", false); if (iconv_hnd == (smb_iconv_t)-1) { + status = NT_STATUS_INTERNAL_ERROR; goto error; } mds_ctx->ic_nfc_to_nfd = iconv_hnd; @@ -1654,17 +1657,20 @@ struct mds_ctx *mds_init_ctx(TALLOC_CTX *mem_ctx, "UTF8-NFD", false); if (iconv_hnd == (smb_iconv_t)-1) { + status = NT_STATUS_INTERNAL_ERROR; goto error; } mds_ctx->ic_nfd_to_nfc = iconv_hnd; mds_ctx->sharename = talloc_strdup(mds_ctx, sharename); if (mds_ctx->sharename == NULL) { + status = NT_STATUS_NO_MEMORY; goto error; } mds_ctx->spath = talloc_strdup(mds_ctx, path); if (mds_ctx->spath == NULL) { + status = NT_STATUS_NO_MEMORY; goto error; } @@ -1672,6 +1678,7 @@ struct mds_ctx *mds_init_ctx(TALLOC_CTX *mem_ctx, mds_ctx->pipe_session_info = session_info; if (session_info->security_token->num_sids < 1) { + status = NT_STATUS_BAD_LOGON_SESSION_STATE; goto error; } sid_copy(&mds_ctx->sid, &session_info->security_token->sids[0]); @@ -1680,6 +1687,7 @@ struct mds_ctx *mds_init_ctx(TALLOC_CTX *mem_ctx, mds_ctx->ino_path_map = db_open_rbt(mds_ctx); if (mds_ctx->ino_path_map == NULL) { DEBUG(1,("open inode map db failed\n")); + status = NT_STATUS_INTERNAL_ERROR; goto error; } @@ -1704,16 +1712,19 @@ struct mds_ctx *mds_init_ctx(TALLOC_CTX *mem_ctx, if (ret != 0) { DBG_ERR("vfs_ChDir [%s] failed: %s\n", conn_basedir.base_name, strerror(errno)); + status = map_nt_error_from_unix(errno); goto error; } ok = mds_ctx->backend->connect(mds_ctx); if (!ok) { DBG_ERR("backend connect failed\n"); + status = NT_STATUS_CONNECTION_RESET; goto error; } - return mds_ctx; + *_mds_ctx = mds_ctx; + return NT_STATUS_OK; error: if (mds_ctx->ic_nfc_to_nfd != NULL) { @@ -1724,7 +1735,7 @@ struct mds_ctx *mds_init_ctx(TALLOC_CTX *mem_ctx, } TALLOC_FREE(mds_ctx); - return NULL; + return status; } /** diff --git a/source3/rpc_server/mdssvc/mdssvc.h b/source3/rpc_server/mdssvc/mdssvc.h index 392482767dd8..205417c4be1c 100644 --- a/source3/rpc_server/mdssvc/mdssvc.h +++ b/source3/rpc_server/mdssvc/mdssvc.h @@ -149,13 +149,14 @@ struct mdssvc_backend { */ 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, - const char *path); +NTSTATUS 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, + const char *path, + struct mds_ctx **_mds_ctx); extern bool mds_dispatch(struct mds_ctx *query_ctx, struct mdssvc_blob *request_blob, struct mdssvc_blob *response_blob); diff --git a/source3/rpc_server/mdssvc/srv_mdssvc_nt.c b/source3/rpc_server/mdssvc/srv_mdssvc_nt.c index 01c191bf01d3..2d572a887d0b 100644 --- a/source3/rpc_server/mdssvc/srv_mdssvc_nt.c +++ b/source3/rpc_server/mdssvc/srv_mdssvc_nt.c @@ -48,19 +48,22 @@ static NTSTATUS create_mdssvc_policy_handle(TALLOC_CTX *mem_ctx, struct auth_session_info *session_info = dcesrv_call_session_info(dce_call); struct mds_ctx *mds_ctx; + NTSTATUS status; ZERO_STRUCTP(handle); - mds_ctx = mds_init_ctx(mem_ctx, - messaging_tevent_context(p->msg_ctx), - p->msg_ctx, - session_info, - snum, - sharename, - path); - if (mds_ctx == NULL) { - DEBUG(1, ("error in mds_init_ctx for: %s\n", path)); - return NT_STATUS_UNSUCCESSFUL; + status = mds_init_ctx(mem_ctx, + messaging_tevent_context(p->msg_ctx), + p->msg_ctx, + session_info, + snum, + sharename, + path, + &mds_ctx); + if (!NT_STATUS_IS_OK(status)) { + DBG_WARNING("mds_init_ctx() path [%s] failed: %s\n", + path, nt_errstr(status)); + return status; } if (!create_policy_hnd(p, handle, 0, mds_ctx)) { -- 2.36.1 From fee296152ba23c83b8345c1bc6f2842997cf6a72 Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Tue, 7 Jun 2022 09:52:53 +0200 Subject: [PATCH 2/3] CI: fix check for correct mdsvc resonse when connecting to a share with Spotlight disabled A Mac SMB server returns an all zero handle and an empty path if Spotlight is disabled on a share. We must return the exact same error return in order to trigger client-side searching. Bug: https://bugzilla.samba.org/show_bug.cgi?id=15086 pcap: https://www.samba.org/~slow/pcaps/mac-bigsur-smbserver-spotlight-disabled.pcapng.gz Signed-off-by: Ralph Boehme Reviewed-by: Noel Power (backported from commit 8e997bd6e9250499fd8e569d708edc29e304a0e8) [slow@samba.org: conflicts in tests.py caused by unrelated tests] --- selftest/knownfail.d/samba3.rpc.mdssvc | 1 + source3/selftest/tests.py | 2 +- source4/torture/rpc/mdssvc.c | 17 ++++++++--------- 3 files changed, 10 insertions(+), 10 deletions(-) create mode 100644 selftest/knownfail.d/samba3.rpc.mdssvc diff --git a/selftest/knownfail.d/samba3.rpc.mdssvc b/selftest/knownfail.d/samba3.rpc.mdssvc new file mode 100644 index 000000000000..7a6ed0fe3468 --- /dev/null +++ b/selftest/knownfail.d/samba3.rpc.mdssvc @@ -0,0 +1 @@ +^samba3.rpc.mdssvc.rpccmd.open_spotlight_disabled\(fileserver\) diff --git a/source3/selftest/tests.py b/source3/selftest/tests.py index f4df916e6f85..3bc2b08f8a72 100755 --- a/source3/selftest/tests.py +++ b/source3/selftest/tests.py @@ -882,7 +882,7 @@ tests = base + raw + smb2 + rpc + unix + local + rap + nbt + idmap + vfs plansmbtorture4testsuite(t, "ad_dc", '//$SERVER_IP/tmp -U$USERNAME%$PASSWORD', 'over ncacn_np ') plansmbtorture4testsuite(t, "ad_dc", 'ncacn_ip_tcp:$SERVER_IP -U$USERNAME%$PASSWORD', 'over ncacn_ip_tcp ') elif t == "rpc.mdssvc": - plansmbtorture4testsuite(t, "fileserver", '//$SERVER_IP/tmp -U$USERNAME%$PASSWORD --option=torture:no_spotlight_localdir=$SELFTEST_PREFIX/fileserver/share') + plansmbtorture4testsuite(t, "fileserver", '//$SERVER_IP/tmp -U$USERNAME%$PASSWORD') elif t == "rpc.samr.passwords.validate": plansmbtorture4testsuite(t, "nt4_dc", 'ncacn_ip_tcp:$SERVER_IP[seal] -U$USERNAME%$PASSWORD', 'over ncacn_ip_tcp ') plansmbtorture4testsuite(t, "ad_dc", 'ncacn_ip_tcp:$SERVER_IP[seal] -U$USERNAME%$PASSWORD', 'over ncacn_ip_tcp ') diff --git a/source4/torture/rpc/mdssvc.c b/source4/torture/rpc/mdssvc.c index 17e895a8cc2b..8f16af664766 100644 --- a/source4/torture/rpc/mdssvc.c +++ b/source4/torture/rpc/mdssvc.c @@ -264,7 +264,7 @@ static bool test_mdssvc_open_spotlight_disabled(struct torture_context *tctx, data, struct torture_mdsscv_state); struct dcerpc_binding_handle *b = state->p->binding_handle; struct policy_handle ph; - const char *localdir = NULL; + struct policy_handle nullh; uint32_t device_id; uint32_t unkn2; uint32_t unkn3; @@ -282,17 +282,12 @@ static bool test_mdssvc_open_spotlight_disabled(struct torture_context *tctx, share_mount_path = torture_setting_string( tctx, "share_mount_path", "/foo/bar"); - localdir = torture_setting_string( - tctx, "no_spotlight_localdir", NULL); - torture_assert_not_null_goto( - tctx, localdir, ok, done, - "need 'no_spotlight_localdir' torture option \n"); - device_id_out = device_id = generate_random(); unkn2_out = unkn2 = 23; unkn3_out = unkn3 = 0; ZERO_STRUCT(ph); + ZERO_STRUCT(nullh); status = dcerpc_mdssvc_open(b, tctx, @@ -315,8 +310,12 @@ static bool test_mdssvc_open_spotlight_disabled(struct torture_context *tctx, torture_assert_u32_equal_goto(tctx, unkn3, unkn3_out, ok, done, "Bad unkn3\n"); - torture_assert_str_equal_goto(tctx, share_path, localdir, ok, done, - "Wrong share path\n"); + torture_assert_goto(tctx, share_path[0] == '\0', ok, done, + "Expected empty string as share path\n"); + + torture_assert_mem_equal_goto(tctx, &ph, &nullh, + sizeof(ph), ok, done, + "Expected all-zero policy handle\n"); done: return ok; -- 2.36.1 From 1b6a70310a49beb8f2d19320d3c08b0e4487dbd8 Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Wed, 25 May 2022 17:37:22 +0200 Subject: [PATCH 3/3] mdssvc: return all-zero policy handle if spotlight is disabled A Mac SMB server returns an all zero handle and an empty path if Spotlight is disabled on a share. We must return the exact same error return in order to trigger client-side searching. Bug: https://bugzilla.samba.org/show_bug.cgi?id=15086 pcap: https://www.samba.org/~slow/pcaps/mac-bigsur-smbserver-spotlight-disabled.pcapng.gz Signed-off-by: Ralph Boehme Reviewed-by: Noel Power Autobuild-User(master): Noel Power Autobuild-Date(master): Tue Jul 12 15:42:52 UTC 2022 on sn-devel-184 (cherry picked from commit 23e6e50c0f82b997dea4a67069f65252045514c0) --- selftest/knownfail.d/samba3.rpc.mdssvc | 1 - source3/rpc_server/mdssvc/mdssvc.c | 7 ++++--- source3/rpc_server/mdssvc/srv_mdssvc_nt.c | 9 +++++++-- 3 files changed, 11 insertions(+), 6 deletions(-) delete mode 100644 selftest/knownfail.d/samba3.rpc.mdssvc diff --git a/selftest/knownfail.d/samba3.rpc.mdssvc b/selftest/knownfail.d/samba3.rpc.mdssvc deleted file mode 100644 index 7a6ed0fe3468..000000000000 --- a/selftest/knownfail.d/samba3.rpc.mdssvc +++ /dev/null @@ -1 +0,0 @@ -^samba3.rpc.mdssvc.rpccmd.open_spotlight_disabled\(fileserver\) diff --git a/source3/rpc_server/mdssvc/mdssvc.c b/source3/rpc_server/mdssvc/mdssvc.c index fc6931f227e2..a4b082b32741 100644 --- a/source3/rpc_server/mdssvc/mdssvc.c +++ b/source3/rpc_server/mdssvc/mdssvc.c @@ -1604,6 +1604,10 @@ NTSTATUS mds_init_ctx(TALLOC_CTX *mem_ctx, smb_iconv_t iconv_hnd = (smb_iconv_t)-1; NTSTATUS status; + if (!lp_spotlight(snum)) { + return NT_STATUS_WRONG_VOLUME; + } + mds_ctx = talloc_zero(mem_ctx, struct mds_ctx); if (mds_ctx == NULL) { return NT_STATUS_NO_MEMORY; @@ -1616,9 +1620,6 @@ NTSTATUS mds_init_ctx(TALLOC_CTX *mem_ctx, } backend = lp_spotlight_backend(snum); - if (!lp_spotlight(snum)) { - backend = SPOTLIGHT_BACKEND_NOINDEX; - } switch (backend) { case SPOTLIGHT_BACKEND_NOINDEX: mds_ctx->backend = &mdsscv_backend_noindex; diff --git a/source3/rpc_server/mdssvc/srv_mdssvc_nt.c b/source3/rpc_server/mdssvc/srv_mdssvc_nt.c index 2d572a887d0b..2fca15cb8a8d 100644 --- a/source3/rpc_server/mdssvc/srv_mdssvc_nt.c +++ b/source3/rpc_server/mdssvc/srv_mdssvc_nt.c @@ -61,8 +61,8 @@ static NTSTATUS create_mdssvc_policy_handle(TALLOC_CTX *mem_ctx, path, &mds_ctx); if (!NT_STATUS_IS_OK(status)) { - DBG_WARNING("mds_init_ctx() path [%s] failed: %s\n", - path, nt_errstr(status)); + DBG_DEBUG("mds_init_ctx() path [%s] failed: %s\n", + path, nt_errstr(status)); return status; } @@ -109,6 +109,11 @@ void _mdssvc_open(struct pipes_struct *p, struct mdssvc_open *r) r->in.share_name, path, r->out.handle); + if (NT_STATUS_EQUAL(status, NT_STATUS_WRONG_VOLUME)) { + ZERO_STRUCTP(r->out.handle); + talloc_free(path); + return; + } if (!NT_STATUS_IS_OK(status)) { DBG_ERR("Couldn't create policy handle for %s\n", r->in.share_name); -- 2.36.1