[SCM] Samba Shared Repository - branch master updated

Jeremy Allison jra at samba.org
Fri Feb 10 21:25:02 UTC 2017


The branch, master has been updated
       via  32116e0 s3/util: mvxattr, a tool to rename extended attributes
       via  738797d lib/replace: validate xattr namespace prefix on FreeBSD
       via  e4d1f83 vfs_fruit: cleanup metadata and resource xattr name defines
       via  7355760 vfs_fruit: correct Netatalk metadata xattr on FreeBSD
      from  34b0ee8 messaging_dgm: avoid GCC snprintf warnings in messaging_dgm_out_create

https://git.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit 32116e015b14cfa697569fce01daf8cde3285970
Author: Ralph Boehme <slow at samba.org>
Date:   Fri Feb 3 14:57:45 2017 +0100

    s3/util: mvxattr, a tool to rename extended attributes
    
    Usage: mvxattr -s STRING -d STRING PATH [PATH ...]
      -s, --from=STRING         xattr source name
      -d, --to=STRING           xattr destination name
      -l, --follow-symlinks     follow symlinks, the default is to ignore them
      -p, --print               print files where the xattr got renamed
      -v, --verbose             print files as they are checked
      -f, --force               force overwriting of destination xattr
    
    Help options:
      -?, --help            Show this help message
      --usage               Display brief usage message
    
    Bug: https://bugzilla.samba.org/show_bug.cgi?id=12490
    
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    
    Autobuild-User(master): Jeremy Allison <jra at samba.org>
    Autobuild-Date(master): Fri Feb 10 22:24:59 CET 2017 on sn-devel-144

commit 738797d8ad6908de457786cc948dcde151e2b9e1
Author: Ralph Boehme <slow at samba.org>
Date:   Fri Feb 3 18:08:12 2017 +0100

    lib/replace: validate xattr namespace prefix on FreeBSD
    
    We should validate the xattr name string ensuring it either begins with
    "sytem." or "user.". If it doesn't, we should fail the request with
    EINVAL.
    
    The FreeBSD xattr API uses namespaces but doesn't put the namespace name
    as a string prefix at the beginning of the xattr name. It gets passed as
    an additional int arg instead.
    
    On the other hand, our libreplace xattr API expects the caller to put a
    namespace prefix into the xattr name.
    
    Unfortunately the conversion and stripping of the namespace string prefix
    from the xattr name gives the following unexpected result on FreeBSD:
    
    rep_setxattr("foo.bar", ...) => xattr with name "bar"
    
    The code checks if the name begins with "system.", if it doesn't find
    it, it defaults to the user namespace and then does a strchr(name, '.')
    which skips *any* leading string before the first dot.
    
    Bug: https://bugzilla.samba.org/show_bug.cgi?id=12490
    
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit e4d1f8354f97ab9007e4c5f7d164937bdc5cd6f1
Author: Ralph Boehme <slow at samba.org>
Date:   Fri Feb 3 16:43:26 2017 +0100

    vfs_fruit: cleanup metadata and resource xattr name defines
    
    Just some cleanup, no change in behaviour. This also removes the hokey
    tag. :)
    
    Bug: https://bugzilla.samba.org/show_bug.cgi?id=12490
    
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 73557605fdf72221e3cbc218fc9782d163029a08
Author: Ralph Boehme <slow at samba.org>
Date:   Fri Feb 3 16:33:00 2017 +0100

    vfs_fruit: correct Netatalk metadata xattr on FreeBSD
    
    Bug: https://bugzilla.samba.org/show_bug.cgi?id=12490
    
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

-----------------------------------------------------------------------

Summary of changes:
 docs-xml/manpages/mvxattr.1.xml | 100 ++++++++++++++++++++++
 docs-xml/wscript_build          |   1 +
 lib/replace/xattr.c             | 105 ++++++++++++++++++------
 source3/modules/vfs_fruit.c     |  12 ++-
 source3/utils/mvxattr.c         | 178 ++++++++++++++++++++++++++++++++++++++++
 source3/utils/wscript_build     |   8 ++
 source3/wscript                 |   3 +
 7 files changed, 376 insertions(+), 31 deletions(-)
 create mode 100644 docs-xml/manpages/mvxattr.1.xml
 create mode 100644 source3/utils/mvxattr.c


