diff options
author | Stefan Metzmacher <metze@samba.org> | 2018-12-10 22:41:31 +0100 |
---|---|---|
committer | Jeremy Allison <jra@samba.org> | 2019-01-12 03:13:38 +0100 |
commit | c76a5be87bf8985d54e82a32df3abf855a616134 (patch) | |
tree | c938b4e8b7d2a7ada11f668bd79343ed56376f8c /source4 | |
parent | 38e0c06abc71620af7c8cfc44af326d10ff9ff14 (diff) | |
download | samba-c76a5be87bf8985d54e82a32df3abf855a616134.tar.gz |
s4:rpc_server: add dcesrv_iface_state_{store,find}_{assoc,conn}() helpers
They can be used instead of
dcesrv_connection_context->private_data and
dcesrv_assoc_group->proxied_id.
This is the first step to hide internal details of
the core dcerpc server from the interface implementations.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=7113
BUG: https://bugzilla.samba.org/show_bug.cgi?id=11892
Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
Diffstat (limited to 'source4')
-rw-r--r-- | source4/rpc_server/dcerpc_server.h | 38 | ||||
-rw-r--r-- | source4/rpc_server/handles.c | 223 |
2 files changed, 261 insertions, 0 deletions
diff --git a/source4/rpc_server/dcerpc_server.h b/source4/rpc_server/dcerpc_server.h index 557883090af..ad97b0e0cee 100644 --- a/source4/rpc_server/dcerpc_server.h +++ b/source4/rpc_server/dcerpc_server.h @@ -38,6 +38,7 @@ struct dcesrv_connection; struct dcesrv_call_state; struct dcesrv_auth; struct dcesrv_connection_context; +struct dcesrv_iface_state; struct dcesrv_interface { const char *name; @@ -353,6 +354,11 @@ struct dcesrv_assoc_group { /* list of handles in this association group */ struct dcesrv_handle *handles; + /* + * list of iface states per assoc/conn + */ + struct dcesrv_iface_state *iface_states; + /* parent context */ struct dcesrv_context *dce_ctx; @@ -536,4 +542,36 @@ _PUBLIC_ NTSTATUS dcesrv_interface_bind_reject_connect(struct dcesrv_call_state _PUBLIC_ NTSTATUS dcesrv_interface_bind_allow_connect(struct dcesrv_call_state *dce_call, const struct dcesrv_interface *iface); +_PUBLIC_ NTSTATUS _dcesrv_iface_state_store_assoc( + struct dcesrv_call_state *call, + uint64_t magic, + void *ptr, + const char *location); +#define dcesrv_iface_state_store_assoc(call, magic, ptr) \ + _dcesrv_iface_state_store_assoc((call), (magic), (ptr), \ + __location__) +_PUBLIC_ void *_dcesrv_iface_state_find_assoc( + struct dcesrv_call_state *call, + uint64_t magic); +#define dcesrv_iface_state_find_assoc(call, magic, _type) \ + talloc_get_type( \ + _dcesrv_iface_state_find_assoc((call), (magic)), \ + _type) + +_PUBLIC_ NTSTATUS _dcesrv_iface_state_store_conn( + struct dcesrv_call_state *call, + uint64_t magic, + void *_pptr, + const char *location); +#define dcesrv_iface_state_store_conn(call, magic, ptr) \ + _dcesrv_iface_state_store_conn((call), (magic), (ptr), \ + __location__) +_PUBLIC_ void *_dcesrv_iface_state_find_conn( + struct dcesrv_call_state *call, + uint64_t magic); +#define dcesrv_iface_state_find_conn(call, magic, _type) \ + talloc_get_type( \ + _dcesrv_iface_state_find_conn((call), (magic)), \ + _type) + #endif /* SAMBA_DCERPC_SERVER_H */ diff --git a/source4/rpc_server/handles.c b/source4/rpc_server/handles.c index 68bacefaaf5..91bfaf9c62c 100644 --- a/source4/rpc_server/handles.c +++ b/source4/rpc_server/handles.c @@ -137,3 +137,226 @@ struct dcesrv_handle *dcesrv_handle_lookup(struct dcesrv_call_state *call, return NULL; } + +struct dcesrv_iface_state { + struct dcesrv_iface_state *prev, *next; + struct dcesrv_assoc_group *assoc; + const struct dcesrv_interface *iface; + struct dom_sid owner; + const struct dcesrv_connection *conn; + const struct dcesrv_auth *auth; + const struct dcesrv_connection_context *pres; + uint64_t magic; + void *ptr; + const char *location; +}; + +static int dcesrv_iface_state_destructor(struct dcesrv_iface_state *istate) +{ + DLIST_REMOVE(istate->assoc->iface_states, istate); + return 0; +} + +static void *dcesrv_iface_state_find(struct dcesrv_assoc_group *assoc, + const struct dcesrv_interface *iface, + const struct dom_sid *owner, + const struct dcesrv_connection *conn, + const struct dcesrv_auth *auth, + const struct dcesrv_connection_context *pres, + uint64_t magic, + const void *ptr) +{ + struct dcesrv_iface_state *cur = NULL; + + for (cur = assoc->iface_states; cur != NULL; cur = cur->next) { + bool match; + + SMB_ASSERT(cur->assoc == assoc); + + if (cur->ptr == ptr) { + return cur->ptr; + } + + if (cur->iface != iface) { + continue; + } + + match = dom_sid_equal(&cur->owner, owner); + if (!match) { + continue; + } + + if (cur->conn != conn) { + continue; + } + + if (cur->auth != auth) { + continue; + } + + if (cur->pres != pres) { + continue; + } + + if (cur->magic != magic) { + continue; + } + + return cur->ptr; + } + + return NULL; +} + +static NTSTATUS dcesrv_iface_state_store(struct dcesrv_assoc_group *assoc, + const struct dcesrv_interface *iface, + const struct dom_sid *owner, + const struct dcesrv_connection *conn, + const struct dcesrv_auth *auth, + const struct dcesrv_connection_context *pres, + uint64_t magic, + TALLOC_CTX *mem_ctx, + void *ptr, + const char *location) +{ + struct dcesrv_iface_state *istate = NULL; + void *optr = NULL; + + optr = dcesrv_iface_state_find(assoc, + iface, + owner, + conn, + auth, + pres, + magic, + ptr); + if (optr != NULL) { + return NT_STATUS_OBJECTID_EXISTS; + } + + istate = talloc_zero(ptr, struct dcesrv_iface_state); + if (istate == NULL) { + return NT_STATUS_NO_MEMORY; + } + + *istate = (struct dcesrv_iface_state) { + .assoc = assoc, + .iface = iface, + .owner = *owner, + .conn = conn, + .auth = auth, + .pres = pres, + .magic = magic, + .location = location, + }; + + istate->ptr = talloc_steal(mem_ctx, ptr); + + talloc_set_destructor(istate, dcesrv_iface_state_destructor); + + DLIST_ADD_END(assoc->iface_states, istate); + + return NT_STATUS_OK; +} + +NTSTATUS _dcesrv_iface_state_store_assoc(struct dcesrv_call_state *call, + uint64_t magic, + void *ptr, + const char *location) +{ + struct auth_session_info *session_info = + dcesrv_call_session_info(call); + const struct dom_sid *owner = + &session_info->security_token->sids[0]; + NTSTATUS status; + + status = dcesrv_iface_state_store(call->conn->assoc_group, + call->context->iface, + owner, + NULL, /* conn */ + NULL, /* auth */ + NULL, /* pres */ + magic, + call->conn->assoc_group, /* mem_ctx */ + ptr, + location); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + return NT_STATUS_OK; +} + +void *_dcesrv_iface_state_find_assoc(struct dcesrv_call_state *call, uint64_t magic) +{ + struct auth_session_info *session_info = + dcesrv_call_session_info(call); + const struct dom_sid *owner = + &session_info->security_token->sids[0]; + void *ptr = NULL; + + ptr = dcesrv_iface_state_find(call->conn->assoc_group, + call->context->iface, + owner, + NULL, /* conn */ + NULL, /* auth */ + NULL, /* pres */ + magic, + NULL); /* ptr */ + if (ptr == NULL) { + return NULL; + } + + return ptr; +} + +NTSTATUS _dcesrv_iface_state_store_conn(struct dcesrv_call_state *call, + uint64_t magic, + void *ptr, + const char *location) +{ + struct auth_session_info *session_info = + dcesrv_call_session_info(call); + const struct dom_sid *owner = + &session_info->security_token->sids[0]; + NTSTATUS status; + + status = dcesrv_iface_state_store(call->conn->assoc_group, + call->context->iface, + owner, + call->conn, + call->auth_state, + call->context, + magic, + call->conn, /* mem_ctx */ + ptr, + location); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + return NT_STATUS_OK; +} + +void *_dcesrv_iface_state_find_conn(struct dcesrv_call_state *call, uint64_t magic) +{ + struct auth_session_info *session_info = + dcesrv_call_session_info(call); + const struct dom_sid *owner = + &session_info->security_token->sids[0]; + void *ptr = NULL; + + ptr = dcesrv_iface_state_find(call->conn->assoc_group, + call->context->iface, + owner, + call->conn, + call->auth_state, + call->context, + magic, + NULL); /* ptr */ + if (ptr == NULL) { + return NULL; + } + + return ptr; +} |