rdiff-backup-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Rdiff-backup-commits] rdiff-backup CHANGELOG rdiff_backup/fs_abilitie..


From: Andrew Ferguson
Subject: [Rdiff-backup-commits] rdiff-backup CHANGELOG rdiff_backup/fs_abilitie...
Date: Thu, 02 Oct 2008 03:46:02 +0000

CVSROOT:        /sources/rdiff-backup
Module name:    rdiff-backup
Changes by:     Andrew Ferguson <owsla> 08/10/02 03:46:02

Modified files:
        .              : CHANGELOG 
        rdiff_backup   : fs_abilities.py win_acls.py 

Log message:
        Add error handling and logging to Windows ACL support; fixes Windows 
backup to
        SMB share. Improve test in fs_abilities to determine if Windows ACLs are
        supported.

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/rdiff-backup/CHANGELOG?cvsroot=rdiff-backup&r1=1.307&r2=1.308
http://cvs.savannah.gnu.org/viewcvs/rdiff-backup/rdiff_backup/fs_abilities.py?cvsroot=rdiff-backup&r1=1.52&r2=1.53
http://cvs.savannah.gnu.org/viewcvs/rdiff-backup/rdiff_backup/win_acls.py?cvsroot=rdiff-backup&r1=1.2&r2=1.3

Patches:
Index: CHANGELOG
===================================================================
RCS file: /sources/rdiff-backup/rdiff-backup/CHANGELOG,v
retrieving revision 1.307
retrieving revision 1.308
diff -u -b -r1.307 -r1.308
--- CHANGELOG   2 Oct 2008 00:29:02 -0000       1.307
+++ CHANGELOG   2 Oct 2008 03:46:01 -0000       1.308
@@ -1,6 +1,10 @@
 New in v1.2.2 (????/??/??)
 ---------------------------
 
+Add error handling and logging to Windows ACL support; fixes Windows backup to
+SMB share. Improve test in fs_abilities to determine if Windows ACLs are
+supported. (Andrew Ferguson)
+
 Add a warning message if extended attributes support is broken by the
 filesystem (such as with older EncFS versions). (Andrew Ferguson)
 

Index: rdiff_backup/fs_abilities.py
===================================================================
RCS file: /sources/rdiff-backup/rdiff-backup/rdiff_backup/fs_abilities.py,v
retrieving revision 1.52
retrieving revision 1.53
diff -u -b -r1.52 -r1.53
--- rdiff_backup/fs_abilities.py        2 Oct 2008 00:29:02 -0000       1.52
+++ rdiff_backup/fs_abilities.py        2 Oct 2008 03:46:02 -0000       1.53
@@ -122,7 +122,7 @@
                self.read_only = 1
                self.set_eas(rp, 0)
                self.set_acls(rp)
-               self.set_win_acls(rp)
+               self.set_win_acls(rp, 0)
                self.set_resource_fork_readonly(rp)
                self.set_carbonfile()
                self.set_case_sensitive_readonly(rp)
@@ -154,7 +154,7 @@
                self.set_fsync_dirs(subdir)
                self.set_eas(subdir, 1)
                self.set_acls(subdir)
-               self.set_win_acls(subdir)
+               self.set_win_acls(subdir, 1)
                self.set_dir_inc_perms(subdir)
                self.set_resource_fork_readwrite(subdir)
                self.set_carbonfile()
@@ -368,27 +368,53 @@
                        self.eas = 0
                except AssertionError:
                        log.Log("Extended attributes support is broken on 
filesystem at "
-                                       "%s. Please upgrade the filesystem 
driver, contact the "
-                                       "developers, or use the --no-eas option 
to disable "
-                                       "extended attributes support and 
suppress this message."
+                                       "%s.\nPlease upgrade the filesystem 
driver, contact the "
+                                       "developers,\nor use the --no-eas 
option to disable "
+                                       "extended attributes\nsupport and 
suppress this message."
                                        % (rp.path,), 1)
                        self.eas = 0
                else: self.eas = 1
 