Changeset truncated at 500 lines:

diff --git a/docs-xml/manpages/mvxattr.1.xml b/docs-xml/manpages/mvxattr.1.xml
new file mode 100644
index 0000000..034dc3a
--- /dev/null
+++ b/docs-xml/manpages/mvxattr.1.xml
@@ -0,0 +1,100 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!DOCTYPE refentry PUBLIC "-//Samba-Team//DTD DocBook V4.2-Based Variant V1.0//EN" "http://www.samba.org/samba/DTD/samba-doc">
+<refentry id="mvxattr.1">
+
+<refmeta>
+	<refentrytitle>mvxattr</refentrytitle>
+	<manvolnum>1</manvolnum>
+	<refmiscinfo class="source">Samba</refmiscinfo>
+	<refmiscinfo class="manual">User Commands</refmiscinfo>
+	<refmiscinfo class="version">4.7</refmiscinfo>
+</refmeta>
+
+
+<refnamediv>
+	<refname>mvxattr</refname>
+	<refpurpose>Recursively rename extended attributes</refpurpose>
+</refnamediv>
+
+<refsynopsisdiv>
+	<cmdsynopsis>
+		<command>mvxattr</command>
+		<arg choice="req">-s STRING, --from=STRING</arg>
+		<arg choice="req">-d STRING, --to=STRING</arg>
+		<arg choice="opt">-l, --follow-symlinks</arg>
+		<arg choice="opt">-p, --print</arg>
+		<arg choice="opt">-v, --verbose</arg>
+		<arg choice="opt">-f, --force</arg>
+		<arg choice="req">PATH [PATH ...]</arg>
+	</cmdsynopsis>
+</refsynopsisdiv>
+
+<refsect1>
+	<title>DESCRIPTION</title>
+
+	<para>This tool is part of the <citerefentry><refentrytitle>samba</refentrytitle>
+	<manvolnum>1</manvolnum></citerefentry> suite.</para>
+
+	<para>mvxattr is a simple utility to recursively rename extended
+	attributes.</para>
+
+	<para>By default all symlinks are ignored, use <option>-l</option> to
+	follow them.</para>
+</refsect1>
+
+<refsect1>
+	<title>OPTIONS</title>
+
+	<variablelist>
+	<varlistentry>
+		<term>-s STRING, --from=STRING</term>
+		<listitem><para>Source xattr name</para></listitem>
+	</varlistentry>
+
+	<varlistentry>
+		<term>-d STRING, --to=STRING</term>
+		<listitem><para>Destination xattr name</para></listitem>
+	</varlistentry>
+
+	<varlistentry>
+		<term>-l, --follow-symlinks</term>
+		<listitem><para>Follow symlinks, the default is to ignore
+		them.</para></listitem>
+	</varlistentry>
+
+	<varlistentry>
+		<term>-p, --print</term>
+		<listitem><para>Print files where the xattr got renamed.</para></listitem>
+	</varlistentry>
+
+	<varlistentry>
+		<term>-v, --verbose</term>
+		<listitem><para>Print files as they are checked.</para></listitem>
+	</varlistentry>
+
+	<varlistentry>
+		<term>-f, --force</term>
+		<listitem><para>Force overwriting of destination xattr.</para></listitem>
+	</varlistentry>
+	</variablelist>
+
+</refsect1>
+
+<refsect1>
+	<title>VERSION</title>
+
+	<para>This man page is correct for version 4 of the Samba suite.</para>
+</refsect1>
+
+<refsect1>
+	<title>AUTHOR</title>
+
+	<para>The original Samba software and related utilities were created by
+	Andrew Tridgell. Samba is now developed by the Samba Team as an Open
+	Source project similar to the way the Linux kernel is developed.</para>
+
+	<para>The mvxattr manpage was written by Ralph Boehme.</para>
+
+</refsect1>
+
+</refentry>
diff --git a/docs-xml/wscript_build b/docs-xml/wscript_build
index 2b3a180..0b690a8 100644
--- a/docs-xml/wscript_build
+++ b/docs-xml/wscript_build
@@ -18,6 +18,7 @@ manpages='''
          manpages/idmap_script.8
          manpages/idmap_tdb.8
          manpages/idmap_tdb2.8
+         manpages/mvxattr.1
          manpages/net.8
          manpages/nmbd.8
          manpages/nmblookup.1
diff --git a/lib/replace/xattr.c b/lib/replace/xattr.c
index ce52d1a..2479c21 100644
--- a/lib/replace/xattr.c
+++ b/lib/replace/xattr.c
@@ -61,11 +61,21 @@ ssize_t rep_getxattr (const char *path, const char *name, void *value, size_t si
 #elif defined(HAVE_GETEA)
 	return getea(path, name, value, size);
 #elif defined(HAVE_EXTATTR_GET_FILE)
-	char *s;
 	ssize_t retval;
-	int attrnamespace = (strncmp(name, "system", 6) == 0) ? 
-		EXTATTR_NAMESPACE_SYSTEM : EXTATTR_NAMESPACE_USER;
-	const char *attrname = ((s=strchr(name, '.')) == NULL) ? name : s + 1;
+	int attrnamespace;
+	const char *attrname;
+
+	if (strncmp(name, "system.", 7) == 0) {
+		attrnamespace = EXTATTR_NAMESPACE_SYSTEM;
+		attrname = name + 7;
+	} else if (strncmp(name, "user.", 5) == 0) {
+		attrnamespace = EXTATTR_NAMESPACE_USER;
+		attrname = name + 5;
+	} else {
+		errno = EINVAL;
+		return -1;
+	}
+
 	/*
 	 * The BSD implementation has a nasty habit of silently truncating
 	 * the returned value to the size of the buffer, so we have to check
@@ -125,11 +135,20 @@ ssize_t rep_fgetxattr (int filedes, const char *name, void *value, size_t size)
 #elif defined(HAVE_FGETEA)
 	return fgetea(filedes, name, value, size);
 #elif defined(HAVE_EXTATTR_GET_FD)
-	char *s;
 	ssize_t retval;
-	int attrnamespace = (strncmp(name, "system", 6) == 0) ? 
-		EXTATTR_NAMESPACE_SYSTEM : EXTATTR_NAMESPACE_USER;
-	const char *attrname = ((s=strchr(name, '.')) == NULL) ? name : s + 1;
+	int attrnamespace;
+	const char *attrname;
+
+	if (strncmp(name, "system.", 7) == 0) {
+		attrnamespace = EXTATTR_NAMESPACE_SYSTEM;
+		attrname = name + 7;
+	} else if (strncmp(name, "user.", 5) == 0) {
+		attrnamespace = EXTATTR_NAMESPACE_USER;
+		attrname = name + 5;
+	} else {
+		errno = EINVAL;
+		return -1;
+	}
 
 	if((retval=extattr_get_fd(filedes, attrnamespace, attrname, NULL, 0)) >= 0) {
 		if (size == 0) {
@@ -414,10 +433,19 @@ int rep_removexattr (const char *path, const char *name)
 #elif defined(HAVE_REMOVEEA)
 	return removeea(path, name);
 #elif defined(HAVE_EXTATTR_DELETE_FILE)
-	char *s;
-	int attrnamespace = (strncmp(name, "system", 6) == 0) ? 
-		EXTATTR_NAMESPACE_SYSTEM : EXTATTR_NAMESPACE_USER;
-	const char *attrname = ((s=strchr(name, '.')) == NULL) ? name : s + 1;
+	int attrnamespace;
+	const char *attrname;
+
+	if (strncmp(name, "system.", 7) == 0) {
+		attrnamespace = EXTATTR_NAMESPACE_SYSTEM;
+		attrname = name + 7;
+	} else if (strncmp(name, "user.", 5) == 0) {
+		attrnamespace = EXTATTR_NAMESPACE_USER;
+		attrname = name + 5;
+	} else {
+		errno = EINVAL;
+		return -1;
+	}
 
 	return extattr_delete_file(path, attrnamespace, attrname);
 #elif defined(HAVE_ATTR_REMOVE)
@@ -455,10 +483,19 @@ int rep_fremovexattr (int filedes, const char *name)
 #elif defined(HAVE_FREMOVEEA)
 	return fremoveea(filedes, name);
 #elif defined(HAVE_EXTATTR_DELETE_FD)
-	char *s;
-	int attrnamespace = (strncmp(name, "system", 6) == 0) ? 
-		EXTATTR_NAMESPACE_SYSTEM : EXTATTR_NAMESPACE_USER;
-	const char *attrname = ((s=strchr(name, '.')) == NULL) ? name : s + 1;
+	int attrnamespace;
+	const char *attrname;
+
+	if (strncmp(name, "system.", 7) == 0) {
+		attrnamespace = EXTATTR_NAMESPACE_SYSTEM;
+		attrname = name + 7;
+	} else if (strncmp(name, "user.", 5) == 0) {
+		attrnamespace = EXTATTR_NAMESPACE_USER;
+		attrname = name + 5;
+	} else {
+		errno = EINVAL;
+		return -1;
+	}
 
 	return extattr_delete_fd(filedes, attrnamespace, attrname);
 #elif defined(HAVE_ATTR_REMOVEF)
@@ -496,11 +533,21 @@ int rep_setxattr (const char *path, const char *name, const void *value, size_t
 #elif defined(HAVE_SETEA)
 	return setea(path, name, value, size, flags);
 #elif defined(HAVE_EXTATTR_SET_FILE)
-	char *s;
 	int retval = 0;
-	int attrnamespace = (strncmp(name, "system", 6) == 0) ? 
-		EXTATTR_NAMESPACE_SYSTEM : EXTATTR_NAMESPACE_USER;
-	const char *attrname = ((s=strchr(name, '.')) == NULL) ? name : s + 1;
+	int attrnamespace;
+	const char *attrname;
+
+	if (strncmp(name, "system.", 7) == 0) {
+		attrnamespace = EXTATTR_NAMESPACE_SYSTEM;
+		attrname = name + 7;
+	} else if (strncmp(name, "user.", 5) == 0) {
+		attrnamespace = EXTATTR_NAMESPACE_USER;
+		attrname = name + 5;
+	} else {
+		errno = EINVAL;
+		return -1;
+	}
+
 	if (flags) {
 		/* Check attribute existence */
 		retval = extattr_get_file(path, attrnamespace, attrname, NULL, 0);
@@ -563,11 +610,21 @@ int rep_fsetxattr (int filedes, const char *name, const void *value, size_t size
 #elif defined(HAVE_FSETEA)
 	return fsetea(filedes, name, value, size, flags);
 #elif defined(HAVE_EXTATTR_SET_FD)
-	char *s;
 	int retval = 0;
-	int attrnamespace = (strncmp(name, "system", 6) == 0) ? 
-		EXTATTR_NAMESPACE_SYSTEM : EXTATTR_NAMESPACE_USER;
-	const char *attrname = ((s=strchr(name, '.')) == NULL) ? name : s + 1;
+	int attrnamespace;
+	const char *attrname;
+
+	if (strncmp(name, "system.", 7) == 0) {
+		attrnamespace = EXTATTR_NAMESPACE_SYSTEM;
+		attrname = name + 7;
+	} else if (strncmp(name, "user.", 5) == 0) {
+		attrnamespace = EXTATTR_NAMESPACE_USER;
+		attrname = name + 5;
+	} else {
+		errno = EINVAL;
+		return -1;
+	}
+
 	if (flags) {
 		/* Check attribute existence */
 		retval = extattr_get_fd(filedes, attrnamespace, attrname, NULL, 0);
diff --git a/source3/modules/vfs_fruit.c b/source3/modules/vfs_fruit.c
index 3599dcb..4387447 100644
--- a/source3/modules/vfs_fruit.c
+++ b/source3/modules/vfs_fruit.c
@@ -100,17 +100,15 @@ static int vfs_fruit_debug_level = DBGC_VFS;
 #define FRUIT_PARAM_TYPE_NAME "fruit"
 #define ADOUBLE_NAME_PREFIX "._"
 
-/*
- * REVIEW:
- * This is hokey, but what else can we do?
- */
 #define NETATALK_META_XATTR "org.netatalk.Metadata"
-#if defined(HAVE_ATTROPEN) || defined(FREEBSD)
+#define NETATALK_RSRC_XATTR "org.netatalk.Metadata"
+
+#if defined(HAVE_ATTROPEN)
 #define AFPINFO_EA_NETATALK NETATALK_META_XATTR
-#define AFPRESOURCE_EA_NETATALK "org.netatalk.ResourceFork"
+#define AFPRESOURCE_EA_NETATALK NETATALK_RSRC_XATTR
 #else
 #define AFPINFO_EA_NETATALK "user." NETATALK_META_XATTR
-#define AFPRESOURCE_EA_NETATALK "user.org.netatalk.ResourceFork"
+#define AFPRESOURCE_EA_NETATALK "user." NETATALK_RSRC_XATTR
 #endif
 
 enum apple_fork {APPLE_FORK_DATA, APPLE_FORK_RSRC};
diff --git a/source3/utils/mvxattr.c b/source3/utils/mvxattr.c
new file mode 100644
index 0000000..9cc2ec0
--- /dev/null
+++ b/source3/utils/mvxattr.c
@@ -0,0 +1,178 @@
+/*
+   Unix SMB/CIFS implementation.
+   xattr renaming
+   Copyright (C) Ralph Boehme 2017
+
+   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 <http://www.gnu.org/licenses/>.
+*/
+
+#include "includes.h"
+#include "system/filesys.h"
+#include "popt_common.h"
+#include <ftw.h>
+
+static struct rename_xattr_state {
+	int follow_symlink;
+	int print;
+	int force;
+	int verbose;
+	char *xattr_from;
+	char *xattr_to;
+} state;
+
+static int rename_xattr(const char *path,
+			const struct stat *sb,
+			int typeflag,
+			struct FTW *ftwbuf)
+{
+	ssize_t len;
+	int ret;
+
+	if (typeflag == FTW_SL) {
+		d_printf("Ignoring symlink %s\n", path);
+		return 0;
+	}
+
+	if (state.verbose) {
+		d_printf("%s\n", path);
+	}
+
+	len = getxattr(path, state.xattr_from, NULL, 0);
+	if (len < 0) {
+		if (errno == ENOATTR) {
+			return 0;
+		}
+		d_printf("getxattr [%s] failed [%s]\n",
+			 path, strerror(errno));
+		return -1;
+	}
+
+	{
+		uint8_t buf[len];
+
+		len = getxattr(path, state.xattr_from, &buf[0], len);
+		if (len == -1) {
+			d_printf("getxattr [%s] failed [%s]\n",
+				 path, strerror(errno));
+			return -1;
+		}
+
+		ret = setxattr(path, state.xattr_to, &buf[0], len, XATTR_CREATE);
+		if (ret != 0) {
+			if (errno != EEXIST) {
+				d_printf("setxattr [%s] failed [%s]\n",
+					 path, strerror(errno));
+				return -1;
+			}
+			if (!state.force) {
+				d_printf("destination [%s:%s] exists, use -f to force\n",
+					 path, state.xattr_to);
+				return -1;
+			}
+			ret = setxattr(path, state.xattr_to, &buf[0], len, XATTR_REPLACE);
+			if (ret != 0) {
+				d_printf("setxattr [%s:%s] failed [%s]\n",
+					 path, state.xattr_to, strerror(errno));
+				return -1;
+			}
+		}
+
+		ret = removexattr(path, state.xattr_from);
+		if (ret != 0) {
+			d_printf("removexattr [%s:%s] failed [%s]\n",
+				 path, state.xattr_from, strerror(errno));
+			return -1;
+		}
+
+		if (state.print) {
+			d_printf("Renamed %s to %s on %s\n",
+				 state.xattr_from, state.xattr_to, path);
+		}
+	}
+
+	return 0;
+}
+
+int main(int argc, const char *argv[])
+{
+	int c;
+	const char *path = NULL;
+	poptContext pc;
+	struct poptOption long_options[] = {
+		POPT_AUTOHELP
+		{"from", 		's', POPT_ARG_STRING,	&state.xattr_from,	's', "xattr source name" },
+		{"to",			'd', POPT_ARG_STRING, 	&state.xattr_to, 	'd', "xattr destination name" },
+		{"follow-symlinks",	'l', POPT_ARG_NONE,	&state.follow_symlink,	'l', "follow symlinks, the default is to ignore them" },
+		{"print",		'p', POPT_ARG_NONE,	&state.print,		'p', "print files where the xattr got renamed" },
+		{"verbose",		'v', POPT_ARG_NONE,	&state.verbose,		'v', "print files as they are checked" },
+		{"force",		'f', POPT_ARG_NONE,	&state.force,		'f', "force overwriting of destination xattr" },
+		POPT_TABLEEND
+	};
+	TALLOC_CTX *frame = talloc_stackframe();
+	const char *s = NULL;
+	int ret = 0;
+
+	if (getuid() != 0) {
+		d_printf("%s only works as root!\n", argv[0]);
+		ret = 1;
+		goto done;
+	}
+
+	pc = poptGetContext(NULL, argc, argv, long_options, 0);
+	poptSetOtherOptionHelp(pc, "-s STRING -d STRING PATH [PATH ...]");
+
+	while ((c = poptGetNextOpt(pc)) != -1) {
+		switch (c) {
+		case 's':
+			s = poptGetOptArg(pc);
+			state.xattr_from = talloc_strdup(frame, s);
+			if (state.xattr_from == NULL) {
+				ret = 1;
+				goto done;
+			}
+			break;
+		case 'd':
+			s = poptGetOptArg(pc);
+			state.xattr_to = talloc_strdup(frame, s);
+			if (state.xattr_to == NULL) {
+				ret = 1;
+				goto done;
+			}
+			break;
+		}
+	}
+
+	if (state.xattr_from == NULL || state.xattr_to == NULL) {
+		poptPrintUsage(pc, stderr, 0);
+		ret = 1;
+		goto done;
+	}
+
+	if (poptPeekArg(pc) == NULL) {
+		poptPrintUsage(pc, stderr, 0);
+		ret = 1;
+		goto done;
+	}
+
+	while ((path = poptGetArg(pc)) != NULL) {
+		ret = nftw(path, rename_xattr, 256,
+			   state.follow_symlink ? 0 : FTW_PHYS);
+	}
+
+	poptFreeContext(pc);
+
+done:
+	TALLOC_FREE(frame);
+	return ret;
+}
diff --git a/source3/utils/wscript_build b/source3/utils/wscript_build
index 0b9356a..4295f85 100644
--- a/source3/utils/wscript_build
+++ b/source3/utils/wscript_build
@@ -249,3 +249,11 @@ bld.SAMBA3_BINARY('net',
                  trusts_util
                  IDMAP_AUTORID_TDB
                  ''')
+
+bld.SAMBA3_BINARY('mvxattr',
+                 source='mvxattr.c',
+                 deps='''
+                 talloc
+                 popt_samba3
+                 ''',
+                 enabled=bld.env.build_mvxattr)


-- 
Samba Shared Repository



More information about the samba-cvs mailing list