Whamcloud - gitweb
LU-3527 nodemap: idmap management functions
[fs/lustre-release.git] / lustre / nodemap / nodemap_handler.c
index 89e7aec..ae814d4 100644 (file)
@@ -40,7 +40,7 @@ struct proc_dir_entry *proc_lustre_nodemap_root;
 static atomic_t nodemap_highest_id;
 
 /* Simple flag to determine if nodemaps are active */
-bool nodemap_idmap_active;
+bool nodemap_active;
 
 /**
  * pointer to default nodemap kept to keep from
@@ -70,6 +70,8 @@ static void nodemap_destroy(struct lu_nodemap *nodemap)
                range_delete(range);
        }
 
+       idmap_delete_tree(nodemap);
+
        lprocfs_remove(&nodemap->nm_proc_entry);
        OBD_FREE_PTR(nodemap);
 }
@@ -271,7 +273,7 @@ struct lu_nodemap *nodemap_classify_nid(lnet_nid_t nid)
 }
 EXPORT_SYMBOL(nodemap_classify_nid);
 
-/*
+/**
  * simple check for default nodemap
  */
 static bool is_default_nodemap(const struct lu_nodemap *nodemap)
@@ -279,7 +281,7 @@ static bool is_default_nodemap(const struct lu_nodemap *nodemap)
        return nodemap->nm_id == 0;
 }
 
