From d19c0ced56af17132e902e1409129dd4ad96afb5 Mon Sep 17 00:00:00 2001 From: Richard Connon Date: Tue, 4 Feb 2014 14:53:13 +0000 Subject: Support ACLs without a specific user/group for default owner/owning-group ACLs on directories --- schemas/types.xsd | 1 + src/lib/Bcfg2/Client/Tools/POSIX/base.py | 80 +++++++++++++++++++++----------- 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 @@ + 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 (, , ) """ 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(): -- cgit v1.2.3-1-g7c22