From e1c3f8328cdcc04d5460a6d685d7189ca4dd5cf0 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 18 Apr 2023 12:47:04 +0200 Subject: [PATCH] rpc_server3: Pass winbind_env_set() state through to rpcd_* Winbind can ask rpcd_lsad for LookupNames etc. This can recurse back into winbind for getpwnam. We have the "_NO_WINBINDD" environment variable set in winbind itself for this case, but this is lost on the way into rpcd_lsad. Use a flag in global_sid_Samba_NPA_Flags to pass this information to dcerpc_core, where it sets the variable on every call if requested. Bug: https://bugzilla.samba.org/show_bug.cgi?id=15361 Signed-off-by: Volker Lendecke Reviewed-by: Stefan Metzmacher Autobuild-User(master): Volker Lendecke Autobuild-Date(master): Tue May 16 11:54:32 UTC 2023 on atb-devel-224 (cherry picked from commit 59694ad0a4cc489f1baa4c2c94c6322c0f22c1df) Autobuild-User(v4-17-test): Jule Anger Autobuild-Date(v4-17-test): Tue May 23 08:09:23 UTC 2023 on sn-devel-184 --- libcli/security/dom_sid.h | 1 + librpc/rpc/dcesrv_core.c | 17 +++++++++++++++++ librpc/rpc/dcesrv_core.h | 1 + source3/rpc_client/local_np.c | 6 ++++++ source3/rpc_server/rpc_worker.c | 31 +++++++++++++++++++++++++++---- 5 files changed, 52 insertions(+), 4 deletions(-) diff --git a/libcli/security/dom_sid.h b/libcli/security/dom_sid.h index 65d8adc7195..c362fa6fe80 100644 --- a/libcli/security/dom_sid.h +++ b/libcli/security/dom_sid.h @@ -68,6 +68,7 @@ extern const struct dom_sid global_sid_Samba_SMB3; extern const struct dom_sid global_sid_Samba_NPA_Flags; #define SAMBA_NPA_FLAGS_NEED_IDLE 1 +#define SAMBA_NPA_FLAGS_WINBIND_OFF 2 enum lsa_SidType; diff --git a/librpc/rpc/dcesrv_core.c b/librpc/rpc/dcesrv_core.c index 9fd71812905..ead37c21988 100644 --- a/librpc/rpc/dcesrv_core.c +++ b/librpc/rpc/dcesrv_core.c @@ -34,6 +34,7 @@ #include "librpc/gen_ndr/ndr_dcerpc.h" #include "lib/util/tevent_ntstatus.h" #include "system/network.h" +#include "nsswitch/winbind_client.h" /** * @file @@ -1838,6 +1839,7 @@ static NTSTATUS dcesrv_request(struct dcesrv_call_state *call) enum dcerpc_transport_t transport = dcerpc_binding_get_transport(endpoint->ep_description); struct ndr_pull *pull; + bool turn_winbind_on = false; NTSTATUS status; if (auth->auth_invalid) { @@ -1953,8 +1955,23 @@ static NTSTATUS dcesrv_request(struct dcesrv_call_state *call) pull->data_size - pull->offset)); } + if (call->state_flags & DCESRV_CALL_STATE_FLAG_WINBIND_OFF) { + bool winbind_active = !winbind_env_set(); + if (winbind_active) { + DBG_DEBUG("turning winbind off\n"); + (void)winbind_off(); + turn_winbind_on = true; + } + } + /* call the dispatch function */ status = call->context->iface->dispatch(call, call, call->r); + + if (turn_winbind_on) { + DBG_DEBUG("turning winbind on\n"); + (void)winbind_on(); + } + if (!NT_STATUS_IS_OK(status)) { DEBUG(5,("dcerpc fault in call %s:%02x - %s\n", call->context->iface->name, diff --git a/librpc/rpc/dcesrv_core.h b/librpc/rpc/dcesrv_core.h index 69815b71f3d..aefb3f12732 100644 --- a/librpc/rpc/dcesrv_core.h +++ b/librpc/rpc/dcesrv_core.h @@ -125,6 +125,7 @@ struct dcesrv_call_state { #define DCESRV_CALL_STATE_FLAG_MAY_ASYNC (1<<1) #define DCESRV_CALL_STATE_FLAG_MULTIPLEXED (1<<3) #define DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL (1<<4) +#define DCESRV_CALL_STATE_FLAG_WINBIND_OFF (1 << 5) uint32_t state_flags; /* the time the request arrived in the server */ diff --git a/source3/rpc_client/local_np.c b/source3/rpc_client/local_np.c index 499d9705e3f..0b323404f06 100644 --- a/source3/rpc_client/local_np.c +++ b/source3/rpc_client/local_np.c @@ -26,6 +26,7 @@ #include "auth/auth_util.h" #include "libcli/security/dom_sid.h" #include "libcli/security/security_token.h" +#include "nsswitch/winbind_client.h" /** * @file local_np.c @@ -629,6 +630,11 @@ struct tevent_req *local_np_connect_send( npa_flags |= SAMBA_NPA_FLAGS_NEED_IDLE; } + ok = winbind_env_set(); + if (ok) { + npa_flags |= SAMBA_NPA_FLAGS_WINBIND_OFF; + } + ok = sid_append_rid(&npa_sid, npa_flags); if (!ok) { tevent_req_error(req, EINVAL); diff --git a/source3/rpc_server/rpc_worker.c b/source3/rpc_server/rpc_worker.c index 23b67857698..dc3bde7bde9 100644 --- a/source3/rpc_server/rpc_worker.c +++ b/source3/rpc_server/rpc_worker.c @@ -42,6 +42,8 @@ #include "nsswitch/winbind_client.h" #include "source3/include/messages.h" #include "libcli/security/security_token.h" +#include "libcli/security/dom_sid.h" +#include "source3/include/proto.h" /* * This is the generic code that becomes the @@ -181,6 +183,9 @@ static void rpc_worker_new_client( struct dcesrv_connection *dcesrv_conn = NULL; DATA_BLOB buffer = { .data = NULL }; struct ncacn_packet *pkt = NULL; + struct security_token *token = NULL; + uint32_t npa_flags, state_flags; + bool found_npa_flags; NTSTATUS status; int ret; @@ -374,13 +379,31 @@ static void rpc_worker_new_client( } sock = -1; - if (security_token_is_system( - info7->session_info->session_info->security_token) && - (transport != NCALRPC)) { + token = info7->session_info->session_info->security_token; + + if (security_token_is_system(token) && (transport != NCALRPC)) { DBG_DEBUG("System token only allowed on NCALRPC\n"); goto fail; } + state_flags = DCESRV_CALL_STATE_FLAG_MAY_ASYNC; + + found_npa_flags = security_token_find_npa_flags(token, &npa_flags); + if (found_npa_flags) { + if (npa_flags & SAMBA_NPA_FLAGS_WINBIND_OFF) { + state_flags |= + DCESRV_CALL_STATE_FLAG_WINBIND_OFF; + } + + /* + * Delete the flags so that we don't bail in + * local_np_connect_send() on subsequent + * connects. Once we connect to another RPC service, a + * new flags sid will be added if required. + */ + security_token_del_npa_flags(token); + } + ncacn_conn->p.msg_ctx = global_messaging_context(); ncacn_conn->p.transport = transport; @@ -389,7 +412,7 @@ static void rpc_worker_new_client( ep, info7->session_info->session_info, global_event_context(), - DCESRV_CALL_STATE_FLAG_MAY_ASYNC, + state_flags, &dcesrv_conn); if (!NT_STATUS_IS_OK(status)) { DBG_DEBUG("Failed to connect to endpoint: %s\n", -- 2.47.3