def list_to_acl(entry_list, map_names=1): """Return posix1e.ACL object from list representation If map_names is true, use user_group to update the names for the current system, and drop if not available. Otherwise just use the same id. See the acl_to_list function for the format of an acllist. """ def char_to_acltag(typechar): """Given typechar, query posix1e module for appropriate constant""" if typechar == "U": return posix1e.ACL_USER_OBJ elif typechar == "u": return posix1e.ACL_USER elif typechar == "G": return posix1e.ACL_GROUP_OBJ elif typechar == "g": return posix1e.ACL_GROUP elif typechar == "M": return posix1e.ACL_MASK else: assert typechar == "O", typechar return posix1e.ACL_OTHER def warn_drop(name): """Warn about acl with name getting dropped""" global dropped_acl_names if Globals.never_drop_acls: log.Log.FatalError( "--never-drop-acls specified but cannot map name\n" "%s occurring inside an ACL." % (name, )) if dropped_acl_names.has_key(name): return log.Log( "Warning: name %s not found on system, dropping ACL entry.\n" "Further ACL entries dropped with this name will not " "trigger further warnings" % (name, ), 2) dropped_acl_names[name] = name acl = posix1e.ACL() for typechar, owner_pair, perms in entry_list: id = None if owner_pair: if map_names: if typechar == "u": id = user_group.acl_user_map(*owner_pair) else: assert typechar == "g", (typechar, owner_pair, perms) id = user_group.acl_group_map(*owner_pair) if id is None: warn_drop(owner_pair[1]) continue else: assert owner_pair[0] is not None, (typechar, owner_pair, perms) id = owner_pair[0] entry = posix1e.Entry(acl) entry.tag_type = char_to_acltag(typechar) if id is not None: entry.qualifier = id entry.permset.read = perms >> 2 entry.permset.write = perms >> 1 & 1 entry.permset.execute = perms & 1 return acl
def _list_to_acl(entry_list, map_names=1): """Return posix1e.ACL object from list representation If map_names is true, use user_group to update the names for the current system, and drop if not available. Otherwise just use the same id. See the _acl_to_list function for the format of an acllist. """ def char_to_acltag(typechar): """Given typechar, query posix1e module for appropriate constant""" if typechar == "U": return posix1e.ACL_USER_OBJ elif typechar == "u": return posix1e.ACL_USER elif typechar == "G": return posix1e.ACL_GROUP_OBJ elif typechar == "g": return posix1e.ACL_GROUP elif typechar == "M": return posix1e.ACL_MASK elif typechar == "O": return posix1e.ACL_OTHER else: raise ValueError( "Unknown ACL character {achar} (must be one of [UuGgMO]).". format(achar=typechar)) def warn_drop(name): """Warn about acl with name getting dropped""" global dropped_acl_names if Globals.never_drop_acls: log.Log.FatalError("--never-drop-acls specified but cannot map " "ACL name {an}".format(an=name)) if name in dropped_acl_names: return log.Log( "ACL name {an} not found on system, dropping entry. " "Further ACL entries dropped with this name will not " "trigger further warnings".format(an=name), log.WARNING) dropped_acl_names[name] = name acl = posix1e.ACL() for typechar, owner_pair, perms in entry_list: id = None if owner_pair: if map_names: if typechar == "u": id = map_owners.map_acl_user(*owner_pair) elif typechar == "g": id = map_owners.map_acl_group(*owner_pair) else: raise ValueError( "Type '{tc}' must be one of 'u' or 'g'.".format( tc=typechar)) if id is None: warn_drop(owner_pair[1]) continue else: assert owner_pair[0] is not None, ( "First owner can't be None with type={tc}, " "owner pair={own}, perms={perms}".format(tc=typechar, own=owner_pair, perms=perms)) id = owner_pair[0] entry = posix1e.Entry(acl) entry.tag_type = char_to_acltag(typechar) if id is not None: entry.qualifier = id entry.permset.read = perms >> 2 entry.permset.write = perms >> 1 & 1 entry.permset.execute = perms & 1 return acl
def _set_acls(self, entry, path=None): # pylint: disable=R0912 """ set POSIX ACLs on the file on disk according to the config """ 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 acls = self._list_entry_acls(entry) if path is None: path = entry.get("name") try: acl = posix1e.ACL(file=path) except IOError: err = sys.exc_info()[1] if err.errno == 95: # fs is mounted noacl if acls: self.logger.error("POSIX: Cannot set ACLs on filesystem " "mounted without ACL support: %s" % path) else: # no ACLs on the entry, no ACLs on the filesystem. # all is well in the world. return True else: self.logger.error("POSIX: Error getting current ACLS on %s: %s" % (path, err)) return False # 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]: acl.delete_entry(aclentry) if os.path.isdir(path): defacl = posix1e.ACL(filedef=path) 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 if not acls: self.logger.debug("POSIX: Removed ACLs from %s" % entry.get("name")) return True for aclkey, perms in acls.items(): atype, scope, qualifier = aclkey if atype == "default": if defacl is None: self.logger.warning("POSIX: Cannot set default ACLs on " "non-directory %s" % path) continue aclentry = posix1e.Entry(defacl) else: aclentry = posix1e.Entry(acl) for perm in ACL_MAP.values(): if perm & perms: aclentry.permset.add(perm) aclentry.tag_type = scope try: if scope == posix1e.ACL_USER: scopename = "user" if qualifier: aclentry.qualifier = self._norm_uid(qualifier) else: aclentry.tag_type = posix1e.ACL_USER_OBJ elif scope == posix1e.ACL_GROUP: scopename = "group" if qualifier: 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" % (scopename, qualifier, err)) continue acl.calc_mask() rv = self._apply_acl(acl, path) if defacl: defacl.calc_mask() rv &= self._apply_acl(defacl, path, posix1e.ACL_TYPE_DEFAULT) return rv
def _create_entry(self, type): entry = posix1e.Entry(self.acl) entry.tag_type = type self.modified = True return SimpleAclEntry(self, entry)