Illumos #1644, #1645, #1646, #1647, #1708
[zfs.git] / module / zfs / dsl_deleg.c
index 6b5c842..a4d4e42 100644 (file)
@@ -20,6 +20,7 @@
  */
 /*
  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011 by Delphix. All rights reserved.
  */
 
 /*
@@ -534,10 +535,12 @@ dsl_load_user_sets(objset_t *mos, uint64_t zapobj, avl_tree_t *avl,
 }
 
 /*
- * Check if user has requested permission.
+ * Check if user has requested permission.  If descendent is set, must have
+ * descendent perms.
  */
 int
-dsl_deleg_access_impl(dsl_dataset_t *ds, const char *perm, cred_t *cr)
+dsl_deleg_access_impl(dsl_dataset_t *ds, boolean_t descendent, const char *perm,
+    cred_t *cr)
 {
        dsl_dir_t *dd;
        dsl_pool_t *dp;
@@ -558,7 +561,7 @@ dsl_deleg_access_impl(dsl_dataset_t *ds, const char *perm, cred_t *cr)
            SPA_VERSION_DELEGATED_PERMS)
                return (EPERM);
 
-       if (dsl_dataset_is_snapshot(ds)) {
+       if (dsl_dataset_is_snapshot(ds) || descendent) {
                /*
                 * Snapshots are treated as descendents only,
                 * local permissions do not apply.
@@ -651,7 +654,7 @@ dsl_deleg_access(const char *dsname, const char *perm, cred_t *cr)
        if (error)
                return (error);
 
-       error = dsl_deleg_access_impl(ds, perm, cr);
+       error = dsl_deleg_access_impl(ds, B_FALSE, perm, cr);
        dsl_dataset_rele(ds, FTAG);
 
        return (error);