From 12f4a44cf549b4ccd729494c242a5ec186d2d670 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 5 Nov 2004 11:31:35 +0000 Subject: r3549: added support for DOS extended attribute lists (name/value pairs) stored in posix xattrs (This used to be commit bad6a88371264cffce2bf5d6ce904b7b357081de) --- source4/include/smb_interfaces.h | 2 +- source4/include/structs.h | 2 + source4/librpc/idl/idl_types.h | 6 ++ source4/librpc/idl/xattr.idl | 20 +++++- source4/librpc/ndr/libndr.h | 3 +- source4/librpc/ndr/ndr_basic.c | 14 +++- source4/ntvfs/posix/config.m4 | 2 - source4/ntvfs/posix/config.mk | 10 +-- source4/ntvfs/posix/pvfs_fileinfo.c | 26 +++---- source4/ntvfs/posix/pvfs_open.c | 10 +-- source4/ntvfs/posix/pvfs_qfileinfo.c | 39 ++++++++-- source4/ntvfs/posix/pvfs_setfileinfo.c | 78 ++++++++++++++++---- source4/ntvfs/posix/pvfs_xattr.c | 128 +++++++++++++++++++++++++-------- 13 files changed, 254 insertions(+), 86 deletions(-) (limited to 'source4') diff --git a/source4/include/smb_interfaces.h b/source4/include/smb_interfaces.h index c7698bd941..434f9513d2 100644 --- a/source4/include/smb_interfaces.h +++ b/source4/include/smb_interfaces.h @@ -433,7 +433,7 @@ union smb_fileinfo { enum smb_fileinfo_level level; union smb_fileinfo_in in; - struct { + struct smb_all_eas { /* the ea_size is implied by the list */ uint_t num_eas; struct ea_struct *eas; diff --git a/source4/include/structs.h b/source4/include/structs.h index 5c7c470a38..2d1679fd1c 100644 --- a/source4/include/structs.h +++ b/source4/include/structs.h @@ -108,3 +108,5 @@ struct net_functable; struct net_context; struct file_info; + +struct xattr_DosEAs; diff --git a/source4/librpc/idl/idl_types.h b/source4/librpc/idl/idl_types.h index 860c9d7260..54943ce78c 100644 --- a/source4/librpc/idl/idl_types.h +++ b/source4/librpc/idl/idl_types.h @@ -8,6 +8,7 @@ #define STR_FIXLEN32 LIBNDR_FLAG_STR_FIXLEN32 #define STR_CONFORMANT LIBNDR_FLAG_STR_CONFORMANT #define STR_CHARLEN LIBNDR_FLAG_STR_CHARLEN +#define STR_UTF8 LIBNDR_FLAG_STR_UTF8 /* a UCS2 string prefixed with [size] [offset] [length], all 32 bits @@ -64,6 +65,11 @@ */ #define astring [flag(STR_ASCII|STR_NULLTERM)] string +/* + a null terminated UTF8 string +*/ +#define utf8string [flag(STR_UTF8|STR_NULLTERM)] string + #define NDR_NOALIGN LIBNDR_FLAG_NOALIGN #define NDR_REMAINING LIBNDR_FLAG_REMAINING diff --git a/source4/librpc/idl/xattr.idl b/source4/librpc/idl/xattr.idl index aa5c0a0d6a..c2487b705c 100644 --- a/source4/librpc/idl/xattr.idl +++ b/source4/librpc/idl/xattr.idl @@ -13,8 +13,9 @@ 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 */ + /* we store basic dos attributes in a DosAttrib xattr. By + using a union we can cope with new version of this + structure more easily */ typedef struct { uint32 attrib; uint32 ea_size; @@ -32,4 +33,19 @@ interface xattr uint16 version; [switch_is(version)] xattr_DosInfo info; } xattr_DosAttrib; + + + /* we store DOS style extended attributes in a DosEAs xattr */ + const string XATTR_DOSEAS_NAME = "user.DosEAs"; + const string XATTR_DOSEAS_ESTIMATED_SIZE = 100; + + typedef struct { + utf8string name; + DATA_BLOB value; + } xattr_EA; + + typedef [public] struct { + uint16 num_eas; + [size_is(num_eas)] xattr_EA *eas; + } xattr_DosEAs; } diff --git a/source4/librpc/ndr/libndr.h b/source4/librpc/ndr/libndr.h index 72d75f7d47..86312b0906 100644 --- a/source4/librpc/ndr/libndr.h +++ b/source4/librpc/ndr/libndr.h @@ -99,7 +99,8 @@ struct ndr_print { #define LIBNDR_FLAG_STR_FIXLEN32 (1<<9) #define LIBNDR_FLAG_STR_CONFORMANT (1<<10) #define LIBNDR_FLAG_STR_CHARLEN (1<<11) -#define LIBNDR_STRING_FLAGS (0xFFC) +#define LIBNDR_FLAG_STR_UTF8 (1<<12) +#define LIBNDR_STRING_FLAGS (0x1FFC) #define LIBNDR_FLAG_REF_ALLOC (1<<20) diff --git a/source4/librpc/ndr/ndr_basic.c b/source4/librpc/ndr/ndr_basic.c index 2dc28c3783..ed591a2e5e 100644 --- a/source4/librpc/ndr/ndr_basic.c +++ b/source4/librpc/ndr/ndr_basic.c @@ -522,6 +522,12 @@ NTSTATUS ndr_pull_string(struct ndr_pull *ndr, int ndr_flags, const char **s) flags &= ~LIBNDR_FLAG_STR_ASCII; } + if (flags & LIBNDR_FLAG_STR_UTF8) { + chset = CH_UTF8; + byte_mul = 1; + flags &= ~LIBNDR_FLAG_STR_UTF8; + } + flags &= ~LIBNDR_FLAG_STR_CONFORMANT; flags &= ~LIBNDR_FLAG_STR_CHARLEN; @@ -762,6 +768,12 @@ NTSTATUS ndr_push_string(struct ndr_push *ndr, int ndr_flags, const char *s) flags &= ~LIBNDR_FLAG_STR_ASCII; } + if (flags & LIBNDR_FLAG_STR_UTF8) { + chset = CH_UTF8; + byte_mul = 1; + flags &= ~LIBNDR_FLAG_STR_UTF8; + } + flags &= ~LIBNDR_FLAG_STR_CONFORMANT; if (flags & LIBNDR_FLAG_STR_CHARLEN) { @@ -902,7 +914,7 @@ size_t ndr_string_array_size(struct ndr_push *ndr, const char *s) c_len = s?strlen_m(s):0; - if (flags & LIBNDR_FLAG_STR_ASCII) { + if (flags & (LIBNDR_FLAG_STR_ASCII|LIBNDR_FLAG_STR_UTF8)) { byte_mul = 1; } diff --git a/source4/ntvfs/posix/config.m4 b/source4/ntvfs/posix/config.m4 index 2fb69b65b0..975da5f2a9 100644 --- a/source4/ntvfs/posix/config.m4 +++ b/source4/ntvfs/posix/config.m4 @@ -28,9 +28,7 @@ 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 d44200d8c3..dd72468216 100644 --- a/source4/ntvfs/posix/config.mk +++ b/source4/ntvfs/posix/config.mk @@ -1,12 +1,3 @@ -################################################ -# 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] @@ -33,6 +24,7 @@ ADD_OBJ_FILES = \ ntvfs/posix/pvfs_wait.o \ ntvfs/posix/pvfs_seek.o \ ntvfs/posix/pvfs_ioctl.o \ + ntvfs/posix/pvfs_xattr.o \ ntvfs/common/opendb.o \ ntvfs/common/brlock.o # End MODULE ntvfs_posix diff --git a/source4/ntvfs/posix/pvfs_fileinfo.c b/source4/ntvfs/posix/pvfs_fileinfo.c index 49678e5998..2419893049 100644 --- a/source4/ntvfs/posix/pvfs_fileinfo.c +++ b/source4/ntvfs/posix/pvfs_fileinfo.c @@ -45,16 +45,14 @@ 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_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 ((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); @@ -100,13 +98,7 @@ 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; + return pvfs_dosattrib_load(pvfs, name, fd); } diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index ed6da83e73..d640bae279 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -330,13 +330,13 @@ 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); + status = pvfs_dosattrib_save(pvfs, name, fd); + if (!NT_STATUS_IS_OK(status)) { + idr_remove(pvfs->idtree_fnum, fnum); + close(fd); + return status; } -#endif /* form the lock context used for byte range locking and opendb locking */ diff --git a/source4/ntvfs/posix/pvfs_qfileinfo.c b/source4/ntvfs/posix/pvfs_qfileinfo.c index 4c699d63ce..51aadc07a5 100644 --- a/source4/ntvfs/posix/pvfs_qfileinfo.c +++ b/source4/ntvfs/posix/pvfs_qfileinfo.c @@ -22,13 +22,42 @@ #include "includes.h" #include "vfs_posix.h" +#include "librpc/gen_ndr/ndr_xattr.h" +/* + reply to a RAW_FILEINFO_ALL_EAS call +*/ +static NTSTATUS pvfs_query_all_eas(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx, + struct pvfs_filename *name, int fd, struct smb_all_eas *eas) +{ + NTSTATUS status; + int i; + struct xattr_DosEAs *ealist = talloc_p(mem_ctx, struct xattr_DosEAs); + + ZERO_STRUCTP(eas); + status = pvfs_doseas_load(pvfs, name, fd, ealist); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + eas->num_eas = ealist->num_eas; + eas->eas = talloc_array_p(mem_ctx, struct ea_struct, eas->num_eas); + if (eas->eas == NULL) { + return NT_STATUS_NO_MEMORY; + } + for (i=0;inum_eas;i++) { + eas->eas[i].flags = 0; + eas->eas[i].name.s = ealist->eas[i].name; + eas->eas[i].value = ealist->eas[i].value; + } + return NT_STATUS_OK; +} /* approximately map a struct pvfs_filename to a generic fileinfo struct */ static NTSTATUS pvfs_map_fileinfo(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx, - struct pvfs_filename *name, union smb_fileinfo *info) + struct pvfs_filename *name, union smb_fileinfo *info, + int fd) { switch (info->generic.level) { case RAW_FILEINFO_GENERIC: @@ -61,9 +90,7 @@ static NTSTATUS pvfs_map_fileinfo(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx, return NT_STATUS_OK; case RAW_FILEINFO_ALL_EAS: - info->all_eas.out.num_eas = 0; - info->all_eas.out.eas = NULL; - return NT_STATUS_OK; + return pvfs_query_all_eas(pvfs, mem_ctx, name, fd, &info->all_eas.out); case RAW_FILEINFO_IS_NAME_VALID: return NT_STATUS_OK; @@ -202,7 +229,7 @@ NTSTATUS pvfs_qpathinfo(struct ntvfs_module_context *ntvfs, return NT_STATUS_OBJECT_NAME_NOT_FOUND; } - status = pvfs_map_fileinfo(pvfs, req, name, info); + status = pvfs_map_fileinfo(pvfs, req, name, info, -1); return status; } @@ -228,7 +255,7 @@ NTSTATUS pvfs_qfileinfo(struct ntvfs_module_context *ntvfs, return status; } - status = pvfs_map_fileinfo(pvfs, req, f->name, info); + status = pvfs_map_fileinfo(pvfs, req, f->name, info, f->fd); /* a qfileinfo can fill in a bit more info than a qpathinfo - now modify the levels that need to be fixed up */ diff --git a/source4/ntvfs/posix/pvfs_setfileinfo.c b/source4/ntvfs/posix/pvfs_setfileinfo.c index fe489c2e69..e570743aba 100644 --- a/source4/ntvfs/posix/pvfs_setfileinfo.c +++ b/source4/ntvfs/posix/pvfs_setfileinfo.c @@ -23,6 +23,62 @@ #include "includes.h" #include "vfs_posix.h" #include "system/time.h" +#include "librpc/gen_ndr/ndr_xattr.h" + + +/* + add a single DOS EA +*/ +static NTSTATUS pvfs_setfileinfo_ea_set(struct pvfs_state *pvfs, + struct pvfs_filename *name, + int fd, struct ea_struct *ea) +{ + struct xattr_DosEAs *ealist = talloc_p(pvfs, struct xattr_DosEAs); + int i; + NTSTATUS status; + + if (!(pvfs->flags & PVFS_FLAG_XATTR_ENABLE)) { + return NT_STATUS_NOT_SUPPORTED; + } + + /* load the current list */ + status = pvfs_doseas_load(pvfs, name, fd, ealist); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + /* see if its already there */ + for (i=0;inum_eas;i++) { + if (StrCaseCmp(ealist->eas[i].name, ea->name.s) == 0) { + ealist->eas[i].value = ea->value; + goto save; + } + } + + /* add it */ + ealist->eas = talloc_realloc_p(ealist, ealist->eas, struct xattr_EA, ealist->num_eas+1); + if (ealist->eas == NULL) { + return NT_STATUS_NO_MEMORY; + } + ealist->eas[i].name = ea->name.s; + ealist->eas[i].value = ea->value; + ealist->num_eas++; + +save: + status = pvfs_doseas_save(pvfs, name, fd, ealist); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + name->dos.ea_size = 4; + for (i=0;inum_eas;i++) { + name->dos.ea_size += 4 + strlen(ealist->eas[i].name)+1 + + ealist->eas[i].value.length; + } + + /* update the ea_size attrib */ + return pvfs_dosattrib_save(pvfs, name, fd); +} /* set info on a open file @@ -77,6 +133,9 @@ NTSTATUS pvfs_setfileinfo(struct ntvfs_module_context *ntvfs, } break; + case RAW_SFILEINFO_EA_SET: + return pvfs_setfileinfo_ea_set(pvfs, f->name, f->fd, &info->ea_set.in.ea); + case RAW_SFILEINFO_BASIC_INFO: case RAW_SFILEINFO_BASIC_INFORMATION: if (info->basic_info.in.create_time) { @@ -165,13 +224,7 @@ 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; + return pvfs_dosattrib_save(pvfs, f->name, f->fd); } @@ -227,6 +280,9 @@ NTSTATUS pvfs_setpathinfo(struct ntvfs_module_context *ntvfs, } break; + case RAW_SFILEINFO_EA_SET: + return pvfs_setfileinfo_ea_set(pvfs, name, -1, &info->ea_set.in.ea); + case RAW_SFILEINFO_BASIC_INFO: case RAW_SFILEINFO_BASIC_INFORMATION: if (info->basic_info.in.create_time) { @@ -296,12 +352,6 @@ 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; + return pvfs_dosattrib_save(pvfs, name, -1); } diff --git a/source4/ntvfs/posix/pvfs_xattr.c b/source4/ntvfs/posix/pvfs_xattr.c index 24fa49108a..e086a019ba 100644 --- a/source4/ntvfs/posix/pvfs_xattr.c +++ b/source4/ntvfs/posix/pvfs_xattr.c @@ -25,7 +25,6 @@ #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 */ @@ -36,6 +35,7 @@ static NTSTATUS pull_xattr_blob(TALLOC_CTX *mem_ctx, size_t estimated_size, DATA_BLOB *blob) { +#if HAVE_XATTR_SUPPORT int ret; *blob = data_blob_talloc(mem_ctx, NULL, estimated_size); @@ -67,17 +67,20 @@ again: blob->length = ret; return NT_STATUS_OK; +#else + return NT_STATUS_NOT_SUPPORTED; +#endif } /* 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, +static NTSTATUS push_xattr_blob(const char *attr_name, const char *fname, int fd, const DATA_BLOB *blob) { +#if HAVE_XATTR_SUPPORT int ret; if (fd != -1) { @@ -90,22 +93,74 @@ static NTSTATUS push_xattr_blob(TALLOC_CTX *mem_ctx, } return NT_STATUS_OK; +#else + return NT_STATUS_NOT_SUPPORTED; +#endif } +/* + load a NDR structure from a xattr +*/ +static NTSTATUS pvfs_xattr_ndr_load(TALLOC_CTX *mem_ctx, + const char *fname, int fd, const char *attr_name, + void *p, ndr_pull_flags_fn_t pull_fn) +{ + NTSTATUS status; + DATA_BLOB blob; + + status = pull_xattr_blob(mem_ctx, attr_name, fname, + fd, XATTR_DOSATTRIB_ESTIMATED_SIZE, &blob); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + /* pull the blob */ + status = ndr_pull_struct_blob(&blob, mem_ctx, p, pull_fn); + + data_blob_free(&blob); + + return status; +} /* - fill in file attributes from extended attributes + save a NDR structure into a xattr */ -NTSTATUS pvfs_xattr_load(struct pvfs_state *pvfs, struct pvfs_filename *name, int fd) +static NTSTATUS pvfs_xattr_ndr_save(const char *fname, int fd, const char *attr_name, + void *p, ndr_push_flags_fn_t push_fn) { + TALLOC_CTX *mem_ctx = talloc(NULL, 0); DATA_BLOB blob; NTSTATUS status; + + status = ndr_push_struct_blob(&blob, mem_ctx, p, (ndr_push_flags_fn_t)push_fn); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(mem_ctx); + return status; + } + + status = push_xattr_blob(attr_name, fname, fd, &blob); + talloc_free(mem_ctx); + + return status; +} + + +/* + fill in file attributes from extended attributes +*/ +NTSTATUS pvfs_dosattrib_load(struct pvfs_state *pvfs, struct pvfs_filename *name, int fd) +{ + 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 (!(pvfs->flags & PVFS_FLAG_XATTR_ENABLE)) { + return NT_STATUS_OK; + } + + status = pvfs_xattr_ndr_load(mem_ctx, name->full_name, fd, XATTR_DOSATTRIB_NAME, + &attrib, (ndr_pull_flags_fn_t)ndr_pull_xattr_DosAttrib); /* if the filesystem doesn't support them, then tell pvfs not to try again */ if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) { @@ -126,14 +181,6 @@ NTSTATUS pvfs_xattr_load(struct pvfs_state *pvfs, struct pvfs_filename *name, in 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; @@ -163,15 +210,16 @@ NTSTATUS pvfs_xattr_load(struct pvfs_state *pvfs, struct pvfs_filename *name, in /* - save the file attribute into into the xattr + save the file attribute into the xattr */ -NTSTATUS pvfs_xattr_save(struct pvfs_state *pvfs, struct pvfs_filename *name, int fd) +NTSTATUS pvfs_dosattrib_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; + + if (!(pvfs->flags & PVFS_FLAG_XATTR_ENABLE)) { + return NT_STATUS_OK; + } attrib.version = 1; info1 = &attrib.info.info1; @@ -183,15 +231,39 @@ NTSTATUS pvfs_xattr_save(struct pvfs_state *pvfs, struct pvfs_filename *name, in 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; - } + return pvfs_xattr_ndr_save(name->full_name, fd, XATTR_DOSATTRIB_NAME, &attrib, + (ndr_push_flags_fn_t)ndr_push_xattr_DosAttrib); +} - status = push_xattr_blob(mem_ctx, XATTR_DOSATTRIB_NAME, name->full_name, fd, &blob); - talloc_free(mem_ctx); +/* + load the set of DOS EAs +*/ +NTSTATUS pvfs_doseas_load(struct pvfs_state *pvfs, struct pvfs_filename *name, int fd, + struct xattr_DosEAs *eas) +{ + NTSTATUS status; + ZERO_STRUCTP(eas); + if (!(pvfs->flags & PVFS_FLAG_XATTR_ENABLE)) { + return NT_STATUS_OK; + } + status = pvfs_xattr_ndr_load(eas, name->full_name, fd, XATTR_DOSEAS_NAME, + eas, (ndr_pull_flags_fn_t)ndr_pull_xattr_DosEAs); + if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) { + return NT_STATUS_OK; + } return status; } + +/* + save the set of DOS EAs +*/ +NTSTATUS pvfs_doseas_save(struct pvfs_state *pvfs, struct pvfs_filename *name, int fd, + struct xattr_DosEAs *eas) +{ + if (!(pvfs->flags & PVFS_FLAG_XATTR_ENABLE)) { + return NT_STATUS_OK; + } + return pvfs_xattr_ndr_save(name->full_name, fd, XATTR_DOSEAS_NAME, eas, + (ndr_push_flags_fn_t)ndr_push_xattr_DosEAs); +} -- cgit