/*
take a reference to an existing association group
*/
-static struct dcesrv_assoc_group *dcesrv_assoc_group_reference(TALLOC_CTX *mem_ctx,
- struct dcesrv_context *dce_ctx,
+static struct dcesrv_assoc_group *dcesrv_assoc_group_reference(struct dcesrv_connection *conn,
uint32_t id)
{
+ const struct dcesrv_endpoint *endpoint = conn->endpoint;
+ enum dcerpc_transport_t transport =
+ dcerpc_binding_get_transport(endpoint->ep_description);
struct dcesrv_assoc_group *assoc_group;
- assoc_group = dcesrv_assoc_group_find(dce_ctx, id);
+ assoc_group = dcesrv_assoc_group_find(conn->dce_ctx, id);
if (assoc_group == NULL) {
- DEBUG(2,(__location__ ": Failed to find assoc_group 0x%08x\n", id));
+ DBG_NOTICE("Failed to find assoc_group 0x%08x\n", id);
+ return NULL;
+ }
+ if (assoc_group->transport != transport) {
+ const char *at =
+ derpc_transport_string_by_transport(
+ assoc_group->transport);
+ const char *ct =
+ derpc_transport_string_by_transport(
+ transport);
+
+ DBG_NOTICE("assoc_group 0x%08x (transport %s) "
+ "is not available on transport %s",
+ id, at, ct);
return NULL;
}
- return talloc_reference(mem_ctx, assoc_group);
+
+ return talloc_reference(conn, assoc_group);
}
static int dcesrv_assoc_group_destructor(struct dcesrv_assoc_group *assoc_group)
/*
allocate a new association group
*/
-static struct dcesrv_assoc_group *dcesrv_assoc_group_new(TALLOC_CTX *mem_ctx,
- struct dcesrv_context *dce_ctx)
+static struct dcesrv_assoc_group *dcesrv_assoc_group_new(struct dcesrv_connection *conn)
{
+ struct dcesrv_context *dce_ctx = conn->dce_ctx;
+ const struct dcesrv_endpoint *endpoint = conn->endpoint;
+ enum dcerpc_transport_t transport =
+ dcerpc_binding_get_transport(endpoint->ep_description);
struct dcesrv_assoc_group *assoc_group;
int id;
- assoc_group = talloc_zero(mem_ctx, struct dcesrv_assoc_group);
+ assoc_group = talloc_zero(conn, struct dcesrv_assoc_group);
if (assoc_group == NULL) {
return NULL;
}
return NULL;
}
+ assoc_group->transport = transport;
assoc_group->id = id;
assoc_group->dce_ctx = dce_ctx;
*/
_PUBLIC_ NTSTATUS dcesrv_interface_register(struct dcesrv_context *dce_ctx,
const char *ep_name,
+ const char *ncacn_np_secondary_endpoint,
const struct dcesrv_interface *iface,
const struct security_descriptor *sd)
{
struct dcesrv_endpoint *ep;
struct dcesrv_if_list *ifl;
struct dcerpc_binding *binding;
+ struct dcerpc_binding *binding2 = NULL;
bool add_ep = false;
NTSTATUS status;
enum dcerpc_transport_t transport;
}
}
+ if (transport == NCACN_NP && ncacn_np_secondary_endpoint != NULL) {
+ enum dcerpc_transport_t transport2;
+
+ status = dcerpc_parse_binding(dce_ctx,
+ ncacn_np_secondary_endpoint,
+ &binding2);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0, ("Trouble parsing 2nd binding string '%s'\n",
+ ncacn_np_secondary_endpoint));
+ return status;
+ }
+
+ transport2 = dcerpc_binding_get_transport(binding2);
+ SMB_ASSERT(transport2 == transport);
+ }
+
/* see if the interface is already registered on the endpoint */
if (find_interface_by_binding(dce_ctx, binding, iface)!=NULL) {
DEBUG(0,("dcesrv_interface_register: interface '%s' already registered on endpoint '%s'\n",
}
ZERO_STRUCTP(ep);
ep->ep_description = talloc_move(ep, &binding);
+ ep->ep_2nd_description = talloc_move(ep, &binding2);
add_ep = true;
/* add mgmt interface */
DATA_BLOB *session_key)
{
struct dcesrv_auth *auth = call->auth_state;
-
+ SMB_ASSERT(auth->auth_finished);
return dcesrv_session_info_session_key(auth, session_key);
}
struct dcesrv_auth *auth = call->auth_state;
NTSTATUS status;
+ SMB_ASSERT(auth->auth_finished);
+
if (auth->session_key_fn == NULL) {
return NT_STATUS_NO_USER_SESSION_KEY;
}
p->max_xmit_frag = 5840;
p->max_total_request_size = DCERPC_NCACN_REQUEST_DEFAULT_MAX_SIZE;
+ p->support_hdr_signing = lpcfg_parm_bool(dce_ctx->lp_ctx,
+ NULL,
+ "dcesrv",
+ "header signing",
+ true);
+
auth = dcesrv_auth_create(p);
if (auth == NULL) {
talloc_free(p);
call->conn->allow_bind = false;
call->conn->allow_alter = false;
- call->conn->allow_request = false;
call->conn->default_auth_state->auth_invalid = true;
context->allow_connect);
}
-NTSTATUS dcesrv_interface_bind_require_integrity(struct dcesrv_call_state *dce_call,
+NTSTATUS dcesrv_interface_bind_require_integrity(struct dcesrv_connection_context *context,
const struct dcesrv_interface *iface)
{
- if (dce_call->context == NULL) {
- return NT_STATUS_INTERNAL_ERROR;
- }
-
/*
* For connection oriented DCERPC DCERPC_AUTH_LEVEL_PACKET (4)
* has the same behavior as DCERPC_AUTH_LEVEL_INTEGRITY (5).
*/
- dce_call->context->min_auth_level = DCERPC_AUTH_LEVEL_PACKET;
+ context->min_auth_level = DCERPC_AUTH_LEVEL_PACKET;
return NT_STATUS_OK;
}
-NTSTATUS dcesrv_interface_bind_require_privacy(struct dcesrv_call_state *dce_call,
+NTSTATUS dcesrv_interface_bind_require_privacy(struct dcesrv_connection_context *context,
const struct dcesrv_interface *iface)
{
- if (dce_call->context == NULL) {
- return NT_STATUS_INTERNAL_ERROR;
- }
-
- dce_call->context->min_auth_level = DCERPC_AUTH_LEVEL_PRIVACY;
+ context->min_auth_level = DCERPC_AUTH_LEVEL_PRIVACY;
return NT_STATUS_OK;
}
-_PUBLIC_ NTSTATUS dcesrv_interface_bind_reject_connect(struct dcesrv_call_state *dce_call,
+_PUBLIC_ NTSTATUS dcesrv_interface_bind_reject_connect(struct dcesrv_connection_context *context,
const struct dcesrv_interface *iface)
{
- struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
- const struct dcesrv_endpoint *endpoint = dce_call->conn->endpoint;
+ struct loadparm_context *lp_ctx = context->conn->dce_ctx->lp_ctx;
+ const struct dcesrv_endpoint *endpoint = context->conn->endpoint;
enum dcerpc_transport_t transport =
dcerpc_binding_get_transport(endpoint->ep_description);
- struct dcesrv_connection_context *context = dce_call->context;
-
- if (context == NULL) {
- return NT_STATUS_INTERNAL_ERROR;
- }
if (transport == NCALRPC) {
context->allow_connect = true;
return NT_STATUS_OK;
}
-_PUBLIC_ NTSTATUS dcesrv_interface_bind_allow_connect(struct dcesrv_call_state *dce_call,
+_PUBLIC_ NTSTATUS dcesrv_interface_bind_allow_connect(struct dcesrv_connection_context *context,
const struct dcesrv_interface *iface)
{
- struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
- const struct dcesrv_endpoint *endpoint = dce_call->conn->endpoint;
+ struct loadparm_context *lp_ctx = context->conn->dce_ctx->lp_ctx;
+ const struct dcesrv_endpoint *endpoint = context->conn->endpoint;
enum dcerpc_transport_t transport =
dcerpc_binding_get_transport(endpoint->ep_description);
- struct dcesrv_connection_context *context = dce_call->context;
-
- if (context == NULL) {
- return NT_STATUS_INTERNAL_ERROR;
- }
if (transport == NCALRPC) {
context->allow_connect = true;
uint32_t extra_flags = 0;
uint16_t max_req = 0;
uint16_t max_rep = 0;
- const char *ep_prefix = "";
+ struct dcerpc_binding *ep_2nd_description = NULL;
const char *endpoint = NULL;
struct dcesrv_auth *auth = call->auth_state;
struct dcerpc_ack_ctx *ack_ctx_list = NULL;
*/
if (call->pkt.u.bind.assoc_group_id != 0) {
call->conn->assoc_group = dcesrv_assoc_group_reference(call->conn,
- call->conn->dce_ctx,
call->pkt.u.bind.assoc_group_id);
} else {
- call->conn->assoc_group = dcesrv_assoc_group_new(call->conn,
- call->conn->dce_ctx);
+ call->conn->assoc_group = dcesrv_assoc_group_new(call->conn);
}
/*
if (call->conn->assoc_group == NULL &&
!call->conn->endpoint->use_single_process) {
call->conn->assoc_group
- = dcesrv_assoc_group_new(call->conn,
- call->conn->dce_ctx);
+ = dcesrv_assoc_group_new(call->conn);
}
if (call->conn->assoc_group == NULL) {
return dcesrv_bind_nak(call, 0);
DCERPC_BIND_TIME_KEEP_CONNECTION_ON_ORPHAN;
}
- call->conn->bind_time_features = a->reason.negotiate;
+ call->conn->assoc_group->bind_time_features = a->reason.negotiate;
}
/*
pkt->u.bind_ack.max_recv_frag = call->conn->max_recv_frag;
pkt->u.bind_ack.assoc_group_id = call->conn->assoc_group->id;
+ ep_2nd_description = call->conn->endpoint->ep_2nd_description;
+ if (ep_2nd_description == NULL) {
+ ep_2nd_description = call->conn->endpoint->ep_description;
+ }
+
endpoint = dcerpc_binding_get_string_option(
- call->conn->endpoint->ep_description,
+ ep_2nd_description,
"endpoint");
if (endpoint == NULL) {
endpoint = "";
}
- if (strncasecmp(endpoint, "\\pipe\\", 6) == 0) {
- /*
- * TODO: check if this is really needed
- *
- * Or if we should fix this in our idl files.
- */
- ep_prefix = "\\PIPE\\";
- endpoint += 6;
- }
-
- pkt->u.bind_ack.secondary_address = talloc_asprintf(call, "%s%s",
- ep_prefix,
- endpoint);
- if (pkt->u.bind_ack.secondary_address == NULL) {
- return NT_STATUS_NO_MEMORY;
- }
+ pkt->u.bind_ack.secondary_address = endpoint;
pkt->u.bind_ack.num_results = call->pkt.u.bind.num_contexts;
pkt->u.bind_ack.ctx_list = ack_ctx_list;
pkt->u.bind_ack.auth_info = data_blob_null;
context->context_id = ctx->context_id;
context->iface = iface;
context->transfer_syntax = *selected_transfer;
- context->private_data = NULL;
DLIST_ADD(call->conn->contexts, context);
call->context = context;
talloc_set_destructor(context, dcesrv_connection_context_destructor);
*/
call->state_flags |= DCESRV_CALL_STATE_FLAG_MULTIPLEXED;
- status = iface->bind(call, iface, if_version);
+ status = iface->bind(context, iface);
call->context = NULL;
if (!NT_STATUS_IS_OK(status)) {
/* we don't want to trigger the iface->unbind() hook */
static NTSTATUS dcesrv_check_verification_trailer(struct dcesrv_call_state *call)
{
TALLOC_CTX *frame = talloc_stackframe();
- const struct dcesrv_auth *auth = call->auth_state;
- const uint32_t bitmask1 = auth->client_hdr_signing ?
+ const uint32_t bitmask1 = call->conn->client_hdr_signing ?
DCERPC_SEC_VT_CLIENT_SUPPORTS_HEADER_SIGNING : 0;
const struct dcerpc_sec_vt_pcontext pcontext = {
.abstract_syntax = call->context->iface->syntax_id,
struct ndr_pull *pull;
NTSTATUS status;
- if (!call->conn->allow_request) {
+ if (!auth->auth_finished) {
return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
}
/* we have to check the signing here, before combining the
pdus */
if (call->pkt.ptype == DCERPC_PKT_REQUEST) {
- if (!call->conn->allow_request) {
+ if (!call->auth_state->auth_finished) {
return dcesrv_fault_disconnect(call,
DCERPC_NCA_S_PROTO_ERROR);
}
dce_conn->allow_bind = false;
dce_conn->allow_alter = false;
- dce_conn->allow_request = false;
dce_conn->default_auth_state->auth_invalid = true;
_PUBLIC_ struct cli_credentials *dcesrv_call_credentials(struct dcesrv_call_state *dce_call)
{
struct dcesrv_auth *auth = dce_call->auth_state;
+ SMB_ASSERT(auth->auth_finished);
return auth->session_info->credentials;
}
{
struct dcesrv_auth *auth = dce_call->auth_state;
enum security_user_level level;
+ SMB_ASSERT(auth->auth_finished);
level = security_session_user_level(auth->session_info, NULL);
return level >= SECURITY_USER;
}
_PUBLIC_ const char *dcesrv_call_account_name(struct dcesrv_call_state *dce_call)
{
struct dcesrv_auth *auth = dce_call->auth_state;
+ SMB_ASSERT(auth->auth_finished);
return auth->session_info->info->account_name;
}
_PUBLIC_ struct auth_session_info *dcesrv_call_session_info(struct dcesrv_call_state *dce_call)
{
struct dcesrv_auth *auth = dce_call->auth_state;
+ SMB_ASSERT(auth->auth_finished);
return auth->session_info;
}
{
struct dcesrv_auth *auth = dce_call->auth_state;
+ SMB_ASSERT(auth->auth_finished);
+
if (auth_type != NULL) {
*auth_type = auth->auth_type;
}