s4:rpc_server: make it possible to specify ncacn_np_secondary_endpoint
[gd/samba-autobuild/.git] / source4 / rpc_server / dcerpc_server.c
index fea3fb305ae78370c17bb1c05755d07654ab7cb6..75e1dfea1c786c9ebe4b184d8e97b1a47708ad9d 100644 (file)
@@ -65,18 +65,34 @@ static struct dcesrv_assoc_group *dcesrv_assoc_group_find(struct dcesrv_context
 /*
   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)
@@ -93,13 +109,16 @@ 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;
        }
@@ -111,6 +130,7 @@ static struct dcesrv_assoc_group *dcesrv_assoc_group_new(TALLOC_CTX *mem_ctx,
                return NULL;
        }
 
+       assoc_group->transport = transport;
        assoc_group->id = id;
        assoc_group->dce_ctx = dce_ctx;
 
@@ -264,12 +284,14 @@ static struct dcesrv_call_state *dcesrv_find_fragmented_call(struct dcesrv_conne
 */
 _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;
@@ -334,6 +356,22 @@ _PUBLIC_ NTSTATUS dcesrv_interface_register(struct dcesrv_context *dce_ctx,
                }
        }
 
+       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",
@@ -375,6 +413,7 @@ _PUBLIC_ NTSTATUS dcesrv_interface_register(struct dcesrv_context *dce_ctx,
                }
                ZERO_STRUCTP(ep);
                ep->ep_description = talloc_move(ep, &binding);
+               ep->ep_2nd_description = talloc_move(ep, &binding2);
                add_ep = true;
 
                /* add mgmt interface */
