summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source4/libcli/raw/interfaces.h3
-rw-r--r--source4/libcli/raw/raweas.c9
-rw-r--r--source4/libcli/raw/rawfile.c4
-rw-r--r--source4/libcli/raw/rawfileinfo.c3
-rw-r--r--source4/libcli/raw/smb.h1
-rw-r--r--source4/libcli/smb2/create.c4
-rw-r--r--source4/ntvfs/ntvfs_generic.c5
-rw-r--r--source4/ntvfs/posix/pvfs_open.c4
-rw-r--r--source4/ntvfs/posix/pvfs_qfileinfo.c13
-rw-r--r--source4/smb_server/blob.c7
-rw-r--r--source4/smb_server/smb2/smb2_server.h4
-rw-r--r--source4/torture/gentest_smb2.c260
-rw-r--r--source4/torture/smb2/getinfo.c12
-rw-r--r--source4/torture/smb2/lock.c20
14 files changed, 155 insertions, 194 deletions
diff --git a/source4/libcli/raw/interfaces.h b/source4/libcli/raw/interfaces.h
index 3370021d48..bae0e67b02 100644
--- a/source4/libcli/raw/interfaces.h
+++ b/source4/libcli/raw/interfaces.h
@@ -684,7 +684,8 @@ union smb_fileinfo {
uint32_t ea_size;
uint32_t access_mask;
uint64_t position;
- uint64_t mode;
+ uint32_t mode;
+ uint32_t alignment_requirement;
struct smb_wire_string fname;
} out;
} all_info2;
diff --git a/source4/libcli/raw/raweas.c b/source4/libcli/raw/raweas.c
index 8ea8e621c9..07b517ade3 100644
--- a/source4/libcli/raw/raweas.c
+++ b/source4/libcli/raw/raweas.c
@@ -54,13 +54,13 @@ static uint_t ea_name_list_size(uint_t num_names, struct ea_name *eas)
This assumes the names are strict ascii, which should be a
reasonable assumption
*/
-size_t ea_list_size_chained(uint_t num_eas, struct ea_struct *eas)
+size_t ea_list_size_chained(uint_t num_eas, struct ea_struct *eas, unsigned alignment)
{
uint_t total = 0;
int i;
for (i=0;i<num_eas;i++) {
uint_t len = 8 + strlen(eas[i].name.s)+1 + eas[i].value.length;
- len = (len + 3) & ~3;
+ len = (len + (alignment-1)) & ~(alignment-1);
total += len;
}
return total;
@@ -96,14 +96,15 @@ void ea_put_list(uint8_t *data, uint_t num_eas, struct ea_struct *eas)
put a chained ea_list into a pre-allocated buffer - buffer must be
at least of size ea_list_size()
*/
-void ea_put_list_chained(uint8_t *data, uint_t num_eas, struct ea_struct *eas)
+void ea_put_list_chained(uint8_t *data, uint_t num_eas, struct ea_struct *eas,
+ unsigned alignment)
{
int i;
for (i=0;i<num_eas;i++) {
uint_t nlen = strlen(eas[i].name.s);
uint32_t len = 8+nlen+1+eas[i].value.length;
- uint_t pad = ((len + 3) & ~3) - len;
+ uint_t pad = ((len + (alignment-1)) & ~(alignment-1)) - len;
if (i == num_eas-1) {
SIVAL(data, 0, 0);
} else {
diff --git a/source4/libcli/raw/rawfile.c b/source4/libcli/raw/rawfile.c
index 3c5c1b742b..d39c61551b 100644
--- a/source4/libcli/raw/rawfile.c
+++ b/source4/libcli/raw/rawfile.c
@@ -314,14 +314,14 @@ static struct smbcli_request *smb_raw_nttrans_create_send(struct smbcli_tree *tr
if (parms->ntcreatex.in.ea_list) {
uint32_t ea_size = ea_list_size_chained(parms->ntcreatex.in.ea_list->num_eas,
- parms->ntcreatex.in.ea_list->eas);
+ parms->ntcreatex.in.ea_list->eas, 4);
ea_blob = data_blob_talloc(mem_ctx, NULL, ea_size);
if (ea_blob.data == NULL) {
return NULL;
}
ea_put_list_chained(ea_blob.data,
parms->ntcreatex.in.ea_list->num_eas,
- parms->ntcreatex.in.ea_list->eas);
+ parms->ntcreatex.in.ea_list->eas, 4);
}
nt.in.params = data_blob_talloc(mem_ctx, NULL, 53);
diff --git a/source4/libcli/raw/rawfileinfo.c b/source4/libcli/raw/rawfileinfo.c
index 71900be49c..0ea5a93606 100644
--- a/source4/libcli/raw/rawfileinfo.c
+++ b/source4/libcli/raw/rawfileinfo.c
@@ -243,7 +243,8 @@ NTSTATUS smb_raw_fileinfo_passthru_parse(const DATA_BLOB *blob, TALLOC_CTX *mem_
parms->all_info2.out.ea_size = IVAL(blob->data, 0x48);
parms->all_info2.out.access_mask = IVAL(blob->data, 0x4C);
parms->all_info2.out.position = BVAL(blob->data, 0x50);
- parms->all_info2.out.mode = BVAL(blob->data, 0x58);
+ parms->all_info2.out.mode = IVAL(blob->data, 0x58);
+ parms->all_info2.out.alignment_requirement = IVAL(blob->data, 0x5C);
smbcli_blob_pull_string(NULL, mem_ctx, blob,
&parms->all_info2.out.fname, 0x60, 0x64, STR_UNICODE);
return NT_STATUS_OK;
diff --git a/source4/libcli/raw/smb.h b/source4/libcli/raw/smb.h
index e054ed6522..74869e8a45 100644
--- a/source4/libcli/raw/smb.h
+++ b/source4/libcli/raw/smb.h
@@ -370,6 +370,7 @@
#define FILE_ATTRIBUTE_OFFLINE 0x1000
#define FILE_ATTRIBUTE_NONINDEXED 0x2000
#define FILE_ATTRIBUTE_ENCRYPTED 0x4000
+#define FILE_ATTRIBUTE_ALL_MASK 0x7FFF
/* Flags - combined with attributes. */
#define FILE_FLAG_WRITE_THROUGH 0x80000000L
diff --git a/source4/libcli/smb2/create.c b/source4/libcli/smb2/create.c
index 6ac32a494f..9d28bbf8c4 100644
--- a/source4/libcli/smb2/create.c
+++ b/source4/libcli/smb2/create.c
@@ -117,8 +117,8 @@ struct smb2_request *smb2_create_send(struct smb2_tree *tree, struct smb2_create
if (io->in.eas.num_eas != 0) {
DATA_BLOB b = data_blob_talloc(req, NULL,
- ea_list_size_chained(io->in.eas.num_eas, io->in.eas.eas));
- ea_put_list_chained(b.data, io->in.eas.num_eas, io->in.eas.eas);
+ ea_list_size_chained(io->in.eas.num_eas, io->in.eas.eas, 8));
+ ea_put_list_chained(b.data, io->in.eas.num_eas, io->in.eas.eas, 8);
status = smb2_create_blob_add(req, &io->in.blobs,
SMB2_CREATE_TAG_EXTA, b);
if (!NT_STATUS_IS_OK(status)) {
diff --git a/source4/ntvfs/ntvfs_generic.c b/source4/ntvfs/ntvfs_generic.c
index a706e621c9..62a1427405 100644
--- a/source4/ntvfs/ntvfs_generic.c
+++ b/source4/ntvfs/ntvfs_generic.c
@@ -1276,6 +1276,11 @@ static NTSTATUS ntvfs_map_read_finish(struct ntvfs_module_context *ntvfs,
rd->smb2.out.data.length= rd2->generic.out.nread;
rd->smb2.out.remaining = 0;
rd->smb2.out.reserved = 0;
+ if (NT_STATUS_IS_OK(status) &&
+ rd->smb2.out.data.length == 0 &&
+ rd->smb2.in.length != 0) {
+ status = NT_STATUS_END_OF_FILE;
+ }
break;
default:
return NT_STATUS_INVALID_LEVEL;
diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c
index 67937324cc..cc4f0add27 100644
--- a/source4/ntvfs/posix/pvfs_open.c
+++ b/source4/ntvfs/posix/pvfs_open.c
@@ -548,6 +548,10 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs,
uint32_t oplock_level = OPLOCK_NONE, oplock_granted;
bool allow_level_II_oplock = false;
+ if (io->ntcreatex.in.file_attr & ~FILE_ATTRIBUTE_ALL_MASK) {
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
if ((io->ntcreatex.in.file_attr & FILE_ATTRIBUTE_READONLY) &&
(create_options & NTCREATEX_OPTIONS_DELETE_ON_CLOSE)) {
return NT_STATUS_CANNOT_DELETE;
diff --git a/source4/ntvfs/posix/pvfs_qfileinfo.c b/source4/ntvfs/posix/pvfs_qfileinfo.c
index 6bc21e5e3e..102660a0bf 100644
--- a/source4/ntvfs/posix/pvfs_qfileinfo.c
+++ b/source4/ntvfs/posix/pvfs_qfileinfo.c
@@ -298,10 +298,21 @@ static NTSTATUS pvfs_map_fileinfo(struct pvfs_state *pvfs,
(name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY)? 1 : 0;
info->all_info2.out.file_id = name->dos.file_id;
info->all_info2.out.ea_size = name->dos.ea_size;
+ if (info->all_info2.out.ea_size == 4) {
+ /* SMB2 uses zero for a empty EA set */
+ info->all_info2.out.ea_size = 0;
+ }
info->all_info2.out.access_mask = 0; /* only set by qfileinfo */
info->all_info2.out.position = 0; /* only set by qfileinfo */
info->all_info2.out.mode = 0; /* only set by qfileinfo */
- info->all_info2.out.fname.s = name->original_name;
+ /* windows wants the full path on disk for this
+ result, but I really don't want to expose that on
+ the wire, so I'll give the path with a share
+ prefix, which is a good approximation */
+ info->all_info2.out.fname.s = talloc_asprintf(req, "\\%s\\%s",
+ pvfs->share_name,
+ name->original_name);
+ NT_STATUS_HAVE_NO_MEMORY(info->all_info2.out.fname.s);
return NT_STATUS_OK;
}
diff --git a/source4/smb_server/blob.c b/source4/smb_server/blob.c
index 8834c4483c..cea4c60e59 100644
--- a/source4/smb_server/blob.c
+++ b/source4/smb_server/blob.c
@@ -476,12 +476,12 @@ NTSTATUS smbsrv_push_passthru_fileinfo(TALLOC_CTX *mem_ctx,
}
list_size = ea_list_size_chained(st->all_eas.out.num_eas,
- st->all_eas.out.eas);
+ st->all_eas.out.eas, 8);
BLOB_CHECK(smbsrv_blob_grow_data(mem_ctx, blob, list_size));
ea_put_list_chained(blob->data,
st->all_eas.out.num_eas,
- st->all_eas.out.eas);
+ st->all_eas.out.eas, 8);
return NT_STATUS_OK;
case RAW_FILEINFO_SMB2_ALL_INFORMATION:
@@ -503,7 +503,8 @@ NTSTATUS smbsrv_push_passthru_fileinfo(TALLOC_CTX *mem_ctx,
SIVAL(blob->data, 0x48, st->all_info2.out.ea_size);
SIVAL(blob->data, 0x4C, st->all_info2.out.access_mask);
SBVAL(blob->data, 0x50, st->all_info2.out.position);
- SBVAL(blob->data, 0x58, st->all_info2.out.mode);
+ SIVAL(blob->data, 0x58, st->all_info2.out.mode);
+ SIVAL(blob->data, 0x5C, st->all_info2.out.alignment_requirement);
BLOB_CHECK(smbsrv_blob_append_string(mem_ctx, blob,
st->all_info2.out.fname.s,
0x60, default_str_flags,
diff --git a/source4/smb_server/smb2/smb2_server.h b/source4/smb_server/smb2/smb2_server.h
index fc40a92efc..ae4abbd71e 100644
--- a/source4/smb_server/smb2/smb2_server.h
+++ b/source4/smb_server/smb2/smb2_server.h
@@ -78,13 +78,13 @@ struct smbsrv_request;
if (is_size < (size)) { \
DEBUG(0,("%s: buffer too small 0x%x. Expected 0x%x\n", \
__location__, (unsigned)is_size, (unsigned)want_size)); \
- smb2srv_send_error(req, NT_STATUS_FOOBAR); \
+ smb2srv_send_error(req, NT_STATUS_INVALID_PARAMETER); \
return; \
}\
if (field_size != want_size) { \
DEBUG(0,("%s: unexpected fixed body size 0x%x. Expected 0x%x\n", \
__location__, (unsigned)field_size, (unsigned)want_size)); \
- smb2srv_send_error(req, NT_STATUS_FOOBAR); \
+ smb2srv_send_error(req, NT_STATUS_INVALID_PARAMETER); \
return; \
} \
} while (0)
diff --git a/source4/torture/gentest_smb2.c b/source4/torture/gentest_smb2.c
index fc6dbcbb9a..6546ba6768 100644
--- a/source4/torture/gentest_smb2.c
+++ b/source4/torture/gentest_smb2.c
@@ -53,6 +53,8 @@ static struct gentest_options {
const char *seeds_file;
int use_preset_seeds;
int fast_reconnect;
+ int mask_indexing;
+ int no_eas;
} options;
/* mapping between open handles on the server and local handles */
@@ -543,15 +545,6 @@ static uint16_t gen_lock_flags(void)
}
/*
- generate a pid
-*/
-static uint16_t gen_pid(void)
-{
- if (gen_chance(10)) return gen_bits_mask(0xFFFF);
- return getpid();
-}
-
-/*
generate a lock count
*/
static off_t gen_lock_count(void)
@@ -599,34 +592,6 @@ static uint32_t gen_open_disp(void)
}
/*
- generate an openx open mode
-*/
-static uint16_t gen_openx_mode(void)
-{
- if (gen_chance(20)) return gen_bits_mask(0xFFFF);
- if (gen_chance(20)) return gen_bits_mask(0xFF);
- return OPENX_MODE_DENY_NONE | gen_bits_mask(0x3);
-}
-
-/*
- generate an openx flags field
-*/
-static uint16_t gen_openx_flags(void)
-{
- if (gen_chance(20)) return gen_bits_mask(0xFFFF);
- return gen_bits_mask(0x7);
-}
-
-/*
- generate an openx open function
-*/
-static uint16_t gen_openx_func(void)
-{
- if (gen_chance(20)) return gen_bits_mask(0xFFFF);
- return gen_bits_mask(0x13);
-}
-
-/*
generate a file attrib combination
*/
static uint32_t gen_attrib(void)
@@ -721,6 +686,25 @@ static struct ea_struct gen_ea_struct(void)
}
/*
+ generate an ea_struct
+*/
+static struct smb_ea_list gen_ea_list(void)
+{
+ struct smb_ea_list eas;
+ int i;
+ if (options.no_eas) {
+ ZERO_STRUCT(eas);
+ return eas;
+ }
+ eas.num_eas = gen_int_range(0, 3);
+ eas.eas = talloc_array(current_op.mem_ctx, struct ea_struct, eas.num_eas);
+ for (i=0;i<eas.num_eas;i++) {
+ eas.eas[i] = gen_ea_struct();
+ }
+ return eas;
+}
+
+/*
the idle function tries to cope with getting an oplock break on a connection, and
an operation on another connection blocking until that break is acked
we check for operations on all transports in the idle function
@@ -953,6 +937,16 @@ again:
#define CHECK_EQUAL(field) do { \
if (parm[0].field != parm[1].field && !ignore_pattern(#field)) { \
+ printf("Mismatch in %s - 0x%llx 0x%llx\n", #field, \
+ (unsigned long long)parm[0].field, (unsigned long long)parm[1].field); \
+ return false; \
+ } \
+} while(0)
+
+#define CHECK_ATTRIB(field) do { \
+ if (!options.mask_indexing) { \
+ CHECK_EQUAL(field); \
+ } else if ((~FILE_ATTRIBUTE_NONINDEXED & parm[0].field) != (~FILE_ATTRIBUTE_NONINDEXED & parm[1].field) && !ignore_pattern(#field)) { \
printf("Mismatch in %s - 0x%x 0x%x\n", #field, \
(int)parm[0].field, (int)parm[1].field); \
return false; \
@@ -1026,6 +1020,7 @@ static bool handler_create(int instance)
parm[0].in.create_disposition = gen_open_disp();
parm[0].in.create_options = gen_create_options();
parm[0].in.fname = gen_fname_open(instance);
+ parm[0].in.eas = gen_ea_list();
if (!options.use_oplocks) {
/* mask out oplocks */
@@ -1044,7 +1039,7 @@ static bool handler_create(int instance)
CHECK_NTTIMES_EQUAL(out.change_time);
CHECK_EQUAL(out.alloc_size);
CHECK_EQUAL(out.size);
- CHECK_EQUAL(out.file_attr);
+ CHECK_ATTRIB(out.file_attr);
CHECK_EQUAL(out.reserved2);
/* ntcreatex creates a new file handle */
@@ -1077,7 +1072,7 @@ static bool handler_close(int instance)
CHECK_NTTIMES_EQUAL(out.change_time);
CHECK_EQUAL(out.alloc_size);
CHECK_EQUAL(out.size);
- CHECK_EQUAL(out.file_attr);
+ CHECK_ATTRIB(out.file_attr);
REMOVE_HANDLE(in.file.handle);
@@ -1194,7 +1189,19 @@ static bool handler_flush(int instance)
return true;
}
-#if 0
+/*
+ generate echo operations
+*/
+static bool handler_echo(int instance)
+{
+ NTSTATUS status[NSERVERS];
+
+ GEN_CALL(smb2_keepalive(tree->session->transport));
+
+ return true;
+}
+
+
/*
generate a fileinfo query structure
@@ -1207,16 +1214,13 @@ static void gen_fileinfo(int instance, union smb_fileinfo *info)
enum smb_fileinfo_level level;
const char *name;
} levels[] = {
- LVL(GETATTR), LVL(GETATTRE), LVL(STANDARD),
- LVL(EA_SIZE), LVL(ALL_EAS), LVL(IS_NAME_VALID),
- LVL(BASIC_INFO), LVL(STANDARD_INFO), LVL(EA_INFO),
- LVL(NAME_INFO), LVL(ALL_INFO), LVL(ALT_NAME_INFO),
- LVL(STREAM_INFO), LVL(COMPRESSION_INFO), LVL(BASIC_INFORMATION),
+ LVL(BASIC_INFORMATION),
LVL(STANDARD_INFORMATION), LVL(INTERNAL_INFORMATION), LVL(EA_INFORMATION),
LVL(ACCESS_INFORMATION), LVL(NAME_INFORMATION), LVL(POSITION_INFORMATION),
- LVL(MODE_INFORMATION), LVL(ALIGNMENT_INFORMATION), LVL(ALL_INFORMATION),
+ LVL(MODE_INFORMATION), LVL(ALIGNMENT_INFORMATION), LVL(SMB2_ALL_INFORMATION),
LVL(ALT_NAME_INFORMATION), LVL(STREAM_INFORMATION), LVL(COMPRESSION_INFORMATION),
- LVL(NETWORK_OPEN_INFORMATION), LVL(ATTRIBUTE_TAG_INFORMATION)
+ LVL(NETWORK_OPEN_INFORMATION), LVL(ATTRIBUTE_TAG_INFORMATION),
+ LVL(SMB2_ALL_EAS), LVL(SMB2_ALL_INFORMATION),
};
do {
i = gen_int_range(0, ARRAY_SIZE(levels)-1);
@@ -1238,62 +1242,14 @@ static bool cmp_fileinfo(int instance,
case RAW_FILEINFO_GENERIC:
return false;
- case RAW_FILEINFO_GETATTR:
- CHECK_EQUAL(getattr.out.attrib);
- CHECK_EQUAL(getattr.out.size);
- CHECK_TIMES_EQUAL(getattr.out.write_time);
- break;
-
- case RAW_FILEINFO_GETATTRE:
- CHECK_TIMES_EQUAL(getattre.out.create_time);
- CHECK_TIMES_EQUAL(getattre.out.access_time);
- CHECK_TIMES_EQUAL(getattre.out.write_time);
- CHECK_EQUAL(getattre.out.size);
- CHECK_EQUAL(getattre.out.alloc_size);
- CHECK_EQUAL(getattre.out.attrib);
- break;
-
- case RAW_FILEINFO_STANDARD:
- CHECK_TIMES_EQUAL(standard.out.create_time);
- CHECK_TIMES_EQUAL(standard.out.access_time);
- CHECK_TIMES_EQUAL(standard.out.write_time);
- CHECK_EQUAL(standard.out.size);
- CHECK_EQUAL(standard.out.alloc_size);
- CHECK_EQUAL(standard.out.attrib);
- break;
-
- case RAW_FILEINFO_EA_SIZE:
- CHECK_TIMES_EQUAL(ea_size.out.create_time);
- CHECK_TIMES_EQUAL(ea_size.out.access_time);
- CHECK_TIMES_EQUAL(ea_size.out.write_time);
- CHECK_EQUAL(ea_size.out.size);
- CHECK_EQUAL(ea_size.out.alloc_size);
- CHECK_EQUAL(ea_size.out.attrib);
- CHECK_EQUAL(ea_size.out.ea_size);
- break;
-
- case RAW_FILEINFO_ALL_EAS:
- CHECK_EQUAL(all_eas.out.num_eas);
- for (i=0;i<parm[0].all_eas.out.num_eas;i++) {
- CHECK_EQUAL(all_eas.out.eas[i].flags);
- CHECK_WSTR_EQUAL(all_eas.out.eas[i].name);
- CHECK_BLOB_EQUAL(all_eas.out.eas[i].value);
- }
- break;
-
- case RAW_FILEINFO_IS_NAME_VALID:
- break;
-
- case RAW_FILEINFO_BASIC_INFO:
case RAW_FILEINFO_BASIC_INFORMATION:
CHECK_NTTIMES_EQUAL(basic_info.out.create_time);
CHECK_NTTIMES_EQUAL(basic_info.out.access_time);
CHECK_NTTIMES_EQUAL(basic_info.out.write_time);
CHECK_NTTIMES_EQUAL(basic_info.out.change_time);
- CHECK_EQUAL(basic_info.out.attrib);
+ CHECK_ATTRIB(basic_info.out.attrib);
break;
- case RAW_FILEINFO_STANDARD_INFO:
case RAW_FILEINFO_STANDARD_INFORMATION:
CHECK_EQUAL(standard_info.out.alloc_size);
CHECK_EQUAL(standard_info.out.size);
@@ -1302,38 +1258,18 @@ static bool cmp_fileinfo(int instance,
CHECK_EQUAL(standard_info.out.directory);
break;
- case RAW_FILEINFO_EA_INFO:
case RAW_FILEINFO_EA_INFORMATION:
CHECK_EQUAL(ea_info.out.ea_size);
break;
- case RAW_FILEINFO_NAME_INFO:
case RAW_FILEINFO_NAME_INFORMATION:
CHECK_WSTR_EQUAL(name_info.out.fname);
break;
- case RAW_FILEINFO_ALL_INFO:
- case RAW_FILEINFO_ALL_INFORMATION:
- CHECK_NTTIMES_EQUAL(all_info.out.create_time);
- CHECK_NTTIMES_EQUAL(all_info.out.access_time);
- CHECK_NTTIMES_EQUAL(all_info.out.write_time);
- CHECK_NTTIMES_EQUAL(all_info.out.change_time);
- CHECK_EQUAL(all_info.out.attrib);
- CHECK_EQUAL(all_info.out.alloc_size);
- CHECK_EQUAL(all_info.out.size);
- CHECK_EQUAL(all_info.out.nlink);
- CHECK_EQUAL(all_info.out.delete_pending);
- CHECK_EQUAL(all_info.out.directory);
- CHECK_EQUAL(all_info.out.ea_size);
- CHECK_WSTR_EQUAL(all_info.out.fname);
- break;
-
- case RAW_FILEINFO_ALT_NAME_INFO:
case RAW_FILEINFO_ALT_NAME_INFORMATION:
CHECK_WSTR_EQUAL(alt_name_info.out.fname);
break;
- case RAW_FILEINFO_STREAM_INFO:
case RAW_FILEINFO_STREAM_INFORMATION:
CHECK_EQUAL(stream_info.out.num_streams);
for (i=0;i<parm[0].stream_info.out.num_streams;i++) {
@@ -1343,7 +1279,6 @@ static bool cmp_fileinfo(int instance,
}
break;
- case RAW_FILEINFO_COMPRESSION_INFO:
case RAW_FILEINFO_COMPRESSION_INFORMATION:
CHECK_EQUAL(compression_info.out.compressed_size);
CHECK_EQUAL(compression_info.out.format);
@@ -1379,22 +1314,51 @@ static bool cmp_fileinfo(int instance,
CHECK_NTTIMES_EQUAL(network_open_information.out.change_time);
CHECK_EQUAL(network_open_information.out.alloc_size);
CHECK_EQUAL(network_open_information.out.size);
- CHECK_EQUAL(network_open_information.out.attrib);
+ CHECK_ATTRIB(network_open_information.out.attrib);
break;
case RAW_FILEINFO_ATTRIBUTE_TAG_INFORMATION:
- CHECK_EQUAL(attribute_tag_information.out.attrib);
+ CHECK_ATTRIB(attribute_tag_information.out.attrib);
CHECK_EQUAL(attribute_tag_information.out.reparse_tag);
break;
+ case RAW_FILEINFO_ALL_INFORMATION:
+ case RAW_FILEINFO_SMB2_ALL_INFORMATION:
+ CHECK_NTTIMES_EQUAL(all_info2.out.create_time);
+ CHECK_NTTIMES_EQUAL(all_info2.out.access_time);
+ CHECK_NTTIMES_EQUAL(all_info2.out.write_time);
+ CHECK_NTTIMES_EQUAL(all_info2.out.change_time);
+ CHECK_ATTRIB(all_info2.out.attrib);
+ CHECK_EQUAL(all_info2.out.unknown1);
+ CHECK_EQUAL(all_info2.out.alloc_size);
+ CHECK_EQUAL(all_info2.out.size);
+ CHECK_EQUAL(all_info2.out.nlink);
+ CHECK_EQUAL(all_info2.out.delete_pending);
+ CHECK_EQUAL(all_info2.out.directory);
+ CHECK_EQUAL(all_info2.out.file_id);
+ CHECK_EQUAL(all_info2.out.ea_size);
+ CHECK_EQUAL(all_info2.out.access_mask);
+ CHECK_EQUAL(all_info2.out.position);
+ CHECK_EQUAL(all_info2.out.mode);
+ CHECK_EQUAL(all_info2.out.alignment_requirement);
+ CHECK_WSTR_EQUAL(all_info2.out.fname);
+ break;
+
+ case RAW_FILEINFO_SMB2_ALL_EAS:
+ CHECK_EQUAL(all_eas.out.num_eas);
+ for (i=0;i<parm[0].all_eas.out.num_eas;i++) {
+ CHECK_EQUAL(all_eas.out.eas[i].flags);
+ CHECK_WSTR_EQUAL(all_eas.out.eas[i].name);
+ CHECK_BLOB_EQUAL(all_eas.out.eas[i].value);
+ }
+ break;
+
/* Unhandled levels */
case RAW_FILEINFO_SEC_DESC:
case RAW_FILEINFO_EA_LIST:
case RAW_FILEINFO_UNIX_BASIC:
case RAW_FILEINFO_UNIX_LINK:
- case RAW_FILEINFO_SMB2_ALL_EAS:
- case RAW_FILEINFO_SMB2_ALL_INFORMATION:
case RAW_FILEINFO_UNIX_INFO2:
break;
}
@@ -1410,13 +1374,13 @@ static bool handler_qfileinfo(int instance)
union smb_fileinfo parm[NSERVERS];
NTSTATUS status[NSERVERS];
- parm[0].generic.in.file.fnum = gen_fnum(instance);
+ parm[0].generic.in.file.handle.data[0] = gen_fnum(instance);
gen_fileinfo(instance, &parm[0]);
GEN_COPY_PARM;
- GEN_SET_FNUM(generic.in.file.fnum);
- GEN_CALL(smb_raw_fileinfo(tree, current_op.mem_ctx, &parm[i]));
+ GEN_SET_FNUM(generic.in.file.handle);
+ GEN_CALL(smb2_getinfo_file(tree, current_op.mem_ctx, &parm[i]));
return cmp_fileinfo(instance, parm, status);
}
@@ -1434,12 +1398,7 @@ static void gen_setfileinfo(int instance, union smb_setfileinfo *info)
enum smb_setfileinfo_level level;
const char *name;
} levels[] = {
-#if 0
- /* disabled until win2003 can handle them ... */
- LVL(EA_SET), LVL(BASIC_INFO), LVL(DISPOSITION_INFO),
- LVL(STANDARD), LVL(ALLOCATION_INFO), LVL(END_OF_FILE_INFO),
-#endif
- LVL(SETATTR), LVL(SETATTRE), LVL(BASIC_INFORMATION),
+ LVL(BASIC_INFORMATION),
LVL(RENAME_INFORMATION), LVL(DISPOSITION_INFORMATION),
LVL(POSITION_INFORMATION), LVL(MODE_INFORMATION),
LVL(ALLOCATION_INFORMATION), LVL(END_OF_FILE_INFORMATION),
@@ -1452,28 +1411,6 @@ static void gen_setfileinfo(int instance, union smb_setfileinfo *info)
info->generic.level = levels[i].level;
switch (info->generic.level) {
- case RAW_SFILEINFO_SETATTR:
- info->setattr.in.attrib = gen_attrib();
- info->setattr.in.write_time = gen_timet();
- break;
- case RAW_SFILEINFO_SETATTRE:
- info->setattre.in.create_time = gen_timet();
- info->setattre.in.access_time = gen_timet();
- info->setattre.in.write_time = gen_timet();
- break;
- case RAW_SFILEINFO_STANDARD:
- info->standard.in.create_time = gen_timet();
- info->standard.in.access_time = gen_timet();
- info->standard.in.write_time = gen_timet();
- break;
- case RAW_SFILEINFO_EA_SET: {
- static struct ea_struct ea;
- info->ea_set.in.num_eas = 1;
- info->ea_set.in.eas = &ea;
- info->ea_set.in.eas[0] = gen_ea_struct();
- }
- break;
- case RAW_SFILEINFO_BASIC_INFO:
case RAW_SFILEINFO_BASIC_INFORMATION:
info->basic_info.in.create_time = gen_nttime();
info->basic_info.in.access_time = gen_nttime();
@@ -1481,15 +1418,12 @@ static void gen_setfileinfo(int instance, union smb_setfileinfo *info)
info->basic_info.in.change_time = gen_nttime();
info->basic_info.in.attrib = gen_attrib();
break;
- case RAW_SFILEINFO_DISPOSITION_INFO:
case RAW_SFILEINFO_DISPOSITION_INFORMATION:
info->disposition_info.in.delete_on_close = gen_bool();
break;
- case RAW_SFILEINFO_ALLOCATION_INFO:
case RAW_SFILEINFO_ALLOCATION_INFORMATION:
info->allocation_info.in.alloc_size = gen_alloc_size();
break;
- case RAW_SFILEINFO_END_OF_FILE_INFO:
case RAW_SFILEINFO_END_OF_FILE_INFORMATION:
info->end_of_file_info.in.size = gen_offset();
break;
@@ -1507,16 +1441,12 @@ static void gen_setfileinfo(int instance, union smb_setfileinfo *info)
break;
case RAW_SFILEINFO_GENERIC:
case RAW_SFILEINFO_SEC_DESC:
- case RAW_SFILEINFO_UNIX_BASIC:
- case RAW_SFILEINFO_UNIX_LINK:
- case RAW_SFILEINFO_UNIX_HLINK:
case RAW_SFILEINFO_1023:
case RAW_SFILEINFO_1025:
case RAW_SFILEINFO_1029:
case RAW_SFILEINFO_1032:
case RAW_SFILEINFO_1039:
case RAW_SFILEINFO_1040:
- case RAW_SFILEINFO_UNIX_INFO2:
/* Untested */
break;
}
@@ -1535,15 +1465,12 @@ static bool handler_sfileinfo(int instance)
gen_setfileinfo(instance, &parm[0]);
GEN_COPY_PARM;
- GEN_SET_FNUM(generic.in.file.fnum);
- GEN_CALL(smb_raw_setfileinfo(tree, &parm[i]));
+ GEN_SET_FNUM(generic.in.file.handle);
+ GEN_CALL(smb2_setinfo_file(tree, &parm[i]));
return true;
}
-#endif
-
-
/*
wipe any relevant files
*/
@@ -1606,6 +1533,9 @@ static struct {
{"WRITE", handler_write},
{"LOCK", handler_lock},
{"FLUSH", handler_flush},
+ {"ECHO", handler_echo},
+ {"QFILEINFO", handler_qfileinfo},
+ {"SFILEINFO", handler_sfileinfo},
};
@@ -1870,6 +1800,8 @@ static bool split_unc_name(const char *unc, char **server, char **share)
{"unclist", 0, POPT_ARG_STRING, NULL, OPT_UNCLIST, "unclist", NULL},
{"seedsfile", 0, POPT_ARG_STRING, &options.seeds_file, 0, "seed file", NULL},
{ "user", 'U', POPT_ARG_STRING, NULL, 'U', "Set the network username", "[DOMAIN/]USERNAME[%PASSWORD]" },
+ {"maskindexing", 0, POPT_ARG_NONE, &options.mask_indexing, 0, "mask out the indexed file attrib", NULL},
+ {"noeas", 0, POPT_ARG_NONE, &options.no_eas, 0, "don't use extended attributes", NULL},
POPT_COMMON_SAMBA
POPT_COMMON_CONNECTION
POPT_COMMON_CREDENTIALS
diff --git a/source4/torture/smb2/getinfo.c b/source4/torture/smb2/getinfo.c
index c47a26277c..906d6e4f8d 100644
--- a/source4/torture/smb2/getinfo.c
+++ b/source4/torture/smb2/getinfo.c
@@ -51,9 +51,9 @@ static struct {
{ LEVEL(RAW_FILEINFO_COMPRESSION_INFORMATION) },
{ LEVEL(RAW_FILEINFO_NETWORK_OPEN_INFORMATION) },
{ LEVEL(RAW_FILEINFO_ATTRIBUTE_TAG_INFORMATION) },
-/*
-disabled until we know how the alignment now works
-{ LEVEL(RAW_FILEINFO_SMB2_ALL_EAS) }, */
+/*
+ { LEVEL(RAW_FILEINFO_SMB2_ALL_EAS) },
+*/
{ LEVEL(RAW_FILEINFO_SMB2_ALL_INFORMATION) },
{ LEVEL(RAW_FILEINFO_SEC_DESC) }
};
@@ -107,9 +107,6 @@ static bool torture_smb2_fileinfo(struct torture_context *tctx, struct smb2_tree
file_levels[i].dinfo.query_secdesc.in.secinfo_flags = 0x7;
}
if (file_levels[i].level == RAW_FILEINFO_SMB2_ALL_EAS) {
- if (torture_setting_bool(tctx, "samba4", false)) {
- continue;
- }
file_levels[i].finfo.all_eas.in.continue_flags =
SMB2_CONTINUE_FLAG_RESTART;
file_levels[i].dinfo.all_eas.in.continue_flags =
@@ -183,6 +180,9 @@ bool torture_smb2_getinfo(struct torture_context *torture)
return false;
}
+ smb2_deltree(tree, FNAME);
+ smb2_deltree(tree, DNAME);
+
status = torture_setup_complex_file(tree, FNAME);
if (!NT_STATUS_IS_OK(status)) {
return false;
diff --git a/source4/torture/smb2/lock.c b/source4/torture/smb2/lock.c
index e81647b497..1a56cb9cad 100644
--- a/source4/torture/smb2/lock.c
+++ b/source4/torture/smb2/lock.c
@@ -90,7 +90,7 @@ static bool test_valid_request(struct torture_context *torture, struct smb2_tree
lck.in.file.handle.data[0] -=1;
lck.in.lock_count = 0x0001;
- lck.in.reserved = 0xFFFFFFFF;
+ lck.in.reserved = 0x123ab1;
lck.in.file.handle = h;
el[0].offset = UINT64_MAX;
el[0].length = UINT64_MAX;
@@ -100,16 +100,20 @@ static bool test_valid_request(struct torture_context *torture, struct smb2_tree
CHECK_STATUS(status, NT_STATUS_OK);
CHECK_VALUE(lck.out.reserved, 0);
+ lck.in.reserved = 0x123ab2;
status = smb2_lock(tree, &lck);
CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
+ lck.in.reserved = 0x123ab3;
status = smb2_lock(tree, &lck);
CHECK_STATUS(status, NT_STATUS_OK);
CHECK_VALUE(lck.out.reserved, 0);
+ lck.in.reserved = 0x123ab4;
status = smb2_lock(tree, &lck);
CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
+ lck.in.reserved = 0x123ab5;
status = smb2_lock(tree, &lck);
CHECK_STATUS(status, NT_STATUS_OK);
CHECK_VALUE(lck.out.reserved, 0);
@@ -162,27 +166,27 @@ static bool test_valid_request(struct torture_context *torture, struct smb2_tree
lck.in.file.handle = h;
el[0].offset = 0x00000000FFFFFFFF;
el[0].length = 0x00000000FFFFFFFF;
- el[0].reserved = 0x12345678;
+ el[0].reserved = 0x1234567;
el[0].flags = SMB2_LOCK_FLAG_UNLOCK;
status = smb2_lock(tree, &lck);
- CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
+ CHECK_STATUS(status, NT_STATUS_OK);
lck.in.lock_count = 0x0001;
- lck.in.reserved = 0x12345678;
+ lck.in.reserved = 0x1234567;
lck.in.file.handle = h;
el[0].offset = 0x00000000FFFFFFFF;
el[0].length = 0x00000000FFFFFFFF;
el[0].reserved = 0x00000000;
el[0].flags = SMB2_LOCK_FLAG_UNLOCK;
status = smb2_lock(tree, &lck);
- CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
+ CHECK_STATUS(status, NT_STATUS_OK);
status = smb2_lock(tree, &lck);
- CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
+ CHECK_STATUS(status, NT_STATUS_OK);
status = smb2_lock(tree, &lck);
- CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
+ CHECK_STATUS(status, NT_STATUS_OK);
status = smb2_lock(tree, &lck);
- CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
+ CHECK_STATUS(status, NT_STATUS_OK);
done:
return ret;