/* 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,
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
*/
/* 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_create(struct dcesrv_call_state \*, 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_lookup(
+* struct dcesrv_call_state *dce_call,
+* struct policy_handle *p,
+* uint8 handle_type)
+*
+* and destroyed by:
+*
+* TALLOC_FREE(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 */
/* 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);
+ NTSTATUS (*session_key_fn)(struct dcesrv_auth *, 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;
/* 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;
};
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;
/* 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;
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;
};
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 */
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);
-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_create(struct dcesrv_call_state *call,
+ 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 dcesrv_handle *dcesrv_handle_lookup(struct dcesrv_call_state *call,
+ const struct policy_handle *p,
+ uint8_t handle_type);
-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);
+/*
+ * Fetch the authentication session key if available.
+ *
+ * This is the key generated by a gensec authentication.
+ */
+NTSTATUS dcesrv_auth_session_key(struct dcesrv_call_state *call,
+ DATA_BLOB *session_key);
+
+/*
+ * Fetch the transport session key if available.
+ * Typically this is the SMB session key
+ * or a fixed key for local transports.
+ *
+ * The key is always truncated to 16 bytes.
+*/
+NTSTATUS dcesrv_transport_session_key(struct dcesrv_call_state *call,
+ DATA_BLOB *session_key);
/* a useful macro for generating a RPC fault in the backend code */
#define DCESRV_FAULT(code) do { \
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); \
+ (h) = dcesrv_handle_lookup(dce_call, (inhandle), DCESRV_HANDLE_ANY); \
DCESRV_CHECK_HANDLE(h); \
if ((t) != DCESRV_HANDLE_ANY && (h)->wire_handle.handle_type != (t)) { \
return retval; \
/* 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); \
+ (h) = dcesrv_handle_lookup(dce_call, (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)
+#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
*/
_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);
+
+/**
+ * retrieve auth type/level from a dce_call
+ */
+_PUBLIC_ void dcesrv_call_auth_info(struct dcesrv_call_state *dce_call,
+ enum dcerpc_AuthType *auth_type,
+ enum dcerpc_AuthLevel *auth_level);
+
+_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 */