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 From a40c7fe2457688fd574558de7b8e31e9c30afb96 Mon Sep 17 00:00:00 2001 From: Richard Connon Date: Tue, 4 Feb 2014 15:52:48 +0000 Subject: Minor changes to default ACL code --- src/lib/Bcfg2/Client/Tools/POSIX/base.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/lib/Bcfg2/Client/Tools/POSIX/base.py b/src/lib/Bcfg2/Client/Tools/POSIX/base.py index 82e7c8fd8..4ef4ae3f5 100644 --- a/src/lib/Bcfg2/Client/Tools/POSIX/base.py +++ b/src/lib/Bcfg2/Client/Tools/POSIX/base.py @@ -251,14 +251,14 @@ class POSIXTool(Bcfg2.Client.Tools.Tool): aclentry.tag_type = scope try: if scope == posix1e.ACL_USER: + scopename = "user" 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" if qualifier: - scopename = "group" aclentry.qualifier = self._norm_gid(qualifier) else: aclentry.tag_type = posix1e.ACL_GROUP_OBJ @@ -610,9 +610,7 @@ class POSIXTool(Bcfg2.Client.Tools.Tool): qual = pwd.getpwuid(acl.qualifier)[0] elif acl.tag_type == posix1e.ACL_GROUP: qual = grp.getgrgid(acl.qualifier)[0] - elif atype == "access": - return - elif acl.tag_type == posix1e.ACL_MASK: + elif atype == "access" or acl.tag_type == posix1e.ACL_MASK: return except (OSError, KeyError): err = sys.exc_info()[1] @@ -686,6 +684,7 @@ class POSIXTool(Bcfg2.Client.Tools.Tool): self.logger.debug("POSIX: Unknown ACL scope %s on %s" % (scope, path)) continue + if scope != posix1e.ACL_OTHER: aclentry.set(aclentry.get("scope"), qual) entry.append(aclentry) -- cgit v1.2.3-1-g7c22 From d208eed80e048ea2081165c7aaaa92c558c38b25 Mon Sep 17 00:00:00 2001 From: Richard Connon Date: Tue, 4 Feb 2014 16:03:17 +0000 Subject: fix for "Too many branches" in _verify_acls --- src/lib/Bcfg2/Client/Tools/POSIX/base.py | 43 +++++++++++++++++--------------- 1 file changed, 23 insertions(+), 20 deletions(-) diff --git a/src/lib/Bcfg2/Client/Tools/POSIX/base.py b/src/lib/Bcfg2/Client/Tools/POSIX/base.py index 4ef4ae3f5..4fb3c7b34 100644 --- a/src/lib/Bcfg2/Client/Tools/POSIX/base.py +++ b/src/lib/Bcfg2/Client/Tools/POSIX/base.py @@ -643,26 +643,7 @@ class POSIXTool(Bcfg2.Client.Tools.Tool): def _verify_acls(self, entry, path=None): """ verify POSIX ACLs on the given entry. return True if all ACLS are correct, false otherwise """ - if not HAS_ACLS: - if entry.findall("ACL"): - self.logger.debug("POSIX: ACLs listed for %s but no pylibacl " - "library installed" % entry.get('name')) - return True - - if path is None: - path = entry.get("name") - - # create lists of normalized representations of the ACLs we want - # and the ACLs we have. this will make them easier to compare - # than trying to mine that data out of the ACL objects and XML - # objects and compare it at the same time. - wanted = self._list_entry_acls(entry) - existing = self._list_file_acls(path) - - missing = [] - extra = [] - wrong = [] - for aclkey, perms in wanted.items(): + def _verify_acl(aclkey, perms): if aclkey not in existing: missing.append(self._acl2string(aclkey, perms)) elif existing[aclkey] != perms: @@ -689,6 +670,28 @@ class POSIXTool(Bcfg2.Client.Tools.Tool): aclentry.set(aclentry.get("scope"), qual) entry.append(aclentry) + if not HAS_ACLS: + if entry.findall("ACL"): + self.logger.debug("POSIX: ACLs listed for %s but no pylibacl " + "library installed" % entry.get('name')) + return True + + if path is None: + path = entry.get("name") + + # create lists of normalized representations of the ACLs we want + # and the ACLs we have. this will make them easier to compare + # than trying to mine that data out of the ACL objects and XML + # objects and compare it at the same time. + wanted = self._list_entry_acls(entry) + existing = self._list_file_acls(path) + + missing = [] + extra = [] + wrong = [] + for aclkey, perms in wanted.items(): + _verify_acl(aclkey, perms) + for aclkey, perms in existing.items(): if aclkey not in wanted: extra.append(self._acl2string(aclkey, perms)) -- cgit v1.2.3-1-g7c22 From 310ec389a7542b8f7aeb807c6ed71ae7a82515d0 Mon Sep 17 00:00:00 2001 From: Richard Connon Date: Tue, 4 Feb 2014 16:07:54 +0000 Subject: Fixed continue not in a loop error in previous --- src/lib/Bcfg2/Client/Tools/POSIX/base.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/Bcfg2/Client/Tools/POSIX/base.py b/src/lib/Bcfg2/Client/Tools/POSIX/base.py index 4fb3c7b34..4089e9f22 100644 --- a/src/lib/Bcfg2/Client/Tools/POSIX/base.py +++ b/src/lib/Bcfg2/Client/Tools/POSIX/base.py @@ -664,7 +664,7 @@ class POSIXTool(Bcfg2.Client.Tools.Tool): else: self.logger.debug("POSIX: Unknown ACL scope %s on %s" % (scope, path)) - continue + return if scope != posix1e.ACL_OTHER: aclentry.set(aclentry.get("scope"), qual) -- cgit v1.2.3-1-g7c22 From b30cdb5330940c4606acbb83b057335be480552b Mon Sep 17 00:00:00 2001 From: Richard Connon Date: Tue, 4 Feb 2014 16:20:24 +0000 Subject: Removed redundant condition for empty default ACL --- src/lib/Bcfg2/Client/Tools/POSIX/base.py | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/lib/Bcfg2/Client/Tools/POSIX/base.py b/src/lib/Bcfg2/Client/Tools/POSIX/base.py index 4089e9f22..d230a5b3a 100644 --- a/src/lib/Bcfg2/Client/Tools/POSIX/base.py +++ b/src/lib/Bcfg2/Client/Tools/POSIX/base.py @@ -219,14 +219,13 @@ class POSIXTool(Bcfg2.Client.Tools.Tool): acl.delete_entry(aclentry) if os.path.isdir(path): defacl = posix1e.ACL(filedef=path) - if defacl.valid(): - for aclentry in defacl: - if aclentry.tag_type in [posix1e.ACL_USER, - posix1e.ACL_USER_OBJ, - posix1e.ACL_GROUP, - posix1e.ACL_GROUP_OBJ, - posix1e.ACL_OTHER]: - defacl.delete_entry(aclentry) + for aclentry in defacl: + if aclentry.tag_type in [posix1e.ACL_USER, + posix1e.ACL_USER_OBJ, + posix1e.ACL_GROUP, + posix1e.ACL_GROUP_OBJ, + posix1e.ACL_OTHER]: + defacl.delete_entry(aclentry) else: defacl = None -- cgit v1.2.3-1-g7c22 From bfdf4e9cac0c5d93cf7ce63513557847f005d5d2 Mon Sep 17 00:00:00 2001 From: Richard Connon Date: Tue, 4 Feb 2014 16:59:44 +0000 Subject: Except _verify_acls from pylint branches check --- src/lib/Bcfg2/Client/Tools/POSIX/base.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/Bcfg2/Client/Tools/POSIX/base.py b/src/lib/Bcfg2/Client/Tools/POSIX/base.py index d230a5b3a..d4051ba7f 100644 --- a/src/lib/Bcfg2/Client/Tools/POSIX/base.py +++ b/src/lib/Bcfg2/Client/Tools/POSIX/base.py @@ -639,7 +639,7 @@ class POSIXTool(Bcfg2.Client.Tools.Tool): _process_acl(acl, "default") return existing - def _verify_acls(self, entry, path=None): + def _verify_acls(self, entry, path=None): # pylint: disable=R0912 """ verify POSIX ACLs on the given entry. return True if all ACLS are correct, false otherwise """ def _verify_acl(aclkey, perms): -- cgit v1.2.3-1-g7c22 From 86f4766fd357c79956cd95b0506d1c85da96416d Mon Sep 17 00:00:00 2001 From: Richard Connon Date: Tue, 4 Feb 2014 20:05:24 +0000 Subject: docstring for new sub-method --- src/lib/Bcfg2/Client/Tools/POSIX/base.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/lib/Bcfg2/Client/Tools/POSIX/base.py b/src/lib/Bcfg2/Client/Tools/POSIX/base.py index d4051ba7f..0eb9239c5 100644 --- a/src/lib/Bcfg2/Client/Tools/POSIX/base.py +++ b/src/lib/Bcfg2/Client/Tools/POSIX/base.py @@ -643,6 +643,8 @@ class POSIXTool(Bcfg2.Client.Tools.Tool): """ verify POSIX ACLs on the given entry. return True if all ACLS are correct, false otherwise """ def _verify_acl(aclkey, perms): + """ Given ACL data, process it appropriately and add it to + missing or wrong lists if appropriate """ if aclkey not in existing: missing.append(self._acl2string(aclkey, perms)) elif existing[aclkey] != perms: -- cgit v1.2.3-1-g7c22 From 75e1233c4ac292a554562b51475e972c647bd2b5 Mon Sep 17 00:00:00 2001 From: Richard Connon Date: Mon, 10 Feb 2014 17:32:57 +0000 Subject: Don't strip other entries from default ACL, these are defined by mode number. --- src/lib/Bcfg2/Client/Tools/POSIX/base.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/lib/Bcfg2/Client/Tools/POSIX/base.py b/src/lib/Bcfg2/Client/Tools/POSIX/base.py index 0eb9239c5..e593e0a0a 100644 --- a/src/lib/Bcfg2/Client/Tools/POSIX/base.py +++ b/src/lib/Bcfg2/Client/Tools/POSIX/base.py @@ -213,9 +213,7 @@ 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, - posix1e.ACL_OTHER]: + if aclentry.tag_type in [posix1e.ACL_USER, posix1e.ACL_GROUP]: acl.delete_entry(aclentry) if os.path.isdir(path): defacl = posix1e.ACL(filedef=path) -- cgit v1.2.3-1-g7c22 From 9ac25c247afc348c90197f33039c066d2a9d4247 Mon Sep 17 00:00:00 2001 From: Richard Connon Date: Fri, 14 Feb 2014 12:04:43 +0000 Subject: Lint checking for invalid default ACLs --- src/lib/Bcfg2/Server/Lint/RequiredAttrs.py | 33 +++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/src/lib/Bcfg2/Server/Lint/RequiredAttrs.py b/src/lib/Bcfg2/Server/Lint/RequiredAttrs.py index e49779a10..77934d720 100644 --- a/src/lib/Bcfg2/Server/Lint/RequiredAttrs.py +++ b/src/lib/Bcfg2/Server/Lint/RequiredAttrs.py @@ -119,6 +119,7 @@ class RequiredAttrs(Bcfg2.Server.Lint.ServerPlugin): POSIXUser={None: dict(name=is_username)}) def Run(self): + self.check_default_acls() self.check_packages() if "Defaults" in self.core.plugins: self.logger.info("Defaults plugin enabled; skipping required " @@ -129,12 +130,42 @@ class RequiredAttrs(Bcfg2.Server.Lint.ServerPlugin): @classmethod def Errors(cls): - return {"unknown-entry-type": "error", + return {"missing-elements": "error", + "unknown-entry-type": "error", "unknown-entry-tag": "error", "required-attrs-missing": "error", "required-attr-format": "error", "extra-attrs": "warning"} + def check_default_acls(self): + """ Check Path entries have valid default ACLs """ + def check_acl(path): + """ Check that a default ACL contains either no entries or minimum + required entries """ + defaults = 1 if len(path.xpath( + "/ACL[@type='default' and @scope='user']")) else 0 + defaults += 1 if len(path.xpath( + "/ACL[@type='default' and @scope='user']")) else 0 + defaults += 1 if len(path.xpath( + "/ACL[@type='default' and @scope='user']")) else 0 + if defaults > 0 and defaults < 3: + self.LintError( + "missing-elements", + "A Path must have either no default ACLs or at" + " least default:user::, default:group:: and" + " default:other::") + + if 'Bundler' in self.core.plugins: + for bundle in self.core.plugins['Bundler'].entries.values(): + xdata = bundle.pnode.data + for path in xdata.xpath("//BoundPath"): + check_acl(path) + if 'Rules' in self.core.plugins: + for rules in self.core.plugins['Rules'].entries.values(): + xdata = rules.pnode.data + for path in xdata.xpath("//Path"): + check_acl(path) + def check_packages(self): """ Check Packages sources for Source entries with missing attributes. """ -- cgit v1.2.3-1-g7c22 From 06bc91f8a8c919e5e552f46386841a75fcc3619a Mon Sep 17 00:00:00 2001 From: Richard Connon Date: Fri, 14 Feb 2014 12:10:04 +0000 Subject: Correct XML source for bundles in default ACL Lint --- src/lib/Bcfg2/Server/Lint/RequiredAttrs.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/Bcfg2/Server/Lint/RequiredAttrs.py b/src/lib/Bcfg2/Server/Lint/RequiredAttrs.py index 77934d720..fce90154e 100644 --- a/src/lib/Bcfg2/Server/Lint/RequiredAttrs.py +++ b/src/lib/Bcfg2/Server/Lint/RequiredAttrs.py @@ -157,7 +157,7 @@ class RequiredAttrs(Bcfg2.Server.Lint.ServerPlugin): if 'Bundler' in self.core.plugins: for bundle in self.core.plugins['Bundler'].entries.values(): - xdata = bundle.pnode.data + xdata = lxml.etree.XML(bundle.data) for path in xdata.xpath("//BoundPath"): check_acl(path) if 'Rules' in self.core.plugins: -- cgit v1.2.3-1-g7c22 From e4b2b05de382743883ee613236d4647c588d811d Mon Sep 17 00:00:00 2001 From: Richard Connon Date: Fri, 14 Feb 2014 23:29:48 +0000 Subject: Working lint check for invalid default ACLs --- src/lib/Bcfg2/Server/Lint/RequiredAttrs.py | 47 ++++++++++++------------------ 1 file changed, 18 insertions(+), 29 deletions(-) diff --git a/src/lib/Bcfg2/Server/Lint/RequiredAttrs.py b/src/lib/Bcfg2/Server/Lint/RequiredAttrs.py index fce90154e..bb0d6956a 100644 --- a/src/lib/Bcfg2/Server/Lint/RequiredAttrs.py +++ b/src/lib/Bcfg2/Server/Lint/RequiredAttrs.py @@ -119,7 +119,6 @@ class RequiredAttrs(Bcfg2.Server.Lint.ServerPlugin): POSIXUser={None: dict(name=is_username)}) def Run(self): - self.check_default_acls() self.check_packages() if "Defaults" in self.core.plugins: self.logger.info("Defaults plugin enabled; skipping required " @@ -137,34 +136,21 @@ class RequiredAttrs(Bcfg2.Server.Lint.ServerPlugin): "required-attr-format": "error", "extra-attrs": "warning"} - def check_default_acls(self): - """ Check Path entries have valid default ACLs """ - def check_acl(path): - """ Check that a default ACL contains either no entries or minimum - required entries """ - defaults = 1 if len(path.xpath( - "/ACL[@type='default' and @scope='user']")) else 0 - defaults += 1 if len(path.xpath( - "/ACL[@type='default' and @scope='user']")) else 0 - defaults += 1 if len(path.xpath( - "/ACL[@type='default' and @scope='user']")) else 0 - if defaults > 0 and defaults < 3: - self.LintError( - "missing-elements", - "A Path must have either no default ACLs or at" - " least default:user::, default:group:: and" - " default:other::") - - if 'Bundler' in self.core.plugins: - for bundle in self.core.plugins['Bundler'].entries.values(): - xdata = lxml.etree.XML(bundle.data) - for path in xdata.xpath("//BoundPath"): - check_acl(path) - if 'Rules' in self.core.plugins: - for rules in self.core.plugins['Rules'].entries.values(): - xdata = rules.pnode.data - for path in xdata.xpath("//Path"): - check_acl(path) + def check_default_acl(self, path): + """ Check that a default ACL contains either no entries or minimum + required entries """ + defaults = 1 if path.xpath( + "ACL[@type='default' and @scope='user' and @user='']") else 0 + defaults += 1 if path.xpath( + "ACL[@type='default' and @scope='group' and @group='']") else 0 + defaults += 1 if path.xpath( + "ACL[@type='default' and @scope='other']") else 0 + if defaults > 0 and defaults < 3: + self.LintError( + "missing-elements", + "A Path must have either no default ACLs or at" + " least default:user::, default:group:: and" + " default:other::") def check_packages(self): """ Check Packages sources for Source entries with missing @@ -265,6 +251,9 @@ class RequiredAttrs(Bcfg2.Server.Lint.ServerPlugin): required_attrs['major'] = is_device_mode required_attrs['minor'] = is_device_mode + if tag == 'Path': + self.check_default_acl(entry) + if tag == 'ACL' and 'scope' in required_attrs: required_attrs[entry.get('scope')] = is_username -- cgit v1.2.3-1-g7c22 From b63d4e12333b229948ea53703213b97275d790bd Mon Sep 17 00:00:00 2001 From: Richard Connon Date: Fri, 14 Feb 2014 23:35:04 +0000 Subject: Documentation changes for default ACLs --- doc/server/plugins/generators/rules.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/doc/server/plugins/generators/rules.txt b/doc/server/plugins/generators/rules.txt index a21dd217f..77ce63e51 100644 --- a/doc/server/plugins/generators/rules.txt +++ b/doc/server/plugins/generators/rules.txt @@ -295,6 +295,7 @@ child ```` tags. For instance: mode="0775"> + .. xml:element:: ACL @@ -303,6 +304,9 @@ It is not currently possible to manually set an effective rights mask; the mask will be automatically calculated from the given ACLs when they are applied. +For directories either no default ACL entries or at least an entry for +the owner, owning group and other must be defined. + Note that it is possible to set ACLs that demand different permissions on a file than those specified in the ``perms`` attribute on the ``Path`` tag. For instance: -- cgit v1.2.3-1-g7c22 From 304cf13f4988312a4ec6ac14fff79bc74737e3ee Mon Sep 17 00:00:00 2001 From: Richard Connon Date: Tue, 18 Feb 2014 14:46:49 +0000 Subject: support python 2.4 for default ACL checking in Lint --- src/lib/Bcfg2/Server/Lint/RequiredAttrs.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/lib/Bcfg2/Server/Lint/RequiredAttrs.py b/src/lib/Bcfg2/Server/Lint/RequiredAttrs.py index bb0d6956a..1d12ee461 100644 --- a/src/lib/Bcfg2/Server/Lint/RequiredAttrs.py +++ b/src/lib/Bcfg2/Server/Lint/RequiredAttrs.py @@ -139,12 +139,13 @@ class RequiredAttrs(Bcfg2.Server.Lint.ServerPlugin): def check_default_acl(self, path): """ Check that a default ACL contains either no entries or minimum required entries """ - defaults = 1 if path.xpath( - "ACL[@type='default' and @scope='user' and @user='']") else 0 - defaults += 1 if path.xpath( - "ACL[@type='default' and @scope='group' and @group='']") else 0 - defaults += 1 if path.xpath( - "ACL[@type='default' and @scope='other']") else 0 + defaults = 0 + if path.xpath("ACL[@type='default' and @scope='user' and @user='']"): + defaults += 1 + if path.xpath("ACL[@type='default' and @scope='group' and @group='']"): + defaults += 1 + if path.xpath("ACL[@type='default' and @scope='other']"): + defaults += 1 if defaults > 0 and defaults < 3: self.LintError( "missing-elements", -- cgit v1.2.3-1-g7c22