-/*
+/**
  * parse a nodemap range string into two nids
  *
  * \param      range_str               string to parse
@@ -311,6 +313,172 @@ out:
 }
 EXPORT_SYMBOL(nodemap_parse_range);
 
+/**
+ * parse a string containing an id map of form "client_id:filesystem_id"
+ * into an array of __u32 * for use in mapping functions
+ *
+ * \param      idmap_str               map string
+ * \param      idmap                   array[2] of __u32
+ *
+ * \retval     0 on success
+ */
+int nodemap_parse_idmap(const char *idmap_str, __u32 idmap[2])
+{
+       char    *end;
+
+       if (idmap_str == NULL)
+               return -EINVAL;
+
+       idmap[0] = simple_strtoul(idmap_str, &end, 10);
+       if (end == idmap_str || *end != ':')
+               return -EINVAL;
+
+       idmap_str = end + 1;
+       idmap[1] = simple_strtoul(idmap_str, &end, 10);
+       if (end == idmap_str)
+               return -EINVAL;
+
+       return 0;
+}
+EXPORT_SYMBOL(nodemap_parse_idmap);
+
+/**
+ * add an idmap to the proper nodemap trees
+ *
+ * \param      name            name of nodemap
+ * \param      id_type         NODEMAP_UID or NODEMAP_GID
+ * \param      map             array[2] __u32 containing the mapA values
+ *                             map[0] is client id
+ *                             map[1] is the filesystem id
+ *
+ * \retval     0 on success
+ */
+int nodemap_add_idmap(const char *name, enum nodemap_id_type id_type,
+                     const __u32 map[2])
+{
+       struct lu_nodemap       *nodemap = NULL;
+       struct lu_idmap         *idmap;
+       int                     rc = 0;
+
+       rc = nodemap_lookup(name, &nodemap);
+       if (nodemap == NULL || is_default_nodemap(nodemap))
+               GOTO(out, rc = -EINVAL);
+
+       idmap = idmap_create(map[0], map[1]);
+       if (idmap == NULL)
+               GOTO(out_putref, rc = -ENOMEM);
+
+       idmap_insert(id_type, idmap, nodemap);
+
+out_putref:
+       nodemap_putref(nodemap);
+out:
+       return rc;
+}
+EXPORT_SYMBOL(nodemap_add_idmap);
+
+/**
+ * delete idmap from proper nodemap tree
+ *
+ * \param      name            name of nodemap
+ * \param      id_type         NODEMAP_UID or NODEMAP_GID
+ * \param      map             array[2] __u32 containing the mapA values
+ *                             map[0] is client id
+ *                             map[1] is the filesystem id
+ *
+ * \retval     0 on success
+ */
+int nodemap_del_idmap(const char *name, enum nodemap_id_type id_type,
+                     const __u32 map[2])
+{
+       struct lu_nodemap       *nodemap = NULL;
+       struct lu_idmap         *idmap = NULL;
+       int                     rc = 0;
+
+       rc = nodemap_lookup(name, &nodemap);
+       if (nodemap == NULL || is_default_nodemap(nodemap))
+               GOTO(out, rc = -EINVAL);
+
+       idmap = idmap_search(nodemap, NODEMAP_CLIENT_TO_FS, id_type,
+                            map[0]);
+       if (idmap == NULL)
+               GOTO(out_putref, rc = -EINVAL);
+
+       idmap_delete(id_type, idmap, nodemap);
+
+out_putref:
+       nodemap_putref(nodemap);
+out:
+       return rc;
+}
+EXPORT_SYMBOL(nodemap_del_idmap);
+
+/**
+ * mapping function for nodemap idmaps
+ *
+ * \param      nodemap         lu_nodemap structure defining nodemap
+ * \param      node_type       NODEMAP_UID or NODEMAP_GID
+ * \param      tree_type       NODEMAP_CLIENT_TO_FS or
+ *                             NODEMAP_FS_TO_CLIENT
+ * \param      id              id to map
+ *
+ * \retval     mapped id according to the rules below.
+ *
+ * if the nodemap_active is false, just return the passed id without mapping
+ *
+ * if the id to be looked up in 0, check that root access is allowed and if it
+ * is, return 0. Otherwise, return the squash uid or gid.
+ *
+ * if the nodemap is configured to trusted the ids from the client system, just
+ * return the passwd id without mapping.
+ *
+ * if by this point, we haven't returned and the nodemap in question is the
+ * default nodemap, return the dquash uid or gid.
+ *
+ * after these checks, search the proper tree for the mapping, and if found
+ * return the mapped value, otherwise return the squash uid or gid.
+ */
+__u32 nodemap_map_id(struct lu_nodemap *nodemap,
+                    enum nodemap_id_type id_type,
+                    enum nodemap_tree_type tree_type, __u32 id)
+{
+       struct lu_idmap         *idmap = NULL;
+
+       if (!nodemap_active)
+               goto out;
+
+       if (id == 0) {
+               if (nodemap->nmf_allow_root_access)
+                       goto out;
+               else
+                       goto squash;
+       }
+
+       if (nodemap->nmf_trust_client_ids)
+               goto out;
+
+       if (is_default_nodemap(nodemap))
+               goto squash;
+
+       idmap = idmap_search(nodemap, tree_type, id_type, id);
+       if (idmap == NULL)
+               goto squash;
+
+       if (tree_type == NODEMAP_FS_TO_CLIENT)
+               return idmap->id_client;
+
+       return idmap->id_fs;
+
+squash:
+       if (id_type == NODEMAP_UID)
+               return nodemap->nm_squash_uid;
+       else
+               return nodemap->nm_squash_gid;
+out:
+       return id;
+}
+EXPORT_SYMBOL(nodemap_map_id);
+
 /*
  * add nid range to nodemap
  * \param      name            nodemap name
@@ -425,10 +593,10 @@ static int nodemap_create(const char *name, bool is_default)
        snprintf(nodemap->nm_name, sizeof(nodemap->nm_name), "%s", name);
 
        INIT_LIST_HEAD(&(nodemap->nm_ranges));
-       nodemap->nm_local_to_remote_uidmap = RB_ROOT;
-       nodemap->nm_remote_to_local_uidmap = RB_ROOT;
-       nodemap->nm_local_to_remote_gidmap = RB_ROOT;
-       nodemap->nm_remote_to_local_gidmap = RB_ROOT;
+       nodemap->nm_fs_to_client_uidmap = RB_ROOT;
+       nodemap->nm_client_to_fs_uidmap = RB_ROOT;
+       nodemap->nm_fs_to_client_gidmap = RB_ROOT;
+       nodemap->nm_client_to_fs_gidmap = RB_ROOT;
 
        if (is_default) {
                nodemap->nm_id = LUSTRE_NODEMAP_DEFAULT_ID;
@@ -470,7 +638,7 @@ out:
        return rc;
 }
 
-/*
+/**
  * update flag to turn on or off nodemap functions
  * \param      name            nodemap name
  * \param      admin_string    string containing updated value
@@ -617,6 +785,17 @@ out:
 EXPORT_SYMBOL(nodemap_del);
 
 /**
+ * activate nodemap functions
+ *
+ * \param      value           1 for on, 0 for off
+ */
+void nodemap_activate(const bool value)
+{
+       nodemap_active = value;
+}
+EXPORT_SYMBOL(nodemap_activate);
+
+/**
  * Cleanup nodemap module on exit
  */
 static void nodemap_mod_exit(void)