CVE-2016-2118: s4:rpc_server: make it possible to define a min_auth_level on a presen...
[samba.git] / source4 / rpc_server / dcerpc_server.h
index 219bb51e023bbd809d54ec39c94ac088271c38cb..26c5c72be3158822791cc34ddd8494796d649b80 100644 (file)
@@ -23,8 +23,7 @@
 #ifndef SAMBA_DCERPC_SERVER_H
 #define SAMBA_DCERPC_SERVER_H
 
-#include "core.h"
-#include "librpc/gen_ndr/misc.h"
+#include "librpc/gen_ndr/server_id.h"
 #include "librpc/rpc/dcerpc.h"
 #include "librpc/ndr/libndr.h"
 
@@ -45,7 +44,7 @@ struct dcesrv_interface {
        struct ndr_syntax_id syntax_id;
 
        /* this function is called when the client binds to this interface  */
-       NTSTATUS (*bind)(struct dcesrv_call_state *, const struct dcesrv_interface *);
+       NTSTATUS (*bind)(struct dcesrv_call_state *, const struct dcesrv_interface *, uint32_t if_version);
 
        /* this function is called when the client disconnects the endpoint */
        void (*unbind)(struct dcesrv_connection_context *, const struct dcesrv_interface *);
@@ -67,7 +66,7 @@ struct dcesrv_interface {
        NTSTATUS (*ndr_push)(struct dcesrv_call_state *, TALLOC_CTX *, struct ndr_push *, const void *);
 
        /* for any private use by the interface code */
-       const void *private;
+       const void *private_data;
 };
 
 enum dcesrv_call_list {
@@ -77,6 +76,11 @@ enum dcesrv_call_list {
        DCESRV_LIST_PENDING_CALL_LIST
 };
 
+struct data_blob_list_item {
+       struct data_blob_list_item *prev,*next;
+       DATA_BLOB blob;
+};
+
 /* the state of an ongoing dcerpc call */
 struct dcesrv_call_state {
        struct dcesrv_call_state *next, *prev;
@@ -102,16 +106,18 @@ struct dcesrv_call_state {
         */
 #define DCESRV_CALL_STATE_FLAG_ASYNC (1<<0)
 #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)
        uint32_t state_flags;
 
        /* the time the request arrived in the server */
        struct timeval time;
 
        /* the backend can use this event context for async replies */
-       struct event_context *event_ctx;
+       struct tevent_context *event_ctx;
 
        /* the message_context that will be used for async replies */
-       struct messaging_context *msg_ctx;
+       struct imessaging_context *msg_ctx;
 
        /* this is the pointer to the allocated function struct */
        void *r;
@@ -136,8 +142,10 @@ struct dcesrv_call_state {
 /* a dcerpc handle in internal format */
 struct dcesrv_handle {
        struct dcesrv_handle *next, *prev;
-       struct dcesrv_connection_context *context;
+       struct dcesrv_assoc_group *assoc_group;
        struct policy_handle wire_handle;
+       struct dom_sid *sid;
+       const struct dcesrv_interface *iface;
        void *data;
 };
 
@@ -147,12 +155,16 @@ struct dcesrv_auth {
        struct gensec_security *gensec_security;
        struct auth_session_info *session_info;
        NTSTATUS (*session_key)(struct dcesrv_connection *, DATA_BLOB *session_key);
+       bool client_hdr_signing;
+       bool hdr_signing;
 };
 
 struct dcesrv_connection_context {
        struct dcesrv_connection_context *next, *prev;
        uint32_t context_id;
 
+       struct dcesrv_assoc_group *assoc_group;
+
        /* the connection this is on */
        struct dcesrv_connection *conn;
 
@@ -160,16 +172,20 @@ struct dcesrv_connection_context {
        const struct dcesrv_interface *iface;
 
        /* private data for the interface implementation */
-       void *private;
+       void *private_data;
 
-       /* current rpc handles - this is really the wrong scope for
-          them, but it will do for now */
-       struct dcesrv_handle *handles;
+       /*
+        * the minimum required auth level for this interface
+        */
+       enum dcerpc_AuthLevel min_auth_level;
 };
 
 
 /* the state associated with a dcerpc server connection */
 struct dcesrv_connection {
+       /* for the broken_connections DLIST */
+       struct dcesrv_connection *prev, *next;
+
        /* the top level context for this server */
        struct dcesrv_context *dce_ctx;
 
@@ -197,10 +213,10 @@ struct dcesrv_connection {
        struct dcesrv_auth auth_state;
 
        /* the event_context that will be used for this connection */
-       struct event_context *event_ctx;
+       struct tevent_context *event_ctx;
 
        /* the message_context that will be used for this connection */
-       struct messaging_context *msg_ctx;
+       struct imessaging_context *msg_ctx;
 
        /* the server_id that will be used for this connection */
        struct server_id server_id;
@@ -208,7 +224,10 @@ struct dcesrv_connection {
        /* the transport level session key */
        DATA_BLOB transport_session_key;
 
-       bool processing;
+       /* is this connection pending termination?  If so, why? */
+       const char *terminate;
+
+       const char *packet_log_dir;
 
        /* this is the default state_flags for dcesrv_call_state structs */
        uint32_t state_flags;
@@ -216,9 +235,13 @@ struct dcesrv_connection {
        struct {
                void *private_data;
                void (*report_output_data)(struct dcesrv_connection *);
-               struct socket_address *(*get_my_addr)(struct dcesrv_connection *, TALLOC_CTX *mem_ctx);
-               struct socket_address *(*get_peer_addr)(struct dcesrv_connection *, TALLOC_CTX *mem_ctx);
        } transport;
+
+       struct tstream_context *stream;
+       struct tevent_queue *send_queue;
+
+       const struct tsocket_address *local_address;
+       const struct tsocket_address *remote_address;
 };
 
 
@@ -245,8 +268,30 @@ struct dcesrv_endpoint_server {
 };
 
 
+/* one association groups */
+struct dcesrv_assoc_group {
+       /* the wire id */
+       uint32_t id;
+       
+       /* list of handles in this association group */
+       struct dcesrv_handle *handles;
+
+       /* parent context */
+       struct dcesrv_context *dce_ctx;
+
+       /* Remote association group ID (if proxied) */
+       uint32_t proxied_id;
+};
+
 /* server-wide context information for the dcerpc server */
 struct dcesrv_context {
+       /*
+        * The euid at startup time.
+        *
+        * This is required for DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM
+        */
+       uid_t initial_euid;
+
        /* the list of endpoints that have registered 
         * by the configured endpoint servers 
         */
@@ -262,6 +307,13 @@ struct dcesrv_context {
                        struct dcesrv_interface iface;
                } *interface_list;
        } *endpoint_list;
+
+       /* loadparm context to use for this connection */
+       struct loadparm_context *lp_ctx;
+
+       struct idr_context *assoc_groups_idr;
+
+       struct dcesrv_connection *broken_connections;
 };
 
 /* this structure is used by modules to determine the size of some critical types */
@@ -280,6 +332,101 @@ struct dcesrv_critical_sizes {
 
 struct model_ops;
 
-#include "rpc_server/dcerpc_server_proto.h"
+NTSTATUS dcesrv_interface_register(struct dcesrv_context *dce_ctx,
+                                  const char *ep_name,
+                                  const struct dcesrv_interface *iface,
+                                  const struct security_descriptor *sd);
+NTSTATUS dcerpc_register_ep_server(const void *_ep_server);
+NTSTATUS dcesrv_init_context(TALLOC_CTX *mem_ctx, 
+                                     struct loadparm_context *lp_ctx,
+                                     const char **endpoint_servers, struct dcesrv_context **_dce_ctx);
+NTSTATUS dcesrv_endpoint_connect(struct dcesrv_context *dce_ctx,
+                                TALLOC_CTX *mem_ctx,
+                                const struct dcesrv_endpoint *ep,
+                                struct auth_session_info *session_info,
+                                struct tevent_context *event_ctx,
+                                struct imessaging_context *msg_ctx,
+                                struct server_id server_id,
+                                uint32_t state_flags,
+                                struct dcesrv_connection **_p);
+
+NTSTATUS dcesrv_reply(struct dcesrv_call_state *call);
+struct dcesrv_handle *dcesrv_handle_new(struct dcesrv_connection_context *context, 
+                                       uint8_t handle_type);
+
+struct dcesrv_handle *dcesrv_handle_fetch(
+                                         struct dcesrv_connection_context *context, 
+                                         struct policy_handle *p,
+                                         uint8_t handle_type);
+struct socket_address *dcesrv_connection_get_my_addr(struct dcesrv_connection *conn, TALLOC_CTX *mem_ctx);
+
+struct socket_address *dcesrv_connection_get_peer_addr(struct dcesrv_connection *conn, TALLOC_CTX *mem_ctx);
+const struct tsocket_address *dcesrv_connection_get_local_address(struct dcesrv_connection *conn);
+const struct tsocket_address *dcesrv_connection_get_remote_address(struct dcesrv_connection *conn);
+
+NTSTATUS dcesrv_fetch_session_key(struct dcesrv_connection *p, DATA_BLOB *session_key);
+
+/* a useful macro for generating a RPC fault in the backend code */
+#define DCESRV_FAULT(code) do { \
+       dce_call->fault_code = code; \
+       return r->out.result; \
+} while(0)
+
+/* a useful macro for generating a RPC fault in the backend code */
+#define DCESRV_FAULT_VOID(code) do { \
+       dce_call->fault_code = code; \
+       return; \
+} while(0)
+
+/* a useful macro for checking the validity of a dcerpc policy handle
+   and giving the right fault code if invalid */
+#define DCESRV_CHECK_HANDLE(h) do {if (!(h)) DCESRV_FAULT(DCERPC_FAULT_CONTEXT_MISMATCH); } while (0)
+
+/* this checks for a valid policy handle, and gives a fault if an
+   invalid handle or retval if the handle is of the
+   wrong type */
+#define DCESRV_PULL_HANDLE_RETVAL(h, inhandle, t, retval) do { \
+       (h) = dcesrv_handle_fetch(dce_call->context, (inhandle), DCESRV_HANDLE_ANY); \
+       DCESRV_CHECK_HANDLE(h); \
+       if ((t) != DCESRV_HANDLE_ANY && (h)->wire_handle.handle_type != (t)) { \
+               return retval; \
+       } \
+} while (0)
+
+/* this checks for a valid policy handle and gives a dcerpc fault 
+   if its the wrong type of handle */
+#define DCESRV_PULL_HANDLE_FAULT(h, inhandle, t) do { \
+       (h) = dcesrv_handle_fetch(dce_call->context, (inhandle), t); \
+       DCESRV_CHECK_HANDLE(h); \
+} while (0)
+
+#define DCESRV_PULL_HANDLE(h, inhandle, t) DCESRV_PULL_HANDLE_RETVAL(h, inhandle, t, NT_STATUS_INVALID_HANDLE)
+#define DCESRV_PULL_HANDLE_WERR(h, inhandle, t) DCESRV_PULL_HANDLE_RETVAL(h, inhandle, t, WERR_BADFID)
+
+NTSTATUS dcesrv_add_ep(struct dcesrv_context *dce_ctx,
+                      struct loadparm_context *lp_ctx,
+                      struct dcesrv_endpoint *e,
+                      struct tevent_context *event_ctx,
+                      const struct model_ops *model_ops);
+
+/**
+ * retrieve credentials from a dce_call
+ */
+_PUBLIC_ struct cli_credentials *dcesrv_call_credentials(struct dcesrv_call_state *dce_call);
+
+/**
+ * returns true if this is an authenticated call
+ */
+_PUBLIC_ bool dcesrv_call_authenticated(struct dcesrv_call_state *dce_call);
+
+/**
+ * retrieve account_name for a dce_call
+ */
+_PUBLIC_ const char *dcesrv_call_account_name(struct dcesrv_call_state *dce_call);
+
+_PUBLIC_ NTSTATUS dcesrv_interface_bind_require_integrity(struct dcesrv_call_state *dce_call,
+                                                         const struct dcesrv_interface *iface);
+_PUBLIC_ NTSTATUS dcesrv_interface_bind_require_privacy(struct dcesrv_call_state *dce_call,
+                                                       const struct dcesrv_interface *iface);
 
 #endif /* SAMBA_DCERPC_SERVER_H */