Whamcloud - gitweb
LU-17431 nodemap: introduce child_raise_privileges property 39/55539/14
authorSebastien Buisson <sbuisson@ddn.com>
Tue, 25 Jun 2024 11:02:55 +0000 (13:02 +0200)
committerOleg Drokin <green@whamcloud.com>
Thu, 10 Apr 2025 06:52:59 +0000 (06:52 +0000)
The new 'child_raise_privileges' property is a mask of nodemap
properties. It is set to 'none' by default, meaning child nodemaps can
only lower privileges established by their parent nodemap.
Parent nodemaps can grant permission for child nodemaps to raise
privilege associated with a nodemap property by adding it to
child_raise_privileges. Possible values (multiple can be specified,
comma separated) are:
- admin, defining whether root is squashed;
- trusted, permitting to see the file system's canonical identifiers;
- deny_unknown, denying all access to users not explicitly mapped;
- readonly_mount, forcing clients to read-only mount;
- forbid_encryption, preventing use of encryption by clients;
- subnm_raise_privs, for the raise privileges property itself;
- and any roles accepted by the rbac property, defining admin roles.
To allow all privileges to be raised, use 'all' value.
Any privilege not explicitly specified by the parent cannot be raised
in the child nodemap.

Signed-off-by: Sebastien Buisson <sbuisson@ddn.com>
Change-Id: Ifac5e3ea2f47ea3910e7cd0de6379b0e9ada8d18
Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/55539
Reviewed-by: Marc Vef <mvef@whamcloud.com>
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
14 files changed:
lustre/doc/lctl-nodemap-modify.8
lustre/include/lustre_nodemap.h
lustre/include/uapi/linux/lustre/lustre_cfg.h
lustre/include/uapi/linux/lustre/lustre_disk.h
lustre/include/uapi/linux/lustre/lustre_idl.h
lustre/ptlrpc/nodemap_handler.c
lustre/ptlrpc/nodemap_lproc.c
lustre/ptlrpc/nodemap_storage.c
lustre/ptlrpc/wiretest.c
lustre/tests/sanity-sec.sh
lustre/utils/lctl.c
lustre/utils/obd.c
lustre/utils/wirecheck.c
lustre/utils/wiretest.c

index 2be825c..83dafb9 100644 (file)
@@ -1,4 +1,4 @@
-.TH LCTL-NODEMAP_MODIFY 8 2024-08-14 Lustre "Lustre Configuration Utilities"
+.TH LCTL-NODEMAP_MODIFY 8 2025-02-28 Lustre "Lustre Configuration Utilities"
 .SH NAME
 lctl-nodemap_modify \- modify a nodemap property
 .SH SYNOPSIS
@@ -85,6 +85,30 @@ map UIDs, gid to map GIDs, both to map UIDs and GIDs, and projid to map PROJIDs.
 Defaults to 0, which means encryption is allowed.
 Set to 1 to prevent clients from using encryption.
 .TP
+.B child_raise_privileges
+Defaults to none, allowing child nodemaps to only lower privileges established
+by parent nodemap. Other possible values (multiple can be specified, comma
+separated) are the nodemap properties names that support privilege raise:
+.br
+- admin
+.br
+- trusted
+.br
+- deny_unknown
+.br
+- readonly_mount
+.br
+- forbid_encryption
+.br
+- child_raise_privs
+.br
+It is also possible to specify any roles accepted by the
+.B rbac
+property (see below).
+.br
+Any privilege not explicitly specified cannot be raised. To allow all privileges
+to be raised, use 'all' value.
+.TP
 .B readonly_mount
 Defaults to 0, which lets clients mount in read-write mode. If set to 1,
 clients are forced to a read-only mount if not specified explicitly.
@@ -133,6 +157,7 @@ and
 .BI --value " VALUE"
 is invalid.
 .SH EXAMPLES
+Commands illustrating how to modify nodemap properties:
 .EX
 .B # lctl nodemap_modify --name remotesite --property trusted --value 1
 .B # lctl nodemap_modify --name remotesite --property admin --value 1
index 7a59954..3f94443 100644 (file)
@@ -44,6 +44,19 @@ struct nodemap_pde {
        struct list_head         npe_list_member;
 };
 
+static const struct nodemap_priv_name {
+       enum nodemap_raise_privs        npn_priv;
+       const char                     *npn_name;
+} nodemap_priv_names[] = {
+       { NODEMAP_RAISE_PRIV_RAISE,             "child_raise_privs"     },
+       { NODEMAP_RAISE_PRIV_ADMIN,             "admin"                 },
+       { NODEMAP_RAISE_PRIV_TRUSTED,           "trusted"               },
+       { NODEMAP_RAISE_PRIV_DENY_UNKN,         "deny_unknown"          },
+       { NODEMAP_RAISE_PRIV_RO,                "readonly_mount"        },
+       /* NODEMAP_RAISE_PRIV_RBAC uses the rbac roles directly */
+       { NODEMAP_RAISE_PRIV_FORBID_ENC,        "forbid_encryption"     },
+};
+
 /** The nodemap id 0 will be the default nodemap. It will have a configuration
  * set by the MGS, but no ranges will be allowed as all NIDs that do not map
  * will be added to the default nodemap
@@ -65,6 +78,10 @@ struct lu_nodemap {
        enum nodemap_mapping_modes nmf_map_mode;
        /* bitmap for rbac, enum nodemap_rbac_roles */
        enum nodemap_rbac_roles  nmf_rbac;
+       /* bitmap for privilege raise, enum nodemap_raise_privs */
+       enum nodemap_raise_privs nmf_raise_privs;
+       /* bitmap for rbac raise, enum nodemap_rbac_roles */
+       enum nodemap_rbac_roles nmf_rbac_raise;
        /* unique ID set by MGS */
        unsigned int             nm_id;
        /* nodemap ref counter */
@@ -167,6 +184,8 @@ int nodemap_set_squash_gid(const char *name, gid_t gid);
 int nodemap_set_squash_projid(const char *name, projid_t projid);
 int nodemap_set_audit_mode(const char *name, bool enable_audit);
 int nodemap_set_forbid_encryption(const char *name, bool forbid_encryption);
+int nodemap_set_raise_privs(const char *name, enum nodemap_raise_privs privs,
+                           enum nodemap_rbac_roles rbac_raise);
 int nodemap_set_readonly_mount(const char *name, bool readonly_mount);
 int nodemap_set_deny_mount(const char *name, bool deny_mount);
 bool nodemap_can_setquota(struct lu_nodemap *nodemap, __u32 qc_type, __u32 id);
