Unix SMB/CIFS implementation.
RAW_FILEINFO_* individual test suite
Copyright (C) Andrew Tridgell 2003
+ Copyright (C) Andrew Bartlett <abartlet@samba.org> 2007
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
+ the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "includes.h"
+#include "torture/torture.h"
+#include "libcli/raw/libcliraw.h"
+#include "libcli/libcli.h"
+#include "torture/util.h"
+#include "librpc/rpc/dcerpc.h"
+#include "torture/rpc/rpc.h"
static struct {
const char *name;
uint_t only_paths:1;
uint_t only_handles:1;
uint32_t capability_mask;
+ uint_t expected_ipc_access_denied:1;
+ NTSTATUS expected_ipc_fnum_status;
NTSTATUS fnum_status, fname_status;
union smb_fileinfo fnum_finfo, fname_finfo;
} levels[] = {
- { "GETATTR", RAW_FILEINFO_GETATTR, 1, 0, },
- { "GETATTRE", RAW_FILEINFO_GETATTRE, 0, 1, },
- { "STANDARD", RAW_FILEINFO_STANDARD, },
- { "EA_SIZE", RAW_FILEINFO_EA_SIZE, },
- { "ALL_EAS", RAW_FILEINFO_ALL_EAS, },
- { "IS_NAME_VALID", RAW_FILEINFO_IS_NAME_VALID, 1, 0, },
- { "BASIC_INFO", RAW_FILEINFO_BASIC_INFO, },
- { "STANDARD_INFO", RAW_FILEINFO_STANDARD_INFO, },
- { "EA_INFO", RAW_FILEINFO_EA_INFO, },
- { "NAME_INFO", RAW_FILEINFO_NAME_INFO, },
- { "ALL_INFO", RAW_FILEINFO_ALL_INFO, },
- { "ALT_NAME_INFO", RAW_FILEINFO_ALT_NAME_INFO, },
- { "STREAM_INFO", RAW_FILEINFO_STREAM_INFO, },
- { "COMPRESSION_INFO", RAW_FILEINFO_COMPRESSION_INFO, },
- { "UNIX_BASIC_INFO", RAW_FILEINFO_UNIX_BASIC, 0, 0, CAP_UNIX},
- { "UNIX_LINK_INFO", RAW_FILEINFO_UNIX_LINK, 0, 0, CAP_UNIX},
- { "BASIC_INFORMATION", RAW_FILEINFO_BASIC_INFORMATION, },
- { "STANDARD_INFORMATION", RAW_FILEINFO_STANDARD_INFORMATION, },
- { "INTERNAL_INFORMATION", RAW_FILEINFO_INTERNAL_INFORMATION, },
- { "EA_INFORMATION", RAW_FILEINFO_EA_INFORMATION, },
- { "ACCESS_INFORMATION", RAW_FILEINFO_ACCESS_INFORMATION, },
- { "NAME_INFORMATION", RAW_FILEINFO_NAME_INFORMATION, },
- { "POSITION_INFORMATION", RAW_FILEINFO_POSITION_INFORMATION, },
- { "MODE_INFORMATION", RAW_FILEINFO_MODE_INFORMATION, },
- { "ALIGNMENT_INFORMATION", RAW_FILEINFO_ALIGNMENT_INFORMATION, },
- { "ALL_INFORMATION", RAW_FILEINFO_ALL_INFORMATION, },
- { "ALT_NAME_INFORMATION", RAW_FILEINFO_ALT_NAME_INFORMATION, },
- { "STREAM_INFORMATION", RAW_FILEINFO_STREAM_INFORMATION, },
- { "COMPRESSION_INFORMATION", RAW_FILEINFO_COMPRESSION_INFORMATION, },
- { "NETWORK_OPEN_INFORMATION", RAW_FILEINFO_NETWORK_OPEN_INFORMATION, },
- { "ATTRIBUTE_TAG_INFORMATION", RAW_FILEINFO_ATTRIBUTE_TAG_INFORMATION, },
- { NULL, }
+ { .name = "GETATTR",
+ .level = RAW_FILEINFO_GETATTR,
+ .only_paths = 1,
+ .only_handles = 0,
+ .expected_ipc_access_denied = 1},
+ { .name ="GETATTRE",
+ .level = RAW_FILEINFO_GETATTRE,
+ .only_paths = 0,
+ .only_handles = 1 },
+ { .name ="STANDARD",
+ .level = RAW_FILEINFO_STANDARD, },
+ { .name ="EA_SIZE",
+ .level = RAW_FILEINFO_EA_SIZE },
+ { .name ="ALL_EAS",
+ .level = RAW_FILEINFO_ALL_EAS,
+ .expected_ipc_fnum_status = NT_STATUS_ACCESS_DENIED,
+ },
+ { .name ="IS_NAME_VALID",
+ .level = RAW_FILEINFO_IS_NAME_VALID,
+ .only_paths = 1,
+ .only_handles = 0 },
+ { .name ="BASIC_INFO",
+ .level = RAW_FILEINFO_BASIC_INFO },
+ { .name ="STANDARD_INFO",
+ .level = RAW_FILEINFO_STANDARD_INFO },
+ { .name ="EA_INFO",
+ .level = RAW_FILEINFO_EA_INFO },
+ { .name ="NAME_INFO",
+ .level = RAW_FILEINFO_NAME_INFO },
+ { .name ="ALL_INFO",
+ .level = RAW_FILEINFO_ALL_INFO },
+ { .name ="ALT_NAME_INFO",
+ .level = RAW_FILEINFO_ALT_NAME_INFO,
+ .expected_ipc_fnum_status = NT_STATUS_INVALID_PARAMETER
+ },
+ { .name ="STREAM_INFO",
+ .level = RAW_FILEINFO_STREAM_INFO,
+ .expected_ipc_fnum_status = NT_STATUS_INVALID_PARAMETER
+ },
+ { .name ="COMPRESSION_INFO",
+ .level = RAW_FILEINFO_COMPRESSION_INFO,
+ .expected_ipc_fnum_status = NT_STATUS_INVALID_PARAMETER
+ },
+ { .name ="UNIX_BASIC_INFO",
+ .level = RAW_FILEINFO_UNIX_BASIC,
+ .only_paths = 0,
+ .only_handles = 0,
+ .capability_mask = CAP_UNIX},
+ { .name ="UNIX_LINK_INFO",
+ .level = RAW_FILEINFO_UNIX_LINK,
+ .only_paths = 0,
+ .only_handles = 0,
+ .capability_mask = CAP_UNIX},
+ { .name ="BASIC_INFORMATION",
+ .level = RAW_FILEINFO_BASIC_INFORMATION },
+ { .name ="STANDARD_INFORMATION",
+ .level = RAW_FILEINFO_STANDARD_INFORMATION },
+ { .name ="INTERNAL_INFORMATION",
+ .level = RAW_FILEINFO_INTERNAL_INFORMATION },
+ { .name ="EA_INFORMATION",
+ .level = RAW_FILEINFO_EA_INFORMATION },
+ { .name = "ACCESS_INFORMATION",
+ .level = RAW_FILEINFO_ACCESS_INFORMATION },
+ { .name = "NAME_INFORMATION",
+ .level = RAW_FILEINFO_NAME_INFORMATION },
+ { .name ="POSITION_INFORMATION",
+ .level = RAW_FILEINFO_POSITION_INFORMATION },
+ { .name ="MODE_INFORMATION",
+ .level = RAW_FILEINFO_MODE_INFORMATION },
+ { .name ="ALIGNMENT_INFORMATION",
+ .level = RAW_FILEINFO_ALIGNMENT_INFORMATION },
+ { .name ="ALL_INFORMATION",
+ .level = RAW_FILEINFO_ALL_INFORMATION },
+ { .name ="ALT_NAME_INFORMATION",
+ .level = RAW_FILEINFO_ALT_NAME_INFORMATION,
+ .expected_ipc_fnum_status = NT_STATUS_INVALID_PARAMETER
+ },
+ { .name ="STREAM_INFORMATION",
+ .level = RAW_FILEINFO_STREAM_INFORMATION,
+ .expected_ipc_fnum_status = NT_STATUS_INVALID_PARAMETER
+ },
+ { .name = "COMPRESSION_INFORMATION",
+ .level = RAW_FILEINFO_COMPRESSION_INFORMATION,
+ .expected_ipc_fnum_status = NT_STATUS_INVALID_PARAMETER
+ },
+ { .name ="NETWORK_OPEN_INFORMATION",
+ .level = RAW_FILEINFO_NETWORK_OPEN_INFORMATION,
+ .expected_ipc_fnum_status = NT_STATUS_INVALID_PARAMETER
+ },
+ { .name = "ATTRIBUTE_TAG_INFORMATION",
+ .level = RAW_FILEINFO_ATTRIBUTE_TAG_INFORMATION,
+ .expected_ipc_fnum_status = NT_STATUS_INVALID_PARAMETER
+ },
+ { NULL }
};
/*
static int dos_nt_time_cmp(time_t t, NTTIME nt)
{
time_t t2 = nt_time_to_unix(nt);
- if (ABS(t2 - t) <= 2) return 0;
+ if (abs(t2 - t) <= 2) return 0;
return t2 - t;
}
/*
find a level in the levels[] table
*/
-static union smb_fileinfo *fname_find(const char *name)
+static union smb_fileinfo *fname_find(bool is_ipc, const char *name)
{
int i;
+ if (is_ipc) {
+ return NULL;
+ }
for (i=0; levels[i].name; i++) {
if (NT_STATUS_IS_OK(levels[i].fname_status) &&
strcmp(name, levels[i].name) == 0 &&
/* used to find hints on unknown values - and to make sure
we zero-fill */
+#if 0 /* unused */
#define VAL_UNKNOWN(n1, v1) do {if (s1->n1.out.v1 != 0) { \
printf("%s/%s non-zero unknown - %u (0x%x) at %s(%d)\n", \
#n1, #v1, \
__FILE__, __LINE__); \
ret = False; \
}} while(0)
+#endif
/* basic testing of all RAW_FILEINFO_* calls
for each call we test that it succeeds, and where possible test
for consistency between the calls.
*/
-BOOL torture_raw_qfileinfo(void)
+static BOOL torture_raw_qfileinfo_internals(struct torture_context *torture, TALLOC_CTX *mem_ctx,
+ struct smbcli_tree *tree, int fnum, const char *fname,
+ bool is_ipc)
{
- struct smbcli_state *cli;
int i;
BOOL ret = True;
int count;
union smb_fileinfo *s1, *s2;
- TALLOC_CTX *mem_ctx;
- int fnum;
- const char *fname = "\\torture_qfileinfo.txt";
NTTIME correct_time;
uint64_t correct_size;
uint32_t correct_attrib;
const char *correct_name;
BOOL skip_streams = False;
- if (!torture_open_connection(&cli)) {
- return False;
- }
-
- mem_ctx = talloc_init("torture_qfileinfo");
-
- fnum = create_complex_file(cli, mem_ctx, fname);
- if (fnum == -1) {
- printf("ERROR: open of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
- ret = False;
- goto done;
- }
-
-
/* scan all the fileinfo and pathinfo levels */
for (i=0; levels[i].name; i++) {
if (!levels[i].only_paths) {
levels[i].fnum_finfo.generic.level = levels[i].level;
- levels[i].fnum_finfo.generic.in.fnum = fnum;
- levels[i].fnum_status = smb_raw_fileinfo(cli->tree, mem_ctx,
+ levels[i].fnum_finfo.generic.in.file.fnum = fnum;
+ levels[i].fnum_status = smb_raw_fileinfo(tree, mem_ctx,
&levels[i].fnum_finfo);
}
if (!levels[i].only_handles) {
levels[i].fname_finfo.generic.level = levels[i].level;
- levels[i].fname_finfo.generic.in.fname = talloc_strdup(mem_ctx, fname);
- levels[i].fname_status = smb_raw_pathinfo(cli->tree, mem_ctx,
+ levels[i].fname_finfo.generic.in.file.path = talloc_strdup(mem_ctx, fname);
+ levels[i].fname_status = smb_raw_pathinfo(tree, mem_ctx,
&levels[i].fname_finfo);
}
}
/* check for completely broken levels */
for (count=i=0; levels[i].name; i++) {
- uint32_t cap = cli->transport->negotiate.capabilities;
+ uint32_t cap = tree->session->transport->negotiate.capabilities;
/* see if this server claims to support this level */
if ((cap & levels[i].capability_mask) != levels[i].capability_mask) {
continue;
}
- if (!levels[i].only_paths && !NT_STATUS_IS_OK(levels[i].fnum_status)) {
- printf("ERROR: level %s failed - %s\n",
- levels[i].name, nt_errstr(levels[i].fnum_status));
- count++;
- }
- if (!levels[i].only_handles && !NT_STATUS_IS_OK(levels[i].fname_status)) {
- printf("ERROR: level %s failed - %s\n",
- levels[i].name, nt_errstr(levels[i].fname_status));
- count++;
+ if (is_ipc) {
+ if (levels[i].expected_ipc_access_denied && NT_STATUS_EQUAL(NT_STATUS_ACCESS_DENIED, levels[i].fname_status)) {
+ } else if (!levels[i].only_handles && !NT_STATUS_EQUAL(NT_STATUS_INVALID_DEVICE_REQUEST, levels[i].fname_status)) {
+ printf("ERROR: fname level %s failed, expected NT_STATUS_INVALID_DEVICE_REQUEST - %s\n",
+ levels[i].name, nt_errstr(levels[i].fname_status));
+ count++;
+ }
+ if (!levels[i].only_paths && !NT_STATUS_EQUAL(levels[i].expected_ipc_fnum_status, levels[i].fnum_status)) {
+ printf("ERROR: fnum level %s failed, expected %s - %s\n",
+ levels[i].name, nt_errstr(levels[i].expected_ipc_fnum_status),
+ nt_errstr(levels[i].fnum_status));
+ count++;
+ }
+ } else {
+ if (!levels[i].only_paths && !NT_STATUS_IS_OK(levels[i].fnum_status)) {
+ printf("ERROR: fnum level %s failed - %s\n",
+ levels[i].name, nt_errstr(levels[i].fnum_status));
+ count++;
+ }
+ if (!levels[i].only_handles && !NT_STATUS_IS_OK(levels[i].fname_status)) {
+ printf("ERROR: fname level %s failed - %s\n",
+ levels[i].name, nt_errstr(levels[i].fname_status));
+ count++;
+ }
}
+
}
if (count != 0) {
/* see if we can do streams */
s1 = fnum_find("STREAM_INFO");
if (!s1 || s1->stream_info.out.num_streams == 0) {
- printf("STREAM_INFO broken (%d) - skipping streams checks\n",
- s1 ? s1->stream_info.out.num_streams : -1);
+ if (!is_ipc) {
+ printf("STREAM_INFO broken (%d) - skipping streams checks\n",
+ s1 ? s1->stream_info.out.num_streams : -1);
+ }
skip_streams = True;
}
do { \
s1 = fnum_find(sname1); s2 = fnum_find(sname2); \
if (s1 && s2) { INFO_CHECK } \
- s1 = fname_find(sname1); s2 = fname_find(sname2); \
+ s1 = fname_find(is_ipc, sname1); s2 = fname_find(is_ipc, sname2); \
if (s1 && s2) { INFO_CHECK } \
- s1 = fnum_find(sname1); s2 = fname_find(sname2); \
+ s1 = fnum_find(sname1); s2 = fname_find(is_ipc, sname2); \
if (s1 && s2) { INFO_CHECK } \
} while (0)
nt_time_string(mem_ctx, correct_time)); \
ret = False; \
} \
- s1 = fname_find(sname); \
+ s1 = fname_find(is_ipc, sname); \
if (s1 && memcmp(&s1->stype.out.tfield, &correct_time, sizeof(correct_time)) != 0) { \
printf("(%d) path %s/%s incorrect - %s should be %s\n", __LINE__, #stype, #tfield, \
nt_time_string(mem_ctx, s1->stype.out.tfield), \
nt_time_string(mem_ctx, correct_time)); \
ret = False; \
} \
- s1 = fname_find(sname); \
+ s1 = fname_find(is_ipc, sname); \
if (s1 && dos_nt_time_cmp(s1->stype.out.tfield, correct_time) != 0) { \
printf("(%d) path %s/%s incorrect - %s should be %s\n", __LINE__, #stype, #tfield, \
timestring(mem_ctx, s1->stype.out.tfield), \
ret = False; \
}} while (0)
+#if 0 /* unused */
#define TIME_CHECK_UNX(sname, stype, tfield) do { \
s1 = fnum_find(sname); \
if (s1 && unx_nt_time_cmp(s1->stype.out.tfield, correct_time) != 0) { \
nt_time_string(mem_ctx, correct_time)); \
ret = False; \
} \
- s1 = fname_find(sname); \
+ s1 = fname_find(is_ipc, sname); \
if (s1 && unx_nt_time_cmp(s1->stype.out.tfield, correct_time) != 0) { \
printf("(%d) path %s/%s incorrect - %s should be %s\n", __LINE__, #stype, #tfield, \
timestring(mem_ctx, s1->stype.out.tfield), \
nt_time_string(mem_ctx, correct_time)); \
ret = False; \
}} while (0)
+#endif
/* now check that all the times that are supposed to be equal are correct */
s1 = fnum_find("BASIC_INFO");
(uint_t)correct_size); \
ret = False; \
} \
- s1 = fname_find(sname); \
+ s1 = fname_find(is_ipc, sname); \
if (s1 && s1->stype.out.tfield != correct_size) { \
printf("(%d) path %s/%s incorrect - %u should be %u\n", __LINE__, #stype, #tfield, \
(uint_t)s1->stype.out.tfield, \
(uint_t)correct_attrib); \
ret = False; \
} \
- s1 = fname_find(sname); \
+ s1 = fname_find(is_ipc, sname); \
if (s1 && s1->stype.out.tfield != correct_attrib) { \
printf("(%d) path %s/%s incorrect - 0x%x should be 0x%x\n", __LINE__, #stype, #tfield, \
(uint_t)s1->stype.out.tfield, \
printf("attrib: 0x%x\n", (uint_t)correct_attrib);
ATTRIB_CHECK("GETATTR", getattr, attrib);
- ATTRIB_CHECK("GETATTRE", getattre, attrib);
- ATTRIB_CHECK("STANDARD", standard, attrib);
+ if (!is_ipc) {
+ ATTRIB_CHECK("GETATTRE", getattre, attrib);
+ ATTRIB_CHECK("STANDARD", standard, attrib);
+ ATTRIB_CHECK("EA_SIZE", ea_size, attrib);
+ }
ATTRIB_CHECK("BASIC_INFO", basic_info, attrib);
ATTRIB_CHECK("BASIC_INFORMATION", basic_info, attrib);
- ATTRIB_CHECK("EA_SIZE", ea_size, attrib);
ATTRIB_CHECK("ALL_INFO", all_info, attrib);
ATTRIB_CHECK("ALL_INFORMATION", all_info, attrib);
ATTRIB_CHECK("NETWORK_OPEN_INFORMATION", network_open_information, attrib);
#define NAME_CHECK(sname, stype, tfield, flags) do { \
s1 = fnum_find(sname); \
if (s1 && (strcmp_safe(s1->stype.out.tfield.s, correct_name) != 0 || \
- wire_bad_flags(&s1->stype.out.tfield, flags, cli))) { \
+ wire_bad_flags(&s1->stype.out.tfield, flags, tree->session->transport))) { \
printf("(%d) handle %s/%s incorrect - '%s/%d'\n", __LINE__, #stype, #tfield, \
s1->stype.out.tfield.s, s1->stype.out.tfield.private_length); \
ret = False; \
} \
- s1 = fname_find(sname); \
+ s1 = fname_find(is_ipc, sname); \
if (s1 && (strcmp_safe(s1->stype.out.tfield.s, correct_name) != 0 || \
- wire_bad_flags(&s1->stype.out.tfield, flags, cli))) { \
+ wire_bad_flags(&s1->stype.out.tfield, flags, tree->session->transport))) { \
printf("(%d) path %s/%s incorrect - '%s/%d'\n", __LINE__, #stype, #tfield, \
s1->stype.out.tfield.s, s1->stype.out.tfield.private_length); \
ret = False; \
ret = False;
}
}
- if (wire_bad_flags(&s1->all_info.out.fname, STR_UNICODE, cli)) {
+ if (wire_bad_flags(&s1->all_info.out.fname, STR_UNICODE, tree->session->transport)) {
printf("Should not null terminate all_info/fname\n");
ret = False;
}
}
s1 = fnum_find("ALT_NAME_INFO");
- correct_name = s1->alt_name_info.out.fname.s;
- printf("alt_name: %s\n", correct_name);
-
- NAME_CHECK("ALT_NAME_INFO", alt_name_info, fname, STR_UNICODE);
- NAME_CHECK("ALT_NAME_INFORMATION", alt_name_info, fname, STR_UNICODE);
-
- /* and make sure we can open by alternate name */
- smbcli_close(cli->tree, fnum);
- fnum = smbcli_nt_create_full(cli->tree, correct_name, 0, GENERIC_RIGHTS_FILE_ALL_ACCESS,
- FILE_ATTRIBUTE_NORMAL,
- NTCREATEX_SHARE_ACCESS_DELETE|
- NTCREATEX_SHARE_ACCESS_READ|
- NTCREATEX_SHARE_ACCESS_WRITE,
- NTCREATEX_DISP_OVERWRITE_IF,
- 0, 0);
- if (fnum == -1) {
- printf("Unable to open by alt_name - %s\n", smbcli_errstr(cli->tree));
- ret = False;
- }
-
- if (!skip_streams) {
- correct_name = "::$DATA";
- printf("stream_name: %s\n", correct_name);
-
- NAME_CHECK("STREAM_INFO", stream_info, streams[0].stream_name, STR_UNICODE);
- NAME_CHECK("STREAM_INFORMATION", stream_info, streams[0].stream_name, STR_UNICODE);
+ if (s1) {
+ correct_name = s1->alt_name_info.out.fname.s;
+ printf("alt_name: %s\n", correct_name);
+
+ NAME_CHECK("ALT_NAME_INFO", alt_name_info, fname, STR_UNICODE);
+ NAME_CHECK("ALT_NAME_INFORMATION", alt_name_info, fname, STR_UNICODE);
+
+ /* and make sure we can open by alternate name */
+ smbcli_close(tree, fnum);
+ fnum = smbcli_nt_create_full(tree, correct_name, 0,
+ SEC_RIGHTS_FILE_ALL,
+ FILE_ATTRIBUTE_NORMAL,
+ NTCREATEX_SHARE_ACCESS_DELETE|
+ NTCREATEX_SHARE_ACCESS_READ|
+ NTCREATEX_SHARE_ACCESS_WRITE,
+ NTCREATEX_DISP_OVERWRITE_IF,
+ 0, 0);
+ if (fnum == -1) {
+ printf("Unable to open by alt_name - %s\n", smbcli_errstr(tree));
+ ret = False;
+ }
+
+ if (!skip_streams) {
+ correct_name = "::$DATA";
+ printf("stream_name: %s\n", correct_name);
+
+ NAME_CHECK("STREAM_INFO", stream_info, streams[0].stream_name, STR_UNICODE);
+ NAME_CHECK("STREAM_INFORMATION", stream_info, streams[0].stream_name, STR_UNICODE);
+ }
}
-
+
/* make sure the EAs look right */
s1 = fnum_find("ALL_EAS");
s2 = fnum_find("ALL_INFO");
printf(" flags=%d %s=%*.*s\n",
s1->all_eas.out.eas[i].flags,
s1->all_eas.out.eas[i].name.s,
- s1->all_eas.out.eas[i].value.length,
- s1->all_eas.out.eas[i].value.length,
+ (int)s1->all_eas.out.eas[i].value.length,
+ (int)s1->all_eas.out.eas[i].value.length,
s1->all_eas.out.eas[i].value.data);
}
}
if (s2->all_info.out.ea_size !=
ea_list_size(s1->all_eas.out.num_eas, s1->all_eas.out.eas)) {
printf("ERROR: ea_list_size=%d != fnum all_info.out.ea_size=%d\n",
- ea_list_size(s1->all_eas.out.num_eas, s1->all_eas.out.eas),
- s2->all_info.out.ea_size);
+ (int)ea_list_size(s1->all_eas.out.num_eas, s1->all_eas.out.eas),
+ (int)s2->all_info.out.ea_size);
}
}
}
- s2 = fname_find("ALL_EAS");
+ s2 = fname_find(is_ipc, "ALL_EAS");
if (s2) {
VAL_EQUAL(all_eas, num_eas, all_eas, num_eas);
for (i=0;i<s1->all_eas.out.num_eas;i++) {
s1->stype1.out.tfield1, s2->stype2.out.tfield2); \
ret = False; \
} \
- s1 = fname_find(sname1); s2 = fname_find(sname2); \
+ s1 = fname_find(is_ipc, sname1); s2 = fname_find(is_ipc, sname2); \
if (s1 && s2 && s1->stype1.out.tfield1 != s2->stype2.out.tfield2) { \
printf("(%d) path %s/%s != %s/%s - 0x%x vs 0x%x\n", __LINE__, \
#stype1, #tfield1, #stype2, #tfield2, \
s1->stype1.out.tfield1, s2->stype2.out.tfield2); \
ret = False; \
} \
- s1 = fnum_find(sname1); s2 = fname_find(sname2); \
+ s1 = fnum_find(sname1); s2 = fname_find(is_ipc, sname2); \
if (s1 && s2 && s1->stype1.out.tfield1 != s2->stype2.out.tfield2) { \
printf("(%d) handle %s/%s != path %s/%s - 0x%x vs 0x%x\n", __LINE__, \
#stype1, #tfield1, #stype2, #tfield2, \
s1->stype1.out.tfield1, s2->stype2.out.tfield2); \
ret = False; \
} \
- s1 = fname_find(sname1); s2 = fnum_find(sname2); \
+ s1 = fname_find(is_ipc, sname1); s2 = fnum_find(sname2); \
if (s1 && s2 && s1->stype1.out.tfield1 != s2->stype2.out.tfield2) { \
printf("(%d) path %s/%s != handle %s/%s - 0x%x vs 0x%x\n", __LINE__, \
#stype1, #tfield1, #stype2, #tfield2, \
"ALL_INFO", all_info, directory);
VAL_CHECK("STANDARD_INFO", standard_info, nlink,
"ALL_INFO", all_info, nlink);
+ s1 = fnum_find("BASIC_INFO");
+ if (s1 && is_ipc) {
+ if (s1->basic_info.out.attrib != FILE_ATTRIBUTE_NORMAL) {
+ printf("(%d) attrib basic_info/nlink incorrect - %d should be %d\n", __LINE__, s1->basic_info.out.attrib, FILE_ATTRIBUTE_NORMAL);
+ ret = False;
+ }
+ }
+ s1 = fnum_find("STANDARD_INFO");
+ if (s1 && is_ipc) {
+ if (s1->standard_info.out.nlink != 1) {
+ printf("(%d) nlinks standard_info/nlink incorrect - %d should be 1\n", __LINE__, s1->standard_info.out.nlink);
+ ret = False;
+ }
+ if (s1->standard_info.out.delete_pending != 1) {
+ printf("(%d) nlinks standard_info/delete_pending incorrect - %d should be 1\n", __LINE__, s1->standard_info.out.delete_pending);
+ ret = False;
+ }
+ }
VAL_CHECK("EA_INFO", ea_info, ea_size,
"ALL_INFO", all_info, ea_size);
- VAL_CHECK("EA_SIZE", ea_size, ea_size,
- "ALL_INFO", all_info, ea_size);
-
+ if (!is_ipc) {
+ VAL_CHECK("EA_SIZE", ea_size, ea_size,
+ "ALL_INFO", all_info, ea_size);
+ }
#define NAME_PATH_CHECK(sname, stype, field) do { \
- s1 = fname_find(sname); s2 = fnum_find(sname); \
+ s1 = fname_find(is_ipc, sname); s2 = fnum_find(sname); \
if (s1 && s2) { \
VAL_EQUAL(stype, field, stype, field); \
} \
NAME_PATH_CHECK("ACCESS_INFORMATION", access_information, access_flags);
#endif
+#if 0 /* unused */
#define UNKNOWN_CHECK(sname, stype, tfield) do { \
s1 = fnum_find(sname); \
if (s1 && s1->stype.out.tfield != 0) { \
#stype, #tfield, \
(uint_t)s1->stype.out.tfield); \
} \
- s1 = fname_find(sname); \
+ s1 = fname_find(is_ipc, sname); \
if (s1 && s1->stype.out.tfield != 0) { \
printf("(%d) path %s/%s unknown != 0 (0x%x)\n", __LINE__, \
#stype, #tfield, \
(uint_t)s1->stype.out.tfield); \
}} while (0)
-
+#endif
/* now get a bit fancier .... */
/* when we set the delete disposition then the link count should drop
done:
+
+ return ret;
+}
+
+/* basic testing of all RAW_FILEINFO_* calls
+ for each call we test that it succeeds, and where possible test
+ for consistency between the calls.
+*/
+BOOL torture_raw_qfileinfo(struct torture_context *torture)
+{
+ struct smbcli_state *cli;
+ BOOL ret = True;
+ TALLOC_CTX *mem_ctx;
+ int fnum;
+ const char *fname = "\\torture_qfileinfo.txt";
+
+ if (!torture_open_connection(&cli, 0)) {
+ return False;
+ }
+
+ mem_ctx = talloc_init("torture_qfileinfo");
+
+ fnum = create_complex_file(cli, mem_ctx, fname);
+ if (fnum == -1) {
+ printf("ERROR: open of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
+ ret = False;
+ goto done;
+ }
+
+ ret = torture_raw_qfileinfo_internals(torture, mem_ctx, cli->tree, fnum, fname, False /* is_ipc */);
+
smbcli_close(cli->tree, fnum);
smbcli_unlink(cli->tree, fname);
+done:
torture_close_connection(cli);
- talloc_destroy(mem_ctx);
+ talloc_free(mem_ctx);
+ return ret;
+}
+
+BOOL torture_raw_qfileinfo_pipe(struct torture_context *torture)
+{
+ TALLOC_CTX *mem_ctx;
+ BOOL ret = True;
+ int fnum;
+ const char *fname = "\\lsass";
+ struct smbcli_state *cli;
+ struct dcerpc_pipe *p;
+ struct smbcli_tree *ipc_tree;
+ NTSTATUS status;
+
+ if (!torture_open_connection(&cli, 0)) {
+ return False;
+ }
+
+ mem_ctx = talloc_init("torture_qfileinfo_pipe");
+
+ if (!(p = dcerpc_pipe_init(mem_ctx,
+ cli->tree->session->transport->socket->event.ctx))) {
+ return False;
+ }
+
+ status = dcerpc_pipe_open_smb(p, cli->tree, fname);
+ if (!NT_STATUS_IS_OK(status)) {
+ d_printf("dcerpc_pipe_open_smb failed: %s\n",
+ nt_errstr(status));
+ talloc_free(p);
+ return False;
+ }
+
+ ipc_tree = dcerpc_smb_tree(p->conn);
+ fnum = dcerpc_smb_fnum(p->conn);
+
+ ret = torture_raw_qfileinfo_internals(torture, mem_ctx, ipc_tree, fnum, fname, True /* is_ipc */);
+
+ talloc_free(p);
return ret;
}