return 0;
}
EXPORT_SYMBOL(nodemap_test_id);
+
+static int cfg_nodemap_cmd(enum lcfg_command_type cmd, const char *nodemap_name,
+ char *param, bool dynamic)
+{
+ struct lnet_nid nid[2];
+ bool bool_switch;
+ u8 netmask = 0;
+ u32 idmap[2];
+ u32 int_id;
+ int rc = 0;
+
+ ENTRY;
+ switch (cmd) {
+ case LCFG_NODEMAP_ADD:
+ rc = nodemap_add(nodemap_name);
+ break;
+ case LCFG_NODEMAP_DEL:
+ rc = nodemap_del(nodemap_name);
+ break;
+ case LCFG_NODEMAP_ADD_RANGE:
+ rc = nodemap_parse_range(param, nid, &netmask);
+ if (rc != 0)
+ break;
+ rc = nodemap_add_range(nodemap_name, nid, netmask);
+ break;
+ case LCFG_NODEMAP_DEL_RANGE:
+ rc = nodemap_parse_range(param, nid, &netmask);
+ if (rc != 0)
+ break;
+ rc = nodemap_del_range(nodemap_name, nid, netmask);
+ break;
+ case LCFG_NODEMAP_ADMIN:
+ rc = kstrtobool(param, &bool_switch);
+ if (rc)
+ break;
+ rc = nodemap_set_allow_root(nodemap_name, bool_switch);
+ break;
+ case LCFG_NODEMAP_DENY_UNKNOWN:
+ rc = kstrtobool(param, &bool_switch);
+ if (rc)
+ break;
+ rc = nodemap_set_deny_unknown(nodemap_name, bool_switch);
+ break;
+ case LCFG_NODEMAP_AUDIT_MODE:
+ rc = kstrtobool(param, &bool_switch);
+ if (rc == 0)
+ rc = nodemap_set_audit_mode(nodemap_name, bool_switch);
+ break;
+ case LCFG_NODEMAP_FORBID_ENCRYPT:
+ rc = kstrtobool(param, &bool_switch);
+ if (rc == 0)
+ rc = nodemap_set_forbid_encryption(nodemap_name,
+ bool_switch);
+ break;
+ case LCFG_NODEMAP_READONLY_MOUNT:
+ rc = kstrtobool(param, &bool_switch);
+ if (rc == 0)
+ rc = nodemap_set_readonly_mount(nodemap_name,
+ bool_switch);
+ break;
+ case LCFG_NODEMAP_MAP_MODE:
+ {
+ char *p;
+ __u8 map_mode = 0;
+
+ if ((p = strstr(param, "all")) != NULL) {
+ if ((p == param || *(p-1) == ',') &&
+ (*(p+3) == '\0' || *(p+3) == ',')) {
+ map_mode = NODEMAP_MAP_ALL;
+ } else {
+ rc = -EINVAL;
+ break;
+ }
+ } else {
+ while ((p = strsep(¶m, ",")) != NULL) {
+ if (!*p)
+ break;
+
+ if (strcmp("both", p) == 0)
+ map_mode |= NODEMAP_MAP_BOTH;
+ else if (strcmp("uid_only", p) == 0 ||
+ strcmp("uid", p) == 0)
+ map_mode |= NODEMAP_MAP_UID;
+ else if (strcmp("gid_only", p) == 0 ||
+ strcmp("gid", p) == 0)
+ map_mode |= NODEMAP_MAP_GID;
+ else if (strcmp("projid_only", p) == 0 ||
+ strcmp("projid", p) == 0)
+ map_mode |= NODEMAP_MAP_PROJID;
+ else
+ break;
+ }
+ if (p) {
+ rc = -EINVAL;
+ break;
+ }
+ }
+
+ rc = nodemap_set_mapping_mode(nodemap_name, map_mode);
+ break;
+ }
+ case LCFG_NODEMAP_RBAC:
+ {
+ enum nodemap_rbac_roles rbac;
+ char *p;
+
+ if (strcmp(param, "all") == 0) {
+ rbac = NODEMAP_RBAC_ALL;
+ } else if (strcmp(param, "none") == 0) {
+ rbac = NODEMAP_RBAC_NONE;
+ } else {
+ rbac = NODEMAP_RBAC_NONE;
+ while ((p = strsep(¶m, ",")) != NULL) {
+ int i;
+
+ if (!*p)
+ break;
+
+ for (i = 0; i < ARRAY_SIZE(nodemap_rbac_names);
+ i++) {
+ if (strcmp(p,
+ nodemap_rbac_names[i].nrn_name)
+ == 0) {
+ rbac |=
+ nodemap_rbac_names[i].nrn_mode;
+ break;
+ }
+ }
+ if (i == ARRAY_SIZE(nodemap_rbac_names))
+ break;
+ }
+ if (p) {
+ rc = -EINVAL;
+ break;
+ }
+ }
+
+ rc = nodemap_set_rbac(nodemap_name, rbac);
+ break;
+ }
+ case LCFG_NODEMAP_TRUSTED:
+ rc = kstrtobool(param, &bool_switch);
+ if (rc)
+ break;
+ rc = nodemap_set_trust_client_ids(nodemap_name, bool_switch);
+ break;
+ case LCFG_NODEMAP_SQUASH_UID:
+ rc = kstrtouint(param, 10, &int_id);
+ if (rc)
+ break;
+ rc = nodemap_set_squash_uid(nodemap_name, int_id);
+ break;
+ case LCFG_NODEMAP_SQUASH_GID:
+ rc = kstrtouint(param, 10, &int_id);
+ if (rc)
+ break;
+ rc = nodemap_set_squash_gid(nodemap_name, int_id);
+ break;
+ case LCFG_NODEMAP_SQUASH_PROJID:
+ rc = kstrtouint(param, 10, &int_id);
+ if (rc)
+ break;
+ rc = nodemap_set_squash_projid(nodemap_name, int_id);
+ break;
+ case LCFG_NODEMAP_ADD_UIDMAP:
+ case LCFG_NODEMAP_ADD_GIDMAP:
+ case LCFG_NODEMAP_ADD_PROJIDMAP:
+ rc = nodemap_parse_idmap(param, idmap);
+ if (rc != 0)
+ break;
+ if (cmd == LCFG_NODEMAP_ADD_UIDMAP)
+ rc = nodemap_add_idmap(nodemap_name, NODEMAP_UID,
+ idmap);
+ else if (cmd == LCFG_NODEMAP_ADD_GIDMAP)
+ rc = nodemap_add_idmap(nodemap_name, NODEMAP_GID,
+ idmap);
+ else if (cmd == LCFG_NODEMAP_ADD_PROJIDMAP)
+ rc = nodemap_add_idmap(nodemap_name, NODEMAP_PROJID,
+ idmap);
+ else
+ rc = -EINVAL;
+ break;
+ case LCFG_NODEMAP_DEL_UIDMAP:
+ case LCFG_NODEMAP_DEL_GIDMAP:
+ case LCFG_NODEMAP_DEL_PROJIDMAP:
+ rc = nodemap_parse_idmap(param, idmap);
+ if (rc != 0)
+ break;
+ if (cmd == LCFG_NODEMAP_DEL_UIDMAP)
+ rc = nodemap_del_idmap(nodemap_name, NODEMAP_UID,
+ idmap);
+ else if (cmd == LCFG_NODEMAP_DEL_GIDMAP)
+ rc = nodemap_del_idmap(nodemap_name, NODEMAP_GID,
+ idmap);
+ else if (cmd == LCFG_NODEMAP_DEL_PROJIDMAP)
+ rc = nodemap_del_idmap(nodemap_name, NODEMAP_PROJID,
+ idmap);
+ else
+ rc = -EINVAL;
+ break;
+ case LCFG_NODEMAP_SET_FILESET:
+ rc = nodemap_set_fileset(nodemap_name, param);
+ break;
+ case LCFG_NODEMAP_SET_SEPOL:
+ rc = nodemap_set_sepol(nodemap_name, param);
+ break;
+ default:
+ rc = -EINVAL;
+ }
+
+ RETURN(rc);
+}
+
+int server_iocontrol_nodemap(struct obd_device *obd,
+ struct obd_ioctl_data *data, bool dynamic)
+{
+ char name_buf[LUSTRE_NODEMAP_NAME_LENGTH + 1];
+ struct lustre_cfg *lcfg = NULL;
+ const char *nodemap_name = NULL;
+ const char *client_idstr = NULL;
+ const char *idtype_str = NULL;
+ const char *nidstr = NULL;
+ unsigned long client_id;
+ struct lnet_nid nid;
+ char *param = NULL;
+ char fs_idstr[16];
+ __u32 fs_id, cmd;
+ int idtype;
+ int rc = 0;
+
+ ENTRY;
+
+ if (data->ioc_plen1 > PAGE_SIZE)
+ GOTO(out, rc = -E2BIG);
+
+ OBD_ALLOC(lcfg, data->ioc_plen1);
+ if (lcfg == NULL)
+ GOTO(out, rc = -ENOMEM);
+
+ if (copy_from_user(lcfg, data->ioc_pbuf1, data->ioc_plen1))
+ GOTO(out_lcfg, rc = -EFAULT);
+
+ cmd = lcfg->lcfg_command;
+
+ switch (cmd) {
+ case LCFG_NODEMAP_ACTIVATE:
+ if (lcfg->lcfg_bufcount != 2)
+ GOTO(out_lcfg, rc = -EINVAL);
+ param = lustre_cfg_string(lcfg, 1);
+ if (strcmp(param, "1") == 0)
+ nodemap_activate(1);
+ else
+ nodemap_activate(0);
+ break;
+ case LCFG_NODEMAP_ADD:
+ case LCFG_NODEMAP_DEL:
+ if (lcfg->lcfg_bufcount != 2)
+ GOTO(out_lcfg, rc = -EINVAL);
+ nodemap_name = lustre_cfg_string(lcfg, 1);
+ rc = cfg_nodemap_cmd(cmd, nodemap_name, param, dynamic);
+ break;
+ case LCFG_NODEMAP_TEST_NID:
+ if (lcfg->lcfg_bufcount != 2)
+ GOTO(out_lcfg, rc = -EINVAL);
+ nidstr = lustre_cfg_string(lcfg, 1);
+ rc = libcfs_strnid(&nid, nidstr);
+ if (rc < 0)
+ GOTO(out_lcfg, rc);
+
+ nodemap_test_nid(&nid, name_buf, sizeof(name_buf));
+ rc = copy_to_user(data->ioc_pbuf1, name_buf,
+ min_t(size_t, data->ioc_plen1,
+ sizeof(name_buf)));
+ if (rc != 0)
+ GOTO(out_lcfg, rc = -EFAULT);
+ break;
+ case LCFG_NODEMAP_TEST_ID:
+ if (lcfg->lcfg_bufcount != 4)
+ GOTO(out_lcfg, rc = -EINVAL);
+ nidstr = lustre_cfg_string(lcfg, 1);
+ idtype_str = lustre_cfg_string(lcfg, 2);
+ client_idstr = lustre_cfg_string(lcfg, 3);
+
+ rc = libcfs_strnid(&nid, nidstr);
+ if (rc < 0)
+ GOTO(out_lcfg, rc);
+
+ if (strcmp(idtype_str, "uid") == 0)
+ idtype = NODEMAP_UID;
+ else if (strcmp(idtype_str, "gid") == 0)
+ idtype = NODEMAP_GID;
+ else if (strcmp(idtype_str, "projid") == 0)
+ idtype = NODEMAP_PROJID;
+ else
+ GOTO(out_lcfg, rc = -EINVAL);
+
+ rc = kstrtoul(client_idstr, 10, &client_id);
+ if (rc != 0)
+ GOTO(out_lcfg, rc = -EINVAL);
+
+ rc = nodemap_test_id(&nid, idtype, client_id, &fs_id);
+ if (rc < 0)
+ GOTO(out_lcfg, rc = -EINVAL);
+
+ if (data->ioc_plen1 < sizeof(fs_idstr))
+ GOTO(out_lcfg, rc = -EINVAL);
+
+ snprintf(fs_idstr, sizeof(fs_idstr), "%u", fs_id);
+ if (copy_to_user(data->ioc_pbuf1, fs_idstr,
+ sizeof(fs_idstr)) != 0)
+ GOTO(out_lcfg, rc = -EINVAL);
+ break;
+ case LCFG_NODEMAP_ADD_RANGE:
+ case LCFG_NODEMAP_DEL_RANGE:
+ case LCFG_NODEMAP_ADD_UIDMAP:
+ case LCFG_NODEMAP_DEL_UIDMAP:
+ case LCFG_NODEMAP_ADD_GIDMAP:
+ case LCFG_NODEMAP_DEL_GIDMAP:
+ case LCFG_NODEMAP_ADD_PROJIDMAP:
+ case LCFG_NODEMAP_DEL_PROJIDMAP:
+ case LCFG_NODEMAP_SET_FILESET:
+ case LCFG_NODEMAP_SET_SEPOL:
+ if (lcfg->lcfg_bufcount != 3)
+ GOTO(out_lcfg, rc = -EINVAL);
+ nodemap_name = lustre_cfg_string(lcfg, 1);
+ param = lustre_cfg_string(lcfg, 2);
+ rc = cfg_nodemap_cmd(cmd, nodemap_name, param, dynamic);
+ break;
+ case LCFG_NODEMAP_ADMIN:
+ case LCFG_NODEMAP_TRUSTED:
+ case LCFG_NODEMAP_DENY_UNKNOWN:
+ case LCFG_NODEMAP_SQUASH_UID:
+ case LCFG_NODEMAP_SQUASH_GID:
+ case LCFG_NODEMAP_SQUASH_PROJID:
+ case LCFG_NODEMAP_MAP_MODE:
+ case LCFG_NODEMAP_AUDIT_MODE:
+ case LCFG_NODEMAP_FORBID_ENCRYPT:
+ case LCFG_NODEMAP_READONLY_MOUNT:
+ case LCFG_NODEMAP_RBAC:
+ if (lcfg->lcfg_bufcount != 4)
+ GOTO(out_lcfg, rc = -EINVAL);
+ nodemap_name = lustre_cfg_string(lcfg, 1);
+ param = lustre_cfg_string(lcfg, 3);
+ rc = cfg_nodemap_cmd(cmd, nodemap_name, param, dynamic);
+ break;
+ default:
+ rc = -ENOTTY;
+ }
+
+ if (rc) {
+ CDEBUG_LIMIT(rc == -EEXIST ? D_INFO : D_ERROR,
+ "%s: OBD_IOC_NODEMAP command %X for %s: rc = %d\n",
+ obd->obd_name, lcfg->lcfg_command,
+ nodemap_name, rc);
+ GOTO(out_lcfg, rc);
+ }
+
+out_lcfg:
+ OBD_FREE(lcfg, data->ioc_plen1);
+out:
+ RETURN(rc);
+}
+EXPORT_SYMBOL(server_iocontrol_nodemap);