summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xsource4/scripting/bin/upgradeprovision2
-rw-r--r--source4/scripting/python/samba/tests/xattr.py25
-rw-r--r--source4/scripting/python/samba/xattr.py98
3 files changed, 59 insertions, 66 deletions
diff --git a/source4/scripting/bin/upgradeprovision b/source4/scripting/bin/upgradeprovision
index 8066ac38d4..7003717b4e 100755
--- a/source4/scripting/bin/upgradeprovision
+++ b/source4/scripting/bin/upgradeprovision
@@ -1471,7 +1471,7 @@ def backup_provision(paths, dir):
:param paths: Paths to different objects
:param dir: Directory where to store the backup
"""
- if paths.sysvol is not None:
+ if paths.sysvol:
copytree_with_xattrs(paths.sysvol, os.path.join(dir, "sysvol"))
shutil.copy2(paths.samdb, dir)
shutil.copy2(paths.secrets, dir)
diff --git a/source4/scripting/python/samba/tests/xattr.py b/source4/scripting/python/samba/tests/xattr.py
index 7b4627fdad..1f325322fa 100644
--- a/source4/scripting/python/samba/tests/xattr.py
+++ b/source4/scripting/python/samba/tests/xattr.py
@@ -20,10 +20,16 @@
"""Tests for samba.xattr_native and samba.xattr_tdb."""
import samba.xattr_native, samba.xattr_tdb
+from samba.xattr import copytree_with_xattrs
from samba.dcerpc import xattr
from samba.ndr import ndr_pack
-from samba.tests import TestCase, TestSkipped
+from samba.tests import (
+ TestCase,
+ TestCaseInTempDir,
+ TestSkipped,
+ )
import random
+import shutil
import os
class XattrTests(TestCase):
@@ -103,3 +109,20 @@ class XattrTests(TestCase):
finally:
os.unlink(tempf)
os.unlink(eadb_path)
+
+
+class TestCopyTreeWithXattrs(TestCaseInTempDir):
+
+ def test_simple(self):
+ os.chdir(self.tempdir)
+ os.mkdir("a")
+ os.mkdir("a/b")
+ os.mkdir("a/b/c")
+ f = open('a/b/c/d', 'w')
+ try:
+ f.write("foo")
+ finally:
+ f.close()
+ copytree_with_xattrs("a", "b")
+ shutil.rmtree("a")
+ shutil.rmtree("b")
diff --git a/source4/scripting/python/samba/xattr.py b/source4/scripting/python/samba/xattr.py
index 55ae041675..1c53ae810d 100644
--- a/source4/scripting/python/samba/xattr.py
+++ b/source4/scripting/python/samba/xattr.py
@@ -3,7 +3,6 @@
#
# Utility code for dealing with POSIX extended attributes
#
-# Copyright (C) Matthieu Patou <mat@matws.net> 2009 - 2010
# Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2012
#
# This program is free software; you can redistribute it and/or modify
@@ -25,70 +24,41 @@ import samba.xattr_native
import shutil
-def copytree_with_xattrs(source, target):
- """Copy a tree but preserve extended attributes.
-
- :param source: Source tree path
- :param target: Target path
- """
- shutil.copytree(source, target)
- copyxattrs(target, source)
+def copyattrs(frompath, topath):
+ """Copy ACL related attributes from a path to another path."""
+ for attr_name in (xattr.XATTR_NTACL_NAME, "system.posix_acl_access"):
+ # Get the xattr attributes if any
+ try:
+ attribute = samba.xattr_native.wrap_getxattr(frompath,
+ xattr.XATTR_NTACL_NAME)
+ samba.xattr_native.wrap_setxattr(topath,
+ xattr.XATTR_NTACL_NAME,
+ attribute)
+ except Exception:
+ pass
+ # FIXME:Catch a specific exception
-def copyxattrs(dir, refdir):
- """Copy extended attributes from a reference dir to a destination dir
+def copytree_with_xattrs(src, dst):
+ """Recursively copy a directory tree using shutil.copy2(), preserving xattrs.
- Both dir are supposed to hold the same files
- :param dir: Destination dir
- :param refdir: Reference directory"""
-
- for root, dirs, files in os.walk(dir, topdown=True):
- for name in files:
- subdir = root[len(dir):]
- ref = os.path.join(refdir, subdir, name)
- statsinfo = os.stat(ref)
- tgt = os.path.join(root, name)
- try:
- os.chown(tgt, statsinfo.st_uid, statsinfo.st_gid)
- # Get the xattr attributes if any
- try:
- attribute = samba.xattr_native.wrap_getxattr(ref,
- xattr.XATTR_NTACL_NAME)
- samba.xattr_native.wrap_setxattr(tgt,
- xattr.XATTR_NTACL_NAME,
- attribute)
- except Exception:
- pass
- # FIXME:Catch a specific exception
- attribute = samba.xattr_native.wrap_getxattr(ref,
- "system.posix_acl_access")
- samba.xattr_native.wrap_setxattr(tgt,
- "system.posix_acl_access",
- attribute)
- except Exception:
- # FIXME: Catch a specific exception
- continue
- for name in dirs:
- subdir = root[len(dir):]
- ref = os.path.join(refdir, subdir, name)
- statsinfo = os.stat(ref)
- tgt = os.path.join(root, name)
- try:
- os.chown(os.path.join(root, name), statsinfo.st_uid,
- statsinfo.st_gid)
- try:
- attribute = samba.xattr_native.wrap_getxattr(ref,
- xattr.XATTR_NTACL_NAME)
- samba.xattr_native.wrap_setxattr(tgt,
- xattr.XATTR_NTACL_NAME,
- attribute)
- except Exception:
- pass # FIXME: Catch a specific exception
- attribute = samba.xattr_native.wrap_getxattr(ref,
- "system.posix_acl_access")
- samba.xattr_native.wrap_setxattr(tgt,
- "system.posix_acl_access",
- attribute)
+ The destination directory must not already exist.
+ If exception(s) occur, an Error is raised with a list of reasons.
+ """
+ names = os.listdir(src)
- except Exception:
- continue
+ os.makedirs(dst)
+ errors = []
+ for name in names:
+ srcname = os.path.join(src, name)
+ dstname = os.path.join(dst, name)
+ if os.path.islink(srcname):
+ linkto = os.readlink(srcname)
+ os.symlink(linkto, dstname)
+ elif os.path.isdir(srcname):
+ copytree_with_xattrs(srcname, dstname)
+ else:
+ # Will raise a SpecialFileError for unsupported file types
+ shutil.copy2(srcname, dstname)
+ shutil.copystat(src, dst)
+ copyattrs(src, dst)