From ffb8b50e3c07c833fb7b1a583d21f9dc1166a0a6 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 14 Nov 2016 11:24:03 +1300 Subject: [PATCH] s4-rpc_server: Allow each interface to declare if it uses handles This will allow the NETLOGON server in the AD DC to declare that it does not use handles, and so allow some more flexibility with association groups Signed-off-by: Andrew Bartlett Reviewed-by: Stefan Metzmacher --- pidl/lib/Parse/Pidl/Samba4/NDR/Server.pm | 21 ++++++++++++------- source4/rpc_server/dcerpc_server.h | 4 ++++ source4/rpc_server/dcesrv_mgmt.c | 10 +++++++++ source4/rpc_server/handles.c | 10 +++++++++ source4/rpc_server/netlogon/dcerpc_netlogon.c | 9 ++++++++ source4/rpc_server/remote/dcesrv_remote.c | 1 + 6 files changed, 47 insertions(+), 8 deletions(-) diff --git a/pidl/lib/Parse/Pidl/Samba4/NDR/Server.pm b/pidl/lib/Parse/Pidl/Samba4/NDR/Server.pm index fe5ca0bc5e9..88c7705c3c2 100644 --- a/pidl/lib/Parse/Pidl/Samba4/NDR/Server.pm +++ b/pidl/lib/Parse/Pidl/Samba4/NDR/Server.pm @@ -193,14 +193,19 @@ static NTSTATUS $name\__op_ndr_push(struct dcesrv_call_state *dce_call, TALLOC_C } static const struct dcesrv_interface dcesrv\_$name\_interface = { - .name = \"$name\", - .syntax_id = {".print_uuid($uuid).",$if_version}, - .bind = $name\__op_bind, - .unbind = $name\__op_unbind, - .ndr_pull = $name\__op_ndr_pull, - .dispatch = $name\__op_dispatch, - .reply = $name\__op_reply, - .ndr_push = $name\__op_ndr_push + .name = \"$name\", + .syntax_id = {".print_uuid($uuid).",$if_version}, + .bind = $name\__op_bind, + .unbind = $name\__op_unbind, + .ndr_pull = $name\__op_ndr_pull, + .dispatch = $name\__op_dispatch, + .reply = $name\__op_reply, + .ndr_push = $name\__op_ndr_push, +#ifdef DCESRV_INTERFACE_$uname\_FLAGS + .flags = DCESRV_INTERFACE_$uname\_FLAGS +#else + .flags = 0 +#endif }; "; diff --git a/source4/rpc_server/dcerpc_server.h b/source4/rpc_server/dcerpc_server.h index a1eddbcd5eb..a6772f94f62 100644 --- a/source4/rpc_server/dcerpc_server.h +++ b/source4/rpc_server/dcerpc_server.h @@ -67,8 +67,12 @@ struct dcesrv_interface { /* for any private use by the interface code */ const void *private_data; + + uint64_t flags; }; +#define DCESRV_INTERFACE_FLAGS_HANDLES_NOT_USED 0x00000001 + enum dcesrv_call_list { DCESRV_LIST_NONE, DCESRV_LIST_CALL_LIST, diff --git a/source4/rpc_server/dcesrv_mgmt.c b/source4/rpc_server/dcesrv_mgmt.c index 577f0fbb369..ecb90d8848e 100644 --- a/source4/rpc_server/dcesrv_mgmt.c +++ b/source4/rpc_server/dcesrv_mgmt.c @@ -26,6 +26,16 @@ #define DCESRV_INTERFACE_MGMT_BIND(call, iface) \ dcesrv_interface_mgmt_bind(call, iface) +/* + * This #define allows the mgmt interface to accept invalid + * association groups, because association groups are to coordinate + * handles, and handles are not used in mgmt. This in turn avoids + * the need to coordinate these across multiple possible NETLOGON + * processes, as an mgmt interface is added to each + */ + +#define DCESRV_INTERFACE_MGMT_FLAGS DCESRV_INTERFACE_FLAGS_HANDLES_NOT_USED + static NTSTATUS dcesrv_interface_mgmt_bind(struct dcesrv_call_state *dce_call, const struct dcesrv_interface *iface) { diff --git a/source4/rpc_server/handles.c b/source4/rpc_server/handles.c index 820da49c02d..af49f4caf1c 100644 --- a/source4/rpc_server/handles.c +++ b/source4/rpc_server/handles.c @@ -44,6 +44,11 @@ _PUBLIC_ struct dcesrv_handle *dcesrv_handle_new(struct dcesrv_connection_contex struct dcesrv_handle *h; struct dom_sid *sid; + /* + * For simplicty, ensure we abort here for an interface that has no handles (programmer error) + */ + SMB_ASSERT((context->iface->flags & DCESRV_INTERFACE_FLAGS_HANDLES_NOT_USED) == 0); + sid = &context->conn->auth_state.session_info->security_token->sids[PRIMARY_USER_SID_INDEX]; h = talloc_zero(context->conn->assoc_group, struct dcesrv_handle); @@ -80,6 +85,11 @@ _PUBLIC_ struct dcesrv_handle *dcesrv_handle_fetch( struct dcesrv_handle *h; struct dom_sid *sid; + /* + * For simplicty, ensure we abort here for an interface that has no handles (programmer error) + */ + SMB_ASSERT((context->iface->flags & DCESRV_INTERFACE_FLAGS_HANDLES_NOT_USED) == 0); + sid = &context->conn->auth_state.session_info->security_token->sids[PRIMARY_USER_SID_INDEX]; if (ndr_policy_handle_empty(p)) { diff --git a/source4/rpc_server/netlogon/dcerpc_netlogon.c b/source4/rpc_server/netlogon/dcerpc_netlogon.c index 416acdc0ef3..15f0a77739b 100644 --- a/source4/rpc_server/netlogon/dcerpc_netlogon.c +++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c @@ -46,6 +46,15 @@ #define DCESRV_INTERFACE_NETLOGON_BIND(call, iface) \ dcesrv_interface_netlogon_bind(call, iface) +/* + * This #define allows the netlogon interface to accept invalid + * association groups, because association groups are to coordinate + * handles, and handles are not used in NETLOGON. This in turn avoids + * the need to coordinate these across multiple possible NETLOGON + * processes + */ +#define DCESRV_INTERFACE_NETLOGON_FLAGS DCESRV_INTERFACE_FLAGS_HANDLES_NOT_USED + static NTSTATUS dcesrv_interface_netlogon_bind(struct dcesrv_call_state *dce_call, const struct dcesrv_interface *iface) { diff --git a/source4/rpc_server/remote/dcesrv_remote.c b/source4/rpc_server/remote/dcesrv_remote.c index c6ef75720f5..69ce08cd1f7 100644 --- a/source4/rpc_server/remote/dcesrv_remote.c +++ b/source4/rpc_server/remote/dcesrv_remote.c @@ -374,6 +374,7 @@ static bool remote_fill_interface(struct dcesrv_interface *iface, const struct n iface->ndr_push = remote_op_ndr_push; iface->private_data = if_tabl; + iface->flags = 0; return true; }