summaryrefslogtreecommitdiff
path: root/librpc
diff options
context:
space:
mode:
authorStefan Metzmacher <metze@samba.org>2022-01-22 01:08:26 +0100
committerStefan Metzmacher <metze@samba.org>2022-01-24 15:25:36 +0000
commit0651fa474cd68b18d8eb9bdc7c4ba5b847ba9ad9 (patch)
tree8a850c300df26c84a5e58c58704b6672268d4ea6 /librpc
parentbe1935dac8a188901ae0f13181b356b508c5be4f (diff)
downloadsamba-0651fa474cd68b18d8eb9bdc7c4ba5b847ba9ad9.tar.gz
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>
Diffstat (limited to 'librpc')
-rw-r--r--librpc/rpc/dcesrv_auth.c5
-rw-r--r--librpc/rpc/dcesrv_core.c18
-rw-r--r--librpc/rpc/dcesrv_core.h2
3 files changed, 25 insertions, 0 deletions
diff --git a/librpc/rpc/dcesrv_auth.c b/librpc/rpc/dcesrv_auth.c
index fec8df513a8..99d8e016216 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 015c7639a51..9fd71812905 100644
--- a/librpc/rpc/dcesrv_core.c
+++ b/librpc/rpc/dcesrv_core.c
@@ -970,6 +970,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;
@@ -1175,9 +1176,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;
}
@@ -1192,10 +1195,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);
@@ -1253,6 +1259,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;
@@ -1297,9 +1304,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;
}
@@ -1315,10 +1324,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);
@@ -1587,6 +1599,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;
@@ -1698,9 +1711,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;
}
@@ -1715,10 +1730,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 e8e87bcce94..69815b71f3d 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)(