diff options
-rw-r--r-- | source4/libcli/raw/rawfile.c | 4 | ||||
-rw-r--r-- | source4/ntvfs/posix/pvfs_mkdir.c | 52 | ||||
-rw-r--r-- | source4/smb_server/trans2.c | 43 |
3 files changed, 97 insertions, 2 deletions
diff --git a/source4/libcli/raw/rawfile.c b/source4/libcli/raw/rawfile.c index bfd96bd360..4a11fd3834 100644 --- a/source4/libcli/raw/rawfile.c +++ b/source4/libcli/raw/rawfile.c @@ -122,7 +122,7 @@ static struct smbcli_request *smb_raw_t2mkdir_send(struct smbcli_tree *tree, data_total = ea_list_size(parms->t2mkdir.in.num_eas, parms->t2mkdir.in.eas); - t2.in.max_param = 0; + t2.in.max_param = 2; t2.in.max_data = 0; t2.in.max_setup = 0; t2.in.flags = 0; @@ -135,7 +135,7 @@ static struct smbcli_request *smb_raw_t2mkdir_send(struct smbcli_tree *tree, SIVAL(t2.in.params.data, VWV(0), 0); /* reserved */ smbcli_blob_append_string(tree->session, mem_ctx, - &t2.in.params, parms->t2mkdir.in.path, 0); + &t2.in.params, parms->t2mkdir.in.path, STR_TERMINATE); ea_put_list(t2.in.data.data, parms->t2mkdir.in.num_eas, parms->t2mkdir.in.eas); diff --git a/source4/ntvfs/posix/pvfs_mkdir.c b/source4/ntvfs/posix/pvfs_mkdir.c index 1bc0fa569e..b43e67faed 100644 --- a/source4/ntvfs/posix/pvfs_mkdir.c +++ b/source4/ntvfs/posix/pvfs_mkdir.c @@ -24,6 +24,54 @@ #include "vfs_posix.h" /* + create a directory with EAs +*/ +static NTSTATUS pvfs_t2mkdir(struct pvfs_state *pvfs, + struct smbsrv_request *req, union smb_mkdir *md) +{ + 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); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + if (name->exists) { + return NT_STATUS_OBJECT_NAME_COLLISION; + } + + mode = pvfs_fileperms(pvfs, FILE_ATTRIBUTE_DIRECTORY); + + if (mkdir(name->full_name, mode) == -1) { + return pvfs_map_errno(pvfs, errno); + } + + status = pvfs_resolve_name(pvfs, req, md->t2mkdir.in.path, 0, &name); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + if (!name->exists || + !(name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY)) { + return NT_STATUS_INTERNAL_ERROR; + } + + /* 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; + } + } + + return NT_STATUS_OK; +} + +/* create a directory */ NTSTATUS pvfs_mkdir(struct ntvfs_module_context *ntvfs, @@ -34,6 +82,10 @@ NTSTATUS pvfs_mkdir(struct ntvfs_module_context *ntvfs, struct pvfs_filename *name; mode_t mode; + if (md->generic.level == RAW_MKDIR_T2MKDIR) { + return pvfs_t2mkdir(pvfs, req, md); + } + if (md->generic.level != RAW_MKDIR_MKDIR) { return NT_STATUS_INVALID_LEVEL; } diff --git a/source4/smb_server/trans2.c b/source4/smb_server/trans2.c index 8f995e2f6a..c3768d6ee0 100644 --- a/source4/smb_server/trans2.c +++ b/source4/smb_server/trans2.c @@ -464,6 +464,47 @@ static NTSTATUS trans2_open(struct smbsrv_request *req, struct smb_trans2 *trans return status; } + +/* + trans2 mkdir implementation +*/ +static NTSTATUS trans2_mkdir(struct smbsrv_request *req, struct smb_trans2 *trans) +{ + union smb_mkdir *io; + NTSTATUS status; + + /* make sure we got enough parameters */ + if (trans->in.params.length < 5) { + return NT_STATUS_FOOBAR; + } + + io = talloc_p(req, union smb_mkdir); + if (io == NULL) { + return NT_STATUS_NO_MEMORY; + } + + io->t2mkdir.level = RAW_MKDIR_T2MKDIR; + trans2_pull_blob_string(req, &trans->in.params, 4, &io->t2mkdir.in.path, 0); + + status = ea_pull_list(&trans->in.data, io, + &io->t2mkdir.in.num_eas, + &io->t2mkdir.in.eas); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + status = ntvfs_mkdir(req, io); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + trans2_setup_reply(req, trans, 2, 0, 0); + + SSVAL(trans->out.params.data, VWV(0), 0); + + return status; +} + /* fill in the reply from a qpathinfo or qfileinfo call */ @@ -1305,6 +1346,8 @@ static NTSTATUS trans2_backend(struct smbsrv_request *req, struct smb_trans2 *tr return trans2_qfsinfo(req, trans); case TRANSACT2_OPEN: return trans2_open(req, trans); + case TRANSACT2_MKDIR: + return trans2_mkdir(req, trans); } /* an unknown trans2 command */ |