xref: /illumos-gate/usr/src/uts/common/fs/zfs/zfs_ioctl.c (revision d8f839f9)
1fa9e4066Sahrens /*
2fa9e4066Sahrens  * CDDL HEADER START
3fa9e4066Sahrens  *
4fa9e4066Sahrens  * The contents of this file are subject to the terms of the
5441d80aaSlling  * Common Development and Distribution License (the "License").
6441d80aaSlling  * You may not use this file except in compliance with the License.
7fa9e4066Sahrens  *
8fa9e4066Sahrens  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9fa9e4066Sahrens  * or http://www.opensolaris.org/os/licensing.
10fa9e4066Sahrens  * See the License for the specific language governing permissions
11fa9e4066Sahrens  * and limitations under the License.
12fa9e4066Sahrens  *
13fa9e4066Sahrens  * When distributing Covered Code, include this CDDL HEADER in each
14fa9e4066Sahrens  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15fa9e4066Sahrens  * If applicable, add the following below this CDDL HEADER, with the
16fa9e4066Sahrens  * fields enclosed by brackets "[]" replaced with your own identifying
17fa9e4066Sahrens  * information: Portions Copyright [yyyy] [name of copyright owner]
18fa9e4066Sahrens  *
19fa9e4066Sahrens  * CDDL HEADER END
20fa9e4066Sahrens  */
21ad135b5dSChristopher Siden 
22fa9e4066Sahrens /*
233f9d6ad7SLin Ling  * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
240dfe541eSEvan Layton  */
250dfe541eSEvan Layton 
260dfe541eSEvan Layton /*
270d8fa8f8SMartin Matuska  * Copyright (c) 2011-2012 Pawel Jakub Dawidek. All rights reserved.
281df56adaSMartin Matuska  * Portions Copyright 2011 Martin Matuska
295878fad7SDan McDonald  * Copyright 2015, OmniTI Computer Consulting, Inc. All rights reserved.
300dfe541eSEvan Layton  * Copyright 2018 Nexenta Systems, Inc.  All rights reserved.
3128df1ae0SJason King  * Copyright 2019 Joyent, Inc.
322840dce1SChris Williamson  * Copyright (c) 2011, 2017 by Delphix. All rights reserved.
33a6f561b4SSašo Kiselkov  * Copyright (c) 2013 by Saso Kiselkov. All rights reserved.
34a7a845e4SSteven Hartland  * Copyright (c) 2013 Steven Hartland. All rights reserved.
35c3d26abcSMatthew Ahrens  * Copyright (c) 2014 Integros [integros.com]
36c8811bd3SToomas Soome  * Copyright 2016 Toomas Soome <tsoome@me.com>
376ccda740Sloli  * Copyright (c) 2017, loli10K <ezomori.nozomu@gmail.com>. All rights reserved.
38a4b8c9aaSAndrew Stormont  * Copyright 2017 RackTop Systems.
39eb633035STom Caputi  * Copyright (c) 2017, Datto, Inc. All rights reserved.
40*d8f839f9SJason King  * Copyright 2021 The University of Queensland
414445fffbSMatthew Ahrens  */
424445fffbSMatthew Ahrens 
434445fffbSMatthew Ahrens /*
444445fffbSMatthew Ahrens  * ZFS ioctls.
454445fffbSMatthew Ahrens  *
464445fffbSMatthew Ahrens  * This file handles the ioctls to /dev/zfs, used for configuring ZFS storage
474445fffbSMatthew Ahrens  * pools and filesystems, e.g. with /sbin/zfs and /sbin/zpool.
484445fffbSMatthew Ahrens  *
494445fffbSMatthew Ahrens  * There are two ways that we handle ioctls: the legacy way where almost
504445fffbSMatthew Ahrens  * all of the logic is in the ioctl callback, and the new way where most
514445fffbSMatthew Ahrens  * of the marshalling is handled in the common entry point, zfsdev_ioctl().
524445fffbSMatthew Ahrens  *
534445fffbSMatthew Ahrens  * Non-legacy ioctls should be registered by calling
544445fffbSMatthew Ahrens  * zfs_ioctl_register() from zfs_ioctl_init().  The ioctl is invoked
554445fffbSMatthew Ahrens  * from userland by lzc_ioctl().
564445fffbSMatthew Ahrens  *
574445fffbSMatthew Ahrens  * The registration arguments are as follows:
584445fffbSMatthew Ahrens  *
594445fffbSMatthew Ahrens  * const char *name
604445fffbSMatthew Ahrens  *   The name of the ioctl.  This is used for history logging.  If the
614445fffbSMatthew Ahrens  *   ioctl returns successfully (the callback returns 0), and allow_log
624445fffbSMatthew Ahrens  *   is true, then a history log entry will be recorded with the input &
634445fffbSMatthew Ahrens  *   output nvlists.  The log entry can be printed with "zpool history -i".
644445fffbSMatthew Ahrens  *
654445fffbSMatthew Ahrens  * zfs_ioc_t ioc
664445fffbSMatthew Ahrens  *   The ioctl request number, which userland will pass to ioctl(2).
677ac89354SDon Brady  *   We want newer versions of libzfs and libzfs_core to run against
687ac89354SDon Brady  *   existing zfs kernel modules (i.e. a deferred reboot after an update).
697ac89354SDon Brady  *   Therefore the ioctl numbers cannot change from release to release.
704445fffbSMatthew Ahrens  *
714445fffbSMatthew Ahrens  * zfs_secpolicy_func_t *secpolicy
724445fffbSMatthew Ahrens  *   This function will be called before the zfs_ioc_func_t, to
734445fffbSMatthew Ahrens  *   determine if this operation is permitted.  It should return EPERM
744445fffbSMatthew Ahrens  *   on failure, and 0 on success.  Checks include determining if the
754445fffbSMatthew Ahrens  *   dataset is visible in this zone, and if the user has either all
764445fffbSMatthew Ahrens  *   zfs privileges in the zone (SYS_MOUNT), or has been granted permission
774445fffbSMatthew Ahrens  *   to do this operation on this dataset with "zfs allow".
784445fffbSMatthew Ahrens  *
794445fffbSMatthew Ahrens  * zfs_ioc_namecheck_t namecheck
804445fffbSMatthew Ahrens  *   This specifies what to expect in the zfs_cmd_t:zc_name -- a pool
814445fffbSMatthew Ahrens  *   name, a dataset name, or nothing.  If the name is not well-formed,
824445fffbSMatthew Ahrens  *   the ioctl will fail and the callback will not be called.
834445fffbSMatthew Ahrens  *   Therefore, the callback can assume that the name is well-formed
844445fffbSMatthew Ahrens  *   (e.g. is null-terminated, doesn't have more than one '@' character,
854445fffbSMatthew Ahrens  *   doesn't have invalid characters).
864445fffbSMatthew Ahrens  *
874445fffbSMatthew Ahrens  * zfs_ioc_poolcheck_t pool_check
884445fffbSMatthew Ahrens  *   This specifies requirements on the pool state.  If the pool does
894445fffbSMatthew Ahrens  *   not meet them (is suspended or is readonly), the ioctl will fail
904445fffbSMatthew Ahrens  *   and the callback will not be called.  If any checks are specified
914445fffbSMatthew Ahrens  *   (i.e. it is not POOL_CHECK_NONE), namecheck must not be NO_NAME.
924445fffbSMatthew Ahrens  *   Multiple checks can be or-ed together (e.g. POOL_CHECK_SUSPENDED |
934445fffbSMatthew Ahrens  *   POOL_CHECK_READONLY).
944445fffbSMatthew Ahrens  *
957ac89354SDon Brady  * zfs_ioc_key_t *nvl_keys
967ac89354SDon Brady  *  The list of expected/allowable innvl input keys. This list is used
977ac89354SDon Brady  *  to validate the nvlist input to the ioctl.
987ac89354SDon Brady  *
994445fffbSMatthew Ahrens  * boolean_t smush_outnvlist
1004445fffbSMatthew Ahrens  *   If smush_outnvlist is true, then the output is presumed to be a
1014445fffbSMatthew Ahrens  *   list of errors, and it will be "smushed" down to fit into the
1024445fffbSMatthew Ahrens  *   caller's buffer, by removing some entries and replacing them with a
1034445fffbSMatthew Ahrens  *   single "N_MORE_ERRORS" entry indicating how many were removed.  See
1044445fffbSMatthew Ahrens  *   nvlist_smush() for details.  If smush_outnvlist is false, and the
1054445fffbSMatthew Ahrens  *   outnvlist does not fit into the userland-provided buffer, then the
1064445fffbSMatthew Ahrens  *   ioctl will fail with ENOMEM.
1074445fffbSMatthew Ahrens  *
1084445fffbSMatthew Ahrens  * zfs_ioc_func_t *func
1094445fffbSMatthew Ahrens  *   The callback function that will perform the operation.
1104445fffbSMatthew Ahrens  *
1114445fffbSMatthew Ahrens  *   The callback should return 0 on success, or an error number on
1124445fffbSMatthew Ahrens  *   failure.  If the function fails, the userland ioctl will return -1,
1134445fffbSMatthew Ahrens  *   and errno will be set to the callback's return value.  The callback
1144445fffbSMatthew Ahrens  *   will be called with the following arguments:
1154445fffbSMatthew Ahrens  *
1164445fffbSMatthew Ahrens  *   const char *name
1174445fffbSMatthew Ahrens  *     The name of the pool or dataset to operate on, from
1184445fffbSMatthew Ahrens  *     zfs_cmd_t:zc_name.  The 'namecheck' argument specifies the
1194445fffbSMatthew Ahrens  *     expected type (pool, dataset, or none).
1204445fffbSMatthew Ahrens  *
1214445fffbSMatthew Ahrens  *   nvlist_t *innvl
1224445fffbSMatthew Ahrens  *     The input nvlist, deserialized from zfs_cmd_t:zc_nvlist_src.  Or
1234445fffbSMatthew Ahrens  *     NULL if no input nvlist was provided.  Changes to this nvlist are
1244445fffbSMatthew Ahrens  *     ignored.  If the input nvlist could not be deserialized, the
1254445fffbSMatthew Ahrens  *     ioctl will fail and the callback will not be called.
1264445fffbSMatthew Ahrens  *
1274445fffbSMatthew Ahrens  *   nvlist_t *outnvl
1284445fffbSMatthew Ahrens  *     The output nvlist, initially empty.  The callback can fill it in,
1294445fffbSMatthew Ahrens  *     and it will be returned to userland by serializing it into
1304445fffbSMatthew Ahrens  *     zfs_cmd_t:zc_nvlist_dst.  If it is non-empty, and serialization
1314445fffbSMatthew Ahrens  *     fails (e.g. because the caller didn't supply a large enough
1324445fffbSMatthew Ahrens  *     buffer), then the overall ioctl will fail.  See the
1334445fffbSMatthew Ahrens  *     'smush_nvlist' argument above for additional behaviors.
1344445fffbSMatthew Ahrens  *
1354445fffbSMatthew Ahrens  *     There are two typical uses of the output nvlist:
1364445fffbSMatthew Ahrens  *       - To return state, e.g. property values.  In this case,
1374445fffbSMatthew Ahrens  *         smush_outnvlist should be false.  If the buffer was not large
1384445fffbSMatthew Ahrens  *         enough, the caller will reallocate a larger buffer and try
1394445fffbSMatthew Ahrens  *         the ioctl again.
1404445fffbSMatthew Ahrens  *
1414445fffbSMatthew Ahrens  *       - To return multiple errors from an ioctl which makes on-disk
1424445fffbSMatthew Ahrens  *         changes.  In this case, smush_outnvlist should be true.
1434445fffbSMatthew Ahrens  *         Ioctls which make on-disk modifications should generally not
1444445fffbSMatthew Ahrens  *         use the outnvl if they succeed, because the caller can not
1454445fffbSMatthew Ahrens  *         distinguish between the operation failing, and
1464445fffbSMatthew Ahrens  *         deserialization failing.
1477ac89354SDon Brady  *
1487ac89354SDon Brady  * IOCTL Interface Errors
1497ac89354SDon Brady  *
1507ac89354SDon Brady  * The following ioctl input errors can be returned:
1517ac89354SDon Brady  *   ZFS_ERR_IOC_CMD_UNAVAIL	the ioctl number is not supported by kernel
1527ac89354SDon Brady  *   ZFS_ERR_IOC_ARG_UNAVAIL	an input argument is not supported by kernel
1537ac89354SDon Brady  *   ZFS_ERR_IOC_ARG_REQUIRED	a required input argument is missing
1547ac89354SDon Brady  *   ZFS_ERR_IOC_ARG_BADTYPE	an input argument has an invalid type
155e9103aaeSGarrett D'Amore  */
157fa9e4066Sahrens #include <sys/types.h>
158fa9e4066Sahrens #include <sys/param.h>
159fa9e4066Sahrens #include <sys/errno.h>
160fa9e4066Sahrens #include <sys/uio.h>
161fa9e4066Sahrens #include <sys/buf.h>
162fa9e4066Sahrens #include <sys/modctl.h>
163fa9e4066Sahrens #include <sys/open.h>
164fa9e4066Sahrens #include <sys/file.h>
165fa9e4066Sahrens #include <sys/kmem.h>
166fa9e4066Sahrens #include <sys/conf.h>
167fa9e4066Sahrens #include <sys/cmn_err.h>
168fa9e4066Sahrens #include <sys/stat.h>
169fa9e4066Sahrens #include <sys/zfs_ioctl.h>
1704201a95eSRic Aleshire #include <sys/zfs_vfsops.h>
171da6c28aaSamw #include <sys/zfs_znode.h>
172fa9e4066Sahrens #include <sys/zap.h>
173fa9e4066Sahrens #include <sys/spa.h>
174b1b8ab34Slling #include <sys/spa_impl.h>
175fa9e4066Sahrens #include <sys/vdev.h>
1764201a95eSRic Aleshire #include <sys/priv_impl.h>
177fa9e4066Sahrens #include <sys/dmu.h>
178fa9e4066Sahrens #include <sys/dsl_dir.h>
179fa9e4066Sahrens #include <sys/dsl_dataset.h>
180fa9e4066Sahrens #include <sys/dsl_prop.h>
181ecd6cf80Smarks #include <sys/dsl_deleg.h>
182ecd6cf80Smarks #include <sys/dmu_objset.h>
1834e3c9f44SBill Pijewski #include <sys/dmu_impl.h>
1843b2aab18SMatthew Ahrens #include <sys/dmu_tx.h>
185fa9e4066Sahrens #include <sys/ddi.h>
186fa9e4066Sahrens #include <sys/sunddi.h>
187fa9e4066Sahrens #include <sys/sunldi.h>
188fa9e4066Sahrens #include <sys/policy.h>
189fa9e4066Sahrens #include <sys/zone.h>
190fa9e4066Sahrens #include <sys/nvpair.h>
191fa9e4066Sahrens #include <sys/pathname.h>
192fa9e4066Sahrens #include <sys/mount.h>
193fa9e4066Sahrens #include <sys/sdt.h>
194fa9e4066Sahrens #include <sys/fs/zfs.h>
195fa9e4066Sahrens #include <sys/zfs_ctldir.h>
196da6c28aaSamw #include <sys/zfs_dir.h>
197c99e4bdcSChris Kirby #include <sys/zfs_onexit.h>
198a2eea2e1Sahrens #include <sys/zvol.h>
1993f9d6ad7SLin Ling #include <sys/dsl_scan.h>
200ecd6cf80Smarks #include <sharefs/share.h>
201f18faf3fSek #include <sys/dmu_objset.h>
2020fa1b3ccSPaul Dagnelie #include <sys/dmu_recv.h>
2033b2aab18SMatthew Ahrens #include <sys/dmu_send.h>
2043b2aab18SMatthew Ahrens #include <sys/dsl_destroy.h>
20578f17100SMatthew Ahrens #include <sys/dsl_bookmark.h>
2063b2aab18SMatthew Ahrens #include <sys/dsl_userhold.h>
207a6f561b4SSašo Kiselkov #include <sys/zfeature.h>
208dfc11533SChris Williamson #include <sys/zcp.h>
20945818ee1SMatthew Ahrens #include <sys/zio_checksum.h>
2105cabbc6bSPrashanth Sreenivasa #include <sys/vdev_removal.h>
211094e47e9SGeorge Wilson #include <sys/vdev_impl.h>
212094e47e9SGeorge Wilson #include <sys/vdev_initialize.h>
213084fd14fSBrian Behlendorf #include <sys/vdev_trim.h>
214eb633035STom Caputi #include <sys/dsl_crypt.h>
216fa9e4066Sahrens #include "zfs_namecheck.h"
217e9dbad6fSeschrock #include "zfs_prop.h"
218ecd6cf80Smarks #include "zfs_deleg.h"
2190a586ceaSMark Shellenbaum #include "zfs_comutil.h"
221dfc11533SChris Williamson #include "lua.h"
222dfc11533SChris Williamson #include "lauxlib.h"
223dfc11533SChris Williamson 
224fa9e4066Sahrens extern struct modlfs zfs_modlfs;
226fa9e4066Sahrens extern void zfs_init(void);
227fa9e4066Sahrens extern void zfs_fini(void);
229fa9e4066Sahrens ldi_ident_t zfs_li = NULL;
230fa9e4066Sahrens dev_info_t *zfs_dip;
2324445fffbSMatthew Ahrens uint_t zfs_fsyncer_key;
2334445fffbSMatthew Ahrens extern uint_t rrw_tsd_key;
2344445fffbSMatthew Ahrens static uint_t zfs_allow_log_key;
2354445fffbSMatthew Ahrens 
2364445fffbSMatthew Ahrens typedef int zfs_ioc_legacy_func_t(zfs_cmd_t *);
2374445fffbSMatthew Ahrens typedef int zfs_ioc_func_t(const char *, nvlist_t *, nvlist_t *);
2384445fffbSMatthew Ahrens typedef int zfs_secpolicy_func_t(zfs_cmd_t *, nvlist_t *, cred_t *);
2407ac89354SDon Brady /*
2417ac89354SDon Brady  * IOC Keys are used to document and validate user->kernel interface inputs.
2427ac89354SDon Brady  * See zfs_keys_recv_new for an example declaration. Any key name that is not
2437ac89354SDon Brady  * listed will be rejected as input.
2447ac89354SDon Brady  *
2457ac89354SDon Brady  * The keyname 'optional' is always allowed, and must be an nvlist if present.
2467ac89354SDon Brady  * Arguments which older kernels can safely ignore can be placed under the
2477ac89354SDon Brady  * "optional" key.
2487ac89354SDon Brady  *
2497ac89354SDon Brady  * When adding new keys to an existing ioc for new functionality, consider:
2507ac89354SDon Brady  *	- adding an entry into zfs_sysfs.c zfs_features[] list
2517ac89354SDon Brady  *	- updating the libzfs_input_check.c test utility
2527ac89354SDon Brady  *
2537ac89354SDon Brady  * Note: in the ZK_WILDCARDLIST case, the name serves as documentation
2547ac89354SDon Brady  * for the expected name (bookmark, snapshot, property, etc) but there
2557ac89354SDon Brady  * is no validation in the preflight zfs_check_input_nvpairs() check.
2567ac89354SDon Brady  */
2577ac89354SDon Brady typedef enum {
2587ac89354SDon Brady 	ZK_OPTIONAL = 1 << 0,		/* pair is optional */
2597ac89354SDon Brady 	ZK_WILDCARDLIST = 1 << 1,	/* one or more unspecified key names */
2607ac89354SDon Brady } ioc_key_flag_t;
2617ac89354SDon Brady 
2627ac89354SDon Brady /* DATA_TYPE_ANY is used when zkey_type can vary. */
2637ac89354SDon Brady #define	DATA_TYPE_ANY	DATA_TYPE_UNKNOWN
2647ac89354SDon Brady 
2657ac89354SDon Brady typedef struct zfs_ioc_key {
2667ac89354SDon Brady 	const char	*zkey_name;
2677ac89354SDon Brady 	data_type_t	zkey_type;
2687ac89354SDon Brady 	ioc_key_flag_t	zkey_flags;
2697ac89354SDon Brady } zfs_ioc_key_t;
2707ac89354SDon Brady 
27154d692b7SGeorge Wilson typedef enum {
27254d692b7SGeorge Wilson 	NO_NAME,
27354d692b7SGeorge Wilson 	POOL_NAME,
27454d692b7SGeorge Wilson 	DATASET_NAME
27554d692b7SGeorge Wilson } zfs_ioc_namecheck_t;
27654d692b7SGeorge Wilson 
277f9af39baSGeorge Wilson typedef enum {
278f9af39baSGeorge Wilson 	POOL_CHECK_NONE		= 1 << 0,
279f9af39baSGeorge Wilson 	POOL_CHECK_SUSPENDED	= 1 << 1,
2804445fffbSMatthew Ahrens 	POOL_CHECK_READONLY	= 1 << 2,
281f9af39baSGeorge Wilson } zfs_ioc_poolcheck_t;
282f9af39baSGeorge Wilson 
283fa9e4066Sahrens typedef struct zfs_ioc_vec {
2844445fffbSMatthew Ahrens 	zfs_ioc_legacy_func_t	*zvec_legacy_func;
285fa9e4066Sahrens 	zfs_ioc_func_t		*zvec_func;
286fa9e4066Sahrens 	zfs_secpolicy_func_t	*zvec_secpolicy;
28754d692b7SGeorge Wilson 	zfs_ioc_namecheck_t	zvec_namecheck;
2884445fffbSMatthew Ahrens 	boolean_t		zvec_allow_log;
289f9af39baSGeorge Wilson 	zfs_ioc_poolcheck_t	zvec_pool_check;
2904445fffbSMatthew Ahrens 	boolean_t		zvec_smush_outnvlist;
2914445fffbSMatthew Ahrens 	const char		*zvec_name;
2927ac89354SDon Brady 	const zfs_ioc_key_t	*zvec_nvl_keys;
2937ac89354SDon Brady 	size_t			zvec_nvl_key_count;
294fa9e4066Sahrens } zfs_ioc_vec_t;
29614843421SMatthew Ahrens /* This array is indexed by zfs_userquota_prop_t */
29714843421SMatthew Ahrens static const char *userquota_perms[] = {
29814843421SMatthew Ahrens 	ZFS_DELEG_PERM_USERUSED,
29914843421SMatthew Ahrens 	ZFS_DELEG_PERM_USERQUOTA,
30014843421SMatthew Ahrens 	ZFS_DELEG_PERM_GROUPUSED,
30114843421SMatthew Ahrens 	ZFS_DELEG_PERM_GROUPQUOTA,
31014843421SMatthew Ahrens };
31114843421SMatthew Ahrens 
31214843421SMatthew Ahrens static int zfs_ioc_userspace_upgrade(zfs_cmd_t *zc);
313f67950b2SNasf-Fan static int zfs_ioc_id_quota_upgrade(zfs_cmd_t *zc);
31492241e0bSTom Erickson static int zfs_check_settable(const char *name, nvpair_t *property,
31592241e0bSTom Erickson     cred_t *cr);
31692241e0bSTom Erickson static int zfs_check_clearable(char *dataset, nvlist_t *props,
31792241e0bSTom Erickson     nvlist_t **errors);
3180a48a24eStimh static int zfs_fill_zplprops_root(uint64_t, nvlist_t *, nvlist_t *,
3190a48a24eStimh     boolean_t *);
3204445fffbSMatthew Ahrens int zfs_set_prop_nvlist(const char *, zprop_source_t, nvlist_t *, nvlist_t *);
3214445fffbSMatthew Ahrens static int get_nvlist(uint64_t nvl, uint64_t size, int iflag, nvlist_t **nvp);
3232acef22dSMatthew Ahrens static int zfs_prop_activate_feature(spa_t *spa, spa_feature_t feature);
324a6f561b4SSašo Kiselkov 
325fa9e4066Sahrens /* _NOTE(PRINTFLIKE(4)) - this is printf-like, but lint is too whiney */
326fa9e4066Sahrens void
__dprintf(const char * file,const char * func,int line,const char * fmt,...)327fa9e4066Sahrens __dprintf(const char *file, const char *func, int line, const char *fmt, ...)
328fa9e4066Sahrens {
329fa9e4066Sahrens 	const char *newfile;
3303f9d6ad7SLin Ling 	char buf[512];
331fa9e4066Sahrens 	va_list adx;
333fa9e4066Sahrens 	/*
334fa9e4066Sahrens 	 * Get rid of annoying "../common/" prefix to filename.
335fa9e4066Sahrens 	 */
336fa9e4066Sahrens 	newfile = strrchr(file, '/');
337fa9e4066Sahrens 	if (newfile != NULL) {
338fa9e4066Sahrens 		newfile = newfile + 1; /* Get rid of leading / */
339fa9e4066Sahrens 	} else {
340fa9e4066Sahrens 		newfile = file;
341fa9e4066Sahrens 	}
343fa9e4066Sahrens 	va_start(adx, fmt);
344fa9e4066Sahrens 	(void) vsnprintf(buf, sizeof (buf), fmt, adx);
345fa9e4066Sahrens 	va_end(adx);
347fa9e4066Sahrens 	/*
348fa9e4066Sahrens 	 * To get this data, use the zfs-dprintf probe as so:
349fa9e4066Sahrens 	 * dtrace -q -n 'zfs-dprintf \
350fa9e4066Sahrens 	 *	/stringof(arg0) == "dbuf.c"/ \
351fa9e4066Sahrens 	 *	{printf("%s: %s", stringof(arg1), stringof(arg3))}'
352fa9e4066Sahrens 	 * arg0 = file name
353fa9e4066Sahrens 	 * arg1 = function name
354fa9e4066Sahrens 	 * arg2 = line number
355fa9e4066Sahrens 	 * arg3 = message
356fa9e4066Sahrens 	 */
357fa9e4066Sahrens 	DTRACE_PROBE4(zfs__dprintf,
358fa9e4066Sahrens 	    char *, newfile, char *, func, int, line, char *, buf);
359fa9e4066Sahrens }
361ecd6cf80Smarks static void
history_str_free(char * buf)362228975ccSek history_str_free(char *buf)
363228975ccSek {
364228975ccSek 	kmem_free(buf, HIS_MAX_RECORD_LEN);
365228975ccSek }
367228975ccSek static char *
history_str_get(zfs_cmd_t * zc)368228975ccSek history_str_get(zfs_cmd_t *zc)
369ecd6cf80Smarks {
37040feaa91Sahrens 	char *buf;
372dd328bf6SToomas Soome 	if (zc->zc_history == 0)
373228975ccSek 		return (NULL);
375ecd6cf80Smarks 	buf = kmem_alloc(HIS_MAX_RECORD_LEN, KM_SLEEP);
376ecd6cf80Smarks 	if (copyinstr((void *)(uintptr_t)zc->zc_history,
377ecd6cf80Smarks 	    buf, HIS_MAX_RECORD_LEN, NULL) != 0) {
378228975ccSek 		history_str_free(buf);
379228975ccSek 		return (NULL);
380ecd6cf80Smarks 	}
382ecd6cf80Smarks 	buf[HIS_MAX_RECORD_LEN -1] = '\0';
384228975ccSek 	return (buf);
385228975ccSek }
38715e6edf1Sgw /*
38815e6edf1Sgw  * Check to see if the named dataset is currently defined as bootable
38915e6edf1Sgw  */
39015e6edf1Sgw static boolean_t
zfs_is_bootfs(const char * name)39115e6edf1Sgw zfs_is_bootfs(const char *name)
39215e6edf1Sgw {
393503ad85cSMatthew Ahrens 	objset_t *os;
395503ad85cSMatthew Ahrens 	if (dmu_objset_hold(name, FTAG, &os) == 0) {
396503ad85cSMatthew Ahrens 		boolean_t ret;
397b24ab676SJeff Bonwick 		ret = (dmu_objset_id(os) == spa_bootfs(dmu_objset_spa(os)));
398503ad85cSMatthew Ahrens 		dmu_objset_rele(os, FTAG);
399503ad85cSMatthew Ahrens 		return (ret);
40015e6edf1Sgw 	}
401503ad85cSMatthew Ahrens 	return (B_FALSE);
40215e6edf1Sgw }
404c2a93d44Stimh /*
405f7170741SWill Andrews  * Return non-zero if the spa version is less than requested version.
406c2a93d44Stimh  */
407da6c28aaSamw static int
zfs_earlier_version(const char * name,int version)4080a48a24eStimh zfs_earlier_version(const char *name, int version)
409da6c28aaSamw {
410da6c28aaSamw 	spa_t *spa;
412da6c28aaSamw 	if (spa_open(name, &spa, FTAG) == 0) {
413da6c28aaSamw 		if (spa_version(spa) < version) {
414da6c28aaSamw 			spa_close(spa, FTAG);
415da6c28aaSamw 			return (1);
416da6c28aaSamw 		}
417da6c28aaSamw 		spa_close(spa, FTAG);
418da6c28aaSamw 	}
419da6c28aaSamw 	return (0);
420da6c28aaSamw }
4229e6eda55Smarks /*
423745cd3c5Smaybee  * Return TRUE if the ZPL version is less than requested version.
4249e6eda55Smarks  */
425745cd3c5Smaybee static boolean_t
zpl_earlier_version(const char * name,int version)426745cd3c5Smaybee zpl_earlier_version(const char *name, int version)
4279e6eda55Smarks {
4289e6eda55Smarks 	objset_t *os;
429745cd3c5Smaybee 	boolean_t rc = B_TRUE;
431503ad85cSMatthew Ahrens 	if (dmu_objset_hold(name, FTAG, &os) == 0) {
432745cd3c5Smaybee 		uint64_t zplversion;
434503ad85cSMatthew Ahrens 		if (dmu_objset_type(os) != DMU_OST_ZFS) {
435503ad85cSMatthew Ahrens 			dmu_objset_rele(os, FTAG);
436503ad85cSMatthew Ahrens 			return (B_TRUE);
437503ad85cSMatthew Ahrens 		}
438503ad85cSMatthew Ahrens 		/* XXX reading from non-owned objset */
439745cd3c5Smaybee 		if (zfs_get_zplprop(os, ZFS_PROP_VERSION, &zplversion) == 0)
440745cd3c5Smaybee 			rc = zplversion < version;
441503ad85cSMatthew Ahrens 		dmu_objset_rele(os, FTAG);
4429e6eda55Smarks 	}
4439e6eda55Smarks 	return (rc);
4449e6eda55Smarks }
446228975ccSek static void
zfs_log_history(zfs_cmd_t * zc)447228975ccSek zfs_log_history(zfs_cmd_t *zc)
448228975ccSek {
449228975ccSek 	spa_t *spa;
450228975ccSek 	char *buf;
452228975ccSek 	if ((buf = history_str_get(zc)) == NULL)
453228975ccSek 		return;
455228975ccSek 	if (spa_open(zc->zc_name, &spa, FTAG) == 0) {
456228975ccSek 		if (spa_version(spa) >= SPA_VERSION_ZPOOL_HISTORY)
4574445fffbSMatthew Ahrens 			(void) spa_history_log(spa, buf);
458228975ccSek 		spa_close(spa, FTAG);
459228975ccSek 	}
460228975ccSek 	history_str_free(buf);
461ecd6cf80Smarks }
463fa9e4066Sahrens /*
464fa9e4066Sahrens  * Policy for top-level read operations (list pools).  Requires no privileges,
465fa9e4066Sahrens  * and can be used in the local zone, as there is no associated dataset.
466fa9e4066Sahrens  */
467fa9e4066Sahrens /* ARGSUSED */
468fa9e4066Sahrens static int
zfs_secpolicy_none(zfs_cmd_t * zc,nvlist_t * innvl,cred_t * cr)4694445fffbSMatthew Ahrens zfs_secpolicy_none(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr)
470fa9e4066Sahrens {
471fa9e4066Sahrens 	return (0);
472fa9e4066Sahrens }
474fa9e4066Sahrens /*
475fa9e4066Sahrens  * Policy for dataset read operations (list children, get statistics).  Requires
476fa9e4066Sahrens  * no privileges, but must be visible in the local zone.
477fa9e4066Sahrens  */
478fa9e4066Sahrens /* ARGSUSED */
479fa9e4066Sahrens static int
zfs_secpolicy_read(zfs_cmd_t * zc,nvlist_t * innvl,cred_t * cr)4804445fffbSMatthew Ahrens zfs_secpolicy_read(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr)
481fa9e4066Sahrens {
482fa9e4066Sahrens 	if (INGLOBALZONE(curproc) ||
483ecd6cf80Smarks 	    zone_dataset_visible(zc->zc_name, NULL))
484fa9e4066Sahrens 		return (0);
486be6fd75aSMatthew Ahrens 	return (SET_ERROR(ENOENT));
487fa9e4066Sahrens }
489fa9e4066Sahrens static int
zfs_dozonecheck_impl(const char * dataset,uint64_t zoned,cred_t * cr)490a7f53a56SChris Kirby zfs_dozonecheck_impl(const char *dataset, uint64_t zoned, cred_t *cr)
491fa9e4066Sahrens {
492fa9e4066Sahrens 	int writable = 1;
494fa9e4066Sahrens 	/*
495fa9e4066Sahrens 	 * The dataset must be visible by this zone -- check this first
496fa9e4066Sahrens 	 * so they don't see EPERM on something they shouldn't know about.
497fa9e4066Sahrens 	 */
498fa9e4066Sahrens 	if (!INGLOBALZONE(curproc) &&
499fa9e4066Sahrens 	    !zone_dataset_visible(dataset, &writable))
500be6fd75aSMatthew Ahrens 		return (SET_ERROR(ENOENT));
502fa9e4066Sahrens 	if (INGLOBALZONE(curproc)) {
503fa9e4066Sahrens 		/*
504fa9e4066Sahrens 		 * If the fs is zoned, only root can access it from the
505fa9e4066Sahrens 		 * global zone.
506fa9e4066Sahrens 		 */
507fa9e4066Sahrens 		if (secpolicy_zfs(cr) && zoned)
508be6fd75aSMatthew Ahrens 			return (SET_ERROR(EPERM));
509fa9e4066Sahrens 	} else {
510fa9e4066Sahrens 		/*
511fa9e4066Sahrens 		 * If we are in a local zone, the 'zoned' property must be set.
512fa9e4066Sahrens 		 */
513fa9e4066Sahrens 		if (!zoned)
514be6fd75aSMatthew Ahrens 			return (SET_ERROR(EPERM));
516fa9e4066Sahrens 		/* must be writable by this zone */
517fa9e4066Sahrens 		if (!writable)
518be6fd75aSMatthew Ahrens 			return (SET_ERROR(EPERM));
519fa9e4066Sahrens 	}
520fa9e4066Sahrens 	return (0);
521fa9e4066Sahrens }
523a7f53a56SChris Kirby static int
zfs_dozonecheck(const char * dataset,cred_t * cr)524a7f53a56SChris Kirby zfs_dozonecheck(const char *dataset, cred_t *cr)
525a7f53a56SChris Kirby {
526a7f53a56SChris Kirby 	uint64_t zoned;
527a7f53a56SChris Kirby 
528a7f53a56SChris Kirby 	if (dsl_prop_get_integer(dataset, "zoned", &zoned, NULL))
529be6fd75aSMatthew Ahrens 		return (SET_ERROR(ENOENT));
530a7f53a56SChris Kirby 
531a7f53a56SChris Kirby 	return (zfs_dozonecheck_impl(dataset, zoned, cr));
532a7f53a56SChris Kirby }
533a7f53a56SChris Kirby 
534a7f53a56SChris Kirby static int
zfs_dozonecheck_ds(const char * dataset,dsl_dataset_t * ds,cred_t * cr)535a7f53a56SChris Kirby zfs_dozonecheck_ds(const char *dataset, dsl_dataset_t *ds, cred_t *cr)
536a7f53a56SChris Kirby {
537a7f53a56SChris Kirby 	uint64_t zoned;
538a7f53a56SChris Kirby 
5393b2aab18SMatthew Ahrens 	if (dsl_prop_get_int_ds(ds, "zoned", &zoned))
540be6fd75aSMatthew Ahrens 		return (SET_ERROR(ENOENT));
541a7f53a56SChris Kirby 
542a7f53a56SChris Kirby 	return (zfs_dozonecheck_impl(dataset, zoned, cr));
543a7f53a56SChris Kirby }
544a7f53a56SChris Kirby 
5454445fffbSMatthew Ahrens static int
zfs_secpolicy_write_perms_ds(const char * name,dsl_dataset_t * ds,const char * perm,cred_t * cr)5463b2aab18SMatthew Ahrens zfs_secpolicy_write_perms_ds(const char *name, dsl_dataset_t *ds,
5473b2aab18SMatthew Ahrens     const char *perm, cred_t *cr)
548fa9e4066Sahrens {
549fa9e4066Sahrens 	int error;
55119b94df9SMatthew Ahrens 	error = zfs_dozonecheck_ds(name, ds, cr);
552ecd6cf80Smarks 	if (error == 0) {
553ecd6cf80Smarks 		error = secpolicy_zfs(cr);
5543b2aab18SMatthew Ahrens 		if (error != 0)
5554445fffbSMatthew Ahrens 			error = dsl_deleg_access_impl(ds, perm, cr);
556ecd6cf80Smarks 	}
557ecd6cf80Smarks 	return (error);
558ecd6cf80Smarks }
5604445fffbSMatthew Ahrens static int
zfs_secpolicy_write_perms(const char * name,const char * perm,cred_t * cr)5613b2aab18SMatthew Ahrens zfs_secpolicy_write_perms(const char *name, const char *perm, cred_t *cr)
562a7f53a56SChris Kirby {
563a7f53a56SChris Kirby 	int error;
5643b2aab18SMatthew Ahrens 	dsl_dataset_t *ds;
5653b2aab18SMatthew Ahrens 	dsl_pool_t *dp;
566a7f53a56SChris Kirby 
56725f7d993SMatthew Ahrens 	/*
56825f7d993SMatthew Ahrens 	 * First do a quick check for root in the global zone, which
56925f7d993SMatthew Ahrens 	 * is allowed to do all write_perms.  This ensures that zfs_ioc_*
57025f7d993SMatthew Ahrens 	 * will get to handle nonexistent datasets.
57125f7d993SMatthew Ahrens 	 */
57225f7d993SMatthew Ahrens 	if (INGLOBALZONE(curproc) && secpolicy_zfs(cr) == 0)
57325f7d993SMatthew Ahrens 		return (0);
57425f7d993SMatthew Ahrens 
5753b2aab18SMatthew Ahrens 	error = dsl_pool_hold(name, FTAG, &dp);
5763b2aab18SMatthew Ahrens 	if (error != 0)
5773b2aab18SMatthew Ahrens 		return (error);
5783b2aab18SMatthew Ahrens 
5793b2aab18SMatthew Ahrens 	error = dsl_dataset_hold(dp, name, FTAG, &ds);
5803b2aab18SMatthew Ahrens 	if (error != 0) {
5813b2aab18SMatthew Ahrens 		dsl_pool_rele(dp, FTAG);
5823b2aab18SMatthew Ahrens 		return (error);
583a7f53a56SChris Kirby 	}
5843b2aab18SMatthew Ahrens 
5853b2aab18SMatthew Ahrens 	error = zfs_secpolicy_write_perms_ds(name, ds, perm, cr);
5863b2aab18SMatthew Ahrens 
5873b2aab18SMatthew Ahrens 	dsl_dataset_rele(ds, FTAG);
5883b2aab18SMatthew Ahrens 	dsl_pool_rele(dp, FTAG);
589a7f53a56SChris Kirby 	return (error);
590a7f53a56SChris Kirby }
591a7f53a56SChris Kirby 
5924201a95eSRic Aleshire /*
5934201a95eSRic Aleshire  * Policy for setting the security label property.
5944201a95eSRic Aleshire  *
5954201a95eSRic Aleshire  * Returns 0 for success, non-zero for access and other errors.
5964201a95eSRic Aleshire  */
5974201a95eSRic Aleshire static int
zfs_set_slabel_policy(const char * name,char * strval,cred_t * cr)59892241e0bSTom Erickson zfs_set_slabel_policy(const char *name, char *strval, cred_t *cr)
5994201a95eSRic Aleshire {
6004201a95eSRic Aleshire 	char		ds_hexsl[MAXNAMELEN];
6014201a95eSRic Aleshire 	bslabel_t	ds_sl, new_sl;
6024201a95eSRic Aleshire 	boolean_t	new_default = FALSE;
6034201a95eSRic Aleshire 	uint64_t	zoned;
6044201a95eSRic Aleshire 	int		needed_priv = -1;
6054201a95eSRic Aleshire 	int		error;
6064201a95eSRic Aleshire 
6074201a95eSRic Aleshire 	/* First get the existing dataset label. */
6084201a95eSRic Aleshire 	error = dsl_prop_get(name, zfs_prop_to_name(ZFS_PROP_MLSLABEL),
6094201a95eSRic Aleshire 	    1, sizeof (ds_hexsl), &ds_hexsl, NULL);
6103b2aab18SMatthew Ahrens 	if (error != 0)
611be6fd75aSMatthew Ahrens 		return (SET_ERROR(EPERM));
6124201a95eSRic Aleshire 
6134201a95eSRic Aleshire 	if (strcasecmp(strval, ZFS_MLSLABEL_DEFAULT) == 0)
6144201a95eSRic Aleshire 		new_default = TRUE;
6154201a95eSRic Aleshire 
6164201a95eSRic Aleshire 	/* The label must be translatable */
6174201a95eSRic Aleshire 	if (!new_default && (hexstr_to_label(strval, &new_sl) != 0))
618be6fd75aSMatthew Ahrens 		return (SET_ERROR(EINVAL));
6194201a95eSRic Aleshire 
6204201a95eSRic Aleshire 	/*
6214201a95eSRic Aleshire 	 * In a non-global zone, disallow attempts to set a label that
6224201a95eSRic Aleshire 	 * doesn't match that of the zone; otherwise no other checks
6234201a95eSRic Aleshire 	 * are needed.
6244201a95eSRic Aleshire 	 */
6254201a95eSRic Aleshire 	if (!INGLOBALZONE(curproc)) {
6264201a95eSRic Aleshire 		if (new_default || !blequal(&new_sl, CR_SL(CRED())))
627be6fd75aSMatthew Ahrens 			return (SET_ERROR(EPERM));
6284201a95eSRic Aleshire 		return (0);
6294201a95eSRic Aleshire 	}
6304201a95eSRic Aleshire 
6314201a95eSRic Aleshire 	/*
6324201a95eSRic Aleshire 	 * For global-zone datasets (i.e., those whose zoned property is
6334201a95eSRic Aleshire 	 * "off", verify that the specified new label is valid for the
6344201a95eSRic Aleshire 	 * global zone.
6354201a95eSRic Aleshire 	 */
6364201a95eSRic Aleshire 	if (dsl_prop_get_integer(name,
6374201a95eSRic Aleshire 	    zfs_prop_to_name(ZFS_PROP_ZONED), &zoned, NULL))
638be6fd75aSMatthew Ahrens 		return (SET_ERROR(EPERM));
6394201a95eSRic Aleshire 	if (!zoned) {
6404201a95eSRic Aleshire 		if (zfs_check_global_label(name, strval) != 0)
641be6fd75aSMatthew Ahrens 			return (SET_ERROR(EPERM));
6424201a95eSRic Aleshire 	}
6434201a95eSRic Aleshire