diff options
-rw-r--r-- | source4/build/m4/rewrite.m4 | 10 | ||||
-rw-r--r-- | source4/libcli/util/errormap.c | 7 | ||||
-rw-r--r-- | source4/librpc/config.m4 | 46 | ||||
-rw-r--r-- | source4/librpc/config.mk | 50 | ||||
-rw-r--r-- | source4/librpc/idl/xattr.idl | 35 | ||||
-rw-r--r-- | source4/librpc/ndr/ndr.c | 58 | ||||
-rw-r--r-- | source4/ntvfs/posix/config.m4 | 13 | ||||
-rw-r--r-- | source4/ntvfs/posix/config.mk | 9 | ||||
-rw-r--r-- | source4/ntvfs/posix/pvfs_fileinfo.c | 56 | ||||
-rw-r--r-- | source4/ntvfs/posix/pvfs_open.c | 14 | ||||
-rw-r--r-- | source4/ntvfs/posix/pvfs_resolve.c | 10 | ||||
-rw-r--r-- | source4/ntvfs/posix/pvfs_setfileinfo.c | 17 | ||||
-rw-r--r-- | source4/ntvfs/posix/pvfs_xattr.c | 197 | ||||
-rw-r--r-- | source4/ntvfs/posix/vfs_posix.c | 6 | ||||
-rw-r--r-- | source4/ntvfs/posix/vfs_posix.h | 1 |
15 files changed, 403 insertions, 126 deletions
diff --git a/source4/build/m4/rewrite.m4 b/source4/build/m4/rewrite.m4 index 04d904a68d..7a24a11a5c 100644 --- a/source4/build/m4/rewrite.m4 +++ b/source4/build/m4/rewrite.m4 @@ -1455,16 +1455,6 @@ if test x"$samba_cv_HAVE_COMPARISON_FN_T" = x"yes"; then AC_DEFINE(HAVE_COMPARISON_FN_T,1,[Whether or not we have comparison_fn_t]) fi -############################################ -# Check if we have extended attributes -AC_CHECK_HEADERS(sys/attributes.h attr/xattr.h sys/xattr.h) -AC_SEARCH_LIBS(getxattr, [attr]) -AC_CHECK_FUNCS(getxattr lgetxattr fgetxattr listxattr llistxattr) -AC_CHECK_FUNCS(flistxattr removexattr lremovexattr fremovexattr) -AC_CHECK_FUNCS(setxattr lsetxattr fsetxattr) -AC_CHECK_FUNCS(attr_get attr_list attr_set attr_remove) -AC_CHECK_FUNCS(attr_getf attr_listf attr_setf attr_removef) - ################################################# # check for ACL support diff --git a/source4/libcli/util/errormap.c b/source4/libcli/util/errormap.c index 46e4831f89..417f4571a7 100644 --- a/source4/libcli/util/errormap.c +++ b/source4/libcli/util/errormap.c @@ -1517,6 +1517,13 @@ const struct unix_error_map unix_nt_errmap[] = { { EPIPE, NT_STATUS_CONNECTION_DISCONNECTED }, { ECONNREFUSED, NT_STATUS_CONNECTION_REFUSED }, { EBUSY, NT_STATUS_SHARING_VIOLATION }, + { ENOTSUP, NT_STATUS_NOT_SUPPORTED}, +#ifdef ENOATTR + { ENOATTR, NT_STATUS_NOT_FOUND }, +#endif +#ifdef ENODATA + { ENODATA, NT_STATUS_NOT_FOUND }, +#endif #ifdef EDQUOT { EDQUOT, NT_STATUS_QUOTA_EXCEEDED }, #endif diff --git a/source4/librpc/config.m4 b/source4/librpc/config.m4 index 76dc8c9c0f..5c137b738b 100644 --- a/source4/librpc/config.m4 +++ b/source4/librpc/config.m4 @@ -1,50 +1,8 @@ dnl # LIBRPC subsystem -SMB_SUBSYSTEM_MK(LIBNDR_RAW,librpc/config.mk) - SMB_SUBSYSTEM_NOPROTO(LIBNDR_GEN) -SMB_SUBSYSTEM(LIBNDR_GEN,[], - [librpc/gen_ndr/tables.o - librpc/gen_ndr/ndr_audiosrv.o - librpc/gen_ndr/ndr_dcerpc.o - librpc/gen_ndr/ndr_echo.o - librpc/gen_ndr/ndr_exchange.o - librpc/gen_ndr/ndr_dsbackup.o - librpc/gen_ndr/ndr_efs.o - librpc/gen_ndr/ndr_misc.o - librpc/gen_ndr/ndr_lsa.o - librpc/gen_ndr/ndr_lsads.o - librpc/gen_ndr/ndr_dfs.o - librpc/gen_ndr/ndr_drsuapi.o - librpc/gen_ndr/ndr_policyagent.o - librpc/gen_ndr/ndr_samr.o - librpc/gen_ndr/ndr_spoolss.o - librpc/gen_ndr/ndr_wkssvc.o - librpc/gen_ndr/ndr_srvsvc.o - librpc/gen_ndr/ndr_svcctl.o - librpc/gen_ndr/ndr_atsvc.o - librpc/gen_ndr/ndr_eventlog.o - librpc/gen_ndr/ndr_epmapper.o - librpc/gen_ndr/ndr_dbgidl.o - librpc/gen_ndr/ndr_dssetup.o - librpc/gen_ndr/ndr_msgsvc.o - librpc/gen_ndr/ndr_wins.o - librpc/gen_ndr/ndr_winreg.o - librpc/gen_ndr/ndr_mgmt.o - librpc/gen_ndr/ndr_protected_storage.o - librpc/gen_ndr/ndr_dcom.o - librpc/gen_ndr/ndr_oxidresolver.o - librpc/gen_ndr/ndr_remact.o - librpc/gen_ndr/ndr_wzcsvc.o - librpc/gen_ndr/ndr_browser.o - librpc/gen_ndr/ndr_w32time.o - librpc/gen_ndr/ndr_scerpc.o - librpc/gen_ndr/ndr_ntsvcs.o - librpc/gen_ndr/ndr_netlogon.o - librpc/gen_ndr/ndr_trkwks.o - librpc/gen_ndr/ndr_keysvc.o - librpc/gen_ndr/ndr_krb5pac.o - librpc/gen_ndr/ndr_schannel.o]) +SMB_SUBSYSTEM_MK(LIBNDR_GEN,librpc/config.mk) +SMB_SUBSYSTEM_MK(LIBNDR_RAW,librpc/config.mk) SMB_SUBSYSTEM_MK(LIBRPC_RAW,librpc/config.mk) SMB_SUBSYSTEM_MK(LIBRPC,librpc/config.mk) diff --git a/source4/librpc/config.mk b/source4/librpc/config.mk index 6e33b5c104..a359f13f54 100644 --- a/source4/librpc/config.mk +++ b/source4/librpc/config.mk @@ -28,6 +28,56 @@ ADD_OBJ_FILES = \ ################################################ ################################################ +# Start SUBSYSTEM LIBNDR_GEN +[SUBSYSTEM::LIBNDR_GEN] +INIT_OBJ_FILES = \ + librpc/gen_ndr/tables.o +ADD_OBJ_FILES = \ + librpc/gen_ndr/ndr_audiosrv.o \ + librpc/gen_ndr/ndr_dcerpc.o \ + librpc/gen_ndr/ndr_echo.o \ + librpc/gen_ndr/ndr_exchange.o \ + librpc/gen_ndr/ndr_dsbackup.o \ + librpc/gen_ndr/ndr_efs.o \ + librpc/gen_ndr/ndr_misc.o \ + librpc/gen_ndr/ndr_lsa.o \ + librpc/gen_ndr/ndr_lsads.o \ + librpc/gen_ndr/ndr_dfs.o \ + librpc/gen_ndr/ndr_drsuapi.o \ + librpc/gen_ndr/ndr_policyagent.o \ + librpc/gen_ndr/ndr_samr.o \ + librpc/gen_ndr/ndr_spoolss.o \ + librpc/gen_ndr/ndr_wkssvc.o \ + librpc/gen_ndr/ndr_srvsvc.o \ + librpc/gen_ndr/ndr_svcctl.o \ + librpc/gen_ndr/ndr_atsvc.o \ + librpc/gen_ndr/ndr_eventlog.o \ + librpc/gen_ndr/ndr_epmapper.o \ + librpc/gen_ndr/ndr_dbgidl.o \ + librpc/gen_ndr/ndr_dssetup.o \ + librpc/gen_ndr/ndr_msgsvc.o \ + librpc/gen_ndr/ndr_wins.o \ + librpc/gen_ndr/ndr_winreg.o \ + librpc/gen_ndr/ndr_mgmt.o \ + librpc/gen_ndr/ndr_protected_storage.o \ + librpc/gen_ndr/ndr_dcom.o \ + librpc/gen_ndr/ndr_oxidresolver.o \ + librpc/gen_ndr/ndr_remact.o \ + librpc/gen_ndr/ndr_wzcsvc.o \ + librpc/gen_ndr/ndr_browser.o \ + librpc/gen_ndr/ndr_w32time.o \ + librpc/gen_ndr/ndr_scerpc.o \ + librpc/gen_ndr/ndr_ntsvcs.o \ + librpc/gen_ndr/ndr_netlogon.o \ + librpc/gen_ndr/ndr_trkwks.o \ + librpc/gen_ndr/ndr_keysvc.o \ + librpc/gen_ndr/ndr_krb5pac.o \ + librpc/gen_ndr/ndr_xattr.o \ + librpc/gen_ndr/ndr_schannel.o +# End SUBSYSTEM LIBNDR_GEN +################################################ + +################################################ # Start SUBSYSTEM LIBRPC [SUBSYSTEM::LIBRPC] REQUIRED_SUBSYSTEMS = LIBNDR_RAW LIBNDR_GEN LIBRPC_RAW diff --git a/source4/librpc/idl/xattr.idl b/source4/librpc/idl/xattr.idl new file mode 100644 index 0000000000..aa5c0a0d6a --- /dev/null +++ b/source4/librpc/idl/xattr.idl @@ -0,0 +1,35 @@ +#include "idl_types.h" + +/* + IDL structures for xattr file attributes + + this has nothing to do with RPC, we are just using our NDR/IDL + infrastructure as a convenient way to store linearised information + about a file in a architecture independent manner +*/ + +interface xattr +{ + const string XATTR_DOSATTRIB_NAME = "user.DosAttrib"; + const string XATTR_DOSATTRIB_ESTIMATED_SIZE = 64; + + /* by using a union we can cope with new version of + this structure more easily */ + typedef struct { + uint32 attrib; + uint32 ea_size; + uint64 size; + uint64 alloc_size; + NTTIME create_time; + NTTIME change_time; + } xattr_DosInfo1; + + typedef union { + [case(1)] xattr_DosInfo1 info1; + } xattr_DosInfo; + + typedef [public] struct { + uint16 version; + [switch_is(version)] xattr_DosInfo info; + } xattr_DosAttrib; +} diff --git a/source4/librpc/ndr/ndr.c b/source4/librpc/ndr/ndr.c index 8e8e49e220..71019030ac 100644 --- a/source4/librpc/ndr/ndr.c +++ b/source4/librpc/ndr/ndr.c @@ -318,9 +318,7 @@ void ndr_print_debug_helper(struct ndr_print *ndr, const char *format, ...) _PRI /* a useful helper function for printing idl structures via DEBUG() */ -void ndr_print_debug(void (*fn)(struct ndr_print *, const char *, void *), - const char *name, - void *ptr) +void ndr_print_debug(ndr_print_fn_t fn, const char *name, void *ptr) { struct ndr_print *ndr; @@ -337,10 +335,7 @@ void ndr_print_debug(void (*fn)(struct ndr_print *, const char *, void *), /* a useful helper function for printing idl unions via DEBUG() */ -void ndr_print_union_debug(void (*fn)(struct ndr_print *, const char *, uint32_t, void *), - const char *name, - uint32_t level, - void *ptr) +void ndr_print_union_debug(ndr_print_union_fn_t fn, const char *name, uint32_t level, void *ptr) { struct ndr_print *ndr; @@ -356,10 +351,7 @@ void ndr_print_union_debug(void (*fn)(struct ndr_print *, const char *, uint32_t /* a useful helper function for printing idl function calls via DEBUG() */ -void ndr_print_function_debug(void (*fn)(struct ndr_print *, const char *, int , void *), - const char *name, - int flags, - void *ptr) +void ndr_print_function_debug(ndr_print_function_t fn, const char *name, int flags, void *ptr) { struct ndr_print *ndr; @@ -481,10 +473,8 @@ static NTSTATUS ndr_pull_subcontext_header(struct ndr_pull *ndr, handle subcontext buffers, which in midl land are user-marshalled, but we use magic in pidl to make them easier to cope with */ -NTSTATUS ndr_pull_subcontext_fn(struct ndr_pull *ndr, - size_t sub_size, - void *base, - NTSTATUS (*fn)(struct ndr_pull *, void *)) +NTSTATUS ndr_pull_subcontext_fn(struct ndr_pull *ndr, size_t sub_size, + void *base, ndr_pull_fn_t fn) { struct ndr_pull *ndr2; NDR_ALLOC(ndr, ndr2); @@ -499,10 +489,8 @@ NTSTATUS ndr_pull_subcontext_fn(struct ndr_pull *ndr, } -NTSTATUS ndr_pull_subcontext_flags_fn(struct ndr_pull *ndr, - size_t sub_size, - void *base, - NTSTATUS (*fn)(struct ndr_pull *, int , void *)) +NTSTATUS ndr_pull_subcontext_flags_fn(struct ndr_pull *ndr, size_t sub_size, + void *base, ndr_pull_flags_fn_t fn) { struct ndr_pull *ndr2; NDR_ALLOC(ndr, ndr2); @@ -516,11 +504,8 @@ NTSTATUS ndr_pull_subcontext_flags_fn(struct ndr_pull *ndr, return NT_STATUS_OK; } -NTSTATUS ndr_pull_subcontext_union_fn(struct ndr_pull *ndr, - size_t sub_size, - uint32_t level, - void *base, - NTSTATUS (*fn)(struct ndr_pull *, int , uint32_t , void *)) +NTSTATUS ndr_pull_subcontext_union_fn(struct ndr_pull *ndr, size_t sub_size, + uint32_t level, void *base, ndr_pull_union_fn_t fn) { struct ndr_pull *ndr2; @@ -566,10 +551,8 @@ static NTSTATUS ndr_push_subcontext_header(struct ndr_push *ndr, handle subcontext buffers, which in midl land are user-marshalled, but we use magic in pidl to make them easier to cope with */ -NTSTATUS ndr_push_subcontext_fn(struct ndr_push *ndr, - size_t sub_size, - void *base, - NTSTATUS (*fn)(struct ndr_push *, void *)) +NTSTATUS ndr_push_subcontext_fn(struct ndr_push *ndr, size_t sub_size, + void *base, ndr_push_fn_t fn) { struct ndr_push *ndr2; @@ -586,10 +569,8 @@ NTSTATUS ndr_push_subcontext_fn(struct ndr_push *ndr, /* handle subcontext buffers for function that take a flags arg */ -NTSTATUS ndr_push_subcontext_flags_fn(struct ndr_push *ndr, - size_t sub_size, - void *base, - NTSTATUS (*fn)(struct ndr_push *, int, void *)) +NTSTATUS ndr_push_subcontext_flags_fn(struct ndr_push *ndr, size_t sub_size, + void *base, ndr_push_flags_fn_t fn) { struct ndr_push *ndr2; @@ -606,11 +587,8 @@ NTSTATUS ndr_push_subcontext_flags_fn(struct ndr_push *ndr, /* handle subcontext buffers for function that take a union */ -NTSTATUS ndr_push_subcontext_union_fn(struct ndr_push *ndr, - size_t sub_size, - uint32_t level, - void *base, - NTSTATUS (*fn)(struct ndr_push *, int, uint32_t, void *)) +NTSTATUS ndr_push_subcontext_union_fn(struct ndr_push *ndr, size_t sub_size, + uint32_t level, void *base, ndr_push_union_fn_t fn) { struct ndr_push *ndr2; @@ -763,7 +741,7 @@ NTSTATUS ndr_push_relative2(struct ndr_push *ndr, const void *p) pull a union from a blob using NDR */ NTSTATUS ndr_pull_union_blob(DATA_BLOB *blob, TALLOC_CTX *mem_ctx, uint32_t level, void *p, - NTSTATUS (*fn)(struct ndr_pull *, int ndr_flags, uint32_t, void *)) + ndr_pull_union_fn_t fn) { struct ndr_pull *ndr; ndr = ndr_pull_init_blob(blob, mem_ctx); @@ -777,7 +755,7 @@ NTSTATUS ndr_pull_union_blob(DATA_BLOB *blob, TALLOC_CTX *mem_ctx, uint32_t leve pull a struct from a blob using NDR */ NTSTATUS ndr_pull_struct_blob(const DATA_BLOB *blob, TALLOC_CTX *mem_ctx, void *p, - NTSTATUS (*fn)(struct ndr_pull *, int , void *)) + ndr_pull_flags_fn_t fn) { struct ndr_pull *ndr; ndr = ndr_pull_init_blob(blob, mem_ctx); @@ -791,7 +769,7 @@ NTSTATUS ndr_pull_struct_blob(const DATA_BLOB *blob, TALLOC_CTX *mem_ctx, void * push a struct to a blob using NDR */ NTSTATUS ndr_push_struct_blob(DATA_BLOB *blob, TALLOC_CTX *mem_ctx, void *p, - NTSTATUS (*fn)(struct ndr_push *, int , void *)) + ndr_push_flags_fn_t fn) { NTSTATUS status; struct ndr_push *ndr; diff --git a/source4/ntvfs/posix/config.m4 b/source4/ntvfs/posix/config.m4 index b1de4c20e5..2fb69b65b0 100644 --- a/source4/ntvfs/posix/config.m4 +++ b/source4/ntvfs/posix/config.m4 @@ -1,4 +1,3 @@ -SMB_MODULE_MK(ntvfs_posix, NTVFS, STATIC, ntvfs/config.mk) dnl ############################################# @@ -22,4 +21,16 @@ if test x"$ac_cv_decl_have_stat_tv_nsec" = x"yes"; then AC_DEFINE(HAVE_STAT_TV_NSEC,1,[Whether stat has tv_nsec nanosecond fields]) fi +dnl ############################################ +dnl use flistxattr as the key function for having +dnl sufficient xattr support for posix xattr backend +AC_CHECK_HEADERS(sys/attributes.h attr/xattr.h sys/xattr.h) +AC_SEARCH_LIBS(flistxattr, [attr]) + +if test x"$ac_cv_func_flistxattr" = x"yes"; then + SMB_MODULE_DEFAULT(posix_xattr, STATIC) + AC_DEFINE(HAVE_XATTR_SUPPORT,1,[Whether we have xattr support]) +fi +SMB_MODULE_MK(posix_xattr, NTVFS, NOT, ntvfs/posix/config.mk) +SMB_MODULE_MK(ntvfs_posix, NTVFS, STATIC, ntvfs/config.mk) diff --git a/source4/ntvfs/posix/config.mk b/source4/ntvfs/posix/config.mk index 4918ee61eb..d44200d8c3 100644 --- a/source4/ntvfs/posix/config.mk +++ b/source4/ntvfs/posix/config.mk @@ -1,4 +1,13 @@ ################################################ +# Start MODULE posix_xattr +[MODULE::posix_xattr] +INIT_OBJ_FILES = \ + ntvfs/posix/pvfs_xattr.o +# End MODULE posix_xattr +################################################ + + +################################################ # Start MODULE ntvfs_posix [MODULE::ntvfs_posix] INIT_OBJ_FILES = \ diff --git a/source4/ntvfs/posix/pvfs_fileinfo.c b/source4/ntvfs/posix/pvfs_fileinfo.c index 42aad1a20e..49678e5998 100644 --- a/source4/ntvfs/posix/pvfs_fileinfo.c +++ b/source4/ntvfs/posix/pvfs_fileinfo.c @@ -20,7 +20,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include "include/includes.h" +#include "includes.h" #include "vfs_posix.h" @@ -45,14 +45,16 @@ static uint32_t dos_mode_from_stat(struct pvfs_state *pvfs, struct stat *st) if ((st->st_mode & S_IWUSR) == 0) result |= FILE_ATTRIBUTE_READONLY; - if ((pvfs->flags & PVFS_FLAG_MAP_ARCHIVE) && ((st->st_mode & S_IXUSR) != 0)) - result |= FILE_ATTRIBUTE_ARCHIVE; - - if ((pvfs->flags & PVFS_FLAG_MAP_SYSTEM) && ((st->st_mode & S_IXGRP) != 0)) - result |= FILE_ATTRIBUTE_SYSTEM; - - if ((pvfs->flags & PVFS_FLAG_MAP_HIDDEN) && ((st->st_mode & S_IXOTH) != 0)) - result |= FILE_ATTRIBUTE_HIDDEN; + if (!(pvfs->flags & PVFS_FLAG_XATTR_ENABLE)) { + if ((pvfs->flags & PVFS_FLAG_MAP_ARCHIVE) && ((st->st_mode & S_IXUSR) != 0)) + result |= FILE_ATTRIBUTE_ARCHIVE; + + if ((pvfs->flags & PVFS_FLAG_MAP_SYSTEM) && ((st->st_mode & S_IXGRP) != 0)) + result |= FILE_ATTRIBUTE_SYSTEM; + + if ((pvfs->flags & PVFS_FLAG_MAP_HIDDEN) && ((st->st_mode & S_IXOTH) != 0)) + result |= FILE_ATTRIBUTE_HIDDEN; + } if (S_ISDIR(st->st_mode)) result = FILE_ATTRIBUTE_DIRECTORY | (result & FILE_ATTRIBUTE_READONLY); @@ -74,7 +76,7 @@ static uint32_t dos_mode_from_stat(struct pvfs_state *pvfs, struct stat *st) /* fill in the dos file attributes for a file */ -NTSTATUS pvfs_fill_dos_info(struct pvfs_state *pvfs, struct pvfs_filename *name) +NTSTATUS pvfs_fill_dos_info(struct pvfs_state *pvfs, struct pvfs_filename *name, int fd) { /* make directories appear as size 0 */ if (S_ISDIR(name->st.st_mode)) { @@ -98,6 +100,12 @@ NTSTATUS pvfs_fill_dos_info(struct pvfs_state *pvfs, struct pvfs_filename *name) name->dos.ea_size = 0; name->dos.file_id = (((uint64_t)name->st.st_dev)<<32) | name->st.st_ino; +#if HAVE_XATTR_SUPPORT + if (pvfs->flags & PVFS_FLAG_XATTR_ENABLE) { + return pvfs_xattr_load(pvfs, name, fd); + } +#endif + return NT_STATUS_OK; } @@ -117,19 +125,21 @@ mode_t pvfs_fileperms(struct pvfs_state *pvfs, uint32 attrib) mode |= S_IWUSR; } - if ((attrib & FILE_ATTRIBUTE_ARCHIVE) && - (pvfs->flags & PVFS_FLAG_MAP_ARCHIVE)) { - mode |= S_IXUSR; - } - - if ((attrib & FILE_ATTRIBUTE_SYSTEM) && - (pvfs->flags & PVFS_FLAG_MAP_SYSTEM)) { - mode |= S_IXGRP; - } - - if ((attrib & FILE_ATTRIBUTE_HIDDEN) && - (pvfs->flags & PVFS_FLAG_MAP_HIDDEN)) { - mode |= S_IXOTH; + if (!(pvfs->flags & PVFS_FLAG_XATTR_ENABLE)) { + if ((attrib & FILE_ATTRIBUTE_ARCHIVE) && + (pvfs->flags & PVFS_FLAG_MAP_ARCHIVE)) { + mode |= S_IXUSR; + } + + if ((attrib & FILE_ATTRIBUTE_SYSTEM) && + (pvfs->flags & PVFS_FLAG_MAP_SYSTEM)) { + mode |= S_IXGRP; + } + + if ((attrib & FILE_ATTRIBUTE_HIDDEN) && + (pvfs->flags & PVFS_FLAG_MAP_HIDDEN)) { + mode |= S_IXOTH; + } } return mode; diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index c8f96849ec..ed6da83e73 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -20,7 +20,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include "include/includes.h" +#include "includes.h" #include "vfs_posix.h" #include "system/time.h" #include "system/filesys.h" @@ -330,6 +330,14 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs, return status; } + +#if HAVE_XATTR_SUPPORT + name->dos.attrib = io->ntcreatex.in.file_attr; + if (pvfs->flags & PVFS_FLAG_XATTR_ENABLE) { + status = pvfs_xattr_save(pvfs, name, fd); + } +#endif + /* form the lock context used for byte range locking and opendb locking */ status = pvfs_locking_key(name, f, &f->locking_key); @@ -472,6 +480,10 @@ static void pvfs_open_retry(void *private, enum pvfs_wait_notice reason) return; } + /* re-mark it async, just in case someone up the chain does + paranoid checking */ + req->async_states->state |= NTVFS_ASYNC_STATE_ASYNC; + /* send the reply up the chain */ req->async_states->status = status; req->async_states->send_fn(req); diff --git a/source4/ntvfs/posix/pvfs_resolve.c b/source4/ntvfs/posix/pvfs_resolve.c index 551b05b248..30602b964a 100644 --- a/source4/ntvfs/posix/pvfs_resolve.c +++ b/source4/ntvfs/posix/pvfs_resolve.c @@ -27,7 +27,7 @@ */ -#include "include/includes.h" +#include "includes.h" #include "vfs_posix.h" #include "system/dir.h" @@ -175,7 +175,7 @@ static NTSTATUS pvfs_case_search(struct pvfs_state *pvfs, struct pvfs_filename * name->full_name = partial_name; if (name->exists) { - return pvfs_fill_dos_info(pvfs, name); + return pvfs_fill_dos_info(pvfs, name, -1); } return NT_STATUS_OK; @@ -446,7 +446,7 @@ NTSTATUS pvfs_resolve_name(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx, /* if we can stat() the full name now then we are done */ if (stat((*name)->full_name, &(*name)->st) == 0) { (*name)->exists = True; - return pvfs_fill_dos_info(pvfs, *name); + return pvfs_fill_dos_info(pvfs, *name, -1); } /* search for a matching filename */ @@ -489,7 +489,7 @@ NTSTATUS pvfs_resolve_partial(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx, (*name)->original_name = talloc_strdup(*name, fname); (*name)->stream_name = NULL; - status = pvfs_fill_dos_info(pvfs, *name); + status = pvfs_fill_dos_info(pvfs, *name, -1); return status; } @@ -534,5 +534,5 @@ NTSTATUS pvfs_resolve_name_fd(struct pvfs_state *pvfs, int fd, name->exists = True; - return pvfs_fill_dos_info(pvfs, name); + return pvfs_fill_dos_info(pvfs, name, fd); } diff --git a/source4/ntvfs/posix/pvfs_setfileinfo.c b/source4/ntvfs/posix/pvfs_setfileinfo.c index 8a4c6e433d..fe489c2e69 100644 --- a/source4/ntvfs/posix/pvfs_setfileinfo.c +++ b/source4/ntvfs/posix/pvfs_setfileinfo.c @@ -20,7 +20,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include "include/includes.h" +#include "includes.h" #include "vfs_posix.h" #include "system/time.h" @@ -163,6 +163,13 @@ NTSTATUS pvfs_setfileinfo(struct ntvfs_module_context *ntvfs, } } + *f->name = newstats; + +#if HAVE_XATTR_SUPPORT + if (pvfs->flags & PVFS_FLAG_XATTR_ENABLE) { + return pvfs_xattr_save(pvfs, f->name, f->fd); + } +#endif return NT_STATUS_OK; } @@ -287,6 +294,14 @@ NTSTATUS pvfs_setpathinfo(struct ntvfs_module_context *ntvfs, } } + *name = newstats; + +#if HAVE_XATTR_SUPPORT + if (pvfs->flags & PVFS_FLAG_XATTR_ENABLE) { + return pvfs_xattr_save(pvfs, name, -1); + } +#endif + return NT_STATUS_OK; } diff --git a/source4/ntvfs/posix/pvfs_xattr.c b/source4/ntvfs/posix/pvfs_xattr.c new file mode 100644 index 0000000000..24fa49108a --- /dev/null +++ b/source4/ntvfs/posix/pvfs_xattr.c @@ -0,0 +1,197 @@ +/* + Unix SMB/CIFS implementation. + + POSIX NTVFS backend - xattr support + + Copyright (C) Andrew Tridgell 2004 + + 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 2 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, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" +#include "system/filesys.h" +#include "vfs_posix.h" +#include "librpc/gen_ndr/ndr_xattr.h" + + +/* + pull a xattr as a blob, from either a file or a file descriptor +*/ +static NTSTATUS pull_xattr_blob(TALLOC_CTX *mem_ctx, + const char *attr_name, + const char *fname, + int fd, + size_t estimated_size, + DATA_BLOB *blob) +{ + int ret; + + *blob = data_blob_talloc(mem_ctx, NULL, estimated_size); + if (blob->data == NULL) { + return NT_STATUS_NO_MEMORY; + } + +again: + if (fd != -1) { + ret = fgetxattr(fd, attr_name, blob->data, estimated_size); + } else { + ret = getxattr(fname, attr_name, blob->data, estimated_size); + } + if (ret == -1 && errno == ERANGE) { + estimated_size *= 2; + blob->data = talloc_realloc(mem_ctx, blob->data, estimated_size); + if (blob->data == NULL) { + return NT_STATUS_NO_MEMORY; + } + blob->length = estimated_size; + goto again; + } + + if (ret == -1) { + data_blob_free(blob); + return map_nt_error_from_unix(errno); + } + + blob->length = ret; + + return NT_STATUS_OK; +} + +/* + push a xattr as a blob, from either a file or a file descriptor +*/ +static NTSTATUS push_xattr_blob(TALLOC_CTX *mem_ctx, + const char *attr_name, + const char *fname, + int fd, + const DATA_BLOB *blob) +{ + int ret; + + if (fd != -1) { + ret = fsetxattr(fd, attr_name, blob->data, blob->length, 0); + } else { + ret = setxattr(fname, attr_name, blob->data, blob->length, 0); + } + if (ret == -1) { + return map_nt_error_from_unix(errno); + } + + return NT_STATUS_OK; +} + + +/* + fill in file attributes from extended attributes +*/ +NTSTATUS pvfs_xattr_load(struct pvfs_state *pvfs, struct pvfs_filename *name, int fd) +{ + DATA_BLOB blob; + NTSTATUS status; + struct xattr_DosAttrib attrib; + TALLOC_CTX *mem_ctx = talloc(name, 0); + struct xattr_DosInfo1 *info1; + + status = pull_xattr_blob(mem_ctx, XATTR_DOSATTRIB_NAME, name->full_name, + fd, XATTR_DOSATTRIB_ESTIMATED_SIZE, &blob); + + /* if the filesystem doesn't support them, then tell pvfs not to try again */ + if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) { + DEBUG(5,("pvfs_xattr: xattr not supported in filesystem\n")); + pvfs->flags &= ~PVFS_FLAG_XATTR_ENABLE; + talloc_free(mem_ctx); + return NT_STATUS_OK; + } + + /* not having a DosAttrib is not an error */ + if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) { + talloc_free(mem_ctx); + return NT_STATUS_OK; + } + + if (!NT_STATUS_IS_OK(status)) { + talloc_free(mem_ctx); + return status; + } + + /* pull the blob */ + status = ndr_pull_struct_blob(&blob, mem_ctx, &attrib, + (ndr_pull_flags_fn_t)ndr_pull_xattr_DosAttrib); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(mem_ctx); + return status; + } + + switch (attrib.version) { + case 1: + info1 = &attrib.info.info1; + name->dos.attrib = info1->attrib; + name->dos.ea_size = info1->ea_size; + if (name->st.st_size == info1->size) { + name->dos.alloc_size = info1->alloc_size; + } + if (info1->create_time != 0) { + name->dos.create_time = info1->create_time; + } + if (info1->change_time != 0) { + name->dos.change_time = info1->change_time; + } + break; + + default: + DEBUG(0,("ERROR: Unsupported xattr DosAttrib version %d on '%s'\n", + attrib.version, name->full_name)); + talloc_free(mem_ctx); + return NT_STATUS_INVALID_LEVEL; + } + + talloc_free(mem_ctx); + return NT_STATUS_OK; +} + + +/* + save the file attribute into into the xattr +*/ +NTSTATUS pvfs_xattr_save(struct pvfs_state *pvfs, struct pvfs_filename *name, int fd) +{ + struct xattr_DosAttrib attrib; + struct xattr_DosInfo1 *info1; + TALLOC_CTX *mem_ctx = talloc(name, 0); + DATA_BLOB blob; + NTSTATUS status; + + attrib.version = 1; + info1 = &attrib.info.info1; + + info1->attrib = name->dos.attrib; + info1->ea_size = name->dos.ea_size; + info1->size = name->st.st_size; + info1->alloc_size = name->dos.alloc_size; + info1->create_time = name->dos.create_time; + info1->change_time = name->dos.change_time; + + status = ndr_push_struct_blob(&blob, mem_ctx, &attrib, + (ndr_push_flags_fn_t)ndr_push_xattr_DosAttrib); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(mem_ctx); + return status; + } + + status = push_xattr_blob(mem_ctx, XATTR_DOSATTRIB_NAME, name->full_name, fd, &blob); + talloc_free(mem_ctx); + + return status; +} diff --git a/source4/ntvfs/posix/vfs_posix.c b/source4/ntvfs/posix/vfs_posix.c index 2f0f38dd22..da4296d062 100644 --- a/source4/ntvfs/posix/vfs_posix.c +++ b/source4/ntvfs/posix/vfs_posix.c @@ -24,7 +24,7 @@ This is the default backend */ -#include "include/includes.h" +#include "includes.h" #include "vfs_posix.h" @@ -44,6 +44,10 @@ static void pvfs_setup_options(struct pvfs_state *pvfs) if (lp_strict_locking(snum)) pvfs->flags |= PVFS_FLAG_STRICT_LOCKING; if (lp_ci_filesystem(snum)) pvfs->flags |= PVFS_FLAG_CI_FILESYSTEM; +#if HAVE_XATTR_SUPPORT + if (lp_parm_bool(snum, "posix", "xattr", True)) pvfs->flags |= PVFS_FLAG_XATTR_ENABLE; +#endif + pvfs->sharing_violation_delay = 1000000; delay = lp_parm_int(snum, "posix", "sharedelay"); if (delay != -1) { diff --git a/source4/ntvfs/posix/vfs_posix.h b/source4/ntvfs/posix/vfs_posix.h index 4ee06723ac..64b9a0d653 100644 --- a/source4/ntvfs/posix/vfs_posix.h +++ b/source4/ntvfs/posix/vfs_posix.h @@ -161,6 +161,7 @@ struct pvfs_mangle_context { #define PVFS_FLAG_READONLY (1<<4) #define PVFS_FLAG_STRICT_SYNC (1<<5) #define PVFS_FLAG_STRICT_LOCKING (1<<6) +#define PVFS_FLAG_XATTR_ENABLE (1<<7) /* forward declare some anonymous structures */ struct pvfs_dir; |