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 /* 23 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #include <assert.h> 28 #include <ctype.h> 29 #include <errno.h> 30 #include <libdevinfo.h> 31 #include <libintl.h> 32 #include <math.h> 33 #include <stdio.h> 34 #include <stdlib.h> 35 #include <strings.h> 36 #include <unistd.h> 37 #include <stddef.h> 38 #include <zone.h> 39 #include <fcntl.h> 40 #include <sys/mntent.h> 41 #include <sys/mnttab.h> 42 #include <sys/mount.h> 43 #include <sys/avl.h> 44 #include <priv.h> 45 #include <pwd.h> 46 #include <grp.h> 47 #include <stddef.h> 48 #include <ucred.h> 49 50 #include <sys/spa.h> 51 #include <sys/zap.h> 52 #include <libzfs.h> 53 54 #include "zfs_namecheck.h" 55 #include "zfs_prop.h" 56 #include "libzfs_impl.h" 57 #include "zfs_deleg.h" 58 59 static int zvol_create_link_common(libzfs_handle_t *, const char *, int); 60 61 /* 62 * Given a single type (not a mask of types), return the type in a human 63 * readable form. 64 */ 65 const char * 66 zfs_type_to_name(zfs_type_t type) 67 { 68 switch (type) { 69 case ZFS_TYPE_FILESYSTEM: 70 return (dgettext(TEXT_DOMAIN, "filesystem")); 71 case ZFS_TYPE_SNAPSHOT: 72 return (dgettext(TEXT_DOMAIN, "snapshot")); 73 case ZFS_TYPE_VOLUME: 74 return (dgettext(TEXT_DOMAIN, "volume")); 75 } 76 77 return (NULL); 78 } 79 80 /* 81 * Given a path and mask of ZFS types, return a string describing this dataset. 82 * This is used when we fail to open a dataset and we cannot get an exact type. 83 * We guess what the type would have been based on the path and the mask of 84 * acceptable types. 85 */ 86 static const char * 87 path_to_str(const char *path, int types) 88 { 89 /* 90 * When given a single type, always report the exact type. 91 */ 92 if (types == ZFS_TYPE_SNAPSHOT) 93 return (dgettext(TEXT_DOMAIN, "snapshot")); 94 if (types == ZFS_TYPE_FILESYSTEM) 95 return (dgettext(TEXT_DOMAIN, "filesystem")); 96 if (types == ZFS_TYPE_VOLUME) 97 return (dgettext(TEXT_DOMAIN, "volume")); 98 99 /* 100 * The user is requesting more than one type of dataset. If this is the 101 * case, consult the path itself. If we're looking for a snapshot, and 102 * a '@' is found, then report it as "snapshot". Otherwise, remove the 103 * snapshot attribute and try again. 104 */ 105 if (types & ZFS_TYPE_SNAPSHOT) { 106 if (strchr(path, '@') != NULL) 107 return (dgettext(TEXT_DOMAIN, "snapshot")); 108 return (path_to_str(path, types & ~ZFS_TYPE_SNAPSHOT)); 109 } 110 111 112 /* 113 * The user has requested either filesystems or volumes. 114 * We have no way of knowing a priori what type this would be, so always 115 * report it as "filesystem" or "volume", our two primitive types. 116 */ 117 if (types & ZFS_TYPE_FILESYSTEM) 118 return (dgettext(TEXT_DOMAIN, "filesystem")); 119 120 assert(types & ZFS_TYPE_VOLUME); 121 return (dgettext(TEXT_DOMAIN, "volume")); 122 } 123 124 /* 125 * Validate a ZFS path. This is used even before trying to open the dataset, to 126 * provide a more meaningful error message. We place a more useful message in 127 * 'buf' detailing exactly why the name was not valid. 128 */ 129 static int 130 zfs_validate_name(libzfs_handle_t *hdl, const char *path, int type, 131 boolean_t modifying) 132 { 133 namecheck_err_t why; 134 char what; 135 136 if (dataset_namecheck(path, &why, &what) != 0) { 137 if (hdl != NULL) { 138 switch (why) { 139 case NAME_ERR_TOOLONG: 140 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 141 "name is too long")); 142 break; 143 144 case NAME_ERR_LEADING_SLASH: 145 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 146 "leading slash in name")); 147 break; 148 149 case NAME_ERR_EMPTY_COMPONENT: 150 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 151 "empty component in name")); 152 break; 153 154 case NAME_ERR_TRAILING_SLASH: 155 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 156 "trailing slash in name")); 157 break; 158 159 case NAME_ERR_INVALCHAR: 160 zfs_error_aux(hdl, 161 dgettext(TEXT_DOMAIN, "invalid character " 162 "'%c' in name"), what); 163 break; 164 165 case NAME_ERR_MULTIPLE_AT: 166 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 167 "multiple '@' delimiters in name")); 168 break; 169 170 case NAME_ERR_NOLETTER: 171 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 172 "pool doesn't begin with a letter")); 173 break; 174 175 case NAME_ERR_RESERVED: 176 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 177 "name is reserved")); 178 break; 179 180 case NAME_ERR_DISKLIKE: 181 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 182 "reserved disk name")); 183 break; 184 } 185 } 186 187 return (0); 188 } 189 190 if (!(type & ZFS_TYPE_SNAPSHOT) && strchr(path, '@') != NULL) { 191 if (hdl != NULL) 192 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 193 "snapshot delimiter '@' in filesystem name")); 194 return (0); 195 } 196 197 if (type == ZFS_TYPE_SNAPSHOT && strchr(path, '@') == NULL) { 198 if (hdl != NULL) 199 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 200 "missing '@' delimiter in snapshot name")); 201 return (0); 202 } 203 204 if (modifying && strchr(path, '%') != NULL) { 205 if (hdl != NULL) 206 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 207 "invalid character %c in name"), '%'); 208 return (0); 209 } 210 211 return (-1); 212 } 213 214 int 215 zfs_name_valid(const char *name, zfs_type_t type) 216 { 217 if (type == ZFS_TYPE_POOL) 218 return (zpool_name_valid(NULL, B_FALSE, name)); 219 return (zfs_validate_name(NULL, name, type, B_FALSE)); 220 } 221 222 /* 223 * This function takes the raw DSL properties, and filters out the user-defined 224 * properties into a separate nvlist. 225 */ 226 static nvlist_t * 227 process_user_props(zfs_handle_t *zhp, nvlist_t *props) 228 { 229 libzfs_handle_t *hdl = zhp->zfs_hdl; 230 nvpair_t *elem; 231 nvlist_t *propval; 232 nvlist_t *nvl; 233 234 if (nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0) != 0) { 235 (void) no_memory(hdl); 236 return (NULL); 237 } 238 239 elem = NULL; 240 while ((elem = nvlist_next_nvpair(props, elem)) != NULL) { 241 if (!zfs_prop_user(nvpair_name(elem))) 242 continue; 243 244 verify(nvpair_value_nvlist(elem, &propval) == 0); 245 if (nvlist_add_nvlist(nvl, nvpair_name(elem), propval) != 0) { 246 nvlist_free(nvl); 247 (void) no_memory(hdl); 248 return (NULL); 249 } 250 } 251 252 return (nvl); 253 } 254 255 static zpool_handle_t * 256 zpool_add_handle(zfs_handle_t *zhp, const char *pool_name) 257 { 258 libzfs_handle_t *hdl = zhp->zfs_hdl; 259 zpool_handle_t *zph; 260 261 if ((zph = zpool_open_canfail(hdl, pool_name)) != NULL) { 262 if (hdl->libzfs_pool_handles != NULL) 263 zph->zpool_next = hdl->libzfs_pool_handles; 264 hdl->libzfs_pool_handles = zph; 265 } 266 return (zph); 267 } 268 269 static zpool_handle_t * 270 zpool_find_handle(zfs_handle_t *zhp, const char *pool_name, int len) 271 { 272 libzfs_handle_t *hdl = zhp->zfs_hdl; 273 zpool_handle_t *zph = hdl->libzfs_pool_handles; 274 275 while ((zph != NULL) && 276 (strncmp(pool_name, zpool_get_name(zph), len) != 0)) 277 zph = zph->zpool_next; 278 return (zph); 279 } 280 281 /* 282 * Returns a handle to the pool that contains the provided dataset. 283 * If a handle to that pool already exists then that handle is returned. 284 * Otherwise, a new handle is created and added to the list of handles. 285 */ 286 static zpool_handle_t * 287 zpool_handle(zfs_handle_t *zhp) 288 { 289 char *pool_name; 290 int len; 291 zpool_handle_t *zph; 292 293 len = strcspn(zhp->zfs_name, "/@") + 1; 294 pool_name = zfs_alloc(zhp->zfs_hdl, len); 295 (void) strlcpy(pool_name, zhp->zfs_name, len); 296 297 zph = zpool_find_handle(zhp, pool_name, len); 298 if (zph == NULL) 299 zph = zpool_add_handle(zhp, pool_name); 300 301 free(pool_name); 302 return (zph); 303 } 304 305 void 306 zpool_free_handles(libzfs_handle_t *hdl) 307 { 308 zpool_handle_t *next, *zph = hdl->libzfs_pool_handles; 309 310 while (zph != NULL) { 311 next = zph->zpool_next; 312 zpool_close(zph); 313 zph = next; 314 } 315 hdl->libzfs_pool_handles = NULL; 316 } 317 318 /* 319 * Utility function to gather stats (objset and zpl) for the given object. 320 */ 321 static int 322 get_stats(zfs_handle_t *zhp) 323 { 324 zfs_cmd_t zc = { 0 }; 325 libzfs_handle_t *hdl = zhp->zfs_hdl; 326 nvlist_t *allprops, *userprops; 327 328 (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name)); 329 330 if (zcmd_alloc_dst_nvlist(hdl, &zc, 0) != 0) 331 return (-1); 332 333 while (ioctl(zhp->zfs_hdl->libzfs_fd, ZFS_IOC_OBJSET_STATS, &zc) != 0) { 334 if (errno == ENOMEM) { 335 if (zcmd_expand_dst_nvlist(hdl, &zc) != 0) { 336 zcmd_free_nvlists(&zc); 337 return (-1); 338 } 339 } else { 340 zcmd_free_nvlists(&zc); 341 return (-1); 342 } 343 } 344 345 zhp->zfs_dmustats = zc.zc_objset_stats; /* structure assignment */ 346 347 if (zcmd_read_dst_nvlist(hdl, &zc, &allprops) != 0) { 348 zcmd_free_nvlists(&zc); 349 return (-1); 350 } 351 352 zcmd_free_nvlists(&zc); 353 354 if ((userprops = process_user_props(zhp, allprops)) == NULL) { 355 nvlist_free(allprops); 356 return (-1); 357 } 358 359 nvlist_free(zhp->zfs_props); 360 nvlist_free(zhp->zfs_user_props); 361 362 zhp->zfs_props = allprops; 363 zhp->zfs_user_props = userprops; 364 365 return (0); 366 } 367 368 /* 369 * Refresh the properties currently stored in the handle. 370 */ 371 void 372 zfs_refresh_properties(zfs_handle_t *zhp) 373 { 374 (void) get_stats(zhp); 375 } 376 377 /* 378 * Makes a handle from the given dataset name. Used by zfs_open() and 379 * zfs_iter_* to create child handles on the fly. 380 */ 381 zfs_handle_t * 382 make_dataset_handle(libzfs_handle_t *hdl, const char *path) 383 { 384 zfs_handle_t *zhp = calloc(sizeof (zfs_handle_t), 1); 385 char *logstr; 386 387 if (zhp == NULL) 388 return (NULL); 389 390 zhp->zfs_hdl = hdl; 391 392 /* 393 * Preserve history log string. 394 * any changes performed here will be 395 * logged as an internal event. 396 */ 397 logstr = zhp->zfs_hdl->libzfs_log_str; 398 zhp->zfs_hdl->libzfs_log_str = NULL; 399 top: 400 (void) strlcpy(zhp->zfs_name, path, sizeof (zhp->zfs_name)); 401 402 if (get_stats(zhp) != 0) { 403 zhp->zfs_hdl->libzfs_log_str = logstr; 404 free(zhp); 405 return (NULL); 406 } 407 408 if (zhp->zfs_dmustats.dds_inconsistent) { 409 zfs_cmd_t zc = { 0 }; 410 411 /* 412 * If it is dds_inconsistent, then we've caught it in 413 * the middle of a 'zfs receive' or 'zfs destroy', and 414 * it is inconsistent from the ZPL's point of view, so 415 * can't be mounted. However, it could also be that we 416 * have crashed in the middle of one of those 417 * operations, in which case we need to get rid of the 418 * inconsistent state. We do that by either rolling 419 * back to the previous snapshot (which will fail if 420 * there is none), or destroying the filesystem. Note 421 * that if we are still in the middle of an active 422 * 'receive' or 'destroy', then the rollback and destroy 423 * will fail with EBUSY and we will drive on as usual. 424 */ 425 426 (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name)); 427 428 if (zhp->zfs_dmustats.dds_type == DMU_OST_ZVOL) { 429 (void) zvol_remove_link(hdl, zhp->zfs_name); 430 zc.zc_objset_type = DMU_OST_ZVOL; 431 } else { 432 zc.zc_objset_type = DMU_OST_ZFS; 433 } 434 435 /* 436 * If we can successfully destroy it, pretend that it 437 * never existed. 438 */ 439 if (ioctl(hdl->libzfs_fd, ZFS_IOC_DESTROY, &zc) == 0) { 440 zhp->zfs_hdl->libzfs_log_str = logstr; 441 free(zhp); 442 errno = ENOENT; 443 return (NULL); 444 } 445 /* If we can successfully roll it back, reget the stats */ 446 if (ioctl(hdl->libzfs_fd, ZFS_IOC_ROLLBACK, &zc) == 0) 447 goto top; 448 } 449 450 /* 451 * We've managed to open the dataset and gather statistics. Determine 452 * the high-level type. 453 */ 454 if (zhp->zfs_dmustats.dds_type == DMU_OST_ZVOL) 455 zhp->zfs_head_type = ZFS_TYPE_VOLUME; 456 else if (zhp->zfs_dmustats.dds_type == DMU_OST_ZFS) 457 zhp->zfs_head_type = ZFS_TYPE_FILESYSTEM; 458 else 459 abort(); 460 461 if (zhp->zfs_dmustats.dds_is_snapshot) 462 zhp->zfs_type = ZFS_TYPE_SNAPSHOT; 463 else if (zhp->zfs_dmustats.dds_type == DMU_OST_ZVOL) 464 zhp->zfs_type = ZFS_TYPE_VOLUME; 465 else if (zhp->zfs_dmustats.dds_type == DMU_OST_ZFS) 466 zhp->zfs_type = ZFS_TYPE_FILESYSTEM; 467 else 468 abort(); /* we should never see any other types */ 469 470 zhp->zfs_hdl->libzfs_log_str = logstr; 471 zhp->zpool_hdl = zpool_handle(zhp); 472 return (zhp); 473 } 474 475 /* 476 * Opens the given snapshot, filesystem, or volume. The 'types' 477 * argument is a mask of acceptable types. The function will print an 478 * appropriate error message and return NULL if it can't be opened. 479 */ 480 zfs_handle_t * 481 zfs_open(libzfs_handle_t *hdl, const char *path, int types) 482 { 483 zfs_handle_t *zhp; 484 char errbuf[1024]; 485 486 (void) snprintf(errbuf, sizeof (errbuf), 487 dgettext(TEXT_DOMAIN, "cannot open '%s'"), path); 488 489 /* 490 * Validate the name before we even try to open it. 491 */ 492 if (!zfs_validate_name(hdl, path, ZFS_TYPE_DATASET, B_FALSE)) { 493 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 494 "invalid dataset name")); 495 (void) zfs_error(hdl, EZFS_INVALIDNAME, errbuf); 496 return (NULL); 497 } 498 499 /* 500 * Try to get stats for the dataset, which will tell us if it exists. 501 */ 502 errno = 0; 503 if ((zhp = make_dataset_handle(hdl, path)) == NULL) { 504 (void) zfs_standard_error(hdl, errno, errbuf); 505 return (NULL); 506 } 507 508 if (!(types & zhp->zfs_type)) { 509 (void) zfs_error(hdl, EZFS_BADTYPE, errbuf); 510 zfs_close(zhp); 511 return (NULL); 512 } 513 514 return (zhp); 515 } 516 517 /* 518 * Release a ZFS handle. Nothing to do but free the associated memory. 519 */ 520 void 521 zfs_close(zfs_handle_t *zhp) 522 { 523 if (zhp->zfs_mntopts) 524 free(zhp->zfs_mntopts); 525 nvlist_free(zhp->zfs_props); 526 nvlist_free(zhp->zfs_user_props); 527 free(zhp); 528 } 529 530 int 531 zfs_spa_version(zfs_handle_t *zhp, int *spa_version) 532 { 533 zpool_handle_t *zpool_handle = zhp->zpool_hdl; 534 535 if (zpool_handle == NULL) 536 return (-1); 537 538 *spa_version = zpool_get_prop_int(zpool_handle, 539 ZPOOL_PROP_VERSION, NULL); 540 return (0); 541 } 542 543 /* 544 * The choice of reservation property depends on the SPA version. 545 */ 546 static int 547 zfs_which_resv_prop(zfs_handle_t *zhp, zfs_prop_t *resv_prop) 548 { 549 int spa_version; 550 551 if (zfs_spa_version(zhp, &spa_version) < 0) 552 return (-1); 553 554 if (spa_version >= SPA_VERSION_REFRESERVATION) 555 *resv_prop = ZFS_PROP_REFRESERVATION; 556 else 557 *resv_prop = ZFS_PROP_RESERVATION; 558 559 return (0); 560 } 561 562 /* 563 * Given an nvlist of properties to set, validates that they are correct, and 564 * parses any numeric properties (index, boolean, etc) if they are specified as 565 * strings. 566 */ 567 nvlist_t * 568 zfs_valid_proplist(libzfs_handle_t *hdl, zfs_type_t type, nvlist_t *nvl, 569 uint64_t zoned, zfs_handle_t *zhp, const char *errbuf) 570 { 571 nvpair_t *elem; 572 uint64_t intval; 573 char *strval; 574 zfs_prop_t prop; 575 nvlist_t *ret; 576 int chosen_normal = -1; 577 int chosen_utf = -1; 578 579 if (nvlist_alloc(&ret, NV_UNIQUE_NAME, 0) != 0) { 580 (void) no_memory(hdl); 581 return (NULL); 582 } 583 584 elem = NULL; 585 while ((elem = nvlist_next_nvpair(nvl, elem)) != NULL) { 586 const char *propname = nvpair_name(elem); 587 588 /* 589 * Make sure this property is valid and applies to this type. 590 */ 591 if ((prop = zfs_name_to_prop(propname)) == ZPROP_INVAL) { 592 if (!zfs_prop_user(propname)) { 593 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 594 "invalid property '%s'"), propname); 595 (void) zfs_error(hdl, EZFS_BADPROP, errbuf); 596 goto error; 597 } 598 599 /* 600 * If this is a user property, make sure it's a 601 * string, and that it's less than ZAP_MAXNAMELEN. 602 */ 603 if (nvpair_type(elem) != DATA_TYPE_STRING) { 604 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 605 "'%s' must be a string"), propname); 606 (void) zfs_error(hdl, EZFS_BADPROP, errbuf); 607 goto error; 608 } 609 610 if (strlen(nvpair_name(elem)) >= ZAP_MAXNAMELEN) { 611 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 612 "property name '%s' is too long"), 613 propname); 614 (void) zfs_error(hdl, EZFS_BADPROP, errbuf); 615 goto error; 616 } 617 618 (void) nvpair_value_string(elem, &strval); 619 if (nvlist_add_string(ret, propname, strval) != 0) { 620 (void) no_memory(hdl); 621 goto error; 622 } 623 continue; 624 } 625 626 if (type == ZFS_TYPE_SNAPSHOT) { 627 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 628 "this property can not be modified for snapshots")); 629 (void) zfs_error(hdl, EZFS_PROPTYPE, errbuf); 630 goto error; 631 } 632 633 if (!zfs_prop_valid_for_type(prop, type)) { 634 zfs_error_aux(hdl, 635 dgettext(TEXT_DOMAIN, "'%s' does not " 636 "apply to datasets of this type"), propname); 637 (void) zfs_error(hdl, EZFS_PROPTYPE, errbuf); 638 goto error; 639 } 640 641 if (zfs_prop_readonly(prop) && 642 (!zfs_prop_setonce(prop) || zhp != NULL)) { 643 zfs_error_aux(hdl, 644 dgettext(TEXT_DOMAIN, "'%s' is readonly"), 645 propname); 646 (void) zfs_error(hdl, EZFS_PROPREADONLY, errbuf); 647 goto error; 648 } 649 650 if (zprop_parse_value(hdl, elem, prop, type, ret, 651 &strval, &intval, errbuf) != 0) 652 goto error; 653 654 /* 655 * Perform some additional checks for specific properties. 656 */ 657 switch (prop) { 658 case ZFS_PROP_VERSION: 659 { 660 int version; 661 662 if (zhp == NULL) 663 break; 664 version = zfs_prop_get_int(zhp, ZFS_PROP_VERSION); 665 if (intval < version) { 666 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 667 "Can not downgrade; already at version %u"), 668 version); 669 (void) zfs_error(hdl, EZFS_BADPROP, errbuf); 670 goto error; 671 } 672 break; 673 } 674 675 case ZFS_PROP_RECORDSIZE: 676 case ZFS_PROP_VOLBLOCKSIZE: 677 /* must be power of two within SPA_{MIN,MAX}BLOCKSIZE */ 678 if (intval < SPA_MINBLOCKSIZE || 679 intval > SPA_MAXBLOCKSIZE || !ISP2(intval)) { 680 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 681 "'%s' must be power of 2 from %u " 682 "to %uk"), propname, 683 (uint_t)SPA_MINBLOCKSIZE, 684 (uint_t)SPA_MAXBLOCKSIZE >> 10); 685 (void) zfs_error(hdl, EZFS_BADPROP, errbuf); 686 goto error; 687 } 688 break; 689 690 case ZFS_PROP_SHAREISCSI: 691 if (strcmp(strval, "off") != 0 && 692 strcmp(strval, "on") != 0 && 693 strcmp(strval, "type=disk") != 0) { 694 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 695 "'%s' must be 'on', 'off', or 'type=disk'"), 696 propname); 697 (void) zfs_error(hdl, EZFS_BADPROP, errbuf); 698 goto error; 699 } 700 701 break; 702 703 case ZFS_PROP_MOUNTPOINT: 704 { 705 namecheck_err_t why; 706 707 if (strcmp(strval, ZFS_MOUNTPOINT_NONE) == 0 || 708 strcmp(strval, ZFS_MOUNTPOINT_LEGACY) == 0) 709 break; 710 711 if (mountpoint_namecheck(strval, &why)) { 712 switch (why) { 713 case NAME_ERR_LEADING_SLASH: 714 zfs_error_aux(hdl, 715 dgettext(TEXT_DOMAIN, 716 "'%s' must be an absolute path, " 717 "'none', or 'legacy'"), propname); 718 break; 719 case NAME_ERR_TOOLONG: 720 zfs_error_aux(hdl, 721 dgettext(TEXT_DOMAIN, 722 "component of '%s' is too long"), 723 propname); 724 break; 725 } 726 (void) zfs_error(hdl, EZFS_BADPROP, errbuf); 727 goto error; 728 } 729 } 730 731 /*FALLTHRU*/ 732 733 case ZFS_PROP_SHARESMB: 734 case ZFS_PROP_SHARENFS: 735 /* 736 * For the mountpoint and sharenfs or sharesmb 737 * properties, check if it can be set in a 738 * global/non-global zone based on 739 * the zoned property value: 740 * 741 * global zone non-global zone 742 * -------------------------------------------------- 743 * zoned=on mountpoint (no) mountpoint (yes) 744 * sharenfs (no) sharenfs (no) 745 * sharesmb (no) sharesmb (no) 746 * 747 * zoned=off mountpoint (yes) N/A 748 * sharenfs (yes) 749 * sharesmb (yes) 750 */ 751 if (zoned) { 752 if (getzoneid() == GLOBAL_ZONEID) { 753 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 754 "'%s' cannot be set on " 755 "dataset in a non-global zone"), 756 propname); 757 (void) zfs_error(hdl, EZFS_ZONED, 758 errbuf); 759 goto error; 760 } else if (prop == ZFS_PROP_SHARENFS || 761 prop == ZFS_PROP_SHARESMB) { 762 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 763 "'%s' cannot be set in " 764 "a non-global zone"), propname); 765 (void) zfs_error(hdl, EZFS_ZONED, 766 errbuf); 767 goto error; 768 } 769 } else if (getzoneid() != GLOBAL_ZONEID) { 770 /* 771 * If zoned property is 'off', this must be in 772 * a globle zone. If not, something is wrong. 773 */ 774 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 775 "'%s' cannot be set while dataset " 776 "'zoned' property is set"), propname); 777 (void) zfs_error(hdl, EZFS_ZONED, errbuf); 778 goto error; 779 } 780 781 /* 782 * At this point, it is legitimate to set the 783 * property. Now we want to make sure that the 784 * property value is valid if it is sharenfs. 785 */ 786 if ((prop == ZFS_PROP_SHARENFS || 787 prop == ZFS_PROP_SHARESMB) && 788 strcmp(strval, "on") != 0 && 789 strcmp(strval, "off") != 0) { 790 zfs_share_proto_t proto; 791 792 if (prop == ZFS_PROP_SHARESMB) 793 proto = PROTO_SMB; 794 else 795 proto = PROTO_NFS; 796 797 /* 798 * Must be an valid sharing protocol 799 * option string so init the libshare 800 * in order to enable the parser and 801 * then parse the options. We use the 802 * control API since we don't care about 803 * the current configuration and don't 804 * want the overhead of loading it 805 * until we actually do something. 806 */ 807 808 if (zfs_init_libshare(hdl, 809 SA_INIT_CONTROL_API) != SA_OK) { 810 /* 811 * An error occurred so we can't do 812 * anything 813 */ 814 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 815 "'%s' cannot be set: problem " 816 "in share initialization"), 817 propname); 818 (void) zfs_error(hdl, EZFS_BADPROP, 819 errbuf); 820 goto error; 821 } 822 823 if (zfs_parse_options(strval, proto) != SA_OK) { 824 /* 825 * There was an error in parsing so 826 * deal with it by issuing an error 827 * message and leaving after 828 * uninitializing the the libshare 829 * interface. 830 */ 831 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 832 "'%s' cannot be set to invalid " 833 "options"), propname); 834 (void) zfs_error(hdl, EZFS_BADPROP, 835 errbuf); 836 zfs_uninit_libshare(hdl); 837 goto error; 838 } 839 zfs_uninit_libshare(hdl); 840 } 841 842 break; 843 case ZFS_PROP_UTF8ONLY: 844 chosen_utf = (int)intval; 845 break; 846 case ZFS_PROP_NORMALIZE: 847 chosen_normal = (int)intval; 848 break; 849 } 850 851 /* 852 * For changes to existing volumes, we have some additional 853 * checks to enforce. 854 */ 855 if (type == ZFS_TYPE_VOLUME && zhp != NULL) { 856 uint64_t volsize = zfs_prop_get_int(zhp, 857 ZFS_PROP_VOLSIZE); 858 uint64_t blocksize = zfs_prop_get_int(zhp, 859 ZFS_PROP_VOLBLOCKSIZE); 860 char buf[64]; 861 862 switch (prop) { 863 case ZFS_PROP_RESERVATION: 864 case ZFS_PROP_REFRESERVATION: 865 if (intval > volsize) { 866 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 867 "'%s' is greater than current " 868 "volume size"), propname); 869 (void) zfs_error(hdl, EZFS_BADPROP, 870 errbuf); 871 goto error; 872 } 873 break; 874 875 case ZFS_PROP_VOLSIZE: 876 if (intval % blocksize != 0) { 877 zfs_nicenum(blocksize, buf, 878 sizeof (buf)); 879 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 880 "'%s' must be a multiple of " 881 "volume block size (%s)"), 882 propname, buf); 883 (void) zfs_error(hdl, EZFS_BADPROP, 884 errbuf); 885 goto error; 886 } 887 888 if (intval == 0) { 889 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 890 "'%s' cannot be zero"), 891 propname); 892 (void) zfs_error(hdl, EZFS_BADPROP, 893 errbuf); 894 goto error; 895 } 896 break; 897 } 898 } 899 } 900 901 /* 902 * If normalization was chosen, but no UTF8 choice was made, 903 * enforce rejection of non-UTF8 names. 904 * 905 * If normalization was chosen, but rejecting non-UTF8 names 906 * was explicitly not chosen, it is an error. 907 */ 908 if (chosen_normal > 0 && chosen_utf < 0) { 909 if (nvlist_add_uint64(ret, 910 zfs_prop_to_name(ZFS_PROP_UTF8ONLY), 1) != 0) { 911 (void) no_memory(hdl); 912 goto error; 913 } 914 } else if (chosen_normal > 0 && chosen_utf == 0) { 915 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 916 "'%s' must be set 'on' if normalization chosen"), 917 zfs_prop_to_name(ZFS_PROP_UTF8ONLY)); 918 (void) zfs_error(hdl, EZFS_BADPROP, errbuf); 919 goto error; 920 } 921 922 /* 923 * If this is an existing volume, and someone is setting the volsize, 924 * make sure that it matches the reservation, or add it if necessary. 925 */ 926 if (zhp != NULL && type == ZFS_TYPE_VOLUME && 927 nvlist_lookup_uint64(ret, zfs_prop_to_name(ZFS_PROP_VOLSIZE), 928 &intval) == 0) { 929 uint64_t old_volsize = zfs_prop_get_int(zhp, 930 ZFS_PROP_VOLSIZE); 931 uint64_t old_reservation; 932 uint64_t new_reservation; 933 zfs_prop_t resv_prop; 934 935 if (zfs_which_resv_prop(zhp, &resv_prop) < 0) 936 goto error; 937 old_reservation = zfs_prop_get_int(zhp, resv_prop); 938 939 if (old_volsize == old_reservation && 940 nvlist_lookup_uint64(ret, zfs_prop_to_name(resv_prop), 941 &new_reservation) != 0) { 942 if (nvlist_add_uint64(ret, 943 zfs_prop_to_name(resv_prop), intval) != 0) { 944 (void) no_memory(hdl); 945 goto error; 946 } 947 } 948 } 949 return (ret); 950 951 error: 952 nvlist_free(ret); 953 return (NULL); 954 } 955 956 static int 957 zfs_get_perm_who(const char *who, zfs_deleg_who_type_t *who_type, 958 uint64_t *ret_who) 959 { 960 struct passwd *pwd; 961 struct group *grp; 962 uid_t id; 963 964 if (*who_type == ZFS_DELEG_EVERYONE || *who_type == ZFS_DELEG_CREATE || 965 *who_type == ZFS_DELEG_NAMED_SET) { 966 *ret_who = -1; 967 return (0); 968 } 969 if (who == NULL && !(*who_type == ZFS_DELEG_EVERYONE)) 970 return (EZFS_BADWHO); 971 972 if (*who_type == ZFS_DELEG_WHO_UNKNOWN && 973 strcmp(who, "everyone") == 0) { 974 *ret_who = -1; 975 *who_type = ZFS_DELEG_EVERYONE; 976 return (0); 977 } 978 979 pwd = getpwnam(who); 980 grp = getgrnam(who); 981 982 if ((*who_type == ZFS_DELEG_USER) && pwd) { 983 *ret_who = pwd->pw_uid; 984 } else if ((*who_type == ZFS_DELEG_GROUP) && grp) { 985 *ret_who = grp->gr_gid; 986 } else if (pwd) { 987 *ret_who = pwd->pw_uid; 988 *who_type = ZFS_DELEG_USER; 989 } else if (grp) { 990 *ret_who = grp->gr_gid; 991 *who_type = ZFS_DELEG_GROUP; 992 } else { 993 char *end; 994 995 id = strtol(who, &end, 10); 996 if (errno != 0 || *end != '\0') { 997 return (EZFS_BADWHO); 998 } else { 999 *ret_who = id; 1000 if (*who_type == ZFS_DELEG_WHO_UNKNOWN) 1001 *who_type = ZFS_DELEG_USER; 1002 } 1003 } 1004 1005 return (0); 1006 } 1007 1008 static void 1009 zfs_perms_add_to_nvlist(nvlist_t *who_nvp, char *name, nvlist_t *perms_nvp) 1010 { 1011 if (perms_nvp != NULL) { 1012 verify(nvlist_add_nvlist(who_nvp, 1013 name, perms_nvp) == 0); 1014 } else { 1015 verify(nvlist_add_boolean(who_nvp, name) == 0); 1016 } 1017 } 1018 1019 static void 1020 helper(zfs_deleg_who_type_t who_type, uint64_t whoid, char *whostr, 1021 zfs_deleg_inherit_t inherit, nvlist_t *who_nvp, nvlist_t *perms_nvp, 1022 nvlist_t *sets_nvp) 1023 { 1024 boolean_t do_perms, do_sets; 1025 char name[ZFS_MAX_DELEG_NAME]; 1026 1027 do_perms = (nvlist_next_nvpair(perms_nvp, NULL) != NULL); 1028 do_sets = (nvlist_next_nvpair(sets_nvp, NULL) != NULL); 1029 1030 if (!do_perms && !do_sets) 1031 do_perms = do_sets = B_TRUE; 1032 1033 if (do_perms) { 1034 zfs_deleg_whokey(name, who_type, inherit, 1035 (who_type == ZFS_DELEG_NAMED_SET) ? 1036 whostr : (void *)&whoid); 1037 zfs_perms_add_to_nvlist(who_nvp, name, perms_nvp); 1038 } 1039 if (do_sets) { 1040 zfs_deleg_whokey(name, toupper(who_type), inherit, 1041 (who_type == ZFS_DELEG_NAMED_SET) ? 1042 whostr : (void *)&whoid); 1043 zfs_perms_add_to_nvlist(who_nvp, name, sets_nvp); 1044 } 1045 } 1046 1047 static void 1048 zfs_perms_add_who_nvlist(nvlist_t *who_nvp, uint64_t whoid, void *whostr, 1049 nvlist_t *perms_nvp, nvlist_t *sets_nvp, 1050 zfs_deleg_who_type_t who_type, zfs_deleg_inherit_t inherit) 1051 { 1052 if (who_type == ZFS_DELEG_NAMED_SET || who_type == ZFS_DELEG_CREATE) { 1053 helper(who_type, whoid, whostr, 0, 1054 who_nvp, perms_nvp, sets_nvp); 1055 } else { 1056 if (inherit & ZFS_DELEG_PERM_LOCAL) { 1057 helper(who_type, whoid, whostr, ZFS_DELEG_LOCAL, 1058 who_nvp, perms_nvp, sets_nvp); 1059 } 1060 if (inherit & ZFS_DELEG_PERM_DESCENDENT) { 1061 helper(who_type, whoid, whostr, ZFS_DELEG_DESCENDENT, 1062 who_nvp, perms_nvp, sets_nvp); 1063 } 1064 } 1065 } 1066 1067 /* 1068 * Construct nvlist to pass down to kernel for setting/removing permissions. 1069 * 1070 * The nvlist is constructed as a series of nvpairs with an optional embedded 1071 * nvlist of permissions to remove or set. The topmost nvpairs are the actual 1072 * base attribute named stored in the dsl. 1073 * Arguments: 1074 * 1075 * whostr: is a comma separated list of users, groups, or a single set name. 1076 * whostr may be null for everyone or create perms. 1077 * who_type: is the type of entry in whostr. Typically this will be 1078 * ZFS_DELEG_WHO_UNKNOWN. 1079 * perms: common separated list of permissions. May be null if user 1080 * is requested to remove permissions by who. 1081 * inherit: Specifies the inheritance of the permissions. Will be either 1082 * ZFS_DELEG_PERM_LOCAL and/or ZFS_DELEG_PERM_DESCENDENT. 1083 * nvp The constructed nvlist to pass to zfs_perm_set(). 1084 * The output nvp will look something like this. 1085 * ul$1234 -> {create ; destroy } 1086 * Ul$1234 -> { @myset } 1087 * s-$@myset - { snapshot; checksum; compression } 1088 */ 1089 int 1090 zfs_build_perms(zfs_handle_t *zhp, char *whostr, char *perms, 1091 zfs_deleg_who_type_t who_type, zfs_deleg_inherit_t inherit, nvlist_t **nvp) 1092 { 1093 nvlist_t *who_nvp; 1094 nvlist_t *perms_nvp = NULL; 1095 nvlist_t *sets_nvp = NULL; 1096 char errbuf[1024]; 1097 char *who_tok, *perm; 1098 int error; 1099 1100 *nvp = NULL; 1101 1102 if (perms) { 1103 if ((error = nvlist_alloc(&perms_nvp, 1104 NV_UNIQUE_NAME, 0)) != 0) { 1105 return (1); 1106 }