Merge b2af9f487a
into b109925820
This commit is contained in:
commit
5b8db3ac0a
|
@ -425,7 +425,7 @@ get_usage(zfs_help_t idx)
|
|||
return (gettext("\tchange-key [-l] [-o keyformat=<value>]\n"
|
||||
"\t [-o keylocation=<value>] [-o pbkdf2iters=<value>]\n"
|
||||
"\t <filesystem|volume>\n"
|
||||
"\tchange-key -i [-l] <filesystem|volume>\n"));
|
||||
"\tchange-key -i [-lf] <filesystem|volume>\n"));
|
||||
case HELP_VERSION:
|
||||
return (gettext("\tversion [-j]\n"));
|
||||
case HELP_REDACT:
|
||||
|
@ -8711,11 +8711,11 @@ zfs_do_change_key(int argc, char **argv)
|
|||
{
|
||||
int c, ret;
|
||||
uint64_t keystatus;
|
||||
boolean_t loadkey = B_FALSE, inheritkey = B_FALSE;
|
||||
boolean_t loadkey = B_FALSE, inheritkey = B_FALSE, force = B_FALSE;
|
||||
zfs_handle_t *zhp = NULL;
|
||||
nvlist_t *props = fnvlist_alloc();
|
||||
|
||||
while ((c = getopt(argc, argv, "lio:")) != -1) {
|
||||
while ((c = getopt(argc, argv, "lifo:")) != -1) {
|
||||
switch (c) {
|
||||
case 'l':
|
||||
loadkey = B_TRUE;
|
||||
|
@ -8723,6 +8723,9 @@ zfs_do_change_key(int argc, char **argv)
|
|||
case 'i':
|
||||
inheritkey = B_TRUE;
|
||||
break;
|
||||
case 'f':
|
||||
force = B_TRUE;
|
||||
break;
|
||||
case 'o':
|
||||
if (!parseprop(props, optarg)) {
|
||||
nvlist_free(props);
|
||||
|
@ -8742,6 +8745,12 @@ zfs_do_change_key(int argc, char **argv)
|
|||
usage(B_FALSE);
|
||||
}
|
||||
|
||||
if (force && !inheritkey) {
|
||||
(void) fprintf(stderr,
|
||||
gettext("Force option only applies to inherit\n"));
|
||||
usage(B_FALSE);
|
||||
}
|
||||
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
|
@ -8775,7 +8784,7 @@ zfs_do_change_key(int argc, char **argv)
|
|||
zfs_refresh_properties(zhp);
|
||||
}
|
||||
|
||||
ret = zfs_crypto_rewrap(zhp, props, inheritkey);
|
||||
ret = zfs_crypto_rewrap(zhp, props, inheritkey, force);
|
||||
if (ret != 0) {
|
||||
nvlist_free(props);
|
||||
zfs_close(zhp);
|
||||
|
|
|
@ -589,7 +589,8 @@ _LIBZFS_H int zfs_crypto_clone_check(libzfs_handle_t *, zfs_handle_t *, char *,
|
|||
_LIBZFS_H int zfs_crypto_attempt_load_keys(libzfs_handle_t *, const char *);
|
||||
_LIBZFS_H int zfs_crypto_load_key(zfs_handle_t *, boolean_t, const char *);
|
||||
_LIBZFS_H int zfs_crypto_unload_key(zfs_handle_t *);
|
||||
_LIBZFS_H int zfs_crypto_rewrap(zfs_handle_t *, nvlist_t *, boolean_t);
|
||||
_LIBZFS_H int zfs_crypto_rewrap(zfs_handle_t *, nvlist_t *, boolean_t,
|
||||
boolean_t);
|
||||
|
||||
typedef struct zprop_list {
|
||||
int pl_prop;
|
||||
|
|
|
@ -3643,6 +3643,7 @@
|
|||
<parameter type-id='9200a744' name='zhp'/>
|
||||
<parameter type-id='5ce45b60' name='raw_props'/>
|
||||
<parameter type-id='c19b74c3' name='inheritkey'/>
|
||||
<parameter type-id='c19b74c3' name='forceinherit'/>
|
||||
<return type-id='95e97e5e'/>
|
||||
</function-decl>
|
||||
<function-decl name='zfs_error_aux' visibility='default' binding='global' size-in-bits='64'>
|
||||
|
|
|
@ -1584,7 +1584,8 @@ error:
|
|||
}
|
||||
|
||||
int
|
||||
zfs_crypto_rewrap(zfs_handle_t *zhp, nvlist_t *raw_props, boolean_t inheritkey)
|
||||
zfs_crypto_rewrap(zfs_handle_t *zhp, nvlist_t *raw_props, boolean_t inheritkey,
|
||||
boolean_t forceinherit)
|
||||
{
|
||||
int ret;
|
||||
char errbuf[ERRBUFLEN];
|
||||
|
@ -1601,6 +1602,9 @@ zfs_crypto_rewrap(zfs_handle_t *zhp, nvlist_t *raw_props, boolean_t inheritkey)
|
|||
char prop_keylocation[MAXNAMELEN];
|
||||
char parent_name[ZFS_MAX_DATASET_NAME_LEN];
|
||||
|
||||
if (inheritkey && forceinherit)
|
||||
cmd = DCP_CMD_FORCE_INHERIT;
|
||||
|
||||
(void) snprintf(errbuf, sizeof (errbuf),
|
||||
dgettext(TEXT_DOMAIN, "Key change error"));
|
||||
|
||||
|
@ -1760,7 +1764,7 @@ zfs_crypto_rewrap(zfs_handle_t *zhp, nvlist_t *raw_props, boolean_t inheritkey)
|
|||
|
||||
/* check that the parent's key is loaded */
|
||||
pkeystatus = zfs_prop_get_int(pzhp, ZFS_PROP_KEYSTATUS);
|
||||
if (pkeystatus == ZFS_KEYSTATUS_UNAVAILABLE) {
|
||||
if (!forceinherit && pkeystatus == ZFS_KEYSTATUS_UNAVAILABLE) {
|
||||
zfs_error_aux(pzhp->zfs_hdl, dgettext(TEXT_DOMAIN,
|
||||
"Parent key must be loaded."));
|
||||
ret = EACCES;
|
||||
|
@ -1770,7 +1774,7 @@ zfs_crypto_rewrap(zfs_handle_t *zhp, nvlist_t *raw_props, boolean_t inheritkey)
|
|||
|
||||
/* check that the key is loaded */
|
||||
keystatus = zfs_prop_get_int(zhp, ZFS_PROP_KEYSTATUS);
|
||||
if (keystatus == ZFS_KEYSTATUS_UNAVAILABLE) {
|
||||
if (!forceinherit && keystatus == ZFS_KEYSTATUS_UNAVAILABLE) {
|
||||
zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
|
||||
"Key must be loaded."));
|
||||
ret = EACCES;
|
||||
|
|
|
@ -56,7 +56,7 @@
|
|||
.Nm zfs
|
||||
.Cm change-key
|
||||
.Fl i
|
||||
.Op Fl l
|
||||
.Op Fl lf
|
||||
.Ar filesystem
|
||||
.
|
||||
.Sh DESCRIPTION
|
||||
|
@ -159,7 +159,7 @@ Unloads the keys for all encryption roots in all imported pools.
|
|||
.Nm zfs
|
||||
.Cm change-key
|
||||
.Fl i
|
||||
.Op Fl l
|
||||
.Op Fl lf
|
||||
.Ar filesystem
|
||||
.Xc
|
||||
Changes the user's key (e.g. a passphrase) used to access a dataset.
|
||||
|
@ -217,6 +217,12 @@ Indicates that zfs should make
|
|||
inherit the key of its parent.
|
||||
Note that this command can only be run on an encryption root
|
||||
that has an encrypted parent.
|
||||
.It Fl f
|
||||
When used with
|
||||
.Fl i
|
||||
the key will be force-inherited.
|
||||
This should only be used when it is known that the parent is a replica of the
|
||||
original encryptionroot and has the same key.
|
||||
.El
|
||||
.El
|
||||
.Ss Encryption
|
||||
|
|
|
@ -187,7 +187,8 @@ tags = ['functional', 'cli_root', 'zfs_bookmark']
|
|||
[tests/functional/cli_root/zfs_change-key]
|
||||
tests = ['zfs_change-key', 'zfs_change-key_child', 'zfs_change-key_format',
|
||||
'zfs_change-key_inherit', 'zfs_change-key_load', 'zfs_change-key_location',
|
||||
'zfs_change-key_pbkdf2iters', 'zfs_change-key_clones']
|
||||
'zfs_change-key_pbkdf2iters', 'zfs_change-key_clones',
|
||||
'zfs_change-key_inherit-force']
|
||||
tags = ['functional', 'cli_root', 'zfs_change-key']
|
||||
|
||||
[tests/functional/cli_root/zfs_clone]
|
||||
|
|
|
@ -104,7 +104,8 @@ tags = ['functional', 'cli_root', 'zfs_bookmark']
|
|||
[tests/functional/cli_root/zfs_change-key]
|
||||
tests = ['zfs_change-key', 'zfs_change-key_child', 'zfs_change-key_format',
|
||||
'zfs_change-key_inherit', 'zfs_change-key_load', 'zfs_change-key_location',
|
||||
'zfs_change-key_pbkdf2iters', 'zfs_change-key_clones']
|
||||
'zfs_change-key_pbkdf2iters', 'zfs_change-key_clones',
|
||||
'zfs_change-key_inherit-force']
|
||||
tags = ['functional', 'cli_root', 'zfs_change-key']
|
||||
|
||||
[tests/functional/cli_root/zfs_clone]
|
||||
|
|
|
@ -639,6 +639,7 @@ nobase_dist_datadir_zfs_tests_tests_SCRIPTS += \
|
|||
functional/cli_root/zfs_change-key/zfs_change-key_child.ksh \
|
||||
functional/cli_root/zfs_change-key/zfs_change-key_clones.ksh \
|
||||
functional/cli_root/zfs_change-key/zfs_change-key_format.ksh \
|
||||
functional/cli_root/zfs_change-key/zfs_change-key_inherit-force.ksh \
|
||||
functional/cli_root/zfs_change-key/zfs_change-key_inherit.ksh \
|
||||
functional/cli_root/zfs_change-key/zfs_change-key.ksh \
|
||||
functional/cli_root/zfs_change-key/zfs_change-key_load.ksh \
|
||||
|
|
|
@ -0,0 +1,88 @@
|
|||
#!/bin/ksh -p
|
||||
#
|
||||
# CDDL HEADER START
|
||||
#
|
||||
# This file and its contents are supplied under the terms of the
|
||||
# Common Development and Distribution License ("CDDL"), version 1.0.
|
||||
# You may only use this file in accordance with the terms of version
|
||||
# 1.0 of the CDDL.
|
||||
#
|
||||
# A full copy of the text of the CDDL should have accompanied this
|
||||
# source. A copy of the CDDL is also available via the Internet at
|
||||
# http://www.illumos.org/license/CDDL.
|
||||
#
|
||||
# CDDL HEADER END
|
||||
#
|
||||
|
||||
#
|
||||
# Copyright (c) 2017 Datto, Inc. All rights reserved.
|
||||
#
|
||||
|
||||
. $STF_SUITE/include/libtest.shlib
|
||||
. $STF_SUITE/tests/functional/cli_root/zfs_load-key/zfs_load-key_common.kshlib
|
||||
|
||||
#
|
||||
# DESCRIPTION:
|
||||
# 'zfs change-key -if' should cause a dataset to inherit its parent key
|
||||
# without the key being loaded
|
||||
#
|
||||
# STRATEGY:
|
||||
# 1. Create a parent encrypted dataset
|
||||
# 2. Create a child dataset
|
||||
# 3. Create a copy of the parent dataset
|
||||
# 4. Send a copy of the child to the copy of the parent
|
||||
# 5. Attempt to force inherit the parent key without the keys being loaded
|
||||
# 6. Verify the key is inherited
|
||||
# 7. Load the parent key
|
||||
# 8. Verify the key is available for parent and child
|
||||
# 9. Attempt to mount the datasets
|
||||
#
|
||||
|
||||
verify_runnable "both"
|
||||
|
||||
function cleanup
|
||||
{
|
||||
datasetexists $TESTPOOL/$TESTFS1 && \
|
||||
destroy_dataset $TESTPOOL/$TESTFS1 -r
|
||||
|
||||
datasetexists $TESTPOOL/$TESTFS2 && \
|
||||
destroy_dataset $TESTPOOL/$TESTFS2 -r
|
||||
}
|
||||
|
||||
log_onexit cleanup
|
||||
|
||||
log_assert "'zfs change-key -if' should cause a dataset to inherit its" \
|
||||
"parent key"
|
||||
|
||||
log_must eval "echo $PASSPHRASE | zfs create -o encryption=on" \
|
||||
"-o keyformat=passphrase -o keylocation=prompt $TESTPOOL/$TESTFS1"
|
||||
log_must eval "echo $PASSPHRASE1 | zfs create $TESTPOOL/$TESTFS1/child"
|
||||
log_must verify_encryption_root $TESTPOOL/$TESTFS1/child "$TESTPOOL/$TESTFS1"
|
||||
|
||||
log_must zfs snapshot -r $TESTPOOL/$TESTFS1@snap
|
||||
|
||||
log_must eval "zfs send -w $TESTPOOL/$TESTFS1@snap | zfs receive $TESTPOOL/$TESTFS2"
|
||||
log_must verify_encryption_root $TESTPOOL/$TESTFS2 $TESTPOOL/$TESTFS2
|
||||
log_must key_unavailable $TESTPOOL/$TESTFS2
|
||||
|
||||
log_must eval "zfs send -w $TESTPOOL/$TESTFS1/child@snap | zfs receive $TESTPOOL/$TESTFS2/child"
|
||||
log_must verify_encryption_root $TESTPOOL/$TESTFS2/child $TESTPOOL/$TESTFS2/child
|
||||
log_must key_unavailable $TESTPOOL/$TESTFS2/child
|
||||
|
||||
log_must_not zfs change-key -i $TESTPOOL/$TESTFS2/child
|
||||
log_must_not zfs change-key -f $TESTPOOL/$TESTFS2/child
|
||||
log_must zfs change-key -if $TESTPOOL/$TESTFS2/child
|
||||
log_must verify_encryption_root $TESTPOOL/$TESTFS2/child "$TESTPOOL/$TESTFS2"
|
||||
|
||||
log_must key_unavailable $TESTPOOL/$TESTFS2
|
||||
log_must key_unavailable $TESTPOOL/$TESTFS2/child
|
||||
|
||||
log_must eval "echo $PASSPHRASE | zfs load-key $TESTPOOL/$TESTFS2"
|
||||
|
||||
log_must key_available $TESTPOOL/$TESTFS2
|
||||
log_must key_available $TESTPOOL/$TESTFS2/child
|
||||
|
||||
log_must zfs mount $TESTPOOL/$TESTFS2
|
||||
log_must zfs mount $TESTPOOL/$TESTFS2/child
|
||||
|
||||
log_pass "'zfs change-key -if' causes a dataset to inherit its parent key"
|
Loading…
Reference in New Issue