zfs_ioc_snapshot: check user-prop permissions on snapshotted datasets
Previously, the permissions were checked on the pool which was obviously incorrect. After this change, zfs_check_userprops() only validates the properties without any permission checks. The permissions are checked individually for each snapshotted dataset. Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> Reviewed-by: Matt Ahrens <mahrens@delphix.com> Signed-off-by: Andriy Gapon <avg@FreeBSD.org> Closes #9179 Closes #9180
This commit is contained in:
parent
f335b8ffe1
commit
e6203d288a
|
@ -2739,10 +2739,9 @@ retry:
|
|||
* Check that all the properties are valid user properties.
|
||||
*/
|
||||
static int
|
||||
zfs_check_userprops(const char *fsname, nvlist_t *nvl)
|
||||
zfs_check_userprops(nvlist_t *nvl)
|
||||
{
|
||||
nvpair_t *pair = NULL;
|
||||
int error = 0;
|
||||
|
||||
while ((pair = nvlist_next_nvpair(nvl, pair)) != NULL) {
|
||||
const char *propname = nvpair_name(pair);
|
||||
|
@ -2751,10 +2750,6 @@ zfs_check_userprops(const char *fsname, nvlist_t *nvl)
|
|||
nvpair_type(pair) != DATA_TYPE_STRING)
|
||||
return (SET_ERROR(EINVAL));
|
||||
|
||||
if ((error = zfs_secpolicy_write_perms(fsname,
|
||||
ZFS_DELEG_PERM_USERPROP, CRED())))
|
||||
return (error);
|
||||
|
||||
if (strlen(propname) >= ZAP_MAXNAMELEN)
|
||||
return (SET_ERROR(ENAMETOOLONG));
|
||||
|
||||
|
@ -3465,19 +3460,18 @@ zfs_ioc_snapshot(const char *poolname, nvlist_t *innvl, nvlist_t *outnvl)
|
|||
nvpair_t *pair;
|
||||
|
||||
(void) nvlist_lookup_nvlist(innvl, "props", &props);
|
||||
if ((error = zfs_check_userprops(poolname, props)) != 0)
|
||||
return (error);
|
||||
|
||||
if (!nvlist_empty(props) &&
|
||||
zfs_earlier_version(poolname, SPA_VERSION_SNAP_PROPS))
|
||||
return (SET_ERROR(ENOTSUP));
|
||||
if ((error = zfs_check_userprops(props)) != 0)
|
||||
return (error);
|
||||
|
||||
snaps = fnvlist_lookup_nvlist(innvl, "snaps");
|
||||
poollen = strlen(poolname);
|
||||
for (pair = nvlist_next_nvpair(snaps, NULL); pair != NULL;
|
||||
pair = nvlist_next_nvpair(snaps, pair)) {
|
||||
const char *name = nvpair_name(pair);
|
||||
const char *cp = strchr(name, '@');
|
||||
char *cp = strchr(name, '@');
|
||||
|
||||
/*
|
||||
* The snap name must contain an @, and the part after it must
|
||||
|
@ -3494,6 +3488,18 @@ zfs_ioc_snapshot(const char *poolname, nvlist_t *innvl, nvlist_t *outnvl)
|
|||
(name[poollen] != '/' && name[poollen] != '@'))
|
||||
return (SET_ERROR(EXDEV));
|
||||
|
||||
/*
|
||||
* Check for permission to set the properties on the fs.
|
||||
*/
|
||||
if (!nvlist_empty(props)) {
|
||||
*cp = '\0';
|
||||
error = zfs_secpolicy_write_perms(name,
|
||||
ZFS_DELEG_PERM_USERPROP, CRED());
|
||||
*cp = '@';
|
||||
if (error != 0)
|
||||
return (error);
|
||||
}
|
||||
|
||||
/* This must be the only snap of this fs. */
|
||||
for (nvpair_t *pair2 = nvlist_next_nvpair(snaps, pair);
|
||||
pair2 != NULL; pair2 = nvlist_next_nvpair(snaps, pair2)) {
|
||||
|
|
Loading…
Reference in New Issue