summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVolker Lendecke <vl@samba.org>2023-04-18 12:47:04 +0200
committerVolker Lendecke <vl@samba.org>2023-05-16 11:54:32 +0000
commit59694ad0a4cc489f1baa4c2c94c6322c0f22c1df (patch)
tree2abfdc5792e6f264f89ca96585a1a3d5ab2d7b05
parentbb3ea36e10079ad9c73c68d7ed8fce51ecb40ebe (diff)
downloadsamba-59694ad0a4cc489f1baa4c2c94c6322c0f22c1df.tar.gz
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 <vl@samba.org> Reviewed-by: Stefan Metzmacher <metze@samba.org> Autobuild-User(master): Volker Lendecke <vl@samba.org> Autobuild-Date(master): Tue May 16 11:54:32 UTC 2023 on atb-devel-224
-rw-r--r--libcli/security/dom_sid.h1
-rw-r--r--librpc/rpc/dcesrv_core.c17
-rw-r--r--librpc/rpc/dcesrv_core.h1
-rw-r--r--source3/rpc_client/local_np.c6
-rw-r--r--source3/rpc_server/rpc_worker.c31
5 files changed, 52 insertions, 4 deletions
diff --git a/libcli/security/dom_sid.h b/libcli/security/dom_sid.h
index bb81037b904..d99713cb914 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
struct auth_SidAttr;
enum lsa_SidType;
diff --git a/librpc/rpc/dcesrv_core.c b/librpc/rpc/dcesrv_core.c
index d2870046248..d0e68d585e3 100644
--- a/librpc/rpc/dcesrv_core.c
+++ b/librpc/rpc/dcesrv_core.c
@@ -35,6 +35,7 @@
#include "lib/util/tevent_ntstatus.h"
#include "system/network.h"
#include "lib/util/idtree_random.h"
+#include "nsswitch/winbind_client.h"
/**
* @file
@@ -1839,6 +1840,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) {
@@ -1954,8 +1956,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 39dae54a34c..4f47a0ad4f3 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",