summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source4/libcli/raw/rawfile.c133
-rw-r--r--source4/torture/raw/open.c176
2 files changed, 309 insertions, 0 deletions
diff --git a/source4/libcli/raw/rawfile.c b/source4/libcli/raw/rawfile.c
index 4da7ff3a9e..5fc40bc45a 100644
--- a/source4/libcli/raw/rawfile.c
+++ b/source4/libcli/raw/rawfile.c
@@ -22,6 +22,7 @@
#include "includes.h"
#include "libcli/raw/libcliraw.h"
+#include "librpc/gen_ndr/ndr_security.h"
#define SETUP_REQUEST(cmd, wct, buflen) do { \
req = smbcli_request_setup(tree, cmd, wct, buflen); \
@@ -213,6 +214,132 @@ NTSTATUS smb_raw_rmdir(struct smbcli_tree *tree,
}
+/*
+ Open a file using TRANSACT2_OPEN - async recv
+*/
+static NTSTATUS smb_raw_nttrans_create_recv(struct smbcli_request *req,
+ TALLOC_CTX *mem_ctx,
+ union smb_open *parms)
+{
+ NTSTATUS status;
+ struct smb_nttrans nt;
+ uint8_t *params;
+
+ status = smb_raw_nttrans_recv(req, mem_ctx, &nt);
+ if (!NT_STATUS_IS_OK(status)) return status;
+
+ if (nt.out.params.length < 69) {
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
+ params = nt.out.params.data;
+
+ parms->ntcreatex.out.oplock_level = CVAL(params, 0);
+ parms->ntcreatex.out.fnum = SVAL(params, 2);
+ parms->ntcreatex.out.create_action = IVAL(params, 4);
+ parms->ntcreatex.out.create_time = smbcli_pull_nttime(params, 12);
+ parms->ntcreatex.out.access_time = smbcli_pull_nttime(params, 20);
+ parms->ntcreatex.out.write_time = smbcli_pull_nttime(params, 28);
+ parms->ntcreatex.out.change_time = smbcli_pull_nttime(params, 36);
+ parms->ntcreatex.out.attrib = IVAL(params, 44);
+ parms->ntcreatex.out.alloc_size = BVAL(params, 48);
+ parms->ntcreatex.out.size = BVAL(params, 56);
+ parms->ntcreatex.out.file_type = SVAL(params, 64);
+ parms->ntcreatex.out.ipc_state = SVAL(params, 66);
+ parms->ntcreatex.out.is_directory = CVAL(params, 68);
+
+ return NT_STATUS_OK;
+}
+
+
+/*
+ Open a file using NTTRANS CREATE - async send
+*/
+static struct smbcli_request *smb_raw_nttrans_create_send(struct smbcli_tree *tree,
+ union smb_open *parms)
+{
+ struct smb_nttrans nt;
+ uint8_t *params;
+ TALLOC_CTX *mem_ctx = talloc(tree, 0);
+ uint16_t fname_len;
+ DATA_BLOB sd_blob, ea_blob;
+ struct smbcli_request *req;
+ NTSTATUS status;
+
+ nt.in.max_setup = 0;
+ nt.in.max_param = 101;
+ nt.in.max_data = 0;
+ nt.in.setup_count = 0;
+ nt.in.function = NT_TRANSACT_CREATE;
+ nt.in.setup = NULL;
+
+ sd_blob = data_blob(NULL, 0);
+ ea_blob = data_blob(NULL, 0);
+
+ if (parms->ntcreatex.in.sec_desc) {
+ status = ndr_push_struct_blob(&sd_blob, mem_ctx,
+ parms->ntcreatex.in.sec_desc,
+ (ndr_push_flags_fn_t)ndr_push_security_descriptor);
+ if (!NT_STATUS_IS_OK(status)) {
+ talloc_free(mem_ctx);
+ return NULL;
+ }
+ }
+
+ if (parms->ntcreatex.in.ea_list) {
+ uint32_t ea_size = ea_list_size(parms->ntcreatex.in.ea_list->num_eas,
+ parms->ntcreatex.in.ea_list->eas);
+ ea_blob = data_blob_talloc(mem_ctx, NULL, ea_size);
+ if (ea_blob.data == NULL) {
+ return NULL;
+ }
+ ea_put_list(ea_blob.data,
+ parms->ntcreatex.in.ea_list->num_eas,
+ parms->ntcreatex.in.ea_list->eas);
+ }
+
+ nt.in.params = data_blob_talloc(mem_ctx, NULL, 54);
+ if (nt.in.params.data == NULL) {
+ talloc_free(mem_ctx);
+ return NULL;
+ }
+
+ /* build the parameter section */
+ params = nt.in.params.data;
+
+ SIVAL(params, 0, parms->ntcreatex.in.flags);
+ SIVAL(params, 4, parms->ntcreatex.in.root_fid);
+ SIVAL(params, 8, parms->ntcreatex.in.access_mask);
+ SBVAL(params, 12, parms->ntcreatex.in.alloc_size);
+ SIVAL(params, 20, parms->ntcreatex.in.file_attr);
+ SIVAL(params, 24, parms->ntcreatex.in.share_access);
+ SIVAL(params, 28, parms->ntcreatex.in.open_disposition);
+ SIVAL(params, 32, parms->ntcreatex.in.create_options);
+ SIVAL(params, 36, sd_blob.length);
+ SIVAL(params, 40, ea_blob.length);
+ SIVAL(params, 48, parms->ntcreatex.in.impersonation);
+ SCVAL(params, 52, parms->ntcreatex.in.security_flags);
+ SCVAL(params, 53, 0);
+
+ fname_len = smbcli_blob_append_string(tree->session, mem_ctx, &nt.in.params,
+ parms->ntcreatex.in.fname, STR_TERMINATE);
+
+ SIVAL(nt.in.params.data, 44, fname_len);
+
+ /* build the data section */
+ nt.in.data = data_blob_talloc(mem_ctx, NULL, sd_blob.length + ea_blob.length);
+ memcpy(nt.in.data.data, sd_blob.data, sd_blob.length);
+ memcpy(nt.in.data.data+sd_blob.length, ea_blob.data, ea_blob.length);
+
+ /* send the request on its way */
+ req = smb_raw_nttrans_send(tree, &nt);
+
+ talloc_free(mem_ctx);
+
+ return req;
+}
+
+
/****************************************************************************
Open a file using TRANSACT2_OPEN - async send
****************************************************************************/
@@ -377,6 +504,9 @@ struct smbcli_request *smb_raw_open_send(struct smbcli_tree *tree, union smb_ope
smbcli_req_append_string_len(req, parms->ntcreatex.in.fname, STR_TERMINATE, &len);
SSVAL(req->out.vwv, 5, len);
break;
+
+ case RAW_OPEN_NTTRANS_CREATE:
+ return smb_raw_nttrans_create_send(tree, parms);
}
if (!smbcli_request_send(req)) {
@@ -469,6 +599,9 @@ NTSTATUS smb_raw_open_recv(struct smbcli_request *req, TALLOC_CTX *mem_ctx, unio
parms->ntcreatex.out.ipc_state = SVAL(req->in.vwv, 65);
parms->ntcreatex.out.is_directory = CVAL(req->in.vwv, 67);
break;
+
+ case RAW_OPEN_NTTRANS_CREATE:
+ return smb_raw_nttrans_create_recv(req, mem_ctx, parms);
}
failed:
diff --git a/source4/torture/raw/open.c b/source4/torture/raw/open.c
index b80f6278c6..f938c82cfb 100644
--- a/source4/torture/raw/open.c
+++ b/source4/torture/raw/open.c
@@ -752,6 +752,181 @@ done:
return ret;
}
+
+/*
+ test RAW_OPEN_NTTRANS_CREATE
+*/
+static BOOL test_nttrans_create(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
+{
+ union smb_open io;
+ union smb_fileinfo finfo;
+ const char *fname = BASEDIR "\\torture_ntcreatex.txt";
+ const char *dname = BASEDIR "\\torture_ntcreatex.dir";
+ NTSTATUS status;
+ int fnum = -1;
+ BOOL ret = True;
+ int i;
+ struct {
+ uint32_t open_disp;
+ BOOL with_file;
+ NTSTATUS correct_status;
+ } open_funcs[] = {
+ { NTCREATEX_DISP_SUPERSEDE, True, NT_STATUS_OK },
+ { NTCREATEX_DISP_SUPERSEDE, False, NT_STATUS_OK },
+ { NTCREATEX_DISP_OPEN, True, NT_STATUS_OK },
+ { NTCREATEX_DISP_OPEN, False, NT_STATUS_OBJECT_NAME_NOT_FOUND },
+ { NTCREATEX_DISP_CREATE, True, NT_STATUS_OBJECT_NAME_COLLISION },
+ { NTCREATEX_DISP_CREATE, False, NT_STATUS_OK },
+ { NTCREATEX_DISP_OPEN_IF, True, NT_STATUS_OK },
+ { NTCREATEX_DISP_OPEN_IF, False, NT_STATUS_OK },
+ { NTCREATEX_DISP_OVERWRITE, True, NT_STATUS_OK },
+ { NTCREATEX_DISP_OVERWRITE, False, NT_STATUS_OBJECT_NAME_NOT_FOUND },
+ { NTCREATEX_DISP_OVERWRITE_IF, True, NT_STATUS_OK },
+ { NTCREATEX_DISP_OVERWRITE_IF, False, NT_STATUS_OK },
+ { 6, True, NT_STATUS_INVALID_PARAMETER },
+ { 6, False, NT_STATUS_INVALID_PARAMETER },
+ };
+
+ printf("Checking RAW_OPEN_NTTRANS_CREATE\n");
+
+ /* reasonable default parameters */
+ io.generic.level = RAW_OPEN_NTTRANS_CREATE;
+ io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED;
+ io.ntcreatex.in.root_fid = 0;
+ io.ntcreatex.in.access_mask = GENERIC_RIGHTS_FILE_ALL_ACCESS;
+ io.ntcreatex.in.alloc_size = 1024*1024;
+ io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
+ io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
+ io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
+ io.ntcreatex.in.create_options = 0;
+ io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
+ io.ntcreatex.in.security_flags = 0;
+ io.ntcreatex.in.fname = fname;
+ io.ntcreatex.in.sec_desc = NULL;
+ io.ntcreatex.in.ea_list = NULL;
+
+ /* test the open disposition */
+ for (i=0; i<ARRAY_SIZE(open_funcs); i++) {
+ if (open_funcs[i].with_file) {
+ fnum = smbcli_open(cli->tree, fname, O_CREAT|O_RDWR|O_TRUNC, DENY_NONE);
+ if (fnum == -1) {
+ d_printf("Failed to create file %s - %s\n", fname, smbcli_errstr(cli->tree));
+ ret = False;
+ goto done;
+ }
+ smbcli_close(cli->tree, fnum);
+ }
+ io.ntcreatex.in.open_disposition = open_funcs[i].open_disp;
+ status = smb_raw_open(cli->tree, mem_ctx, &io);
+ if (!NT_STATUS_EQUAL(status, open_funcs[i].correct_status)) {
+ printf("(%s) incorrect status %s should be %s (i=%d with_file=%d open_disp=%d)\n",
+ __location__, nt_errstr(status), nt_errstr(open_funcs[i].correct_status),
+ i, (int)open_funcs[i].with_file, (int)open_funcs[i].open_disp);
+ ret = False;
+ }
+ if (NT_STATUS_IS_OK(status) || open_funcs[i].with_file) {
+ smbcli_close(cli->tree, io.ntcreatex.out.fnum);
+ smbcli_unlink(cli->tree, fname);
+ }
+ }
+
+ /* basic field testing */
+ io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
+
+ status = smb_raw_open(cli->tree, mem_ctx, &io);
+ CHECK_STATUS(status, NT_STATUS_OK);
+ fnum = io.ntcreatex.out.fnum;
+
+ CHECK_VAL(io.ntcreatex.out.oplock_level, 0);
+ CHECK_VAL(io.ntcreatex.out.create_action, NTCREATEX_ACTION_CREATED);
+ CHECK_NTTIME(io.ntcreatex.out.create_time, create_time);
+ CHECK_NTTIME(io.ntcreatex.out.access_time, access_time);
+ CHECK_NTTIME(io.ntcreatex.out.write_time, write_time);
+ CHECK_NTTIME(io.ntcreatex.out.change_time, change_time);
+ CHECK_ALL_INFO(io.ntcreatex.out.attrib, attrib);
+ CHECK_ALL_INFO(io.ntcreatex.out.alloc_size, alloc_size);
+ CHECK_ALL_INFO(io.ntcreatex.out.size, size);
+ CHECK_ALL_INFO(io.ntcreatex.out.is_directory, directory);
+ CHECK_VAL(io.ntcreatex.out.file_type, FILE_TYPE_DISK);
+
+ /* check fields when the file already existed */
+ smbcli_close(cli->tree, fnum);
+ smbcli_unlink(cli->tree, fname);
+ fnum = create_complex_file(cli, mem_ctx, fname);
+ if (fnum == -1) {
+ ret = False;
+ goto done;
+ }
+ smbcli_close(cli->tree, fnum);
+
+ io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
+ status = smb_raw_open(cli->tree, mem_ctx, &io);
+ CHECK_STATUS(status, NT_STATUS_OK);
+ fnum = io.ntcreatex.out.fnum;
+
+ CHECK_VAL(io.ntcreatex.out.oplock_level, 0);
+ CHECK_VAL(io.ntcreatex.out.create_action, NTCREATEX_ACTION_EXISTED);
+ CHECK_NTTIME(io.ntcreatex.out.create_time, create_time);
+ CHECK_NTTIME(io.ntcreatex.out.access_time, access_time);
+ CHECK_NTTIME(io.ntcreatex.out.write_time, write_time);
+ CHECK_NTTIME(io.ntcreatex.out.change_time, change_time);
+ CHECK_ALL_INFO(io.ntcreatex.out.attrib, attrib);
+ CHECK_ALL_INFO(io.ntcreatex.out.alloc_size, alloc_size);
+ CHECK_ALL_INFO(io.ntcreatex.out.size, size);
+ CHECK_ALL_INFO(io.ntcreatex.out.is_directory, directory);
+ CHECK_VAL(io.ntcreatex.out.file_type, FILE_TYPE_DISK);
+ smbcli_close(cli->tree, fnum);
+ smbcli_unlink(cli->tree, fname);
+
+
+ /* create a directory */
+ io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
+ io.ntcreatex.in.access_mask = GENERIC_RIGHTS_FILE_ALL_ACCESS;
+ io.ntcreatex.in.alloc_size = 0;
+ io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_DIRECTORY;
+ io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
+ io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
+ io.ntcreatex.in.create_options = 0;
+ io.ntcreatex.in.fname = dname;
+ fname = dname;
+
+ smbcli_rmdir(cli->tree, fname);
+ smbcli_unlink(cli->tree, fname);
+
+ io.ntcreatex.in.access_mask = SEC_RIGHT_MAXIMUM_ALLOWED;
+ io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
+ io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
+ io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
+ status = smb_raw_open(cli->tree, mem_ctx, &io);
+ CHECK_STATUS(status, NT_STATUS_OK);
+ fnum = io.ntcreatex.out.fnum;
+
+ CHECK_VAL(io.ntcreatex.out.oplock_level, 0);
+ CHECK_VAL(io.ntcreatex.out.create_action, NTCREATEX_ACTION_CREATED);
+ CHECK_NTTIME(io.ntcreatex.out.create_time, create_time);
+ CHECK_NTTIME(io.ntcreatex.out.access_time, access_time);
+ CHECK_NTTIME(io.ntcreatex.out.write_time, write_time);
+ CHECK_NTTIME(io.ntcreatex.out.change_time, change_time);
+ CHECK_ALL_INFO(io.ntcreatex.out.attrib, attrib);
+ CHECK_VAL(io.ntcreatex.out.attrib & ~FILE_ATTRIBUTE_NONINDEXED,
+ FILE_ATTRIBUTE_DIRECTORY);
+ CHECK_ALL_INFO(io.ntcreatex.out.alloc_size, alloc_size);
+ CHECK_ALL_INFO(io.ntcreatex.out.size, size);
+ CHECK_ALL_INFO(io.ntcreatex.out.is_directory, directory);
+ CHECK_VAL(io.ntcreatex.out.is_directory, 1);
+ CHECK_VAL(io.ntcreatex.out.size, 0);
+ CHECK_VAL(io.ntcreatex.out.alloc_size, 0);
+ CHECK_VAL(io.ntcreatex.out.file_type, FILE_TYPE_DISK);
+ smbcli_unlink(cli->tree, fname);
+
+
+done:
+ smbcli_close(cli->tree, fnum);
+ smbcli_unlink(cli->tree, fname);
+
+ return ret;
+}
+
/*
test RAW_OPEN_NTCREATEX with an already opened and byte range locked file
@@ -1001,6 +1176,7 @@ BOOL torture_raw_open(void)
ret &= test_open(cli, mem_ctx);
ret &= test_openx(cli, mem_ctx);
ret &= test_ntcreatex(cli, mem_ctx);
+ ret &= test_nttrans_create(cli, mem_ctx);
ret &= test_t2open(cli, mem_ctx);
ret &= test_mknew(cli, mem_ctx);
ret &= test_create(cli, mem_ctx);