@@ -499,8 +538,8 @@ static NTSTATUS dcesrv_local_fixed_session_key(struct dcesrv_auth *auth,
 _PUBLIC_ NTSTATUS dcesrv_auth_session_key(struct dcesrv_call_state *call,
                                          DATA_BLOB *session_key)
 {
-       struct dcesrv_auth *auth = &call->conn->auth_state;
-
+       struct dcesrv_auth *auth = call->auth_state;
+       SMB_ASSERT(auth->auth_finished);
        return dcesrv_session_info_session_key(auth, session_key);
 }
 
@@ -514,9 +553,11 @@ _PUBLIC_ NTSTATUS dcesrv_auth_session_key(struct dcesrv_call_state *call,
 _PUBLIC_ NTSTATUS dcesrv_transport_session_key(struct dcesrv_call_state *call,
                                               DATA_BLOB *session_key)
 {
-       struct dcesrv_auth *auth = &call->conn->auth_state;
+       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;
        }
@@ -531,6 +572,37 @@ _PUBLIC_ NTSTATUS dcesrv_transport_session_key(struct dcesrv_call_state *call,
        return NT_STATUS_OK;
 }
 
+static struct dcesrv_auth *dcesrv_auth_create(struct dcesrv_connection *conn)
+{
+       const struct dcesrv_endpoint *ep = conn->endpoint;
+       enum dcerpc_transport_t transport =
+               dcerpc_binding_get_transport(ep->ep_description);
+       struct dcesrv_auth *auth = NULL;
+
+       auth = talloc_zero(conn, struct dcesrv_auth);
+       if (auth == NULL) {
+               return NULL;
+       }
+
+       switch (transport) {
+       case NCACN_NP:
+               auth->session_key_fn = dcesrv_remote_session_key;
+               break;
+       case NCALRPC:
+       case NCACN_UNIX_STREAM:
+               auth->session_key_fn = dcesrv_local_fixed_session_key;
+               break;
+       default:
+               /*
+                * All other's get a NULL pointer, which
+                * results in NT_STATUS_NO_USER_SESSION_KEY
+                */
+               break;
+       }
+
+       return auth;
+}
+
 /*
   connect to a dcerpc endpoint
 */
@@ -544,8 +616,7 @@ static NTSTATUS dcesrv_endpoint_connect(struct dcesrv_context *dce_ctx,
                                 uint32_t state_flags,
                                 struct dcesrv_connection **_p)
 {
-       enum dcerpc_transport_t transport =
-               dcerpc_binding_get_transport(ep->ep_description);
+       struct dcesrv_auth *auth = NULL;
        struct dcesrv_connection *p;
 
        if (!session_info) {
@@ -555,11 +626,6 @@ static NTSTATUS dcesrv_endpoint_connect(struct dcesrv_context *dce_ctx,
        p = talloc_zero(mem_ctx, struct dcesrv_connection);
        NT_STATUS_HAVE_NO_MEMORY(p);
 
-       if (!talloc_reference(p, session_info)) {
-               talloc_free(p);
-               return NT_STATUS_NO_MEMORY;
-       }
-
        p->dce_ctx = dce_ctx;
        p->endpoint = ep;
        p->packet_log_dir = lpcfg_lock_directory(dce_ctx->lp_ctx);
@@ -572,23 +638,26 @@ static NTSTATUS dcesrv_endpoint_connect(struct dcesrv_context *dce_ctx,
        p->max_xmit_frag = 5840;
        p->max_total_request_size = DCERPC_NCACN_REQUEST_DEFAULT_MAX_SIZE;
 
-       p->auth_state.session_info = session_info;
-       switch (transport) {
-       case NCACN_NP:
-               p->auth_state.session_key_fn = dcesrv_remote_session_key;
-               break;
-       case NCALRPC:
-       case NCACN_UNIX_STREAM:
-               p->auth_state.session_key_fn = dcesrv_local_fixed_session_key;
-               break;
-       default:
-               /*
-                * All other's get a NULL pointer, which
-                * results in NT_STATUS_NO_USER_SESSION_KEY
-                */
-               break;
+       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);
+               return NT_STATUS_NO_MEMORY;
        }
 
+       auth->session_info = talloc_reference(auth, session_info);
+       if (auth->session_info == NULL) {
+               talloc_free(p);
+               return NT_STATUS_NO_MEMORY;
+       }
+
+       p->default_auth_state = auth;
+
        /*
         * For now we only support NDR32.
         */
@@ -644,8 +713,8 @@ static void dcesrv_call_disconnect_after(struct dcesrv_call_state *call,
 
        call->conn->allow_bind = false;
        call->conn->allow_alter = false;
-       call->conn->allow_auth3 = false;
-       call->conn->allow_request = false;
+
+       call->conn->default_auth_state->auth_invalid = true;
 
        call->terminate_reason = talloc_strdup(call, reason);
        if (call->terminate_reason == NULL) {
@@ -759,44 +828,31 @@ static void dcesrv_prepare_context_auth(struct dcesrv_call_state *dce_call)
                                        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;
@@ -815,18 +871,13 @@ _PUBLIC_ NTSTATUS dcesrv_interface_bind_reject_connect(struct dcesrv_call_state
        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;
@@ -946,9 +997,9 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call)
        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->conn->auth_state;
+       struct dcesrv_auth *auth = call->auth_state;
        struct dcerpc_ack_ctx *ack_ctx_list = NULL;
        struct dcerpc_ack_ctx *ack_features = NULL;
        struct tevent_req *subreq = NULL;
@@ -992,11 +1043,9 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call)
         */
        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);
        }
 
        /*
@@ -1022,8 +1071,7 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call)
        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);
@@ -1085,7 +1133,7 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call)
                                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;
        }
 
        /*
@@ -1159,29 +1207,19 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call)
        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;
@@ -1270,11 +1308,11 @@ static void dcesrv_auth3_done(struct tevent_req *subreq);
 static NTSTATUS dcesrv_auth3(struct dcesrv_call_state *call)
 {
        struct dcesrv_connection *conn = call->conn;
-       struct dcesrv_auth *auth = &call->conn->auth_state;
+       struct dcesrv_auth *auth = call->auth_state;
        struct tevent_req *subreq = NULL;
        NTSTATUS status;
 
-       if (!call->conn->allow_auth3) {
+       if (!auth->auth_started) {
                return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
        }
 
@@ -1332,7 +1370,7 @@ static void dcesrv_auth3_done(struct tevent_req *subreq)
                tevent_req_callback_data(subreq,
                struct dcesrv_call_state);
        struct dcesrv_connection *conn = call->conn;
-       struct dcesrv_auth *auth = &call->conn->auth_state;
+       struct dcesrv_auth *auth = call->auth_state;
        NTSTATUS status;
 
        status = gensec_update_recv(subreq, call,
@@ -1495,7 +1533,6 @@ static NTSTATUS dcesrv_check_or_create_context(struct dcesrv_call_state *call,
        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);
@@ -1507,7 +1544,7 @@ static NTSTATUS dcesrv_check_or_create_context(struct dcesrv_call_state *call,
         */
        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 */
@@ -1608,7 +1645,7 @@ static NTSTATUS dcesrv_alter(struct dcesrv_call_state *call)
        bool auth_ok = false;
        struct ncacn_packet *pkt = &call->ack_pkt;
        uint32_t extra_flags = 0;
-       struct dcesrv_auth *auth = &call->conn->auth_state;
+       struct dcesrv_auth *auth = call->auth_state;
        struct dcerpc_ack_ctx *ack_ctx_list = NULL;
        struct tevent_req *subreq = NULL;
        size_t i;
@@ -1782,8 +1819,7 @@ static void dcesrv_save_call(struct dcesrv_call_state *call, const char *why)
 static NTSTATUS dcesrv_check_verification_trailer(struct dcesrv_call_state *call)
 {
        TALLOC_CTX *frame = talloc_stackframe();
-       const struct dcesrv_auth *auth = &call->conn->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,
@@ -1822,13 +1858,13 @@ done:
 static NTSTATUS dcesrv_request(struct dcesrv_call_state *call)
 {
        const struct dcesrv_endpoint *endpoint = call->conn->endpoint;
-       struct dcesrv_auth *auth = &call->conn->auth_state;
+       struct dcesrv_auth *auth = call->auth_state;
        enum dcerpc_transport_t transport =
                dcerpc_binding_get_transport(endpoint->ep_description);
        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);
        }
 
@@ -2000,6 +2036,8 @@ static NTSTATUS dcesrv_process_ncacn_packet(struct dcesrv_connection *dce_conn,
        talloc_steal(call, blob.data);
        call->pkt = *pkt;
 
+       call->auth_state = dce_conn->default_auth_state;
+
        talloc_set_destructor(call, dcesrv_call_dequeue);
 
        if (call->conn->allow_bind) {
@@ -2013,7 +2051,7 @@ static NTSTATUS dcesrv_process_ncacn_packet(struct dcesrv_connection *dce_conn,
        /* 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);
                }
@@ -2450,9 +2488,9 @@ static void dcesrv_terminate_connection(struct dcesrv_connection *dce_conn, cons
        dce_conn->wait_private = NULL;
 
        dce_conn->allow_bind = false;
-       dce_conn->allow_auth3 = false;
        dce_conn->allow_alter = false;
-       dce_conn->allow_request = false;
+
+       dce_conn->default_auth_state->auth_invalid = true;
 
        if (dce_conn->pending_call_list == NULL) {
                char *full_reason = talloc_asprintf(dce_conn, "dcesrv: %s", reason);
@@ -3206,7 +3244,8 @@ NTSTATUS dcesrv_add_ep(struct dcesrv_context *dce_ctx,
  */
 _PUBLIC_ struct cli_credentials *dcesrv_call_credentials(struct dcesrv_call_state *dce_call)
 {
-       struct dcesrv_auth *auth = &dce_call->conn->auth_state;
+       struct dcesrv_auth *auth = dce_call->auth_state;
+       SMB_ASSERT(auth->auth_finished);
        return auth->session_info->credentials;
 }
 
@@ -3215,8 +3254,9 @@ _PUBLIC_ struct cli_credentials *dcesrv_call_credentials(struct dcesrv_call_stat
  */
 _PUBLIC_ bool dcesrv_call_authenticated(struct dcesrv_call_state *dce_call)
 {
-       struct dcesrv_auth *auth = &dce_call->conn->auth_state;
+       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;
 }
@@ -3226,7 +3266,8 @@ _PUBLIC_ bool dcesrv_call_authenticated(struct dcesrv_call_state *dce_call)
  */
 _PUBLIC_ const char *dcesrv_call_account_name(struct dcesrv_call_state *dce_call)
 {
-       struct dcesrv_auth *auth = &dce_call->conn->auth_state;
+       struct dcesrv_auth *auth = dce_call->auth_state;
+       SMB_ASSERT(auth->auth_finished);
        return auth->session_info->info->account_name;
 }
 
@@ -3235,7 +3276,8 @@ _PUBLIC_ const char *dcesrv_call_account_name(struct dcesrv_call_state *dce_call
  */
 _PUBLIC_ struct auth_session_info *dcesrv_call_session_info(struct dcesrv_call_state *dce_call)
 {
-       struct dcesrv_auth *auth = &dce_call->conn->auth_state;
+       struct dcesrv_auth *auth = dce_call->auth_state;
+       SMB_ASSERT(auth->auth_finished);
        return auth->session_info;
 }
 
@@ -3246,7 +3288,9 @@ _PUBLIC_ void dcesrv_call_auth_info(struct dcesrv_call_state *dce_call,
                                    enum dcerpc_AuthType *auth_type,
                                    enum dcerpc_AuthLevel *auth_level)
 {
-       struct dcesrv_auth *auth = &dce_call->conn->auth_state;
+       struct dcesrv_auth *auth = dce_call->auth_state;
+
+       SMB_ASSERT(auth->auth_finished);
 
        if (auth_type != NULL) {
                *auth_type = auth->auth_type;