Commit 6e3650ed authored by Volker Lendecke's avatar Volker Lendecke Committed by Jeremy Allison

torture: Add buffercheck tests

Make sure we get the smb2 infolevel fixed portions right

I could not find correct #defines for the infolevels

Bug: https://bugzilla.samba.org/show_bug.cgi?id=10106Signed-off-by: default avatarVolker Lendecke <vl@samba.org>
Reviewed-by: default avatarJeremy Allison <jra@samba.org>

Autobuild-User(master): Jeremy Allison <jra@samba.org>
Autobuild-Date(master): Thu Aug 29 01:27:11 CEST 2013 on sn-devel-104
parent 1b1935b8
......@@ -171,6 +171,9 @@
^samba4.smb2.oplock.batch20\(.*\)$ # samba 4 oplocks are a mess
^samba4.smb2.oplock.stream1 # samba 4 oplocks are a mess
^samba4.smb2.getinfo.complex # streams on directories does not work
^samba4.smb2.getinfo.qfs_buffercheck # S4 does not do the INFO_LENGTH_MISMATCH/BUFFER_OVERFLOW thingy
^samba4.smb2.getinfo.qfile_buffercheck # S4 does not do the INFO_LENGTH_MISMATCH/BUFFER_OVERFLOW thingy
^samba4.smb2.getinfo.qsec_buffercheck # S4 does not do the BUFFER_TOO_SMALL thingy
^samba4.ntvfs.cifs.krb5.base.createx_access.createx_access\(.*\)$
^samba4.rpc.lsa.forest.trust #Not fully provided by Samba4
^samba4.blackbox.kinit\(.*\).kinit with user password for expired password\(.*\) # We need to work out why this fails only during the pw change
......
......@@ -22,9 +22,11 @@
#include "includes.h"
#include "libcli/smb2/smb2.h"
#include "libcli/smb2/smb2_calls.h"
#include "libcli/smb/smbXcli_base.h"
#include "torture/torture.h"
#include "torture/smb2/proto.h"
#include "torture/util.h"
static struct {
const char *name;
......@@ -154,41 +156,243 @@ static bool torture_smb2_fsinfo(struct torture_context *tctx)
return true;
}
static bool torture_smb2_buffercheck_err(struct torture_context *tctx,
struct smb2_tree *tree,
struct smb2_getinfo *b,
size_t fixed,
DATA_BLOB full)
{
size_t i;
/*
test for buffer size handling
*/
static bool torture_smb2_buffercheck(struct torture_context *tctx)
for (i=0; i<=full.length; i++) {
NTSTATUS status;
b->in.output_buffer_length = i;
status = smb2_getinfo(tree, tree, b);
if (i < fixed) {
torture_assert_ntstatus_equal(
tctx, status, NT_STATUS_INFO_LENGTH_MISMATCH,
"Wrong error code small buffer");
continue;
}
if (i<full.length) {
torture_assert_ntstatus_equal(
tctx, status, STATUS_BUFFER_OVERFLOW,
"Wrong error code for large buffer");
/*
* TODO: compare the output buffer. That seems a bit
* difficult, because for level 5 for example the
* label length is adjusted to what is there. And some
* reserved fields seem to be not initialized to 0.
*/
TALLOC_FREE(b->out.blob.data);
continue;
}
torture_assert_ntstatus_equal(
tctx, status, NT_STATUS_OK,
"Wrong error code for right sized buffer");
}
return true;
}
struct level_buffersize {
int level;
size_t fixed;
};
static bool torture_smb2_qfs_buffercheck(struct torture_context *tctx)
{
bool ret;
struct smb2_tree *tree;
NTSTATUS status;
struct smb2_handle handle;
struct smb2_getinfo b;
int i;
struct level_buffersize levels[] = {
{ 1, 24 }, /* We don't have proper defines here */
{ 3, 24 },
{ 4, 8 },
{ 5, 16 },
{ 6, 48 },
{ 7, 32 },
{ 11, 28 },
};
printf("Testing buffer size handling\n");
printf("Testing SMB2_GETINFO_FS buffer sizes\n");
ret = torture_smb2_connection(tctx, &tree);
torture_assert(tctx, ret, "connection failed");
status = smb2_util_roothandle(tree, &handle);
torture_assert_ntstatus_ok(tctx, status, "Unable to create root handle");
torture_assert_ntstatus_ok(
tctx, status, "Unable to create root handle");
for (i=0; i<ARRAY_SIZE(levels); i++) {
struct smb2_getinfo b;
if (TARGET_IS_SAMBA3(tctx) &&
((levels[i].level == 6) || (levels[i].level == 11))) {
continue;
}
ZERO_STRUCT(b);
b.in.info_type = SMB2_GETINFO_FS;
b.in.info_class = levels[i].level;
b.in.file.handle = handle;
b.in.output_buffer_length = 65535;
status = smb2_getinfo(tree, tree, &b);
torture_assert_ntstatus_equal(
tctx, status, NT_STATUS_OK,
"Wrong error code for large buffer");
ret = torture_smb2_buffercheck_err(
tctx, tree, &b, levels[i].fixed, b.out.blob);
if (!ret) {
return ret;
}
}
return true;
}
static bool torture_smb2_qfile_buffercheck(struct torture_context *tctx)
{
bool ret;
struct smb2_tree *tree;
struct smb2_create c;
NTSTATUS status;
struct smb2_handle handle;
int i;
struct level_buffersize levels[] = {
{ 4, 40 },
{ 5, 24 },
{ 6, 8 },
{ 7, 4 },
{ 8, 4 },
{ 16, 4 },
{ 17, 4 },
{ 18, 104 },
{ 21, 8 },
{ 22, 32 },
{ 28, 16 },
{ 34, 56 },
{ 35, 8 },
};
printf("Testing SMB2_GETINFO_FILE buffer sizes\n");
ret = torture_smb2_connection(tctx, &tree);
torture_assert(tctx, ret, "connection failed");
ZERO_STRUCT(c);
c.in.desired_access = SEC_FLAG_MAXIMUM_ALLOWED;
c.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
c.in.create_disposition = NTCREATEX_DISP_OVERWRITE_IF;
c.in.share_access =
NTCREATEX_SHARE_ACCESS_DELETE|
NTCREATEX_SHARE_ACCESS_READ|
NTCREATEX_SHARE_ACCESS_WRITE;
c.in.create_options = 0;
c.in.fname = "bufsize.txt";
c.in.eas.num_eas = 2;
c.in.eas.eas = talloc_array(tree, struct ea_struct, 2);
c.in.eas.eas[0].flags = 0;
c.in.eas.eas[0].name.s = "EAONE";
c.in.eas.eas[0].value = data_blob_talloc(c.in.eas.eas, "VALUE1", 6);
c.in.eas.eas[1].flags = 0;
c.in.eas.eas[1].name.s = "SECONDEA";
c.in.eas.eas[1].value = data_blob_talloc(c.in.eas.eas, "ValueTwo", 8);
status = smb2_create(tree, tree, &c);
torture_assert_ntstatus_ok(
tctx, status, "Unable to create test file");
handle = c.out.file.handle;
for (i=0; i<ARRAY_SIZE(levels); i++) {
struct smb2_getinfo b;
ZERO_STRUCT(b);
b.in.info_type = SMB2_GETINFO_FILE;
b.in.info_class = levels[i].level;
b.in.file.handle = handle;
b.in.output_buffer_length = 65535;
status = smb2_getinfo(tree, tree, &b);
torture_assert_ntstatus_equal(
tctx, status, NT_STATUS_OK,
"Wrong error code for large buffer");
ret = torture_smb2_buffercheck_err(
tctx, tree, &b, levels[i].fixed, b.out.blob);
if (!ret) {
return ret;
}
}
return true;
}
static bool torture_smb2_qsec_buffercheck(struct torture_context *tctx)
{
struct smb2_getinfo b;
bool ret;
struct smb2_tree *tree;
struct smb2_create c;
NTSTATUS status;
struct smb2_handle handle;
int i;
printf("Testing SMB2_GETINFO_SECURITY buffer sizes\n");
ret = torture_smb2_connection(tctx, &tree);
torture_assert(tctx, ret, "connection failed");
ZERO_STRUCT(c);
c.in.oplock_level = 0;
c.in.desired_access = SEC_STD_SYNCHRONIZE | SEC_DIR_READ_ATTRIBUTE |
SEC_DIR_LIST | SEC_STD_READ_CONTROL;
c.in.file_attributes = 0;
c.in.create_disposition = NTCREATEX_DISP_OPEN;
c.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
NTCREATEX_SHARE_ACCESS_DELETE;
c.in.create_options = NTCREATEX_OPTIONS_ASYNC_ALERT;
c.in.fname = "";
status = smb2_create(tree, tree, &c);
torture_assert_ntstatus_ok(
tctx, status, "Unable to create root handle");
handle = c.out.file.handle;
ZERO_STRUCT(b);
b.in.info_type = SMB2_GETINFO_FS;
b.in.info_class = 1;
b.in.output_buffer_length = 0x1;
b.in.input_buffer_length = 0;
b.in.file.handle = handle;
b.in.info_type = SMB2_GETINFO_SECURITY;
b.in.info_class = 0;
b.in.file.handle = handle;
b.in.output_buffer_length = 0;
status = smb2_getinfo(tree, tree, &b);
torture_assert_ntstatus_equal(tctx, status,
NT_STATUS_INFO_LENGTH_MISMATCH,
"Wrong error code for small buffer");
torture_assert_ntstatus_equal(
tctx, status, NT_STATUS_BUFFER_TOO_SMALL,
"Wrong error code for large buffer");
b.in.output_buffer_length = 1;
status = smb2_getinfo(tree, tree, &b);
torture_assert_ntstatus_equal(
tctx, status, NT_STATUS_BUFFER_TOO_SMALL,
"Wrong error code for large buffer");
return true;
}
/* basic testing of all SMB2 getinfo levels
*/
static bool torture_smb2_getinfo(struct torture_context *torture)
......@@ -231,7 +435,11 @@ struct torture_suite *torture_smb2_getinfo_init(void)
torture_suite_add_simple_test(suite, "complex", torture_smb2_getinfo);
torture_suite_add_simple_test(suite, "fsinfo", torture_smb2_fsinfo);
torture_suite_add_simple_test(suite, "buffercheck",
torture_smb2_buffercheck);
torture_suite_add_simple_test(suite, "qfs_buffercheck",
torture_smb2_qfs_buffercheck);
torture_suite_add_simple_test(suite, "qfile_buffercheck",
torture_smb2_qfile_buffercheck);
torture_suite_add_simple_test(suite, "qsec_buffercheck",
torture_smb2_qsec_buffercheck);
return suite;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment