You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
229 lines
7.9 KiB
229 lines
7.9 KiB
From 10f485b3a27e10906aa6ee40833fca8bf81b5511 Mon Sep 17 00:00:00 2001 |
|
From: Stefan Metzmacher <metze@samba.org> |
|
Date: Sat, 22 Jan 2022 01:08:26 +0100 |
|
Subject: [PATCH] dcesrv_core: wrap gensec_*() calls in [un]become_root() calls |
|
|
|
This is important for the source3/rpc_server code as it might |
|
be called embedded in smbd and may not run as root with access |
|
to our private tdb/ldb files. |
|
|
|
Note this is only really needed for 4.15 and older, as |
|
we no longer run the rpc_server embedded in smbd, |
|
but we better be consistent for now. |
|
|
|
This should be able to fix the problem the printing no longer works |
|
on Windows 7 with 2021-10 monthly rollup patch (KB5006743). |
|
|
|
Windows uses NTLMSSP with privacy at the DCERPC layer on top |
|
of NCACN_NP (smb). |
|
|
|
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14867 |
|
|
|
Signed-off-by: Stefan Metzmacher <metze@samba.org> |
|
Reviewed-by: Andreas Schneider <asn@samba.org> |
|
(cherry picked from commit 0651fa474cd68b18d8eb9bdc7c4ba5b847ba9ad9) |
|
--- |
|
librpc/rpc/dcesrv_auth.c | 5 +++++ |
|
librpc/rpc/dcesrv_core.c | 18 ++++++++++++++++++ |
|
librpc/rpc/dcesrv_core.h | 2 ++ |
|
source3/rpc_server/rpc_config.c | 2 ++ |
|
source4/rpc_server/service_rpc.c | 10 ++++++++++ |
|
5 files changed, 37 insertions(+) |
|
|
|
diff --git a/librpc/rpc/dcesrv_auth.c b/librpc/rpc/dcesrv_auth.c |
|
index fec8df513a83..99d8e0162160 100644 |
|
--- a/librpc/rpc/dcesrv_auth.c |
|
+++ b/librpc/rpc/dcesrv_auth.c |
|
@@ -130,11 +130,13 @@ static bool dcesrv_auth_prepare_gensec(struct dcesrv_call_state *call) |
|
auth->auth_level = call->in_auth_info.auth_level; |
|
auth->auth_context_id = call->in_auth_info.auth_context_id; |
|
|
|
+ cb->auth.become_root(); |
|
status = cb->auth.gensec_prepare( |
|
auth, |
|
call, |
|
&auth->gensec_security, |
|
cb->auth.private_data); |
|
+ cb->auth.unbecome_root(); |
|
if (!NT_STATUS_IS_OK(status)) { |
|
DEBUG(1, ("Failed to call samba_server_gensec_start %s\n", |
|
nt_errstr(status))); |
|
@@ -329,6 +331,7 @@ bool dcesrv_auth_bind(struct dcesrv_call_state *call) |
|
NTSTATUS dcesrv_auth_complete(struct dcesrv_call_state *call, NTSTATUS status) |
|
{ |
|
struct dcesrv_auth *auth = call->auth_state; |
|
+ struct dcesrv_context_callbacks *cb = call->conn->dce_ctx->callbacks; |
|
const char *pdu = "<unknown>"; |
|
|
|
switch (call->pkt.ptype) { |
|
@@ -359,9 +362,11 @@ NTSTATUS dcesrv_auth_complete(struct dcesrv_call_state *call, NTSTATUS status) |
|
return status; |
|
} |
|
|
|
+ cb->auth.become_root(); |
|
status = gensec_session_info(auth->gensec_security, |
|
auth, |
|
&auth->session_info); |
|
+ cb->auth.unbecome_root(); |
|
if (!NT_STATUS_IS_OK(status)) { |
|
DEBUG(1, ("Failed to establish session_info: %s\n", |
|
nt_errstr(status))); |
|
diff --git a/librpc/rpc/dcesrv_core.c b/librpc/rpc/dcesrv_core.c |
|
index d16159b0b6cd..ea91fc689b4a 100644 |
|
--- a/librpc/rpc/dcesrv_core.c |
|
+++ b/librpc/rpc/dcesrv_core.c |
|
@@ -938,6 +938,7 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call) |
|
struct dcerpc_binding *ep_2nd_description = NULL; |
|
const char *endpoint = NULL; |
|
struct dcesrv_auth *auth = call->auth_state; |
|
+ struct dcesrv_context_callbacks *cb = call->conn->dce_ctx->callbacks; |
|
struct dcerpc_ack_ctx *ack_ctx_list = NULL; |
|
struct dcerpc_ack_ctx *ack_features = NULL; |
|
struct tevent_req *subreq = NULL; |
|
@@ -1143,9 +1144,11 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call) |
|
return dcesrv_auth_reply(call); |
|
} |
|
|
|
+ cb->auth.become_root(); |
|
subreq = gensec_update_send(call, call->event_ctx, |
|
auth->gensec_security, |
|
call->in_auth_info.credentials); |
|
+ cb->auth.unbecome_root(); |
|
if (subreq == NULL) { |
|
return NT_STATUS_NO_MEMORY; |
|
} |
|
@@ -1160,10 +1163,13 @@ static void dcesrv_bind_done(struct tevent_req *subreq) |
|
tevent_req_callback_data(subreq, |
|
struct dcesrv_call_state); |
|
struct dcesrv_connection *conn = call->conn; |
|
+ struct dcesrv_context_callbacks *cb = call->conn->dce_ctx->callbacks; |
|
NTSTATUS status; |
|
|
|
+ cb->auth.become_root(); |
|
status = gensec_update_recv(subreq, call, |
|
&call->out_auth_info->credentials); |
|
+ cb->auth.unbecome_root(); |
|
TALLOC_FREE(subreq); |
|
|
|
status = dcesrv_auth_complete(call, status); |
|
@@ -1221,6 +1227,7 @@ static NTSTATUS dcesrv_auth3(struct dcesrv_call_state *call) |
|
{ |
|
struct dcesrv_connection *conn = call->conn; |
|
struct dcesrv_auth *auth = call->auth_state; |
|
+ struct dcesrv_context_callbacks *cb = call->conn->dce_ctx->callbacks; |
|
struct tevent_req *subreq = NULL; |
|
NTSTATUS status; |
|
|
|
@@ -1265,9 +1272,11 @@ static NTSTATUS dcesrv_auth3(struct dcesrv_call_state *call) |
|
return NT_STATUS_OK; |
|
} |
|
|
|
+ cb->auth.become_root(); |
|
subreq = gensec_update_send(call, call->event_ctx, |
|
auth->gensec_security, |
|
call->in_auth_info.credentials); |
|
+ cb->auth.unbecome_root(); |
|
if (subreq == NULL) { |
|
return NT_STATUS_NO_MEMORY; |
|
} |
|
@@ -1283,10 +1292,13 @@ static void dcesrv_auth3_done(struct tevent_req *subreq) |
|
struct dcesrv_call_state); |
|
struct dcesrv_connection *conn = call->conn; |
|
struct dcesrv_auth *auth = call->auth_state; |
|
+ struct dcesrv_context_callbacks *cb = call->conn->dce_ctx->callbacks; |
|
NTSTATUS status; |
|
|
|
+ cb->auth.become_root(); |
|
status = gensec_update_recv(subreq, call, |
|
&call->out_auth_info->credentials); |
|
+ cb->auth.unbecome_root(); |
|
TALLOC_FREE(subreq); |
|
|
|
status = dcesrv_auth_complete(call, status); |
|
@@ -1555,6 +1567,7 @@ static NTSTATUS dcesrv_alter(struct dcesrv_call_state *call) |
|
struct ncacn_packet *pkt = &call->ack_pkt; |
|
uint32_t extra_flags = 0; |
|
struct dcesrv_auth *auth = call->auth_state; |
|
+ struct dcesrv_context_callbacks *cb = call->conn->dce_ctx->callbacks; |
|
struct dcerpc_ack_ctx *ack_ctx_list = NULL; |
|
struct tevent_req *subreq = NULL; |
|
size_t i; |
|
@@ -1666,9 +1679,11 @@ static NTSTATUS dcesrv_alter(struct dcesrv_call_state *call) |
|
return dcesrv_auth_reply(call); |
|
} |
|
|
|
+ cb->auth.become_root(); |
|
subreq = gensec_update_send(call, call->event_ctx, |
|
auth->gensec_security, |
|
call->in_auth_info.credentials); |
|
+ cb->auth.unbecome_root(); |
|
if (subreq == NULL) { |
|
return NT_STATUS_NO_MEMORY; |
|
} |
|
@@ -1683,10 +1698,13 @@ static void dcesrv_alter_done(struct tevent_req *subreq) |
|
tevent_req_callback_data(subreq, |
|
struct dcesrv_call_state); |
|
struct dcesrv_connection *conn = call->conn; |
|
+ struct dcesrv_context_callbacks *cb = call->conn->dce_ctx->callbacks; |
|
NTSTATUS status; |
|
|
|
+ cb->auth.become_root(); |
|
status = gensec_update_recv(subreq, call, |
|
&call->out_auth_info->credentials); |
|
+ cb->auth.unbecome_root(); |
|
TALLOC_FREE(subreq); |
|
|
|
status = dcesrv_auth_complete(call, status); |
|
diff --git a/librpc/rpc/dcesrv_core.h b/librpc/rpc/dcesrv_core.h |
|
index d8d5f9030959..0538442e0ce6 100644 |
|
--- a/librpc/rpc/dcesrv_core.h |
|
+++ b/librpc/rpc/dcesrv_core.h |
|
@@ -392,6 +392,8 @@ struct dcesrv_context_callbacks { |
|
struct gensec_security **out, |
|
void *private_data); |
|
void *private_data; |
|
+ void (*become_root)(void); |
|
+ void (*unbecome_root)(void); |
|
} auth; |
|
struct { |
|
NTSTATUS (*find)( |
|
diff --git a/source3/rpc_server/rpc_config.c b/source3/rpc_server/rpc_config.c |
|
index 2f1a01da1c0b..289c4f398409 100644 |
|
--- a/source3/rpc_server/rpc_config.c |
|
+++ b/source3/rpc_server/rpc_config.c |
|
@@ -31,6 +31,8 @@ |
|
static struct dcesrv_context_callbacks srv_callbacks = { |
|
.log.successful_authz = dcesrv_log_successful_authz, |
|
.auth.gensec_prepare = dcesrv_auth_gensec_prepare, |
|
+ .auth.become_root = become_root, |
|
+ .auth.unbecome_root = unbecome_root, |
|
.assoc_group.find = dcesrv_assoc_group_find, |
|
}; |
|
|
|
diff --git a/source4/rpc_server/service_rpc.c b/source4/rpc_server/service_rpc.c |
|
index d8c6746d7815..ebb50f8a7ef3 100644 |
|
--- a/source4/rpc_server/service_rpc.c |
|
+++ b/source4/rpc_server/service_rpc.c |
|
@@ -40,9 +40,19 @@ |
|
#include "../libcli/named_pipe_auth/npa_tstream.h" |
|
#include "samba/process_model.h" |
|
|
|
+static void skip_become_root(void) |
|
+{ |
|
+} |
|
+ |
|
+static void skip_unbecome_root(void) |
|
+{ |
|
+} |
|
+ |
|
static struct dcesrv_context_callbacks srv_callbacks = { |
|
.log.successful_authz = log_successful_dcesrv_authz_event, |
|
.auth.gensec_prepare = dcesrv_gensec_prepare, |
|
+ .auth.become_root = skip_become_root, |
|
+ .auth.unbecome_root = skip_unbecome_root, |
|
.assoc_group.find = dcesrv_assoc_group_find, |
|
}; |
|
|
|
-- |
|
2.25.1 |
|
|
|
|