mirror of
https://github.com/samba-team/samba.git
synced 2025-01-11 05:18:09 +03:00
r3821: added client side code and test code for NTTRANS_CREATE
(This used to be commit 8422789c06
)
This commit is contained in:
parent
856ee66537
commit
5efd740d4d
@ -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:
|
||||
|
@ -745,6 +745,181 @@ static BOOL test_ntcreatex(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
|
||||
smbcli_unlink(cli->tree, fname);
|
||||
|
||||
|
||||
done:
|
||||
smbcli_close(cli->tree, fnum);
|
||||
smbcli_unlink(cli->tree, fname);
|
||||
|
||||
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);
|
||||
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user