1185029Spjd/* 2185029Spjd * CDDL HEADER START 3185029Spjd * 4185029Spjd * The contents of this file are subject to the terms of the 5185029Spjd * Common Development and Distribution License (the "License"). 6185029Spjd * You may not use this file except in compliance with the License. 7185029Spjd * 8185029Spjd * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9185029Spjd * or http://www.opensolaris.org/os/licensing. 10185029Spjd * See the License for the specific language governing permissions 11185029Spjd * and limitations under the License. 12185029Spjd * 13185029Spjd * When distributing Covered Code, include this CDDL HEADER in each 14185029Spjd * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15185029Spjd * If applicable, add the following below this CDDL HEADER, with the 16185029Spjd * fields enclosed by brackets "[]" replaced with your own identifying 17185029Spjd * information: Portions Copyright [yyyy] [name of copyright owner] 18185029Spjd * 19185029Spjd * CDDL HEADER END 20185029Spjd */ 21185029Spjd/* 22219089Spjd * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. 23219089Spjd * Copyright 2010 Nexenta Systems, Inc. All rights reserved. 24185029Spjd */ 25185029Spjd 26185029Spjd#if defined(_KERNEL) 27185029Spjd#include <sys/systm.h> 28185029Spjd#include <sys/sunddi.h> 29185029Spjd#include <sys/ctype.h> 30185029Spjd#else 31185029Spjd#include <stdio.h> 32185029Spjd#include <unistd.h> 33185029Spjd#include <strings.h> 34185029Spjd#include <libnvpair.h> 35185029Spjd#include <ctype.h> 36185029Spjd#endif 37185029Spjd/* XXX includes zfs_context.h, so why bother with the above? */ 38185029Spjd#include <sys/dsl_deleg.h> 39185029Spjd#include "zfs_prop.h" 40185029Spjd#include "zfs_deleg.h" 41185029Spjd#include "zfs_namecheck.h" 42185029Spjd 43185029Spjd/* 44185029Spjd * permission table 45185029Spjd * 46185029Spjd * Keep this table in sorted order 47185029Spjd * 48185029Spjd * This table is used for displaying all permissions for 49185029Spjd * zfs allow 50185029Spjd */ 51185029Spjd 52185029Spjdzfs_deleg_perm_tab_t zfs_deleg_perm_tab[] = { 53185029Spjd {ZFS_DELEG_PERM_ALLOW, ZFS_DELEG_NOTE_ALLOW}, 54185029Spjd {ZFS_DELEG_PERM_CLONE, ZFS_DELEG_NOTE_CLONE }, 55185029Spjd {ZFS_DELEG_PERM_CREATE, ZFS_DELEG_NOTE_CREATE }, 56185029Spjd {ZFS_DELEG_PERM_DESTROY, ZFS_DELEG_NOTE_DESTROY }, 57185029Spjd {ZFS_DELEG_PERM_MOUNT, ZFS_DELEG_NOTE_MOUNT }, 58185029Spjd {ZFS_DELEG_PERM_PROMOTE, ZFS_DELEG_NOTE_PROMOTE }, 59185029Spjd {ZFS_DELEG_PERM_RECEIVE, ZFS_DELEG_NOTE_RECEIVE }, 60185029Spjd {ZFS_DELEG_PERM_RENAME, ZFS_DELEG_NOTE_RENAME }, 61185029Spjd {ZFS_DELEG_PERM_ROLLBACK, ZFS_DELEG_NOTE_ROLLBACK }, 62185029Spjd {ZFS_DELEG_PERM_SNAPSHOT, ZFS_DELEG_NOTE_SNAPSHOT }, 63185029Spjd {ZFS_DELEG_PERM_SHARE, ZFS_DELEG_NOTE_SHARE }, 64219089Spjd {ZFS_DELEG_PERM_SEND, ZFS_DELEG_NOTE_SEND }, 65185029Spjd {ZFS_DELEG_PERM_USERPROP, ZFS_DELEG_NOTE_USERPROP }, 66209962Smm {ZFS_DELEG_PERM_USERQUOTA, ZFS_DELEG_NOTE_USERQUOTA }, 67209962Smm {ZFS_DELEG_PERM_GROUPQUOTA, ZFS_DELEG_NOTE_GROUPQUOTA }, 68209962Smm {ZFS_DELEG_PERM_USERUSED, ZFS_DELEG_NOTE_USERUSED }, 69209962Smm {ZFS_DELEG_PERM_GROUPUSED, ZFS_DELEG_NOTE_GROUPUSED }, 70219089Spjd {ZFS_DELEG_PERM_HOLD, ZFS_DELEG_NOTE_HOLD }, 71219089Spjd {ZFS_DELEG_PERM_RELEASE, ZFS_DELEG_NOTE_RELEASE }, 72219089Spjd {ZFS_DELEG_PERM_DIFF, ZFS_DELEG_NOTE_DIFF}, 73185029Spjd {NULL, ZFS_DELEG_NOTE_NONE } 74185029Spjd}; 75185029Spjd 76185029Spjdstatic int 77185029Spjdzfs_valid_permission_name(const char *perm) 78185029Spjd{ 79185029Spjd if (zfs_deleg_canonicalize_perm(perm)) 80185029Spjd return (0); 81185029Spjd 82185029Spjd return (permset_namecheck(perm, NULL, NULL)); 83185029Spjd} 84185029Spjd 85185029Spjdconst char * 86185029Spjdzfs_deleg_canonicalize_perm(const char *perm) 87185029Spjd{ 88185029Spjd int i; 89185029Spjd zfs_prop_t prop; 90185029Spjd 91185029Spjd for (i = 0; zfs_deleg_perm_tab[i].z_perm != NULL; i++) { 92185029Spjd if (strcmp(perm, zfs_deleg_perm_tab[i].z_perm) == 0) 93185029Spjd return (perm); 94185029Spjd } 95185029Spjd 96185029Spjd prop = zfs_name_to_prop(perm); 97185029Spjd if (prop != ZPROP_INVAL && zfs_prop_delegatable(prop)) 98185029Spjd return (zfs_prop_to_name(prop)); 99185029Spjd return (NULL); 100185029Spjd 101185029Spjd} 102185029Spjd 103185029Spjdstatic int 104185029Spjdzfs_validate_who(char *who) 105185029Spjd{ 106185029Spjd char *p; 107185029Spjd 108185029Spjd if (who[2] != ZFS_DELEG_FIELD_SEP_CHR) 109185029Spjd return (-1); 110185029Spjd 111185029Spjd switch (who[0]) { 112185029Spjd case ZFS_DELEG_USER: 113185029Spjd case ZFS_DELEG_GROUP: 114185029Spjd case ZFS_DELEG_USER_SETS: 115185029Spjd case ZFS_DELEG_GROUP_SETS: 116185029Spjd if (who[1] != ZFS_DELEG_LOCAL && who[1] != ZFS_DELEG_DESCENDENT) 117185029Spjd return (-1); 118185029Spjd for (p = &who[3]; *p; p++) 119185029Spjd if (!isdigit(*p)) 120185029Spjd return (-1); 121185029Spjd break; 122185029Spjd 123185029Spjd case ZFS_DELEG_NAMED_SET: 124185029Spjd case ZFS_DELEG_NAMED_SET_SETS: 125185029Spjd if (who[1] != ZFS_DELEG_NA) 126185029Spjd return (-1); 127185029Spjd return (permset_namecheck(&who[3], NULL, NULL)); 128185029Spjd 129185029Spjd case ZFS_DELEG_CREATE: 130185029Spjd case ZFS_DELEG_CREATE_SETS: 131185029Spjd if (who[1] != ZFS_DELEG_NA) 132185029Spjd return (-1); 133185029Spjd if (who[3] != '\0') 134185029Spjd return (-1); 135185029Spjd break; 136185029Spjd 137185029Spjd case ZFS_DELEG_EVERYONE: 138185029Spjd case ZFS_DELEG_EVERYONE_SETS: 139185029Spjd if (who[1] != ZFS_DELEG_LOCAL && who[1] != ZFS_DELEG_DESCENDENT) 140185029Spjd return (-1); 141185029Spjd if (who[3] != '\0') 142185029Spjd return (-1); 143185029Spjd break; 144185029Spjd 145185029Spjd default: 146185029Spjd return (-1); 147185029Spjd } 148185029Spjd 149185029Spjd return (0); 150185029Spjd} 151185029Spjd 152185029Spjdint 153185029Spjdzfs_deleg_verify_nvlist(nvlist_t *nvp) 154185029Spjd{ 155185029Spjd nvpair_t *who, *perm_name; 156185029Spjd nvlist_t *perms; 157185029Spjd int error; 158185029Spjd 159185029Spjd if (nvp == NULL) 160185029Spjd return (-1); 161185029Spjd 162185029Spjd who = nvlist_next_nvpair(nvp, NULL); 163185029Spjd if (who == NULL) 164185029Spjd return (-1); 165185029Spjd 166185029Spjd do { 167185029Spjd if (zfs_validate_who(nvpair_name(who))) 168185029Spjd return (-1); 169185029Spjd 170185029Spjd error = nvlist_lookup_nvlist(nvp, nvpair_name(who), &perms); 171185029Spjd 172185029Spjd if (error && error != ENOENT) 173185029Spjd return (-1); 174185029Spjd if (error == ENOENT) 175185029Spjd continue; 176185029Spjd 177185029Spjd perm_name = nvlist_next_nvpair(perms, NULL); 178185029Spjd if (perm_name == NULL) { 179185029Spjd return (-1); 180185029Spjd } 181185029Spjd do { 182185029Spjd error = zfs_valid_permission_name( 183185029Spjd nvpair_name(perm_name)); 184185029Spjd if (error) 185185029Spjd return (-1); 186185029Spjd } while (perm_name = nvlist_next_nvpair(perms, perm_name)); 187185029Spjd } while (who = nvlist_next_nvpair(nvp, who)); 188185029Spjd return (0); 189185029Spjd} 190185029Spjd 191185029Spjd/* 192185029Spjd * Construct the base attribute name. The base attribute names 193185029Spjd * are the "key" to locate the jump objects which contain the actual 194185029Spjd * permissions. The base attribute names are encoded based on 195185029Spjd * type of entry and whether it is a local or descendent permission. 196185029Spjd * 197185029Spjd * Arguments: 198185029Spjd * attr - attribute name return string, attribute is assumed to be 199185029Spjd * ZFS_MAX_DELEG_NAME long. 200185029Spjd * type - type of entry to construct 201185029Spjd * inheritchr - inheritance type (local,descendent, or NA for create and 202185029Spjd * permission set definitions 203185029Spjd * data - is either a permission set name or a 64 bit uid/gid. 204185029Spjd */ 205185029Spjdvoid 206185029Spjdzfs_deleg_whokey(char *attr, zfs_deleg_who_type_t type, 207185029Spjd char inheritchr, void *data) 208185029Spjd{ 209185029Spjd int len = ZFS_MAX_DELEG_NAME; 210185029Spjd uint64_t *id = data; 211185029Spjd 212185029Spjd switch (type) { 213185029Spjd case ZFS_DELEG_USER: 214185029Spjd case ZFS_DELEG_GROUP: 215185029Spjd case ZFS_DELEG_USER_SETS: 216185029Spjd case ZFS_DELEG_GROUP_SETS: 217185029Spjd (void) snprintf(attr, len, "%c%c%c%lld", type, inheritchr, 218185029Spjd ZFS_DELEG_FIELD_SEP_CHR, (longlong_t)*id); 219185029Spjd break; 220185029Spjd case ZFS_DELEG_NAMED_SET_SETS: 221185029Spjd case ZFS_DELEG_NAMED_SET: 222185029Spjd (void) snprintf(attr, len, "%c-%c%s", type, 223185029Spjd ZFS_DELEG_FIELD_SEP_CHR, (char *)data); 224185029Spjd break; 225185029Spjd case ZFS_DELEG_CREATE: 226185029Spjd case ZFS_DELEG_CREATE_SETS: 227185029Spjd (void) snprintf(attr, len, "%c-%c", type, 228185029Spjd ZFS_DELEG_FIELD_SEP_CHR); 229185029Spjd break; 230185029Spjd case ZFS_DELEG_EVERYONE: 231185029Spjd case ZFS_DELEG_EVERYONE_SETS: 232185029Spjd (void) snprintf(attr, len, "%c%c%c", type, inheritchr, 233185029Spjd ZFS_DELEG_FIELD_SEP_CHR); 234185029Spjd break; 235185029Spjd default: 236185029Spjd ASSERT(!"bad zfs_deleg_who_type_t"); 237185029Spjd } 238185029Spjd} 239