usr/src/uts/common/fs/zfs/dsl_deleg.c
author marks
Tue, 26 Jun 2007 07:44:24 -0700
changeset 4543 12bb2876a62e
child 4787 602d3f97842c
permissions -rw-r--r--
PSARC/2006/465 ZFS Delegated Administration PSARC/2006/577 zpool property to disable delegation PSARC/2006/625 Enhancements to zpool history PSARC/2007/228 ZFS delegation amendments PSARC/2007/295 ZFS Delegated Administration Addendum 6280676 restore "owner" property 6349470 investigate non-root restore/backup 6572465 'zpool set bootfs=...' records history as 'zfs set bootfs=...'
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
4543
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
     1
/*
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
     2
 * CDDL HEADER START
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
     3
 *
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
     4
 * The contents of this file are subject to the terms of the
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
     5
 * Common Development and Distribution License (the "License").
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
     6
 * You may not use this file except in compliance with the License.
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
     7
 *
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
     8
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
     9
 * or http://www.opensolaris.org/os/licensing.
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
    10
 * See the License for the specific language governing permissions
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
    11
 * and limitations under the License.
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
    12
 *
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
    13
 * When distributing Covered Code, include this CDDL HEADER in each
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
    14
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
    15
 * If applicable, add the following below this CDDL HEADER, with the
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
    16
 * fields enclosed by brackets "[]" replaced with your own identifying
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
    17
 * information: Portions Copyright [yyyy] [name of copyright owner]
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
    18
 *
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
    19
 * CDDL HEADER END
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
    20
 */
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
    21
/*
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
    22
 * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
    23
 * Use is subject to license terms.
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
    24
 */
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
    25
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
    26
/*
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
    27
 * DSL permissions are stored in a two level zap attribute
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
    28
 * mechanism.   The first level identifies the "class" of
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
    29
 * entry.  The class is identified by the first 2 letters of
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
    30
 * the attribute.  The second letter "l" or "d" identifies whether
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
    31
 * it is a local or descendent permission.  The first letter
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
    32
 * identifies the type of entry.
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
    33
 *
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
    34
 * ul$<id>    identifies permssions granted locally for this userid.
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
    35
 * ud$<id>    identifies permissions granted on descendent datasets for
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
    36
 *            this userid.
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
    37
 * Ul$<id>    identifies permission sets granted locally for this userid.
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
    38
 * Ud$<id>    identifies permission sets granted on descendent datasets for
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
    39
 *            this userid.
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
    40
 * gl$<id>    identifies permissions granted locally for this groupid.
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
    41
 * gd$<id>    identifies permissions granted on descendent datasets for
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
    42
 *            this groupid.
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
    43
 * Gl$<id>    identifies permission sets granted locally for this groupid.
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
    44
 * Gd$<id>    identifies permission sets granted on descendent datasets for
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
    45
 *            this groupid.
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
    46
 * el$        identifies permissions granted locally for everyone.
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
    47
 * ed$        identifies permissions granted on descendent datasets
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
    48
 *            for everyone.
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
    49
 * El$        identifies permission sets granted locally for everyone.
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
    50
 * Ed$        identifies permission sets granted to descendent datasets for
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
    51
 *            everyone.
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
    52
 * c-$        identifies permission to create at dataset creation time.
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
    53
 * C-$        identifies permission sets to grant locally at dataset creation
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
    54
 *            time.
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
    55
 * s-$@<name> permissions defined in specified set @<name>
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
    56
 * S-$@<name> Sets defined in named set @<name>
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
    57
 *
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
    58
 * Each of the above entiies points to another zap attribute that contains one
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
    59
 * attribute for each allowed permission, such as create, destroy,...
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
    60
 * All of the "upper" case class types will specify permission set names
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
    61
 * rather than permissions.
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
    62
 *
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
    63
 * Basically it looks something like this:
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
    64
 * ul$12 -> ZAP OBJ -> permissions...
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
    65
 *
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
    66
 * The ZAP OBJ is referred to as the jump object.
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
    67
 */
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
    68
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
    69
#pragma ident	"%Z%%M%	%I%	%E% SMI"
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
    70
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
    71
#include <sys/dmu.h>
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
    72
#include <sys/dmu_objset.h>
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
    73
#include <sys/dmu_tx.h>
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
    74