-       def set_win_acls(self, dir_rp):
+       def set_win_acls(self, dir_rp, write):
                """Test if windows access control lists are supported"""
+               assert Globals.local_connection is dir_rp.conn
+               assert dir_rp.lstat()
                try:
-                       import win32security
+                       import win32security, pywintypes
                except ImportError:
                        log.Log("Unable to import win32security module. Windows 
ACLs\n"
                                        "not supported by filesystem at %s" % 
dir_rp.path, 4)
                        self.win_acls = 0
                        return
                try:
+                       sd = win32security.GetNamedSecurityInfo(dir_rp.path,
+                                               win32security.SE_FILE_OBJECT,
+                                               
win32security.OWNER_SECURITY_INFORMATION | 
+                                               
win32security.GROUP_SECURITY_INFORMATION | 
+                                               
win32security.DACL_SECURITY_INFORMATION)
+                       acl = sd.GetSecurityDescriptorDacl()
+                       n = acl.GetAceCount()
+                       if write:
+                               win32security.SetNamedSecurityInfo(dir_rp.path,
+                                               win32security.SE_FILE_OBJECT,
+                                               
win32security.OWNER_SECURITY_INFORMATION | 
+                                               
win32security.GROUP_SECURITY_INFORMATION | 
+                                               
win32security.DACL_SECURITY_INFORMATION,
+                                               sd.GetSecurityDescriptorOwner(),
+                                               sd.GetSecurityDescriptorGroup(),
+                                               sd.GetSecurityDescriptorDacl(),
+                                               None)
+               except (OSError, AttributeError, pywintypes.error):
+                       log.Log("Unable to load a Windows ACL.\nWindows ACLs 
not supported "
+                                       "by filesystem at %s" % dir_rp.path, 4)
+                       self.win_acls = 0
+                       return
+               
+               try:
                        win_acls.init_acls()
-               except OSError:
-                       log.Log("Windows ACLs not supported by filesystem\n"
-                                       "at %s" % dir_rp.path, 4)
+               except (OSError, AttributeError, pywintypes.error):
+                       log.Log("Unable to init win_acls.\nWindows ACLs not 
supported by "
+                                       "filesystem at %s" % dir_rp.path, 4)
                        self.win_acls = 0
                        return
                self.win_acls = 1
@@ -414,7 +440,7 @@
                try:
                        import Carbon.File
                        import MacOS
-               except:
+               except (ImportError, AttributeError):
                        self.carbonfile = 0
                        return
 

Index: rdiff_backup/win_acls.py
===================================================================
RCS file: /sources/rdiff-backup/rdiff-backup/rdiff_backup/win_acls.py,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -b -r1.2 -r1.3
--- rdiff_backup/win_acls.py    30 Sep 2008 03:54:42 -0000      1.2
+++ rdiff_backup/win_acls.py    2 Oct 2008 03:46:02 -0000       1.3
@@ -17,11 +17,12 @@
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
 # USA
 
-import C, metadata, re, rorpiter, rpath
+import C, metadata, re, rorpiter, rpath, log
 
 try:
        from win32security import *
-except:
+       import pywintypes
+except ImportError:
        GROUP_SECURITY_INFORMATION = 0
        OWNER_SECURITY_INFORMATION = 0
        DACL_SECURITY_INFORMATION = 0
@@ -40,8 +41,11 @@
        def load_from_rp(self, rp, skip_inherit_only = True):
                self.index = rp.index
                try:
-                       sd = 
rp.conn.win32security.GetNamedSecurityInfo(rp.path, SE_FILE_OBJECT, ACL.flags)
-               except:
+                       sd = rp.conn.win32security. \
+                                       GetNamedSecurityInfo(rp.path, 
SE_FILE_OBJECT, ACL.flags)
+               except (OSError, IOError, pywintypes.error), exc:
+                       log.Log("Warning: unable to read ACL from %s: %s"
+                                       % (repr(rp.path), exc), 4)
                        return
 
                if skip_inherit_only:
