The branch, master has been updated via 81a754f lib/replace: Relicence xattr.c to LGPLv3 via 2716b0a build: Always attempt to build posix ACLs via e9d797e lib/replace: Merge remaining xattr test details from lib/util via f9b7cd5 s4-xattr: Use libreplace xattr functions directly via c290cdb lib/replace: xattr wrappers in lib/replace rather than source3/lib/system.c via 664af06 lib/replace: We cannot use strchr_m in lib/replace via 954da1b lib/replace: DEBUG is not acceptable here, as this may not be linked into Samba via b347067 lib/replace: Copy lib/system.c xattr wrappers to lib/replace from 97a4901 s3: Same fix as 8576256, this time for fgetxattr
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master - Log ----------------------------------------------------------------- commit 81a754fb6462bc9f6b4be6bc1ee04a85a85e1686 Author: Andrew Bartlett <abart...@samba.org> Date: Sat Jun 2 09:28:04 2012 +1000 lib/replace: Relicence xattr.c to LGPLv3 By the kind consent of the copyright holders. (There wasn't any code from tridge in the code brought in from source3/lib/system.c). Andrew Bartlett Autobuild-User: Andrew Bartlett <abart...@samba.org> Autobuild-Date: Sat Jun 2 04:00:42 CEST 2012 on sn-devel-104 commit 2716b0a3f3037a5b8ac95b586158ed849c3418c3 Author: Andrew Bartlett <abart...@samba.org> Date: Fri Jun 1 15:24:20 2012 +1000 build: Always attempt to build posix ACLs These are on more systems than just linux. If the configure test passes then assume it is available. Andrew Bartlett commit e9d797e153ae95561dbb10b56a41281b2472f137 Author: Andrew Bartlett <abart...@samba.org> Date: Fri Jun 1 15:01:09 2012 +1000 lib/replace: Merge remaining xattr test details from lib/util I prefer the longer XATTR_ADDITIONAL_OPTIONS define and the NULL rather than 0 values in the getxattr test. Andrew Bartlett commit f9b7cd53b9fe253b122cb545c2dd1be073ab0592 Author: Andrew Bartlett <abart...@samba.org> Date: Fri Jun 1 13:41:46 2012 +1000 s4-xattr: Use libreplace xattr functions directly commit c290cdb9349220ba70b54143e1432da0230e2cee Author: Andrew Bartlett <abart...@samba.org> Date: Fri Jun 1 13:29:38 2012 +1000 lib/replace: xattr wrappers in lib/replace rather than source3/lib/system.c This also moves all the still-used configure tests etc. The unused OSF API is also removed at this time. Andrew Bartlett commit 664af060ac9ea83b565fbb817bb63d67d83843ef Author: Andrew Bartlett <abart...@samba.org> Date: Fri Jun 1 14:07:42 2012 +1000 lib/replace: We cannot use strchr_m in lib/replace In any case, it is always safe to search for . even in a multibyte string. Andrew Bartlett commit 954da1b81ec1a4ef9b417885e3a587b9c49b7056 Author: Andrew Bartlett <abart...@samba.org> Date: Fri Jun 1 14:05:10 2012 +1000 lib/replace: DEBUG is not acceptable here, as this may not be linked into Samba commit b347067a67b791fa83c1cfa5b33a5de1a3045170 Author: Andrew Bartlett <abart...@samba.org> Date: Fri Jun 1 14:14:45 2012 +1000 lib/replace: Copy lib/system.c xattr wrappers to lib/replace ----------------------------------------------------------------------- Summary of changes: lib/replace/libreplace.m4 | 47 ++ lib/replace/replace.h | 40 ++ lib/replace/system/filesys.h | 56 +++ lib/replace/wscript | 38 ++- lib/replace/xattr.c | 699 +++++++++++++++++++++++++++ lib/util/wrap_xattr.c | 120 ----- lib/util/wrap_xattr.h | 33 -- lib/util/wscript_build | 9 - lib/util/wscript_configure | 13 - source3/configure.in | 59 --- source3/include/includes.h | 23 - source3/lib/system.c | 678 -------------------------- source3/modules/vfs_default.c | 16 +- source3/wscript | 44 +-- source4/ntvfs/posix/python/pyposix_eadb.c | 1 - source4/ntvfs/posix/python/pyxattr_native.c | 8 +- source4/ntvfs/posix/python/pyxattr_tdb.c | 1 - source4/ntvfs/posix/wscript_build | 4 +- source4/ntvfs/posix/xattr_system.c | 13 +- 19 files changed, 913 insertions(+), 989 deletions(-) create mode 100644 lib/replace/xattr.c delete mode 100644 lib/util/wrap_xattr.c delete mode 100644 lib/util/wrap_xattr.h Changeset truncated at 500 lines: diff --git a/lib/replace/libreplace.m4 b/lib/replace/libreplace.m4 index 7335c98..641d25b 100644 --- a/lib/replace/libreplace.m4 +++ b/lib/replace/libreplace.m4 @@ -144,6 +144,53 @@ AC_CHECK_FUNCS(clock_gettime,libreplace_cv_have_clock_gettime=yes,[ libreplace_cv_have_clock_gettime=yes AC_DEFINE(HAVE_CLOCK_GETTIME, 1, Define to 1 if there is support for clock_gettime)]) ]) + +AC_CHECK_HEADERS(sys/attributes.h attr/xattr.h sys/xattr.h sys/extattr.h sys/uio.h) +AC_CHECK_HEADERS(sys/ea.h sys/proplist.h) + +############################################ +# Check for EA implementations +case "$host_os" in + *freebsd4* | *dragonfly* ) + AC_DEFINE(BROKEN_EXTATTR, 1, [Does extattr API work]) + ;; + *) + AC_SEARCH_LIBS(getxattr, [attr]) + AC_CHECK_FUNCS(attr_get attr_getf attr_list attr_listf attropen attr_remove) + AC_CHECK_FUNCS(attr_removef attr_set attr_setf extattr_delete_fd extattr_delete_file) + AC_CHECK_FUNCS(extattr_get_fd extattr_get_file extattr_list_fd extattr_list_file) + AC_CHECK_FUNCS(extattr_set_fd extattr_set_file fgetea fgetxattr flistea flistxattr) + AC_CHECK_FUNCS(fremoveea fremovexattr fsetea fsetxattr getea getxattr listea) + AC_CHECK_FUNCS(listxattr removeea removexattr setea setxattr) + + ;; +esac + + +######################################################## +# Do xattr functions take additional options like on Darwin? +if test x"$ac_cv_func_getxattr" = x"yes" ; then + AC_CACHE_CHECK([whether xattr interface takes additional options], smb_attr_cv_xattr_add_opt, [ + old_LIBS=$LIBS + LIBS="$LIBS $ACL_LIBS" + AC_TRY_COMPILE([ + #include <sys/types.h> + #if HAVE_ATTR_XATTR_H + #include <attr/xattr.h> + #elif HAVE_SYS_XATTR_H + #include <sys/xattr.h> + #endif + ],[ + getxattr(NULL, NULL, NULL, 0, 0, 0); + ], + [smb_attr_cv_xattr_add_opt=yes], + [smb_attr_cv_xattr_add_opt=no;LIBS=$old_LIBS]) + ]) + if test x"$smb_attr_cv_xattr_add_opt" = x"yes"; then + AC_DEFINE(XATTR_ADDITIONAL_OPTIONS, 1, [xattr functions have additional options]) + fi +fi + AC_CHECK_FUNCS(get_current_dir_name) AC_HAVE_DECL(setresuid, [#include <unistd.h>]) AC_HAVE_DECL(setresgid, [#include <unistd.h>]) diff --git a/lib/replace/replace.h b/lib/replace/replace.h index 776da8a..218303f 100644 --- a/lib/replace/replace.h +++ b/lib/replace/replace.h @@ -543,6 +543,46 @@ ssize_t rep_pwrite(int __fd, const void *__buf, size_t __nbytes, off_t __offset) /* prototype is in "system/network.h" */ #endif +#if !defined(HAVE_GETXATTR) || defined(XATTR_ADDITIONAL_OPTIONS) +#define getxattr rep_getxattr +/* prototype is in "system/filesys.h" */ +#endif + +#if !defined(HAVE_FGETXATTR) || defined(XATTR_ADDITIONAL_OPTIONS) +#define fgetxattr rep_fgetxattr +/* prototype is in "system/filesys.h" */ +#endif + +#if !defined(HAVE_LISTXATTR) || defined(XATTR_ADDITIONAL_OPTIONS) +#define listxattr rep_listxattr +/* prototype is in "system/filesys.h" */ +#endif + +#if !defined(HAVE_FLISTXATTR) || defined(XATTR_ADDITIONAL_OPTIONS) +#define flistxattr rep_flistxattr +/* prototype is in "system/filesys.h" */ +#endif + +#if !defined(HAVE_REMOVEXATTR) || defined(XATTR_ADDITIONAL_OPTIONS) +#define removexattr rep_removexattr +/* prototype is in "system/filesys.h" */ +#endif + +#if !defined(HAVE_FREMOVEXATTR) || defined(XATTR_ADDITIONAL_OPTIONS) +#define fremovexattr rep_fremovexattr +/* prototype is in "system/filesys.h" */ +#endif + +#if !defined(HAVE_SETXATTR) || defined(XATTR_ADDITIONAL_OPTIONS) +#define setxattr rep_setxattr +/* prototype is in "system/filesys.h" */ +#endif + +#if !defined(HAVE_FSETXATTR) || defined(XATTR_ADDITIONAL_OPTIONS) +#define fsetxattr rep_fsetxattr +/* prototype is in "system/filesys.h" */ +#endif + #ifndef HAVE_GET_CURRENT_DIR_NAME #define get_current_dir_name rep_get_current_dir_name char *rep_get_current_dir_name(void); diff --git a/lib/replace/system/filesys.h b/lib/replace/system/filesys.h index 2393068..a72a59a 100644 --- a/lib/replace/system/filesys.h +++ b/lib/replace/system/filesys.h @@ -123,11 +123,26 @@ #include <sys/xattr.h> #endif +#ifdef HAVE_SYS_EA_H +#include <sys/ea.h> +#endif + +#ifdef HAVE_SYS_EXTATTR_H +#include <sys/extattr.h> +#endif #ifdef HAVE_SYS_RESOURCE_H #include <sys/resource.h> #endif +#ifndef XATTR_CREATE +#define XATTR_CREATE 0x1 /* set value, fail if attr already exists */ +#endif + +#ifndef XATTR_REPLACE +#define XATTR_REPLACE 0x2 /* set value, fail if attr does not exist */ +#endif + /* Some POSIX definitions for those without */ #ifndef S_IFDIR @@ -208,4 +223,45 @@ #define ENOATTR ENODATA #endif + +#if !defined(HAVE_GETXATTR) || defined(XATTR_ADDITIONAL_OPTIONS) +ssize_t rep_getxattr (const char *path, const char *name, void *value, size_t size); +/* define is in "replace.h" */ +#endif + +#if !defined(HAVE_FGETXATTR) || defined(XATTR_ADDITIONAL_OPTIONS) +ssize_t rep_fgetxattr (int filedes, const char *name, void *value, size_t size); +/* define is in "replace.h" */ +#endif + +#if !defined(HAVE_LISTXATTR) || defined(XATTR_ADDITIONAL_OPTIONS) +ssize_t rep_listxattr (const char *path, char *list, size_t size); +/* define is in "replace.h" */ +#endif + +#if !defined(HAVE_FLISTXATTR) || defined(XATTR_ADDITIONAL_OPTIONS) +ssize_t rep_flistxattr (int filedes, char *list, size_t size); +/* define is in "replace.h" */ +#endif + +#if !defined(HAVE_REMOVEXATTR) || defined(XATTR_ADDITIONAL_OPTIONS) +int rep_removexattr (const char *path, const char *name); +/* define is in "replace.h" */ +#endif + +#if !defined(HAVE_FREMOVEXATTR) || defined(XATTR_ADDITIONAL_OPTIONS) +int rep_fremovexattr (int filedes, const char *name); +/* define is in "replace.h" */ +#endif + +#if !defined(HAVE_SETXATTR) || defined(XATTR_ADDITIONAL_OPTIONS) +int rep_setxattr (const char *path, const char *name, const void *value, size_t size, int flags); +/* define is in "replace.h" */ +#endif + +#if !defined(HAVE_FSETXATTR) || defined(XATTR_ADDITIONAL_OPTIONS) +int rep_fsetxattr (int filedes, const char *name, const void *value, size_t size, int flags); +/* define is in "replace.h" */ +#endif + #endif diff --git a/lib/replace/wscript b/lib/replace/wscript index d7b0634..6331b88 100644 --- a/lib/replace/wscript +++ b/lib/replace/wscript @@ -211,6 +211,40 @@ def configure(conf): conf.CHECK_FUNCS('getgrent_r getgrgid_r getgrnam_r getgrouplist getpagesize') conf.CHECK_FUNCS('getpwent_r getpwnam_r getpwuid_r epoll_create') + conf.SET_TARGET_TYPE('attr', 'EMPTY') + + xattr_headers='sys/attributes.h attr/xattr.h sys/xattr.h' + + conf.CHECK_FUNCS_IN(''' +fgetxattr flistea flistxattr +fremovexattr fsetxattr getxattr +listxattr removexattr setxattr +''', 'attr', checklibc=True, headers=xattr_headers) + + # We need to check for linux xattrs first, as we do not wish to link to -lattr + # (the XFS compat API) on Linux systems with the native xattr API + if not conf.CONFIG_SET('HAVE_GETXATTR'): + conf.CHECK_FUNCS_IN(''' +attr_get attr_getf attr_list attr_listf attropen attr_remove +attr_removef attr_set attr_setf extattr_delete_fd extattr_delete_file +extattr_get_fd extattr_get_file extattr_list_fd extattr_list_file +extattr_set_fd extattr_set_file fgetea flistea +fremoveea fsetea getea listea +removeea setea +''', 'attr', checklibc=True, headers=xattr_headers) + + if (conf.CONFIG_SET('HAVE_ATTR_LISTF') or + conf.CONFIG_SET('HAVE_EXTATTR_LIST_FD') or + conf.CONFIG_SET('HAVE_FLISTEA') or + conf.CONFIG_SET('HAVE_FLISTXATTR')): + conf.DEFINE('HAVE_XATTR_SUPPORT', 1) + + # Darwin has extra options to xattr-family functions + conf.CHECK_CODE('getxattr(NULL, NULL, NULL, 0, 0, 0)', + headers=xattr_headers, local_include=False, + define='XATTR_ADDITIONAL_OPTIONS', + msg="Checking whether xattr interface takes additional options") + conf.CHECK_FUNCS_IN('dlopen dlsym dlerror dlclose', 'dl', checklibc=True, headers='dlfcn.h dl.h') @@ -474,6 +508,8 @@ def build(bld): if not bld.CONFIG_SET('HAVE_INET_ATON'): REPLACE_SOURCE += ' inet_aton.c' if not bld.CONFIG_SET('HAVE_INET_NTOP'): REPLACE_SOURCE += ' inet_ntop.c' if not bld.CONFIG_SET('HAVE_INET_PTON'): REPLACE_SOURCE += ' inet_pton.c' + if not bld.CONFIG_SET('HAVE_GETXATTR') or bld.CONFIG_SET('XATTR_ADD_OPT'): + REPLACE_SOURCE += ' xattr.c' bld.SAMBA_LIBRARY('replace', source=REPLACE_SOURCE, @@ -484,7 +520,7 @@ def build(bld): # at the moment: # hide_symbols=bld.BUILTIN_LIBRARY('replace'), private_library=True, - deps='crypt dl nsl socket rt' + extra_libs) + deps='crypt dl nsl socket rt attr' + extra_libs) bld.SAMBA_SUBSYSTEM('replace-test', source='''test/testsuite.c test/strptime.c diff --git a/lib/replace/xattr.c b/lib/replace/xattr.c new file mode 100644 index 0000000..95bea77 --- /dev/null +++ b/lib/replace/xattr.c @@ -0,0 +1,699 @@ +/* + Unix SMB/CIFS implementation. + replacement routines for xattr implementations + Copyright (C) Jeremy Allison 1998-2005 + Copyright (C) Timur Bakeyev 2005 + Copyright (C) Bjoern Jacke 2006-2007 + + ** NOTE! The following LGPL license applies to the replace + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see <http://www.gnu.org/licenses/>. +*/ + +#include "replace.h" +#include "system/filesys.h" + +/******** Solaris EA helper function prototypes ********/ +#ifdef HAVE_ATTROPEN +#define SOLARIS_ATTRMODE S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP +static int solaris_write_xattr(int attrfd, const char *value, size_t size); +static ssize_t solaris_read_xattr(int attrfd, void *value, size_t size); +static ssize_t solaris_list_xattr(int attrdirfd, char *list, size_t size); +static int solaris_unlinkat(int attrdirfd, const char *name); +static int solaris_attropen(const char *path, const char *attrpath, int oflag, mode_t mode); +static int solaris_openat(int fildes, const char *path, int oflag, mode_t mode); +#endif + +/************************************************************************** + Wrappers for extented attribute calls. Based on the Linux package with + support for IRIX and (Net|Free)BSD also. Expand as other systems have them. +****************************************************************************/ + +ssize_t rep_getxattr (const char *path, const char *name, void *value, size_t size) +{ +#if defined(HAVE_GETXATTR) +#ifndef XATTR_ADDITIONAL_OPTIONS + return getxattr(path, name, value, size); +#else + int options = 0; + return getxattr(path, name, value, size, 0, options); +#endif +#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; + /* + * The BSD implementation has a nasty habit of silently truncating + * the returned value to the size of the buffer, so we have to check + * that the buffer is large enough to fit the returned value. + */ + if((retval=extattr_get_file(path, attrnamespace, attrname, NULL, 0)) >= 0) { + if(retval > size) { + errno = ERANGE; + return -1; + } + if((retval=extattr_get_file(path, attrnamespace, attrname, value, size)) >= 0) + return retval; + } + + return -1; +#elif defined(HAVE_ATTR_GET) + int retval, flags = 0; + int valuelength = (int)size; + char *attrname = strchr(name,'.') + 1; + + if (strncmp(name, "system", 6) == 0) flags |= ATTR_ROOT; + + retval = attr_get(path, attrname, (char *)value, &valuelength, flags); + + return retval ? retval : valuelength; +#elif defined(HAVE_ATTROPEN) + ssize_t ret = -1; + int attrfd = solaris_attropen(path, name, O_RDONLY, 0); + if (attrfd >= 0) { + ret = solaris_read_xattr(attrfd, value, size); + close(attrfd); + } + return ret; +#else + errno = ENOSYS; + return -1; +#endif +} + +ssize_t rep_fgetxattr (int filedes, const char *name, void *value, size_t size) +{ +#if defined(HAVE_FGETXATTR) +#ifndef XATTR_ADDITIONAL_OPTIONS + return fgetxattr(filedes, name, value, size); +#else + int options = 0; + return fgetxattr(filedes, name, value, size, 0, options); +#endif +#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; + + if((retval=extattr_get_fd(filedes, attrnamespace, attrname, NULL, 0)) >= 0) { + if(retval > size) { + errno = ERANGE; + return -1; + } + if((retval=extattr_get_fd(filedes, attrnamespace, attrname, value, size)) >= 0) + return retval; + } + + return -1; +#elif defined(HAVE_ATTR_GETF) + int retval, flags = 0; + int valuelength = (int)size; + char *attrname = strchr(name,'.') + 1; + + if (strncmp(name, "system", 6) == 0) flags |= ATTR_ROOT; + + retval = attr_getf(filedes, attrname, (char *)value, &valuelength, flags); + + return retval ? retval : valuelength; +#elif defined(HAVE_ATTROPEN) + ssize_t ret = -1; + int attrfd = solaris_openat(filedes, name, O_RDONLY|O_XATTR, 0); + if (attrfd >= 0) { + ret = solaris_read_xattr(attrfd, value, size); + close(attrfd); + } + return ret; +#else + errno = ENOSYS; + return -1; +#endif +} + +#if defined(HAVE_EXTATTR_LIST_FILE) + +#define EXTATTR_PREFIX(s) (s), (sizeof((s))-1) + +static struct { + int space; + const char *name; + size_t len; +} +extattr[] = { + { EXTATTR_NAMESPACE_SYSTEM, EXTATTR_PREFIX("system.") }, + { EXTATTR_NAMESPACE_USER, EXTATTR_PREFIX("user.") }, +}; + +typedef union { + const char *path; + int filedes; +} extattr_arg; + +static ssize_t bsd_attr_list (int type, extattr_arg arg, char *list, size_t size) +{ + ssize_t list_size, total_size = 0; + int i, t, len; + char *buf; + /* Iterate through extattr(2) namespaces */ + for(t = 0; t < ARRAY_SIZE(extattr); t++) { + switch(type) { +#if defined(HAVE_EXTATTR_LIST_FILE) + case 0: + list_size = extattr_list_file(arg.path, extattr[t].space, list, size); + break; +#endif +#if defined(HAVE_EXTATTR_LIST_LINK) + case 1: + list_size = extattr_list_link(arg.path, extattr[t].space, list, size); + break; +#endif +#if defined(HAVE_EXTATTR_LIST_FD) + case 2: + list_size = extattr_list_fd(arg.filedes, extattr[t].space, list, size); + break; +#endif + default: + errno = ENOSYS; + return -1; + } + /* Some error happend. Errno should be set by the previous call */ + if(list_size < 0) + return -1; + /* No attributes */ + if(list_size == 0) + continue; + /* XXX: Call with an empty buffer may be used to calculate + necessary buffer size. Unfortunately, we can't say, how + many attributes were returned, so here is the potential + problem with the emulation. + */ + if(list == NULL) { + /* Take the worse case of one char attribute names - + two bytes per name plus one more for sanity. + */ + total_size += list_size + (list_size/2 + 1)*extattr[t].len; + continue; + } + /* Count necessary offset to fit namespace prefixes */ + len = 0; + for(i = 0; i < list_size; i += list[i] + 1) + len += extattr[t].len; + + total_size += list_size + len; + /* Buffer is too small to fit the results */ + if(total_size > size) { + errno = ERANGE; + return -1; + } + /* Shift results back, so we can prepend prefixes */ + buf = (char *)memmove(list + len, list, list_size); + + for(i = 0; i < list_size; i += len + 1) { + len = buf[i]; + strncpy(list, extattr[t].name, extattr[t].len + 1); + list += extattr[t].len; + strncpy(list, buf + i + 1, len); + list[len] = '\0'; + list += len + 1; + } + size -= total_size; + } + return total_size; +} + +#endif + -- Samba Shared Repository