diff options
author | Stefan Metzmacher <metze@samba.org> | 2022-01-22 01:08:26 +0100 |
---|---|---|
committer | Jule Anger <janger@samba.org> | 2022-01-30 10:57:11 +0000 |
commit | 20f84f11651e93c14818bcfcfe9b2fe259496ae3 (patch) | |
tree | 1b9dcdc9faed00991a421b201ed739ab786acc81 /librpc | |
parent | 3fdc553c9812f1d857abc7ed328e21ec7b56796d (diff) | |
download | samba-20f84f11651e93c14818bcfcfe9b2fe259496ae3.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>
(cherry picked from commit 0651fa474cd68b18d8eb9bdc7c4ba5b847ba9ad9)
Diffstat (limited to 'librpc')
-rw-r--r-- | librpc/rpc/dcesrv_auth.c | 5 | ||||
-rw-r--r-- | librpc/rpc/dcesrv_core.c | 18 | ||||
-rw-r--r-- | librpc/rpc/dcesrv_core.h | 2 |
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)( |