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 2009 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 /* 26 * Copyright (c) 2013 by Delphix. All rights reserved. 27 */ 28 29 /* 30 * Common name validation routines for ZFS. These routines are shared by the 31 * userland code as well as the ioctl() layer to ensure that we don't 32 * inadvertently expose a hole through direct ioctl()s that never gets tested. 33 * In userland, however, we want significantly more information about _why_ the 34 * name is invalid. In the kernel, we only care whether it's valid or not. 35 * Each routine therefore takes a 'namecheck_err_t' which describes exactly why 36 * the name failed to validate. 37 * 38 * Each function returns 0 on success, -1 on error. 39 */ 40 41 #if defined(_KERNEL) 42 #include <sys/systm.h> 43 #else 44 #include <string.h> 45 #endif 46 47 #include <sys/dsl_dir.h> 48 #include <sys/param.h> 49 #include <sys/nvpair.h> 50 #include "zfs_namecheck.h" 51 #include "zfs_deleg.h" 52 53 static int 54 valid_char(char c) 55 { 56 return ((c >= 'a' && c <= 'z') || 57 (c >= 'A' && c <= 'Z') || 58 (c >= '0' && c <= '9') || 59 c == '-' || c == '_' || c == '.' || c == ':' || c == ' '); 60 } 61 62 /* 63 * Snapshot names must be made up of alphanumeric characters plus the following 64 * characters: 65 * 66 * [-_.: ] 67 */ 68 int 69 zfs_component_namecheck(const char *path, namecheck_err_t *why, char *what) 70 { 71 const char *loc; 72 73 if (strlen(path) >= ZFS_MAX_DATASET_NAME_LEN) { 74 if (why) 75 *why = NAME_ERR_TOOLONG; 76 return (-1); 77 } 78 79 if (path[0] == '\0') { 80 if (why) 81 *why = NAME_ERR_EMPTY_COMPONENT; 82 return (-1); 83 } 84 85 for (loc = path; *loc; loc++) { 86 if (!valid_char(*loc)) { 87 if (why) { 88 *why = NAME_ERR_INVALCHAR; 89 *what = *loc; 90 } 91 return (-1); 92 } 93 } 94 return (0); 95 } 96 97 98 /* 99 * Permissions set name must start with the letter '@' followed by the 100 * same character restrictions as snapshot names, except that the name 101 * cannot exceed 64 characters. 102 */ 103 int 104 permset_namecheck(const char *path, namecheck_err_t *why, char *what) 105 { 106 if (strlen(path) >= ZFS_PERMSET_MAXLEN) { 107 if (why) 108 *why = NAME_ERR_TOOLONG; 109 return (-1); 110 } 111 112 if (path[0] != '@') { 113 if (why) { 114 *why = NAME_ERR_NO_AT; 115 *what = path[0]; 116 } 117 return (-1); 118 } 119 120 return (zfs_component_namecheck(&path[1], why, what)); 121 } 122 123 /* 124 * Entity names must be of the following form: 125 * 126 * [component/]*[component][(@|#)component]? 127 * 128 * Where each component is made up of alphanumeric characters plus the following 129 * characters: 130 * 131 * [-_.:%] 132 * 133 * We allow '%' here as we use that character internally to create unique 134 * names for temporary clones (for online recv). 135 */ 136 int 137 entity_namecheck(const char *path, namecheck_err_t *why, char *what) 138 { 139 const char *start, *end; 140 int found_delim; 141 142 /* 143 * Make sure the name is not too long. 144 */ 145 146 if (strlen(path) >= ZFS_MAX_DATASET_NAME_LEN) { 147 if (why) 148 *why = NAME_ERR_TOOLONG; 149 return (-1); 150 } 151 152 /* Explicitly check for a leading slash. */ 153 if (path[0] == '/') { 154 if (why) 155 *why = NAME_ERR_LEADING_SLASH; 156 return (-1); 157 } 158 159 if (path[0] == '\0') { 160 if (why) 161 *why = NAME_ERR_EMPTY_COMPONENT; 162 return (-1); 163 } 164 165 start = path; 166 found_delim = 0; 167 for (;;) { 168 /* Find the end of this component */ 169 end = start; 170 while (*end != '/' && *end != '@' && *end != '#' && 171 *end != '\0') 172 end++; 173 174 if (*end == '\0' && end[-1] == '/') { 175 /* trailing slashes are not allowed */ 176 if (why) 177 *why = NAME_ERR_TRAILING_SLASH; 178 return (-1); 179 } 180 181 /* Validate the contents of this component */ 182 for (const char *loc = start; loc != end; loc++) { 183 if (!valid_char(*loc) && *loc != '%') { 184 if (why) { 185 *why = NAME_ERR_INVALCHAR; 186 *what = *loc; 187 } 188 return (-1); 189 } 190 } 191 192 /* Snapshot or bookmark delimiter found */ 193 if (*end == '@' || *end == '#') { 194 /* Multiple delimiters are not allowed */ 195 if (found_delim != 0) { 196 if (why) 197 *why = NAME_ERR_MULTIPLE_DELIMITERS; 198 return (-1); 199 } 200 201 found_delim = 1; 202 } 203 204 /* Zero-length components are not allowed */ 205 if (start == end) { 206 if (why) 207 *why = NAME_ERR_EMPTY_COMPONENT; 208 return (-1); 209 } 210 211 /* If we've reached the end of the string, we're OK */ 212 if (*end == '\0') 213 return (0); 214 215 /* 216 * If there is a '/' in a snapshot or bookmark name 217 * then report an error 218 */ 219 if (*end == '/' && found_delim != 0) { 220 if (why) 221 *why = NAME_ERR_TRAILING_SLASH; 222 return (-1); 223 } 224 225 /* Update to the next component */ 226 start = end + 1; 227 } 228 } 229 230 /* 231 * Dataset is any entity, except bookmark 232 */ 233 int 234 dataset_namecheck(const char *path, namecheck_err_t *why, char *what) 235 { 236 int ret = entity_namecheck(path, why, what); 237 238 if (ret == 0 && strchr(path, '#') != NULL) { 239 if (why != NULL) { 240 *why = NAME_ERR_INVALCHAR; 241 *what = '#'; 242 } 243 return (-1); 244 } 245 246 return (ret); 247 } 248 249 /* 250 * mountpoint names must be of the following form: 251 * 252 * /[component][/]*[component][/] 253 */ 254 int 255 mountpoint_namecheck(const char *path, namecheck_err_t *why) 256 { 257 const char *start, *end; 258 259 /* 260 * Make sure none of the mountpoint component names are too long. 261 * If a component name is too long then the mkdir of the mountpoint 262 * will fail but then the mountpoint property will be set to a value 263 * that can never be mounted. Better to fail before setting the prop. 264 * Extra slashes are OK, they will be tossed by the mountpoint mkdir. 265 */ 266 267 if (path == NULL || *path != '/') { 268 if (why) 269 *why = NAME_ERR_LEADING_SLASH; 270 return (-1); 271 } 272 273 /* Skip leading slash */ 274 start = &path[1]; 275 do { 276 end = start; 277 while (*end != '/' && *end != '\0') 278 end++; 279 280 if (end - start >= ZFS_MAX_DATASET_NAME_LEN) { 281 if (why) 282 *why = NAME_ERR_TOOLONG; 283 return (-1); 284 } 285 start = end + 1; 286 287 } while (*end != '\0'); 288 289 return (0); 290 } 291 292 /* 293 * For pool names, we have the same set of valid characters as described in 294 * dataset names, with the additional restriction that the pool name must begin 295 * with a letter. The pool names 'raidz' and 'mirror' are also reserved names 296 * that cannot be used. 297 */ 298 int 299 pool_namecheck(const char *pool, namecheck_err_t *why, char *what) 300 { 301 const char *c; 302 303 /* 304 * Make sure the name is not too long. 305 * If we're creating a pool with version >= SPA_VERSION_DSL_SCRUB (v11) 306 * we need to account for additional space needed by the origin ds which 307 * will also be snapshotted: "poolname"+"/"+"$ORIGIN"+"@"+"$ORIGIN". 308 * Play it safe and enforce this limit even if the pool version is < 11 309 * so it can be upgraded without issues. 310 */ 311 if (strlen(pool) >= (ZFS_MAX_DATASET_NAME_LEN - 2 - 312 strlen(ORIGIN_DIR_NAME) * 2)) { 313 if (why) 314 *why = NAME_ERR_TOOLONG; 315 return (-1); 316 } 317 318 c = pool; 319 while (*c != '\0') { 320 if (!valid_char(*c)) { 321 if (why) { 322 *why = NAME_ERR_INVALCHAR; 323 *what = *c; 324 } 325 return (-1); 326 } 327 c++; 328 } 329 330 if (!(*pool >= 'a' && *pool <= 'z') && 331 !(*pool >= 'A' && *pool <= 'Z')) { 332 if (why) 333 *why = NAME_ERR_NOLETTER; 334 return (-1); 335 } 336 337 if (strcmp(pool, "mirror") == 0 || strcmp(pool, "raidz") == 0) { 338 if (why) 339 *why = NAME_ERR_RESERVED; 340 return (-1); 341 } 342 343 if (pool[0] == 'c' && (pool[1] >= '0' && pool[1] <= '9')) { 344 if (why) 345 *why = NAME_ERR_DISKLIKE; 346 return (-1); 347 } 348 349 return (0); 350 } 351