summaryrefslogtreecommitdiff
path: root/source4
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>2004-12-17 04:51:23 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 13:07:28 -0500
commit3b8e83a8c8f32ca658841f1fae344399a48d66a4 (patch)
treefebc6b07ebea32366b3ecc8f7b4862f7294e6798 /source4
parent50005129ab0a5c5f2422460e6d7c19616e5e1124 (diff)
downloadsamba-3b8e83a8c8f32ca658841f1fae344399a48d66a4.tar.gz
samba-3b8e83a8c8f32ca658841f1fae344399a48d66a4.tar.bz2
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')
-rw-r--r--source4/include/smb_interfaces.h3
-rw-r--r--source4/libcli/raw/raweas.c4
-rw-r--r--source4/libcli/raw/rawsetfileinfo.c4
-rw-r--r--source4/ntvfs/posix/pvfs_mkdir.c18
-rw-r--r--source4/ntvfs/posix/pvfs_open.c21
-rw-r--r--source4/ntvfs/posix/pvfs_setfileinfo.c54
-rw-r--r--source4/smb_server/trans2.c18
-rw-r--r--source4/torture/gentest.c8
-rw-r--r--source4/torture/raw/eas.c42
-rw-r--r--source4/torture/torture_util.c19
10 files changed, 101 insertions, 90 deletions
diff --git a/source4/include/smb_interfaces.h b/source4/include/smb_interfaces.h
index 4ba8ea3442..d5e43633db 100644
--- a/source4/include/smb_interfaces.h
+++ b/source4/include/smb_interfaces.h
@@ -764,7 +764,8 @@ union smb_setfileinfo {
enum smb_setfileinfo_level level;
union setfileinfo_file file;
struct {
- struct ea_struct ea;
+ uint_t num_eas;
+ struct ea_struct *eas;
} in;
} ea_set;
diff --git a/source4/libcli/raw/raweas.c b/source4/libcli/raw/raweas.c
index 027705b381..14d4557995 100644
--- a/source4/libcli/raw/raweas.c
+++ b/source4/libcli/raw/raweas.c
@@ -147,8 +147,8 @@ uint_t ea_pull_struct(const DATA_BLOB *blob,
pull a ea_list from a buffer
*/
NTSTATUS ea_pull_list(const DATA_BLOB *blob,
- TALLOC_CTX *mem_ctx,
- uint_t *num_eas, struct ea_struct **eas)
+ TALLOC_CTX *mem_ctx,
+ uint_t *num_eas, struct ea_struct **eas)
{
int n;
uint32_t ea_size, ofs;
diff --git a/source4/libcli/raw/rawsetfileinfo.c b/source4/libcli/raw/rawsetfileinfo.c
index 76756971ae..9576bdf356 100644
--- a/source4/libcli/raw/rawsetfileinfo.c
+++ b/source4/libcli/raw/rawsetfileinfo.c
@@ -56,8 +56,8 @@ static BOOL smb_raw_setinfo_backend(struct smbcli_tree *tree,
return True;
case RAW_SFILEINFO_EA_SET:
- NEED_BLOB(ea_list_size(1, &parms->ea_set.in.ea));
- ea_put_list(blob->data, 1, &parms->ea_set.in.ea);
+ NEED_BLOB(ea_list_size(parms->ea_set.in.num_eas, parms->ea_set.in.eas));
+ ea_put_list(blob->data, parms->ea_set.in.num_eas, parms->ea_set.in.eas);
return True;
case RAW_SFILEINFO_BASIC_INFO:
diff --git a/source4/ntvfs/posix/pvfs_mkdir.c b/source4/ntvfs/posix/pvfs_mkdir.c
index b43e67faed..549f4b9780 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 e31d79b9e0..bd96b935ad 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 c43ef5c40a..2a06def2b4 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:
diff --git a/source4/smb_server/trans2.c b/source4/smb_server/trans2.c
index a8cad915f9..3ca9bafcfa 100644
--- a/source4/smb_server/trans2.c
+++ b/source4/smb_server/trans2.c
@@ -827,21 +827,9 @@ static NTSTATUS trans2_parse_sfileinfo(struct smbsrv_request *req,
return NT_STATUS_OK;
case RAW_SFILEINFO_EA_SET:
- CHECK_MIN_BLOB_SIZE(blob, 4);
- len = IVAL(blob->data, 0);
- if (len > blob->length || len < 4) {
- return NT_STATUS_INFO_LENGTH_MISMATCH;
- }
- {
- DATA_BLOB blob2;
- blob2.data = blob->data+4;
- blob2.length = len-4;
- len = ea_pull_struct(&blob2, req, &st->ea_set.in.ea);
- }
- if (len == 0) {
- return NT_STATUS_INVALID_PARAMETER;
- }
- return NT_STATUS_OK;
+ return ea_pull_list(blob, req,
+ &st->ea_set.in.num_eas,
+ &st->ea_set.in.eas);
case SMB_SFILEINFO_BASIC_INFO:
case SMB_SFILEINFO_BASIC_INFORMATION:
diff --git a/source4/torture/gentest.c b/source4/torture/gentest.c
index 6c2f9d37fa..01b4022d32 100644
--- a/source4/torture/gentest.c
+++ b/source4/torture/gentest.c
@@ -1685,8 +1685,12 @@ static void gen_setfileinfo(int instance, union smb_setfileinfo *info)
info->standard.in.access_time = gen_timet();
info->standard.in.write_time = gen_timet();
break;
- case RAW_SFILEINFO_EA_SET:
- info->ea_set.in.ea = gen_ea_struct();
+ case RAW_SFILEINFO_EA_SET: {
+ static struct ea_struct ea;
+ info->ea_set.in.num_eas = 1;
+ info->ea_set.in.eas = &ea;
+ info->ea_set.in.eas[0] = gen_ea_struct();
+ }
break;
case RAW_SFILEINFO_BASIC_INFO:
case RAW_SFILEINFO_BASIC_INFORMATION:
diff --git a/source4/torture/raw/eas.c b/source4/torture/raw/eas.c
index 00c2fac74a..572a551d17 100644
--- a/source4/torture/raw/eas.c
+++ b/source4/torture/raw/eas.c
@@ -80,30 +80,28 @@ static BOOL test_eas(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
ret &= check_ea(cli, fname, "EAONE", NULL);
- printf("Adding first EA\n");
+ printf("Adding first two EAs\n");
setfile.generic.level = RAW_SFILEINFO_EA_SET;
setfile.generic.file.fnum = fnum;
- setfile.ea_set.in.ea.flags = 0;
- setfile.ea_set.in.ea.name.s = "EAONE";
- setfile.ea_set.in.ea.value = data_blob_string_const("VALUE1");
+ setfile.ea_set.in.num_eas = 2;
+ setfile.ea_set.in.eas = talloc_array_p(mem_ctx, struct ea_struct, 2);
+ setfile.ea_set.in.eas[0].flags = 0;
+ setfile.ea_set.in.eas[0].name.s = "EAONE";
+ setfile.ea_set.in.eas[0].value = data_blob_string_const("VALUE1");
+ setfile.ea_set.in.eas[1].flags = 0;
+ setfile.ea_set.in.eas[1].name.s = "SECONDEA";
+ setfile.ea_set.in.eas[1].value = data_blob_string_const("ValueTwo");
status = smb_raw_setfileinfo(cli->tree, &setfile);
CHECK_STATUS(status, NT_STATUS_OK);
ret &= check_ea(cli, fname, "EAONE", "VALUE1");
-
- setfile.ea_set.in.ea.name.s = "SECONDEA";
- setfile.ea_set.in.ea.value = data_blob_string_const("ValueTwo");
-
- printf("Adding second EA\n");
- status = smb_raw_setfileinfo(cli->tree, &setfile);
- CHECK_STATUS(status, NT_STATUS_OK);
-
- ret &= check_ea(cli, fname, "EAONE", "VALUE1");
ret &= check_ea(cli, fname, "SECONDEA", "ValueTwo");
printf("Modifying 2nd EA\n");
- setfile.ea_set.in.ea.value = data_blob_string_const(" Changed Value");
+ setfile.ea_set.in.num_eas = 1;
+ setfile.ea_set.in.eas[0].name.s = "SECONDEA";
+ setfile.ea_set.in.eas[0].value = data_blob_string_const(" Changed Value");
status = smb_raw_setfileinfo(cli->tree, &setfile);
CHECK_STATUS(status, NT_STATUS_OK);
@@ -111,8 +109,8 @@ static BOOL test_eas(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
ret &= check_ea(cli, fname, "SECONDEA", " Changed Value");
printf("Setting a NULL EA\n");
- setfile.ea_set.in.ea.value = data_blob(NULL, 0);
- setfile.ea_set.in.ea.name.s = "NULLEA";
+ setfile.ea_set.in.eas[0].value = data_blob(NULL, 0);
+ setfile.ea_set.in.eas[0].name.s = "NULLEA";
status = smb_raw_setfileinfo(cli->tree, &setfile);
CHECK_STATUS(status, NT_STATUS_OK);
@@ -121,9 +119,9 @@ static BOOL test_eas(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
ret &= check_ea(cli, fname, "NULLEA", NULL);
printf("Deleting first EA\n");
- setfile.ea_set.in.ea.flags = 0;
- setfile.ea_set.in.ea.name.s = "EAONE";
- setfile.ea_set.in.ea.value = data_blob(NULL, 0);
+ setfile.ea_set.in.eas[0].flags = 0;
+ setfile.ea_set.in.eas[0].name.s = "EAONE";
+ setfile.ea_set.in.eas[0].value = data_blob(NULL, 0);
status = smb_raw_setfileinfo(cli->tree, &setfile);
CHECK_STATUS(status, NT_STATUS_OK);
@@ -131,9 +129,9 @@ static BOOL test_eas(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
ret &= check_ea(cli, fname, "SECONDEA", " Changed Value");
printf("Deleting second EA\n");
- setfile.ea_set.in.ea.flags = 0;
- setfile.ea_set.in.ea.name.s = "SECONDEA";
- setfile.ea_set.in.ea.value = data_blob(NULL, 0);
+ setfile.ea_set.in.eas[0].flags = 0;
+ setfile.ea_set.in.eas[0].name.s = "SECONDEA";
+ setfile.ea_set.in.eas[0].value = data_blob(NULL, 0);
status = smb_raw_setfileinfo(cli->tree, &setfile);
CHECK_STATUS(status, NT_STATUS_OK);
diff --git a/source4/torture/torture_util.c b/source4/torture/torture_util.c
index 05b06c6d0e..d96a285b6f 100644
--- a/source4/torture/torture_util.c
+++ b/source4/torture/torture_util.c
@@ -102,17 +102,14 @@ int create_complex_file(struct smbcli_state *cli, TALLOC_CTX *mem_ctx, const cha
/* setup some EAs */
setfile.generic.level = RAW_SFILEINFO_EA_SET;
setfile.generic.file.fnum = fnum;
- setfile.ea_set.in.ea.flags = 0;
- setfile.ea_set.in.ea.name.s = "EAONE";
- setfile.ea_set.in.ea.value = data_blob_talloc(mem_ctx, "VALUE1", 6);
-
- status = smb_raw_setfileinfo(cli->tree, &setfile);
- if (!NT_STATUS_IS_OK(status)) {
- printf("Failed to setup EAs\n");
- }
-
- setfile.ea_set.in.ea.name.s = "SECONDEA";
- setfile.ea_set.in.ea.value = data_blob_talloc(mem_ctx, "ValueTwo", 8);
+ setfile.ea_set.in.num_eas = 2;
+ setfile.ea_set.in.eas = talloc_array_p(mem_ctx, struct ea_struct, 2);
+ setfile.ea_set.in.eas[0].flags = 0;
+ setfile.ea_set.in.eas[0].name.s = "EAONE";
+ setfile.ea_set.in.eas[0].value = data_blob_talloc(mem_ctx, "VALUE1", 6);
+ setfile.ea_set.in.eas[1].flags = 0;
+ setfile.ea_set.in.eas[1].name.s = "SECONDEA";
+ setfile.ea_set.in.eas[1].value = data_blob_talloc(mem_ctx, "ValueTwo", 8);
status = smb_raw_setfileinfo(cli->tree, &setfile);
if (!NT_STATUS_IS_OK(status)) {
printf("Failed to setup EAs\n");