--- a/usr/src/cmd/zfs/zfs_main.c Mon Feb 11 08:20:23 2008 -0800
+++ b/usr/src/cmd/zfs/zfs_main.c Mon Feb 11 11:57:00 2008 -0800
@@ -313,6 +313,7 @@
{
int i;
boolean_t show_properties = B_FALSE;
+ boolean_t show_permissions = B_FALSE;
FILE *fp = requested ? stdout : stderr;
if (current_command == NULL) {
@@ -343,6 +344,11 @@
strcmp(current_command->name, "list") == 0))
show_properties = B_TRUE;
+ if (current_command != NULL &&
+ (strcmp(current_command->name, "allow") == 0 ||
+ strcmp(current_command->name, "unallow") == 0))
+ show_permissions = B_TRUE;
+
if (show_properties) {
(void) fprintf(fp,
@@ -359,14 +365,25 @@
"with standard units such as K, M, G, etc.\n"));
(void) fprintf(fp, gettext("\n\nUser-defined properties can "
"be specified by using a name containing a colon (:).\n"));
+
+ } else if (show_permissions) {
+ (void) fprintf(fp,
+ gettext("\nThe following permissions are supported:\n"));
+
+ zfs_deleg_permissions();
} else {
/*
* TRANSLATION NOTE:
* "zfs set|get" must not be localised this is the
* command name and arguments.
*/
+
(void) fprintf(fp,
gettext("\nFor the property list, run: zfs set|get\n"));
+
+ (void) fprintf(fp,
+ gettext("\nFor the delegated permission list, run:"
+ " zfs allow|unallow\n"));
}
/*
--- a/usr/src/common/zfs/zfs_deleg.c Mon Feb 11 08:20:23 2008 -0800
+++ b/usr/src/common/zfs/zfs_deleg.c Mon Feb 11 11:57:00 2008 -0800
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -45,23 +45,28 @@
/*
* permission table
+ *
+ * Keep this table in sorted order
+ *
+ * This table is used for displaying all permissions for
+ * zfs allow
*/
-char *zfs_deleg_perm_tab[] = {
- ZFS_DELEG_PERM_CREATE,
- ZFS_DELEG_PERM_DESTROY,
- ZFS_DELEG_PERM_SNAPSHOT,
- ZFS_DELEG_PERM_ROLLBACK,
- ZFS_DELEG_PERM_CLONE,
- ZFS_DELEG_PERM_PROMOTE,
- ZFS_DELEG_PERM_RENAME,
- ZFS_DELEG_PERM_MOUNT,
- ZFS_DELEG_PERM_SHARE,
- ZFS_DELEG_PERM_SEND,
- ZFS_DELEG_PERM_RECEIVE,
- ZFS_DELEG_PERM_ALLOW,
- ZFS_DELEG_PERM_USERPROP,
- NULL
+zfs_deleg_perm_tab_t zfs_deleg_perm_tab[] = {
+ {ZFS_DELEG_PERM_ALLOW, ZFS_DELEG_NOTE_ALLOW},
+ {ZFS_DELEG_PERM_CLONE, ZFS_DELEG_NOTE_CLONE },
+ {ZFS_DELEG_PERM_CREATE, ZFS_DELEG_NOTE_CREATE },
+ {ZFS_DELEG_PERM_DESTROY, ZFS_DELEG_NOTE_DESTROY },
+ {ZFS_DELEG_PERM_MOUNT, ZFS_DELEG_NOTE_MOUNT },
+ {ZFS_DELEG_PERM_PROMOTE, ZFS_DELEG_NOTE_PROMOTE },
+ {ZFS_DELEG_PERM_RECEIVE, ZFS_DELEG_NOTE_RECEIVE },
+ {ZFS_DELEG_PERM_RENAME, ZFS_DELEG_NOTE_RENAME },
+ {ZFS_DELEG_PERM_ROLLBACK, ZFS_DELEG_NOTE_ROLLBACK },
+ {ZFS_DELEG_PERM_SNAPSHOT, ZFS_DELEG_NOTE_SNAPSHOT },
+ {ZFS_DELEG_PERM_SHARE, ZFS_DELEG_NOTE_SHARE },
+ {ZFS_DELEG_PERM_SEND, ZFS_DELEG_NOTE_NONE },
+ {ZFS_DELEG_PERM_USERPROP, ZFS_DELEG_NOTE_USERPROP },
+ {NULL, ZFS_DELEG_NOTE_NONE }
};
static int
@@ -79,8 +84,8 @@
int i;
zfs_prop_t prop;
- for (i = 0; zfs_deleg_perm_tab[i] != NULL; i++) {
- if (strcmp(perm, zfs_deleg_perm_tab[i]) == 0)
+ for (i = 0; zfs_deleg_perm_tab[i].z_perm != NULL; i++) {
+ if (strcmp(perm, zfs_deleg_perm_tab[i].z_perm) == 0)
return (perm);
}
--- a/usr/src/common/zfs/zfs_deleg.h Mon Feb 11 08:20:23 2008 -0800
+++ b/usr/src/common/zfs/zfs_deleg.h Mon Feb 11 11:57:00 2008 -0800
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -46,7 +46,28 @@
#define ZFS_DELEG_DESCENDENT 'd'
#define ZFS_DELEG_NA '-'
-extern char *zfs_deleg_perm_tab[];
+typedef enum {
+ ZFS_DELEG_NOTE_CREATE,
+ ZFS_DELEG_NOTE_DESTROY,
+ ZFS_DELEG_NOTE_SNAPSHOT,
+ ZFS_DELEG_NOTE_ROLLBACK,
+ ZFS_DELEG_NOTE_CLONE,
+ ZFS_DELEG_NOTE_PROMOTE,
+ ZFS_DELEG_NOTE_RENAME,
+ ZFS_DELEG_NOTE_RECEIVE,
+ ZFS_DELEG_NOTE_ALLOW,
+ ZFS_DELEG_NOTE_USERPROP,
+ ZFS_DELEG_NOTE_MOUNT,
+ ZFS_DELEG_NOTE_SHARE,
+ ZFS_DELEG_NOTE_NONE
+} zfs_deleg_note_t;
+
+typedef struct zfs_deleg_perm_tab {
+ char *z_perm;
+ zfs_deleg_note_t z_note;
+} zfs_deleg_perm_tab_t;
+
+extern zfs_deleg_perm_tab_t zfs_deleg_perm_tab[];
int zfs_deleg_verify_nvlist(nvlist_t *nvlist);
void zfs_deleg_whokey(char *attr, zfs_deleg_who_type_t type,
--- a/usr/src/lib/libzfs/common/libzfs.h Mon Feb 11 08:20:23 2008 -0800
+++ b/usr/src/lib/libzfs/common/libzfs.h Mon Feb 11 11:57:00 2008 -0800
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -466,6 +466,7 @@
zfs_deleg_who_type_t, zfs_deleg_inherit_t, nvlist_t **nvlist_t);
extern int zfs_perm_get(zfs_handle_t *, zfs_allow_t **);
extern void zfs_free_allows(zfs_allow_t *);
+extern void zfs_deleg_permissions(void);
/*
* Mount support functions.
--- a/usr/src/lib/libzfs/common/libzfs_dataset.c Mon Feb 11 08:20:23 2008 -0800
+++ b/usr/src/lib/libzfs/common/libzfs_dataset.c Mon Feb 11 11:57:00 2008 -0800
@@ -1589,6 +1589,124 @@
return (-1);
}
+static char *
+zfs_deleg_perm_note(zfs_deleg_note_t note)
+{
+ /*
+ * Don't put newlines on end of lines
+ */
+ switch (note) {
+ case ZFS_DELEG_NOTE_CREATE:
+ return (dgettext(TEXT_DOMAIN,
+ "Must also have the 'mount' ability"));
+ case ZFS_DELEG_NOTE_DESTROY:
+ return (dgettext(TEXT_DOMAIN,
+ "Must also have the 'mount' ability"));
+ case ZFS_DELEG_NOTE_SNAPSHOT:
+ return (dgettext(TEXT_DOMAIN,
+ "Must also have the 'mount' ability"));
+ case ZFS_DELEG_NOTE_ROLLBACK:
+ return (dgettext(TEXT_DOMAIN,
+ "Must also have the 'mount' ability"));
+ case ZFS_DELEG_NOTE_CLONE:
+ return (dgettext(TEXT_DOMAIN, "Must also have the 'create' "
+ "ability and 'mount'\n"
+ "\t\t\t\tability in the origin file system"));
+ case ZFS_DELEG_NOTE_PROMOTE:
+ return (dgettext(TEXT_DOMAIN, "Must also have the 'mount'\n"
+ "\t\t\t\tand 'promote' ability in the origin file system"));
+ case ZFS_DELEG_NOTE_RENAME:
+ return (dgettext(TEXT_DOMAIN, "Must also have the 'mount' "
+ "and 'create' \n\t\t\t\tability in the new parent"));
+ case ZFS_DELEG_NOTE_RECEIVE:
+ return (dgettext(TEXT_DOMAIN, "Must also have the 'mount'"
+ " and 'create' ability"));
+ case ZFS_DELEG_NOTE_USERPROP:
+ return (dgettext(TEXT_DOMAIN,
+ "Allows changing any user property"));
+ case ZFS_DELEG_NOTE_ALLOW:
+ return (dgettext(TEXT_DOMAIN,
+ "Must also have the permission that is being\n"
+ "\t\t\t\tallowed"));
+ case ZFS_DELEG_NOTE_MOUNT:
+ return (dgettext(TEXT_DOMAIN,
+ "Allows mount/umount of ZFS datasets"));
+ case ZFS_DELEG_NOTE_SHARE:
+ return (dgettext(TEXT_DOMAIN,
+ "Allows sharing file systems over NFS or SMB\n"
+ "\t\t\t\tprotocols"));
+ case ZFS_DELEG_NOTE_NONE:
+ default:
+ return (dgettext(TEXT_DOMAIN, ""));
+ }
+}
+
+typedef enum {
+ ZFS_DELEG_SUBCOMMAND,
+ ZFS_DELEG_PROP,
+ ZFS_DELEG_OTHER
+} zfs_deleg_perm_type_t;
+
+/*
+ * is the permission a subcommand or other?
+ */
+zfs_deleg_perm_type_t
+zfs_deleg_perm_type(const char *perm)
+{
+ if (strcmp(perm, "userprop") == 0)
+ return (ZFS_DELEG_OTHER);
+ else
+ return (ZFS_DELEG_SUBCOMMAND);
+}
+
+static char *
+zfs_deleg_perm_type_str(zfs_deleg_perm_type_t type)
+{
+ switch (type) {
+ case ZFS_DELEG_SUBCOMMAND:
+ return (dgettext(TEXT_DOMAIN, "subcommand"));
+ case ZFS_DELEG_PROP:
+ return (dgettext(TEXT_DOMAIN, "property"));
+ case ZFS_DELEG_OTHER:
+ return (dgettext(TEXT_DOMAIN, "other"));
+ }
+ return ("");
+}
+
+/*ARGSUSED*/
+static int
+zfs_deleg_prop_cb(int prop, void *cb)
+{
+ if (zfs_prop_delegatable(prop))
+ (void) fprintf(stderr, "%-15s %-15s\n", zfs_prop_to_name(prop),
+ zfs_deleg_perm_type_str(ZFS_DELEG_PROP));
+
+ return (ZPROP_CONT);
+}
+
+void
+zfs_deleg_permissions(void)
+{
+ int i;
+
+ (void) fprintf(stderr, "\n%-15s %-15s\t%s\n\n", "NAME",
+ "TYPE", "NOTES");
+
+ /*
+ * First print out the subcommands
+ */
+ for (i = 0; zfs_deleg_perm_tab[i].z_perm != NULL; i++) {
+ (void) fprintf(stderr, "%-15s %-15s\t%s\n",
+ zfs_deleg_perm_tab[i].z_perm,
+ zfs_deleg_perm_type_str(
+ zfs_deleg_perm_type(zfs_deleg_perm_tab[i].z_perm)),
+ zfs_deleg_perm_note(zfs_deleg_perm_tab[i].z_note));
+ }
+
+ (void) zprop_iter(zfs_deleg_prop_cb, NULL, B_FALSE, B_TRUE,
+ ZFS_TYPE_DATASET|ZFS_TYPE_VOLUME);
+}
+
/*
* Given a property name and value, set the property for the given dataset.
*/
--- a/usr/src/lib/libzfs/common/mapfile-vers Mon Feb 11 08:20:23 2008 -0800
+++ b/usr/src/lib/libzfs/common/mapfile-vers Mon Feb 11 11:57:00 2008 -0800
@@ -40,6 +40,7 @@
zfs_create;
zfs_create_ancestors;
zfs_dataset_exists;
+ zfs_deleg_permissions;
zfs_deleg_share_nfs;
zfs_destroy;
zfs_destroy_snaps;