From 4918807565a39f78b1a37159c20b3b472d73522e Mon Sep 17 00:00:00 2001 From: bescoto Date: Wed, 10 Aug 2005 05:25:43 +0000 Subject: Fix for bug #13576, destination system should not need posix1e git-svn-id: http://svn.savannah.nongnu.org/svn/rdiff-backup/trunk@604 2b77aa54-bcbc-44c9-a7ec-4f6cf2b41109 --- rdiff-backup/CHANGELOG | 3 ++ rdiff-backup/rdiff_backup/eas_acls.py | 87 ++++++++++++++++++++++++----------- rdiff-backup/testing/eas_aclstest.py | 5 +- 3 files changed, 66 insertions(+), 29 deletions(-) diff --git a/rdiff-backup/CHANGELOG b/rdiff-backup/CHANGELOG index 3b7059f..ca57603 100644 --- a/rdiff-backup/CHANGELOG +++ b/rdiff-backup/CHANGELOG @@ -37,6 +37,9 @@ Added Keith Edmunds patch adding the --create-full-path option. Fixed selection bug reported by Daniel Richard G. +bug#13576: You can now back ACLs to a computer that doesn't have the +posix1e module. + New in v0.13.6 (2005/04/07) --------------------------- diff --git a/rdiff-backup/rdiff_backup/eas_acls.py b/rdiff-backup/rdiff_backup/eas_acls.py index fe24c81..0db865f 100644 --- a/rdiff-backup/rdiff_backup/eas_acls.py +++ b/rdiff-backup/rdiff_backup/eas_acls.py @@ -228,21 +228,19 @@ class AccessControlLists: def entrytuple_to_text(self, entrytuple): """Return text version of entrytuple, as in getfacl""" - type, name_pair, perms = entrytuple - if type == posix1e.ACL_USER_OBJ: - text = 'user::' - elif type == posix1e.ACL_USER: + tagchar, name_pair, perms = entrytuple + if tagchar == "U": text = 'user::' + elif tagchar == "u": uid, uname = name_pair text = 'user:%s:' % (uname or uid) - elif type == posix1e.ACL_GROUP_OBJ: + elif tagchar == "G": text = 'group::' - elif type == posix1e.ACL_GROUP: + elif tagchar == "g": gid, gname = name_pair text = 'group:%s:' % (gname or gid) - elif type == posix1e.ACL_MASK: - text = 'mask::' + elif tagchar == "M": text = 'mask::' else: - assert type == posix1e.ACL_OTHER, type + assert tagchar == "O", tagchar text = 'other::' permstring = '%s%s%s' % (perms & 4 and 'r' or '-', @@ -251,32 +249,36 @@ class AccessControlLists: return text+permstring def text_to_entrytuple(self, text): - """Return entrytuple given text like 'user:foo:r--'""" + """Return entrytuple given text like 'user:foo:r--' + + See the acl_to_list function for entrytuple documentation. + + """ typetext, qualifier, permtext = text.split(':') if qualifier: try: uid = int(qualifier) except ValueError: namepair = (None, qualifier) else: namepair = (uid, None) - if typetext == 'user': type = posix1e.ACL_USER + if typetext == 'user': typechar = "u" else: assert typetext == 'group', (typetext, text) - type = posix1e.ACL_GROUP + typechar = "g" else: namepair = None - if typetext == 'user': type = posix1e.ACL_USER_OBJ - elif typetext == 'group': type = posix1e.ACL_GROUP_OBJ - elif typetext == 'mask': type = posix1e.ACL_MASK + if typetext == 'user': typechar = "U" + elif typetext == 'group': typechar = "G" + elif typetext == 'mask': typechar = "M" else: assert typetext == 'other', (typetext, text) - type = posix1e.ACL_OTHER + typechar = "O" assert len(permtext) == 3, (permtext, text) read, write, execute = permtext perms = ((read == 'r') << 2 | (write == 'w') << 1 | (execute == 'x')) - return (type, namepair, perms) + return (typechar, namepair, perms) def cmp_entry_list(self, l1, l2): """True if the lists have same entries. Assume preordered""" @@ -385,15 +387,33 @@ def acl_to_list(acl): lost when moved to another system. The result will be a list of tuples. Each tuple will have the - form (acltype, (uid or gid, uname or gname) or None, - permissions as an int). + form (acltype, (uid or gid, uname or gname) or None, permissions + as an int). acltype is encoded as a single character: + + U - ACL_USER_OBJ + u - ACL_USER + G - ACL_GROUP_OBJ + g - ACL_GROUP + M - ACL_MASK + O - ACL_OTHER """ + def acltag_to_char(tag): + if tag == posix1e.ACL_USER_OBJ: return "U" + elif tag == posix1e.ACL_USER: return "u" + elif tag == posix1e.ACL_GROUP_OBJ: return "G" + elif tag == posix1e.ACL_GROUP: return "g" + elif tag == posix1e.ACL_MASK: return "M" + else: + assert tag == posix1e.ACL_OTHER, tag + return "O" + def entry_to_tuple(entry): - if entry.tag_type == posix1e.ACL_USER: + tagchar = acltag_to_char(entry.tag_type) + if tagchar == "u": uid = entry.qualifier owner_pair = (uid, user_group.uid2uname(uid)) - elif entry.tag_type == posix1e.ACL_GROUP: + elif tagchar == "g": gid = entry.qualifier owner_pair = (gid, user_group.gid2gname(gid)) else: owner_pair = None @@ -401,7 +421,7 @@ def acl_to_list(acl): perms = (entry.permset.read << 2 | entry.permset.write << 1 | entry.permset.execute) - return (entry.tag_type, owner_pair, perms) + return (tagchar, owner_pair, perms) return map(entry_to_tuple, acl) def list_to_acl(entry_list, map_names = 1): @@ -411,7 +431,20 @@ def list_to_acl(entry_list, map_names = 1): 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 @@ -435,23 +468,23 @@ def list_to_acl(entry_list, map_names = 1): return Map.get_id_from_id(id) acl = posix1e.ACL() - for tag, owner_pair, perms in entry_list: + for typechar, owner_pair, perms in entry_list: id = None if owner_pair: if map_names: - if tag == posix1e.ACL_USER: id = map_id_name(owner_pair, 0) + if typechar == "u": id = map_id_name(owner_pair, 0) else: - assert tag == posix1e.ACL_GROUP, (tag, owner_pair, perms) + assert typechar == "g", (typechar, owner_pair, perms) id = map_id_name(owner_pair, 1) if id is None: warn_drop(owner_pair[1]) continue else: - assert owner_pair[0] is not None, (tag, owner_pair, perms) + assert owner_pair[0] is not None, (typechar, owner_pair, perms) id = owner_pair[0] entry = posix1e.Entry(acl) - entry.tag_type = tag + 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 diff --git a/rdiff-backup/testing/eas_aclstest.py b/rdiff-backup/testing/eas_aclstest.py index 2d6a2b6..a595cfe 100644 --- a/rdiff-backup/testing/eas_aclstest.py +++ b/rdiff-backup/testing/eas_aclstest.py @@ -245,6 +245,7 @@ other::---""") new_acl = AccessControlLists(()) tempdir.chmod(0700) new_acl.read_from_rp(tempdir) + print "@", new_acl assert new_acl.is_basic(), str(new_acl) assert not new_acl == self.sample_acl assert new_acl != self.sample_acl @@ -449,8 +450,8 @@ other::---""") def get_perms_of_user(acl, user): """Return the permissions of ACL_USER in acl, or None""" - for type, owner_pair, perms in acl.entry_list: - if type == posix1e.ACL_USER and owner_pair[1] == user: + for typechar, owner_pair, perms in acl.entry_list: + if typechar == "u" and owner_pair[1] == user: return perms return None -- cgit v1.2.1