From: Samuel Cabrero Date: Thu, 18 Jun 2020 16:40:16 +0000 (+0200) Subject: s3: rpc_server: Search for already created association groups X-Git-Tag: tevent-0.11.0~1299 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=f5178ef11e675b07ff49c8f1e0b1e193fc0babb2;p=thirdparty%2Fsamba.git s3: rpc_server: Search for already created association groups If the client requests to join to an association group in the bind operation try to find it and do not create a new one. Signed-off-by: Samuel Cabrero Reviewed-by: Andrew Bartlett Reviewed-by: Andreas Schneider --- diff --git a/source3/rpc_server/rpc_server.c b/source3/rpc_server/rpc_server.c index 01350d67283..35cc1de9081 100644 --- a/source3/rpc_server/rpc_server.c +++ b/source3/rpc_server/rpc_server.c @@ -636,18 +636,62 @@ static NTSTATUS dcesrv_assoc_group_new(struct dcesrv_call_state *call, return NT_STATUS_OK; } +static NTSTATUS dcesrv_assoc_group_reference(struct dcesrv_call_state *call, + uint32_t assoc_group_id) +{ + struct dcesrv_connection *conn = call->conn; + const struct dcesrv_endpoint *endpoint = conn->endpoint; + enum dcerpc_transport_t transport = + dcerpc_binding_get_transport(endpoint->ep_description); + struct dcesrv_assoc_group *assoc_group = NULL; + void *id_ptr = NULL; + + /* find an association group given a assoc_group_id */ + id_ptr = idr_find(conn->dce_ctx->assoc_groups_idr, assoc_group_id); + if (id_ptr == NULL) { + /* + * FIXME If the association group is not found it has + * been created in other process (preforking daemons). + * Until this is properly fixed we just create a new + * association group in this process + */ + DBG_NOTICE("Failed to find assoc_group 0x%08x in this " + "server process, creating a new one\n", + assoc_group_id); + return dcesrv_assoc_group_new(call, assoc_group_id); + } + assoc_group = talloc_get_type_abort(id_ptr, struct dcesrv_assoc_group); + + if (assoc_group->transport != transport) { + const char *at = + derpc_transport_string_by_transport( + assoc_group->transport); + const char *ct = + derpc_transport_string_by_transport( + transport); + + DBG_NOTICE("assoc_group 0x%08x (transport %s) " + "is not available on transport %s", + assoc_group_id, at, ct); + return NT_STATUS_UNSUCCESSFUL; + } + + conn->assoc_group = talloc_reference(conn, assoc_group); + return NT_STATUS_OK; +} + NTSTATUS dcesrv_assoc_group_find( struct dcesrv_call_state *call, void *private_data) { uint32_t assoc_group_id = call->pkt.u.bind.assoc_group_id; - /* If not requested by client create a new association group */ - if (assoc_group_id == 0) { - assoc_group_id = 0x53F0; + if (assoc_group_id != 0) { + return dcesrv_assoc_group_reference(call, assoc_group_id); } - return dcesrv_assoc_group_new(call, assoc_group_id); + /* If not requested by client create a new association group */ + return dcesrv_assoc_group_new(call, 0x53F0); } void dcesrv_transport_terminate_connection(struct dcesrv_connection *dce_conn,