From: Jelmer Vernooij Date: Sun, 26 Feb 2012 23:50:00 +0000 (+0100) Subject: samba.xattr: Split copying of tree with extended attributes out into separate module. X-Git-Tag: samba-4.0.0alpha19~732 X-Git-Url: http://git.samba.org/samba.git/?a=commitdiff_plain;h=f40c9ac7ac794c09dbeaa1bf1fdb0df980b74b63;p=samba.git samba.xattr: Split copying of tree with extended attributes out into separate module. --- diff --git a/source4/scripting/bin/upgradeprovision b/source4/scripting/bin/upgradeprovision index 2adb9a5b1ae..ba9e5e5c0ac 100755 --- a/source4/scripting/bin/upgradeprovision +++ b/source4/scripting/bin/upgradeprovision @@ -50,7 +50,7 @@ from samba.provision import (get_domain_descriptor, find_provision_key_parameter ProvisioningError, get_last_provision_usn, get_max_usn, update_provision_usn, setup_path) from samba.schema import get_linked_attributes, Schema, get_schema_descriptor -from samba.dcerpc import security, drsblobs, xattr +from samba.dcerpc import security, drsblobs from samba.ndr import ndr_unpack from samba.upgradehelpers import (dn_sort, get_paths, newprovision, get_ldbs, @@ -63,6 +63,7 @@ from samba.upgradehelpers import (dn_sort, get_paths, newprovision, search_constructed_attrs_stored, int64range2str, update_dns_account_password, increment_calculated_keyversion_number) +from samba.xattr import copytree_with_xattrs replace=2**FLAG_MOD_REPLACE add=2**FLAG_MOD_ADD @@ -1463,66 +1464,6 @@ def update_samdb(ref_samdb, samdb, names, provisionUSNs, schema, prereloadfunc): return 0 -def copyxattrs(dir, refdir): - """ Copy owner, groups, extended ACL and NT acls from - a reference dir to a destination dir - - Both dir are supposed to hold the same files - :param dir: Destination dir - :param refdir: Reference directory""" - - noxattr = 0 - for root, dirs, files in os.walk(dir, topdown=True): - for name in files: - subdir=root[len(dir):] - ref = os.path.join("%s%s" % (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: - noxattr = 1 - attribute = samba.xattr_native.wrap_getxattr(ref, - "system.posix_acl_access") - samba.xattr_native.wrap_setxattr(tgt, - "system.posix_acl_access", - attribute) - except Exception: - continue - for name in dirs: - subdir=root[len(dir):] - ref = os.path.join("%s%s" % (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: - noxattr = 1 - attribute = samba.xattr_native.wrap_getxattr(ref, - "system.posix_acl_access") - samba.xattr_native.wrap_setxattr(tgt, - "system.posix_acl_access", - attribute) - - except Exception: - continue - - def backup_provision(paths, dir): """This function backup the provision files so that a rollback is possible @@ -1530,9 +1471,7 @@ def backup_provision(paths, dir): :param paths: Paths to different objects :param dir: Directory where to store the backup """ - - shutil.copytree(paths.sysvol, os.path.join(dir, "sysvol")) - copyxattrs(os.path.join(dir, "sysvol"), paths.sysvol) + copytree_with_xattrs(paths.sysvol, os.path.join(dir, "sysvol")) shutil.copy2(paths.samdb, dir) shutil.copy2(paths.secrets, dir) shutil.copy2(paths.idmapdb, dir) @@ -1555,8 +1494,6 @@ def backup_provision(paths, dir): shutil.copytree(samldbdir, os.path.join(dir, "sam.ldb.d")) - - def sync_calculated_attributes(samdb, names): """Synchronize attributes used for constructed ones, with the old constructed that were stored in the database. diff --git a/source4/scripting/python/samba/xattr.py b/source4/scripting/python/samba/xattr.py new file mode 100644 index 00000000000..55ae0416759 --- /dev/null +++ b/source4/scripting/python/samba/xattr.py @@ -0,0 +1,94 @@ +#!/usr/bin/env python +# vim: expandtab +# +# Utility code for dealing with POSIX extended attributes +# +# Copyright (C) Matthieu Patou 2009 - 2010 +# Copyright (C) Jelmer Vernooij 2012 +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +from samba.dcerpc import xattr +import os +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 copyxattrs(dir, refdir): + """Copy extended attributes from a reference dir to a destination dir + + 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) + + except Exception: + continue