1
0
mirror of https://github.com/samba-team/samba.git synced 2024-12-23 17:34:34 +03:00

Merge branch 'v4-0-test' of ssh://git.samba.org/data/git/samba into 4-0-local

(This used to be commit cd10b38176)
This commit is contained in:
Andrew Bartlett 2008-05-30 07:55:29 +10:00
commit 437ca06107
24 changed files with 1860 additions and 2784 deletions

View File

@ -271,7 +271,7 @@ AC_DEFUN([AC_LIBREPLACE_LD_SHLIB_ALLOW_UNDEF_FLAG],
LD_SHLIB_ALLOW_UNDEF_FLAG="-undefined dynamic_lookup"
;;
*aix*)
LD_SHLIB_ALLOW_UNDEF_FLAG="--Wl,-bnoentry"
LD_SHLIB_ALLOW_UNDEF_FLAG="-Wl,-bnoentry"
;;
esac

View File

@ -1354,7 +1354,7 @@ union smb_open {
break; \
} \
} while (0)
/* SMBNTCreateX interface */
/* SMBNTCreateX, nttrans and generic interface */
struct {
enum smb_open_level level;
struct {
@ -1377,6 +1377,9 @@ union smb_open {
NTTRANS varient of the call */
struct security_descriptor *sec_desc;
struct smb_ea_list *ea_list;
/* some optional parameters from the SMB2 varient */
bool query_maximal_access;
} in;
struct {
union smb_handle file;
@ -1392,6 +1395,10 @@ union smb_open {
uint16_t file_type;
uint16_t ipc_state;
uint8_t is_directory;
/* optional return values matching SMB2 tagged
values in the call */
uint32_t maximal_access;
} out;
} ntcreatex, nttrans, generic;

View File

@ -387,12 +387,13 @@ NTSTATUS smb2_create_recv(struct smb2_request *req, TALLOC_CTX *mem_ctx, struct
/* pull out the parsed blobs */
for (i=0;i<io->out.blobs.num_blobs;i++) {
if (strcmp(io->out.blobs.blobs[i].tag, SMB2_CREATE_TAG_MXAC) == 0) {
/* why 8 bytes not 4?? */
/* TODO: this also contains a status field in
first 4 bytes */
if (io->out.blobs.blobs[i].data.length != 8) {
smb2_request_destroy(req);
return NT_STATUS_INVALID_NETWORK_RESPONSE;
}
io->out.maximal_access = IVAL(io->out.blobs.blobs[i].data.data, 0);
io->out.maximal_access = IVAL(io->out.blobs.blobs[i].data.data, 4);
}
if (strcmp(io->out.blobs.blobs[i].tag, SMB2_CREATE_TAG_QFID) == 0) {
if (io->out.blobs.blobs[i].data.length != 32) {

View File

@ -233,6 +233,7 @@ static NTSTATUS ntvfs_map_open_finish(struct ntvfs_module_context *ntvfs,
io->smb2.out.size = io2->generic.out.size;
io->smb2.out.file_attr = io2->generic.out.attrib;
io->smb2.out.reserved2 = 0;
io->smb2.out.maximal_access = io2->generic.out.maximal_access;
break;
default:
@ -522,6 +523,7 @@ NTSTATUS ntvfs_map_open(struct ntvfs_module_context *ntvfs,
io2->generic.in.fname = io->smb2.in.fname;
io2->generic.in.sec_desc = io->smb2.in.sec_desc;
io2->generic.in.ea_list = &io->smb2.in.eas;
io2->generic.in.query_maximal_access = io->smb2.in.query_maximal_access;
/* we don't support timewarp yet */
if (io->smb2.in.timewarp != 0) {

View File

@ -464,7 +464,11 @@ NTSTATUS pvfs_access_check_unix(struct pvfs_state *pvfs,
return NT_STATUS_ACCESS_DENIED;
}
*access_mask |= SEC_FILE_READ_ATTRIBUTE;
if (pvfs->ntvfs->ctx->protocol != PROTOCOL_SMB2) {
/* on SMB, this bit is always granted, even if not
asked for */
*access_mask |= SEC_FILE_READ_ATTRIBUTE;
}
return NT_STATUS_OK;
}
@ -496,7 +500,9 @@ NTSTATUS pvfs_access_check(struct pvfs_state *pvfs,
/* expand the generic access bits to file specific bits */
*access_mask = pvfs_translate_mask(*access_mask);
*access_mask &= ~SEC_FILE_READ_ATTRIBUTE;
if (pvfs->ntvfs->ctx->protocol != PROTOCOL_SMB2) {
*access_mask &= ~SEC_FILE_READ_ATTRIBUTE;
}
status = pvfs_acl_load(pvfs, name, -1, acl);
if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
@ -518,8 +524,11 @@ NTSTATUS pvfs_access_check(struct pvfs_state *pvfs,
/* check the acl against the required access mask */
status = sec_access_check(sd, token, *access_mask, access_mask);
/* this bit is always granted, even if not asked for */
*access_mask |= SEC_FILE_READ_ATTRIBUTE;
if (pvfs->ntvfs->ctx->protocol != PROTOCOL_SMB2) {
/* on SMB, this bit is always granted, even if not
asked for */
*access_mask |= SEC_FILE_READ_ATTRIBUTE;
}
talloc_free(acl);
@ -800,3 +809,15 @@ NTSTATUS pvfs_acl_inherit(struct pvfs_state *pvfs,
return status;
}
/*
return the maximum allowed access mask
*/
NTSTATUS pvfs_access_maximal_allowed(struct pvfs_state *pvfs,
struct ntvfs_request *req,
struct pvfs_filename *name,
uint32_t *maximal_access)
{
*maximal_access = SEC_FLAG_MAXIMUM_ALLOWED;
return pvfs_access_check(pvfs, req, name, maximal_access);
}

View File

@ -73,7 +73,8 @@ NTSTATUS pvfs_ioctl(struct ntvfs_module_context *ntvfs,
case RAW_IOCTL_SMB2:
case RAW_IOCTL_SMB2_NO_HANDLE:
return NT_STATUS_FS_DRIVER_REQUIRED;
/* see WSPP SMB2 test 46 */
return NT_STATUS_INVALID_DEVICE_REQUEST;
}
return NT_STATUS_INVALID_LEVEL;

View File

@ -68,13 +68,8 @@ static void pvfs_lock_async_failed(struct pvfs_state *pvfs,
int i,
NTSTATUS status)
{
/* in SMB2 mode we also try to unlock failing lock */
if (req->ctx->protocol != PROTOCOL_SMB2) {
i--;
}
/* undo the locks we just did */
for (;i>=0;i--) {
for (i--;i>=0;i--) {
brl_unlock(pvfs->brl_context,
f->brl_handle,
locks[i].pid,
@ -390,12 +385,9 @@ NTSTATUS pvfs_lock(struct ntvfs_module_context *ntvfs,
DLIST_ADD(f->pending_list, pending);
return NT_STATUS_OK;
}
/* in SMB2 mode we also try to unlock failing lock */
if (req->ctx->protocol != PROTOCOL_SMB2) {
i--;
}
/* undo the locks we just did */
for (;i>=0;i--) {
for (i--;i>=0;i--) {
brl_unlock(pvfs->brl_context,
f->brl_handle,
locks[i].pid,

View File

@ -252,8 +252,12 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs,
} else {
status = pvfs_access_check_create(pvfs, req, name, &access_mask);
}
if (!NT_STATUS_IS_OK(status)) {
return status;
NT_STATUS_NOT_OK_RETURN(status);
if (io->generic.in.query_maximal_access) {
status = pvfs_access_maximal_allowed(pvfs, req, name,
&io->generic.out.maximal_access);
NT_STATUS_NOT_OK_RETURN(status);
}
f->ntvfs = h;
@ -578,6 +582,12 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs,
status = pvfs_access_check_create(pvfs, req, name, &access_mask);
NT_STATUS_NOT_OK_RETURN(status);
if (io->generic.in.query_maximal_access) {
status = pvfs_access_maximal_allowed(pvfs, req, name,
&io->generic.out.maximal_access);
NT_STATUS_NOT_OK_RETURN(status);
}
/* check that the parent isn't opened with delete on close set */
status = pvfs_resolve_parent(pvfs, req, name, &parent);
if (NT_STATUS_IS_OK(status)) {
@ -1122,6 +1132,7 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs,
uint32_t create_options;
uint32_t share_access;
uint32_t access_mask;
uint32_t create_action = NTCREATEX_ACTION_EXISTED;
bool del_on_close;
bool stream_existed, stream_truncate=false;
uint32_t oplock_level = OPLOCK_NONE, oplock_granted;
@ -1134,6 +1145,8 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs,
return ntvfs_map_open(ntvfs, req, io);
}
ZERO_STRUCT(io->generic.out);
create_options = io->generic.in.create_options;
share_access = io->generic.in.share_access;
access_mask = io->generic.in.access_mask;
@ -1169,6 +1182,13 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs,
return NT_STATUS_INVALID_PARAMETER;
}
/* we ignore some file_attr bits */
io->ntcreatex.in.file_attr &= ~(FILE_ATTRIBUTE_NONINDEXED |
FILE_ATTRIBUTE_COMPRESSED |
FILE_ATTRIBUTE_REPARSE_POINT |
FILE_ATTRIBUTE_SPARSE |
FILE_ATTRIBUTE_NORMAL);
/* resolve the cifs name to a posix name */
status = pvfs_resolve_name(pvfs, req, io->ntcreatex.in.fname,
PVFS_RESOLVE_STREAMS, &name);
@ -1210,6 +1230,7 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs,
} else {
stream_truncate = true;
}
create_action = NTCREATEX_ACTION_TRUNCATED;
break;
case NTCREATEX_DISP_OPEN:
@ -1228,6 +1249,7 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs,
} else {
stream_truncate = true;
}
create_action = NTCREATEX_ACTION_TRUNCATED;
break;
case NTCREATEX_DISP_CREATE:
@ -1272,8 +1294,12 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs,
/* check the security descriptor */
status = pvfs_access_check(pvfs, req, name, &access_mask);
if (!NT_STATUS_IS_OK(status)) {
return status;
NT_STATUS_NOT_OK_RETURN(status);
if (io->generic.in.query_maximal_access) {
status = pvfs_access_maximal_allowed(pvfs, req, name,
&io->generic.out.maximal_access);
NT_STATUS_NOT_OK_RETURN(status);
}
status = ntvfs_handle_new(pvfs->ntvfs, req, &h);
@ -1487,7 +1513,8 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs,
io->generic.out.oplock_level = oplock_granted;
io->generic.out.file.ntvfs = h;
io->generic.out.create_action = stream_existed?
NTCREATEX_ACTION_EXISTED:NTCREATEX_ACTION_CREATED;
create_action:NTCREATEX_ACTION_CREATED;
io->generic.out.create_time = name->dos.create_time;
io->generic.out.access_time = name->dos.access_time;
io->generic.out.write_time = name->dos.write_time;

View File

@ -41,6 +41,10 @@ static uint32_t pvfs_fileinfo_access(union smb_fileinfo *info)
needed = 0;
break;
case RAW_FILEINFO_ACCESS_INFORMATION:
needed = 0;
break;
case RAW_FILEINFO_SEC_DESC:
needed = 0;
if (info->query_secdesc.in.secinfo_flags & (SECINFO_OWNER|SECINFO_GROUP)) {
@ -216,6 +220,10 @@ static NTSTATUS pvfs_map_fileinfo(struct pvfs_state *pvfs,
case RAW_FILEINFO_NAME_INFO:
case RAW_FILEINFO_NAME_INFORMATION:
if (req->ctx->protocol == PROTOCOL_SMB2) {
/* strange that SMB2 doesn't have this */
return NT_STATUS_NOT_SUPPORTED;
}
info->name_info.out.fname.s = name->original_name;
return NT_STATUS_OK;

View File

@ -457,7 +457,12 @@ NTSTATUS pvfs_setfileinfo(struct ntvfs_module_context *ntvfs,
/* possibly change the attribute */
if (newstats.dos.attrib != h->name->dos.attrib) {
mode_t mode = pvfs_fileperms(pvfs, newstats.dos.attrib);
mode_t mode;
if ((newstats.dos.attrib & FILE_ATTRIBUTE_DIRECTORY) &&
!(h->name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY)) {
return NT_STATUS_INVALID_PARAMETER;
}
mode = pvfs_fileperms(pvfs, newstats.dos.attrib);
if (!(h->name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY)) {
if (fchmod(h->fd, mode) == -1) {
return pvfs_map_errno(pvfs, errno);

View File

@ -48,6 +48,5 @@ samba4.ntvfs.cifs.raw.
^samba4.net.api.become.dc.*$ # Fails
nss.test # Fails
samba4.samba3sam.python # Conversion from EJS not yet finished
samba4.samdb.python # Not finished yet
raw.offline # Samba 4 doesn't have much offline support yet
winreg* #Does not authenticate against the target server

View File

@ -47,6 +47,7 @@ class TestCaseInTempDir(unittest.TestCase):
def tearDown(self):
super(TestCaseInTempDir, self).tearDown()
self.assertEquals([], os.listdir(self.tempdir))
os.rmdir(self.tempdir)

View File

@ -16,13 +16,13 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
from auth import system_session
from credentials import Credentials
from samba.auth import system_session
from samba.credentials import Credentials
import os
from samba.provision import setup_samdb
from samba.provision import setup_samdb, guess_names, setup_templatesdb
from samba.samdb import SamDB
from samba.tests import cmdline_loadparm, TestCaseInTempDir
import security
from samba import security
from unittest import TestCase
import uuid
@ -42,14 +42,27 @@ class SamDBTestCase(TestCaseInTempDir):
domainsid = security.random_sid()
hostguid = str(uuid.uuid4())
path = os.path.join(self.tempdir, "samdb.ldb")
self.samdb = setup_samdb(path, setup_path, system_session(), creds,
cmdline_loadparm, schemadn, configdn,
self.domaindn, "example.com", "EXAMPLE.COM",
"FOO", lambda x: None, "foo", domaindn,
False, domainsid, "# no aci", domainguid,
policyguid, "EXAMPLE", True, "secret",
"secret", "secret", hostguid, invocationid,
session_info = system_session()
names = guess_names(lp=cmdline_loadparm, hostname="foo",
domain="EXAMPLE.COM", dnsdomain="example.com",
serverrole="domain controller",
domaindn=self.domaindn, configdn=configdn,
schemadn=schemadn)
setup_templatesdb(os.path.join(self.tempdir, "templates.ldb"),
setup_path, session_info=session_info,
credentials=creds, lp=cmdline_loadparm)
self.samdb = setup_samdb(path, setup_path, session_info, creds,
cmdline_loadparm, names,
lambda x: None, domainsid,
"# no aci", domainguid,
policyguid, False, "secret",
"secret", "secret", invocationid,
"secret", "domain controller")
def tearDown(self):
for f in ['templates.ldb', 'schema.ldb', 'configuration.ldb',
'users.ldb', 'samdb.ldb']:
os.remove(os.path.join(self.tempdir, f))
super(SamDBTestCase, self).tearDown()
def test_add_foreign(self):
self.samdb.add_foreign(self.domaindn, "S-1-5-7", "Somedescription")

View File

@ -340,8 +340,8 @@ plantest "provision.python" none $SUBUNITRUN samba.tests.provision
plantest "samba3.python" none $SUBUNITRUN samba.tests.samba3
plantest "samr.python" dc $SUBUNITRUN samba.tests.dcerpc.sam
plantest "dcerpc.bare.python" dc $SUBUNITRUN samba.tests.dcerpc.bare
plantest "samdb.python" dc $SUBUNITRUN samba.tests.samdb
plantest "unixinfo.python" dc $SUBUNITRUN samba.tests.dcerpc.unix
plantest "samdb.python" none $SUBUNITRUN samba.tests.samdb
plantest "events.python" none PYTHONPATH="$PYTHONPATH:lib/events" $SUBUNITRUN tests
plantest "messaging.python" none PYTHONPATH="$PYTHONPATH:lib/messaging/tests" $SUBUNITRUN bindings
plantest "samba3sam.python" none PYTHONPATH="$PYTHONPATH:dsdb/samdb/ldb_modules/tests" $SUBUNITRUN samba3sam

View File

@ -55,8 +55,7 @@ static void smb2srv_getinfo_send(struct ntvfs_request *ntvfs)
SMB2SRV_CHECK(smb2srv_setup_reply(req, 0x08, true, op->info->out.blob.length));
/* TODO: this is maybe a o16s32_blob */
SMB2SRV_CHECK(smb2_push_o16s16_blob(&req->out, 0x02, op->info->out.blob));
SMB2SRV_CHECK(smb2_push_o16s32_blob(&req->out, 0x02, op->info->out.blob));
SSVAL(req->out.body, 0x06, 0);
smb2srv_send_reply(req);

View File

@ -36,6 +36,18 @@ static void smb2srv_create_send(struct ntvfs_request *ntvfs)
DATA_BLOB blob;
SMB2SRV_CHECK_ASYNC_STATUS(io, union smb_open);
/* setup the blobs we should give in the reply */
if (io->smb2.out.maximal_access != 0) {
uint32_t data[2];
SIVAL(data, 0, 0);
SIVAL(data, 4, io->smb2.out.maximal_access);
SMB2SRV_CHECK(smb2_create_blob_add(req, &io->smb2.out.blobs,
SMB2_CREATE_TAG_MXAC,
data_blob_const(data, 8)));
}
SMB2SRV_CHECK(smb2_create_blob_push(req, &blob, io->smb2.out.blobs));
SMB2SRV_CHECK(smb2srv_setup_reply(req, 0x58, true, blob.length));

View File

@ -158,7 +158,8 @@ static void smb2srv_sesssetup_backend(struct smb2srv_request *req, union smb_ses
}
if (!smb_sess) {
status = NT_STATUS_USER_SESSION_DELETED;
/* see WSPP test suite - test 11 */
status = NT_STATUS_REQUEST_NOT_ACCEPTED;
goto failed;
}

View File

@ -262,23 +262,6 @@ gentest_OBJ_FILES = $(torturesrcdir)/gentest.o
MANPAGES += $(torturesrcdir)/man/gentest.1
#################################
# Start BINARY gentest_smb2
[BINARY::gentest_smb2]
INSTALLDIR = BINDIR
PRIVATE_DEPENDENCIES = \
LIBSAMBA-HOSTCONFIG \
LIBSAMBA-UTIL \
LIBPOPT \
POPT_SAMBA \
POPT_CREDENTIALS \
LIBCLI_SMB \
LIBCLI_RAW
# End BINARY gentest_smb2
#################################
gentest_smb2_OBJ_FILES = $(torturesrcdir)/gentest_smb2.o
#################################
# Start BINARY masktest
[BINARY::masktest]

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -41,7 +41,7 @@
if (v != correct) { \
printf("(%s) Incorrect value for %s 0x%08llx - should be 0x%08llx\n", \
__location__, #v, (unsigned long long)v, (unsigned long long)correct); \
return false; \
return false; \
}} while (0)
/*
@ -52,7 +52,8 @@ static bool test_create_gentest(struct torture_context *torture, struct smb2_tre
struct smb2_create io;
NTSTATUS status;
TALLOC_CTX *tmp_ctx = talloc_new(tree);
uint32_t access_mask, file_attributes, denied_mask;
uint32_t access_mask, file_attributes, file_attributes_set, denied_mask;
union smb_fileinfo q;
ZERO_STRUCT(io);
io.in.desired_access = SEC_FLAG_MAXIMUM_ALLOWED;
@ -115,7 +116,8 @@ static bool test_create_gentest(struct torture_context *torture, struct smb2_tre
for (i=0;i<32;i++) {
io.in.desired_access = 1<<i;
status = smb2_create(tree, tmp_ctx, &io);
if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) ||
NT_STATUS_EQUAL(status, NT_STATUS_PRIVILEGE_NOT_HELD)) {
access_mask |= io.in.desired_access;
} else {
CHECK_STATUS(status, NT_STATUS_OK);
@ -131,6 +133,7 @@ static bool test_create_gentest(struct torture_context *torture, struct smb2_tre
io.in.desired_access = SEC_FLAG_MAXIMUM_ALLOWED;
io.in.file_attributes = 0;
file_attributes = 0;
file_attributes_set = 0;
denied_mask = 0;
{
int i;
@ -146,12 +149,14 @@ static bool test_create_gentest(struct torture_context *torture, struct smb2_tre
CHECK_STATUS(status, NT_STATUS_OK);
status = smb2_util_close(tree, io.out.file.handle);
CHECK_STATUS(status, NT_STATUS_OK);
file_attributes_set |= io.out.file_attr;
}
}
}
CHECK_EQUAL(file_attributes, 0xffff8048);
CHECK_EQUAL(denied_mask, 0x4000);
CHECK_EQUAL(file_attributes_set, 0x00001127);
smb2_deltree(tree, FNAME);
@ -177,6 +182,20 @@ static bool test_create_gentest(struct torture_context *torture, struct smb2_tre
status = smb2_create(tree, tmp_ctx, &io);
CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
io.in.fname = FNAME;
io.in.file_attributes = 0;
io.in.desired_access = SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA | SEC_FILE_APPEND_DATA;
io.in.query_maximal_access = true;
status = smb2_create(tree, tmp_ctx, &io);
CHECK_STATUS(status, NT_STATUS_OK);
CHECK_EQUAL(io.out.maximal_access, 0x001f01ff);
q.access_information.level = RAW_FILEINFO_ACCESS_INFORMATION;
q.access_information.in.file.handle = io.out.file.handle;
status = smb2_getinfo_file(tree, tmp_ctx, &q);
CHECK_STATUS(status, NT_STATUS_OK);
CHECK_EQUAL(q.access_information.out.access_flags, io.in.desired_access);
talloc_free(tmp_ctx);
smb2_deltree(tree, FNAME);
@ -237,6 +256,7 @@ static bool test_create_blob(struct torture_context *torture, struct smb2_tree *
io.in.query_maximal_access = true;
status = smb2_create(tree, tmp_ctx, &io);
CHECK_STATUS(status, NT_STATUS_OK);
CHECK_EQUAL(io.out.maximal_access, 0x001f01ff);
status = smb2_util_close(tree, io.out.file.handle);
CHECK_STATUS(status, NT_STATUS_OK);

View File

@ -106,7 +106,11 @@ static bool test_valid_request(struct torture_context *torture, struct smb2_tree
lck.in.reserved = 0x123ab3;
status = smb2_lock(tree, &lck);
CHECK_STATUS(status, NT_STATUS_OK);
if (torture_setting_bool(torture, "windows", false)) {
CHECK_STATUS(status, NT_STATUS_OK);
} else {
CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
}
CHECK_VALUE(lck.out.reserved, 0);
lck.in.reserved = 0x123ab4;
@ -115,7 +119,11 @@ static bool test_valid_request(struct torture_context *torture, struct smb2_tree
lck.in.reserved = 0x123ab5;
status = smb2_lock(tree, &lck);
CHECK_STATUS(status, NT_STATUS_OK);
if (torture_setting_bool(torture, "windows", false)) {
CHECK_STATUS(status, NT_STATUS_OK);
} else {
CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
}
CHECK_VALUE(lck.out.reserved, 0);
lck.in.lock_count = 0x0001;
@ -133,14 +141,22 @@ static bool test_valid_request(struct torture_context *torture, struct smb2_tree
CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
status = smb2_lock(tree, &lck);
CHECK_STATUS(status, NT_STATUS_OK);
if (torture_setting_bool(torture, "windows", false)) {
CHECK_STATUS(status, NT_STATUS_OK);
} else {
CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
}
CHECK_VALUE(lck.out.reserved, 0);
status = smb2_lock(tree, &lck);
CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
status = smb2_lock(tree, &lck);
CHECK_STATUS(status, NT_STATUS_OK);
if (torture_setting_bool(torture, "windows", false)) {
CHECK_STATUS(status, NT_STATUS_OK);
} else {
CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
}
CHECK_VALUE(lck.out.reserved, 0);
el[0].flags = 0x00000000;
@ -473,6 +489,51 @@ static bool test_lock_rw_exclusiv(struct torture_context *torture, struct smb2_t
return test_lock_read_write(torture, tree, &s);
}
static bool test_lock_auto_unlock(struct torture_context *torture, struct smb2_tree *tree)
{
bool ret = true;
NTSTATUS status;
struct smb2_handle h;
uint8_t buf[200];
struct smb2_lock lck;
struct smb2_lock_element el[2];
ZERO_STRUCT(buf);
status = torture_smb2_testfile(tree, "autounlock.txt", &h);
CHECK_STATUS(status, NT_STATUS_OK);
status = smb2_util_write(tree, h, buf, 0, ARRAY_SIZE(buf));
CHECK_STATUS(status, NT_STATUS_OK);
ZERO_STRUCT(lck);
lck.in.locks = el;
lck.in.lock_count = 0x0001;
lck.in.file.handle = h;
el[0].offset = 0;
el[0].length = 1;
el[0].flags = SMB2_LOCK_FLAG_EXCLUSIVE | SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
status = smb2_lock(tree, &lck);
CHECK_STATUS(status, NT_STATUS_OK);
status = smb2_lock(tree, &lck);
CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
status = smb2_lock(tree, &lck);
if (torture_setting_bool(torture, "windows", false)) {
CHECK_STATUS(status, NT_STATUS_OK);
} else {
CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
}
done:
return ret;
}
/* basic testing of SMB2 locking
*/
struct torture_suite *torture_smb2_lock_init(void)
@ -483,6 +544,7 @@ struct torture_suite *torture_smb2_lock_init(void)
torture_suite_add_1smb2_test(suite, "RW-NONE", test_lock_rw_none);
torture_suite_add_1smb2_test(suite, "RW-SHARED", test_lock_rw_shared);
torture_suite_add_1smb2_test(suite, "RW-EXCLUSIV", test_lock_rw_exclusiv);
torture_suite_add_1smb2_test(suite, "AUTO-UNLOCK", test_lock_auto_unlock);
suite->description = talloc_strdup(suite, "SMB2-LOCK tests");

View File

@ -44,6 +44,9 @@
goto done; \
}} while (0)
#define FNAME "smb2_readtest.dat"
#define DNAME "smb2_readtest.dir"
static bool test_read_eof(struct torture_context *torture, struct smb2_tree *tree)
{
bool ret = true;
@ -55,7 +58,7 @@ static bool test_read_eof(struct torture_context *torture, struct smb2_tree *tre
ZERO_STRUCT(buf);
status = torture_smb2_testfile(tree, "lock1.txt", &h);
status = torture_smb2_testfile(tree, FNAME, &h);
CHECK_STATUS(status, NT_STATUS_OK);
status = smb2_util_write(tree, h, buf, 0, ARRAY_SIZE(buf));
@ -139,7 +142,7 @@ static bool test_read_position(struct torture_context *torture, struct smb2_tree
ZERO_STRUCT(buf);
status = torture_smb2_testfile(tree, "lock1.txt", &h);
status = torture_smb2_testfile(tree, FNAME, &h);
CHECK_STATUS(status, NT_STATUS_OK);
status = smb2_util_write(tree, h, buf, 0, ARRAY_SIZE(buf));
@ -172,6 +175,59 @@ done:
return ret;
}
static bool test_read_dir(struct torture_context *torture, struct smb2_tree *tree)
{
bool ret = true;
NTSTATUS status;
struct smb2_handle h;
uint8_t buf[100];
struct smb2_read rd;
TALLOC_CTX *tmp_ctx = talloc_new(tree);
status = torture_smb2_testdir(tree, DNAME, &h);
if (!NT_STATUS_IS_OK(status)) {
printf(__location__ " Unable to create test directory '%s' - %s\n", DNAME, nt_errstr(status));
return false;
}
ZERO_STRUCT(rd);
rd.in.file.handle = h;
rd.in.length = 10;
rd.in.offset = 0;
rd.in.min_count = 1;
status = smb2_read(tree, tmp_ctx, &rd);
CHECK_STATUS(status, NT_STATUS_INVALID_DEVICE_REQUEST);
rd.in.min_count = 11;
status = smb2_read(tree, tmp_ctx, &rd);
CHECK_STATUS(status, NT_STATUS_INVALID_DEVICE_REQUEST);
rd.in.length = 0;
rd.in.min_count = 2592;
status = smb2_read(tree, tmp_ctx, &rd);
if (torture_setting_bool(torture, "windows", false)) {
CHECK_STATUS(status, NT_STATUS_END_OF_FILE);
} else {
CHECK_STATUS(status, NT_STATUS_INVALID_DEVICE_REQUEST);
}
rd.in.length = 0;
rd.in.min_count = 0;
rd.in.channel = 0;
status = smb2_read(tree, tmp_ctx, &rd);
if (torture_setting_bool(torture, "windows", false)) {
CHECK_STATUS(status, NT_STATUS_OK);
} else {
CHECK_STATUS(status, NT_STATUS_INVALID_DEVICE_REQUEST);
}
done:
talloc_free(tmp_ctx);
return ret;
}
/*
basic testing of SMB2 read
*/
@ -181,6 +237,7 @@ struct torture_suite *torture_smb2_read_init(void)
torture_suite_add_1smb2_test(suite, "EOF", test_read_eof);
torture_suite_add_1smb2_test(suite, "POSITION", test_read_position);
torture_suite_add_1smb2_test(suite, "DIR", test_read_dir);
suite->description = talloc_strdup(suite, "SMB2-READ tests");

View File

@ -175,6 +175,10 @@ bool torture_smb2_setinfo(struct torture_context *torture)
CHECK_CALL(BASIC_INFORMATION, NT_STATUS_OK);
CHECK_VALUE(SMB2_ALL_INFORMATION, all_info2, attrib, FILE_ATTRIBUTE_HIDDEN);
printf("can't change a file to a directory\n");
sfinfo.basic_info.in.attrib = FILE_ATTRIBUTE_DIRECTORY;
CHECK_CALL(BASIC_INFORMATION, NT_STATUS_INVALID_PARAMETER);
printf("restore attribute\n");
sfinfo.basic_info.in.attrib = FILE_ATTRIBUTE_NORMAL;
CHECK_CALL(BASIC_INFORMATION, NT_STATUS_OK);