index 1a2ef77..2b1b9cb 100644 (file)
@@ -127,6 +127,7 @@ enum lcfg_command_type {
        LCFG_NODEMAP_READONLY_MOUNT     = 0x00ce05e, /**< read-only mount */
        LCFG_NODEMAP_RBAC         = 0x00ce05f, /**< rbac */
        LCFG_NODEMAP_DENY_MOUNT   = 0x00ce060, /**< deny mount */
+       LCFG_NODEMAP_RAISE_PRIVS        = 0x00ce061, /**< sub-nm raise privs */
 };
 
 struct lustre_cfg_bufs {
index 4ea9588..3fe114e 100644 (file)
@@ -317,9 +317,9 @@ struct nodemap_global_rec {
 
 struct nodemap_cluster_roles_rec {
        __u64 ncrr_roles;               /* enum nodemap_rbac_roles */
-       __u64 ncrr_padding1;            /* zeroed since 2.16 (always) */
-       __u64 ncrr_padding2;            /* zeroed since 2.16 (always) */
-       __u64 ncrr_padding3;            /* zeroed since 2.16 (always) */
+       __u64 ncrr_privs;               /* enum nodemap_raise_privs */
+       __u64 ncrr_roles_raise;         /* enum nodemap_rbac_roles */
+       __u64 ncrr_unused1;             /* zeroed since 2.16 (always) */
 };
 
 struct nodemap_offset_rec {
index e34cfdd..3bd8dca 100644 (file)
@@ -3854,6 +3854,24 @@ enum nodemap_rbac_roles {
        NODEMAP_RBAC_ALL        = 0xFFFFFFFF, /* future caps ON by default */
 };
 
+enum nodemap_raise_privs {
+       NODEMAP_RAISE_PRIV_RAISE        = 0x00000001,
+       NODEMAP_RAISE_PRIV_ADMIN        = 0x00000002,
+       NODEMAP_RAISE_PRIV_TRUSTED      = 0x00000004,
+       NODEMAP_RAISE_PRIV_DENY_UNKN    = 0x00000008,
+       NODEMAP_RAISE_PRIV_RO           = 0x00000010,
+       NODEMAP_RAISE_PRIV_RBAC         = 0x00000020,
+       NODEMAP_RAISE_PRIV_FORBID_ENC   = 0x00000040,
+       NODEMAP_RAISE_PRIV_NONE = (__u32)~(NODEMAP_RAISE_PRIV_RAISE     |
+                                          NODEMAP_RAISE_PRIV_ADMIN     |
+                                          NODEMAP_RAISE_PRIV_TRUSTED   |
+                                          NODEMAP_RAISE_PRIV_DENY_UNKN |
+                                          NODEMAP_RAISE_PRIV_RO        |
+                                          NODEMAP_RAISE_PRIV_RBAC      |
+                                          NODEMAP_RAISE_PRIV_FORBID_ENC),
+       NODEMAP_RAISE_PRIV_ALL  = 0xFFFFFFFF, /* future privs RAISED by def */
+};
+
 /*
  * rawobj stuff for GSS
  */
index dcefca2..dbd7376 100644 (file)
@@ -211,6 +211,76 @@ static bool allow_op_on_nm(struct lu_nodemap *nodemap)
 }
 
 /**
+ * Check if sub-nodemap can raise privileges
+ *
+ * \param      nodemap         the nodemap to modify
+ * \param      priv            the attempted privilege raise
+ * \param      val             new value for the field
+ * \retval     true            if the modification is allowed
+ *
+ * The following properties are checked:
+ * - nmf_allow_root_access
+ * - nmf_trust_client_ids
+ * - nmf_deny_unknown
+ * - nmf_readonly_mount
+ * - nmf_rbac
+ * - nmf_rbac_raise
+ * - nmf_forbid_encryption
+ * If nmf_raise_privs grants corresponding privilege, any change on these
+ * properties is permitted. Otherwise, only lowering privileges is possible,
+ * which means:
+ * - nmf_allow_root_access from 1 (parent) to 0
+ * - nmf_trust_client_ids from 1 (parent) to 0
+ * - nmf_deny_unknown from 0 (parent) to 1
+ * - nmf_readonly_mount from 0 (parent) to 1
+ * - nmf_rbac to fewer roles
+ * - nmf_rbac_raise to fewer roles
+ * - nmf_forbid_encryption from 1 (parent) to 0
+ */
+static bool check_privs_for_op(struct lu_nodemap *nodemap,
+                              enum nodemap_raise_privs priv, u64 val)
+{
+       u32 prop_val = (u32)(0xffffffff & val);
+       /* only relevant with priv == NODEMAP_RAISE_PRIV_RAISE */
+       u32 rbac_raise = (u32)(val >> 32);
+
+       if (!allow_op_on_nm(nodemap))
+               return false;
+
+       if (!nodemap->nm_dyn)
+               return true;
+
+       if (!nodemap->nm_parent_nm)
+               return false;
+
+       if (nodemap->nm_parent_nm->nmf_raise_privs & priv)
+               return true;
+
+       switch (priv) {
+       case NODEMAP_RAISE_PRIV_RAISE:
+               return !(~nodemap->nm_parent_nm->nmf_raise_privs & prop_val) &&
+                       !(~nodemap->nm_parent_nm->nmf_rbac_raise & rbac_raise);
+       case NODEMAP_RAISE_PRIV_ADMIN:
+               return (nodemap->nm_parent_nm->nmf_allow_root_access ||
+                       !prop_val);
+       case NODEMAP_RAISE_PRIV_TRUSTED:
+               return (nodemap->nm_parent_nm->nmf_trust_client_ids ||
+                       !prop_val);
+       case NODEMAP_RAISE_PRIV_DENY_UNKN:
+               return (!nodemap->nm_parent_nm->nmf_deny_unknown || prop_val);
+       case NODEMAP_RAISE_PRIV_RO:
+               return (!nodemap->nm_parent_nm->nmf_readonly_mount || prop_val);
+       case NODEMAP_RAISE_PRIV_RBAC:
+               return !(~nodemap->nm_parent_nm->nmf_rbac & prop_val);
+       case NODEMAP_RAISE_PRIV_FORBID_ENC:
+               return (nodemap->nm_parent_nm->nmf_forbid_encryption ||
+                       !prop_val);
+       default:
+               return true;
+       }
+}
+
+/**
  * Check for valid nodemap name
  *
  * \param      name            nodemap name
@@ -976,6 +1046,8 @@ static int nodemap_inherit_properties(struct lu_nodemap *dst,
                dst->nmf_rbac = NODEMAP_RBAC_ALL;
                dst->nmf_deny_mount = 0;
                dst->nmf_fileset_use_iam = 0;
+               dst->nmf_raise_privs = NODEMAP_RAISE_PRIV_NONE;
+               dst->nmf_rbac_raise = NODEMAP_RBAC_NONE;
 
                dst->nm_squash_uid = NODEMAP_NOBODY_UID;
                dst->nm_squash_gid = NODEMAP_NOBODY_GID;
@@ -1000,7 +1072,8 @@ static int nodemap_inherit_properties(struct lu_nodemap *dst,
                dst->nmf_rbac = src->nmf_rbac;
                dst->nmf_deny_mount = src->nmf_deny_mount;
                dst->nmf_fileset_use_iam = 0;
-
+               dst->nmf_raise_privs = src->nmf_raise_privs;
+               dst->nmf_rbac_raise = src->nmf_rbac_raise;
                dst->nm_squash_uid = src->nm_squash_uid;
                dst->nm_squash_gid = src->nm_squash_gid;
                dst->nm_squash_projid = src->nm_squash_projid;
@@ -1710,7 +1783,8 @@ int nodemap_set_deny_unknown(const char *name, bool deny_unknown)
        mutex_unlock(&active_config_lock);
        if (IS_ERR(nodemap))
                GOTO(out, rc = PTR_ERR(nodemap));
-       if (!allow_op_on_nm(nodemap))
+       if (!check_privs_for_op(nodemap, NODEMAP_RAISE_PRIV_DENY_UNKN,
+                               deny_unknown))
                GOTO(out_putref, rc = -EPERM);
 
        nodemap->nmf_deny_unknown = deny_unknown;
@@ -1741,7 +1815,7 @@ int nodemap_set_allow_root(const char *name, bool allow_root)
        mutex_unlock(&active_config_lock);
        if (IS_ERR(nodemap))
                GOTO(out, rc = PTR_ERR(nodemap));
-       if (!allow_op_on_nm(nodemap))
+       if (!check_privs_for_op(nodemap, NODEMAP_RAISE_PRIV_ADMIN, allow_root))
                GOTO(out_putref, rc = -EPERM);
 
        nodemap->nmf_allow_root_access = allow_root;
@@ -1773,7 +1847,8 @@ int nodemap_set_trust_client_ids(const char *name, bool trust_client_ids)
        mutex_unlock(&active_config_lock);
        if (IS_ERR(nodemap))
                GOTO(out, rc = PTR_ERR(nodemap));
-       if (!allow_op_on_nm(nodemap))
+       if (!check_privs_for_op(nodemap, NODEMAP_RAISE_PRIV_TRUSTED,
+                               trust_client_ids))
                GOTO(out_putref, rc = -EPERM);
 
        nodemap->nmf_trust_client_ids = trust_client_ids;
@@ -1812,6 +1887,34 @@ out:
 }
 EXPORT_SYMBOL(nodemap_set_mapping_mode);
 
+int nodemap_idx_cluster_roles_modify(struct lu_nodemap *nodemap,
+                                    enum nodemap_rbac_roles old_rbac,
+                                    enum nodemap_raise_privs old_privs,
+                                    enum nodemap_rbac_roles old_rbac_raise)
+{
+       int rc;
+
+       if (nodemap->nmf_rbac == NODEMAP_RBAC_ALL &&
+           nodemap->nmf_raise_privs == NODEMAP_RAISE_PRIV_NONE &&
+           nodemap->nmf_rbac_raise == NODEMAP_RBAC_NONE)
+               /* if new value is the default, just delete
+                * NODEMAP_CLUSTER_ROLES idx
+                */
+               rc = nodemap_idx_cluster_roles_del(nodemap);
+       else if (old_rbac == NODEMAP_RBAC_ALL &&
+                old_privs == NODEMAP_RAISE_PRIV_NONE &&
+                old_rbac_raise == NODEMAP_RBAC_NONE)
+               /* if old value is the default, need to insert
+                * new NODEMAP_CLUSTER_ROLES idx
+                */
+               rc = nodemap_idx_cluster_roles_add(nodemap);
+       else
+               /* otherwise just update existing NODEMAP_CLUSTER_ROLES idx */
+               rc = nodemap_idx_cluster_roles_update(nodemap);
+
+       return rc;
+}
+
 int nodemap_set_rbac(const char *name, enum nodemap_rbac_roles rbac)
 {
        struct lu_nodemap *nodemap = NULL;
@@ -1823,7 +1926,7 @@ int nodemap_set_rbac(const char *name, enum nodemap_rbac_roles rbac)
        mutex_unlock(&active_config_lock);
        if (IS_ERR(nodemap))
                GOTO(out, rc = PTR_ERR(nodemap));
-       if (!allow_op_on_nm(nodemap))
+       if (!check_privs_for_op(nodemap, NODEMAP_RAISE_PRIV_RBAC, rbac))
                GOTO(put, rc = -EPERM);
 
        if (is_default_nodemap(nodemap))
@@ -1835,19 +1938,9 @@ int nodemap_set_rbac(const char *name, enum nodemap_rbac_roles rbac)
                GOTO(put, rc = 0);
 
        nodemap->nmf_rbac = rbac;
-       if (rbac == NODEMAP_RBAC_ALL)
-               /* if new value is ALL (default), just delete
-                * NODEMAP_CLUSTER_ROLES idx
-                */
-               rc = nodemap_idx_cluster_roles_del(nodemap);
-       else if (old_rbac == NODEMAP_RBAC_ALL)
-               /* if old value is ALL (default), need to insert
-                * NODEMAP_CLUSTER_ROLES idx
-                */
-               rc = nodemap_idx_cluster_roles_add(nodemap);
-       else
-               /* otherwise just update existing NODEMAP_CLUSTER_ROLES idx */
-               rc = nodemap_idx_cluster_roles_update(nodemap);
+       rc = nodemap_idx_cluster_roles_modify(nodemap, old_rbac,
+                                             nodemap->nmf_raise_privs,
+                                             nodemap->nmf_rbac_raise);
 
        nm_member_revoke_locks(nodemap);
 put:
@@ -2047,15 +2140,16 @@ EXPORT_SYMBOL(nodemap_set_audit_mode);
  */
 int nodemap_set_forbid_encryption(const char *name, bool forbid_encryption)
 {
-       struct lu_nodemap       *nodemap = NULL;
-       int                     rc = 0;
+       struct lu_nodemap *nodemap = NULL;
+       int rc = 0;
 
        mutex_lock(&active_config_lock);
        nodemap = nodemap_lookup(name);
        mutex_unlock(&active_config_lock);
        if (IS_ERR(nodemap))
                GOTO(out, rc = PTR_ERR(nodemap));
-       if (!allow_op_on_nm(nodemap))
+       if (!check_privs_for_op(nodemap, NODEMAP_RAISE_PRIV_FORBID_ENC,
+                               forbid_encryption))
                GOTO(out_putref, rc = -EPERM);
 
        nodemap->nmf_forbid_encryption = forbid_encryption;
@@ -2070,6 +2164,52 @@ out:
 EXPORT_SYMBOL(nodemap_set_forbid_encryption);
 
 /**
+ * Set the rbac_raise and nmf_rbac_raise properties.
+ * If NODEMAP_RAISE_PRIV_RAISE is not set on parent, it is only possible to
+ * reduce the scope.
+ * \param      name                    nodemap name
+ * \param      privs                   bitfield for privs that can be raised
+ * \param      rbac_raise              bitfield for roles that can be raised
+ * \retval     0 on success
+ *
+ */
+int nodemap_set_raise_privs(const char *name, enum nodemap_raise_privs privs,
+                           enum nodemap_rbac_roles rbac_raise)
+{
+       struct lu_nodemap *nodemap = NULL;
+       enum nodemap_raise_privs old_privs;
+       enum nodemap_rbac_roles old_rbac_raise;
+       int rc = 0;
+
+       mutex_lock(&active_config_lock);
+       nodemap = nodemap_lookup(name);
+       mutex_unlock(&active_config_lock);
+       if (IS_ERR(nodemap))
+               GOTO(out, rc = PTR_ERR(nodemap));
+       if (!check_privs_for_op(nodemap, NODEMAP_RAISE_PRIV_RAISE,
+                               privs | (u64)rbac_raise << 32))
+               GOTO(out_putref, rc = -EPERM);
+
+       old_privs = nodemap->nmf_raise_privs;
+       old_rbac_raise = nodemap->nmf_rbac_raise;
+       /* if value does not change, do nothing */
+       if (privs == old_privs && rbac_raise == old_rbac_raise)
+               GOTO(out_putref, rc = 0);
+
+       nodemap->nmf_raise_privs = privs;
+       nodemap->nmf_rbac_raise = rbac_raise;
+       rc = nodemap_idx_cluster_roles_modify(nodemap, nodemap->nmf_rbac,
+                                             old_privs, old_rbac_raise);
+
+       nm_member_revoke_locks(nodemap);
+out_putref:
+       nodemap_putref(nodemap);
+out:
+       return rc;
+}
+EXPORT_SYMBOL(nodemap_set_raise_privs);
+
+/**
  * Set the nmf_readonly_mount flag to true or false.
  * \param      name                    nodemap name
  * \param      readonly_mount          if true, forbid rw mount
@@ -2086,7 +2226,8 @@ int nodemap_set_readonly_mount(const char *name, bool readonly_mount)
        mutex_unlock(&active_config_lock);
        if (IS_ERR(nodemap))
                GOTO(out, rc = PTR_ERR(nodemap));
-       if (!allow_op_on_nm(nodemap))
+       if (!check_privs_for_op(nodemap, NODEMAP_RAISE_PRIV_RO,
+                               readonly_mount))
                GOTO(out_putref, rc = -EPERM);
 
        nodemap->nmf_readonly_mount = readonly_mount;
@@ -2150,6 +2291,11 @@ int nodemap_add(const char *nodemap_name, bool dynamic)
        }
 
        rc = nodemap_idx_nodemap_add(nodemap);
+       if (rc == 0 &&
+           (nodemap->nmf_rbac != NODEMAP_RBAC_ALL ||
+            nodemap->nmf_raise_privs != NODEMAP_RAISE_PRIV_NONE ||
+            nodemap->nmf_rbac_raise != NODEMAP_RBAC_NONE))
+               rc = nodemap_idx_cluster_roles_add(nodemap);
        if (rc == 0)
                rc = lprocfs_nodemap_register(nodemap, 0);
 
@@ -2923,6 +3069,58 @@ static int cfg_nodemap_cmd(enum lcfg_command_type cmd, const char *nodemap_name,
                rc = nodemap_set_rbac(nodemap_name, rbac);
                break;
        }
+       case LCFG_NODEMAP_RAISE_PRIVS:
+       {
+               enum nodemap_raise_privs privs = NODEMAP_RAISE_PRIV_NONE;
+               enum nodemap_rbac_roles rbac = NODEMAP_RBAC_NONE;
+               char *p;
+
+               if (strcmp(param, "all") == 0) {
+                       privs = NODEMAP_RAISE_PRIV_ALL;
+                       rbac = NODEMAP_RBAC_ALL;
+               } else if (strcmp(param, "none") != 0) {
+                       while ((p = strsep(&param, ",")) != NULL) {
+                               int i;
+
+                               if (!*p)
+                                       break;
+
+                               for (i = 0; i < ARRAY_SIZE(nodemap_priv_names);
+                                    i++) {
+                                       if (strcmp(p,
+                                                nodemap_priv_names[i].npn_name)
+                                           == 0) {
+                                               privs |=
+                                                nodemap_priv_names[i].npn_priv;
+                                               break;
+                                       }
+                               }
+                               if (i != ARRAY_SIZE(nodemap_priv_names))
+                                       continue;
+                               for (i = 0; i < ARRAY_SIZE(nodemap_rbac_names);
+                                    i++) {
+                                       if (strcmp(p,
+                                                nodemap_rbac_names[i].nrn_name)
+                                           == 0) {
+                                               privs |=
+                                                       NODEMAP_RAISE_PRIV_RBAC;
+                                               rbac |=
+                                                nodemap_rbac_names[i].nrn_mode;
+                                               break;
+                                       }
+                               }
+                               if (i == ARRAY_SIZE(nodemap_rbac_names))
+                                       break;
+                       }
+                       if (p) {
+                               rc = -EINVAL;
+                               break;
+                       }
+               }
+
+               rc = nodemap_set_raise_privs(nodemap_name, privs, rbac);
+               break;
+       }
        case LCFG_NODEMAP_TRUSTED:
                rc = kstrtobool(param, &bool_switch);
                if (rc)
@@ -3143,6 +3341,7 @@ int server_iocontrol_nodemap(struct obd_device *obd,
        case LCFG_NODEMAP_MAP_MODE:
        case LCFG_NODEMAP_AUDIT_MODE:
        case LCFG_NODEMAP_FORBID_ENCRYPT:
+       case LCFG_NODEMAP_RAISE_PRIVS:
        case LCFG_NODEMAP_READONLY_MOUNT:
        case LCFG_NODEMAP_DENY_MOUNT:
        case LCFG_NODEMAP_RBAC:
index 138a6b3..eda3a3e 100644 (file)
@@ -790,6 +790,73 @@ static int nodemap_forbid_encryption_seq_show(struct seq_file *m, void *data)
 }
 
 /**
+ * Reads and prints the raise_privs property for the given nodemap.
+ *
+ * \param      m               seq file in proc fs
+ * \param      data            unused
+ * \retval     0               success
+ */
+static int nodemap_raise_privs_seq_show(struct seq_file *m, void *data)
+{
+       struct lu_nodemap *nodemap;
+       char *sep = "";
+       int i, rc;
+
+       mutex_lock(&active_config_lock);
+       nodemap = nodemap_lookup(m->private);
+       mutex_unlock(&active_config_lock);
+       if (IS_ERR(nodemap)) {
+               rc = PTR_ERR(nodemap);
+               CERROR("cannot find nodemap '%s': rc = %d\n",
+                      (char *)m->private, rc);
+               return rc;
+       }
+
+       if (nodemap->nmf_raise_privs == NODEMAP_RAISE_PRIV_ALL) {
+               for (i = 0; i < ARRAY_SIZE(nodemap_priv_names); i++)
+                       seq_printf(m, "%s%s", i == 0 ? "" : ",",
+                                  nodemap_priv_names[i].npn_name);
+               sep = ",";
+       } else if (nodemap->nmf_raise_privs == NODEMAP_RAISE_PRIV_NONE) {
+               seq_puts(m, "none");
+       } else {
+               for (i = 0; i < ARRAY_SIZE(nodemap_priv_names); i++) {
+                       if (nodemap->nmf_raise_privs &
+                           nodemap_priv_names[i].npn_priv) {
+                               seq_printf(m, "%s%s", sep,
+                                          nodemap_priv_names[i].npn_name);
+                               sep = ",";
+                       }
+               }
+       }
+
+       if (!(nodemap->nmf_raise_privs & NODEMAP_RAISE_PRIV_RBAC))
+               goto putref;
+
+       if (nodemap->nmf_rbac_raise == NODEMAP_RBAC_ALL) {
+               for (i = 0; i < ARRAY_SIZE(nodemap_rbac_names); i++) {
+                       seq_printf(m, "%s%s", sep,
+                                  nodemap_rbac_names[i].nrn_name);
+                       sep = ",";
+               }
+       } else if (nodemap->nmf_rbac_raise != NODEMAP_RBAC_NONE) {
+               for (i = 0; i < ARRAY_SIZE(nodemap_rbac_names); i++) {
+                       if (nodemap->nmf_rbac_raise &
+                           nodemap_rbac_names[i].nrn_mode) {
+                               seq_printf(m, "%s%s", sep,
+                                          nodemap_rbac_names[i].nrn_name);
+                               sep = ",";
+                       }
+               }
+       }
+
+putref:
+       seq_puts(m, "\n");
+       nodemap_putref(nodemap);
+       return 0;
+}
+
+/**
  * Reads and prints the readonly_mount flag for the given nodemap.
  *
  * \param      m               seq file in proc fs
@@ -903,6 +970,7 @@ LDEBUGFS_SEQ_FOPS_RO(nodemap_offset);
 LDEBUGFS_SEQ_FOPS_RO(nodemap_rbac);
 LDEBUGFS_SEQ_FOPS_RO(nodemap_audit_mode);
 LDEBUGFS_SEQ_FOPS_RO(nodemap_forbid_encryption);
+LDEBUGFS_SEQ_FOPS_RO(nodemap_raise_privs);
 LDEBUGFS_SEQ_FOPS_RO(nodemap_readonly_mount);
 LDEBUGFS_SEQ_FOPS_RO(nodemap_deny_mount);
 LDEBUGFS_SEQ_FOPS_RO(nodemap_parent);
@@ -975,6 +1043,10 @@ static struct ldebugfs_vars lprocfs_nodemap_vars[] = {
                .fops           = &nodemap_parent_fops,
        },
        {
+               .name           = "child_raise_privileges",
+               .fops           = &nodemap_raise_privs_fops,
+       },
+       {
                .name           = "ranges",
                .fops           = &nodemap_ranges_fops,
        },
@@ -1050,6 +1122,10 @@ static struct ldebugfs_vars lprocfs_default_nodemap_vars[] = {
                .fops           = &nodemap_map_mode_fops,
        },
        {
+               .name           = "child_raise_privileges",
+               .fops           = &nodemap_raise_privs_fops,
+       },
+       {
                .name           = "readonly_mount",
                .fops           = &nodemap_readonly_mount_fops,
        },
index e88bd27..eeaa2f2 100644 (file)
@@ -102,9 +102,9 @@ static void nodemap_cluster_roles_rec_init(union nodemap_rec *nr,
        struct nodemap_cluster_roles_rec *ncrr = &nr->ncrr;
 
        ncrr->ncrr_roles = cpu_to_le64(nodemap->nmf_rbac);
-       ncrr->ncrr_padding1 = 0;
-       ncrr->ncrr_padding2 = 0;
-       ncrr->ncrr_padding3 = 0;
+       ncrr->ncrr_privs = cpu_to_le64(nodemap->nmf_raise_privs);
+       ncrr->ncrr_roles_raise = cpu_to_le64(nodemap->nmf_rbac_raise);
+       ncrr->ncrr_unused1 = 0;
 }
 
 static void nodemap_offset_rec_init(union nodemap_rec *nr,
@@ -1407,8 +1407,12 @@ static int nodemap_cluster_rec_helper(struct nodemap_config *config,
        nodemap->nmf_deny_mount = flags2 & NM_FL2_DENY_MOUNT;
        nodemap->nmf_fileset_use_iam = flags2 & NM_FL2_FILESET_USE_IAM;
 
-       /* by default, and in the absence of cluster_roles, grant all roles */
+       /* by default, and in the absence of cluster_roles, grant all rbac roles
+        * and prevent raising privileges
+        */
        nodemap->nmf_rbac = NODEMAP_RBAC_ALL;
+       nodemap->nmf_raise_privs = NODEMAP_RAISE_PRIV_NONE;
+       nodemap->nmf_rbac_raise = NODEMAP_RBAC_NONE;
 
        /*
         * If the use IAM flag has not been set on the nodemap, a llog-based
@@ -1456,6 +1460,8 @@ static int nodemap_cluster_roles_helper(struct lu_nodemap *nodemap,
                                        const union nodemap_rec *rec)
 {
        nodemap->nmf_rbac = le64_to_cpu(rec->ncrr.ncrr_roles);
+       nodemap->nmf_raise_privs = le64_to_cpu(rec->ncrr.ncrr_privs);
+       nodemap->nmf_rbac_raise = le64_to_cpu(rec->ncrr.ncrr_roles_raise);
 
        return 0;
 }
@@ -1909,9 +1915,11 @@ nodemap_save_config_cache(const struct lu_env *env,
                }
 
                /* only insert NODEMAP_CLUSTER_ROLES idx in saved config cache
-                * if nmf_rbac is not default value NODEMAP_RBAC_ALL
+                * if rbac or raise privs are not the default value
                 */
-               if (nodemap->nmf_rbac != NODEMAP_RBAC_ALL) {
+               if (nodemap->nmf_rbac != NODEMAP_RBAC_ALL ||
+                   nodemap->nmf_raise_privs != NODEMAP_RAISE_PRIV_NONE ||
+                   nodemap->nmf_rbac_raise != NODEMAP_RBAC_NONE) {
                        nodemap_cluster_key_init(&nk, nodemap->nm_id,
                                                 NODEMAP_CLUSTER_ROLES);
                        nodemap_cluster_roles_rec_init(&nr, nodemap);
index 7a82095..efc1d83 100644 (file)
@@ -6369,18 +6369,18 @@ void lustre_assert_wire_constants(void)
                 (long long)(int)offsetof(struct nodemap_cluster_roles_rec, ncrr_roles));
        LASSERTF((int)sizeof(((struct nodemap_cluster_roles_rec *)0)->ncrr_roles) == 8, "found %lld\n",
                 (long long)(int)sizeof(((struct nodemap_cluster_roles_rec *)0)->ncrr_roles));
-       LASSERTF((int)offsetof(struct nodemap_cluster_roles_rec, ncrr_padding1) == 8, "found %lld\n",
-                (long long)(int)offsetof(struct nodemap_cluster_roles_rec, ncrr_padding1));
-       LASSERTF((int)sizeof(((struct nodemap_cluster_roles_rec *)0)->ncrr_padding1) == 8, "found %lld\n",
-                (long long)(int)sizeof(((struct nodemap_cluster_roles_rec *)0)->ncrr_padding1));
-       LASSERTF((int)offsetof(struct nodemap_cluster_roles_rec, ncrr_padding2) == 16, "found %lld\n",
-                (long long)(int)offsetof(struct nodemap_cluster_roles_rec, ncrr_padding2));
-       LASSERTF((int)sizeof(((struct nodemap_cluster_roles_rec *)0)->ncrr_padding2) == 8, "found %lld\n",
-                (long long)(int)sizeof(((struct nodemap_cluster_roles_rec *)0)->ncrr_padding2));
-       LASSERTF((int)offsetof(struct nodemap_cluster_roles_rec, ncrr_padding3) == 24, "found %lld\n",
-                (long long)(int)offsetof(struct nodemap_cluster_roles_rec, ncrr_padding3));
-       LASSERTF((int)sizeof(((struct nodemap_cluster_roles_rec *)0)->ncrr_padding3) == 8, "found %lld\n",
-                (long long)(int)sizeof(((struct nodemap_cluster_roles_rec *)0)->ncrr_padding3));
+       LASSERTF((int)offsetof(struct nodemap_cluster_roles_rec, ncrr_privs) == 8, "found %lld\n",
+                (long long)(int)offsetof(struct nodemap_cluster_roles_rec, ncrr_privs));
+       LASSERTF((int)sizeof(((struct nodemap_cluster_roles_rec *)0)->ncrr_privs) == 8, "found %lld\n",
+                (long long)(int)sizeof(((struct nodemap_cluster_roles_rec *)0)->ncrr_privs));
+       LASSERTF((int)offsetof(struct nodemap_cluster_roles_rec, ncrr_roles_raise) == 16, "found %lld\n",
+                (long long)(int)offsetof(struct nodemap_cluster_roles_rec, ncrr_roles_raise));
+       LASSERTF((int)sizeof(((struct nodemap_cluster_roles_rec *)0)->ncrr_roles_raise) == 8, "found %lld\n",
+                (long long)(int)sizeof(((struct nodemap_cluster_roles_rec *)0)->ncrr_roles_raise));
+       LASSERTF((int)offsetof(struct nodemap_cluster_roles_rec, ncrr_unused1) == 24, "found %lld\n",
+                (long long)(int)offsetof(struct nodemap_cluster_roles_rec, ncrr_unused1));
+       LASSERTF((int)sizeof(((struct nodemap_cluster_roles_rec *)0)->ncrr_unused1) == 8, "found %lld\n",
+                (long long)(int)sizeof(((struct nodemap_cluster_roles_rec *)0)->ncrr_unused1));
 
        /* Checks for struct nodemap_offset_rec */
        LASSERTF((int)sizeof(struct nodemap_offset_rec) == 32, "found %lld\n",
@@ -6554,6 +6554,24 @@ void lustre_assert_wire_constants(void)
                 (unsigned)NODEMAP_RBAC_NONE);
        LASSERTF(NODEMAP_RBAC_ALL == 0xffffffffUL, "found 0x%.8xUL\n",
                (unsigned)NODEMAP_RBAC_ALL);
+       LASSERTF(NODEMAP_RAISE_PRIV_RAISE == 0x00000001UL, "found 0x%.8xUL\n",
+                (unsigned)NODEMAP_RAISE_PRIV_RAISE);
+       LASSERTF(NODEMAP_RAISE_PRIV_ADMIN == 0x00000002UL, "found 0x%.8xUL\n",
+                (unsigned)NODEMAP_RAISE_PRIV_ADMIN);
+       LASSERTF(NODEMAP_RAISE_PRIV_TRUSTED == 0x00000004UL, "found 0x%.8xUL\n",
+                (unsigned)NODEMAP_RAISE_PRIV_TRUSTED);
+       LASSERTF(NODEMAP_RAISE_PRIV_DENY_UNKN == 0x00000008UL, "found 0x%.8xUL\n",
+                (unsigned)NODEMAP_RAISE_PRIV_DENY_UNKN);
+       LASSERTF(NODEMAP_RAISE_PRIV_RO == 0x00000010UL, "found 0x%.8xUL\n",
+                (unsigned)NODEMAP_RAISE_PRIV_RO);
+       LASSERTF(NODEMAP_RAISE_PRIV_RBAC == 0x00000020UL, "found 0x%.8xUL\n",
+                (unsigned)NODEMAP_RAISE_PRIV_RBAC);
+       LASSERTF(NODEMAP_RAISE_PRIV_FORBID_ENC == 0x00000040UL, "found 0x%.8xUL\n",
+                (unsigned)NODEMAP_RAISE_PRIV_FORBID_ENC);
+       LASSERTF(NODEMAP_RAISE_PRIV_NONE == 0xffffff80UL, "found 0x%.8xUL\n",
+                (unsigned)NODEMAP_RAISE_PRIV_NONE);
+       LASSERTF(NODEMAP_RAISE_PRIV_ALL == 0xffffffffUL, "found 0x%.8xUL\n",
+                (unsigned)NODEMAP_RAISE_PRIV_ALL);
 
        /* Checks for struct scrub_file */
        LASSERTF((int)sizeof(struct scrub_file) == 400, "found %lld\n",
@@ -7128,6 +7146,8 @@ void lustre_assert_wire_constants(void)
                (unsigned)LCFG_NODEMAP_RBAC);
        LASSERTF(LCFG_NODEMAP_DENY_MOUNT == 0x000ce060UL, "found 0x%.8xUL\n",
                (unsigned int)LCFG_NODEMAP_DENY_MOUNT);
+       LASSERTF(LCFG_NODEMAP_RAISE_PRIVS == 0x000ce061UL, "found 0x%.8xUL\n",
+                (unsigned)LCFG_NODEMAP_RAISE_PRIVS);
 #endif /* HAVE_SERVER_SUPPORT */
        LASSERTF(PORTALS_CFG_TYPE == 1, "found %lld\n",
                 (long long)PORTALS_CFG_TYPE);
index 2abff1e..055dd7d 100755 (executable)
@@ -7106,7 +7106,7 @@ dyn_nm_helper() {
        local mgsnids2=1.0.0.[1-100]@tcp
        local mgsclid=600
        local mgsfsid=2000
-       local nm=nm_test71a
+       local nm=nm_test72
        local nids=1.1.1.[1-100]@tcp
        local startnid=1.1.1.1@tcp
        local endnid=1.1.1.100@tcp
@@ -7122,6 +7122,7 @@ dyn_nm_helper() {
                          readonly_mount"
        local sepol="1:mls:31:40afb76d077c441b69af58cccaaa2ca63641ed6e21b0a887dc21a684f508b78f"
        local rbac_val
+       local raise
        local val
 
        activedefault=$(do_facet mgs $LCTL get_param -n nodemap.active)
@@ -7134,6 +7135,17 @@ dyn_nm_helper() {
        do_facet mgs $LCTL nodemap_set_fileset --name default \
                --fileset "/deffset" ||
                        error "setting fileset on default failed"
+       raise=$(do_facet mgs $LCTL get_param -n \
+               nodemap.default.child_raise_privileges)
+       if [[ -n "$raise" ]]; then
+               do_facet mgs $LCTL nodemap_modify --name default \
+                   --property child_raise_privileges --value all ||
+                      error "modify raise_privileges for default on MGS failed"
+               wait_nm_sync default child_raise_privileges
+               stack_trap "do_facet mgs $LCTL nodemap_modify --name default \
+                       --property child_raise_privileges --value $raise" EXIT
+       fi
+
        do_facet mgs $LCTL nodemap_add $mgsnm ||
                error "adding $mgsnm on MGS failed"
        stack_trap "do_facet mgs $LCTL nodemap_del $mgsnm" EXIT
@@ -7376,6 +7388,118 @@ test_72b() {
 }
 run_test 72b "dynamic nodemap properties on MDS"
 
+test_72c() {
+       local mgsnm=mgsnm
+       local nm=nm_test72c
+       local val
+
+       (( MDS1_VERSION >= $(version_code 2.16.52) )) ||
+               skip "Need MDS >= 2.16.52 dynamic nodemaps"
+
+       do_facet mgs $LCTL nodemap_add $mgsnm ||
+               error "adding $mgsnm on MGS failed"
+       stack_trap "do_facet mgs $LCTL nodemap_del $mgsnm" EXIT
+
+       do_facet mgs $LCTL nodemap_modify --name $mgsnm \
+               --property child_raise_privileges --value trusted ||
+               error "modify raise_privileges for $mgsnm on MGS failed (1)"
+       do_facet mgs $LCTL nodemap_modify --name $mgsnm \
+               --property admin --value 0 ||
+               error "modify admin for $mgsnm on MGS failed"
+       do_facet mgs $LCTL nodemap_modify --name $mgsnm \
+               --property trusted --value 0 ||
+               error "modify trusted for $mgsnm on MGS failed"
+       do_facet mgs $LCTL nodemap_modify --name $mgsnm \
+               --property deny_unknown --value 0 ||
+               error "modify deny_unknown for $mgsnm on MGS failed"
+       do_facet mgs $LCTL nodemap_modify --name $mgsnm \
+               --property readonly_mount --value 0 ||
+               error "modify readonly_mount for $mgsnm on MGS failed"
+       do_facet mgs $LCTL nodemap_modify --name $mgsnm \
+               --property rbac --value file_perms,quota_ops,byfid_ops ||
+               error "modify rbac for $mgsnm on MGS failed"
+       wait_nm_sync $mgsnm rbac '' inactive
+
+       do_facet mds1 $LCTL nodemap_add -d -p $mgsnm $nm ||
+               error "dynamic nodemap on server failed (1)"
+       stack_trap "do_facet mds1 $LCTL nodemap_del $nm || true" EXIT
+       val=$(do_facet mds1 $LCTL get_param -n nodemap.$nm.id)
+       if [[ -z "$val" || "$val" == "0" ]]; then
+               error "dynamic nodemap wrong id $val (1)"
+       fi
+       val=$(do_facet mds1 $LCTL get_param -n \
+               nodemap.$nm.child_raise_privileges)
+       [[ $val == "trusted" ]] ||
+               error "dyn nodemap should inherit child_raise_privileges"
+       do_facet mds1 $LCTL nodemap_modify --name $nm \
+               --property admin --value 1 &&
+               error "modify admin for $nm on mds1 should fail"
+       do_facet mds1 $LCTL nodemap_modify --name $nm \
+               --property trusted --value 1 ||
+               error "modify trusted for $nm on mds1 failed"
+       do_facet mds1 $LCTL nodemap_modify --name $nm \
+               --property deny_unknown --value 1 ||
+               error "modify deny_unknown for $nm on mds1 failed"
+       do_facet mds1 $LCTL nodemap_modify --name $nm \
+               --property readonly_mount --value 1 ||
+               error "modify readonly_mount for $nm on mds1 failed"
+       do_facet mds1 $LCTL nodemap_modify --name $nm \
+              --property rbac --value file_perms,quota_ops,byfid_ops,dne_ops &&
+               error "modify rbac for $nm on mds1 should fail"
+       do_facet mds1 $LCTL nodemap_modify --name $nm \
+               --property rbac --value file_perms ||
+               error "modify rbac for $nm on mds1 failed (1)"
+       do_facet mds1 $LCTL nodemap_modify --name $nm \
+              --property child_raise_privileges \
+              --value trusted,admin &&
+           error "modify nm.child_raise_privileges for $nm on mds1 should fail"
+
+       do_facet mds1 $LCTL nodemap_del $nm ||
+               error "failed to delete dynamic nodemap $nm"
+
+       do_facet mgs $LCTL nodemap_modify --name $mgsnm \
+               --property child_raise_privileges --value trusted,dne_ops ||
+               error "modify raise_privileges for $mgsnm on MGS failed (2)"
+       wait_nm_sync $mgsnm child_raise_privileges '' inactive
+
+       do_facet mds1 $LCTL nodemap_add -d -p $mgsnm $nm ||
+               error "dynamic nodemap on server failed (2)"
+       val=$(do_facet mds1 $LCTL get_param -n nodemap.$nm.id)
+       if [[ -z "$val" || "$val" == "0" ]]; then
+               error "dynamic nodemap wrong id $val (2)"
+       fi
+       do_facet mds1 $LCTL nodemap_modify --name $nm \
+              --property rbac --value file_perms,quota_ops,byfid_ops,dne_ops ||
+               error "modify rbac for $nm on mds1 failed (2)"
+       do_facet mds1 $LCTL nodemap_modify --name $nm \
+              --property child_raise_privileges \
+              --value trusted ||
+           error "modify nm.child_raise_privileges for $nm on mds1 failed (1)"
+
+       do_facet mds1 $LCTL nodemap_del $nm ||
+               error "failed to delete dynamic nodemap $nm"
+
+       do_facet mgs $LCTL nodemap_modify --name $mgsnm \
+               --property child_raise_privileges \
+               --value child_raise_privs,trusted,dne_ops ||
+               error "modify raise_privileges for $mgsnm on MGS failed (3)"
+       wait_nm_sync $mgsnm child_raise_privileges '' inactive
+
+       do_facet mds1 $LCTL nodemap_add -d -p $mgsnm $nm ||
+               error "dynamic nodemap on server failed (3)"
+       val=$(do_facet mds1 $LCTL get_param -n nodemap.$nm.id)
+       if [[ -z "$val" || "$val" == "0" ]]; then
+               error "dynamic nodemap wrong id $val (3)"
+       fi
+       do_facet mds1 $LCTL nodemap_modify --name $nm \
+              --property child_raise_privileges \
+              --value child_raise_privs,trusted,dne_ops,admin ||
+           error "modify nm.child_raise_privileges for $nm on mds1 failed (2)"
+
+       do_facet mds1 $LCTL get_param -R nodemap.*
+}
+run_test 72c "child_raise_privileges nodemap property"
+
 test_73() {
        local vaultdir1=$DIR/$tdir/vault1
        local vaultdir2=$DIR/$tdir/vault2
index 79beba7..6e2d5da 100644 (file)
@@ -604,7 +604,7 @@ command_t cmdlist[] = {
        {"nodemap_modify", jt_nodemap_modify, 0,
         "modify a nodemap property\n"
         "usage: nodemap_modify --name NODEMAP_NAME --property PROPERTY_NAME{=VALUE| --value VALUE}\n"
-        "valid properties: admin trusted map_mode squash_uid squash_gid squash_projid deny_unknown audit_mode forbid_encryption readonly_mount rbac deny_mount"},
+        "valid properties: admin trusted map_mode squash_uid squash_gid squash_projid deny_unknown audit_mode forbid_encryption readonly_mount rbac deny_mount child_raise_privileges"},
        {"nodemap_add_offset", jt_nodemap_add_offset, 0,
         "add an offset for UID/GID/PROJID mappings\n"
         "usage: nodemap_add_offset --name NODEMAP_NAME --offset OFFSET --limit LIMIT\n"},
index aed7f26..29b1c9b 100644 (file)
@@ -4705,6 +4705,8 @@ int jt_nodemap_modify(int argc, char **argv)
                cmd = LCFG_NODEMAP_AUDIT_MODE;
        } else if (strcmp("forbid_encryption", param) == 0) {
                cmd = LCFG_NODEMAP_FORBID_ENCRYPT;
+       } else if (strcmp("child_raise_privileges", param) == 0) {
+               cmd = LCFG_NODEMAP_RAISE_PRIVS;
        } else if (strcmp("readonly_mount", param) == 0) {
                cmd = LCFG_NODEMAP_READONLY_MOUNT;
        } else if (strcmp("rbac", param) == 0) {
index 9c0a80b..d86e070 100644 (file)
@@ -3016,9 +3016,9 @@ static void check_nodemap_cluster_roles_rec(void)
        BLANK_LINE();
        CHECK_STRUCT(nodemap_cluster_roles_rec);
        CHECK_MEMBER(nodemap_cluster_roles_rec, ncrr_roles);
-       CHECK_MEMBER(nodemap_cluster_roles_rec, ncrr_padding1);
-       CHECK_MEMBER(nodemap_cluster_roles_rec, ncrr_padding2);
-       CHECK_MEMBER(nodemap_cluster_roles_rec, ncrr_padding3);
+       CHECK_MEMBER(nodemap_cluster_roles_rec, ncrr_privs);
+       CHECK_MEMBER(nodemap_cluster_roles_rec, ncrr_roles_raise);
+       CHECK_MEMBER(nodemap_cluster_roles_rec, ncrr_unused1);
 }
 
 static void check_nodemap_fileset_rec(void)
@@ -3100,6 +3100,16 @@ static void check_nodemap_key(void)
        CHECK_VALUE_X(NODEMAP_RBAC_LOCAL_ADMIN);
        CHECK_VALUE_X(NODEMAP_RBAC_NONE);
        CHECK_VALUE_X(NODEMAP_RBAC_ALL);
+
+       CHECK_VALUE_X(NODEMAP_RAISE_PRIV_RAISE);
+       CHECK_VALUE_X(NODEMAP_RAISE_PRIV_ADMIN);
+       CHECK_VALUE_X(NODEMAP_RAISE_PRIV_TRUSTED);
+       CHECK_VALUE_X(NODEMAP_RAISE_PRIV_DENY_UNKN);
+       CHECK_VALUE_X(NODEMAP_RAISE_PRIV_RO);
+       CHECK_VALUE_X(NODEMAP_RAISE_PRIV_RBAC);
+       CHECK_VALUE_X(NODEMAP_RAISE_PRIV_FORBID_ENC);
+       CHECK_VALUE_X(NODEMAP_RAISE_PRIV_NONE);
+       CHECK_VALUE_X(NODEMAP_RAISE_PRIV_ALL);
 }
 
 static void check_scrub_file(void)
@@ -3361,6 +3371,7 @@ check_lustre_cfg(void)
        CHECK_VALUE_X(LCFG_NODEMAP_READONLY_MOUNT);
        CHECK_VALUE_X(LCFG_NODEMAP_RBAC);
        CHECK_VALUE_X(LCFG_NODEMAP_DENY_MOUNT);
+       CHECK_VALUE_X(LCFG_NODEMAP_RAISE_PRIVS);
        printf("#endif /* HAVE_SERVER_SUPPORT */\n");
 #endif /* !HAVE_NATIVE_LINUX_CLIENT */
        CHECK_VALUE(PORTALS_CFG_TYPE);
index f644558..80c2a1d 100644 (file)
@@ -6412,18 +6412,18 @@ void lustre_assert_wire_constants(void)
                 (long long)(int)offsetof(struct nodemap_cluster_roles_rec, ncrr_roles));
        LASSERTF((int)sizeof(((struct nodemap_cluster_roles_rec *)0)->ncrr_roles) == 8, "found %lld\n",
                 (long long)(int)sizeof(((struct nodemap_cluster_roles_rec *)0)->ncrr_roles));
-       LASSERTF((int)offsetof(struct nodemap_cluster_roles_rec, ncrr_padding1) == 8, "found %lld\n",
-                (long long)(int)offsetof(struct nodemap_cluster_roles_rec, ncrr_padding1));
-       LASSERTF((int)sizeof(((struct nodemap_cluster_roles_rec *)0)->ncrr_padding1) == 8, "found %lld\n",
-                (long long)(int)sizeof(((struct nodemap_cluster_roles_rec *)0)->ncrr_padding1));
-       LASSERTF((int)offsetof(struct nodemap_cluster_roles_rec, ncrr_padding2) == 16, "found %lld\n",
-                (long long)(int)offsetof(struct nodemap_cluster_roles_rec, ncrr_padding2));
-       LASSERTF((int)sizeof(((struct nodemap_cluster_roles_rec *)0)->ncrr_padding2) == 8, "found %lld\n",
-                (long long)(int)sizeof(((struct nodemap_cluster_roles_rec *)0)->ncrr_padding2));
-       LASSERTF((int)offsetof(struct nodemap_cluster_roles_rec, ncrr_padding3) == 24, "found %lld\n",
-                (long long)(int)offsetof(struct nodemap_cluster_roles_rec, ncrr_padding3));
-       LASSERTF((int)sizeof(((struct nodemap_cluster_roles_rec *)0)->ncrr_padding3) == 8, "found %lld\n",
-                (long long)(int)sizeof(((struct nodemap_cluster_roles_rec *)0)->ncrr_padding3));
+       LASSERTF((int)offsetof(struct nodemap_cluster_roles_rec, ncrr_privs) == 8, "found %lld\n",
+                (long long)(int)offsetof(struct nodemap_cluster_roles_rec, ncrr_privs));
+       LASSERTF((int)sizeof(((struct nodemap_cluster_roles_rec *)0)->ncrr_privs) == 8, "found %lld\n",
+                (long long)(int)sizeof(((struct nodemap_cluster_roles_rec *)0)->ncrr_privs));
+       LASSERTF((int)offsetof(struct nodemap_cluster_roles_rec, ncrr_roles_raise) == 16, "found %lld\n",
+                (long long)(int)offsetof(struct nodemap_cluster_roles_rec, ncrr_roles_raise));
+       LASSERTF((int)sizeof(((struct nodemap_cluster_roles_rec *)0)->ncrr_roles_raise) == 8, "found %lld\n",
+                (long long)(int)sizeof(((struct nodemap_cluster_roles_rec *)0)->ncrr_roles_raise));
+       LASSERTF((int)offsetof(struct nodemap_cluster_roles_rec, ncrr_unused1) == 24, "found %lld\n",
+                (long long)(int)offsetof(struct nodemap_cluster_roles_rec, ncrr_unused1));
+       LASSERTF((int)sizeof(((struct nodemap_cluster_roles_rec *)0)->ncrr_unused1) == 8, "found %lld\n",
+                (long long)(int)sizeof(((struct nodemap_cluster_roles_rec *)0)->ncrr_unused1));
 
        /* Checks for struct nodemap_offset_rec */
        LASSERTF((int)sizeof(struct nodemap_offset_rec) == 32, "found %lld\n",
@@ -6597,6 +6597,24 @@ void lustre_assert_wire_constants(void)
                 (unsigned)NODEMAP_RBAC_NONE);
        LASSERTF(NODEMAP_RBAC_ALL == 0xffffffffUL, "found 0x%.8xUL\n",
                (unsigned)NODEMAP_RBAC_ALL);
+       LASSERTF(NODEMAP_RAISE_PRIV_RAISE == 0x00000001UL, "found 0x%.8xUL\n",
+                (unsigned)NODEMAP_RAISE_PRIV_RAISE);
+       LASSERTF(NODEMAP_RAISE_PRIV_ADMIN == 0x00000002UL, "found 0x%.8xUL\n",
+                (unsigned)NODEMAP_RAISE_PRIV_ADMIN);
+       LASSERTF(NODEMAP_RAISE_PRIV_TRUSTED == 0x00000004UL, "found 0x%.8xUL\n",
+                (unsigned)NODEMAP_RAISE_PRIV_TRUSTED);
+       LASSERTF(NODEMAP_RAISE_PRIV_DENY_UNKN == 0x00000008UL, "found 0x%.8xUL\n",
+                (unsigned)NODEMAP_RAISE_PRIV_DENY_UNKN);
+       LASSERTF(NODEMAP_RAISE_PRIV_RO == 0x00000010UL, "found 0x%.8xUL\n",
+                (unsigned)NODEMAP_RAISE_PRIV_RO);
+       LASSERTF(NODEMAP_RAISE_PRIV_RBAC == 0x00000020UL, "found 0x%.8xUL\n",
+                (unsigned)NODEMAP_RAISE_PRIV_RBAC);
+       LASSERTF(NODEMAP_RAISE_PRIV_FORBID_ENC == 0x00000040UL, "found 0x%.8xUL\n",
+                (unsigned)NODEMAP_RAISE_PRIV_FORBID_ENC);
+       LASSERTF(NODEMAP_RAISE_PRIV_NONE == 0xffffff80UL, "found 0x%.8xUL\n",
+                (unsigned)NODEMAP_RAISE_PRIV_NONE);
+       LASSERTF(NODEMAP_RAISE_PRIV_ALL == 0xffffffffUL, "found 0x%.8xUL\n",
+                (unsigned)NODEMAP_RAISE_PRIV_ALL);
 
        /* Checks for struct scrub_file */
        LASSERTF((int)sizeof(struct scrub_file) == 400, "found %lld\n",
@@ -7171,6 +7189,8 @@ void lustre_assert_wire_constants(void)
                (unsigned)LCFG_NODEMAP_RBAC);
        LASSERTF(LCFG_NODEMAP_DENY_MOUNT == 0x000ce060UL, "found 0x%.8xUL\n",
                (unsigned int)LCFG_NODEMAP_DENY_MOUNT);
+       LASSERTF(LCFG_NODEMAP_RAISE_PRIVS == 0x000ce061UL, "found 0x%.8xUL\n",
+                (unsigned)LCFG_NODEMAP_RAISE_PRIVS);
 #endif /* HAVE_SERVER_SUPPORT */
        LASSERTF(PORTALS_CFG_TYPE == 1, "found %lld\n",
                 (long long)PORTALS_CFG_TYPE);