6576659 zfs allow should list delegatable perms
authormarks
Mon, 11 Feb 2008 11:57:00 -0800
changeset 5993 6309c3c0a28f
parent 5992 528b377af3c0
child 5994 bedab011a2e5
6576659 zfs allow should list delegatable perms
usr/src/cmd/zfs/zfs_main.c
usr/src/common/zfs/zfs_deleg.c
usr/src/common/zfs/zfs_deleg.h
usr/src/lib/libzfs/common/libzfs.h
usr/src/lib/libzfs/common/libzfs_dataset.c
usr/src/lib/libzfs/common/mapfile-vers
--- 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;