1
0
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:
Andrew Tridgell 2004-11-17 20:56:26 +00:00 committed by Gerald (Jerry) Carter
parent 856ee66537
commit 5efd740d4d
2 changed files with 309 additions and 0 deletions

View File

@ -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:

View File

@ -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);