コード例 #1
0
ファイル: eas_acls.py プロジェクト: Acidburn0zzz/rdiff-backup
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
コード例 #2
0
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
コード例 #3
0
ファイル: base.py プロジェクト: tomaszov/bcfg2
    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
コード例 #4
0
 def _create_entry(self, type):
     entry = posix1e.Entry(self.acl)
     entry.tag_type = type
     self.modified = True
     return SimpleAclEntry(self, entry)