#!@PYTHON@
#
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
# Common Development and Distribution License (the "License").
# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# See the License for the specific language governing permissions
# and limitations under the License.
#
# When distributing Covered Code, include this CDDL HEADER in each
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
# If applicable, add the following below this CDDL HEADER, with the
# fields enclosed by brackets "[]" replaced with your own identifying
# information: Portions Copyright [yyyy] [name of copyright owner]
#
# CDDL HEADER END
#
# Copyright (c) 2013 by Delphix. All rights reserved.
#
"""This module implements the "zfs allow" and "zfs unallow" subcommands.
The only public interface is the zfs.allow.do_allow() function."""
import optparse
import sys
import pwd
import grp
import errno
"""This class represents all the permissions that are set on a
particular filesystem (not including those inherited)."""
"""Create a FSPerms based on the dict of raw permissions
from zfs.ioctl.get_fsacl()."""
# set of perms
# below are { "Ntype name": set(perms) }
# where N is a number that we just use for sorting,
# type is "user", "group", "everyone", or "" (for sets)
# name is a user, group, or set name, or "" (for everyone)
# see the comment in dsl_deleg.c for the definition of whokey
if whotypechr == "c":
elif whotypechr == "s":
else:
if whotypechr == "u":
try:
except KeyError:
elif whotypechr == "g":
try:
except KeyError:
elif whotypechr == "e":
nwho = "3everyone"
else:
raise ValueError(whotypechr)
else:
# Find perms that are in both local and descend, and
# move them to ld.
continue
# note: these are set operations
s = ""
# local and descend may have entries where perms
# is an empty set, due to consolidating all
# permissions into ld
if perms:
s += "\t%s %s\n" % \
if s:
s = header + s
return s
s += _("Create time permissions:\n")
return s.rstrip()
"""Return a dict of raw perms {"whostr" -> {"perm" -> None}}
based on the command-line input."""
# perms is not set if we are doing a "zfs unallow <who> <fs>" to
# remove all of someone's permissions
if perms:
else:
setperms = None
baseperms = None
d = dict()
assert typechr in "ugecs"
assert inheritchr in "ld-"
def mkwhokey(t):
try:
return int(w)
except ValueError:
try:
return toidfunc(w)[2]
except KeyError:
else:
for w in who:
_("invalid user %s"))
typechr = "u"
_("invalid group %s"))
typechr = "g"
elif w == "everyone":
id = ""
typechr = "e"
else:
try:
typechr = "u"
except KeyError:
try:
typechr = "g"
except KeyError:
return d
create=_("Must also have the 'mount' ability"),
destroy=_("Must also have the 'mount' ability"),
snapshot="",
rollback="",
clone=_("""Must also have the 'create' ability and 'mount'
\t\t\t\tability in the origin file system"""),
promote=_("""Must also have the 'mount'
\t\t\t\tand 'promote' ability in the origin file system"""),
rename=_("""Must also have the 'mount' and 'create'
\t\t\t\tability in the new parent"""),
receive=_("Must also have the 'mount' and 'create' ability"),
allow=_("Must also have the permission that is being\n\t\t\t\tallowed"),
share=_("Allows sharing file systems over NFS or SMB\n\t\t\t\tprotocols"),
send="",
hold=_("Allows adding a user hold to a snapshot"),
release=_("Allows releasing a user hold which\n\t\t\t\tmight destroy the snapshot"),
diff=_("Allows lookup of paths within a dataset,\n\t\t\t\tgiven an object number. Ordinary users need this\n\t\t\t\tin order to use zfs diff"),
bookmark="",
)
userprop=_("Allows changing any user property"),
userquota=_("Allows accessing any userquota@... property"),
groupquota=_("Allows accessing any groupquota@... property"),
userused=_("Allows reading any userused@... property"),
groupused=_("Allows reading any groupused@... property"),
)
"""Return True if the given setname (string) is defined for this
ds (Dataset)."""
# It would be nice to cache the result of get_fsacl().
return True
return False
"""Return the canonical name (string) for this permission (string).
Raises ZFSError if it is not a valid permission."""
return permname
try:
except KeyError:
_("invalid permission"))
def print_perms():
"""Print the set of supported permissions."""
print(_("\nThe following permissions are supported:\n"))
fmt = "%-16s %-14s\t%s"
def do_allow():
"""Implements the "zfs allow" and "zfs unallow" subcommands."""
if msg:
print
else:
if un:
u = _("""unallow [-rldug] <"everyone"|user|group>[,...]
[<perm|@setname>[,...]] <filesystem|volume>
unallow [-rld] -e [<perm|@setname>[,...]] <filesystem|volume>
unallow [-r] -c [<perm|@setname>[,...]] <filesystem|volume>
unallow [-r] -s @setname [<perm|@setname>[,...]] <filesystem|volume>""")
verb = _("remove")
sstr = _("undefine permission set")
else:
u = _("""allow <filesystem|volume>
allow [-ldug] <"everyone"|user|group>[,...] <perm|@setname>[,...]
<filesystem|volume>
allow [-ld] -e <perm|@setname>[,...] <filesystem|volume>
allow -c <perm|@setname>[,...] <filesystem|volume>
allow -s @setname <perm|@setname>[,...] <filesystem|volume>""")
verb = _("set")
sstr = _("define permission set")
if un:
help=_("remove permissions recursively"))
# just print the permissions on this fs
# hack to make "zfs allow -h" work
usage()
p = dict()
s = _("---- Permissions on %s ") % fs
print(p[fs])
return
else:
usage(_("wrong number of parameters"))
who = None
who = ["everyone"]
else:
for p in perms: