summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard Connon <richard@connon.me.uk>2014-02-04 14:53:13 +0000
committerRichard Connon <richard@connon.me.uk>2014-02-04 14:53:13 +0000
commitd19c0ced56af17132e902e1409129dd4ad96afb5 (patch)
tree071b698d67f1125b64c164406fc0af0167f626fd
parentc5ad7f0edbdbfcb38506b97a92001a9624e36f6b (diff)
downloadbcfg2-d19c0ced56af17132e902e1409129dd4ad96afb5.tar.gz
bcfg2-d19c0ced56af17132e902e1409129dd4ad96afb5.tar.bz2
bcfg2-d19c0ced56af17132e902e1409129dd4ad96afb5.zip
Support ACLs without a specific user/group for default owner/owning-group ACLs on directories
-rw-r--r--schemas/types.xsd1
-rw-r--r--src/lib/Bcfg2/Client/Tools/POSIX/base.py80
2 files changed, 53 insertions, 28 deletions
diff --git a/schemas/types.xsd b/schemas/types.xsd
index 836cfa38e..52c9d59c8 100644
--- a/schemas/types.xsd
+++ b/schemas/types.xsd
@@ -200,6 +200,7 @@
<xsd:restriction base="xsd:string">
<xsd:enumeration value="user"/>
<xsd:enumeration value="group"/>
+ <xsd:enumeration value="other"/>
</xsd:restriction>
</xsd:simpleType>
diff --git a/src/lib/Bcfg2/Client/Tools/POSIX/base.py b/src/lib/Bcfg2/Client/Tools/POSIX/base.py
index 3243bbf50..82e7c8fd8 100644
--- a/src/lib/Bcfg2/Client/Tools/POSIX/base.py
+++ b/src/lib/Bcfg2/Client/Tools/POSIX/base.py
@@ -213,21 +213,19 @@ class POSIXTool(Bcfg2.Client.Tools.Tool):
# clear ACLs out so we start fresh -- way easier than trying
# to add/remove/modify ACLs
for aclentry in acl:
- if aclentry.tag_type in [posix1e.ACL_USER, posix1e.ACL_GROUP]:
+ if aclentry.tag_type in [posix1e.ACL_USER,
+ posix1e.ACL_GROUP,
+ posix1e.ACL_OTHER]:
acl.delete_entry(aclentry)
if os.path.isdir(path):
defacl = posix1e.ACL(filedef=path)
- if not defacl.valid():
- # when a default ACL is queried on a directory that
- # has no default ACL entries at all, you get an empty
- # ACL, which is not valid. in this circumstance, we
- # just copy the access ACL to get a base valid ACL
- # that we can add things to.
- defacl = posix1e.ACL(acl=acl)
- else:
+ if defacl.valid():
for aclentry in defacl:
if aclentry.tag_type in [posix1e.ACL_USER,
- posix1e.ACL_GROUP]:
+ posix1e.ACL_USER_OBJ,
+ posix1e.ACL_GROUP,
+ posix1e.ACL_GROUP_OBJ,
+ posix1e.ACL_OTHER]:
defacl.delete_entry(aclentry)
else:
defacl = None
@@ -253,11 +251,17 @@ class POSIXTool(Bcfg2.Client.Tools.Tool):
aclentry.tag_type = scope
try:
if scope == posix1e.ACL_USER:
- scopename = "user"
- aclentry.qualifier = self._norm_uid(qualifier)
+ if qualifier:
+ scopename = "user"
+ aclentry.qualifier = self._norm_uid(qualifier)
+ else:
+ aclentry.tag_type = posix1e.ACL_USER_OBJ
elif scope == posix1e.ACL_GROUP:
- scopename = "group"
- aclentry.qualifier = self._norm_gid(qualifier)
+ if qualifier:
+ scopename = "group"
+ aclentry.qualifier = self._norm_gid(qualifier)
+ else:
+ aclentry.tag_type = posix1e.ACL_GROUP_OBJ
except (OSError, KeyError):
err = sys.exc_info()[1]
self.logger.error("POSIX: Could not resolve %s %s: %s" %
@@ -358,7 +362,7 @@ class POSIXTool(Bcfg2.Client.Tools.Tool):
try:
# single octal digit
rv = int(perms)
- if rv > 0 and rv < 8:
+ if rv >= 0 and rv < 8:
return rv
else:
self.logger.error("POSIX: Permissions digit out of range in "
@@ -388,17 +392,18 @@ class POSIXTool(Bcfg2.Client.Tools.Tool):
""" Get a string representation of the given ACL. aclkey must
be a tuple of (<acl type>, <acl scope>, <qualifier>) """
atype, scope, qualifier = aclkey
+ if not qualifier:
+ qualifier = ''
acl_str = []
if atype == 'default':
acl_str.append(atype)
- if scope == posix1e.ACL_USER:
+ if scope == posix1e.ACL_USER or scope == posix1e.ACL_USER_OBJ:
acl_str.append("user")
- elif scope == posix1e.ACL_GROUP:
+ elif scope == posix1e.ACL_GROUP or scope == posix1e.ACL_GROUP_OBJ:
acl_str.append("group")
- if qualifier is None:
- acl_str.append('')
- else:
- acl_str.append(qualifier)
+ elif scope == posix1e.ACL_OTHER:
+ acl_str.append("other")
+ acl_str.append(qualifier)
acl_str.append(self._acl_perm2string(perms))
return ":".join(acl_str)
@@ -564,9 +569,17 @@ class POSIXTool(Bcfg2.Client.Tools.Tool):
wanted = dict()
for acl in entry.findall("ACL"):
if acl.get("scope") == "user":
- scope = posix1e.ACL_USER
+ if acl.get("user"):
+ scope = posix1e.ACL_USER
+ else:
+ scope = posix1e.ACL_USER_OBJ
elif acl.get("scope") == "group":
- scope = posix1e.ACL_GROUP
+ if acl.get("group"):
+ scope = posix1e.ACL_GROUP
+ else:
+ scope = posix1e.ACL_GROUP_OBJ
+ elif acl.get("scope") == "other":
+ scope = posix1e.ACL_OTHER
else:
self.logger.error("POSIX: Unknown ACL scope %s" %
acl.get("scope"))
@@ -575,7 +588,10 @@ class POSIXTool(Bcfg2.Client.Tools.Tool):
self.logger.error("POSIX: No permissions set for ACL: %s" %
Bcfg2.Client.XML.tostring(acl))
continue
- wanted[(acl.get("type"), scope, acl.get(acl.get("scope")))] = \
+ qual = acl.get(acl.get("scope"))
+ if not qual:
+ qual = ''
+ wanted[(acl.get("type"), scope, qual)] = \
self._norm_acl_perms(acl.get('perms'))
return wanted
@@ -589,11 +605,14 @@ class POSIXTool(Bcfg2.Client.Tools.Tool):
""" Given an ACL object, process it appropriately and add
it to the return value """
try:
+ qual = ''
if acl.tag_type == posix1e.ACL_USER:
qual = pwd.getpwuid(acl.qualifier)[0]
elif acl.tag_type == posix1e.ACL_GROUP:
qual = grp.getgrgid(acl.qualifier)[0]
- else:
+ elif atype == "access":
+ return
+ elif acl.tag_type == posix1e.ACL_MASK:
return
except (OSError, KeyError):
err = sys.exc_info()[1]
@@ -655,15 +674,20 @@ class POSIXTool(Bcfg2.Client.Tools.Tool):
atype, scope, qual = aclkey
aclentry = Bcfg2.Client.XML.Element("ACL", type=atype,
perms=str(perms))
- if scope == posix1e.ACL_USER:
+ if (scope == posix1e.ACL_USER or
+ scope == posix1e.ACL_USER_OBJ):
aclentry.set("scope", "user")
- elif scope == posix1e.ACL_GROUP:
+ elif (scope == posix1e.ACL_GROUP or
+ scope == posix1e.ACL_GROUP_OBJ):
aclentry.set("scope", "group")
+ elif scope == posix1e.ACL_OTHER:
+ aclentry.set("scope", "other")
else:
self.logger.debug("POSIX: Unknown ACL scope %s on %s" %
(scope, path))
continue
- aclentry.set(aclentry.get("scope"), qual)
+ if scope != posix1e.ACL_OTHER:
+ aclentry.set(aclentry.get("scope"), qual)
entry.append(aclentry)
for aclkey, perms in existing.items():