s4:rpc_server: add dcesrv_call_auth_info()
[samba.git] / source4 / rpc_server / dcerpc_server.c
index e0d222fe2aa99d551cb1ad73c591ddf409927be1..8f48814366b810074fe014b6fbce97b5a2a0bd54 100644 (file)
@@ -474,11 +474,9 @@ static NTSTATUS dcesrv_session_info_session_key(struct dcesrv_auth *auth,
        return NT_STATUS_OK;
 }
 
-NTSTATUS dcesrv_inherited_session_key(struct dcesrv_connection *p,
-                                     DATA_BLOB *session_key)
+static NTSTATUS dcesrv_remote_session_key(struct dcesrv_auth *auth,
+                                         DATA_BLOB *session_key)
 {
-       struct dcesrv_auth *auth = &p->auth_state;
-
        if (auth->auth_type != DCERPC_AUTH_TYPE_NONE) {
                return NT_STATUS_NO_USER_SESSION_KEY;
        }
@@ -486,6 +484,12 @@ NTSTATUS dcesrv_inherited_session_key(struct dcesrv_connection *p,
        return dcesrv_session_info_session_key(auth, session_key);
 }
 
+static NTSTATUS dcesrv_local_fixed_session_key(struct dcesrv_auth *auth,
+                                              DATA_BLOB *session_key)
+{
+       return dcerpc_generic_session_key(NULL, session_key);
+}
+
 /*
  * Fetch the authentication session key if available.
  *
@@ -501,21 +505,23 @@ _PUBLIC_ NTSTATUS dcesrv_auth_session_key(struct dcesrv_call_state *call,
 }
 
 /*
-  fetch the user session key - may be default (above) or the SMB session key
-
-  The key is always truncated to 16 bytes 
+ * 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.
 */
-_PUBLIC_ NTSTATUS dcesrv_fetch_session_key(struct dcesrv_connection *p,
-                                 DATA_BLOB *session_key)
+_PUBLIC_ NTSTATUS dcesrv_transport_session_key(struct dcesrv_call_state *call,
+                                              DATA_BLOB *session_key)
 {
-       struct dcesrv_auth *auth = &p->auth_state;
+       struct dcesrv_auth *auth = &call->conn->auth_state;
        NTSTATUS status;
 
-       if (auth->session_key == NULL) {
+       if (auth->session_key_fn == NULL) {
                return NT_STATUS_NO_USER_SESSION_KEY;
        }
 
-       status = auth->session_key(p, session_key);
+       status = auth->session_key_fn(auth, session_key);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
@@ -525,19 +531,6 @@ _PUBLIC_ NTSTATUS dcesrv_fetch_session_key(struct dcesrv_connection *p,
        return NT_STATUS_OK;
 }
 
-/*
- * 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.
-*/
-_PUBLIC_ NTSTATUS dcesrv_transport_session_key(struct dcesrv_call_state *call,
-                                              DATA_BLOB *session_key)
-{
-       return dcesrv_fetch_session_key(call->conn, session_key);
-}
-
 /*
   connect to a dcerpc endpoint
 */
@@ -551,6 +544,8 @@ 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_connection *p;
 
        if (!session_info) {
@@ -568,8 +563,6 @@ static NTSTATUS dcesrv_endpoint_connect(struct dcesrv_context *dce_ctx,
        p->dce_ctx = dce_ctx;
        p->endpoint = ep;
        p->packet_log_dir = lpcfg_lock_directory(dce_ctx->lp_ctx);
-       p->auth_state.session_info = session_info;
-       p->auth_state.session_key = dcesrv_generic_session_key;
        p->event_ctx = event_ctx;
        p->msg_ctx = msg_ctx;
        p->server_id = server_id;
@@ -579,6 +572,23 @@ 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;
+       }
+
        /*
         * For now we only support NDR32.
         */
@@ -2712,7 +2722,6 @@ static void dcesrv_sock_accept(struct stream_connection *srv_conn)
        }
 
        if (transport == NCACN_NP) {
-               dcesrv_conn->auth_state.session_key = dcesrv_inherited_session_key;
                dcesrv_conn->stream = talloc_move(dcesrv_conn,
                                                  &srv_conn->tstream);
        } else {
@@ -3224,3 +3233,20 @@ _PUBLIC_ struct auth_session_info *dcesrv_call_session_info(struct dcesrv_call_s
 {
        return dce_call->context->conn->auth_state.session_info;
 }
+
+/**
+ * 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)
+{
+       struct dcesrv_auth *auth = &dce_call->conn->auth_state;
+
+       if (auth_type != NULL) {
+               *auth_type = auth->auth_type;
+       }
+       if (auth_level != NULL) {
+               *auth_level = auth->auth_level;
+       }
+}