summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source4/libcli/raw/rawfile.c4
-rw-r--r--source4/ntvfs/posix/pvfs_mkdir.c52
-rw-r--r--source4/smb_server/trans2.c43
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 */