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"
|
return (gettext("\tchange-key [-l] [-o keyformat=<value>]\n"
|
||||||
"\t [-o keylocation=<value>] [-o pbkdf2iters=<value>]\n"
|
"\t [-o keylocation=<value>] [-o pbkdf2iters=<value>]\n"
|
||||||
"\t <filesystem|volume>\n"
|
"\t <filesystem|volume>\n"
|
||||||
"\tchange-key -i [-l] <filesystem|volume>\n"));
|
"\tchange-key -i [-lf] <filesystem|volume>\n"));
|
||||||
case HELP_VERSION:
|
case HELP_VERSION:
|
||||||
return (gettext("\tversion [-j]\n"));
|
return (gettext("\tversion [-j]\n"));
|
||||||
case HELP_REDACT:
|
case HELP_REDACT:
|
||||||
|
@ -8711,11 +8711,11 @@ zfs_do_change_key(int argc, char **argv)
|
||||||
{
|
{
|
||||||
int c, ret;
|
int c, ret;
|
||||||
uint64_t keystatus;
|
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;
|
zfs_handle_t *zhp = NULL;
|
||||||
nvlist_t *props = fnvlist_alloc();
|
nvlist_t *props = fnvlist_alloc();
|
||||||
|
|
||||||
while ((c = getopt(argc, argv, "lio:")) != -1) {
|
while ((c = getopt(argc, argv, "lifo:")) != -1) {
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case 'l':
|
case 'l':
|
||||||
loadkey = B_TRUE;
|
loadkey = B_TRUE;
|
||||||
|
@ -8723,6 +8723,9 @@ zfs_do_change_key(int argc, char **argv)
|
||||||
case 'i':
|
case 'i':
|
||||||
inheritkey = B_TRUE;
|
inheritkey = B_TRUE;
|
||||||
break;
|
break;
|
||||||
|
case 'f':
|
||||||
|
force = B_TRUE;
|
||||||
|
break;
|
||||||
case 'o':
|
case 'o':
|
||||||
if (!parseprop(props, optarg)) {
|
if (!parseprop(props, optarg)) {
|
||||||
nvlist_free(props);
|
nvlist_free(props);
|
||||||
|
@ -8742,6 +8745,12 @@ zfs_do_change_key(int argc, char **argv)
|
||||||
usage(B_FALSE);
|
usage(B_FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (force && !inheritkey) {
|
||||||
|
(void) fprintf(stderr,
|
||||||
|
gettext("Force option only applies to inherit\n"));
|
||||||
|
usage(B_FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
argc -= optind;
|
argc -= optind;
|
||||||
argv += optind;
|
argv += optind;
|
||||||
|
|
||||||
|
@ -8775,7 +8784,7 @@ zfs_do_change_key(int argc, char **argv)
|
||||||
zfs_refresh_properties(zhp);
|
zfs_refresh_properties(zhp);
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = zfs_crypto_rewrap(zhp, props, inheritkey);
|
ret = zfs_crypto_rewrap(zhp, props, inheritkey, force);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
nvlist_free(props);
|
nvlist_free(props);
|
||||||
zfs_close(zhp);
|
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_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_load_key(zfs_handle_t *, boolean_t, const char *);
|
||||||
_LIBZFS_H int zfs_crypto_unload_key(zfs_handle_t *);
|
_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 {
|
typedef struct zprop_list {
|
||||||
int pl_prop;
|
int pl_prop;
|
||||||
|
|
|
@ -3643,6 +3643,7 @@
|
||||||
<parameter type-id='9200a744' name='zhp'/>
|
<parameter type-id='9200a744' name='zhp'/>
|
||||||
<parameter type-id='5ce45b60' name='raw_props'/>
|
<parameter type-id='5ce45b60' name='raw_props'/>
|
||||||
<parameter type-id='c19b74c3' name='inheritkey'/>
|
<parameter type-id='c19b74c3' name='inheritkey'/>
|
||||||
|
<parameter type-id='c19b74c3' name='forceinherit'/>
|
||||||
<return type-id='95e97e5e'/>
|
<return type-id='95e97e5e'/>
|
||||||
</function-decl>
|
</function-decl>
|
||||||
<function-decl name='zfs_error_aux' visibility='default' binding='global' size-in-bits='64'>
|
<function-decl name='zfs_error_aux' visibility='default' binding='global' size-in-bits='64'>
|
||||||
|
|
|
@ -1584,7 +1584,8 @@ error:
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
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;
|
int ret;
|
||||||
char errbuf[ERRBUFLEN];
|
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 prop_keylocation[MAXNAMELEN];
|
||||||
char parent_name[ZFS_MAX_DATASET_NAME_LEN];
|
char parent_name[ZFS_MAX_DATASET_NAME_LEN];
|
||||||
|
|
||||||
|
if (inheritkey && forceinherit)
|
||||||
|
cmd = DCP_CMD_FORCE_INHERIT;
|
||||||
|
|
||||||
(void) snprintf(errbuf, sizeof (errbuf),
|
(void) snprintf(errbuf, sizeof (errbuf),
|
||||||
dgettext(TEXT_DOMAIN, "Key change error"));
|
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 */
|
/* check that the parent's key is loaded */
|
||||||
pkeystatus = zfs_prop_get_int(pzhp, ZFS_PROP_KEYSTATUS);
|
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,
|
zfs_error_aux(pzhp->zfs_hdl, dgettext(TEXT_DOMAIN,
|
||||||
"Parent key must be loaded."));
|
"Parent key must be loaded."));
|
||||||
ret = EACCES;
|
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 */
|
/* check that the key is loaded */
|
||||||
keystatus = zfs_prop_get_int(zhp, ZFS_PROP_KEYSTATUS);
|
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,
|
zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
|
||||||
"Key must be loaded."));
|
"Key must be loaded."));
|
||||||
ret = EACCES;
|
ret = EACCES;
|
||||||
|
|
|
@ -56,7 +56,7 @@
|
||||||
.Nm zfs
|
.Nm zfs
|
||||||
.Cm change-key
|
.Cm change-key
|
||||||
.Fl i
|
.Fl i
|
||||||
.Op Fl l
|
.Op Fl lf
|
||||||
.Ar filesystem
|
.Ar filesystem
|
||||||
.
|
.
|
||||||
.Sh DESCRIPTION
|
.Sh DESCRIPTION
|
||||||
|
@ -159,7 +159,7 @@ Unloads the keys for all encryption roots in all imported pools.
|
||||||
.Nm zfs
|
.Nm zfs
|
||||||
.Cm change-key
|
.Cm change-key
|
||||||
.Fl i
|
.Fl i
|
||||||
.Op Fl l
|
.Op Fl lf
|
||||||
.Ar filesystem
|
.Ar filesystem
|
||||||
.Xc
|
.Xc
|
||||||
Changes the user's key (e.g. a passphrase) used to access a dataset.
|
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.
|
inherit the key of its parent.
|
||||||
Note that this command can only be run on an encryption root
|
Note that this command can only be run on an encryption root
|
||||||
that has an encrypted parent.
|
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
|
||||||
.El
|
.El
|
||||||
.Ss Encryption
|
.Ss Encryption
|
||||||
|
|
|
@ -187,7 +187,8 @@ tags = ['functional', 'cli_root', 'zfs_bookmark']
|
||||||
[tests/functional/cli_root/zfs_change-key]
|
[tests/functional/cli_root/zfs_change-key]
|
||||||
tests = ['zfs_change-key', 'zfs_change-key_child', 'zfs_change-key_format',
|
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_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']
|
tags = ['functional', 'cli_root', 'zfs_change-key']
|
||||||
|
|
||||||
[tests/functional/cli_root/zfs_clone]
|
[tests/functional/cli_root/zfs_clone]
|
||||||
|
|
|
@ -104,7 +104,8 @@ tags = ['functional', 'cli_root', 'zfs_bookmark']
|
||||||
[tests/functional/cli_root/zfs_change-key]
|
[tests/functional/cli_root/zfs_change-key]
|
||||||
tests = ['zfs_change-key', 'zfs_change-key_child', 'zfs_change-key_format',
|
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_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']
|
tags = ['functional', 'cli_root', 'zfs_change-key']
|
||||||
|
|
||||||
[tests/functional/cli_root/zfs_clone]
|
[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_child.ksh \
|
||||||
functional/cli_root/zfs_change-key/zfs_change-key_clones.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_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_inherit.ksh \
|
||||||
functional/cli_root/zfs_change-key/zfs_change-key.ksh \
|
functional/cli_root/zfs_change-key/zfs_change-key.ksh \
|
||||||
functional/cli_root/zfs_change-key/zfs_change-key_load.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