diff options
author | Andrew Tridgell <tridge@samba.org> | 2004-12-17 04:51:23 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 13:07:28 -0500 |
commit | 3b8e83a8c8f32ca658841f1fae344399a48d66a4 (patch) | |
tree | febc6b07ebea32366b3ecc8f7b4862f7294e6798 /source4/ntvfs | |
parent | 50005129ab0a5c5f2422460e6d7c19616e5e1124 (diff) | |
download | samba-3b8e83a8c8f32ca658841f1fae344399a48d66a4.tar.gz samba-3b8e83a8c8f32ca658841f1fae344399a48d66a4.tar.xz samba-3b8e83a8c8f32ca658841f1fae344399a48d66a4.zip |
r4243: a sniff from kukks showed that the ea_set interface in trans2 setfileinfo allows
for multiple EAs to be set at once. This fixes all the ea code to allow for that.
(This used to be commit b26828bef5d55e5eef0e34a164e76292df45e207)
Diffstat (limited to 'source4/ntvfs')
-rw-r--r-- | source4/ntvfs/posix/pvfs_mkdir.c | 18 | ||||
-rw-r--r-- | source4/ntvfs/posix/pvfs_open.c | 21 | ||||
-rw-r--r-- | source4/ntvfs/posix/pvfs_setfileinfo.c | 54 |
3 files changed, 58 insertions, 35 deletions
diff --git a/source4/ntvfs/posix/pvfs_mkdir.c b/source4/ntvfs/posix/pvfs_mkdir.c index b43e67faed1..549f4b9780c 100644 --- a/source4/ntvfs/posix/pvfs_mkdir.c +++ b/source4/ntvfs/posix/pvfs_mkdir.c @@ -32,7 +32,6 @@ static NTSTATUS pvfs_t2mkdir(struct pvfs_state *pvfs, NTSTATUS status; struct pvfs_filename *name; mode_t mode; - int i; /* resolve the cifs name to a posix name */ status = pvfs_resolve_name(pvfs, req, md->t2mkdir.in.path, 0, &name); @@ -60,12 +59,12 @@ static NTSTATUS pvfs_t2mkdir(struct pvfs_state *pvfs, } /* setup any EAs that were asked for */ - for (i=0;i<md->t2mkdir.in.num_eas;i++) { - status = pvfs_setfileinfo_ea_set(pvfs, name, -1, &md->t2mkdir.in.eas[i]); - if (!NT_STATUS_IS_OK(status)) { - rmdir(name->full_name); - return status; - } + status = pvfs_setfileinfo_ea_set(pvfs, name, -1, + md->t2mkdir.in.num_eas, + md->t2mkdir.in.eas); + if (!NT_STATUS_IS_OK(status)) { + rmdir(name->full_name); + return status; } return NT_STATUS_OK; @@ -129,6 +128,11 @@ NTSTATUS pvfs_rmdir(struct ntvfs_module_context *ntvfs, return NT_STATUS_OBJECT_NAME_NOT_FOUND; } + status = pvfs_xattr_unlink_hook(pvfs, name->full_name); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + if (rmdir(name->full_name) == -1) { return pvfs_map_errno(pvfs, errno); } diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index e31d79b9e06..bd96b935adc 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -70,6 +70,11 @@ static int pvfs_dir_handle_destructor(void *p) struct pvfs_file_handle *h = p; if (h->create_options & NTCREATEX_OPTIONS_DELETE_ON_CLOSE) { + NTSTATUS status = pvfs_xattr_unlink_hook(h->pvfs, h->name->full_name); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0,("Warning: xattr rmdir hook failed for '%s' - %s\n", + h->name->full_name, nt_errstr(status))); + } if (rmdir(h->name->full_name) != 0) { DEBUG(0,("pvfs_close: failed to rmdir '%s' - %s\n", h->name->full_name, strerror(errno))); @@ -459,15 +464,13 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs, /* setup any EAs that were asked for */ if (io->ntcreatex.in.ea_list) { - int i; - for (i=0;i<io->ntcreatex.in.ea_list->num_eas;i++) { - status = pvfs_setfileinfo_ea_set(pvfs, name, fd, - &io->ntcreatex.in.ea_list->eas[i]); - if (!NT_STATUS_IS_OK(status)) { - idr_remove(pvfs->idtree_fnum, fnum); - close(fd); - return status; - } + status = pvfs_setfileinfo_ea_set(pvfs, name, fd, + io->ntcreatex.in.ea_list->num_eas, + io->ntcreatex.in.ea_list->eas); + if (!NT_STATUS_IS_OK(status)) { + idr_remove(pvfs->idtree_fnum, fnum); + close(fd); + return status; } } diff --git a/source4/ntvfs/posix/pvfs_setfileinfo.c b/source4/ntvfs/posix/pvfs_setfileinfo.c index c43ef5c40a7..2a06def2b47 100644 --- a/source4/ntvfs/posix/pvfs_setfileinfo.c +++ b/source4/ntvfs/posix/pvfs_setfileinfo.c @@ -115,40 +115,53 @@ static NTSTATUS pvfs_setfileinfo_rename(struct pvfs_state *pvfs, */ NTSTATUS pvfs_setfileinfo_ea_set(struct pvfs_state *pvfs, struct pvfs_filename *name, - int fd, struct ea_struct *ea) + int fd, uint16_t num_eas, + struct ea_struct *eas) { - struct xattr_DosEAs *ealist = talloc_p(pvfs, struct xattr_DosEAs); - int i; + struct xattr_DosEAs *ealist; + int i, j; NTSTATUS status; + if (num_eas == 0) { + return NT_STATUS_OK; + } + if (!(pvfs->flags & PVFS_FLAG_XATTR_ENABLE)) { return NT_STATUS_NOT_SUPPORTED; } + ealist = talloc_p(name, struct xattr_DosEAs); + /* 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;i<ealist->num_eas;i++) { - if (StrCaseCmp(ealist->eas[i].name, ea->name.s) == 0) { - ealist->eas[i].value = ea->value; - goto save; + for (j=0;j<num_eas;j++) { + struct ea_struct *ea = &eas[j]; + /* see if its already there */ + for (i=0;i<ealist->num_eas;i++) { + if (StrCaseCmp(ealist->eas[i].name, ea->name.s) == 0) { + ealist->eas[i].value = ea->value; + break; + } } - } - /* 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; + if (i==ealist->num_eas) { + /* 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++; + } } - ealist->eas[i].name = ea->name.s; - ealist->eas[i].value = ea->value; - ealist->num_eas++; -save: /* pull out any null EAs */ for (i=0;i<ealist->num_eas;i++) { if (ealist->eas[i].value.length == 0) { @@ -233,7 +246,8 @@ NTSTATUS pvfs_setfileinfo(struct ntvfs_module_context *ntvfs, case RAW_SFILEINFO_EA_SET: return pvfs_setfileinfo_ea_set(pvfs, h->name, h->fd, - &info->ea_set.in.ea); + info->ea_set.in.num_eas, + info->ea_set.in.eas); case RAW_SFILEINFO_BASIC_INFO: case RAW_SFILEINFO_BASIC_INFORMATION: @@ -419,7 +433,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); + return pvfs_setfileinfo_ea_set(pvfs, name, -1, + info->ea_set.in.num_eas, + info->ea_set.in.eas); case RAW_SFILEINFO_BASIC_INFO: case RAW_SFILEINFO_BASIC_INFORMATION: |