From e09f44860285b50b544af0833d05087cb0394c8c Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 18 Apr 2023 11:31:16 +0200 Subject: [PATCH 1/9] libcli: Add security_token_count_flag_sids() To be used in a few places when checking special-case Samba SIDs. Bug: https://bugzilla.samba.org/show_bug.cgi?id=15361 Signed-off-by: Volker Lendecke Reviewed-by: Stefan Metzmacher (cherry picked from commit 5e8c7192ba5469547ba3101885dfbaba2f8181f4) --- libcli/security/security_token.c | 36 ++++++++++++++++++++++++++++++++ libcli/security/security_token.h | 9 ++++++++ 2 files changed, 45 insertions(+) diff --git a/libcli/security/security_token.c b/libcli/security/security_token.c index 03e7bb70743..f788540e98e 100644 --- a/libcli/security/security_token.c +++ b/libcli/security/security_token.c @@ -95,6 +95,42 @@ bool security_token_has_sid(const struct security_token *token, const struct dom return false; } +size_t security_token_count_flag_sids(const struct security_token *token, + const struct dom_sid *prefix_sid, + size_t num_flags, + const struct dom_sid **_flag_sid) +{ + const size_t num_auths_expected = prefix_sid->num_auths + num_flags; + const struct dom_sid *found = NULL; + size_t num = 0; + uint32_t i; + + SMB_ASSERT(num_auths_expected <= ARRAY_SIZE(prefix_sid->sub_auths)); + + for (i = 0; i < token->num_sids; i++) { + const struct dom_sid *sid = &token->sids[i]; + int cmp; + + if ((size_t)sid->num_auths != num_auths_expected) { + continue; + } + + cmp = dom_sid_compare_domain(sid, prefix_sid); + if (cmp != 0) { + continue; + } + + num += 1; + found = sid; + } + + if ((num == 1) && (_flag_sid != NULL)) { + *_flag_sid = found; + } + + return num; +} + bool security_token_has_builtin_guests(const struct security_token *token) { return security_token_has_sid(token, &global_sid_Builtin_Guests); diff --git a/libcli/security/security_token.h b/libcli/security/security_token.h index 15773df617f..c6898859b98 100644 --- a/libcli/security/security_token.h +++ b/libcli/security/security_token.h @@ -47,6 +47,15 @@ bool security_token_is_anonymous(const struct security_token *token); bool security_token_has_sid(const struct security_token *token, const struct dom_sid *sid); +/* + * Return any of the domain sids found in the token matching "domain" + * in _domain_sid, makes most sense if you just found one. + */ +size_t security_token_count_flag_sids(const struct security_token *token, + const struct dom_sid *prefix_sid, + size_t num_flags, + const struct dom_sid **_flag_sid); + bool security_token_has_builtin_guests(const struct security_token *token); bool security_token_has_builtin_administrators(const struct security_token *token); -- 2.34.1 From 994ad625bd0b0fdfbd1f45ee5a1eaf3b1ebff5aa Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 18 Apr 2023 12:01:02 +0200 Subject: [PATCH 2/9] smbd: Use security_token_count_flag_sids() in open_np_file() Simpler logic in the caller Bug: https://bugzilla.samba.org/show_bug.cgi?id=15361 Signed-off-by: Volker Lendecke Reviewed-by: Stefan Metzmacher (cherry picked from commit 244ee8ad75c2c968997dfdd5eeb9e9cb97a191fb) --- source3/smbd/smb2_pipes.c | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/source3/smbd/smb2_pipes.c b/source3/smbd/smb2_pipes.c index b637ddf216a..8f8786752db 100644 --- a/source3/smbd/smb2_pipes.c +++ b/source3/smbd/smb2_pipes.c @@ -78,7 +78,7 @@ NTSTATUS open_np_file(struct smb_request *smb_req, const char *name, uint16_t srv_smb_encrypt = DCERPC_SMB_ENCRYPTION_REQUIRED; uint16_t cipher = xconn->smb2.server.cipher; struct dom_sid smb3_sid = global_sid_Samba_SMB3; - uint32_t i; + size_t num_smb3_sids; bool ok; session_info = copy_session_info(fsp, conn->session_info); @@ -94,17 +94,16 @@ NTSTATUS open_np_file(struct smb_request *smb_req, const char *name, * * Make sure we don't have a SMB3 SID in the security token! */ - for (i = 0; i < security_token->num_sids; i++) { - int cmp; - - cmp = dom_sid_compare_domain(&security_token->sids[i], - &smb3_sid); - if (cmp == 0) { - DBG_ERR("ERROR: An SMB3 SID has already been " - "detected in the security token!\n"); - file_free(smb_req, fsp); - return NT_STATUS_ACCESS_DENIED; - } + num_smb3_sids = security_token_count_flag_sids(security_token, + &smb3_sid, + 3, + NULL); + if (num_smb3_sids != 0) { + DBG_ERR("ERROR: %zu SMB3 SIDs have already been " + "detected in the security token!\n", + num_smb3_sids); + file_free(smb_req, fsp); + return NT_STATUS_ACCESS_DENIED; } ok = sid_append_rid(&smb3_sid, dialect); -- 2.34.1 From 86b2947345c3c9ba52f746bb25a2e0ad901e88d9 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 18 Apr 2023 12:04:17 +0200 Subject: [PATCH 3/9] librpc: Simplify dcerpc_is_transport_encrypted() Simplify logic by using security_token_count_flag_sids() Bug: https://bugzilla.samba.org/show_bug.cgi?id=15361 Signed-off-by: Volker Lendecke Reviewed-by: Stefan Metzmacher (cherry picked from commit 1d11e0489b2c91fc05c6befc0463695d7102abcc) --- librpc/rpc/dcerpc_helper.c | 25 ++++++++++--------------- 1 file changed, 10 insertions(+), 15 deletions(-) diff --git a/librpc/rpc/dcerpc_helper.c b/librpc/rpc/dcerpc_helper.c index cf0deeb2079..eec78e034ee 100644 --- a/librpc/rpc/dcerpc_helper.c +++ b/librpc/rpc/dcerpc_helper.c @@ -20,6 +20,7 @@ #include "librpc/gen_ndr/auth.h" #include "lib/crypto/gnutls_helpers.h" #include "libcli/security/dom_sid.h" +#include "libcli/security/security_token.h" #include "libcli/smb/smb2_constants.h" #include "dcerpc_helper.h" @@ -75,23 +76,17 @@ bool dcerpc_is_transport_encrypted(struct auth_session_info *session_info) uint16_t dialect = 0; uint16_t encrypt = 0; uint16_t cipher = 0; - uint32_t i; + size_t num_smb3_sids; bool ok; - for (i = 0; i < token->num_sids; i++) { - int cmp; - - /* There is only one SMB3 SID allowed! */ - cmp = dom_sid_compare_domain(&token->sids[i], &smb3_dom_sid); - if (cmp == 0) { - if (smb3_sid == NULL) { - smb3_sid = &token->sids[i]; - } else { - DBG_ERR("ERROR: The SMB3 SID has been detected " - "multiple times\n"); - return false; - } - } + num_smb3_sids = security_token_count_flag_sids(token, + &smb3_dom_sid, + 3, + &smb3_sid); + if (num_smb3_sids > 1) { + DBG_ERR("ERROR: The SMB3 SID has been detected %zu times\n", + num_smb3_sids); + return false; } if (smb3_sid == NULL) { -- 2.34.1 From 3693f8bb8b5b793d4af4321729615dec08647ee3 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 18 Apr 2023 12:09:45 +0200 Subject: [PATCH 4/9] rpc: Add global_sid_Samba_NPA_Flags SID This will be used as a flexible way to pass per-RPC-connection flags over ncalrpc to the RPC server without having to modify named_pipe_auth_req_info6 every time something new needs to be passed. It's modeled after global_sid_Samba_SMB3. Bug: https://bugzilla.samba.org/show_bug.cgi?id=15361 Signed-off-by: Volker Lendecke Reviewed-by: Stefan Metzmacher (cherry picked from commit ebbb93cc7a57a118b82b8f383d25f1eb022397d6) --- libcli/security/dom_sid.h | 3 +++ libcli/security/util_sid.c | 7 +++++++ source3/include/proto.h | 2 ++ source3/lib/util_sid.c | 19 +++++++++++++++++++ 4 files changed, 31 insertions(+) diff --git a/libcli/security/dom_sid.h b/libcli/security/dom_sid.h index 568916a159d..65d8adc7195 100644 --- a/libcli/security/dom_sid.h +++ b/libcli/security/dom_sid.h @@ -66,6 +66,9 @@ extern const struct dom_sid global_sid_Unix_NFS_Mode; extern const struct dom_sid global_sid_Unix_NFS_Other; 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 + enum lsa_SidType; NTSTATUS dom_sid_lookup_predefined_name(const char *name, diff --git a/libcli/security/util_sid.c b/libcli/security/util_sid.c index 15dc50339d1..d7adef31cb7 100644 --- a/libcli/security/util_sid.c +++ b/libcli/security/util_sid.c @@ -162,6 +162,13 @@ const struct dom_sid global_sid_Unix_NFS_Other = /* Unix other, MS NFS and Appl const struct dom_sid global_sid_Samba_SMB3 = {1, 1, {0,0,0,0,0,22}, {1397571891, }}; +const struct dom_sid global_sid_Samba_NPA_Flags = {1, + 1, + {0, 0, 0, 0, 0, 22}, + { + 2041152804, + }}; + /* Unused, left here for documentary purposes */ #if 0 #define SECURITY_NULL_SID_AUTHORITY 0 diff --git a/source3/include/proto.h b/source3/include/proto.h index f632cf37c08..cfc56f1374e 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -445,6 +445,8 @@ NTSTATUS sid_array_from_info3(TALLOC_CTX *mem_ctx, struct dom_sid **user_sids, uint32_t *num_user_sids, bool include_user_group_rid); +bool security_token_find_npa_flags(const struct security_token *token, + uint32_t *_flags); /* The following definitions come from lib/util_sock.c */ diff --git a/source3/lib/util_sid.c b/source3/lib/util_sid.c index 75918b440a3..16312d27ee6 100644 --- a/source3/lib/util_sid.c +++ b/source3/lib/util_sid.c @@ -173,3 +173,22 @@ NTSTATUS sid_array_from_info3(TALLOC_CTX *mem_ctx, return NT_STATUS_OK; } + +bool security_token_find_npa_flags(const struct security_token *token, + uint32_t *_flags) +{ + const struct dom_sid *npa_flags_sid = NULL; + size_t num_npa_sids; + + num_npa_sids = + security_token_count_flag_sids(token, + &global_sid_Samba_NPA_Flags, + 1, + &npa_flags_sid); + if (num_npa_sids != 1) { + return false; + } + + sid_peek_rid(npa_flags_sid, _flags); + return true; +} -- 2.34.1 From a9cd930f3c457adfde5af42330c7bdafa08aefe3 Mon Sep 17 00:00:00 2001 From: Joseph Sutton Date: Thu, 22 Dec 2022 17:48:26 +1300 Subject: [PATCH 5/9] named_pipe_auth: Bump info5 to info6 In the next commit, we shall replace the 'authenticated' field of named_pipe_auth_req_info.info5.session_info.session_info.info with a more general 'user_flags' field. Signed-off-by: Joseph Sutton Reviewed-by: Andrew Bartlett (cherry picked from commit 8aef16bbbc1e55f0a9f5a8ec87e5348688d93785) --- libcli/named_pipe_auth/npa_tstream.c | 114 +++++++++++++-------------- libcli/named_pipe_auth/npa_tstream.h | 4 +- librpc/idl/named_pipe_auth.idl | 8 +- source3/librpc/idl/rpc_host.idl | 2 +- source3/rpc_client/local_np.c | 44 +++++------ source3/rpc_server/rpc_host.c | 66 ++++++++-------- source3/rpc_server/rpc_worker.c | 50 ++++++------ 7 files changed, 144 insertions(+), 144 deletions(-) diff --git a/libcli/named_pipe_auth/npa_tstream.c b/libcli/named_pipe_auth/npa_tstream.c index 506c4a35681..6f4ab45887b 100644 --- a/libcli/named_pipe_auth/npa_tstream.c +++ b/libcli/named_pipe_auth/npa_tstream.c @@ -73,7 +73,7 @@ struct tevent_req *tstream_npa_connect_send(TALLOC_CTX *mem_ctx, int ret; enum ndr_err_code ndr_err; char *lower_case_npipe; - struct named_pipe_auth_req_info5 *info5; + struct named_pipe_auth_req_info6 *info6; req = tevent_req_create(mem_ctx, &state, struct tstream_npa_connect_state); @@ -119,39 +119,39 @@ struct tevent_req *tstream_npa_connect_send(TALLOC_CTX *mem_ctx, goto post; } - state->auth_req.level = 5; - info5 = &state->auth_req.info.info5; + state->auth_req.level = 6; + info6 = &state->auth_req.info.info6; - info5->transport = transport; - SMB_ASSERT(info5->transport == transport); /* Assert no overflow */ + info6->transport = transport; + SMB_ASSERT(info6->transport == transport); /* Assert no overflow */ - info5->remote_client_name = remote_client_name_in; - info5->remote_client_addr = tsocket_address_inet_addr_string(remote_client_addr, + info6->remote_client_name = remote_client_name_in; + info6->remote_client_addr = tsocket_address_inet_addr_string(remote_client_addr, state); - if (!info5->remote_client_addr) { + if (!info6->remote_client_addr) { /* errno might be EINVAL */ tevent_req_error(req, errno); goto post; } - info5->remote_client_port = tsocket_address_inet_port(remote_client_addr); - if (!info5->remote_client_name) { - info5->remote_client_name = info5->remote_client_addr; + info6->remote_client_port = tsocket_address_inet_port(remote_client_addr); + if (!info6->remote_client_name) { + info6->remote_client_name = info6->remote_client_addr; } - info5->local_server_name = local_server_name_in; - info5->local_server_addr = tsocket_address_inet_addr_string(local_server_addr, + info6->local_server_name = local_server_name_in; + info6->local_server_addr = tsocket_address_inet_addr_string(local_server_addr, state); - if (!info5->local_server_addr) { + if (!info6->local_server_addr) { /* errno might be EINVAL */ tevent_req_error(req, errno); goto post; } - info5->local_server_port = tsocket_address_inet_port(local_server_addr); - if (!info5->local_server_name) { - info5->local_server_name = info5->local_server_addr; + info6->local_server_port = tsocket_address_inet_port(local_server_addr); + if (!info6->local_server_name) { + info6->local_server_name = info6->local_server_addr; } - info5->session_info = discard_const_p(struct auth_session_info_transport, session_info); + info6->session_info = discard_const_p(struct auth_session_info_transport, session_info); if (DEBUGLVL(10)) { NDR_PRINT_DEBUG(named_pipe_auth_req, &state->auth_req); @@ -348,10 +348,10 @@ int _tstream_npa_connect_recv(struct tevent_req *req, npas->unix_stream = talloc_move(stream, &state->unix_stream); switch (state->auth_rep.level) { - case 5: - npas->file_type = state->auth_rep.info.info5.file_type; - device_state = state->auth_rep.info.info5.device_state; - allocation_size = state->auth_rep.info.info5.allocation_size; + case 6: + npas->file_type = state->auth_rep.info.info6.file_type; + device_state = state->auth_rep.info.info6.device_state; + allocation_size = state->auth_rep.info.info6.allocation_size; break; } @@ -1084,7 +1084,7 @@ static void tstream_npa_accept_existing_reply(struct tevent_req *subreq) tevent_req_data(req, struct tstream_npa_accept_state); struct named_pipe_auth_req *pipe_request; struct named_pipe_auth_rep pipe_reply; - struct named_pipe_auth_req_info5 i5; + struct named_pipe_auth_req_info6 i6; enum ndr_err_code ndr_err; DATA_BLOB in, out; int err; @@ -1147,52 +1147,52 @@ static void tstream_npa_accept_existing_reply(struct tevent_req *subreq) NDR_PRINT_DEBUG(named_pipe_auth_req, pipe_request); } - ZERO_STRUCT(i5); + ZERO_STRUCT(i6); - if (pipe_request->level != 5) { + if (pipe_request->level != 6) { DEBUG(0, ("Unknown level %u\n", pipe_request->level)); pipe_reply.level = 0; pipe_reply.status = NT_STATUS_INVALID_LEVEL; goto reply; } - pipe_reply.level = 5; + pipe_reply.level = 6; pipe_reply.status = NT_STATUS_OK; - pipe_reply.info.info5.file_type = state->file_type; - pipe_reply.info.info5.device_state = state->device_state; - pipe_reply.info.info5.allocation_size = state->alloc_size; + pipe_reply.info.info6.file_type = state->file_type; + pipe_reply.info.info6.device_state = state->device_state; + pipe_reply.info.info6.allocation_size = state->alloc_size; - i5 = pipe_request->info.info5; - if (i5.local_server_addr == NULL) { + i6 = pipe_request->info.info6; + if (i6.local_server_addr == NULL) { pipe_reply.status = NT_STATUS_INVALID_ADDRESS; DEBUG(2, ("Missing local server address\n")); goto reply; } - if (i5.remote_client_addr == NULL) { + if (i6.remote_client_addr == NULL) { pipe_reply.status = NT_STATUS_INVALID_ADDRESS; DEBUG(2, ("Missing remote client address\n")); goto reply; } ret = tsocket_address_inet_from_strings(state, "ip", - i5.local_server_addr, - i5.local_server_port, + i6.local_server_addr, + i6.local_server_port, &state->local_server_addr); if (ret != 0) { DEBUG(2, ("Invalid local server address[%s:%u] - %s\n", - i5.local_server_addr, i5.local_server_port, + i6.local_server_addr, i6.local_server_port, strerror(errno))); pipe_reply.status = NT_STATUS_INVALID_ADDRESS; goto reply; } ret = tsocket_address_inet_from_strings(state, "ip", - i5.remote_client_addr, - i5.remote_client_port, + i6.remote_client_addr, + i6.remote_client_port, &state->remote_client_addr); if (ret != 0) { DEBUG(2, ("Invalid remote client address[%s:%u] - %s\n", - i5.remote_client_addr, i5.remote_client_port, + i6.remote_client_addr, i6.remote_client_port, strerror(errno))); pipe_reply.status = NT_STATUS_INVALID_ADDRESS; goto reply; @@ -1249,14 +1249,14 @@ static void tstream_npa_accept_existing_done(struct tevent_req *subreq) tevent_req_done(req); } -static struct named_pipe_auth_req_info5 *copy_npa_info5( - TALLOC_CTX *mem_ctx, const struct named_pipe_auth_req_info5 *src) +static struct named_pipe_auth_req_info6 *copy_npa_info6( + TALLOC_CTX *mem_ctx, const struct named_pipe_auth_req_info6 *src) { - struct named_pipe_auth_req_info5 *dst = NULL; + struct named_pipe_auth_req_info6 *dst = NULL; DATA_BLOB blob; enum ndr_err_code ndr_err; - dst = talloc_zero(mem_ctx, struct named_pipe_auth_req_info5); + dst = talloc_zero(mem_ctx, struct named_pipe_auth_req_info6); if (dst == NULL) { return NULL; } @@ -1265,9 +1265,9 @@ static struct named_pipe_auth_req_info5 *copy_npa_info5( &blob, dst, src, - (ndr_push_flags_fn_t)ndr_push_named_pipe_auth_req_info5); + (ndr_push_flags_fn_t)ndr_push_named_pipe_auth_req_info6); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - DBG_WARNING("ndr_push_named_pipe_auth_req_info5 failed: %s\n", + DBG_WARNING("ndr_push_named_pipe_auth_req_info6 failed: %s\n", ndr_errstr(ndr_err)); TALLOC_FREE(dst); return NULL; @@ -1277,10 +1277,10 @@ static struct named_pipe_auth_req_info5 *copy_npa_info5( &blob, dst, dst, - (ndr_pull_flags_fn_t)ndr_pull_named_pipe_auth_req_info5); + (ndr_pull_flags_fn_t)ndr_pull_named_pipe_auth_req_info6); TALLOC_FREE(blob.data); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - DBG_WARNING("ndr_push_named_pipe_auth_req_info5 failed: %s\n", + DBG_WARNING("ndr_push_named_pipe_auth_req_info6 failed: %s\n", ndr_errstr(ndr_err)); TALLOC_FREE(dst); return NULL; @@ -1294,7 +1294,7 @@ int _tstream_npa_accept_existing_recv( int *perrno, TALLOC_CTX *mem_ctx, struct tstream_context **stream, - struct named_pipe_auth_req_info5 **info5, + struct named_pipe_auth_req_info6 **info6, enum dcerpc_transport_t *transport, struct tsocket_address **remote_client_addr, char **_remote_client_name, @@ -1305,7 +1305,7 @@ int _tstream_npa_accept_existing_recv( { struct tstream_npa_accept_state *state = tevent_req_data(req, struct tstream_npa_accept_state); - struct named_pipe_auth_req_info5 *i5 = &state->pipe_request->info.info5; + struct named_pipe_auth_req_info6 *i6 = &state->pipe_request->info.info6; struct tstream_npa *npas; int ret; @@ -1346,24 +1346,24 @@ int _tstream_npa_accept_existing_recv( npas->unix_stream = state->plain; npas->file_type = state->file_type; - if (info5 != NULL) { + if (info6 != NULL) { /* - * Make a full copy of "info5" because further down we + * Make a full copy of "info6" because further down we * talloc_move() away substructures from * state->pipe_request. */ - struct named_pipe_auth_req_info5 *dst = copy_npa_info5( - mem_ctx, i5); + struct named_pipe_auth_req_info6 *dst = copy_npa_info6( + mem_ctx, i6); if (dst == NULL) { *perrno = ENOMEM; tevent_req_received(req); return -1; } - *info5 = dst; + *info6 = dst; } if (transport != NULL) { - *transport = i5->transport; + *transport = i6->transport; } if (remote_client_addr != NULL) { *remote_client_addr = talloc_move( @@ -1371,7 +1371,7 @@ int _tstream_npa_accept_existing_recv( } if (_remote_client_name != NULL) { *_remote_client_name = discard_const_p( - char, talloc_move(mem_ctx, &i5->remote_client_name)); + char, talloc_move(mem_ctx, &i6->remote_client_name)); } if (local_server_addr != NULL) { *local_server_addr = talloc_move( @@ -1379,10 +1379,10 @@ int _tstream_npa_accept_existing_recv( } if (local_server_name != NULL) { *local_server_name = discard_const_p( - char, talloc_move(mem_ctx, &i5->local_server_name)); + char, talloc_move(mem_ctx, &i6->local_server_name)); } if (session_info != NULL) { - *session_info = talloc_move(mem_ctx, &i5->session_info); + *session_info = talloc_move(mem_ctx, &i6->session_info); } tevent_req_received(req); diff --git a/libcli/named_pipe_auth/npa_tstream.h b/libcli/named_pipe_auth/npa_tstream.h index 1d7e93dc0fa..4aff10f9afd 100644 --- a/libcli/named_pipe_auth/npa_tstream.h +++ b/libcli/named_pipe_auth/npa_tstream.h @@ -27,7 +27,7 @@ struct tevent_req; struct tevent_context; struct auth_session_info_transport; struct tsocket_address; -struct named_pipe_auth_req_info5; +struct named_pipe_auth_req_info6; struct tevent_req *tstream_npa_connect_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, @@ -114,7 +114,7 @@ int _tstream_npa_accept_existing_recv( int *perrno, TALLOC_CTX *mem_ctx, struct tstream_context **stream, - struct named_pipe_auth_req_info5 **info5, + struct named_pipe_auth_req_info6 **info6, enum dcerpc_transport_t *transport, struct tsocket_address **remote_client_addr, char **_remote_client_name, diff --git a/librpc/idl/named_pipe_auth.idl b/librpc/idl/named_pipe_auth.idl index 6f26cceab17..2204deb63c9 100644 --- a/librpc/idl/named_pipe_auth.idl +++ b/librpc/idl/named_pipe_auth.idl @@ -22,10 +22,10 @@ interface named_pipe_auth uint16 local_server_port; auth_session_info_transport *session_info; boolean8 need_idle_server; - } named_pipe_auth_req_info5; + } named_pipe_auth_req_info6; typedef [switch_type(uint32)] union { - [case(5)] named_pipe_auth_req_info5 info5; + [case(6)] named_pipe_auth_req_info6 info6; } named_pipe_auth_req_info; typedef [public,gensize] struct { @@ -41,10 +41,10 @@ interface named_pipe_auth uint16 file_type; uint16 device_state; hyper allocation_size; - } named_pipe_auth_rep_info5; + } named_pipe_auth_rep_info6; typedef [switch_type(uint32)] union { - [case(5)] named_pipe_auth_rep_info5 info5; + [case(6)] named_pipe_auth_rep_info6 info6; } named_pipe_auth_rep_info; typedef [public,gensize] struct { diff --git a/source3/librpc/idl/rpc_host.idl b/source3/librpc/idl/rpc_host.idl index c8abb6c4379..ddbd2781fe1 100644 --- a/source3/librpc/idl/rpc_host.idl +++ b/source3/librpc/idl/rpc_host.idl @@ -31,7 +31,7 @@ interface rpc_host_msg /** * @brief Auth info inherited from SMB */ - named_pipe_auth_req_info5 *npa_info5; + named_pipe_auth_req_info6 *npa_info6; /** * @brief Raw bind PDU diff --git a/source3/rpc_client/local_np.c b/source3/rpc_client/local_np.c index f1d61a09ee3..92d68fa95c6 100644 --- a/source3/rpc_client/local_np.c +++ b/source3/rpc_client/local_np.c @@ -272,8 +272,8 @@ static void np_sock_connect_read_done(struct tevent_req *subreq) tevent_req_error(req, ndr_map_error2errno(ndr_err)); return; } - if (state->npa_rep->level != 5) { - DBG_DEBUG("npa level = %"PRIu32", expected 5\n", + if (state->npa_rep->level != 6) { + DBG_DEBUG("npa level = %"PRIu32", expected 6\n", state->npa_rep->level); tevent_req_error(req, EIO); return; @@ -282,7 +282,7 @@ static void np_sock_connect_read_done(struct tevent_req *subreq) ret = tstream_npa_existing_stream( state, &state->transport, - state->npa_rep->info.info5.file_type, + state->npa_rep->info.info6.file_type, &state->npa_stream); if (ret == -1) { ret = errno; @@ -496,7 +496,7 @@ struct tevent_req *local_np_connect_send( { struct tevent_req *req = NULL, *subreq = NULL; struct local_np_connect_state *state = NULL; - struct named_pipe_auth_req_info5 *i5 = NULL; + struct named_pipe_auth_req_info6 *i6 = NULL; const char *socket_dir = NULL; char *lower_case_pipename = NULL; @@ -532,14 +532,14 @@ struct tevent_req *local_np_connect_send( if (tevent_req_nomem(state->npa_req, req)) { return tevent_req_post(req, ev); } - state->npa_req->level = 5; + state->npa_req->level = 6; - i5 = &state->npa_req->info.info5; + i6 = &state->npa_req->info.info6; - i5->transport = transport; + i6->transport = transport; /* we don't have "int" in IDL, make sure we don't overflow */ - SMB_ASSERT(i5->transport == transport); + SMB_ASSERT(i6->transport == transport); if (remote_client_name == NULL) { remote_client_name = get_myname(state->npa_req); @@ -548,7 +548,7 @@ struct tevent_req *local_np_connect_send( return tevent_req_post(req, ev); } } - i5->remote_client_name = remote_client_name; + i6->remote_client_name = remote_client_name; if (remote_client_addr == NULL) { struct tsocket_address *addr = NULL; @@ -560,18 +560,18 @@ struct tevent_req *local_np_connect_send( } remote_client_addr = addr; } - i5->remote_client_addr = tsocket_address_inet_addr_string( + i6->remote_client_addr = tsocket_address_inet_addr_string( remote_client_addr, state->npa_req); - if (i5->remote_client_addr == NULL) { + if (i6->remote_client_addr == NULL) { tevent_req_error(req, errno); return tevent_req_post(req, ev); } - i5->remote_client_port = tsocket_address_inet_port(remote_client_addr); + i6->remote_client_port = tsocket_address_inet_port(remote_client_addr); if (local_server_name == NULL) { local_server_name = remote_client_name; } - i5->local_server_name = local_server_name; + i6->local_server_name = local_server_name; if (local_server_addr == NULL) { struct tsocket_address *addr = NULL; @@ -583,27 +583,27 @@ struct tevent_req *local_np_connect_send( } local_server_addr = addr; } - i5->local_server_addr = tsocket_address_inet_addr_string( + i6->local_server_addr = tsocket_address_inet_addr_string( local_server_addr, state->npa_req); - if (i5->local_server_addr == NULL) { + if (i6->local_server_addr == NULL) { tevent_req_error(req, errno); return tevent_req_post(req, ev); } - i5->local_server_port = tsocket_address_inet_port(local_server_addr); + i6->local_server_port = tsocket_address_inet_port(local_server_addr); - i5->session_info = talloc_zero( + i6->session_info = talloc_zero( state->npa_req, struct auth_session_info_transport); - if (tevent_req_nomem(i5->session_info, req)) { + if (tevent_req_nomem(i6->session_info, req)) { return tevent_req_post(req, ev); } - i5->session_info->session_info = copy_session_info( - i5->session_info, session_info); - if (tevent_req_nomem(i5->session_info->session_info, req)) { + i6->session_info->session_info = copy_session_info( + i6->session_info, session_info); + if (tevent_req_nomem(i6->session_info->session_info, req)) { return tevent_req_post(req, ev); } - i5->need_idle_server = need_idle_server; + i6->need_idle_server = need_idle_server; subreq = np_sock_connect_send( state, state->ev, state->socketpath, state->npa_req); diff --git a/source3/rpc_server/rpc_host.c b/source3/rpc_server/rpc_host.c index 5bc927763bc..07ab7742c3e 100644 --- a/source3/rpc_server/rpc_host.c +++ b/source3/rpc_server/rpc_host.c @@ -200,7 +200,7 @@ struct rpc_server { * between RPC servers: netlogon requires samr, everybody * requires winreg. And if a deep call in netlogon asks for a * samr connection, this must never end up in the same - * process. named_pipe_auth_req_info5->need_idle_server is set + * process. named_pipe_auth_req_info6->need_idle_server is set * in those cases. */ struct rpc_work_process *workers; @@ -728,14 +728,14 @@ static int rpc_server_get_endpoints_recv( * anonymous session info. */ -static NTSTATUS rpc_host_generate_npa_info5_from_sock( +static NTSTATUS rpc_host_generate_npa_info6_from_sock( TALLOC_CTX *mem_ctx, enum dcerpc_transport_t transport, int sock, const struct samba_sockaddr *peer_addr, - struct named_pipe_auth_req_info5 **pinfo5) + struct named_pipe_auth_req_info6 **pinfo6) { - struct named_pipe_auth_req_info5 *info5 = NULL; + struct named_pipe_auth_req_info6 *info6 = NULL; struct samba_sockaddr local_addr = { .sa_socklen = sizeof(struct sockaddr_storage), }; @@ -758,18 +758,18 @@ static NTSTATUS rpc_host_generate_npa_info5_from_sock( tsocket_address_to_name_fn = (transport == NCACN_IP_TCP) ? tsocket_address_inet_addr_string : tsocket_address_unix_path; - info5 = talloc_zero(mem_ctx, struct named_pipe_auth_req_info5); - if (info5 == NULL) { + info6 = talloc_zero(mem_ctx, struct named_pipe_auth_req_info6); + if (info6 == NULL) { goto fail; } - info5->session_info = talloc_zero( - info5, struct auth_session_info_transport); - if (info5->session_info == NULL) { + info6->session_info = talloc_zero( + info6, struct auth_session_info_transport); + if (info6->session_info == NULL) { goto fail; } status = make_session_info_anonymous( - info5->session_info, &info5->session_info->session_info); + info6->session_info, &info6->session_info->session_info); if (!NT_STATUS_IS_OK(status)) { DBG_DEBUG("make_session_info_anonymous failed: %s\n", nt_errstr(status)); @@ -777,7 +777,7 @@ static NTSTATUS rpc_host_generate_npa_info5_from_sock( } ret = tsocket_address_bsd_from_samba_sockaddr( - info5, peer_addr, &taddr); + info6, peer_addr, &taddr); if (ret == -1) { status = map_nt_error_from_unix(errno); DBG_DEBUG("tsocket_address_bsd_from_samba_sockaddr failed: " @@ -785,14 +785,14 @@ static NTSTATUS rpc_host_generate_npa_info5_from_sock( strerror(errno)); goto fail; } - remote_client_addr = tsocket_address_to_name_fn(taddr, info5); + remote_client_addr = tsocket_address_to_name_fn(taddr, info6); if (remote_client_addr == NULL) { DBG_DEBUG("tsocket_address_to_name_fn failed\n"); goto nomem; } TALLOC_FREE(taddr); - remote_client_name = talloc_strdup(info5, remote_client_addr); + remote_client_name = talloc_strdup(info6, remote_client_addr); if (remote_client_name == NULL) { DBG_DEBUG("talloc_strdup failed\n"); goto nomem; @@ -800,7 +800,7 @@ static NTSTATUS rpc_host_generate_npa_info5_from_sock( if (transport == NCACN_IP_TCP) { bool ok = samba_sockaddr_get_port( - peer_addr, &info5->remote_client_port); + peer_addr, &info6->remote_client_port); if (!ok) { DBG_DEBUG("samba_sockaddr_get_port failed\n"); status = NT_STATUS_INVALID_PARAMETER; @@ -816,7 +816,7 @@ static NTSTATUS rpc_host_generate_npa_info5_from_sock( } ret = tsocket_address_bsd_from_samba_sockaddr( - info5, &local_addr, &taddr); + info6, &local_addr, &taddr); if (ret == -1) { status = map_nt_error_from_unix(errno); DBG_DEBUG("tsocket_address_bsd_from_samba_sockaddr failed: " @@ -824,14 +824,14 @@ static NTSTATUS rpc_host_generate_npa_info5_from_sock( strerror(errno)); goto fail; } - local_server_addr = tsocket_address_to_name_fn(taddr, info5); + local_server_addr = tsocket_address_to_name_fn(taddr, info6); if (local_server_addr == NULL) { DBG_DEBUG("tsocket_address_to_name_fn failed\n"); goto nomem; } TALLOC_FREE(taddr); - local_server_name = talloc_strdup(info5, local_server_addr); + local_server_name = talloc_strdup(info6, local_server_addr); if (local_server_name == NULL) { DBG_DEBUG("talloc_strdup failed\n"); goto nomem; @@ -839,7 +839,7 @@ static NTSTATUS rpc_host_generate_npa_info5_from_sock( if (transport == NCACN_IP_TCP) { bool ok = samba_sockaddr_get_port( - &local_addr, &info5->local_server_port); + &local_addr, &info6->local_server_port); if (!ok) { DBG_DEBUG("samba_sockaddr_get_port failed\n"); status = NT_STATUS_INVALID_PARAMETER; @@ -868,7 +868,7 @@ static NTSTATUS rpc_host_generate_npa_info5_from_sock( TALLOC_FREE(remote_client_name); ret = tsocket_address_unix_from_path( - info5, AS_SYSTEM_MAGIC_PATH_TOKEN, &taddr); + info6, AS_SYSTEM_MAGIC_PATH_TOKEN, &taddr); if (ret == -1) { DBG_DEBUG("tsocket_address_unix_from_path " "failed\n"); @@ -876,14 +876,14 @@ static NTSTATUS rpc_host_generate_npa_info5_from_sock( } remote_client_addr = tsocket_address_unix_path( - taddr, info5); + taddr, info6); if (remote_client_addr == NULL) { DBG_DEBUG("tsocket_address_unix_path " "failed\n"); goto nomem; } remote_client_name = talloc_strdup( - info5, remote_client_addr); + info6, remote_client_addr); if (remote_client_name == NULL) { DBG_DEBUG("talloc_strdup failed\n"); goto nomem; @@ -891,18 +891,18 @@ static NTSTATUS rpc_host_generate_npa_info5_from_sock( } } - info5->remote_client_addr = remote_client_addr; - info5->remote_client_name = remote_client_name; - info5->local_server_addr = local_server_addr; - info5->local_server_name = local_server_name; + info6->remote_client_addr = remote_client_addr; + info6->remote_client_name = remote_client_name; + info6->local_server_addr = local_server_addr; + info6->local_server_name = local_server_name; - *pinfo5 = info5; + *pinfo6 = info6; return NT_STATUS_OK; nomem: status = NT_STATUS_NO_MEMORY; fail: - TALLOC_FREE(info5); + TALLOC_FREE(info6); return status; } @@ -991,12 +991,12 @@ static struct tevent_req *rpc_host_bind_read_send( return req; } - status = rpc_host_generate_npa_info5_from_sock( + status = rpc_host_generate_npa_info6_from_sock( state->client, transport, state->sock, peer_addr, - &state->client->npa_info5); + &state->client->npa_info6); if (!NT_STATUS_IS_OK(status)) { tevent_req_oom(req); return tevent_req_post(req, ev); @@ -1028,7 +1028,7 @@ static void rpc_host_bind_read_got_npa(struct tevent_req *subreq) subreq, struct tevent_req); struct rpc_host_bind_read_state *state = tevent_req_data( req, struct rpc_host_bind_read_state); - struct named_pipe_auth_req_info5 *info5 = NULL; + struct named_pipe_auth_req_info6 *info6 = NULL; int ret, err; ret = tstream_npa_accept_existing_recv( @@ -1036,7 +1036,7 @@ static void rpc_host_bind_read_got_npa(struct tevent_req *subreq) &err, state, &state->npa_stream, - &info5, + &info6, NULL, /* transport */ NULL, /* remote_client_addr */ NULL, /* remote_client_name */ @@ -1048,7 +1048,7 @@ static void rpc_host_bind_read_got_npa(struct tevent_req *subreq) return; } - state->client->npa_info5 = talloc_move(state->client, &info5); + state->client->npa_info6 = talloc_move(state->client, &info6); subreq = dcerpc_read_ncacn_packet_send( state, state->ev, state->npa_stream); @@ -1322,7 +1322,7 @@ again: } } else { /* fresh assoc group requested */ - if (pending_client->client->npa_info5->need_idle_server != 0) { + if (pending_client->client->npa_info6->need_idle_server != 0) { worker = rpc_host_find_idle_worker(server); } else { worker = rpc_host_find_worker(server); diff --git a/source3/rpc_server/rpc_worker.c b/source3/rpc_server/rpc_worker.c index 9b7474c2c86..470c614163e 100644 --- a/source3/rpc_server/rpc_worker.c +++ b/source3/rpc_server/rpc_worker.c @@ -170,7 +170,7 @@ static void rpc_worker_new_client( int sock) { struct dcesrv_context *dce_ctx = worker->dce_ctx; - struct named_pipe_auth_req_info5 *info5 = client->npa_info5; + struct named_pipe_auth_req_info6 *info6 = client->npa_info6; struct tsocket_address *remote_client_addr = NULL; struct tsocket_address *local_server_addr = NULL; struct dcerpc_binding *b = NULL; @@ -261,85 +261,85 @@ static void rpc_worker_new_client( if (transport == NCALRPC) { ret = tsocket_address_unix_from_path( ncacn_conn, - info5->remote_client_addr, + info6->remote_client_addr, &remote_client_addr); if (ret == -1) { DBG_DEBUG("tsocket_address_unix_from_path" "(%s) failed: %s\n", - info5->remote_client_addr, + info6->remote_client_addr, strerror(errno)); goto fail; } ncacn_conn->remote_client_name = talloc_strdup( - ncacn_conn, info5->remote_client_name); + ncacn_conn, info6->remote_client_name); if (ncacn_conn->remote_client_name == NULL) { DBG_DEBUG("talloc_strdup(%s) failed\n", - info5->remote_client_name); + info6->remote_client_name); goto fail; } ret = tsocket_address_unix_from_path( ncacn_conn, - info5->local_server_addr, + info6->local_server_addr, &local_server_addr); if (ret == -1) { DBG_DEBUG("tsocket_address_unix_from_path" "(%s) failed: %s\n", - info5->local_server_addr, + info6->local_server_addr, strerror(errno)); goto fail; } ncacn_conn->local_server_name = talloc_strdup( - ncacn_conn, info5->local_server_name); + ncacn_conn, info6->local_server_name); if (ncacn_conn->local_server_name == NULL) { DBG_DEBUG("talloc_strdup(%s) failed\n", - info5->local_server_name); + info6->local_server_name); goto fail; } } else { ret = tsocket_address_inet_from_strings( ncacn_conn, "ip", - info5->remote_client_addr, - info5->remote_client_port, + info6->remote_client_addr, + info6->remote_client_port, &remote_client_addr); if (ret == -1) { DBG_DEBUG("tsocket_address_inet_from_strings" "(%s, %"PRIu16") failed: %s\n", - info5->remote_client_addr, - info5->remote_client_port, + info6->remote_client_addr, + info6->remote_client_port, strerror(errno)); goto fail; } ncacn_conn->remote_client_name = talloc_strdup( - ncacn_conn, info5->remote_client_name); + ncacn_conn, info6->remote_client_name); if (ncacn_conn->remote_client_name == NULL) { DBG_DEBUG("talloc_strdup(%s) failed\n", - info5->remote_client_name); + info6->remote_client_name); goto fail; } ret = tsocket_address_inet_from_strings( ncacn_conn, "ip", - info5->local_server_addr, - info5->local_server_port, + info6->local_server_addr, + info6->local_server_port, &local_server_addr); if (ret == -1) { DBG_DEBUG("tsocket_address_inet_from_strings" "(%s, %"PRIu16") failed: %s\n", - info5->local_server_addr, - info5->local_server_port, + info6->local_server_addr, + info6->local_server_port, strerror(errno)); goto fail; } ncacn_conn->local_server_name = talloc_strdup( - ncacn_conn, info5->local_server_name); + ncacn_conn, info6->local_server_name); if (ncacn_conn->local_server_name == NULL) { DBG_DEBUG("talloc_strdup(%s) failed\n", - info5->local_server_name); + info6->local_server_name); goto fail; } } @@ -361,10 +361,10 @@ static void rpc_worker_new_client( * socket that the client connected to, passed in from * samba-dcerpcd via the binding. For NCACN_NP (root * only by unix permissions) we got a - * named_pipe_auth_req_info5 where the transport can + * named_pipe_auth_req_info6 where the transport can * be overridden. */ - transport = info5->transport; + transport = info6->transport; } else { ret = tstream_bsd_existing_socket( ncacn_conn, sock, &tstream); @@ -377,7 +377,7 @@ static void rpc_worker_new_client( sock = -1; if (security_token_is_system( - info5->session_info->session_info->security_token) && + info6->session_info->session_info->security_token) && (transport != NCALRPC)) { DBG_DEBUG("System token only allowed on NCALRPC\n"); goto fail; @@ -390,7 +390,7 @@ static void rpc_worker_new_client( dce_ctx, ncacn_conn, ep, - info5->session_info->session_info, + info6->session_info->session_info, global_event_context(), DCESRV_CALL_STATE_FLAG_MAY_ASYNC, &dcesrv_conn); -- 2.34.1 From cc53930c2c21517cd9a0571377046426794b52ec Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 18 Apr 2023 12:28:28 +0200 Subject: [PATCH 6/9] rpc_server3: Use global_sid_Samba_NPA_Flags to pass "need_idle" More code, but will be more flexible in the future. Bug: https://bugzilla.samba.org/show_bug.cgi?id=15361 Signed-off-by: Volker Lendecke Reviewed-by: Stefan Metzmacher (cherry picked from commit 31180e0e6d9e43d54e7656a56ed3af129f578105) --- source3/rpc_client/local_np.c | 42 ++++++++++++++++++++++++++++++++++- source3/rpc_server/rpc_host.c | 13 ++++++++++- 2 files changed, 53 insertions(+), 2 deletions(-) diff --git a/source3/rpc_client/local_np.c b/source3/rpc_client/local_np.c index 92d68fa95c6..2975ea5dad3 100644 --- a/source3/rpc_client/local_np.c +++ b/source3/rpc_client/local_np.c @@ -24,6 +24,8 @@ #include "libcli/named_pipe_auth/tstream_u32_read.h" #include "lib/util/tevent_unix.h" #include "auth/auth_util.h" +#include "libcli/security/dom_sid.h" +#include "libcli/security/security_token.h" /** * @file local_np.c @@ -499,6 +501,12 @@ struct tevent_req *local_np_connect_send( struct named_pipe_auth_req_info6 *i6 = NULL; const char *socket_dir = NULL; char *lower_case_pipename = NULL; + struct dom_sid npa_sid = global_sid_Samba_NPA_Flags; + uint32_t npa_flags = 0; + struct security_token *token = NULL; + NTSTATUS status; + size_t num_npa_sids; + bool ok; req = tevent_req_create( mem_ctx, &state, struct local_np_connect_state); @@ -507,6 +515,19 @@ struct tevent_req *local_np_connect_send( } state->ev = ev; + num_npa_sids = + security_token_count_flag_sids(session_info->security_token, + &npa_sid, + 1, + NULL); + if (num_npa_sids != 0) { + DBG_ERR("ERROR: %zu NPA Flags SIDs have already been " + "detected in the security token!\n", + num_npa_sids); + tevent_req_error(req, EACCES); + return tevent_req_post(req, ev); + } + socket_dir = lp_parm_const_string( GLOBAL_SECTION_SNUM, "external_rpc_pipe", "socket_dir", lp_ncalrpc_dir()); @@ -603,7 +624,26 @@ struct tevent_req *local_np_connect_send( return tevent_req_post(req, ev); } - i6->need_idle_server = need_idle_server; + if (need_idle_server) { + npa_flags |= SAMBA_NPA_FLAGS_NEED_IDLE; + } + + ok = sid_append_rid(&npa_sid, npa_flags); + if (!ok) { + tevent_req_error(req, EINVAL); + return tevent_req_post(req, ev); + } + + token = i6->session_info->session_info->security_token; + + status = add_sid_to_array_unique(token, + &npa_sid, + &token->sids, + &token->num_sids); + if (!NT_STATUS_IS_OK(status)) { + tevent_req_oom(req); + return tevent_req_post(req, ev); + } subreq = np_sock_connect_send( state, state->ev, state->socketpath, state->npa_req); diff --git a/source3/rpc_server/rpc_host.c b/source3/rpc_server/rpc_host.c index 07ab7742c3e..ed9118dc639 100644 --- a/source3/rpc_server/rpc_host.c +++ b/source3/rpc_server/rpc_host.c @@ -68,6 +68,8 @@ #include "librpc/gen_ndr/ndr_epmapper.h" #include "librpc/gen_ndr/ndr_epmapper_c.h" #include "nsswitch/winbind_client.h" +#include "libcli/security/dom_sid.h" +#include "libcli/security/security_token.h" extern bool override_logfile; @@ -1321,8 +1323,17 @@ again: worker = rpc_host_find_worker(server); } } else { + struct auth_session_info_transport *session_info = + pending_client->client->npa_info6->session_info; + uint32_t flags = 0; + bool found; + + found = security_token_find_npa_flags( + session_info->session_info->security_token, + &flags); + /* fresh assoc group requested */ - if (pending_client->client->npa_info6->need_idle_server != 0) { + if (found & (flags & SAMBA_NPA_FLAGS_NEED_IDLE)) { worker = rpc_host_find_idle_worker(server); } else { worker = rpc_host_find_worker(server); -- 2.34.1 From 26426e221f2949f4ebb71b997c425ed0fe87ab28 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 18 Apr 2023 12:29:34 +0200 Subject: [PATCH 7/9] rpc: Remove named_pipe_auth_req_info6->need_idle_server Involves bumping up the version number Bug: https://bugzilla.samba.org/show_bug.cgi?id=15361 Signed-off-by: Volker Lendecke Reviewed-by: Stefan Metzmacher (cherry picked from commit bdba027a33e35aab7bb322bc3167cdd7babfc059) --- libcli/named_pipe_auth/npa_tstream.c | 144 +++++++++++++++------------ libcli/named_pipe_auth/npa_tstream.h | 4 +- librpc/idl/named_pipe_auth.idl | 9 +- source3/librpc/idl/rpc_host.idl | 2 +- source3/rpc_client/local_np.c | 59 +++++------ source3/rpc_server/rpc_host.c | 104 +++++++++---------- source3/rpc_server/rpc_worker.c | 85 ++++++++-------- 7 files changed, 211 insertions(+), 196 deletions(-) diff --git a/libcli/named_pipe_auth/npa_tstream.c b/libcli/named_pipe_auth/npa_tstream.c index 6f4ab45887b..f84440fe755 100644 --- a/libcli/named_pipe_auth/npa_tstream.c +++ b/libcli/named_pipe_auth/npa_tstream.c @@ -73,7 +73,7 @@ struct tevent_req *tstream_npa_connect_send(TALLOC_CTX *mem_ctx, int ret; enum ndr_err_code ndr_err; char *lower_case_npipe; - struct named_pipe_auth_req_info6 *info6; + struct named_pipe_auth_req_info7 *info7; req = tevent_req_create(mem_ctx, &state, struct tstream_npa_connect_state); @@ -119,39 +119,43 @@ struct tevent_req *tstream_npa_connect_send(TALLOC_CTX *mem_ctx, goto post; } - state->auth_req.level = 6; - info6 = &state->auth_req.info.info6; + state->auth_req.level = 7; + info7 = &state->auth_req.info.info7; - info6->transport = transport; - SMB_ASSERT(info6->transport == transport); /* Assert no overflow */ + info7->transport = transport; + SMB_ASSERT(info7->transport == transport); /* Assert no overflow */ - info6->remote_client_name = remote_client_name_in; - info6->remote_client_addr = tsocket_address_inet_addr_string(remote_client_addr, - state); - if (!info6->remote_client_addr) { + info7->remote_client_name = remote_client_name_in; + info7->remote_client_addr = + tsocket_address_inet_addr_string(remote_client_addr, state); + if (!info7->remote_client_addr) { /* errno might be EINVAL */ tevent_req_error(req, errno); goto post; } - info6->remote_client_port = tsocket_address_inet_port(remote_client_addr); - if (!info6->remote_client_name) { - info6->remote_client_name = info6->remote_client_addr; + info7->remote_client_port = + tsocket_address_inet_port(remote_client_addr); + if (!info7->remote_client_name) { + info7->remote_client_name = info7->remote_client_addr; } - info6->local_server_name = local_server_name_in; - info6->local_server_addr = tsocket_address_inet_addr_string(local_server_addr, - state); - if (!info6->local_server_addr) { + info7->local_server_name = local_server_name_in; + info7->local_server_addr = + tsocket_address_inet_addr_string(local_server_addr, state); + if (!info7->local_server_addr) { /* errno might be EINVAL */ tevent_req_error(req, errno); goto post; } - info6->local_server_port = tsocket_address_inet_port(local_server_addr); - if (!info6->local_server_name) { - info6->local_server_name = info6->local_server_addr; + info7->local_server_port = + tsocket_address_inet_port(local_server_addr); + if (!info7->local_server_name) { + info7->local_server_name = info7->local_server_addr; } - info6->session_info = discard_const_p(struct auth_session_info_transport, session_info); + info7->session_info = + discard_const_p(struct auth_session_info_transport, + session_info); if (DEBUGLVL(10)) { NDR_PRINT_DEBUG(named_pipe_auth_req, &state->auth_req); @@ -348,10 +352,10 @@ int _tstream_npa_connect_recv(struct tevent_req *req, npas->unix_stream = talloc_move(stream, &state->unix_stream); switch (state->auth_rep.level) { - case 6: - npas->file_type = state->auth_rep.info.info6.file_type; - device_state = state->auth_rep.info.info6.device_state; - allocation_size = state->auth_rep.info.info6.allocation_size; + case 7: + npas->file_type = state->auth_rep.info.info7.file_type; + device_state = state->auth_rep.info.info7.device_state; + allocation_size = state->auth_rep.info.info7.allocation_size; break; } @@ -1084,7 +1088,7 @@ static void tstream_npa_accept_existing_reply(struct tevent_req *subreq) tevent_req_data(req, struct tstream_npa_accept_state); struct named_pipe_auth_req *pipe_request; struct named_pipe_auth_rep pipe_reply; - struct named_pipe_auth_req_info6 i6; + struct named_pipe_auth_req_info7 i7; enum ndr_err_code ndr_err; DATA_BLOB in, out; int err; @@ -1147,53 +1151,59 @@ static void tstream_npa_accept_existing_reply(struct tevent_req *subreq) NDR_PRINT_DEBUG(named_pipe_auth_req, pipe_request); } - ZERO_STRUCT(i6); + ZERO_STRUCT(i7); - if (pipe_request->level != 6) { + if (pipe_request->level != 7) { DEBUG(0, ("Unknown level %u\n", pipe_request->level)); pipe_reply.level = 0; pipe_reply.status = NT_STATUS_INVALID_LEVEL; goto reply; } - pipe_reply.level = 6; + pipe_reply.level = 7; pipe_reply.status = NT_STATUS_OK; - pipe_reply.info.info6.file_type = state->file_type; - pipe_reply.info.info6.device_state = state->device_state; - pipe_reply.info.info6.allocation_size = state->alloc_size; + pipe_reply.info.info7.file_type = state->file_type; + pipe_reply.info.info7.device_state = state->device_state; + pipe_reply.info.info7.allocation_size = state->alloc_size; - i6 = pipe_request->info.info6; - if (i6.local_server_addr == NULL) { + i7 = pipe_request->info.info7; + if (i7.local_server_addr == NULL) { pipe_reply.status = NT_STATUS_INVALID_ADDRESS; DEBUG(2, ("Missing local server address\n")); goto reply; } - if (i6.remote_client_addr == NULL) { + if (i7.remote_client_addr == NULL) { pipe_reply.status = NT_STATUS_INVALID_ADDRESS; DEBUG(2, ("Missing remote client address\n")); goto reply; } - ret = tsocket_address_inet_from_strings(state, "ip", - i6.local_server_addr, - i6.local_server_port, + ret = tsocket_address_inet_from_strings(state, + "ip", + i7.local_server_addr, + i7.local_server_port, &state->local_server_addr); if (ret != 0) { - DEBUG(2, ("Invalid local server address[%s:%u] - %s\n", - i6.local_server_addr, i6.local_server_port, - strerror(errno))); + DEBUG(2, + ("Invalid local server address[%s:%u] - %s\n", + i7.local_server_addr, + i7.local_server_port, + strerror(errno))); pipe_reply.status = NT_STATUS_INVALID_ADDRESS; goto reply; } - ret = tsocket_address_inet_from_strings(state, "ip", - i6.remote_client_addr, - i6.remote_client_port, + ret = tsocket_address_inet_from_strings(state, + "ip", + i7.remote_client_addr, + i7.remote_client_port, &state->remote_client_addr); if (ret != 0) { - DEBUG(2, ("Invalid remote client address[%s:%u] - %s\n", - i6.remote_client_addr, i6.remote_client_port, - strerror(errno))); + DEBUG(2, + ("Invalid remote client address[%s:%u] - %s\n", + i7.remote_client_addr, + i7.remote_client_port, + strerror(errno))); pipe_reply.status = NT_STATUS_INVALID_ADDRESS; goto reply; } @@ -1249,14 +1259,15 @@ static void tstream_npa_accept_existing_done(struct tevent_req *subreq) tevent_req_done(req); } -static struct named_pipe_auth_req_info6 *copy_npa_info6( - TALLOC_CTX *mem_ctx, const struct named_pipe_auth_req_info6 *src) +static struct named_pipe_auth_req_info7 * +copy_npa_info7(TALLOC_CTX *mem_ctx, + const struct named_pipe_auth_req_info7 *src) { - struct named_pipe_auth_req_info6 *dst = NULL; + struct named_pipe_auth_req_info7 *dst = NULL; DATA_BLOB blob; enum ndr_err_code ndr_err; - dst = talloc_zero(mem_ctx, struct named_pipe_auth_req_info6); + dst = talloc_zero(mem_ctx, struct named_pipe_auth_req_info7); if (dst == NULL) { return NULL; } @@ -1265,9 +1276,9 @@ static struct named_pipe_auth_req_info6 *copy_npa_info6( &blob, dst, src, - (ndr_push_flags_fn_t)ndr_push_named_pipe_auth_req_info6); + (ndr_push_flags_fn_t)ndr_push_named_pipe_auth_req_info7); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - DBG_WARNING("ndr_push_named_pipe_auth_req_info6 failed: %s\n", + DBG_WARNING("ndr_push_named_pipe_auth_req_info7 failed: %s\n", ndr_errstr(ndr_err)); TALLOC_FREE(dst); return NULL; @@ -1277,10 +1288,10 @@ static struct named_pipe_auth_req_info6 *copy_npa_info6( &blob, dst, dst, - (ndr_pull_flags_fn_t)ndr_pull_named_pipe_auth_req_info6); + (ndr_pull_flags_fn_t)ndr_pull_named_pipe_auth_req_info7); TALLOC_FREE(blob.data); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - DBG_WARNING("ndr_push_named_pipe_auth_req_info6 failed: %s\n", + DBG_WARNING("ndr_push_named_pipe_auth_req_info7 failed: %s\n", ndr_errstr(ndr_err)); TALLOC_FREE(dst); return NULL; @@ -1294,7 +1305,7 @@ int _tstream_npa_accept_existing_recv( int *perrno, TALLOC_CTX *mem_ctx, struct tstream_context **stream, - struct named_pipe_auth_req_info6 **info6, + struct named_pipe_auth_req_info7 **info7, enum dcerpc_transport_t *transport, struct tsocket_address **remote_client_addr, char **_remote_client_name, @@ -1305,7 +1316,8 @@ int _tstream_npa_accept_existing_recv( { struct tstream_npa_accept_state *state = tevent_req_data(req, struct tstream_npa_accept_state); - struct named_pipe_auth_req_info6 *i6 = &state->pipe_request->info.info6; + struct named_pipe_auth_req_info7 *i7 = + &state->pipe_request->info.info7; struct tstream_npa *npas; int ret; @@ -1346,24 +1358,24 @@ int _tstream_npa_accept_existing_recv( npas->unix_stream = state->plain; npas->file_type = state->file_type; - if (info6 != NULL) { + if (info7 != NULL) { /* - * Make a full copy of "info6" because further down we + * Make a full copy of "info7" because further down we * talloc_move() away substructures from * state->pipe_request. */ - struct named_pipe_auth_req_info6 *dst = copy_npa_info6( - mem_ctx, i6); + struct named_pipe_auth_req_info7 *dst = + copy_npa_info7(mem_ctx, i7); if (dst == NULL) { *perrno = ENOMEM; tevent_req_received(req); return -1; } - *info6 = dst; + *info7 = dst; } if (transport != NULL) { - *transport = i6->transport; + *transport = i7->transport; } if (remote_client_addr != NULL) { *remote_client_addr = talloc_move( @@ -1371,7 +1383,8 @@ int _tstream_npa_accept_existing_recv( } if (_remote_client_name != NULL) { *_remote_client_name = discard_const_p( - char, talloc_move(mem_ctx, &i6->remote_client_name)); + char, + talloc_move(mem_ctx, &i7->remote_client_name)); } if (local_server_addr != NULL) { *local_server_addr = talloc_move( @@ -1379,10 +1392,11 @@ int _tstream_npa_accept_existing_recv( } if (local_server_name != NULL) { *local_server_name = discard_const_p( - char, talloc_move(mem_ctx, &i6->local_server_name)); + char, + talloc_move(mem_ctx, &i7->local_server_name)); } if (session_info != NULL) { - *session_info = talloc_move(mem_ctx, &i6->session_info); + *session_info = talloc_move(mem_ctx, &i7->session_info); } tevent_req_received(req); diff --git a/libcli/named_pipe_auth/npa_tstream.h b/libcli/named_pipe_auth/npa_tstream.h index 4aff10f9afd..ebb6d16e428 100644 --- a/libcli/named_pipe_auth/npa_tstream.h +++ b/libcli/named_pipe_auth/npa_tstream.h @@ -27,7 +27,7 @@ struct tevent_req; struct tevent_context; struct auth_session_info_transport; struct tsocket_address; -struct named_pipe_auth_req_info6; +struct named_pipe_auth_req_info7; struct tevent_req *tstream_npa_connect_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, @@ -114,7 +114,7 @@ int _tstream_npa_accept_existing_recv( int *perrno, TALLOC_CTX *mem_ctx, struct tstream_context **stream, - struct named_pipe_auth_req_info6 **info6, + struct named_pipe_auth_req_info7 **info7, enum dcerpc_transport_t *transport, struct tsocket_address **remote_client_addr, char **_remote_client_name, diff --git a/librpc/idl/named_pipe_auth.idl b/librpc/idl/named_pipe_auth.idl index 2204deb63c9..b2c9201d1ce 100644 --- a/librpc/idl/named_pipe_auth.idl +++ b/librpc/idl/named_pipe_auth.idl @@ -21,11 +21,10 @@ interface named_pipe_auth [charset(DOS),string] uint8 *local_server_addr; uint16 local_server_port; auth_session_info_transport *session_info; - boolean8 need_idle_server; - } named_pipe_auth_req_info6; + } named_pipe_auth_req_info7; typedef [switch_type(uint32)] union { - [case(6)] named_pipe_auth_req_info6 info6; + [case(7)] named_pipe_auth_req_info7 info7; } named_pipe_auth_req_info; typedef [public,gensize] struct { @@ -41,10 +40,10 @@ interface named_pipe_auth uint16 file_type; uint16 device_state; hyper allocation_size; - } named_pipe_auth_rep_info6; + } named_pipe_auth_rep_info7; typedef [switch_type(uint32)] union { - [case(6)] named_pipe_auth_rep_info6 info6; + [case(7)] named_pipe_auth_rep_info7 info7; } named_pipe_auth_rep_info; typedef [public,gensize] struct { diff --git a/source3/librpc/idl/rpc_host.idl b/source3/librpc/idl/rpc_host.idl index ddbd2781fe1..b992ca814ac 100644 --- a/source3/librpc/idl/rpc_host.idl +++ b/source3/librpc/idl/rpc_host.idl @@ -31,7 +31,7 @@ interface rpc_host_msg /** * @brief Auth info inherited from SMB */ - named_pipe_auth_req_info6 *npa_info6; + named_pipe_auth_req_info7 *npa_info7; /** * @brief Raw bind PDU diff --git a/source3/rpc_client/local_np.c b/source3/rpc_client/local_np.c index 2975ea5dad3..499d9705e3f 100644 --- a/source3/rpc_client/local_np.c +++ b/source3/rpc_client/local_np.c @@ -274,18 +274,17 @@ static void np_sock_connect_read_done(struct tevent_req *subreq) tevent_req_error(req, ndr_map_error2errno(ndr_err)); return; } - if (state->npa_rep->level != 6) { - DBG_DEBUG("npa level = %"PRIu32", expected 6\n", + if (state->npa_rep->level != 7) { + DBG_DEBUG("npa level = %" PRIu32 ", expected 7\n", state->npa_rep->level); tevent_req_error(req, EIO); return; } - ret = tstream_npa_existing_stream( - state, - &state->transport, - state->npa_rep->info.info6.file_type, - &state->npa_stream); + ret = tstream_npa_existing_stream(state, + &state->transport, + state->npa_rep->info.info7.file_type, + &state->npa_stream); if (ret == -1) { ret = errno; DBG_DEBUG("tstream_npa_existing_stream failed: %s\n", @@ -498,7 +497,7 @@ struct tevent_req *local_np_connect_send( { struct tevent_req *req = NULL, *subreq = NULL; struct local_np_connect_state *state = NULL; - struct named_pipe_auth_req_info6 *i6 = NULL; + struct named_pipe_auth_req_info7 *i7 = NULL; const char *socket_dir = NULL; char *lower_case_pipename = NULL; struct dom_sid npa_sid = global_sid_Samba_NPA_Flags; @@ -553,14 +552,14 @@ struct tevent_req *local_np_connect_send( if (tevent_req_nomem(state->npa_req, req)) { return tevent_req_post(req, ev); } - state->npa_req->level = 6; + state->npa_req->level = 7; - i6 = &state->npa_req->info.info6; + i7 = &state->npa_req->info.info7; - i6->transport = transport; + i7->transport = transport; /* we don't have "int" in IDL, make sure we don't overflow */ - SMB_ASSERT(i6->transport == transport); + SMB_ASSERT(i7->transport == transport); if (remote_client_name == NULL) { remote_client_name = get_myname(state->npa_req); @@ -569,7 +568,7 @@ struct tevent_req *local_np_connect_send( return tevent_req_post(req, ev); } } - i6->remote_client_name = remote_client_name; + i7->remote_client_name = remote_client_name; if (remote_client_addr == NULL) { struct tsocket_address *addr = NULL; @@ -581,18 +580,19 @@ struct tevent_req *local_np_connect_send( } remote_client_addr = addr; } - i6->remote_client_addr = tsocket_address_inet_addr_string( - remote_client_addr, state->npa_req); - if (i6->remote_client_addr == NULL) { + i7->remote_client_addr = + tsocket_address_inet_addr_string(remote_client_addr, + state->npa_req); + if (i7->remote_client_addr == NULL) { tevent_req_error(req, errno); return tevent_req_post(req, ev); } - i6->remote_client_port = tsocket_address_inet_port(remote_client_addr); + i7->remote_client_port = tsocket_address_inet_port(remote_client_addr); if (local_server_name == NULL) { local_server_name = remote_client_name; } - i6->local_server_name = local_server_name; + i7->local_server_name = local_server_name; if (local_server_addr == NULL) { struct tsocket_address *addr = NULL; @@ -604,23 +604,24 @@ struct tevent_req *local_np_connect_send( } local_server_addr = addr; } - i6->local_server_addr = tsocket_address_inet_addr_string( - local_server_addr, state->npa_req); - if (i6->local_server_addr == NULL) { + i7->local_server_addr = + tsocket_address_inet_addr_string(local_server_addr, + state->npa_req); + if (i7->local_server_addr == NULL) { tevent_req_error(req, errno); return tevent_req_post(req, ev); } - i6->local_server_port = tsocket_address_inet_port(local_server_addr); + i7->local_server_port = tsocket_address_inet_port(local_server_addr); - i6->session_info = talloc_zero( - state->npa_req, struct auth_session_info_transport); - if (tevent_req_nomem(i6->session_info, req)) { + i7->session_info = talloc_zero(state->npa_req, + struct auth_session_info_transport); + if (tevent_req_nomem(i7->session_info, req)) { return tevent_req_post(req, ev); } - i6->session_info->session_info = copy_session_info( - i6->session_info, session_info); - if (tevent_req_nomem(i6->session_info->session_info, req)) { + i7->session_info->session_info = + copy_session_info(i7->session_info, session_info); + if (tevent_req_nomem(i7->session_info->session_info, req)) { return tevent_req_post(req, ev); } @@ -634,7 +635,7 @@ struct tevent_req *local_np_connect_send( return tevent_req_post(req, ev); } - token = i6->session_info->session_info->security_token; + token = i7->session_info->session_info->security_token; status = add_sid_to_array_unique(token, &npa_sid, diff --git a/source3/rpc_server/rpc_host.c b/source3/rpc_server/rpc_host.c index ed9118dc639..321d30cef2c 100644 --- a/source3/rpc_server/rpc_host.c +++ b/source3/rpc_server/rpc_host.c @@ -202,7 +202,7 @@ struct rpc_server { * between RPC servers: netlogon requires samr, everybody * requires winreg. And if a deep call in netlogon asks for a * samr connection, this must never end up in the same - * process. named_pipe_auth_req_info6->need_idle_server is set + * process. named_pipe_auth_req_info7->need_idle_server is set * in those cases. */ struct rpc_work_process *workers; @@ -730,14 +730,14 @@ static int rpc_server_get_endpoints_recv( * anonymous session info. */ -static NTSTATUS rpc_host_generate_npa_info6_from_sock( +static NTSTATUS rpc_host_generate_npa_info7_from_sock( TALLOC_CTX *mem_ctx, enum dcerpc_transport_t transport, int sock, const struct samba_sockaddr *peer_addr, - struct named_pipe_auth_req_info6 **pinfo6) + struct named_pipe_auth_req_info7 **pinfo7) { - struct named_pipe_auth_req_info6 *info6 = NULL; + struct named_pipe_auth_req_info7 *info7 = NULL; struct samba_sockaddr local_addr = { .sa_socklen = sizeof(struct sockaddr_storage), }; @@ -760,26 +760,28 @@ static NTSTATUS rpc_host_generate_npa_info6_from_sock( tsocket_address_to_name_fn = (transport == NCACN_IP_TCP) ? tsocket_address_inet_addr_string : tsocket_address_unix_path; - info6 = talloc_zero(mem_ctx, struct named_pipe_auth_req_info6); - if (info6 == NULL) { + info7 = talloc_zero(mem_ctx, struct named_pipe_auth_req_info7); + if (info7 == NULL) { goto fail; } - info6->session_info = talloc_zero( - info6, struct auth_session_info_transport); - if (info6->session_info == NULL) { + info7->session_info = + talloc_zero(info7, struct auth_session_info_transport); + if (info7->session_info == NULL) { goto fail; } status = make_session_info_anonymous( - info6->session_info, &info6->session_info->session_info); + info7->session_info, + &info7->session_info->session_info); if (!NT_STATUS_IS_OK(status)) { DBG_DEBUG("make_session_info_anonymous failed: %s\n", nt_errstr(status)); goto fail; } - ret = tsocket_address_bsd_from_samba_sockaddr( - info6, peer_addr, &taddr); + ret = tsocket_address_bsd_from_samba_sockaddr(info7, + peer_addr, + &taddr); if (ret == -1) { status = map_nt_error_from_unix(errno); DBG_DEBUG("tsocket_address_bsd_from_samba_sockaddr failed: " @@ -787,22 +789,22 @@ static NTSTATUS rpc_host_generate_npa_info6_from_sock( strerror(errno)); goto fail; } - remote_client_addr = tsocket_address_to_name_fn(taddr, info6); + remote_client_addr = tsocket_address_to_name_fn(taddr, info7); if (remote_client_addr == NULL) { DBG_DEBUG("tsocket_address_to_name_fn failed\n"); goto nomem; } TALLOC_FREE(taddr); - remote_client_name = talloc_strdup(info6, remote_client_addr); + remote_client_name = talloc_strdup(info7, remote_client_addr); if (remote_client_name == NULL) { DBG_DEBUG("talloc_strdup failed\n"); goto nomem; } if (transport == NCACN_IP_TCP) { - bool ok = samba_sockaddr_get_port( - peer_addr, &info6->remote_client_port); + bool ok = samba_sockaddr_get_port(peer_addr, + &info7->remote_client_port); if (!ok) { DBG_DEBUG("samba_sockaddr_get_port failed\n"); status = NT_STATUS_INVALID_PARAMETER; @@ -817,8 +819,9 @@ static NTSTATUS rpc_host_generate_npa_info6_from_sock( goto fail; } - ret = tsocket_address_bsd_from_samba_sockaddr( - info6, &local_addr, &taddr); + ret = tsocket_address_bsd_from_samba_sockaddr(info7, + &local_addr, + &taddr); if (ret == -1) { status = map_nt_error_from_unix(errno); DBG_DEBUG("tsocket_address_bsd_from_samba_sockaddr failed: " @@ -826,22 +829,22 @@ static NTSTATUS rpc_host_generate_npa_info6_from_sock( strerror(errno)); goto fail; } - local_server_addr = tsocket_address_to_name_fn(taddr, info6); + local_server_addr = tsocket_address_to_name_fn(taddr, info7); if (local_server_addr == NULL) { DBG_DEBUG("tsocket_address_to_name_fn failed\n"); goto nomem; } TALLOC_FREE(taddr); - local_server_name = talloc_strdup(info6, local_server_addr); + local_server_name = talloc_strdup(info7, local_server_addr); if (local_server_name == NULL) { DBG_DEBUG("talloc_strdup failed\n"); goto nomem; } if (transport == NCACN_IP_TCP) { - bool ok = samba_sockaddr_get_port( - &local_addr, &info6->local_server_port); + bool ok = samba_sockaddr_get_port(&local_addr, + &info7->local_server_port); if (!ok) { DBG_DEBUG("samba_sockaddr_get_port failed\n"); status = NT_STATUS_INVALID_PARAMETER; @@ -870,22 +873,24 @@ static NTSTATUS rpc_host_generate_npa_info6_from_sock( TALLOC_FREE(remote_client_name); ret = tsocket_address_unix_from_path( - info6, AS_SYSTEM_MAGIC_PATH_TOKEN, &taddr); + info7, + AS_SYSTEM_MAGIC_PATH_TOKEN, + &taddr); if (ret == -1) { DBG_DEBUG("tsocket_address_unix_from_path " "failed\n"); goto nomem; } - remote_client_addr = tsocket_address_unix_path( - taddr, info6); + remote_client_addr = + tsocket_address_unix_path(taddr, info7); if (remote_client_addr == NULL) { DBG_DEBUG("tsocket_address_unix_path " "failed\n"); goto nomem; } - remote_client_name = talloc_strdup( - info6, remote_client_addr); + remote_client_name = + talloc_strdup(info7, remote_client_addr); if (remote_client_name == NULL) { DBG_DEBUG("talloc_strdup failed\n"); goto nomem; @@ -893,18 +898,18 @@ static NTSTATUS rpc_host_generate_npa_info6_from_sock( } } - info6->remote_client_addr = remote_client_addr; - info6->remote_client_name = remote_client_name; - info6->local_server_addr = local_server_addr; - info6->local_server_name = local_server_name; + info7->remote_client_addr = remote_client_addr; + info7->remote_client_name = remote_client_name; + info7->local_server_addr = local_server_addr; + info7->local_server_name = local_server_name; - *pinfo6 = info6; + *pinfo7 = info7; return NT_STATUS_OK; nomem: status = NT_STATUS_NO_MEMORY; fail: - TALLOC_FREE(info6); + TALLOC_FREE(info7); return status; } @@ -993,12 +998,12 @@ static struct tevent_req *rpc_host_bind_read_send( return req; } - status = rpc_host_generate_npa_info6_from_sock( + status = rpc_host_generate_npa_info7_from_sock( state->client, transport, state->sock, peer_addr, - &state->client->npa_info6); + &state->client->npa_info7); if (!NT_STATUS_IS_OK(status)) { tevent_req_oom(req); return tevent_req_post(req, ev); @@ -1030,27 +1035,26 @@ static void rpc_host_bind_read_got_npa(struct tevent_req *subreq) subreq, struct tevent_req); struct rpc_host_bind_read_state *state = tevent_req_data( req, struct rpc_host_bind_read_state); - struct named_pipe_auth_req_info6 *info6 = NULL; + struct named_pipe_auth_req_info7 *info7 = NULL; int ret, err; - ret = tstream_npa_accept_existing_recv( - subreq, - &err, - state, - &state->npa_stream, - &info6, - NULL, /* transport */ - NULL, /* remote_client_addr */ - NULL, /* remote_client_name */ - NULL, /* local_server_addr */ - NULL, /* local_server_name */ - NULL); /* session_info */ + ret = tstream_npa_accept_existing_recv(subreq, + &err, + state, + &state->npa_stream, + &info7, + NULL, /* transport */ + NULL, /* remote_client_addr */ + NULL, /* remote_client_name */ + NULL, /* local_server_addr */ + NULL, /* local_server_name */ + NULL); /* session_info */ if (ret == -1) { tevent_req_error(req, err); return; } - state->client->npa_info6 = talloc_move(state->client, &info6); + state->client->npa_info7 = talloc_move(state->client, &info7); subreq = dcerpc_read_ncacn_packet_send( state, state->ev, state->npa_stream); @@ -1324,7 +1328,7 @@ again: } } else { struct auth_session_info_transport *session_info = - pending_client->client->npa_info6->session_info; + pending_client->client->npa_info7->session_info; uint32_t flags = 0; bool found; diff --git a/source3/rpc_server/rpc_worker.c b/source3/rpc_server/rpc_worker.c index 470c614163e..23b67857698 100644 --- a/source3/rpc_server/rpc_worker.c +++ b/source3/rpc_server/rpc_worker.c @@ -170,7 +170,7 @@ static void rpc_worker_new_client( int sock) { struct dcesrv_context *dce_ctx = worker->dce_ctx; - struct named_pipe_auth_req_info6 *info6 = client->npa_info6; + struct named_pipe_auth_req_info7 *info7 = client->npa_info7; struct tsocket_address *remote_client_addr = NULL; struct tsocket_address *local_server_addr = NULL; struct dcerpc_binding *b = NULL; @@ -259,87 +259,85 @@ static void rpc_worker_new_client( }; if (transport == NCALRPC) { - ret = tsocket_address_unix_from_path( - ncacn_conn, - info6->remote_client_addr, - &remote_client_addr); + ret = tsocket_address_unix_from_path(ncacn_conn, + info7->remote_client_addr, + &remote_client_addr); if (ret == -1) { DBG_DEBUG("tsocket_address_unix_from_path" "(%s) failed: %s\n", - info6->remote_client_addr, + info7->remote_client_addr, strerror(errno)); goto fail; } - ncacn_conn->remote_client_name = talloc_strdup( - ncacn_conn, info6->remote_client_name); + ncacn_conn->remote_client_name = + talloc_strdup(ncacn_conn, info7->remote_client_name); if (ncacn_conn->remote_client_name == NULL) { DBG_DEBUG("talloc_strdup(%s) failed\n", - info6->remote_client_name); + info7->remote_client_name); goto fail; } - ret = tsocket_address_unix_from_path( - ncacn_conn, - info6->local_server_addr, - &local_server_addr); + ret = tsocket_address_unix_from_path(ncacn_conn, + info7->local_server_addr, + &local_server_addr); if (ret == -1) { DBG_DEBUG("tsocket_address_unix_from_path" "(%s) failed: %s\n", - info6->local_server_addr, + info7->local_server_addr, strerror(errno)); goto fail; } - ncacn_conn->local_server_name = talloc_strdup( - ncacn_conn, info6->local_server_name); + ncacn_conn->local_server_name = + talloc_strdup(ncacn_conn, info7->local_server_name); if (ncacn_conn->local_server_name == NULL) { DBG_DEBUG("talloc_strdup(%s) failed\n", - info6->local_server_name); + info7->local_server_name); goto fail; } } else { ret = tsocket_address_inet_from_strings( ncacn_conn, "ip", - info6->remote_client_addr, - info6->remote_client_port, + info7->remote_client_addr, + info7->remote_client_port, &remote_client_addr); if (ret == -1) { DBG_DEBUG("tsocket_address_inet_from_strings" - "(%s, %"PRIu16") failed: %s\n", - info6->remote_client_addr, - info6->remote_client_port, + "(%s, %" PRIu16 ") failed: %s\n", + info7->remote_client_addr, + info7->remote_client_port, strerror(errno)); goto fail; } - ncacn_conn->remote_client_name = talloc_strdup( - ncacn_conn, info6->remote_client_name); + ncacn_conn->remote_client_name = + talloc_strdup(ncacn_conn, info7->remote_client_name); if (ncacn_conn->remote_client_name == NULL) { DBG_DEBUG("talloc_strdup(%s) failed\n", - info6->remote_client_name); + info7->remote_client_name); goto fail; } ret = tsocket_address_inet_from_strings( ncacn_conn, "ip", - info6->local_server_addr, - info6->local_server_port, + info7->local_server_addr, + info7->local_server_port, &local_server_addr); if (ret == -1) { DBG_DEBUG("tsocket_address_inet_from_strings" - "(%s, %"PRIu16") failed: %s\n", - info6->local_server_addr, - info6->local_server_port, + "(%s, %" PRIu16 ") failed: %s\n", + info7->local_server_addr, + info7->local_server_port, strerror(errno)); goto fail; } - ncacn_conn->local_server_name = talloc_strdup( - ncacn_conn, info6->local_server_name); + ncacn_conn->local_server_name = + talloc_strdup(ncacn_conn, info7->local_server_name); if (ncacn_conn->local_server_name == NULL) { DBG_DEBUG("talloc_strdup(%s) failed\n", - info6->local_server_name); + info7->local_server_name); goto fail; } } @@ -361,10 +359,10 @@ static void rpc_worker_new_client( * socket that the client connected to, passed in from * samba-dcerpcd via the binding. For NCACN_NP (root * only by unix permissions) we got a - * named_pipe_auth_req_info6 where the transport can + * named_pipe_auth_req_info7 where the transport can * be overridden. */ - transport = info6->transport; + transport = info7->transport; } else { ret = tstream_bsd_existing_socket( ncacn_conn, sock, &tstream); @@ -377,7 +375,7 @@ static void rpc_worker_new_client( sock = -1; if (security_token_is_system( - info6->session_info->session_info->security_token) && + info7->session_info->session_info->security_token) && (transport != NCALRPC)) { DBG_DEBUG("System token only allowed on NCALRPC\n"); goto fail; @@ -386,14 +384,13 @@ static void rpc_worker_new_client( ncacn_conn->p.msg_ctx = global_messaging_context(); ncacn_conn->p.transport = transport; - status = dcesrv_endpoint_connect( - dce_ctx, - ncacn_conn, - ep, - info6->session_info->session_info, - global_event_context(), - DCESRV_CALL_STATE_FLAG_MAY_ASYNC, - &dcesrv_conn); + status = dcesrv_endpoint_connect(dce_ctx, + ncacn_conn, + ep, + info7->session_info->session_info, + global_event_context(), + DCESRV_CALL_STATE_FLAG_MAY_ASYNC, + &dcesrv_conn); if (!NT_STATUS_IS_OK(status)) { DBG_DEBUG("Failed to connect to endpoint: %s\n", nt_errstr(status)); -- 2.34.1 From f5b5a5b39cf41bbb9aa142043aeb94c2690b7aa5 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 18 Apr 2023 14:32:20 +0200 Subject: [PATCH 8/9] lib: Add security_token_del_npa_flags() helper function Bug: https://bugzilla.samba.org/show_bug.cgi?id=15361 Signed-off-by: Volker Lendecke Reviewed-by: Stefan Metzmacher (cherry picked from commit bb3ea36e10079ad9c73c68d7ed8fce51ecb40ebe) --- source3/include/proto.h | 1 + source3/lib/util_sid.c | 15 +++++++++++++++ 2 files changed, 16 insertions(+) diff --git a/source3/include/proto.h b/source3/include/proto.h index cfc56f1374e..032e7aa3320 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -447,6 +447,7 @@ NTSTATUS sid_array_from_info3(TALLOC_CTX *mem_ctx, bool include_user_group_rid); bool security_token_find_npa_flags(const struct security_token *token, uint32_t *_flags); +void security_token_del_npa_flags(struct security_token *token); /* The following definitions come from lib/util_sock.c */ diff --git a/source3/lib/util_sid.c b/source3/lib/util_sid.c index 16312d27ee6..5261341fcde 100644 --- a/source3/lib/util_sid.c +++ b/source3/lib/util_sid.c @@ -192,3 +192,18 @@ bool security_token_find_npa_flags(const struct security_token *token, sid_peek_rid(npa_flags_sid, _flags); return true; } + +void security_token_del_npa_flags(struct security_token *token) +{ + const struct dom_sid *npa_flags_sid = NULL; + size_t num_npa_sids; + + num_npa_sids = + security_token_count_flag_sids(token, + &global_sid_Samba_NPA_Flags, + 1, + &npa_flags_sid); + SMB_ASSERT(num_npa_sids == 1); + + del_sid_from_array(npa_flags_sid, &token->sids, &token->num_sids); +} -- 2.34.1 From 63921e7ad1ad268aa9fc7cae129c6ee6a01eba1e Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 18 Apr 2023 12:47:04 +0200 Subject: [PATCH 9/9] 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 Reviewed-by: Stefan Metzmacher Autobuild-User(master): Volker Lendecke Autobuild-Date(master): Tue May 16 11:54:32 UTC 2023 on atb-devel-224 (cherry picked from commit 59694ad0a4cc489f1baa4c2c94c6322c0f22c1df) --- libcli/security/dom_sid.h | 1 + librpc/rpc/dcesrv_core.c | 17 +++++++++++++++++ librpc/rpc/dcesrv_core.h | 1 + source3/rpc_client/local_np.c | 6 ++++++ source3/rpc_server/rpc_worker.c | 31 +++++++++++++++++++++++++++---- 5 files changed, 52 insertions(+), 4 deletions(-) diff --git a/libcli/security/dom_sid.h b/libcli/security/dom_sid.h index 65d8adc7195..c362fa6fe80 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 enum lsa_SidType; diff --git a/librpc/rpc/dcesrv_core.c b/librpc/rpc/dcesrv_core.c index 9fd71812905..ead37c21988 100644 --- a/librpc/rpc/dcesrv_core.c +++ b/librpc/rpc/dcesrv_core.c @@ -34,6 +34,7 @@ #include "librpc/gen_ndr/ndr_dcerpc.h" #include "lib/util/tevent_ntstatus.h" #include "system/network.h" +#include "nsswitch/winbind_client.h" /** * @file @@ -1838,6 +1839,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) { @@ -1953,8 +1955,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 23b67857698..dc3bde7bde9 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", -- 2.34.1