@@ -71,17 +75,29 @@
 
                if not sd.GetSecurityDescriptorDacl():
                        sd.SetSecurityDescriptorDacl(0, None, 0)
-               if not sd.GetSecurityDescriptorSacl():
+               if (ACL.flags & SACL_SECURITY_INFORMATION) and not \
+                               sd.GetSecurityDescriptorSacl():
                        sd.SetSecurityDescriptorSacl(0, None, 0)
 
+               try:
                self.__acl = \
-                       
rp.conn.win32security.ConvertSecurityDescriptorToStringSecurityDescriptor(sd,
+                               rp.conn.win32security. \
+                                       
ConvertSecurityDescriptorToStringSecurityDescriptor(sd,
                                        SDDL_REVISION_1, ACL.flags)
+               except (OSError, IOError, pywintypes.error), exc:
+                       log.Log("Warning: unable to convert ACL from %s to 
string: %s"
+                                       % (repr(rp.path), exc), 4)
+                       self.__acl = ''
 
        def clear_rp(self, rp):
                # not sure how to interpret this
-               # I'll jus clear all acl-s from rp.path
-               sd = rp.conn.win32security.GetNamedSecurityInfo(rp.path, 
SE_FILE_OBJECT, ACL.flags)
+               # I'll just clear all acl-s from rp.path
+               try:
+                       sd = rp.conn.win32security. \
+                                       GetNamedSecurityInfo(rp.path, 
SE_FILE_OBJECT, ACL.flags)
+               except (OSError, IOError, pywintypes.error), exc:
+                       log.Log("Warning: unable to read ACL from %s for 
clearing: %s"
+                                       % (repr(rp.path), exc), 4)
 
                acl = sd.GetSecurityDescriptorDacl()
                if acl:
@@ -102,21 +118,36 @@
                                        acl.DeleteAce(n)
                                sd.SetSecurityDescriptorSacl(0, acl, 0)
 
-               rp.conn.win32security.SetNamedSecurityInfo(rp.path, 
SE_FILE_OBJECT, ACL.flags,
-                       sd.GetSecurityDescriptorOwner(), 
sd.GetSecurityDescriptorGroup(),
-                       sd.GetSecurityDescriptorDacl(), 
sd.GetSecurityDescriptorSacl())
+               try:
+                       rp.conn.win32security. \
+                               SetNamedSecurityInfo(rp.path, SE_FILE_OBJECT, 
ACL.flags,
+                               
sd.GetSecurityDescriptorOwner(),sd.GetSecurityDescriptorGroup(),
+                               sd.GetSecurityDescriptorDacl(),
+                               (ACL.flags & SACL_SECURITY_INFORMATION) and 
+                                       sd.GetSecurityDescriptorSacl() or None)
+               except (OSError, IOError, pywintypes.error), exc:
+                       log.Log("Warning: unable to set ACL on %s after 
clearing: %s"
+                                       % (repr(rp.path), exc), 4)
 
        def write_to_rp(self, rp):
-               if self.__acl:
-                       sd = 
rp.conn.win32security.ConvertStringSecurityDescriptorToSecurityDescriptor(self.__acl,
-                                               SDDL_REVISION_1)
+               if not self.__acl:
+                       return
 
-                       # Enable the next block of code for dirs after we have 
a mechanism in
+               try:
+                       sd = rp.conn.win32security. \
+                               
ConvertStringSecurityDescriptorToSecurityDescriptor(
+                                       self.__acl, SDDL_REVISION_1)
+               except (OSError, IOError, pywintypes.error), exc:
+                       log.Log("Warning: unable to convert string %s to ACL: 
%s"
+                               % (repr(self.__acl), exc), 4)
+
+               # Enable next block of code for dirs after we have a mechanism 
in
                        # backup.py (and similar) to do a first pass to see if 
a directory
                        # has SE_DACL_PROTECTED. In that case, we will need to
                        #               1) 
dest_rorp.write_win_acl(source_rorp.get_win_acl())
-                       #                               --> And clear the 
existing dest_rorp one while doing so
-                       #               2) Check if backup user has Admin privs 
to write to dest_rorp
+               #                               --> And clear existing 
dest_rorp one while doing so
+               #               2) Check if backup user has Admin privs to 
write dest_rorp
+               #                               --> May need to use Win32 
AccessCheck() API
                        #               3) If not, add Admin write privs to 
dest_rorp and add dir
                        #                               to 
dir_perms_list-equivalent
                        #               4) THEN, allow the pre_process() 
function to finish and the
@@ -131,13 +162,21 @@
                        # which we clear during step 6. We need to clear them 
*before* the
                        # children files/subdirs are created and generate the 
appropriate
                        # DACL so the inheritance magic can happen during step 
4.
+
                        (flags, revision) = sd.GetSecurityDescriptorControl()
                        if (not rp.isdir() and flags & SE_DACL_PROTECTED):
                                self.clear_rp(rp)
                        
-                       rp.conn.win32security.SetNamedSecurityInfo(rp.path, 
SE_FILE_OBJECT, ACL.flags,
-                               sd.GetSecurityDescriptorOwner(), 
sd.GetSecurityDescriptorGroup(),
-                               sd.GetSecurityDescriptorDacl(), 
sd.GetSecurityDescriptorSacl())
+               try:
+                       rp.conn.win32security. \
+                               SetNamedSecurityInfo(rp.path, SE_FILE_OBJECT, 
ACL.flags,
+                               
sd.GetSecurityDescriptorOwner(),sd.GetSecurityDescriptorGroup(),
+                               sd.GetSecurityDescriptorDacl(),
+                               (ACL.flags & SACL_SECURITY_INFORMATION) and 
+                                       sd.GetSecurityDescriptorSacl() or None)
+               except (OSError, IOError, pywintypes.error), exc:
+                       log.Log("Warning: unable to set ACL on %s: %s"
+                                       % (repr(rp.path), exc), 4)
 
        def __str__(self):
                return '# file: %s\n%s\n' % \
@@ -208,20 +247,24 @@
        import win32api
        try:
                hnd = OpenProcessToken(win32api.GetCurrentProcess(),
-                       TOKEN_ADJUST_PRIVILEGES| TOKEN_QUERY)
-       except win32api.error:
+                       TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY)
+       except win32api.error, exc:
+               log.Log("Warning: unable to open Windows process token: %s"
+                               % exc, 5)
                return
        try:
                try:
                        lpv = lambda priv: LookupPrivilegeValue(None, priv)
-                       # enable the SE_*_NAME priveleges
+                       # enable the SE_*_NAME privileges 
                        SecurityName = lpv(SE_SECURITY_NAME)
                        AdjustTokenPrivileges(hnd, False, [
                                (SecurityName, SE_PRIVILEGE_ENABLED),
                                (lpv(SE_BACKUP_NAME), SE_PRIVILEGE_ENABLED),
                                (lpv(SE_RESTORE_NAME), SE_PRIVILEGE_ENABLED)
                                ])
-               except win32api.error:
+               except win32api.error, exc:
+                       log.Log("Warning: unable to enable SE_*_NAME 
privileges: %s"
+                               % exc, 5)
                        return
                for name, enabled in GetTokenInformation(hnd, TokenPrivileges):
                        if name == SecurityName and enabled:
@@ -230,4 +273,3 @@
                                break
        finally:
                win32api.CloseHandle(hnd)
-




reply via email to

[Prev in Thread] Current Thread [Next in Thread]