s4:rpc_server: add dcesrv_call_session_info()
[samba.git] / source4 / rpc_server / dcerpc_server.h
index 66fe51e17fcf2f1a1f237e632e87c693e2f7e33b..84a3474216851b1d882e56c425f3c5826450dd8e 100644 (file)
@@ -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,
@@ -76,6 +80,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;
@@ -83,6 +92,11 @@ struct dcesrv_call_state {
        struct dcesrv_connection_context *context;
        struct ncacn_packet pkt;
 
+       /*
+        * Used during async bind/alter_context.
+        */
+       struct ncacn_packet ack_pkt;
+
        /*
          which list this request is in, if any
         */
@@ -101,7 +115,8 @@ 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_HEADER_SIGNING (1<<2)
+#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 */
@@ -129,8 +144,42 @@ struct dcesrv_call_state {
 
        /* this is used by the boilerplate code to generate DCERPC faults */
        uint32_t fault_code;
+
+       /* the reason why we terminate the connection after sending a response */
+       const char *terminate_reason;
+
+       /* temporary auth_info fields */
+       struct dcerpc_auth in_auth_info;
+       struct dcerpc_auth _out_auth_info;
+       struct dcerpc_auth *out_auth_info;
 };
 
+/*
+* DCERPC Handles
+* --------------
+* The various handles that are used in the RPC servers should be
+* created and fetch using the dcesrv_handle_* functions.
+*
+* Use
+* dcesrv_handle_new(struct dcesrv_connection \*, uint8 handle_type)
+* to obtain a new handle of the specified type. Handle types are
+* unique within each pipe.
+*
+* The handle can later be fetched again using:
+*
+* struct dcesrv_handle *dcesrv_handle_fetch(
+*         struct dcesrv_connection *dce_conn,
+*         struct policy_handle *p,
+*         uint8 handle_type)
+*
+* and destroyed by:
+*
+*      dcesrv_handle_destroy(struct dcesrv_handle *).
+*
+* User data should be stored in the 'data' member of the dcesrv_handle
+* struct.
+*/
+
 #define DCESRV_HANDLE_ANY 255
 
 /* a dcerpc handle in internal format */
@@ -145,17 +194,21 @@ struct dcesrv_handle {
 
 /* hold the authentication state information */
 struct dcesrv_auth {
-       struct dcerpc_auth *auth_info;
+       enum dcerpc_AuthType auth_type;
+       enum dcerpc_AuthLevel auth_level;
+       uint32_t auth_context_id;
        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;
+       bool auth_finished;
+       bool auth_invalid;
 };
 
 struct dcesrv_connection_context {
        struct dcesrv_connection_context *next, *prev;
-       uint32_t context_id;
-
-       struct dcesrv_assoc_group *assoc_group;
+       uint16_t context_id;
 
        /* the connection this is on */
        struct dcesrv_connection *conn;
@@ -165,6 +218,15 @@ struct dcesrv_connection_context {
 
        /* private data for the interface implementation */
        void *private_data;
+
+       /*
+        * the minimum required auth level for this interface
+        */
+       enum dcerpc_AuthLevel min_auth_level;
+       bool allow_connect;
+
+       /* the negotiated transfer syntax */
+       struct ndr_syntax_id transfer_syntax;
 };
 
 
@@ -192,13 +254,11 @@ struct dcesrv_connection {
        struct dcesrv_call_state *call_list;
 
        /* the maximum size the client wants to receive */
-       uint32_t cli_max_recv_frag;
+       uint16_t max_recv_frag;
+       uint16_t max_xmit_frag;
 
        DATA_BLOB partial_input;
 
-       /* the current authentication state */
-       struct dcesrv_auth auth_state;
-
        /* the event_context that will be used for this connection */
        struct tevent_context *event_ctx;
 
@@ -208,9 +268,6 @@ struct dcesrv_connection {
        /* the server_id that will be used for this connection */
        struct server_id server_id;
 
-       /* the transport level session key */
-       DATA_BLOB transport_session_key;
-
        /* is this connection pending termination?  If so, why? */
        const char *terminate;
 
@@ -229,6 +286,41 @@ struct dcesrv_connection {
 
        const struct tsocket_address *local_address;
        const struct tsocket_address *remote_address;
+
+       /* the current authentication state */
+       struct dcesrv_auth auth_state;
+
+       /*
+        * remember which pdu types are allowed
+        */
+       bool allow_bind;
+       bool allow_auth3;
+       bool allow_alter;
+       bool allow_request;
+
+       /* the association group the connection belongs to */
+       struct dcesrv_assoc_group *assoc_group;
+
+       /* The maximum total payload of reassembled request pdus */
+       size_t max_total_request_size;
+
+       /*
+        * Our preferred transfer syntax.
+        */
+       const struct ndr_syntax_id *preferred_transfer;
+
+       /* the negotiated bind time features */
+       uint16_t bind_time_features;
+
+       /*
+        * This is used to block the connection during
+        * pending authentication.
+        */
+       struct tevent_req *(*wait_send)(TALLOC_CTX *mem_ctx,
+                                       struct tevent_context *ev,
+                                       void *private_data);
+       NTSTATUS (*wait_recv)(struct tevent_req *req);
+       void *wait_private;
 };
 
 
@@ -272,6 +364,13 @@ struct dcesrv_assoc_group {
 
 /* 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 
         */
@@ -286,6 +385,12 @@ struct dcesrv_context {
                        struct dcesrv_if_list *next, *prev;
                        struct dcesrv_interface iface;
                } *interface_list;
+
+               /*
+                * Should this service be run in a single process (so far only
+                * NETLOGON is not run in a single process)
+                */
+               bool use_single_process;
        } *endpoint_list;
 
        /* loadparm context to use for this connection */
@@ -316,7 +421,7 @@ 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 dcerpc_register_ep_server(const struct dcesrv_endpoint_server *ep_server);
 NTSTATUS dcesrv_init_context(TALLOC_CTX *mem_ctx, 
                                      struct loadparm_context *lp_ctx,
                                      const char **endpoint_servers, struct dcesrv_context **_dce_ctx);
@@ -338,9 +443,7 @@ 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);
 
@@ -381,13 +484,14 @@ NTSTATUS dcesrv_fetch_session_key(struct dcesrv_connection *p, DATA_BLOB *sessio
 } 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)
+#define DCESRV_PULL_HANDLE_WERR(h, inhandle, t) DCESRV_PULL_HANDLE_RETVAL(h, inhandle, t, WERR_INVALID_HANDLE)
 
 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);
+                      const struct model_ops *model_ops,
+                      void *process_context);
 
 /**
  * retrieve credentials from a dce_call
@@ -404,5 +508,18 @@ _PUBLIC_ bool dcesrv_call_authenticated(struct dcesrv_call_state *dce_call);
  */
 _PUBLIC_ const char *dcesrv_call_account_name(struct dcesrv_call_state *dce_call);
 
+/**
+ * retrieve session_info from a dce_call
+ */
+_PUBLIC_ struct auth_session_info *dcesrv_call_session_info(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);
+_PUBLIC_ NTSTATUS dcesrv_interface_bind_reject_connect(struct dcesrv_call_state *dce_call,
+                                                      const struct dcesrv_interface *iface);
+_PUBLIC_ NTSTATUS dcesrv_interface_bind_allow_connect(struct dcesrv_call_state *dce_call,
+                                                     const struct dcesrv_interface *iface);
 
 #endif /* SAMBA_DCERPC_SERVER_H */