summaryrefslogtreecommitdiff
path: root/source4
diff options
context:
space:
mode:
authorStefan Metzmacher <metze@samba.org>2018-12-10 22:41:31 +0100
committerJeremy Allison <jra@samba.org>2019-01-12 03:13:38 +0100
commitc76a5be87bf8985d54e82a32df3abf855a616134 (patch)
treec938b4e8b7d2a7ada11f668bd79343ed56376f8c /source4
parent38e0c06abc71620af7c8cfc44af326d10ff9ff14 (diff)
downloadsamba-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.h38
-rw-r--r--source4/rpc_server/handles.c223
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;
+}