1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 27 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 #if defined(_KERNEL) 30 #include <sys/systm.h> 31 #include <sys/sunddi.h> 32 #include <sys/ctype.h> 33 #else 34 #include <stdio.h> 35 #include <unistd.h> 36 #include <strings.h> 37 #include <libnvpair.h> 38 #include <ctype.h> 39 #endif 40 #include <sys/dsl_deleg.h> 41 #include "zfs_deleg.h" 42 #include "zfs_namecheck.h" 43 44 /* 45 * permission table 46 */ 47 48 char *zfs_deleg_perm_tab[] = { 49 ZFS_DELEG_PERM_CREATE, 50 ZFS_DELEG_PERM_DESTROY, 51 ZFS_DELEG_PERM_SNAPSHOT, 52 ZFS_DELEG_PERM_ROLLBACK, 53 ZFS_DELEG_PERM_CLONE, 54 ZFS_DELEG_PERM_PROMOTE, 55 ZFS_DELEG_PERM_RENAME, 56 ZFS_DELEG_PERM_MOUNT, 57 ZFS_DELEG_PERM_SHARE, 58 ZFS_DELEG_PERM_SEND, 59 ZFS_DELEG_PERM_RECEIVE, 60 ZFS_DELEG_PERM_QUOTA, 61 ZFS_DELEG_PERM_RESERVATION, 62 ZFS_DELEG_PERM_VOLSIZE, 63 ZFS_DELEG_PERM_RECORDSIZE, 64 ZFS_DELEG_PERM_MOUNTPOINT, 65 ZFS_DELEG_PERM_SHARENFS, 66 ZFS_DELEG_PERM_CHECKSUM, 67 ZFS_DELEG_PERM_COMPRESSION, 68 ZFS_DELEG_PERM_ATIME, 69 ZFS_DELEG_PERM_DEVICES, 70 ZFS_DELEG_PERM_EXEC, 71 ZFS_DELEG_PERM_SETUID, 72 ZFS_DELEG_PERM_READONLY, 73 ZFS_DELEG_PERM_ZONED, 74 ZFS_DELEG_PERM_SNAPDIR, 75 ZFS_DELEG_PERM_ACLMODE, 76 ZFS_DELEG_PERM_ACLINHERIT, 77 ZFS_DELEG_PERM_ALLOW, 78 ZFS_DELEG_PERM_CANMOUNT, 79 ZFS_DELEG_PERM_USERPROP, 80 ZFS_DELEG_PERM_SHAREISCSI, 81 ZFS_DELEG_PERM_XATTR, 82 ZFS_DELEG_PERM_COPIES, 83 NULL 84 }; 85 86 int 87 zfs_deleg_type(char *name) 88 { 89 return (name[0]); 90 } 91 92 static int 93 zfs_valid_permission_name(char *perm) 94 { 95 int i; 96 for (i = 0; zfs_deleg_perm_tab[i] != NULL; i++) { 97 if (strcmp(perm, zfs_deleg_perm_tab[i]) == 0) 98 return (0); 99 } 100 101 return (permset_namecheck(perm, NULL, NULL)); 102 } 103 104 static int 105 zfs_validate_who(char *who) 106 { 107 int error = 0; 108 char *p; 109 110 switch (zfs_deleg_type(who)) { 111 case ZFS_DELEG_USER: 112 case ZFS_DELEG_GROUP: 113 case ZFS_DELEG_USER_SETS: 114 case ZFS_DELEG_GROUP_SETS: 115 if ((who[1] != 'l' || who[1] != 'd') && 116 (who[2] != ZFS_DELEG_FIELD_SEP_CHR)) { 117 error = -1; 118 break; 119 } 120 121 for (p = &who[3]; p && *p; p++) 122 if (!isdigit(*p)) { 123 error = -1; 124 } 125 break; 126 case ZFS_DELEG_NAMED_SET: 127 case ZFS_DELEG_NAMED_SET_SETS: 128 error = permset_namecheck(&who[3], NULL, NULL); 129 break; 130 131 case ZFS_DELEG_CREATE: 132 case ZFS_DELEG_CREATE_SETS: 133 case ZFS_DELEG_EVERYONE: 134 case ZFS_DELEG_EVERYONE_SETS: 135 if (who[3] != '\0') 136 error = -1; 137 break; 138 default: 139 error = -1; 140 } 141 142 return (error); 143 } 144 145 static int 146 zfs_validate_iflags(char *who) 147 { 148 switch (zfs_deleg_type(who)) { 149 case ZFS_DELEG_NAMED_SET: 150 case ZFS_DELEG_NAMED_SET_SETS: 151 case ZFS_DELEG_CREATE: 152 case ZFS_DELEG_CREATE_SETS: 153 if (who[1] != '-') 154 return (-1); 155 break; 156 default: 157 if (who[1] != 'l' && who[1] != 'd') 158 return (-1); 159 break; 160 } 161 return (0); 162 } 163 164 int 165 zfs_deleg_verify_nvlist(nvlist_t *nvp) 166 { 167 nvpair_t *who, *perm_name; 168 nvlist_t *perms; 169 int error; 170 171 if (nvp == NULL) 172 return (-1); 173 174 who = nvlist_next_nvpair(nvp, NULL); 175 if (who == NULL) 176 return (-1); 177 178 do { 179 if (zfs_validate_who(nvpair_name(who))) 180 return (-1); 181 182 if (zfs_validate_iflags(nvpair_name(who))) 183 return (-1); 184 185 error = nvlist_lookup_nvlist(nvp, nvpair_name(who), &perms); 186 187 if (error && error != ENOENT) 188 return (-1); 189 if (error == ENOENT) 190 continue; 191 192 perm_name = nvlist_next_nvpair(perms, NULL); 193 if (perm_name == NULL) { 194 return (-1); 195 } 196 do { 197 error = zfs_valid_permission_name( 198 nvpair_name(perm_name)); 199 if (error) { 200 return (-1); 201 } 202 } while (perm_name = nvlist_next_nvpair(perms, perm_name)); 203 } while (who = nvlist_next_nvpair(nvp, who)); 204 return (0); 205 } 206 207 /* 208 * Construct the base attribute name. The base attribute names 209 * are the "key" to locate the jump objects which contain the actual 210 * permissions. The base attribute names are encoded based on 211 * type of entry and whether it is a local or descendent permission. 212 * 213 * Arguments: 214 * attr - attribute name return string, attribute is assumed to be 215 * ZFS_MAX_DELEG_NAME long. 216 * type - type of entry to construct 217 * inheritchr - inheritance type (local,descendent, or NA for create and 218 * permission set definitions 219 * data - is either a permission set name or a 64 bit uid/gid. 220 */ 221 void 222 zfs_deleg_whokey(char *attr, char type, char inheritchr, void *data) 223 { 224 int len = ZFS_MAX_DELEG_NAME; 225 uint64_t *id = data; 226 227 switch (type) { 228 case ZFS_DELEG_USER: 229 case ZFS_DELEG_GROUP: 230 case ZFS_DELEG_USER_SETS: 231 case ZFS_DELEG_GROUP_SETS: 232 (void) snprintf(attr, len, "%c%c%c%lld", type, inheritchr, 233 ZFS_DELEG_FIELD_SEP_CHR, (longlong_t)*id); 234 break; 235 case ZFS_DELEG_NAMED_SET_SETS: 236 case ZFS_DELEG_NAMED_SET: 237 (void) snprintf(attr, len, "%c-%c%s", type, 238 ZFS_DELEG_FIELD_SEP_CHR, (char *)data); 239 break; 240 case ZFS_DELEG_CREATE: 241 case ZFS_DELEG_CREATE_SETS: 242 (void) snprintf(attr, len, "%c-%c", type, 243 ZFS_DELEG_FIELD_SEP_CHR); 244 break; 245 default: 246 (void) snprintf(attr, len, "%c%c%c", type, inheritchr, 247 ZFS_DELEG_FIELD_SEP_CHR); 248 } 249 } 250