#include <sys/dsl_dataset.h>
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
    75
#include <sys/dsl_dir.h>
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
    76
#include <sys/dsl_prop.h>
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
    77
#include <sys/dsl_synctask.h>
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
    78
#include <sys/dsl_deleg.h>
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
    79
#include <sys/spa.h>
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
    80
#include <sys/spa_impl.h>
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
    81
#include <sys/zio_checksum.h> /* for the default checksum value */
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
    82
#include <sys/zap.h>
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
    83
#include <sys/fs/zfs.h>
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
    84
#include <sys/cred.h>
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
    85
#include <sys/sunddi.h>
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
    86
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
    87
#include "zfs_deleg.h"
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
    88
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
    89
/*
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
    90
 * Validate that user is allowed to delegate specified permissions.
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
    91
 *
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
    92
 * In order to delegate "create" you must have create"
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
    93
 * and "allow".
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
    94
 */
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
    95
int
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
    96
dsl_deleg_can_allow(char *ddname, nvlist_t *nvp, cred_t *cr)
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
    97
{
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
    98
	nvpair_t *whopair = NULL;
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
    99
	int error = 0;
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   100
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   101
	if ((error = dsl_deleg_access(ddname,
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   102
	    ZFS_DELEG_PERM_ALLOW, cr)) != 0)
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   103
		return (error);
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   104
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   105
	while (whopair = nvlist_next_nvpair(nvp, whopair)) {
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   106
		nvlist_t *perms;
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   107
		nvpair_t *permpair = NULL;
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   108
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   109
		VERIFY(nvpair_value_nvlist(whopair, &perms) == 0);
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   110
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   111
		while (permpair = nvlist_next_nvpair(perms, permpair)) {
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   112
			const char *perm = nvpair_name(permpair);
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   113
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   114
			if (strcmp(perm, ZFS_DELEG_PERM_ALLOW) == 0)
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   115
				return (EPERM);
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   116
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   117
			if ((error = dsl_deleg_access(ddname,
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   118
			    perm, cr)) != 0)
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   119
				return (error);
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   120
		}
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   121
	}
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   122
	return (error);
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   123
}
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   124
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   125
/*
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   126
 * Validate that user is allowed to unallow specified permissions.  They
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   127
 * must have the 'allow' permission, and even then can only unallow
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   128
 * perms for their uid.
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   129
 */
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   130
int
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   131
dsl_deleg_can_unallow(char *ddname, nvlist_t *nvp, cred_t *cr)
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   132
{
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   133
	nvpair_t *whopair = NULL;
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   134
	int error;
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   135
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   136
	if ((error = dsl_deleg_access(ddname,
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   137
	    ZFS_DELEG_PERM_ALLOW, cr)) != 0)
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   138
		return (error);
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   139
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   140
	while (whopair = nvlist_next_nvpair(nvp, whopair)) {
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   141
		zfs_deleg_who_type_t type = nvpair_name(whopair)[0];
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   142
		char idstr[32];
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   143
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   144
		if (type != ZFS_DELEG_USER &&
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   145
		    type != ZFS_DELEG_USER_SETS)
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   146
			return (EPERM);
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   147
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   148
		(void) snprintf(idstr, sizeof (idstr), "%lld",
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   149
		    (longlong_t)crgetuid(cr));
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   150
		if (strcmp(idstr, &nvpair_name(whopair)[3]) != 0)
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   151
			return (EPERM);
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   152
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   153
		continue;
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   154
	}
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   155
	return (0);
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   156
}
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   157
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   158
typedef struct {
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   159
	nvlist_t *p_nvp;
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   160
	boolean_t p_unset;
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   161
} perm_args_t;
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   162
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   163
static void
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   164
dsl_deleg_set_sync(void *arg1, void *arg2, cred_t *cr, dmu_tx_t *tx)
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   165
{
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   166
	dsl_dir_t *dd = arg1;
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   167
	perm_args_t *pa = arg2;
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   168
	objset_t *mos = dd->dd_pool->dp_meta_objset;
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   169
	nvpair_t *whopair = NULL;
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   170
	uint64_t zapobj = dd->dd_phys->dd_deleg_zapobj;
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   171
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   172
	if (zapobj == 0) {
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   173
		if (pa->p_unset)
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   174
			return;
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   175
		dmu_buf_will_dirty(dd->dd_dbuf, tx);
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   176
		zapobj = dd->dd_phys->dd_deleg_zapobj = zap_create(mos,
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   177
		    DMU_OT_DSL_PERMS, DMU_OT_NONE, 0, tx);
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   178
	}
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   179
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   180
	while (whopair = nvlist_next_nvpair(pa->p_nvp, whopair)) {
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   181
		const char *whokey = nvpair_name(whopair);
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   182
		nvlist_t *perms;
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   183
		nvpair_t *permpair = NULL;
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   184
		uint64_t jumpobj;
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   185
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   186
		if (nvpair_value_nvlist(whopair, &perms) != 0) {
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   187
			if (zap_lookup(mos, zapobj, whokey, 8,
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   188
			    1, &jumpobj) == 0) {
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   189
				(void) zap_remove(mos, zapobj, whokey, tx);
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   190
				VERIFY(0 == zap_destroy(mos, jumpobj, tx));
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   191
			}
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   192
			spa_history_internal_log(LOG_DS_PERM_WHO_REMOVE,
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   193
			    dd->dd_pool->dp_spa, tx, cr,
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   194
			    "%s dataset = %llu", whokey,
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   195
			    dd->dd_phys->dd_head_dataset_obj);
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   196
			continue;
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   197
		}
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   198
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   199
		if (zap_lookup(mos, zapobj, whokey, 8, 1, &jumpobj) != 0) {
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   200
			/*
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   201
			 * If object doesn't exist and we are removing
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   202
			 * it, then just continue to next item in nvlist
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   203
			 */
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   204
			if (pa->p_unset == 1)
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   205
				continue;
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   206
			jumpobj = zap_create(mos, DMU_OT_DSL_PERMS,
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   207
			    DMU_OT_NONE, 0, tx);
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   208
			VERIFY(zap_update(mos, zapobj,
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   209
			    whokey, 8, 1, &jumpobj, tx) == 0);
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   210
		}
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   211
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   212
		while (permpair = nvlist_next_nvpair(perms, permpair)) {
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   213
			const char *perm = nvpair_name(permpair);
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   214
			uint64_t n = 0;
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   215
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   216
			if (pa->p_unset) {
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   217
				(void) zap_remove(mos, jumpobj, perm, tx);
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   218
				if (zap_count(mos, jumpobj, &n) == 0 && !n) {
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   219
					(void) zap_remove(mos, zapobj,
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   220
					    whokey, tx);
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   221
					VERIFY(0 == zap_destroy(mos,
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   222
					    jumpobj, tx));
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   223
				}
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   224
			} else {
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   225
				VERIFY(zap_update(mos, jumpobj,
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   226
				    perm, 8, 1, &n, tx) == 0);
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   227
			}
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   228
			spa_history_internal_log((pa->p_unset == B_FALSE) ?
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   229
			    LOG_DS_PERM_UPDATE : LOG_DS_PERM_REMOVE,
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   230
			    dd->dd_pool->dp_spa, tx, cr,
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   231
			    "%s %s dataset = %llu", whokey, perm,
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   232
			    dd->dd_phys->dd_head_dataset_obj);
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   233
		}
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   234
	}
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   235
}
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   236
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   237
int
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   238
dsl_deleg_set(const char *ddname, nvlist_t *nvp, boolean_t unset)
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   239
{
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   240
	dsl_dir_t *dd;
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   241
	int error;
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   242
	perm_args_t pa;
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   243
	nvpair_t *whopair = NULL;
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   244
	int blocks_modified = 0;
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   245
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   246
	error = dsl_dir_open(ddname, FTAG, &dd, NULL);
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   247
	if (error)
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   248
		return (error);
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   249
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   250
	if (spa_version(dmu_objset_spa(dd->dd_pool->dp_meta_objset)) <
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   251
	    ZFS_VERSION_DELEGATED_PERMS) {
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   252
		dsl_dir_close(dd, FTAG);
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   253
		return (ENOTSUP);
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   254
	}
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   255
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   256
	while (whopair = nvlist_next_nvpair(nvp, whopair))
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   257
		blocks_modified++;
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   258
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   259
	pa.p_nvp = nvp;
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   260
	pa.p_unset = unset;
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   261
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   262
	error = dsl_sync_task_do(dd->dd_pool, NULL, dsl_deleg_set_sync,
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   263
	    dd, &pa, blocks_modified);
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   264
	dsl_dir_close(dd, FTAG);
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   265
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   266
	return (error);
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   267
}
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   268
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   269
/*
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   270
 * Find all 'allow' permissions from a given point and then continue
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   271
 * traversing up to the root.
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   272
 *
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   273
 * This function constructs an nvlist of nvlists.
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   274
 * each setpoint is an nvlist composed of an nvlist of an nvlist
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   275
 * of the individual * users/groups/everyone/create
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   276
 * permissions.
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   277
 *
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   278
 * The nvlist will look like this.
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   279
 *
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   280
 * { source fsname -> { whokeys { permissions,...}, ...}}
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   281
 *
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   282
 * The fsname nvpairs will be arranged in a bottom up order.  For example,
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   283
 * if we have the following structure a/b/c then the nvpairs for the fsnames
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   284
 * will be ordered a/b/c, a/b, a.
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   285
 */
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   286
int
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   287
dsl_deleg_get(const char *ddname, nvlist_t **nvp)
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   288
{
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   289
	dsl_dir_t *dd, *startdd;
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   290
	dsl_pool_t *dp;
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   291
	int error;
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   292
	objset_t *mos;
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   293
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   294
	error = dsl_dir_open(ddname, FTAG, &startdd, NULL);
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   295
	if (error)
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   296
		return (error);
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   297
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   298
	dp = startdd->dd_pool;
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   299
	mos = dp->dp_meta_objset;
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   300
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   301
	VERIFY(nvlist_alloc(nvp, NV_UNIQUE_NAME, KM_SLEEP) == 0);
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   302
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   303
	rw_enter(&dp->dp_config_rwlock, RW_READER);
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   304
	for (dd = startdd; dd != NULL; dd = dd->dd_parent) {
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   305
		zap_cursor_t basezc;
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   306
		zap_attribute_t baseza;
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   307
		nvlist_t *sp_nvp;
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   308
		uint64_t n;
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   309
		char source[MAXNAMELEN];
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   310
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   311
		if (dd->dd_phys->dd_deleg_zapobj &&
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   312
		    (zap_count(mos, dd->dd_phys->dd_deleg_zapobj,
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   313
		    &n) == 0) && n) {
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   314
			VERIFY(nvlist_alloc(&sp_nvp,
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   315
			    NV_UNIQUE_NAME, KM_SLEEP) == 0);
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   316
		} else {
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   317
			continue;
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   318
		}
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   319
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   320
		for (zap_cursor_init(&basezc, mos,
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   321
		    dd->dd_phys->dd_deleg_zapobj);
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   322
		    zap_cursor_retrieve(&basezc, &baseza) == 0;
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   323
		    zap_cursor_advance(&basezc)) {
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   324
			zap_cursor_t zc;
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   325
			zap_attribute_t za;
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   326
			nvlist_t *perms_nvp;
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   327
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   328
			ASSERT(baseza.za_integer_length == 8);
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   329
			ASSERT(baseza.za_num_integers == 1);
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   330
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   331
			VERIFY(nvlist_alloc(&perms_nvp,
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   332
			    NV_UNIQUE_NAME, KM_SLEEP) == 0);
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   333
			for (zap_cursor_init(&zc, mos, baseza.za_first_integer);
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   334
			    zap_cursor_retrieve(&zc, &za) == 0;
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   335
			    zap_cursor_advance(&zc)) {
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   336
				VERIFY(nvlist_add_boolean(perms_nvp,
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   337
				    za.za_name) == 0);
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   338
			}
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   339
			zap_cursor_fini(&zc);
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   340
			VERIFY(nvlist_add_nvlist(sp_nvp, baseza.za_name,
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   341
			    perms_nvp) == 0);
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   342
			nvlist_free(perms_nvp);
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   343
		}
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   344
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   345
		zap_cursor_fini(&basezc);
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   346
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   347
		dsl_dir_name(dd, source);
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   348
		VERIFY(nvlist_add_nvlist(*nvp, source, sp_nvp) == 0);
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   349
		nvlist_free(sp_nvp);
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   350
	}
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   351
	rw_exit(&dp->dp_config_rwlock);
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   352
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   353
	dsl_dir_close(startdd, FTAG);
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   354
	return (0);
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   355
}
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   356
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   357
/*
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   358
 * Routines for dsl_deleg_access() -- access checking.
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   359
 */
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   360
typedef struct perm_set {
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   361
	avl_node_t	p_node;
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   362
	char		p_setname[ZFS_MAX_DELEG_NAME];
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   363
	boolean_t	p_matched;
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   364
} perm_set_t;
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   365
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   366
static int
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   367
perm_set_compare(const void *arg1, const void *arg2)
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   368
{
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   369
	const perm_set_t *node1 = arg1;
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   370
	const perm_set_t *node2 = arg2;
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   371
	int val;
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   372
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   373
	val = strcmp(node1->p_setname, node2->p_setname);
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   374
	if (val == 0)
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   375
		return (0);
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   376
	return (val > 0 ? 1 : -1);
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   377
}
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   378
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   379
/*
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   380
 * Determine whether a specified permission exists.
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   381
 *
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   382
 * First the base attribute has to be retrieved.  i.e. ul$12
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   383
 * Once the base object has been retrieved the actual permission
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   384
 * is lookup up in the zap object the base object points to.
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   385
 *
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   386
 * Return 0 if permission exists, ENOENT if there is no whokey, EPERM if
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   387
 * there is no perm in that jumpobj.
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   388
 */
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   389
static int
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   390
dsl_check_access(objset_t *mos, uint64_t zapobj,
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   391
    char type, char checkflag, void *valp, const char *perm)
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   392
{
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   393
	int error;
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   394
	uint64_t jumpobj, zero;
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   395
	char whokey[ZFS_MAX_DELEG_NAME];
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   396
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   397
	zfs_deleg_whokey(whokey, type, checkflag, valp);
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   398
	error = zap_lookup(mos, zapobj, whokey, 8, 1, &jumpobj);
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   399
	if (error == 0) {
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   400
		error = zap_lookup(mos, jumpobj, perm, 8, 1, &zero);
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   401
		if (error == ENOENT)
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   402
			error = EPERM;
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   403
	}
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   404
	return (error);
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   405
}
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   406
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   407
/*
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   408
 * check a specified user/group for a requested permission
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   409
 */
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   410
static int
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   411
dsl_check_user_access(objset_t *os, uint64_t zapobj, const char *perm,
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   412
    int checkflag, cred_t *cr)
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   413
{
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   414
	const	gid_t *gids;
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   415
	int	ngids;
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   416
	int	i;
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   417
	uint64_t id;
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   418
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   419
	/* check for user */
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   420
	id = crgetuid(cr);
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   421
	if (dsl_check_access(os, zapobj,
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   422
	    ZFS_DELEG_USER, checkflag, &id, perm) == 0)
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   423
		return (0);
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   424
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   425
	/* check for users primary group */
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   426
	id = crgetgid(cr);
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   427
	if (dsl_check_access(os, zapobj,
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   428
	    ZFS_DELEG_GROUP, checkflag, &id, perm) == 0)
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   429
		return (0);
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   430
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   431
	/* check for everyone entry */
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   432
	id = -1;
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   433
	if (dsl_check_access(os, zapobj,
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   434
	    ZFS_DELEG_EVERYONE, checkflag, &id, perm) == 0)
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   435
		return (0);
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   436
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   437
	/* check each supplemental group user is a member of */
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   438
	ngids = crgetngroups(cr);
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   439
	gids = crgetgroups(cr);
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   440
	for (i = 0; i != ngids; i++) {
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   441
		id = gids[i];
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   442
		if (dsl_check_access(os, zapobj,
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   443
		    ZFS_DELEG_GROUP, checkflag, &id, perm) == 0)
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   444
			return (0);
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   445
	}
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   446
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   447
	return (EPERM);
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   448
}
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   449
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   450
/*
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   451
 * Iterate over the sets specified in the specified zapobj
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   452
 * and load them into the permsets avl tree.
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   453
 */
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   454
static int
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   455
dsl_load_sets(objset_t *mos, uint64_t zapobj,
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   456
    char type, char checkflag, void *valp, avl_tree_t *avl)
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   457
{
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   458
	zap_cursor_t zc;
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   459
	zap_attribute_t za;
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   460
	perm_set_t *permnode;
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   461
	avl_index_t idx;
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   462
	uint64_t jumpobj;
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   463
	int error;
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   464
	char whokey[ZFS_MAX_DELEG_NAME];
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   465
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   466
	zfs_deleg_whokey(whokey, type, checkflag, valp);
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   467
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   468
	error = zap_lookup(mos, zapobj, whokey, 8, 1, &jumpobj);
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   469
	if (error != 0)
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   470
		return (error);
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   471
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   472
	for (zap_cursor_init(&zc, mos, jumpobj);
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   473
	    zap_cursor_retrieve(&zc, &za) == 0;
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   474
	    zap_cursor_advance(&zc)) {
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   475
		permnode = kmem_alloc(sizeof (perm_set_t), KM_SLEEP);
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   476
		(void) strlcpy(permnode->p_setname, za.za_name,
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   477
		    sizeof (permnode->p_setname));
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   478
		permnode->p_matched = B_FALSE;
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   479
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   480
		if (avl_find(avl, permnode, &idx) == NULL) {
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   481
			avl_insert(avl, permnode, idx);
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   482
		} else {
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   483
			kmem_free(permnode, sizeof (perm_set_t));
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   484
		}
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   485
	}
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   486
	zap_cursor_fini(&zc);
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   487
	return (0);
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   488
}
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   489
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   490
/*
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   491
 * Load all permissions user based on cred belongs to.
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   492
 */
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   493
static void
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   494
dsl_load_user_sets(objset_t *mos, uint64_t zapobj, avl_tree_t *avl,
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   495
    char checkflag, cred_t *cr)
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   496
{
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   497
	const	gid_t *gids;
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   498
	int	ngids, i;
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   499
	uint64_t id;
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   500
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   501
	id = crgetuid(cr);
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   502
	(void) dsl_load_sets(mos, zapobj,
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   503
	    ZFS_DELEG_USER_SETS, checkflag, &id, avl);
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   504
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   505
	id = crgetgid(cr);
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   506
	(void) dsl_load_sets(mos, zapobj,
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   507
	    ZFS_DELEG_GROUP_SETS, checkflag, &id, avl);
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   508
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   509
	(void) dsl_load_sets(mos, zapobj,
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   510
	    ZFS_DELEG_EVERYONE_SETS, checkflag, NULL, avl);
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   511
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   512
	ngids = crgetngroups(cr);
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   513
	gids = crgetgroups(cr);
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   514
	for (i = 0; i != ngids; i++) {
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   515
		id = gids[i];
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   516
		(void) dsl_load_sets(mos, zapobj,
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   517
		    ZFS_DELEG_GROUP_SETS, checkflag, &id, avl);
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   518
	}
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   519
}
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   520
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   521
/*
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   522
 * Check if user has requested permission.
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   523
 */
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   524
int
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   525
dsl_deleg_access(const char *ddname, const char *perm, cred_t *cr)
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   526
{
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   527
	dsl_dir_t *dd, *startdd;
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   528
	dsl_pool_t *dp;
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   529
	void *cookie;
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   530
	int	error;
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   531
	char	checkflag = ZFS_DELEG_LOCAL;
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   532
	const char *tail;
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   533
	objset_t *mos;
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   534
	avl_tree_t permsets;
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   535
	perm_set_t *setnode;
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   536
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   537
	/*
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   538
	 * Use tail so that zfs_ioctl() code doesn't have
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   539
	 * to always to to figure out parent name in order
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   540
	 * to do access check.  for example renaming a snapshot
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   541
	 */
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   542
	error = dsl_dir_open(ddname, FTAG, &startdd, &tail);
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   543
	if (error)
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   544
		return (error);
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   545
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   546
	if (tail && tail[0] != '@') {
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   547
		dsl_dir_close(startdd, FTAG);
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   548
		return (ENOENT);
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   549
	}
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   550
	dp = startdd->dd_pool;
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   551
	mos = dp->dp_meta_objset;
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   552
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   553
	if (dsl_delegation_on(mos) == B_FALSE) {
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   554
		dsl_dir_close(startdd, FTAG);
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   555
		return (ECANCELED);
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   556
	}
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   557
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   558
	if (spa_version(dmu_objset_spa(dp->dp_meta_objset)) <
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   559
	    ZFS_VERSION_DELEGATED_PERMS) {
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   560
		dsl_dir_close(startdd, FTAG);
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   561
		return (EPERM);
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   562
	}
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   563
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   564
	avl_create(&permsets, perm_set_compare, sizeof (perm_set_t),
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   565
	    offsetof(perm_set_t, p_node));
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   566
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   567
	rw_enter(&dp->dp_config_rwlock, RW_READER);
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   568
	for (dd = startdd; dd != NULL; dd = dd->dd_parent,
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   569
	    checkflag = ZFS_DELEG_DESCENDENT) {
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   570
		uint64_t zapobj;
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   571
		boolean_t expanded;
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   572
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   573
		/*
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   574
		 * If not in global zone then make sure
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   575
		 * the zoned property is set
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   576
		 */
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   577
		if (!INGLOBALZONE(curproc)) {
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   578
			uint64_t zoned;
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   579
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   580
			if (dsl_prop_get_ds_locked(dd,
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   581
			    zfs_prop_to_name(ZFS_PROP_ZONED),
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   582
			    8, 1, &zoned, NULL) != 0)
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   583
				break;
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   584
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   585
			/*
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   586
			 * if zoned property isn't set then break
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   587
			 * out and return EPERM.
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   588
			 */
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   589
			if (!zoned)
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   590
				break;
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   591
		}
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   592
		zapobj = dd->dd_phys->dd_deleg_zapobj;
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   593
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   594
		if (zapobj == 0)
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   595
			continue;
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   596
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   597
		dsl_load_user_sets(mos, zapobj, &permsets, checkflag, cr);
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   598
		setnode = avl_first(&permsets);
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   599
again:
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   600
		expanded = B_FALSE;
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   601
		for (setnode = avl_first(&permsets); setnode;
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   602
		    setnode = AVL_NEXT(&permsets, setnode)) {
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   603
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   604
			if (setnode->p_matched == B_TRUE)
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   605
				continue;
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   606
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   607
			/* See if this set directly grants this permission */
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   608
			error = dsl_check_access(mos, zapobj,
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   609
			    ZFS_DELEG_NAMED_SET, 0, setnode->p_setname, perm);
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   610
			if (error == 0)
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   611
				goto success;
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   612
			if (error == EPERM)
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   613
				setnode->p_matched = B_TRUE;
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   614
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   615
			/* See if this set includes other sets */
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   616
			error = dsl_load_sets(mos, zapobj,
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   617
			    ZFS_DELEG_NAMED_SET_SETS, 0,
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   618
			    setnode->p_setname, &permsets);
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   619
			if (error == 0)
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   620
				setnode->p_matched = expanded = B_TRUE;
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   621
		}
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   622
		/*
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   623
		 * If we expanded any sets, that will define more sets,
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   624
		 * which we need to check.
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   625
		 */
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   626
		if (expanded)
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   627
			goto again;
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   628
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   629
		error = dsl_check_user_access(mos, zapobj, perm, checkflag, cr);
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   630
		if (error == 0)
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   631
			goto success;
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   632
	}
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   633
	error = EPERM;
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   634
success:
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   635
	rw_exit(&dp->dp_config_rwlock);
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   636
	dsl_dir_close(startdd, FTAG);
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   637
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   638
	cookie = NULL;
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   639
	while ((setnode = avl_destroy_nodes(&permsets, &cookie)) != NULL) {
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   640
		/* These sets were used but never defined! */
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   641
		kmem_free(setnode, sizeof (perm_set_t));
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   642
	}
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   643
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   644
	return (error);
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   645
}
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   646
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   647
/*
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   648
 * Other routines.
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   649
 */
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   650
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   651
static void
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   652
copy_create_perms(objset_t *mos, uint64_t pzapobj, dsl_dir_t *dd,
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   653
    boolean_t dosets, uint64_t uid, dmu_tx_t *tx)
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   654
{
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   655
	int error;
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   656
	uint64_t jumpobj, pjumpobj;
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   657
	uint64_t zero = 0;
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   658
	uint64_t zapobj = dd->dd_phys->dd_deleg_zapobj;
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   659
	zap_cursor_t zc;
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   660
	zap_attribute_t za;
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   661
	char whokey[ZFS_MAX_DELEG_NAME];
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   662
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   663
	zfs_deleg_whokey(whokey,
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   664
	    dosets ? ZFS_DELEG_CREATE_SETS : ZFS_DELEG_CREATE,
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   665
	    ZFS_DELEG_LOCAL, NULL);
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   666
	error = zap_lookup(mos, pzapobj, whokey, 8, 1, &pjumpobj);
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   667
	if (error != 0)
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   668
		return;
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   669
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   670
	zfs_deleg_whokey(whokey,
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   671
	    dosets ? ZFS_DELEG_USER_SETS : ZFS_DELEG_USER,
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   672
	    ZFS_DELEG_LOCAL, &uid);
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   673
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   674
	if (zapobj == 0) {
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   675
		dmu_buf_will_dirty(dd->dd_dbuf, tx);
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   676
		zapobj = dd->dd_phys->dd_deleg_zapobj = zap_create(mos,
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   677
		    DMU_OT_DSL_PERMS, DMU_OT_NONE, 0, tx);
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   678
	}
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   679
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   680
	if (zap_lookup(mos, zapobj, whokey, 8, 1, &jumpobj) == ENOENT) {
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   681
		jumpobj = zap_create(mos, DMU_OT_DSL_PERMS, DMU_OT_NONE, 0, tx);
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   682
		VERIFY(zap_add(mos, zapobj, whokey, 8, 1, &jumpobj, tx) == 0);
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   683
	}
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   684
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   685
	for (zap_cursor_init(&zc, mos, pjumpobj);
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   686
	    zap_cursor_retrieve(&zc, &za) == 0;
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   687
	    zap_cursor_advance(&zc)) {
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   688
		ASSERT(za.za_integer_length == 8 && za.za_num_integers == 1);
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   689
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   690
		VERIFY(zap_update(mos, jumpobj, za.za_name,
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   691
		    8, 1, &zero, tx) == 0);
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   692
	}
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   693
	zap_cursor_fini(&zc);
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   694
}
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   695
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   696
/*
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   697
 * set all create time permission on new dataset.
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   698
 */
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   699
void
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   700
dsl_deleg_set_create_perms(dsl_dir_t *sdd, dmu_tx_t *tx, cred_t *cr)
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   701
{
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   702
	dsl_dir_t *dd;
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   703
	objset_t *mos = sdd->dd_pool->dp_meta_objset;
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   704
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   705
	if (spa_version(dmu_objset_spa(sdd->dd_pool->dp_meta_objset)) <
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   706
	    ZFS_VERSION_DELEGATED_PERMS)
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   707
		return;
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   708
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   709
	for (dd = sdd->dd_parent; dd != NULL; dd = dd->dd_parent) {
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   710
		uint64_t pobj = dd->dd_phys->dd_deleg_zapobj;
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   711
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   712
		if (pobj == 0)
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   713
			continue;
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   714
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   715
		copy_create_perms(mos, pobj, sdd, B_FALSE, crgetuid(cr), tx);
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   716
		copy_create_perms(mos, pobj, sdd, B_TRUE, crgetuid(cr), tx);
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   717
	}
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   718
}
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   719
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   720
int
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   721
dsl_deleg_destroy(objset_t *mos, uint64_t zapobj, dmu_tx_t *tx)
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   722
{
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   723
	zap_cursor_t zc;
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   724
	zap_attribute_t za;
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   725
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   726
	if (zapobj == 0)
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   727
		return (0);
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   728
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   729
	for (zap_cursor_init(&zc, mos, zapobj);
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   730
	    zap_cursor_retrieve(&zc, &za) == 0;
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   731
	    zap_cursor_advance(&zc)) {
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   732
		ASSERT(za.za_integer_length == 8 && za.za_num_integers == 1);
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   733
		VERIFY(0 == zap_destroy(mos, za.za_first_integer, tx));
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   734
	}
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   735
	zap_cursor_fini(&zc);
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   736
	VERIFY(0 == zap_destroy(mos, zapobj, tx));
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   737
	return (0);
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   738
}
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   739
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   740
boolean_t
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   741
dsl_delegation_on(objset_t *os)
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   742
{
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   743
	return (os->os->os_spa->spa_delegation);
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents:
diff changeset
   744
}