From 935de6d968c6fe72de5a9ba5798e23c980dde4b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pavel=20Filipensk=C3=BD?= Date: Wed, 2 Feb 2022 10:59:49 +0100 Subject: [PATCH] Fix printing no longer works on Windows 7 resolves: #2044405 --- samba-printing-win7.patch | 229 ++++++++++++++++++++++++++++++++++++++ samba.spec | 2 + 2 files changed, 231 insertions(+) create mode 100644 samba-printing-win7.patch diff --git a/samba-printing-win7.patch b/samba-printing-win7.patch new file mode 100644 index 0000000..d1a6b6a --- /dev/null +++ b/samba-printing-win7.patch @@ -0,0 +1,229 @@ +From 10f485b3a27e10906aa6ee40833fca8bf81b5511 Mon Sep 17 00:00:00 2001 +From: Stefan Metzmacher +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 +Reviewed-by: Andreas Schneider +(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 = ""; + + 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 + diff --git a/samba.spec b/samba.spec index 3897fd2..5d2ad1d 100644 --- a/samba.spec +++ b/samba.spec @@ -204,6 +204,7 @@ Source201: README.downgrade Patch0: samba-s4u.patch Patch1: samba-ctdb-etcd-reclock.patch Patch2: samba-glibc-dns.patch +Patch3: samba-printing-win7.patch Requires(pre): /usr/sbin/groupadd Requires(post): systemd @@ -4106,6 +4107,7 @@ fi - related: rhbz#2013578 - Rebase Samba to the the latest 4.15.x release - resolves: #2046129 - Fix CVE-2021-44141 - resolves: #2046154 - Fix CVE-2021-44142 +- resolves: #2044405 - Fix printing no longer works on Windows 7 * Mon Jan 24 2022 Pavel Filipenský - 4.15.4-100 - related: rhbz#2013578 - Rebase Samba to the the latest 4.15.x release