r4243: a sniff from kukks showed that the ea_set interface in trans2 setfileinfo...
authorAndrew Tridgell <tridge@samba.org>
Fri, 17 Dec 2004 04:51:23 +0000 (04:51 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 18:07:28 +0000 (13:07 -0500)
for multiple EAs to be set at once. This fixes all the ea code to allow for that.
(This used to be commit b26828bef5d55e5eef0e34a164e76292df45e207)

source4/include/smb_interfaces.h
source4/libcli/raw/raweas.c
source4/libcli/raw/rawsetfileinfo.c
source4/ntvfs/posix/pvfs_mkdir.c
source4/ntvfs/posix/pvfs_open.c
source4/ntvfs/posix/pvfs_setfileinfo.c
source4/smb_server/trans2.c
source4/torture/gentest.c
source4/torture/raw/eas.c
source4/torture/torture_util.c

index 4ba8ea3442954cb3312d59fad6ac51b158624d2f..d5e43633db2edae5575b456a04519dee44c980a9 100644 (file)
@@ -764,7 +764,8 @@ union smb_setfileinfo {
                enum smb_setfileinfo_level level;
                union setfileinfo_file file;
                struct {
                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;
 
                } in;
        } ea_set;
 
index 027705b381117d6eaade33148202c49c12638f30..14d4557995d8a5a994ca571eb273d58983d4bd20 100644 (file)
@@ -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, 
   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;
 {
        int n;
        uint32_t ea_size, ofs;
index 76756971ae45b96790c46c038832f985a051983f..9576bdf35626937f83230bf98ce7d1ce325c0765 100644 (file)
@@ -56,8 +56,8 @@ static BOOL smb_raw_setinfo_backend(struct smbcli_tree *tree,
                return True;
 
        case RAW_SFILEINFO_EA_SET:
                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:
                return True;
 
        case RAW_SFILEINFO_BASIC_INFO:
index b43e67faed13e2837bb4766c66f4c009055d9f74..549f4b9780cfeba55c76cb8117a55392b9bd9f12 100644 (file)
@@ -32,7 +32,6 @@ static NTSTATUS pvfs_t2mkdir(struct pvfs_state *pvfs,
        NTSTATUS status;
        struct pvfs_filename *name;
        mode_t mode;
        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);
 
        /* 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 */
        }
 
        /* 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;
        }
 
        return NT_STATUS_OK;
@@ -129,6 +128,11 @@ NTSTATUS pvfs_rmdir(struct ntvfs_module_context *ntvfs,
                return NT_STATUS_OBJECT_NAME_NOT_FOUND;
        }
 
                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);
        }
        if (rmdir(name->full_name) == -1) {
                return pvfs_map_errno(pvfs, errno);
        }
index e31d79b9e063b112fa57513f8332d49b491f5413..bd96b935adcc28f4e610e15dc2849da5a93b4397 100644 (file)
@@ -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) {
        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)));
                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) {
 
        /* 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;
                }
        }
 
                }
        }
 
index c43ef5c40a7c58a35707af8a1ce79da488a9941a..2a06def2b47198716168bdd433c73dc47c99c132 100644 (file)
@@ -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,
 */
 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;
 
        NTSTATUS status;
 
+       if (num_eas == 0) {
+               return NT_STATUS_OK;
+       }
+
        if (!(pvfs->flags & PVFS_FLAG_XATTR_ENABLE)) {
                return NT_STATUS_NOT_SUPPORTED;
        }
 
        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;
        }
 
        /* 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) {
        /* 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, 
 
        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:
 
        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:
                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:
 
        case RAW_SFILEINFO_BASIC_INFO:
        case RAW_SFILEINFO_BASIC_INFORMATION:
index a8cad915f909ccb9e948cf122e870d4b98e458df..3ca9bafcfa1d76c5e32dc3e83f75a838c908b0bd 100644 (file)
@@ -827,21 +827,9 @@ static NTSTATUS trans2_parse_sfileinfo(struct smbsrv_request *req,
                return NT_STATUS_OK;
 
        case RAW_SFILEINFO_EA_SET:
                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:
 
        case SMB_SFILEINFO_BASIC_INFO:
        case SMB_SFILEINFO_BASIC_INFORMATION:
index 6c2f9d37fa6f029beb39faf927f44da876e11d36..01b4022d324d37f0b7eee83ec60c2624eb98bec8 100644 (file)
@@ -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;
                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:
                break;
        case RAW_SFILEINFO_BASIC_INFO:
        case RAW_SFILEINFO_BASIC_INFORMATION:
index 00c2fac74aa6d93a0ee8d195dd865dcd98fe2e21..572a551d1762b75b06db0693244ff85e71daf81b 100644 (file)
@@ -80,30 +80,28 @@ static BOOL test_eas(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
        
        ret &= check_ea(cli, fname, "EAONE", NULL);
 
        
        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.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);
 
 
        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");
        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);
 
        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");
        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);
 
        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");
        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);
 
        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");
        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);
 
        status = smb_raw_setfileinfo(cli->tree, &setfile);
        CHECK_STATUS(status, NT_STATUS_OK);
 
index 05b06c6d0e842572fbbbb130a47cd9333af163c7..d96a285b6fb116e55cef048998bd02e631340b0a 100644 (file)
@@ -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;
        /* 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");
        status = smb_raw_setfileinfo(cli->tree, &setfile);
        if (!NT_STATUS_IS_OK(status)) {
                printf("Failed to setup EAs\n");