From 3e2e970af2f1c501b5a8ebb76252df2e2babf3f9 Mon Sep 17 00:00:00 2001 From: Colin James Date: Thu, 7 Nov 2024 13:58:39 +0000 Subject: [PATCH] Document Rbac module Introduces an interface file for the Rbac module within xapi in order to document the intent of each of its functions. Signed-off-by: Colin James --- ocaml/xapi/rbac.ml | 5 --- ocaml/xapi/rbac.mli | 104 ++++++++++++++++++++++++++++++++++++++++++++ quality-gate.sh | 2 +- 3 files changed, 105 insertions(+), 6 deletions(-) create mode 100644 ocaml/xapi/rbac.mli diff --git a/ocaml/xapi/rbac.ml b/ocaml/xapi/rbac.ml index feefcf4143..2b311a7e56 100644 --- a/ocaml/xapi/rbac.ml +++ b/ocaml/xapi/rbac.ml @@ -243,11 +243,6 @@ let assert_permission_name ~__context ~permission = let assert_permission ~__context ~permission = assert_permission_name ~__context ~permission:permission.role_name_label -(* this is necessary to break dependency cycle between rbac and taskhelper *) -let init_task_helper_rbac_has_permission_fn = - if !TaskHelper.rbac_assert_permission_fn = None then - TaskHelper.rbac_assert_permission_fn := Some assert_permission - let has_permission_name ~__context ~permission = let session_id = get_session_of_context ~__context ~permission in is_access_allowed ~__context ~session_id ~permission diff --git a/ocaml/xapi/rbac.mli b/ocaml/xapi/rbac.mli new file mode 100644 index 0000000000..6905379a31 --- /dev/null +++ b/ocaml/xapi/rbac.mli @@ -0,0 +1,104 @@ +(* + * Copyright (c) Cloud Software Group, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; version 2.1 only. with the special + * exception on linking described in file LICENSE. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + *) + +val is_access_allowed : + __context:Context.t + -> session_id:[`session] Ref.t + -> permission:string + -> bool +(** Determines whether the session associated with the provided + context has the specified permission. The permission set is cached + (on the coordinator only) to benefit successive queries for the + same session. *) + +val check : + ?extra_dmsg:string + -> ?extra_msg:string + -> ?args:(string * Rpc.t) list + -> ?keys:string list + -> __context:Context.t + -> fn:(unit -> 'a) + -> [`session] Ref.t + -> string + -> 'a +(** [check] executes a function associated with an action if the + session associated with the provided context is authorised to + perform the action. + + The [?extra_dmsg] and [?extra_msg] parameters allow for extra + information in debugging and error messages. + + The [?keys] parameter specifies which fields of a (string -> _) + map are RBAC-protected. It is primarily associated with + auto-generated methods such as add_to_other_config. However, if + [?keys] is non-empty, then [?args] must also be consulted as the + related methods that require this protection specify their key + name as a parameter. Otherwise, [?args] is mostly used to log + calls within the RBAC audit log. *) + +val check_with_new_task : + ?extra_dmsg:string + -> ?extra_msg:string + -> ?task_desc:string + -> ?args:(string * Rpc.t) list + -> fn:(unit -> 'a) + -> [`session] Ref.t + -> string + -> 'a +(** Defined in terms of [check] but using a context associated with a + freshly-created task. *) + +val assert_permission_name : __context:Context.t -> permission:string -> unit +(** Performs a dry run of the [check] function with a no-op action + guarded by the provided permission (as a name). *) + +val assert_permission : + __context:Context.t -> permission:Db_actions.role_t -> unit +(** Performs a dry run of the [check] function with a no-op action + guarded by the provided permission (as a database role). *) + +val has_permission : __context:Context.t -> permission:Db_actions.role_t -> bool +(** [has_permission ctx p] determines if the session associated with + the context [ctx] is authorised to perform a specific action. + + [p] is of the type defined by the generated [Db_actions] module, + as [Xapi_role] simulates a database for the checking of static + role sets (as emitted in [Rbac_static]) and only appeals to the + xapi DB for additional roles. *) + +val is_rbac_enabled_for_http_action : string -> bool +(** [is_rbac_enabled_for_http_action route] determines whether RBAC + checks should be applied to the provided HTTP [route]. + + Some routes are precluded from RBAC checks because they are + assumed to only be used by code paths where RBAC has already been + checked or will be checked internally (e.g. /post_cli). *) + +val permission_of_action : + ?args:(string * Rpc.t) list -> keys:string list -> string -> string +(** Constructs the name of a permission associated with using an + RBAC-protected key with a specified action. + + For example, if [keys] specifies "folder" as a protected key name + for the action SR.remove_from_other_config, the permission name + associated with that is "SR.remove_from_other_config/key:folder" + - which is consistent with the format that [Rbac_static] contains. *) + +val nofn : unit -> unit +(** Named function that does nothing, e.g. (fun _ -> ()). + Used as a dummy action for RBAC checking. *) + +val destroy_session_permissions_tbl : session_id:[`session] Ref.t -> unit +(** Removes any cached permission set for the given session. This is + called when xapi destroys the DB entry for a session. *) diff --git a/quality-gate.sh b/quality-gate.sh index 16a90270b1..db8444b53e 100755 --- a/quality-gate.sh +++ b/quality-gate.sh @@ -25,7 +25,7 @@ verify-cert () { } mli-files () { - N=499 + N=498 # do not count ml files from the tests in ocaml/{tests/perftest/quicktest} MLIS=$(git ls-files -- '**/*.mli' | grep -vE "ocaml/tests|ocaml/perftest|ocaml/quicktest|ocaml/message-switch/core_test" | xargs -I {} sh -c "echo {} | cut -f 1 -d '.'" \;) MLS=$(git ls-files -- '**/*.ml' | grep -vE "ocaml/tests|ocaml/perftest|ocaml/quicktest|ocaml/message-switch/core_test" | xargs -I {} sh -c "echo {} | cut -f 1 -d '.'" \;)