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

remove some unused files

This commit is contained in:
Andrew Tridgell 0001-01-01 00:00:00 +00:00
parent 564e505e92
commit a6f43de7f8
9 changed files with 0 additions and 4386 deletions

View File

@ -1,514 +0,0 @@
/*
Unix SMB/CIFS implementation.
SAM module functions
Copyright (C) Jelmer Vernooij 2002
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
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
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.
*/
#include "includes.h"
#include "samtest.h"
static void print_account(SAM_ACCOUNT_HANDLE *a)
{
/* FIXME */
}
static NTSTATUS cmd_context(struct samtest_state *st, TALLOC_CTX *mem_ctx, int argc, char **argv)
{
NTSTATUS status;
char **plugins;
int i;
plugins = malloc(argc * sizeof(char *));
for(i = 1; i < argc; i++)
plugins[i-1] = argv[i];
plugins[argc-1] = NULL;
if(!NT_STATUS_IS_OK(status = make_sam_context_list(&st->context, plugins))) {
printf("make_sam_context_list failed: %s\n", nt_errstr(status));
SAFE_FREE(plugins);
return status;
}
SAFE_FREE(plugins);
return NT_STATUS_OK;
}
static NTSTATUS cmd_load_module(struct samtest_state *st, TALLOC_CTX *mem_ctx, int argc, char **argv)
{
char *plugin_arg[2];
NTSTATUS status;
if (argc != 2 && argc != 3) {
printf("Usage: load <module path> [domain-name]\n");
return NT_STATUS_OK;
}
if (argc == 3)
asprintf(&plugin_arg[0], "plugin:%s|%s", argv[1], argv[2]);
else
asprintf(&plugin_arg[0], "plugin:%s", argv[1]);
plugin_arg[1] = NULL;
if(!NT_STATUS_IS_OK(status = make_sam_context_list(&st->context, plugin_arg))) {
free(plugin_arg[0]);
return status;
}
free(plugin_arg[0]);
printf("load: ok\n");
return NT_STATUS_OK;
}
static NTSTATUS cmd_get_sec_desc(struct samtest_state *st, TALLOC_CTX *mem_ctx, int argc, char **argv)
{
return NT_STATUS_NOT_IMPLEMENTED;
}
static NTSTATUS cmd_set_sec_desc(struct samtest_state *st, TALLOC_CTX *mem_ctx, int argc, char **argv)
{
return NT_STATUS_NOT_IMPLEMENTED;
}
static NTSTATUS cmd_lookup_sid(struct samtest_state *st, TALLOC_CTX *mem_ctx, int argc, char **argv)
{
char *name;
uint32 type;
NTSTATUS status;
DOM_SID sid;
if (argc != 2) {
printf("Usage: lookup_sid <sid>\n");
return NT_STATUS_INVALID_PARAMETER;
}
if (!string_to_sid(&sid, argv[1])){
printf("Unparseable SID specified!\n");
return NT_STATUS_INVALID_PARAMETER;
}
if (!NT_STATUS_IS_OK(status = sam_lookup_sid(st->context, st->token, mem_ctx, &sid, &name, &type))) {
printf("sam_lookup_sid failed!\n");
return status;
}
printf("Name: %s\n", name);
printf("Type: %d\n", type); /* FIXME: What kind of an integer is type ? */
return NT_STATUS_OK;
}
static NTSTATUS cmd_lookup_name(struct samtest_state *st, TALLOC_CTX *mem_ctx, int argc, char **argv)
{
DOM_SID sid;
uint32 type;
NTSTATUS status;
if (argc != 3) {
printf("Usage: lookup_name <domain> <name>\n");
return NT_STATUS_INVALID_PARAMETER;
}
if (!NT_STATUS_IS_OK(status = sam_lookup_name(st->context, st->token, argv[1], argv[2], &sid, &type))) {
printf("sam_lookup_name failed!\n");
return status;
}
printf("SID: %s\n", sid_string_static(&sid));
printf("Type: %d\n", type);
return NT_STATUS_OK;
}
static NTSTATUS cmd_lookup_account(struct samtest_state *st, TALLOC_CTX *mem_ctx, int argc, char **argv)
{
return NT_STATUS_NOT_IMPLEMENTED;
}
static NTSTATUS cmd_lookup_group(struct samtest_state *st, TALLOC_CTX *mem_ctx, int argc, char **argv)
{
return NT_STATUS_NOT_IMPLEMENTED;
}
static NTSTATUS cmd_lookup_domain(struct samtest_state *st, TALLOC_CTX *mem_ctx, int argc, char **argv)
{
DOM_SID *sid;
NTSTATUS status;
if (argc != 2) {
printf("Usage: lookup_domain <domain>\n");
return NT_STATUS_INVALID_PARAMETER;
}
if (!NT_STATUS_IS_OK(status = sam_lookup_domain(st->context, st->token, argv[1], &sid))) {
printf("sam_lookup_name failed!\n");
return status;
}
printf("SID: %s\n", sid_string_static(sid));
return NT_STATUS_OK;
}
static NTSTATUS cmd_enum_domains(struct samtest_state *st, TALLOC_CTX *mem_ctx, int argc, char **argv)
{
int32 domain_count, i;
DOM_SID *domain_sids;
char **domain_names;
NTSTATUS status;
if (!NT_STATUS_IS_OK(status = sam_enum_domains(st->context, st->token, &domain_count, &domain_sids, &domain_names))) {
printf("sam_enum_domains failed!\n");
return status;
}
if (domain_count == 0) {
printf("No domains found!\n");
return NT_STATUS_OK;
}
for (i = 0; i < domain_count; i++) {
printf("%s %s\n", domain_names[i], sid_string_static(&domain_sids[i]));
}
SAFE_FREE(domain_sids);
SAFE_FREE(domain_names);
return NT_STATUS_OK;
}
static NTSTATUS cmd_update_domain(struct samtest_state *st, TALLOC_CTX *mem_ctx, int argc, char **argv)
{
return NT_STATUS_NOT_IMPLEMENTED;
}
static NTSTATUS cmd_show_domain(struct samtest_state *st, TALLOC_CTX *mem_ctx, int argc, char **argv)
{
NTSTATUS status;
DOM_SID sid;
SAM_DOMAIN_HANDLE *domain;
uint32 tmp_uint32;
uint16 tmp_uint16;
NTTIME tmp_nttime;
BOOL tmp_bool;
const char *tmp_string;
if (argc != 2) {
printf("Usage: show_domain <sid>\n");
return status;
}
if (!string_to_sid(&sid, argv[1])){
printf("Unparseable SID specified!\n");
return NT_STATUS_INVALID_PARAMETER;
}
if (!NT_STATUS_IS_OK(status = sam_get_domain_by_sid(st->context, st->token, GENERIC_RIGHTS_DOMAIN_ALL_ACCESS, &sid, &domain))) {
printf("sam_get_domain_by_sid failed\n");
return status;
}
if (!NT_STATUS_IS_OK(status = sam_get_domain_num_accounts(domain, &tmp_uint32))) {
printf("sam_get_domain_num_accounts failed: %s\n", nt_errstr(status));
} else {
printf("Number of accounts: %d\n", tmp_uint32);
}
if (!NT_STATUS_IS_OK(status = sam_get_domain_num_groups(domain, &tmp_uint32))) {
printf("sam_get_domain_num_groups failed: %s\n", nt_errstr(status));
} else {
printf("Number of groups: %u\n", tmp_uint32);
}
if (!NT_STATUS_IS_OK(status = sam_get_domain_num_aliases(domain, &tmp_uint32))) {
printf("sam_get_domain_num_aliases failed: %s\n", nt_errstr(status));
} else {
printf("Number of aliases: %u\n", tmp_uint32);
}
if (!NT_STATUS_IS_OK(status = sam_get_domain_name(domain, &tmp_string))) {
printf("sam_get_domain_name failed: %s\n", nt_errstr(status));
} else {
printf("Domain Name: %s\n", tmp_string);
}
if (!NT_STATUS_IS_OK(status = sam_get_domain_lockout_count(domain, &tmp_uint16))) {
printf("sam_get_domain_lockout_count failed: %s\n", nt_errstr(status));
} else {
printf("Lockout Count: %u\n", tmp_uint16);
}
if (!NT_STATUS_IS_OK(status = sam_get_domain_force_logoff(domain, &tmp_bool))) {
printf("sam_get_domain_force_logoff failed: %s\n", nt_errstr(status));
} else {
printf("Force Logoff: %s\n", (tmp_bool?"Yes":"No"));
}
if (!NT_STATUS_IS_OK(status = sam_get_domain_lockout_duration(domain, &tmp_nttime))) {
printf("sam_get_domain_lockout_duration failed: %s\n", nt_errstr(status));
} else {
printf("Lockout duration: %u\n", tmp_nttime.low);
}
if (!NT_STATUS_IS_OK(status = sam_get_domain_login_pwdchange(domain, &tmp_bool))) {
printf("sam_get_domain_login_pwdchange failed: %s\n", nt_errstr(status));
} else {
printf("Password changing allowed: %s\n", (tmp_bool?"Yes":"No"));
}
if (!NT_STATUS_IS_OK(status = sam_get_domain_max_pwdage(domain, &tmp_nttime))) {
printf("sam_get_domain_max_pwdage failed: %s\n", nt_errstr(status));
} else {
printf("Maximum password age: %u\n", tmp_nttime.low);
}
if (!NT_STATUS_IS_OK(status = sam_get_domain_min_pwdage(domain, &tmp_nttime))) {
printf("sam_get_domain_min_pwdage failed: %s\n", nt_errstr(status));
} else {
printf("Minimal password age: %u\n", tmp_nttime.low);
}
if (!NT_STATUS_IS_OK(status = sam_get_domain_min_pwdlength(domain, &tmp_uint16))) {
printf("sam_get_domain_min_pwdlength: %s\n", nt_errstr(status));
} else {
printf("Minimal Password Length: %u\n", tmp_uint16);
}
if (!NT_STATUS_IS_OK(status = sam_get_domain_pwd_history(domain, &tmp_uint16))) {
printf("sam_get_domain_pwd_history failed: %s\n", nt_errstr(status));
} else {
printf("Password history: %u\n", tmp_uint16);
}
if (!NT_STATUS_IS_OK(status = sam_get_domain_reset_count(domain, &tmp_nttime))) {
printf("sam_get_domain_reset_count failed: %s\n", nt_errstr(status));
} else {
printf("Reset count: %u\n", tmp_nttime.low);
}
if (!NT_STATUS_IS_OK(status = sam_get_domain_server(domain, &tmp_string))) {
printf("sam_get_domain_server failed: %s\n", nt_errstr(status));
} else {
printf("Server: %s\n", tmp_string);
}
return NT_STATUS_OK;
}
static NTSTATUS cmd_create_account(struct samtest_state *st, TALLOC_CTX *mem_ctx, int argc, char **argv)
{
return NT_STATUS_NOT_IMPLEMENTED;
}
static NTSTATUS cmd_update_account(struct samtest_state *st, TALLOC_CTX *mem_ctx, int argc, char **argv)
{
return NT_STATUS_NOT_IMPLEMENTED;
}
static NTSTATUS cmd_delete_account(struct samtest_state *st, TALLOC_CTX *mem_ctx, int argc, char **argv)
{
return NT_STATUS_NOT_IMPLEMENTED;
}
static NTSTATUS cmd_enum_accounts(struct samtest_state *st, TALLOC_CTX *mem_ctx, int argc, char **argv)
{
NTSTATUS status;
DOM_SID sid;
int32 account_count, i;
SAM_ACCOUNT_ENUM *accounts;
if (argc != 2) {
printf("Usage: enum_accounts <domain-sid>\n");
return NT_STATUS_INVALID_PARAMETER;
}
if (!string_to_sid(&sid, argv[1])){
printf("Unparseable SID specified!\n");
return NT_STATUS_INVALID_PARAMETER;
}
if (!NT_STATUS_IS_OK(status = sam_enum_accounts(st->context, st->token, &sid, 0, &account_count, &accounts))) {
printf("sam_enum_accounts failed: %s\n", nt_errstr(status));
return status;
}
if (account_count == 0) {
printf("No accounts found!\n");
return NT_STATUS_OK;
}
for (i = 0; i < account_count; i++)
printf("SID: %s\nName: %s\nFullname: %s\nDescription: %s\nACB_BITS: %08X\n\n",
sid_string_static(&accounts[i].sid), accounts[i].account_name,
accounts[i].full_name, accounts[i].account_desc,
accounts[i].acct_ctrl);
SAFE_FREE(accounts);
return NT_STATUS_OK;
}
static NTSTATUS cmd_lookup_account_sid(struct samtest_state *st, TALLOC_CTX *mem_ctx, int argc, char **argv)
{
NTSTATUS status;
DOM_SID sid;
SAM_ACCOUNT_HANDLE *account;
if (argc != 2) {
printf("Usage: lookup_account_sid <account-sid>\n");
return NT_STATUS_INVALID_PARAMETER;
}
if (!string_to_sid(&sid, argv[1])){
printf("Unparseable SID specified!\n");
return NT_STATUS_INVALID_PARAMETER;
}
if (!NT_STATUS_IS_OK(status = sam_get_account_by_sid(st->context, st->token, GENERIC_RIGHTS_USER_ALL_ACCESS, &sid, &account))) {
printf("context_sam_get_account_by_sid failed: %s\n", nt_errstr(status));
return status;
}
print_account(account);
return NT_STATUS_OK;
}
static NTSTATUS cmd_lookup_account_name(struct samtest_state *st, TALLOC_CTX *mem_ctx, int argc, char **argv)
{
NTSTATUS status;
SAM_ACCOUNT_HANDLE *account;
if (argc != 3) {
printf("Usage: lookup_account_name <domain-name> <account-name>\n");
return NT_STATUS_INVALID_PARAMETER;
}
if (!NT_STATUS_IS_OK(status = sam_get_account_by_name(st->context, st->token, GENERIC_RIGHTS_USER_ALL_ACCESS, argv[1], argv[2], &account))) {
printf("context_sam_get_account_by_sid failed: %s\n", nt_errstr(status));
return status;
}
print_account(account);
return NT_STATUS_OK;
}
static NTSTATUS cmd_create_group(struct samtest_state *st, TALLOC_CTX *mem_ctx, int argc, char **argv)
{
return NT_STATUS_NOT_IMPLEMENTED;
}
static NTSTATUS cmd_update_group(struct samtest_state *st, TALLOC_CTX *mem_ctx, int argc, char **argv)
{
return NT_STATUS_NOT_IMPLEMENTED;
}
static NTSTATUS cmd_delete_group(struct samtest_state *st, TALLOC_CTX *mem_ctx, int argc, char **argv)
{
return NT_STATUS_NOT_IMPLEMENTED;
}
static NTSTATUS cmd_enum_groups(struct samtest_state *st, TALLOC_CTX *mem_ctx, int argc, char **argv)
{
return NT_STATUS_NOT_IMPLEMENTED;
}
static NTSTATUS cmd_lookup_group_sid(struct samtest_state *st, TALLOC_CTX *mem_ctx, int argc, char **argv)
{
return NT_STATUS_NOT_IMPLEMENTED;
}
static NTSTATUS cmd_lookup_group_name(struct samtest_state *st, TALLOC_CTX *mem_ctx, int argc, char **argv)
{
return NT_STATUS_NOT_IMPLEMENTED;
}
static NTSTATUS cmd_group_add_member(struct samtest_state *st, TALLOC_CTX *mem_ctx, int argc, char **argv)
{
return NT_STATUS_NOT_IMPLEMENTED;
}
static NTSTATUS cmd_group_del_member(struct samtest_state *st, TALLOC_CTX *mem_ctx, int argc, char **argv)
{
return NT_STATUS_NOT_IMPLEMENTED;
}
static NTSTATUS cmd_group_enum(struct samtest_state *st, TALLOC_CTX *mem_ctx, int argc, char **argv)
{
return NT_STATUS_NOT_IMPLEMENTED;
}
static NTSTATUS cmd_get_sid_groups(struct samtest_state *st, TALLOC_CTX *mem_ctx, int argc, char **argv)
{
return NT_STATUS_NOT_IMPLEMENTED;
}
struct cmd_set sam_general_commands[] = {
{ "General SAM Commands" },
{ "load", cmd_load_module, "Load a module", "load <module.so> [domain-sid]" },
{ "context", cmd_context, "Load specified context", "context [DOMAIN|]backend1[:options] [DOMAIN|]backend2[:options]" },
{ "get_sec_desc", cmd_get_sec_desc, "Get security descriptor info", "get_sec_desc <access-token> <sid>" },
{ "set_sec_desc", cmd_set_sec_desc, "Set security descriptor info", "set_sec_desc <access-token> <sid>" },
{ "lookup_sid", cmd_lookup_sid, "Lookup type of specified SID", "lookup_sid <sid>" },
{ "lookup_name", cmd_lookup_name, "Lookup type of specified name", "lookup_name <sid>" },
{ NULL }
};
struct cmd_set sam_domain_commands[] = {
{ "Domain Commands" },
{ "update_domain", cmd_update_domain, "Update domain information", "update_domain [domain-options] domain-name | domain-sid" },
{ "show_domain", cmd_show_domain, "Show domain information", "show_domain domain-sid | domain-name" },
{ "enum_domains", cmd_enum_domains, "Enumerate all domains", "enum_domains <token> <acct-ctrl>" },
{ "lookup_domain", cmd_lookup_domain, "Lookup a domain by name", "lookup_domain domain-name" },
{ NULL }
};
struct cmd_set sam_account_commands[] = {
{ "Account Commands" },
{ "create_account", cmd_create_account, "Create a new account with specified properties", "create_account [account-options]" },
{ "update_account", cmd_update_account, "Update an existing account", "update_account [account-options] account-sid | account-name" },
{ "delete_account", cmd_delete_account, "Delete an account", "delete_account account-sid | account-name" },
{ "enum_accounts", cmd_enum_accounts, "Enumerate all accounts", "enum_accounts <token> <acct-ctrl>" },
{ "lookup_account", cmd_lookup_account, "Lookup an account by either sid or name", "lookup_account account-sid | account-name" },
{ "lookup_account_sid", cmd_lookup_account_sid, "Lookup an account by sid", "lookup_account_sid account-sid" },
{ "lookup_account_name", cmd_lookup_account_name, "Lookup an account by name", "lookup_account_name account-name" },
{ NULL }
};
struct cmd_set sam_group_commands[] = {
{ "Group Commands" },
{ "create_group", cmd_create_group, "Create a new group", "create_group [group-opts]" },
{ "update_group", cmd_update_group, "Update an existing group", "update_group [group-opts] group-name | group-sid" },
{ "delete_group", cmd_delete_group, "Delete an existing group", "delete_group group-name | group-sid" },
{ "enum_groups", cmd_enum_groups, "Enumerate all groups", "enum_groups <token> <group-ctrl>" },
{ "lookup_group", cmd_lookup_group, "Lookup a group by SID or name", "lookup_group group-sid | group-name" },
{ "lookup_group_sid", cmd_lookup_group_sid, "Lookup a group by SID", "lookup_group_sid <sid>" },
{ "lookup_group_name", cmd_lookup_group_name, "Lookup a group by name", "lookup_group_name <name>" },
{ "group_add_member", cmd_group_add_member, "Add group member to group", "group_add_member <group-name | group-sid> <member-name | member-sid>" },
{ "group_del_member", cmd_group_del_member, "Delete group member from group", "group_del_member <group-name | group-sid> <member-name | member-sid>" },
{ "group_enum", cmd_group_enum, "Enumerate all members of specified group", "group_enum group-sid | group-name" },
{ "get_sid_groups", cmd_get_sid_groups, "Get a list of groups specified sid is a member of", "group_enum <group-sid | group-name>" },
{ NULL }
};

File diff suppressed because it is too large Load Diff

View File

@ -1,83 +0,0 @@
/*
Unix SMB/CIFS implementation.
Gentest test definitions
Copyright (C) James Myers 2003
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
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
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.
*/
get_field_function test_field_get_file_attr;
get_field_function test_field_get_fid;
get_field_function test_field_get_filename;
get_field_function test_field_get_mtime;
get_field_function test_field_get_trans2;
get_field_function test_field_get_fsinfo_level;
static struct unlink_test_parms_t gen_unlink_test_parms;
static struct close_test_parms_t gen_close_test_parms;
static struct qfsi_test_parms_t gen_qfsi_test_parms;
static struct trans2_parms trans2_qfsi_parms = {
testFieldTypeTrans2, 1, 2, 0, 0, TRANSACT2_QFSINFO
};
static struct field_test_spec gen_unlink_test_spec[] = {
{"FATTR", testFieldTypeFileAttr, NULL,
1, test_field_get_file_attr},
{"FNAME", testFieldTypeFilename, NULL,
-1, test_field_get_filename},
{"", -1, NULL, -1, NULL}
};
static struct field_test_spec gen_close_test_spec[] = {
{"FID", testFieldTypeFid, NULL, 1,
test_field_get_fid},
{"MTIME", testFieldTypeMtime, NULL, 2,
test_field_get_mtime},
{"", -1, NULL, -1, NULL}
};
static struct field_test_spec gen_qfsi_test_spec[] = {
{"TRANS2", testFieldTypeTrans2,
(void*)&trans2_qfsi_parms, 15,
test_field_get_trans2},
{"INFO_LEVEL", 0, NULL, 1, test_field_get_fsinfo_level},
{"", -1, NULL, -1, NULL}
};
static struct enum_test gen_enum_tests[] = {
{SMBunlink, "UNLINK", TEST_COND_TCON,
testTypeFilename,
TEST_OPTION_FILE_EXISTS |
TEST_OPTION_FILE_SYSTEM |
TEST_OPTION_FILE_HIDDEN |
TEST_OPTION_FILE_INVISIBLE |
TEST_OPTION_FILE_WILDCARD |
TEST_OPTION_FILE_NOT_EXIST,
1, gen_unlink_test_spec, (void*)&gen_unlink_test_parms,
gen_execute_unlink, gen_verify_unlink},
{SMBclose, "CLOSE", TEST_COND_TCON,
testTypeFid,
TEST_OPTION_FID_VALID | TEST_OPTION_FID_INVALID,
3, gen_close_test_spec, (void*)&gen_close_test_parms,
gen_execute_close, gen_verify_close},
{SMBtrans2, "QUERY_FS_INFO", TEST_COND_TCON,
testTypeConnected,
1,
16, gen_qfsi_test_spec, (void*)&gen_qfsi_test_parms,
gen_execute_qfsi, gen_verify_qfsi},
{-1, NULL, 0, 0, 0, -1, NULL, NULL, NULL}
};

View File

@ -1,83 +0,0 @@
/*
Unix SMB/CIFS implementation.
Gentest test definitions
Copyright (C) James Myers 2003
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
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
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.
*/
get_field_function test_field_get_file_attr;
get_field_function test_field_get_fid;
get_field_function test_field_get_filename;
get_field_function test_field_get_mtime;
get_field_function test_field_get_trans2;
get_field_function test_field_get_fsinfo_level;
static struct unlink_test_parms_t gen_unlink_test_parms;
static struct close_test_parms_t gen_close_test_parms;
static struct qfsi_test_parms_t gen_qfsi_test_parms;
static struct trans2_parms trans2_qfsi_parms = {
testFieldTypeTrans2, 1, 2, 0, 0, TRANSACT2_QFSINFO
};
static struct field_test_spec gen_unlink_test_spec[] = {
{"FATTR", testFieldTypeFileAttr, NULL,
1, test_field_get_file_attr},
{"FNAME", testFieldTypeFilename, NULL,
-1, test_field_get_filename},
{"", -1, NULL, -1, NULL}
};
static struct field_test_spec gen_close_test_spec[] = {
{"FID", testFieldTypeFid, NULL, 1,
test_field_get_fid},
{"MTIME", testFieldTypeMtime, NULL, 2,
test_field_get_mtime},
{"", -1, NULL, -1, NULL}
};
static struct field_test_spec gen_qfsi_test_spec[] = {
{"TRANS2", testFieldTypeTrans2,
(void*)&trans2_qfsi_parms, 15,
test_field_get_trans2},
{"INFO_LEVEL", 0, NULL, 1, test_field_get_fsinfo_level},
{"", -1, NULL, -1, NULL}
};
static struct enum_test gen_enum_tests[] = {
{SMBunlink, "UNLINK", TEST_COND_TCON,
testTypeFilename,
TEST_OPTION_FILE_EXISTS |
TEST_OPTION_FILE_SYSTEM |
TEST_OPTION_FILE_HIDDEN |
TEST_OPTION_FILE_INVISIBLE |
TEST_OPTION_FILE_WILDCARD |
TEST_OPTION_FILE_NOT_EXIST,
1, gen_unlink_test_spec, (void*)&gen_unlink_test_parms,
gen_execute_unlink, gen_verify_unlink},
{SMBclose, "CLOSE", TEST_COND_TCON,
testTypeFid,
TEST_OPTION_FID_VALID | TEST_OPTION_FID_INVALID,
3, gen_close_test_spec, (void*)&gen_close_test_parms,
gen_execute_close, gen_verify_close},
{SMBtrans2, "QUERY_FS_INFO", TEST_COND_TCON,
testTypeConnected,
1,
16, gen_qfsi_test_spec, (void*)&gen_qfsi_test_parms,
gen_execute_qfsi, gen_verify_qfsi},
{-1, NULL, 0, 0, 0, -1, NULL, NULL, NULL}
};

View File

@ -1,732 +0,0 @@
/*
Unix SMB/CIFS implementation.
SMB test generator - load and parse test config
Copyright (C) James Myers 2003
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
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
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.
*/
#include "includes.h"
#include "gentest.h"
static struct gentest_context_t *contextP;
#define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct))
static BOOL do_parameter(const char *pszParmName, const char *pszParmValue);
static BOOL do_section(const char *pszSectionName);
/* prototypes for the special type handlers */
static BOOL handle_tests(const char *pszParmValue, char **ptr);
static BOOL handle_options(const char *pszParmValue, char **ptr);
static BOOL handle_fields(const char *pszParmValue, char **ptr);
static struct enum_list enum_command[] = {
{
SMBunlink, "SMBunlink"
},
{SMBclose, "SMBclosex"},
{-1, NULL}
};
static struct enum_list enum_condition[] = {
{
TEST_COND_NEGPROT, "TEST_COND_NEGPROT"
},
{TEST_COND_SESSION, "TEST_COND_SESSION"},
{TEST_COND_TCON, "TEST_COND_TCON"},
{TEST_COND_FID, "TEST_COND_FID"},
{-1, NULL}
};
static struct enum_list enum_test_type[] = {
{
testTypeConnected, "Connected"
},
{testTypeFilename, "Filename"},
{testTypeFid, "FID"},
{-1, NULL}
};
static struct enum_list enum_options[] = {
{TEST_OPTION_FILE_EXISTS, "FILE_EXISTS"},
{TEST_OPTION_FILE_NOT_EXIST, "FILE_NOT_EXIST"},
{TEST_OPTION_FILE_HIDDEN, "FILE_HIDDEN"},
{TEST_OPTION_FILE_SYSTEM, "FILE_SYSTEM"},
{TEST_OPTION_FILE_INVISIBLE, "FILE_INVISIBLE"},
{TEST_OPTION_FILE_WILDCARD, "FILE_WILDCARD"},
{TEST_OPTION_FID_INVALID, "FID_INVALID"},
{TEST_OPTION_FID_VALID, "FID_VALID"},
{-1, NULL}
};
static struct enum_list enum_execute[] = {
{(int)gen_execute_unlink, "gen_execute_unlink"},
{(int)gen_execute_close, "gen_execute_close"},
{-1, NULL}
};
static struct enum_list enum_verify[] = {
{
(int)gen_verify_unlink, "gen_verify_unlink"
},
{(int)gen_verify_close, "gen_verify_close"},
{-1, NULL}
};
static struct enum_list enum_field_type[] = {
{
testFieldTypeFilename, "Filename"
},
{testFieldTypeFileAttr, "FileAttr"},
{testFieldTypeFid, "FID"},
{testFieldTypeMtime, "Mtime"},
{testFieldTypeTrans2, "Trans2"},
{-1, NULL}
};
static struct enum_list enum_function[] = {
{
(int)test_field_get_filename, "test_field_get_filename"
},
{(int)test_field_get_file_attr, "test_field_get_file_attr"},
{-1, NULL}
};
/* Note: We do not initialise the defaults union - it is not allowed in ANSI C
*/
#define GEN_FLAG_GLOBAL 0x0001 /* fundamental options */
#define GEN_FLAG_TEST 0x0002 /* test options */
#define GEN_FLAG_FIELD 0x0004 /* field options */
static struct {
int command;
char *name;
int debug;
int condition;
int type;
int options;
int words;
struct field_test_spec* fields;
int field_count;
void* execute;
void* verify;
}
test_section;
static struct {
char *name;
int type;
BOOL random;
int words;
void * function;
}
field_section;
static struct parm_struct parm_table[] = {
{"Base Options", P_SEP, P_SEPARATOR
},
/* global section parameters */
{"tests", P_LIST, P_GLOBAL, NULL, handle_tests, NULL, GEN_FLAG_GLOBAL},
/* test section parameters */
{"Test section", P_SEP, P_SEPARATOR},
{"command", P_ENUM, P_LOCAL, &test_section.command, NULL, enum_command, GEN_FLAG_TEST},
{"name", P_STRING, P_LOCAL, &test_section.name, NULL, NULL, GEN_FLAG_TEST},
{"debug", P_INTEGER, P_LOCAL, &test_section.debug, NULL, NULL, GEN_FLAG_TEST},
{"condition", P_ENUM, P_LOCAL, &test_section.condition, NULL, enum_condition, GEN_FLAG_TEST},
{"type", P_ENUM, P_LOCAL, &test_section.type, NULL, enum_test_type, GEN_FLAG_TEST},
{"options", P_LIST, P_LOCAL, &test_section.options, handle_options, NULL, GEN_FLAG_TEST},
{"word count", P_INTEGER, P_LOCAL, &test_section.words, NULL, NULL, GEN_FLAG_TEST},
{"fields", P_LIST, P_LOCAL, NULL, handle_fields, NULL, GEN_FLAG_TEST},
{"execute", P_ENUM, P_LOCAL, &test_section.execute, NULL, enum_execute, GEN_FLAG_TEST},
{"verify", P_ENUM, P_LOCAL, &test_section.verify, NULL, enum_verify, GEN_FLAG_TEST},
/* field section parameters */
{"Field section", P_SEP, P_SEPARATOR},
{"type", P_ENUM, P_LOCAL, &field_section.type, NULL, enum_field_type, GEN_FLAG_FIELD},
{"random", P_BOOL, P_LOCAL, &field_section.random, NULL, NULL, GEN_FLAG_FIELD},
{"word count", P_INTEGER, P_LOCAL, &field_section.words, NULL, NULL, GEN_FLAG_FIELD},
{"function", P_ENUM, P_LOCAL, &field_section.function, NULL, enum_function, GEN_FLAG_FIELD},
{NULL, P_BOOL, P_NONE, NULL, NULL, NULL, 0}
};
static BOOL handle_tests(const char *pszParmValue, char **ptr) {
contextP->testNames = str_list_make(pszParmValue, NULL);
return True;
}
static BOOL handle_options(const char *pszParmValue, char **ptr) {
/* convert option names (in enum_options) to flags */
char **str_array;
str_array = str_list_make(pszParmValue, NULL);
if (str_array) {
size_t i, j;
for ( j = 0; str_array[j] != NULL; j++) {
BOOL optionValid = False;
for (i = 0; enum_options[i].name; i++) {
if (strequal(str_array[j],
enum_options[i].name)) {
*(int *)ptr |= enum_options[i].value;
optionValid = True;
break;
}
}
if (!optionValid)
DEBUG(0,("handle_options: '%s' invalid option\n",
str_array[j]));
}
}
DEBUG(9,("handle_options: %s -> %p\n", pszParmValue, *ptr));
return True;
}
static BOOL handle_fields(const char *pszParmValue, char **ptr) {
/* create initialized field structures for each name */
char **str_array;
str_array = str_list_make(pszParmValue, NULL);
if (str_array) {
size_t i;
for ( i = 0; str_array[i] != NULL; i++)
test_section.field_count++;
/* allocate new field array */
test_section.fields = talloc(contextP->mem_ctx,
test_section.field_count * sizeof(struct field_test_spec));
for ( i = 0; str_array[i] != NULL; i++)
test_section.fields[i].name = str_array[i];
}
return True;
}
/***************************************************************************
Map a parameter's string representation to something we can use.
Returns False if the parameter string is not recognised, else TRUE.
***************************************************************************/
static int map_parameter(const char *pszParmName, int section) {
int iIndex;
unsigned validFlags = 0;
if (*pszParmName == '-')
return (-1);
/* Check for section-specific parameters.
* This allows the same parameter name to be used in
* different sections with different meanings.
*/
if (section == GEN_SECTION_GLOBAL)
validFlags |= GEN_FLAG_GLOBAL;
if (section == GEN_SECTION_TEST)
validFlags |= GEN_FLAG_TEST;
if (section == GEN_SECTION_FIELD)
validFlags |= GEN_FLAG_FIELD;
for (iIndex = 0; parm_table[iIndex].label; iIndex++)
if ((parm_table[iIndex].flags & validFlags) &&
strwicmp(parm_table[iIndex].label, pszParmName) == 0)
return (iIndex);
/* Warn only if it isn't parametric option */
if (strchr(pszParmName, ':') == NULL)
DEBUG(0, ("Unknown parameter encountered: \"%s\"\n", pszParmName));
/* We do return 'fail' for parametric options as well because they are
stored in different storage
*/
return (-1);
}
/***************************************************************************
Set a boolean variable from the text value stored in the passed string.
Returns True in success, False if the passed string does not correctly
represent a boolean.
***************************************************************************/
static BOOL set_boolean(BOOL *pb, const char *pszParmValue) {
BOOL bRetval;
bRetval = True;
if (strwicmp(pszParmValue, "yes") == 0 ||
strwicmp(pszParmValue, "true") == 0 ||
strwicmp(pszParmValue, "1") == 0) {
*pb = True;
} else if (strwicmp(pszParmValue, "no") == 0 ||
strwicmp(pszParmValue, "False") == 0 ||
strwicmp(pszParmValue, "0") == 0) {
*pb = False;
} else {
DEBUG(0,
("ERROR: Badly formed boolean in configuration file: \"%s\".\n",
pszParmValue));
bRetval = False;
}
return (bRetval);
}
/***************************************************************************
Process a parameter
***************************************************************************/
static BOOL gen_do_parm(struct gentest_context_t *context,
const char *pszParmName, const char *pszParmValue) {
int parmnum, i;
void *parm_ptr = NULL; /* where we are going to store the result */
void *def_ptr = NULL;
parmnum = map_parameter(pszParmName, context->iCurrentSectionType);
if (parmnum < 0) {
DEBUG(0, ("Ignoring unknown parameter \"%s\"\n", pszParmName));
return (True);
}
DEBUG(19,("gen_do_parm: parm %s is valid\n", pszParmName));
def_ptr = parm_table[parmnum].ptr;
/* we might point at a test, a field or a global */
if (context->iCurrentSectionType == GEN_SECTION_GLOBAL) {
parm_ptr = def_ptr;
} else {
if (parm_table[parmnum].class == P_GLOBAL) {
DEBUG(0,
("Global parameter %s found in service section!\n",
pszParmName));
return (True);
}
parm_ptr = def_ptr;
}
/* if it is a special case then go ahead */
if (parm_table[parmnum].special) {
parm_table[parmnum].special(pszParmValue, (char **)parm_ptr);
return (True);
}
DEBUG(19,("gen_do_parm: parm %s type=%d\n", pszParmName,
parm_table[parmnum].type));
/* now switch on the type of variable it is */
switch (parm_table[parmnum].type) {
case P_BOOL:
set_boolean(parm_ptr, pszParmValue);
break;
case P_INTEGER:
*(int *)parm_ptr = atoi(pszParmValue);
break;
case P_LIST:
*(char ***)parm_ptr = str_list_make(pszParmValue, NULL);
break;
case P_STRING:
parm_ptr = talloc_strdup(context->mem_ctx, pszParmValue);
break;
case P_ENUM:
for (i = 0; parm_table[parmnum].enum_list[i].name; i++) {
if (strequal
(pszParmValue,
parm_table[parmnum].enum_list[i].name)) {
*(int *)parm_ptr =
parm_table[parmnum].
enum_list[i].value;
break;
}
}
break;
case P_SEP:
break;
default:
break;
}
return (True);
}
/***************************************************************************
Process a parameter.
***************************************************************************/
static BOOL do_parameter(const char *pszParmName, const char *pszParmValue) {
BOOL bRetval;
DEBUG(4, ("doing parameter %s = %s\n", pszParmName, pszParmValue));
bRetval = gen_do_parm(contextP, pszParmName, pszParmValue);
return bRetval;
}
/***************************************************************************
Check a test for consistency. Return False if the test is in any way
incomplete or faulty, else True.
***************************************************************************/
static BOOL test_ok(struct gentest_context_t *context,int iTest) {
BOOL bRetval = True;
DEBUG(9,("test_ok: index=%d, tests@%p\n", iTest,
context->tests));
/* initialize new test section */
DEBUG(9,("test_ok: name=%s\n", test_section.name));
context->tests[iTest].name = test_section.name;
context->tests[iTest].debug = test_section.debug;
context->tests[iTest].type = test_section.type;
context->tests[iTest].command = test_section.command;
context->tests[iTest].initial_conditions = test_section.condition;
context->tests[iTest].options = test_section.options;
context->tests[iTest].word_count = test_section.words;
context->tests[iTest].fields = test_section.fields;
context->tests[iTest].field_count = test_section.field_count;
context->tests[iTest].execute = test_section.execute;
context->tests[iTest].verify = test_section.verify;
/* validate test entry */
DEBUG(9,("test_ok: validate name=%s\n", test_section.name));
if (context->tests[iTest].name[0] == '\0') {
DEBUG(0, ("The following message indicates an internal error:\n"));
DEBUG(0, ("No test name in test entry.\n"));
bRetval = False;
}
if (bRetval) {
context->tests[iTest].valid = True;
DEBUG(9,("added valid test %s\n",test_section.name));
}
return (bRetval);
}
/***************************************************************************
Check a field for consistency. Return False if the field is in any way
incomplete or faulty, else True.
***************************************************************************/
static BOOL field_ok(struct gentest_context_t *context,int iField) {
BOOL bRetval = True;
/* setup new field entry */
DEBUG(9,("field_ok: index=%d, fields@%p\n", iField,
context->fields));
context->fields[iField].name = field_section.name;
context->fields[iField].type = field_section.type;
context->fields[iField].random = field_section.random;
context->fields[iField].word_count = field_section.words;
context->fields[iField].function = field_section.function;
/* validate field */
if (context->fields[iField].name[0] == '\0') {
DEBUG(0, ("The following message indicates an internal error:\n"));
DEBUG(0, ("No field name in field entry.\n"));
bRetval = False;
}
if (bRetval) {
context->fields[iField].valid = True;
DEBUG(9,("added valid field %s\n",field_section.name));
}
return (bRetval);
}
/***************************************************************************
Find a test by name. Otherwise works like get_test.
***************************************************************************/
static int gettestbyname(struct gentest_context_t *context,
const char *pszTestName) {
int iTest;
for (iTest = context->iNumTests - 1; iTest >= 0; iTest--)
if (context->tests[iTest].valid &&
strwicmp(context->tests[iTest].name, pszTestName) == 0) {
break;
}
return (iTest);
}
/***************************************************************************
Find a field by name. Otherwise works like get_field.
***************************************************************************/
static int getfieldbyname(struct gentest_context_t *context,
const char *pszFieldName) {
int iField;
for (iField = context->iNumFields - 1; iField >= 0; iField--)
if (context->fields[iField].valid &&
strwicmp(context->fields[iField].name, pszFieldName) == 0) {
break;
}
return (iField);
}
/***************************************************************************
Add a new test to the tests array initialising it with the given
test.
***************************************************************************/
static int add_a_test(struct gentest_context_t *context,
const char *name) {
int i;
int num_to_alloc = context->iNumTests + 1;
DEBUG(3, ("add_a_test: %s at index %d\n", name, num_to_alloc-1));
/* it might already exist */
if (name) {
i = gettestbyname(context, name);
if (i >= 0)
return (i);
}
/* find an invalid one */
for (i = 0; i < context->iNumTests; i++)
if (!context->tests[i].valid)
break;
/* if not, then create one */
DEBUG(3, ("add_a_test: add %s at index %d\n", name, i));
if (i == context->iNumTests) {
struct enum_test *tsp;
tsp = talloc_realloc(context->mem_ctx, context->tests,
sizeof(struct enum_test) *
num_to_alloc);
if (!tsp) {
DEBUG(0,("add_a_test: failed to enlarge TestPtrs!\n"));
return (-1);
} else {
context->tests = tsp;
}
context->iNumTests++;
DEBUG(3, ("add_a_test: tests@%p\n", tsp));
} //else
//free_test(context->tests[i]);
/* reinitialize test section fields */
test_section.command = 0;
test_section.name = talloc_strdup(context->mem_ctx, name);
test_section.debug = 0;
test_section.condition = 0;
test_section.type = 0;
test_section.options = 0;
test_section.words = 0;
test_section.fields = NULL;
test_section.field_count = 0;
test_section.execute = NULL;
test_section.verify = NULL;
context->tests[i].valid = False;
if (name)
context->tests[i].name = test_section.name;
DEBUG(3, ("add_a_test: added %s at index %d\n", name, i));
return (i);
}
/***************************************************************************
Add a new field to the fields array initialising it with the given
field.
***************************************************************************/
static int add_a_field(struct gentest_context_t *context,
const char *name) {
int i;
int num_to_alloc = context->iNumFields + 1;
DEBUG(3, ("add_a_field: %s at index %d\n", name, num_to_alloc-1));
/* it might already exist */
if (name) {
i = getfieldbyname(context, name);
if (i >= 0)
return (i);
}
/* find an invalid one */
for (i = 0; i < context->iNumFields; i++)
if (!context->fields[i].valid)
break;
/* if not, then create one */
DEBUG(3, ("add_a_field: add %s at index %d\n", name, i));
if (i == context->iNumFields) {
field_test_spec *tsp;
tsp = talloc_realloc(context->mem_ctx, context->fields,
sizeof(field_test_spec) *
num_to_alloc);
if (!tsp) {
DEBUG(0,("add_a_field: failed to enlarge FieldPtrs!\n"));
return (-1);
} else {
context->fields = tsp;
}
context->iNumFields++;
DEBUG(3, ("add_a_field: fields@%p\n", tsp));
}
/* reinitialize field section fields */
field_section.name = NULL;
field_section.type = 0;
field_section.random = False;
field_section.words = 0;
field_section.function = NULL;
context->fields[i].valid = False;
if (name)
field_section.name = talloc_strdup(context->mem_ctx, name);
DEBUG(3, ("add_a_field: added %s at index %d\n", name, i));
return (i);
}
/***************************************************************************
Process a new section (test or field).
Returns True on success, False on failure.
***************************************************************************/
static BOOL do_section(const char *pszSectionName) {
BOOL bRetval;
BOOL isglobal = (strwicmp(pszSectionName, GLOBAL_NAME) == 0);
char *sectionType, *sectionName, *p;
bRetval = False;
DEBUG(4, ("doing section %s\n", pszSectionName));
/* if we've just struck a global section, note the fact. */
contextP->bInGlobalSection = isglobal;
/* check for multiple global sections */
if (contextP->bInGlobalSection) {
DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName));
contextP->iCurrentSectionType = GEN_SECTION_GLOBAL;
return (True);
} else if (contextP->iCurrentSectionType == GEN_SECTION_GLOBAL) {
/* just finished global section */
;
}
/* parse section name (form <type:name> */
sectionType = talloc_strdup(contextP->mem_ctx, pszSectionName);
p = strchr_m(sectionType,':');
if (p) {
*p = 0;
sectionName = talloc_strdup(contextP->mem_ctx, p+1);
} else {
DEBUG(0, ("Invalid section name %s\n", pszSectionName));
return False;
}
/* if we have a current test or field, tidy it up before moving on */
bRetval = True;
if (contextP->iTestIndex >= 0 && contextP->iCurrentSectionType == GEN_SECTION_TEST)
bRetval = test_ok(contextP, contextP->iTestIndex);
if (contextP->iFieldIndex >= 0 && contextP->iCurrentSectionType == GEN_SECTION_FIELD)
bRetval = field_ok(contextP, contextP->iFieldIndex);
/* determine type of this section */
contextP->iCurrentSectionType = GEN_SECTION_INVALID;
if (strequal(sectionType, "test"))
contextP->iCurrentSectionType = GEN_SECTION_TEST;
if (strequal(sectionType, "field"))
contextP->iCurrentSectionType = GEN_SECTION_FIELD;
if (contextP->iCurrentSectionType == GEN_SECTION_INVALID) {
DEBUG(0, ("Invalid section type %s\n", sectionType));
return False;
}
/* if all is still well, move to the next record in the tests array */
if (bRetval) {
/* We put this here to avoid an odd message order if messages are */
/* issued by the post-processing of a previous section. */
DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName));
if (contextP->iCurrentSectionType == GEN_SECTION_TEST) {
if ((contextP->iTestIndex = add_a_test(contextP, sectionName))
< 0) {
DEBUG(0, ("Failed to add a new test\n"));
return (False);
}
}
if (contextP->iCurrentSectionType == GEN_SECTION_FIELD) {
if ((contextP->iFieldIndex = add_a_field(contextP, sectionName))
< 0) {
DEBUG(0, ("Failed to add a new field\n"));
return (False);
}
}
}
return (bRetval);
}
/***************************************************************************
Load the test configuration from the test config file. Return True on success,
False on failure.
***************************************************************************/
BOOL gen_load_config(struct gentest_context_t *contextPTR) {
char *n2;
BOOL bRetval;
contextP = contextPTR;
contextP->param_opt = NULL;
n2 = talloc_strdup(contextP->mem_ctx, contextP->config_filename);
/* We get sections first, so have to start 'behind' to make up */
contextP->iTestIndex = -1;
bRetval = pm_process(n2, do_section, do_parameter);
/* finish up the last section */
DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
/* if we have a current test or field, tidy it up before moving on */
if (contextP->iTestIndex >= 0 && contextP->iCurrentSectionType == GEN_SECTION_TEST)
bRetval = test_ok(contextP, contextP->iTestIndex);
if (contextP->iFieldIndex >= 0 && contextP->iCurrentSectionType == GEN_SECTION_FIELD)
bRetval = field_ok(contextP, contextP->iFieldIndex);
/* OK, we've parsed the configuration, now we need to match
* the field sections to fields required by tests */
if (bRetval) {
int i,j,k;
BOOL fieldValid;
for (i=0; i<contextP->iNumTests; i++) {
DEBUG(19,("gen_load_config: process test %d %s\n",
i, contextP->tests[i].name));
for (j=0; j<contextP->tests[i].field_count; j++) {
fieldValid = False;
DEBUG(19,("gen_load_config: look for field %s\n",
contextP->tests[i].fields[j].name));
for (k=0; k<contextP->iNumFields; k++) {
DEBUG(19,("gen_load_config: compare field %s\n",
contextP->fields[k].name));
if (strequal(contextP->tests[i].fields[j].name,
contextP->fields[k].name)) {
/* matching field found */
fieldValid = True;
contextP->tests[i].fields[j].type = contextP->fields[k].type;
contextP->tests[i].fields[j].word_count = contextP->fields[k].word_count;
contextP->tests[i].fields[j].function = contextP->fields[k].function;
contextP->tests[i].fields[j].valid = contextP->fields[k].valid;
contextP->tests[i].fields[j].random = contextP->fields[k].random;
contextP->tests[i].fields[j].parms = contextP->fields[k].parms;
break;
}
if (fieldValid)
break;
}
if (!fieldValid) {
contextP->tests[i].fields[j].valid = False;
contextP->tests[i].fields[j].function = test_field_get_null;
DEBUG(0,("missing field section: %s\n",
contextP->tests[i].fields[j].name));
}
}
}
}
return (bRetval);
}

View File

@ -1,640 +0,0 @@
/*
Unix SMB/CIFS implementation.
RAW_FILEINFO_* individual test suite
Copyright (C) Andrew Tridgell 2003
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
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
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.
*/
#include "includes.h"
static struct {
const char *name;
enum fileinfo_level level;
unsigned only_paths:1;
unsigned only_handles:1;
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, },
{ "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, }
};
/*
compare a dos time (2 second resolution) to a nt time
*/
static int dos_nt_time_cmp(time_t t, const NTTIME *nt)
{
time_t t2 = nt_time_to_unix(nt);
if (ABS(t2 - t) <= 2) return 0;
return t2 - t;
}
/*
find a level in the levels[] table
*/
static union smb_fileinfo *fnum_find(const char *name)
{
int i;
for (i=0; levels[i].name; i++) {
if (NT_STATUS_IS_OK(levels[i].fnum_status) &&
strcmp(name, levels[i].name) == 0 &&
!levels[i].only_paths) {
return &levels[i].fnum_finfo;
}
}
return NULL;
}
/*
find a level in the levels[] table
*/
static union smb_fileinfo *fname_find(const char *name)
{
int i;
for (i=0; levels[i].name; i++) {
if (NT_STATUS_IS_OK(levels[i].fname_status) &&
strcmp(name, levels[i].name) == 0 &&
!levels[i].only_handles) {
return &levels[i].fname_finfo;
}
}
return NULL;
}
/* local macros to make the code below more readable */
#define VAL_EQUAL(n1, v1, n2, v2) do {if (s1->n1.out.v1 != s2->n2.out.v2) { \
printf("%s/%s [%u] != %s/%s [%u] at %s(%d)\n", \
#n1, #v1, (uint_t)s1->n1.out.v1, \
#n2, #v2, (uint_t)s2->n2.out.v2, \
__FILE__, __LINE__); \
ret = False; \
}} while(0)
#define STR_EQUAL(n1, v1, n2, v2) do {if (strcmp(s1->n1.out.v1.s, s2->n2.out.v2.s) || \
s1->n1.out.v1.private_length != s2->n2.out.v2.private_length) { \
printf("%s/%s [%s/%d] != %s/%s [%s/%d] at %s(%d)\n", \
#n1, #v1, s1->n1.out.v1.s, s1->n1.out.v1.private_length, \
#n2, #v2, s2->n2.out.v2.s, s2->n2.out.v2.private_length, \
__FILE__, __LINE__); \
ret = False; \
}} while(0)
#define STRUCT_EQUAL(n1, v1, n2, v2) do {if (memcmp(&s1->n1.out.v1,&s2->n2.out.v2,sizeof(s1->n1.out.v1))) { \
printf("%s/%s != %s/%s at %s(%d)\n", \
#n1, #v1, \
#n2, #v2, \
__FILE__, __LINE__); \
ret = False; \
}} while(0)
/* used to find hints on unknown values - and to make sure
we zero-fill */
#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, \
(uint_t)s1->n1.out.v1, \
(uint_t)s1->n1.out.v1, \
__FILE__, __LINE__); \
ret = False; \
}} while(0)
/* 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_qfileinfo(int dummy)
{
struct cli_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;
large_t correct_size;
uint32 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, cli_errstr(cli));
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);
}
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);
}
}
/* check for completely broken levels */
for (count=i=0; levels[i].name; i++) {
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 (count != 0) {
ret = False;
printf("%d levels failed\n", count);
if (count > 32) {
printf("too many level failures - giving up\n");
goto done;
}
}
/* 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);
skip_streams = True;
}
/* this code is incredibly repititive but doesn't lend itself to loops, so
we use lots of macros to make it less painful */
/* first off we check the levels that are supposed to be aliases. It will be quite rare for
this code to fail, but we need to check it for completeness */
#define ALIAS_CHECK(sname1, sname2) \
do { \
s1 = fnum_find(sname1); s2 = fnum_find(sname2); \
if (s1 && s2) { INFO_CHECK } \
s1 = fname_find(sname1); s2 = fname_find(sname2); \
if (s1 && s2) { INFO_CHECK } \
s1 = fnum_find(sname1); s2 = fname_find(sname2); \
if (s1 && s2) { INFO_CHECK } \
} while (0)
#define INFO_CHECK \
STRUCT_EQUAL(basic_info, create_time, basic_info, create_time); \
STRUCT_EQUAL(basic_info, access_time, basic_info, access_time); \
STRUCT_EQUAL(basic_info, write_time, basic_info, write_time); \
STRUCT_EQUAL(basic_info, change_time, basic_info, change_time); \
VAL_EQUAL (basic_info, attrib, basic_info, attrib);
ALIAS_CHECK("BASIC_INFO", "BASIC_INFORMATION");
#undef INFO_CHECK
#define INFO_CHECK \
VAL_EQUAL(standard_info, alloc_size, standard_info, alloc_size); \
VAL_EQUAL(standard_info, size, standard_info, size); \
VAL_EQUAL(standard_info, nlink, standard_info, nlink); \
VAL_EQUAL(standard_info, delete_pending, standard_info, delete_pending); \
VAL_EQUAL(standard_info, directory, standard_info, directory);
ALIAS_CHECK("STANDARD_INFO", "STANDARD_INFORMATION");
#undef INFO_CHECK
#define INFO_CHECK \
VAL_EQUAL(ea_info, ea_size, ea_info, ea_size);
ALIAS_CHECK("EA_INFO", "EA_INFORMATION");
#undef INFO_CHECK
#define INFO_CHECK \
STR_EQUAL(name_info, fname, name_info, fname);
ALIAS_CHECK("NAME_INFO", "NAME_INFORMATION");
#undef INFO_CHECK
#define INFO_CHECK \
STRUCT_EQUAL(all_info, create_time, all_info, create_time); \
STRUCT_EQUAL(all_info, access_time, all_info, access_time); \
STRUCT_EQUAL(all_info, write_time, all_info, write_time); \
STRUCT_EQUAL(all_info, change_time, all_info, change_time); \
VAL_EQUAL(all_info, attrib, all_info, attrib); \
VAL_EQUAL(all_info, alloc_size, all_info, alloc_size); \
VAL_EQUAL(all_info, size, all_info, size); \
VAL_EQUAL(all_info, nlink, all_info, nlink); \
VAL_EQUAL(all_info, delete_pending, all_info, delete_pending); \
VAL_EQUAL(all_info, directory, all_info, directory); \
VAL_EQUAL(all_info, ea_size, all_info, ea_size); \
STR_EQUAL(all_info, fname, all_info, fname);
ALIAS_CHECK("ALL_INFO", "ALL_INFORMATION");
#undef INFO_CHECK
#define INFO_CHECK \
STR_EQUAL(alt_name_info, fname, alt_name_info, fname);
ALIAS_CHECK("ALT_NAME_INFO", "ALT_NAME_INFORMATION");
#define TIME_CHECK_NT(sname, stype, tfield) do { \
s1 = fnum_find(sname); \
if (s1 && memcmp(&s1->stype.out.tfield, &correct_time, sizeof(correct_time)) != 0) { \
printf("(%d) handle %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); \
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; \
}} while (0)
#define TIME_CHECK_DOS(sname, stype, tfield) do { \
s1 = fnum_find(sname); \
if (s1 && dos_nt_time_cmp(s1->stype.out.tfield, &correct_time) != 0) { \
printf("(%d) handle %s/%s incorrect - %s should be %s\n", __LINE__, #stype, #tfield, \
time_string(mem_ctx, s1->stype.out.tfield), \
nt_time_string(mem_ctx, &correct_time)); \
ret = False; \
} \
s1 = fname_find(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, \
time_string(mem_ctx, s1->stype.out.tfield), \
nt_time_string(mem_ctx, &correct_time)); \
ret = False; \
}} while (0)
#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) { \
printf("(%d) handle %s/%s incorrect - %s should be %s\n", __LINE__, #stype, #tfield, \
time_string(mem_ctx, s1->stype.out.tfield), \
nt_time_string(mem_ctx, &correct_time)); \
ret = False; \
} \
s1 = fname_find(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, \
time_string(mem_ctx, s1->stype.out.tfield), \
nt_time_string(mem_ctx, &correct_time)); \
ret = False; \
}} while (0)
/* now check that all the times that are supposed to be equal are correct */
s1 = fnum_find("BASIC_INFO");
correct_time = s1->basic_info.out.create_time;
printf("create_time: %s\n", nt_time_string(mem_ctx, &correct_time));
TIME_CHECK_NT ("BASIC_INFO", basic_info, create_time);
TIME_CHECK_NT ("BASIC_INFORMATION", basic_info, create_time);
TIME_CHECK_DOS("GETATTRE", getattre, create_time);
TIME_CHECK_DOS("STANDARD", standard, create_time);
TIME_CHECK_DOS("EA_SIZE", ea_size, create_time);
TIME_CHECK_NT ("ALL_INFO", all_info, create_time);
TIME_CHECK_NT ("NETWORK_OPEN_INFORMATION", network_open_information, create_time);
s1 = fnum_find("BASIC_INFO");
correct_time = s1->basic_info.out.access_time;
printf("access_time: %s\n", nt_time_string(mem_ctx, &correct_time));
TIME_CHECK_NT ("BASIC_INFO", basic_info, access_time);
TIME_CHECK_NT ("BASIC_INFORMATION", basic_info, access_time);
TIME_CHECK_DOS("GETATTRE", getattre, access_time);
TIME_CHECK_DOS("STANDARD", standard, access_time);
TIME_CHECK_DOS("EA_SIZE", ea_size, access_time);
TIME_CHECK_NT ("ALL_INFO", all_info, access_time);
TIME_CHECK_NT ("NETWORK_OPEN_INFORMATION", network_open_information, access_time);
s1 = fnum_find("BASIC_INFO");
correct_time = s1->basic_info.out.write_time;
printf("write_time : %s\n", nt_time_string(mem_ctx, &correct_time));
TIME_CHECK_NT ("BASIC_INFO", basic_info, write_time);
TIME_CHECK_NT ("BASIC_INFORMATION", basic_info, write_time);
TIME_CHECK_DOS("GETATTRE", getattre, write_time);
TIME_CHECK_DOS("STANDARD", standard, write_time);
TIME_CHECK_DOS("EA_SIZE", ea_size, write_time);
TIME_CHECK_NT ("ALL_INFO", all_info, write_time);
TIME_CHECK_NT ("NETWORK_OPEN_INFORMATION", network_open_information, write_time);
s1 = fnum_find("BASIC_INFO");
correct_time = s1->basic_info.out.change_time;
printf("change_time: %s\n", nt_time_string(mem_ctx, &correct_time));
TIME_CHECK_NT ("BASIC_INFO", basic_info, change_time);
TIME_CHECK_NT ("BASIC_INFORMATION", basic_info, change_time);
TIME_CHECK_NT ("ALL_INFO", all_info, change_time);
TIME_CHECK_NT ("NETWORK_OPEN_INFORMATION", network_open_information, change_time);
#define SIZE_CHECK(sname, stype, tfield) do { \
s1 = fnum_find(sname); \
if (s1 && s1->stype.out.tfield != correct_size) { \
printf("(%d) handle %s/%s incorrect - %u should be %u\n", __LINE__, #stype, #tfield, \
(unsigned)s1->stype.out.tfield, \
(unsigned)correct_size); \
ret = False; \
} \
s1 = fname_find(sname); \
if (s1 && s1->stype.out.tfield != correct_size) { \
printf("(%d) path %s/%s incorrect - %u should be %u\n", __LINE__, #stype, #tfield, \
(unsigned)s1->stype.out.tfield, \
(unsigned)correct_size); \
ret = False; \
}} while (0)
s1 = fnum_find("STANDARD_INFO");
correct_size = s1->standard_info.out.size;
printf("size: %u\n", (unsigned)correct_size);
SIZE_CHECK("GETATTR", getattr, size);
SIZE_CHECK("GETATTRE", getattre, size);
SIZE_CHECK("STANDARD", standard, size);
SIZE_CHECK("EA_SIZE", ea_size, size);
SIZE_CHECK("STANDARD_INFO", standard_info, size);
SIZE_CHECK("STANDARD_INFORMATION", standard_info, size);
SIZE_CHECK("ALL_INFO", all_info, size);
SIZE_CHECK("ALL_INFORMATION", all_info, size);
SIZE_CHECK("COMPRESSION_INFO", compression_info, compressed_size);
SIZE_CHECK("COMPRESSION_INFORMATION", compression_info, compressed_size);
SIZE_CHECK("NETWORK_OPEN_INFORMATION", network_open_information, size);
if (!skip_streams) {
SIZE_CHECK("STREAM_INFO", stream_info, streams[0].size);
SIZE_CHECK("STREAM_INFORMATION", stream_info, streams[0].size);
}
s1 = fnum_find("STANDARD_INFO");
correct_size = s1->standard_info.out.alloc_size;
printf("alloc_size: %u\n", (unsigned)correct_size);
SIZE_CHECK("GETATTRE", getattre, alloc_size);
SIZE_CHECK("STANDARD", standard, alloc_size);
SIZE_CHECK("EA_SIZE", ea_size, alloc_size);
SIZE_CHECK("STANDARD_INFO", standard_info, alloc_size);
SIZE_CHECK("STANDARD_INFORMATION", standard_info, alloc_size);
SIZE_CHECK("ALL_INFO", all_info, alloc_size);
SIZE_CHECK("ALL_INFORMATION", all_info, alloc_size);
SIZE_CHECK("NETWORK_OPEN_INFORMATION", network_open_information, alloc_size);
if (!skip_streams) {
SIZE_CHECK("STREAM_INFO", stream_info, streams[0].alloc_size);
SIZE_CHECK("STREAM_INFORMATION", stream_info, streams[0].alloc_size);
}
#define ATTRIB_CHECK(sname, stype, tfield) do { \
s1 = fnum_find(sname); \
if (s1 && s1->stype.out.tfield != correct_attrib) { \
printf("(%d) handle %s/%s incorrect - 0x%x should be 0x%x\n", __LINE__, #stype, #tfield, \
(unsigned)s1->stype.out.tfield, \
(unsigned)correct_attrib); \
ret = False; \
} \
s1 = fname_find(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, \
(unsigned)s1->stype.out.tfield, \
(unsigned)correct_attrib); \
ret = False; \
}} while (0)
s1 = fnum_find("BASIC_INFO");
correct_attrib = s1->basic_info.out.attrib;
printf("attrib: 0x%x\n", (unsigned)correct_attrib);
ATTRIB_CHECK("GETATTR", getattr, attrib);
ATTRIB_CHECK("GETATTRE", getattre, attrib);
ATTRIB_CHECK("STANDARD", standard, 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);
ATTRIB_CHECK("ATTRIBUTE_TAG_INFORMATION", attribute_tag_information, attrib);
correct_name = fname;
printf("name: %s\n", correct_name);
#define NAME_CHECK(sname, stype, tfield, flags) do { \
s1 = fnum_find(sname); \
if ((s1 && strcmp(s1->stype.out.tfield.s, correct_name) != 0) || \
wire_bad_flags(&s1->stype.out.tfield, flags)) { \
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); \
if ((s1 && strcmp(s1->stype.out.tfield.s, correct_name)) != 0 || \
wire_bad_flags(&s1->stype.out.tfield, flags)) { \
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; \
}} while (0)
NAME_CHECK("NAME_INFO", name_info, fname, STR_UNICODE);
NAME_CHECK("NAME_INFORMATION", name_info, fname, STR_UNICODE);
/* the ALL_INFO file name is the full path on the filesystem */
s1 = fnum_find("ALL_INFO");
if (s1 && !s1->all_info.out.fname.s) {
printf("ALL_INFO didn't give a filename\n");
ret = False;
}
if (s1 && s1->all_info.out.fname.s) {
char *p = strrchr(s1->all_info.out.fname.s, '\\');
if (!p) {
printf("Not a full path in all_info/fname? - '%s'\n",
s1->all_info.out.fname.s);
ret = False;
} else {
if (strcmp(correct_name, p) != 0) {
printf("incorrect basename in all_info/fname - '%s'\n",
s1->all_info.out.fname.s);
ret = False;
}
}
if (wire_bad_flags(&s1->all_info.out.fname, STR_UNICODE)) {
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 */
cli_close(cli, fnum);
fnum = cli_nt_create_full(cli, correct_name, 0, NT_ACCESS_GENERIC_ALL_ACCESS,
FILE_ATTRIBUTE_NORMAL,
NTCREATEX_SHARE_ACCESS_DELETE|
NTCREATEX_SHARE_ACCESS_READ|
NTCREATEX_SHARE_ACCESS_WRITE,
FILE_OVERWRITE_IF,
0, 0);
if (fnum == -1) {
printf("Unable to open by alt_name - %s\n", cli_errstr(cli));
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");
if (s1) {
printf("ea_size: %d\n", s1->all_eas.out.ea_size);
for (i=0;i<s1->all_eas.out.num_eas;i++) {
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,
s1->all_eas.out.eas[i].value.data);
}
}
#define VAL_CHECK(sname1, stype1, tfield1, sname2, stype2, tfield2) do { \
s1 = fnum_find(sname1); s2 = fnum_find(sname2); \
if (s1 && s2 && s1->stype1.out.tfield1 != s2->stype2.out.tfield2) { \
printf("(%d) handle %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 = fname_find(sname1); s2 = fname_find(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); \
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); \
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, \
s1->stype1.out.tfield1, s2->stype2.out.tfield2); \
ret = False; \
}} while (0)
VAL_CHECK("STANDARD_INFO", standard_info, delete_pending,
"ALL_INFO", all_info, delete_pending);
VAL_CHECK("STANDARD_INFO", standard_info, directory,
"ALL_INFO", all_info, directory);
VAL_CHECK("STANDARD_INFO", standard_info, nlink,
"ALL_INFO", all_info, nlink);
VAL_CHECK("EA_INFO", ea_info, ea_size,
"ALL_INFO", all_info, ea_size);
VAL_CHECK("ALL_EAS", all_eas, ea_size,
"ALL_INFO", all_info, ea_size);
VAL_CHECK("EA_SIZE", ea_size, ea_size,
"ALL_INFO", all_info, ea_size);
#define UNKNOWN_CHECK(sname, stype, tfield) do { \
s1 = fnum_find(sname); \
if (s1 && s1->stype.out.tfield != 0) { \
printf("(%d) handle %s/%s unknown != 0 (0x%x)\n", __LINE__, \
#stype, #tfield, \
(unsigned)s1->stype.out.tfield); \
} \
s1 = fname_find(sname); \
if (s1 && s1->stype.out.tfield != 0) { \
printf("(%d) path %s/%s unknown != 0 (0x%x)\n", __LINE__, \
#stype, #tfield, \
(unsigned)s1->stype.out.tfield); \
}} while (0)
/* now get a bit fancier .... */
/* when we set the delete disposition then the link count should drop
to 0 and delete_pending should be 1 */
done:
cli_close(cli, fnum);
cli_unlink(cli, fname);
torture_close_connection(cli);
talloc_destroy(mem_ctx);
return ret;
}

View File

@ -1,286 +0,0 @@
/*
Unix SMB/CIFS implementation.
RAW_QFS_* individual test suite
Copyright (C) Andrew Tridgell 2003
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
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
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.
*/
#include "includes.h"
static struct {
const char *name;
enum fsinfo_level level;
NTSTATUS status;
union smb_fsinfo fsinfo;
} levels[] = {
{"DSKATTR", RAW_QFS_DSKATTR, },
{"ALLOCATION", RAW_QFS_ALLOCATION, },
{"VOLUME", RAW_QFS_VOLUME, },
{"VOLUME_INFO", RAW_QFS_VOLUME_INFO, },
{"SIZE_INFO", RAW_QFS_SIZE_INFO, },
{"DEVICE_INFO", RAW_QFS_DEVICE_INFO, },
{"ATTRIBUTE_INFO", RAW_QFS_ATTRIBUTE_INFO, },
{"VOLUME_INFORMATION", RAW_QFS_VOLUME_INFORMATION, },
{"SIZE_INFORMATION", RAW_QFS_SIZE_INFORMATION, },
{"DEVICE_INFORMATION", RAW_QFS_DEVICE_INFORMATION, },
{"ATTRIBUTE_INFORMATION", RAW_QFS_ATTRIBUTE_INFORMATION, },
{"QUOTA_INFORMATION", RAW_QFS_QUOTA_INFORMATION, },
{"FULL_SIZE_INFORMATION", RAW_QFS_FULL_SIZE_INFORMATION, },
{"OBJECTID_INFORMATION", RAW_QFS_OBJECTID_INFORMATION, },
{ NULL, }
};
/*
find a level in the levels[] table
*/
static union smb_fsinfo *find(const char *name)
{
int i;
for (i=0; levels[i].name; i++) {
if (strcmp(name, levels[i].name) == 0) {
return &levels[i].fsinfo;
}
}
return NULL;
}
/* local macros to make the code below more readable */
#define VAL_EQUAL(n1, v1, n2, v2) do {if (s1->n1.out.v1 != s2->n2.out.v2) { \
printf("%s/%s [%u] != %s/%s [%u] at %s(%d)\n", \
#n1, #v1, (uint_t)s1->n1.out.v1, \
#n2, #v2, (uint_t)s2->n2.out.v2, \
__FILE__, __LINE__); \
ret = False; \
}} while(0)
#define STR_EQUAL(n1, v1, n2, v2) do {if (!s1->n1.out.v1 && !s2->n2.out.v2) return True; \
if (!s1->n1.out.v1 || !s2->n2.out.v2) return False; \
if (strcmp(s1->n1.out.v1, s2->n2.out.v2)) { \
printf("%s/%s [%s] != %s/%s [%s] at %s(%d)\n", \
#n1, #v1, s1->n1.out.v1, \
#n2, #v2, s2->n2.out.v2, \
__FILE__, __LINE__); \
ret = False; \
}} while(0)
#define STRUCT_EQUAL(n1, v1, n2, v2) do {if (memcmp(&s1->n1.out.v1,&s2->n2.out.v2,sizeof(s1->n1.out.v1))) { \
printf("%s/%s != %s/%s at %s(%d)\n", \
#n1, #v1, \
#n2, #v2, \
__FILE__, __LINE__); \
ret = False; \
}} while(0)
/* used to find hints on unknown values - and to make sure
we zero-fill */
#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, \
(uint_t)s1->n1.out.v1, \
(uint_t)s1->n1.out.v1, \
__FILE__, __LINE__); \
ret = False; \
}} while(0)
/* basic testing of all RAW_QFS_* calls
for each call we test that it succeeds, and where possible test
for consistency between the calls.
Some of the consistency tests assume that the target filesystem is
quiescent, which is sometimes hard to achieve
*/
BOOL torture_qfsinfo(int dummy)
{
struct cli_state *cli;
int i;
BOOL ret = True;
int count;
union smb_fsinfo *s1, *s2;
TALLOC_CTX *mem_ctx;
if (!torture_open_connection(&cli)) {
return False;
}
mem_ctx = talloc_init("torture_qfsinfo");
/* scan all the levels, pulling the results */
for (i=0; levels[i].name; i++) {
levels[i].fsinfo.generic.level = levels[i].level;
levels[i].status = smb_raw_fsinfo(cli->tree, mem_ctx, &levels[i].fsinfo);
}
/* check for completely broken levels */
for (count=i=0; levels[i].name; i++) {
if (!NT_STATUS_IS_OK(levels[i].status)) {
printf("ERROR: level %s failed - %s\n", levels[i].name, nt_errstr(levels[i].status));
count++;
}
}
if (count != 0) {
ret = False;
printf("%d levels failed\n", count);
if (count > 10) {
printf("too many level failures - giving up\n");
goto done;
}
}
/* check for correct aliases */
s1 = find("SIZE_INFO");
s2 = find("SIZE_INFORMATION");
if (s1 && s2) {
VAL_EQUAL(size_info, total_alloc_units, size_info, total_alloc_units);
VAL_EQUAL(size_info, avail_alloc_units, size_info, avail_alloc_units);
VAL_EQUAL(size_info, sectors_per_unit, size_info, sectors_per_unit);
VAL_EQUAL(size_info, bytes_per_sector, size_info, bytes_per_sector);
}
s1 = find("DEVICE_INFO");
s2 = find("DEVICE_INFORMATION");
if (s1 && s2) {
VAL_EQUAL(device_info, device_type, device_info, device_type);
VAL_EQUAL(device_info, characteristics, device_info, characteristics);
}
s1 = find("VOLUME_INFO");
s2 = find("VOLUME_INFORMATION");
if (s1 && s2) {
STRUCT_EQUAL(volume_info, create_time, volume_info, create_time);
VAL_EQUAL (volume_info, serial_number, volume_info, serial_number);
STR_EQUAL (volume_info, volume_name.s, volume_info, volume_name.s);
printf("volume_info.volume_name = '%s'\n", s1->volume_info.out.volume_name.s);
}
s1 = find("ATTRIBUTE_INFO");
s2 = find("ATTRIBUTE_INFORMATION");
if (s1 && s2) {
VAL_EQUAL(attribute_info, fs_attr,
attribute_info, fs_attr);
VAL_EQUAL(attribute_info, max_file_component_length,
attribute_info, max_file_component_length);
STR_EQUAL(attribute_info, fs_type.s, attribute_info, fs_type.s);
printf("attribute_info.fs_type = '%s'\n", s1->attribute_info.out.fs_type.s);
}
/* check for consistent disk sizes */
s1 = find("DSKATTR");
s2 = find("ALLOCATION");
if (s1 && s2) {
double size1, size2;
double scale = s1->dskattr.out.blocks_per_unit * s1->dskattr.out.block_size;
size1 = 1.0 *
s1->dskattr.out.units_total *
s1->dskattr.out.blocks_per_unit *
s1->dskattr.out.block_size / scale;
size2 = 1.0 *
s2->allocation.out.sectors_per_unit *
s2->allocation.out.total_alloc_units *
s2->allocation.out.bytes_per_sector / scale;
if (ABS(size1 - size2) > 1) {
printf("Inconsistent total size in DSKATTR and ALLOCATION - size1=%.0f size2=%.0f\n",
size1, size2);
ret = False;
}
printf("total disk = %.0f MB\n", size1*scale/1.0e6);
}
/* and for consistent free disk space */
s1 = find("DSKATTR");
s2 = find("ALLOCATION");
if (s1 && s2) {
double size1, size2;
double scale = s1->dskattr.out.blocks_per_unit * s1->dskattr.out.block_size;
size1 = 1.0 *
s1->dskattr.out.units_free *
s1->dskattr.out.blocks_per_unit *
s1->dskattr.out.block_size / scale;
size2 = 1.0 *
s2->allocation.out.sectors_per_unit *
s2->allocation.out.avail_alloc_units *
s2->allocation.out.bytes_per_sector / scale;
if (ABS(size1 - size2) > 1) {
printf("Inconsistent avail size in DSKATTR and ALLOCATION - size1=%.0f size2=%.0f\n",
size1, size2);
ret = False;
}
printf("free disk = %.0f MB\n", size1*scale/1.0e6);
}
/* volume info consistency */
s1 = find("VOLUME");
s2 = find("VOLUME_INFO");
if (s1 && s2) {
VAL_EQUAL(volume, serial_number, volume_info, serial_number);
STR_EQUAL(volume, volume_name.s, volume_info, volume_name.s);
}
/* disk size consistency - notice that 'avail_alloc_units' maps to the caller
available allocation units, not the total */
s1 = find("SIZE_INFO");
s2 = find("FULL_SIZE_INFORMATION");
if (s1 && s2) {
VAL_EQUAL(size_info, total_alloc_units, full_size_information, total_alloc_units);
VAL_EQUAL(size_info, avail_alloc_units, full_size_information, call_avail_alloc_units);
VAL_EQUAL(size_info, sectors_per_unit, full_size_information, sectors_per_unit);
VAL_EQUAL(size_info, bytes_per_sector, full_size_information, bytes_per_sector);
}
/* check for non-zero unknown fields - if we find them
they might give us some hints */
s1 = find("QUOTA_INFORMATION");
if (s1) {
VAL_UNKNOWN(quota_information, unknown[0]);
VAL_UNKNOWN(quota_information, unknown[1]);
VAL_UNKNOWN(quota_information, unknown[2]);
}
s1 = find("OBJECTID_INFORMATION");
if (s1) {
VAL_UNKNOWN(objectid_information, unknown[0]);
VAL_UNKNOWN(objectid_information, unknown[1]);
VAL_UNKNOWN(objectid_information, unknown[2]);
VAL_UNKNOWN(objectid_information, unknown[3]);
VAL_UNKNOWN(objectid_information, unknown[4]);
VAL_UNKNOWN(objectid_information, unknown[5]);
}
#define STR_CHECK(sname, stype, field, flags) do { \
s1 = find(sname); \
if (s1) { \
if (wire_bad_flags(&s1->stype.out.field, flags)) { \
printf("(%d) incorrect string termination in %s/%s\n", \
__LINE__, #stype, #field); \
ret = False; \
} \
}} while (0)
/* check for correct termination */
STR_CHECK("VOLUME", volume, volume_name, 0);
STR_CHECK("VOLUME_INFO", volume_info, volume_name, STR_UNICODE);
STR_CHECK("VOLUME_INFORMATION", volume_info, volume_name, STR_UNICODE);
STR_CHECK("ATTRIBUTE_INFO", attribute_info, fs_type, STR_UNICODE);
STR_CHECK("ATTRIBUTE_INFORMATION", attribute_info, fs_type, STR_UNICODE);
done:
torture_close_connection(cli);
talloc_destroy(mem_ctx);
return ret;
}

View File

@ -1,526 +0,0 @@
/*
Unix SMB/CIFS implementation.
SMB client
Copyright (C) Andrew Tridgell 1994-1998
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
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
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.
*/
#include "includes.h"
#ifndef REGISTER
#define REGISTER 0
#endif
extern file_info def_finfo;
#define CNV_LANG(s) dos2unix_format(s,False)
#define CNV_INPUT(s) unix2dos_format(s,True)
static struct cli_state smbcli;
struct cli_state *smb_cli = &smbcli;
FILE *out_hnd;
static pstring password; /* local copy only, if one is entered */
/****************************************************************************
initialise smb client structure
****************************************************************************/
void rpcclient_init(void)
{
memset((char *)smb_cli, '\0', sizeof(smb_cli));
cli_initialise(smb_cli);
smb_cli->capabilities |= CAP_NT_SMBS;
}
/****************************************************************************
make smb client connection
****************************************************************************/
static BOOL rpcclient_connect(struct client_info *info)
{
struct nmb_name calling;
struct nmb_name called;
make_nmb_name(&called , dns_to_netbios_name(info->dest_host ), info->name_type);
make_nmb_name(&calling, dns_to_netbios_name(info->myhostname), 0x0);
if (!cli_establish_connection(smb_cli,
info->dest_host, &info->dest_ip,
&calling, &called,
info->share, info->svc_type,
False, True))
{
DEBUG(0,("rpcclient_connect: connection failed\n"));
cli_shutdown(smb_cli);
return False;
}
return True;
}
/****************************************************************************
stop the smb connection(s?)
****************************************************************************/
static void rpcclient_stop(void)
{
cli_shutdown(smb_cli);
}
/****************************************************************************
log in as an nt user, log out again.
****************************************************************************/
void run_enums_test(int num_ops, struct client_info *cli_info, struct cli_state *cli)
{
pstring cmd;
int i;
/* establish connections. nothing to stop these being re-established. */
rpcclient_connect(cli_info);
DEBUG(5,("rpcclient_connect: cli->fd:%d\n", cli->fd));
if (cli->fd <= 0)
{
fprintf(out_hnd, "warning: connection could not be established to %s<%02x>\n",
cli_info->dest_host, cli_info->name_type);
return;
}
for (i = 0; i < num_ops; i++)
{
set_first_token("");
cmd_srv_enum_sess(cli_info);
set_first_token("");
cmd_srv_enum_shares(cli_info);
set_first_token("");
cmd_srv_enum_files(cli_info);
if (password[0] != 0)
{
slprintf(cmd, sizeof(cmd)-1, "1");
set_first_token(cmd);
}
else
{
set_first_token("");
}
cmd_srv_enum_conn(cli_info);
}
rpcclient_stop();
}
/****************************************************************************
log in as an nt user, log out again.
****************************************************************************/
void run_ntlogin_test(int num_ops, struct client_info *cli_info, struct cli_state *cli)
{
pstring cmd;
int i;
/* establish connections. nothing to stop these being re-established. */
rpcclient_connect(cli_info);
DEBUG(5,("rpcclient_connect: cli->fd:%d\n", cli->fd));
if (cli->fd <= 0)
{
fprintf(out_hnd, "warning: connection could not be established to %s<%02x>\n",
cli_info->dest_host, cli_info->name_type);
return;
}
for (i = 0; i < num_ops; i++)
{
slprintf(cmd, sizeof(cmd)-1, "%s %s", cli->user_name, password);
set_first_token(cmd);
cmd_netlogon_login_test(cli_info);
}
rpcclient_stop();
}
/****************************************************************************
runs n simultaneous functions.
****************************************************************************/
static void create_procs(int nprocs, int numops,
struct client_info *cli_info, struct cli_state *cli,
void (*fn)(int, struct client_info *, struct cli_state *))
{
int i, status;
for (i=0;i<nprocs;i++)
{
if (fork() == 0)
{
pid_t mypid = getpid();
sys_srandom(mypid ^ time(NULL));
fn(numops, cli_info, cli);
fflush(out_hnd);
_exit(0);
}
}
for (i=0;i<nprocs;i++)
{
waitpid(0, &status, 0);
}
}
/****************************************************************************
usage on the program - OUT OF DATE!
****************************************************************************/
static void usage(char *pname)
{
fprintf(out_hnd, "Usage: %s service <password> [-d debuglevel] [-l log] ",
pname);
fprintf(out_hnd, "\nVersion %s\n",VERSION);
fprintf(out_hnd, "\t-d debuglevel set the debuglevel\n");
fprintf(out_hnd, "\t-l log basename. Basename for log/debug files\n");
fprintf(out_hnd, "\t-n netbios name. Use this name as my netbios name\n");
fprintf(out_hnd, "\t-m max protocol set the max protocol level\n");
fprintf(out_hnd, "\t-I dest IP use this IP to connect to\n");
fprintf(out_hnd, "\t-E write messages to stderr instead of stdout\n");
fprintf(out_hnd, "\t-U username set the network username\n");
fprintf(out_hnd, "\t-W workgroup set the workgroup name\n");
fprintf(out_hnd, "\t-t terminal code terminal i/o code {sjis|euc|jis7|jis8|junet|hex}\n");
fprintf(out_hnd, "\n");
}
enum client_action
{
CLIENT_NONE,
CLIENT_IPC,
CLIENT_SVC
};
/****************************************************************************
main program
****************************************************************************/
int main(int argc,char *argv[])
{
char *pname = argv[0];
int opt;
extern char *optarg;
extern int optind;
pstring term_code;
BOOL got_pass = False;
char *cmd_str="";
enum client_action cli_action = CLIENT_NONE;
int nprocs = 1;
int numops = 100;
pstring logfile;
struct client_info cli_info;
out_hnd = stdout;
rpcclient_init();
#ifdef KANJI
pstrcpy(term_code, KANJI);
#else /* KANJI */
*term_code = 0;
#endif /* KANJI */
if (!lp_load(dyn_CONFIGFILE,True, False, False))
{
fprintf(stderr, "Can't load %s - run testparm to debug it\n", dyn_CONFIGFILE);
}
DEBUGLEVEL = 0;
cli_info.put_total_size = 0;
cli_info.put_total_time_ms = 0;
cli_info.get_total_size = 0;
cli_info.get_total_time_ms = 0;
cli_info.dir_total = 0;
cli_info.newer_than = 0;
cli_info.archive_level = 0;
cli_info.print_mode = 1;
cli_info.translation = False;
cli_info.recurse_dir = False;
cli_info.lowercase = False;
cli_info.prompt = True;
cli_info.abort_mget = True;
cli_info.dest_ip.s_addr = 0;
cli_info.name_type = 0x20;
pstrcpy(cli_info.cur_dir , "\\");
pstrcpy(cli_info.file_sel, "");
pstrcpy(cli_info.base_dir, "");
pstrcpy(smb_cli->domain, "");
pstrcpy(smb_cli->user_name, "");
pstrcpy(cli_info.myhostname, "");
pstrcpy(cli_info.dest_host, "");
pstrcpy(cli_info.svc_type, "A:");
pstrcpy(cli_info.share, "");
pstrcpy(cli_info.service, "");
ZERO_STRUCT(cli_info.dom.level3_sid);
pstrcpy(cli_info.dom.level3_dom, "");
ZERO_STRUCT(cli_info.dom.level5_sid);
pstrcpy(cli_info.dom.level5_dom, "");
smb_cli->nt_pipe_fnum = 0xffff;
setup_logging(pname, DEBUG_STDOUT);
password[0] = 0;
if (argc < 2)
{
usage(pname);
exit(1);
}
if (*argv[1] != '-')
{
pstrcpy(cli_info.service, argv[1]);
/* Convert any '/' characters in the service name to '\' characters */
string_replace( cli_info.service, '/','\\');
argc--;
argv++;
DEBUG(1,("service: %s\n", cli_info.service));
if (count_chars(cli_info.service,'\\') < 3)
{
usage(pname);
printf("\n%s: Not enough '\\' characters in service\n", cli_info.service);
exit(1);
}
/*
if (count_chars(cli_info.service,'\\') > 3)
{
usage(pname);
printf("\n%s: Too many '\\' characters in service\n", cli_info.service);
exit(1);
}
*/
if (argc > 1 && (*argv[1] != '-'))
{
got_pass = True;
pstrcpy(password,argv[1]);
memset(argv[1],'X',strlen(argv[1]));
argc--;
argv++;
}
cli_action = CLIENT_SVC;
}
while ((opt = getopt(argc, argv,"s:O:M:S:i:N:o:n:d:l:hI:EB:U:L:t:m:W:T:D:c:")) != EOF)
{
switch (opt)
{
case 'm':
{
/* FIXME ... max_protocol seems to be funny here */
int max_protocol = 0;
max_protocol = interpret_protocol(optarg,max_protocol);
fprintf(stderr, "max protocol not currently supported\n");
break;
}
case 'O':
lp_set_cmdline("socket options", optarg);
break;
case 'S':
{
pstrcpy(cli_info.dest_host,optarg);
strupper(cli_info.dest_host);
cli_action = CLIENT_IPC;
break;
}
case 'i':
{
pstrcpy(scope, optarg);
break;
}
case 'U':
{
char *lp;
pstrcpy(smb_cli->user_name,optarg);
if ((lp=strchr_m(smb_cli->user_name,'%')))
{
*lp = 0;
pstrcpy(password,lp+1);
got_pass = True;
memset(strchr_m(optarg,'%')+1,'X',strlen(password));
}
break;
}
case 'W':
{
pstrcpy(smb_cli->domain,optarg);
break;
}
case 'E':
{
dbf = x_stderr;
break;
}
case 'I':
{
cli_info.dest_ip = *interpret_addr2(optarg);
if (is_zero_ip(cli_info.dest_ip))
{
exit(1);
}
break;
}
case 'N':
{
nprocs = atoi(optarg);
break;
}
case 'o':
{
numops = atoi(optarg);
break;
}
case 'n':
lp_set_cmdline("netbios name", optarg);
break;
case 'd':
{
if (*optarg == 'A')
DEBUGLEVEL = 10000;
else
DEBUGLEVEL = atoi(optarg);
break;
}
case 'l':
{
slprintf(logfile, sizeof(logfile)-1,
"%s.client",optarg);
lp_set_logfile(logfile);
break;
}
case 'c':
{
cmd_str = optarg;
got_pass = True;
break;
}
case 'h':
{
usage(pname);
exit(0);
break;
}
case 's':
{
pstrcpy(dyn_CONFIGFILE, optarg);
break;
}
case 't':
{
pstrcpy(term_code, optarg);
break;
}
default:
{
usage(pname);
exit(1);
break;
}
}
}
if (cli_action == CLIENT_NONE)
{
usage(pname);
exit(1);
}
fstrcpy(cli_info.myhostname, lp_netbios_name());
DEBUG(3,("%s client started (version %s)\n",timestring(False),VERSION));
if (*smb_cli->domain == 0)
{
pstrcpy(smb_cli->domain,lp_workgroup());
}
strupper(smb_cli->domain);
load_interfaces();
if (cli_action == CLIENT_IPC)
{
pstrcpy(cli_info.share, "IPC$");
pstrcpy(cli_info.svc_type, "IPC");
}
fstrcpy(cli_info.mach_acct, cli_info.myhostname);
strupper(cli_info.mach_acct);
fstrcat(cli_info.mach_acct, "$");
/* set the password cache info */
if (got_pass)
{
if (password[0] == 0)
{
pwd_set_nullpwd(&(smb_cli->pwd));
}
else
{
pwd_make_lm_nt_16(&(smb_cli->pwd), password); /* generate 16 byte hashes */
}
}
else
{
char *pwd = getpass("Enter Password:");
safe_strcpy(password, pwd, sizeof(password));
pwd_make_lm_nt_16(&(smb_cli->pwd), password); /* generate 16 byte hashes */
}
create_procs(nprocs, numops, &cli_info, smb_cli, run_enums_test);
if (password[0] != 0)
{
create_procs(nprocs, numops, &cli_info, smb_cli, run_ntlogin_test);
}
fflush(out_hnd);
return(0);
}

View File

@ -1,471 +0,0 @@
/*
Unix SMB/CIFS implementation.
RAW_SFILEINFO_* individual test suite
Copyright (C) Andrew Tridgell 2003
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
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
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.
*/
#include "includes.h"
/* basic testing of all RAW_SFILEINFO_* calls
for each call we test that it succeeds, and where possible test
for consistency between the calls.
*/
BOOL torture_sfileinfo(int dummy)
{
struct cli_state *cli;
BOOL ret = True;
TALLOC_CTX *mem_ctx;
int fnum = -1;
const char *fnum_fname = "\\torture_sfileinfo.txt";
const char *fnum_fname_new = "\\torture_sfileinfo-new.txt";
const char *path_fname = "\\torture_spathinfo13.txt";
const char *path_fname_new = "\\torture_spathinfo-new.txt";
union smb_fileinfo finfo1, finfo2;
union smb_setfileinfo sfinfo;
NTSTATUS status, status2;
const char *call_name;
time_t basetime = (time(NULL) - 86400) & ~1;
BOOL check_fnum;
if (!torture_open_connection(&cli)) {
return False;
}
mem_ctx = talloc_init("torture_sfileinfo");
#define RECREATE_FILE(fname) do { \
if (fnum != -1) cli_close(cli, fnum); \
fnum = create_complex_file(cli, mem_ctx, fname); \
if (fnum == -1) { \
printf("(%d) ERROR: open of %s failed (%s)\n", \
__LINE__, fname, cli_errstr(cli)); \
ret = False; \
goto done; \
}} while (0)
#define RECREATE_BOTH do { \
RECREATE_FILE(path_fname); \
cli_close(cli, fnum); \
RECREATE_FILE(fnum_fname); \
} while (0)
RECREATE_BOTH;
#define CHECK_CALL_FNUM(call, rightstatus) do { \
check_fnum = True; \
call_name = #call; \
sfinfo.generic.level = RAW_SFILEINFO_ ## call; \
sfinfo.generic.file.fnum = fnum; \
status = smb_raw_setfileinfo(cli->tree, &sfinfo); \
if (!NT_STATUS_EQUAL(status, rightstatus)) { \
printf("(%d) %s - %s (should be %s)\n", __LINE__, #call, \
nt_errstr(status), nt_errstr(rightstatus)); \
ret = False; \
} \
finfo1.generic.level = RAW_FILEINFO_ALL_INFO; \
finfo1.generic.in.fnum = fnum; \
status2 = smb_raw_fileinfo(cli->tree, mem_ctx, &finfo1); \
if (!NT_STATUS_IS_OK(status2)) { \
printf("(%d) %s pathinfo - %s\n", __LINE__, #call, nt_errstr(status)); \
ret = False; \
}} while (0)
#define CHECK_CALL_PATH(call, rightstatus) do { \
check_fnum = False; \
call_name = #call; \
sfinfo.generic.level = RAW_SFILEINFO_ ## call; \
sfinfo.generic.file.fname = path_fname; \
status = smb_raw_setpathinfo(cli->tree, &sfinfo); \
if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) { \
sfinfo.generic.file.fname = path_fname_new; \
status = smb_raw_setpathinfo(cli->tree, &sfinfo); \
} \
if (!NT_STATUS_EQUAL(status, rightstatus)) { \
printf("(%d) %s - %s (should be %s)\n", __LINE__, #call, \
nt_errstr(status), nt_errstr(rightstatus)); \
ret = False; \
} \
finfo1.generic.level = RAW_FILEINFO_ALL_INFO; \
finfo1.generic.in.fname = path_fname; \
status2 = smb_raw_pathinfo(cli->tree, mem_ctx, &finfo1); \
if (NT_STATUS_EQUAL(status2, NT_STATUS_OBJECT_NAME_NOT_FOUND)) { \
finfo1.generic.in.fname = path_fname_new; \
status2 = smb_raw_pathinfo(cli->tree, mem_ctx, &finfo1); \
} \
if (!NT_STATUS_IS_OK(status2)) { \
printf("(%d) %s pathinfo - %s\n", __LINE__, #call, nt_errstr(status2)); \
ret = False; \
}} while (0)
#define CHECK1(call) \
do { if (NT_STATUS_IS_OK(status)) { \
finfo2.generic.level = RAW_FILEINFO_ ## call; \
if (check_fnum) { \
finfo2.generic.in.fnum = fnum; \
status2 = smb_raw_fileinfo(cli->tree, mem_ctx, &finfo2); \
} else { \
finfo2.generic.in.fname = path_fname; \
status2 = smb_raw_pathinfo(cli->tree, mem_ctx, &finfo2); \
if (NT_STATUS_EQUAL(status2, NT_STATUS_OBJECT_NAME_NOT_FOUND)) { \
finfo2.generic.in.fname = path_fname_new; \
status2 = smb_raw_pathinfo(cli->tree, mem_ctx, &finfo2); \
} \
} \
if (!NT_STATUS_IS_OK(status2)) { \
printf("%s - %s\n", #call, nt_errstr(status2)); \
} \
}} while (0)
#define CHECK_VALUE(call, stype, field, value) do { \
CHECK1(call); \
if (NT_STATUS_IS_OK(status) && finfo2.stype.out.field != value) { \
printf("(%d) %s - %s/%s should be 0x%x - 0x%x\n", __LINE__, \
call_name, #stype, #field, \
(uint_t)value, (uint_t)finfo2.stype.out.field); \
dump_all_info(mem_ctx, &finfo1); \
}} while (0)
#define CHECK_TIME(call, stype, field, value) do { \
CHECK1(call); \
if (NT_STATUS_IS_OK(status) && nt_time_to_unix(&finfo2.stype.out.field) != value) { \
printf("(%d) %s - %s/%s should be 0x%x - 0x%x\n", __LINE__, \
call_name, #stype, #field, \
(uint_t)value, \
(uint_t)nt_time_to_unix(&finfo2.stype.out.field)); \
printf("\t%s", http_timestring(value)); \
printf("\t%s\n", nt_time_string(mem_ctx, &finfo2.stype.out.field)); \
dump_all_info(mem_ctx, &finfo1); \
}} while (0)
#define CHECK_STR(call, stype, field, value) do { \
CHECK1(call); \
if (NT_STATUS_IS_OK(status) && strcmp(finfo2.stype.out.field, value) != 0) { \
printf("(%d) %s - %s/%s should be '%s' - '%s'\n", __LINE__, \
call_name, #stype, #field, \
value, \
finfo2.stype.out.field); \
dump_all_info(mem_ctx, &finfo1); \
}} while (0)
/* test setattr */
sfinfo.setattr.in.attrib = FILE_ATTRIBUTE_READONLY;
sfinfo.setattr.in.write_time = basetime;
CHECK_CALL_PATH(SETATTR, NT_STATUS_OK);
CHECK_VALUE (ALL_INFO, all_info, attrib, FILE_ATTRIBUTE_READONLY);
CHECK_TIME (ALL_INFO, all_info, write_time, basetime);
/* a zero write_time means don't change */
sfinfo.setattr.in.attrib = 0;
sfinfo.setattr.in.write_time = 0;
CHECK_CALL_PATH(SETATTR, NT_STATUS_OK);
CHECK_VALUE(ALL_INFO, all_info, attrib, FILE_ATTRIBUTE_NORMAL);
CHECK_TIME (ALL_INFO, all_info, write_time, basetime);
/* test setattre */
sfinfo.setattre.in.create_time = basetime + 20;
sfinfo.setattre.in.access_time = basetime + 30;
sfinfo.setattre.in.write_time = basetime + 40;
CHECK_CALL_FNUM(SETATTRE, NT_STATUS_OK);
CHECK_TIME(ALL_INFO, all_info, create_time, basetime + 20);
CHECK_TIME(ALL_INFO, all_info, access_time, basetime + 30);
CHECK_TIME(ALL_INFO, all_info, write_time, basetime + 40);
sfinfo.setattre.in.create_time = 0;
sfinfo.setattre.in.access_time = 0;
sfinfo.setattre.in.write_time = 0;
CHECK_CALL_FNUM(SETATTRE, NT_STATUS_OK);
CHECK_TIME(ALL_INFO, all_info, create_time, basetime + 20);
CHECK_TIME(ALL_INFO, all_info, access_time, basetime + 30);
CHECK_TIME(ALL_INFO, all_info, write_time, basetime + 40);
/* test standard level */
sfinfo.standard.in.create_time = basetime + 100;
sfinfo.standard.in.access_time = basetime + 200;
sfinfo.standard.in.write_time = basetime + 300;
CHECK_CALL_FNUM(STANDARD, NT_STATUS_OK);
CHECK_TIME(ALL_INFO, all_info, create_time, basetime + 100);
CHECK_TIME(ALL_INFO, all_info, access_time, basetime + 200);
CHECK_TIME(ALL_INFO, all_info, write_time, basetime + 300);
/* test basic_info level */
basetime += 86400;
unix_to_nt_time(&sfinfo.basic_info.in.create_time, basetime + 100);
unix_to_nt_time(&sfinfo.basic_info.in.access_time, basetime + 200);
unix_to_nt_time(&sfinfo.basic_info.in.write_time, basetime + 300);
unix_to_nt_time(&sfinfo.basic_info.in.change_time, basetime + 400);
sfinfo.basic_info.in.attrib = FILE_ATTRIBUTE_READONLY;
CHECK_CALL_FNUM(BASIC_INFO, NT_STATUS_OK);
CHECK_TIME(ALL_INFO, all_info, create_time, basetime + 100);
CHECK_TIME(ALL_INFO, all_info, access_time, basetime + 200);
CHECK_TIME(ALL_INFO, all_info, write_time, basetime + 300);
CHECK_TIME(ALL_INFO, all_info, change_time, basetime + 400);
CHECK_VALUE(ALL_INFO, all_info, attrib, FILE_ATTRIBUTE_READONLY);
/* a zero time means don't change */
unix_to_nt_time(&sfinfo.basic_info.in.create_time, 0);
unix_to_nt_time(&sfinfo.basic_info.in.access_time, 0);
unix_to_nt_time(&sfinfo.basic_info.in.write_time, 0);
unix_to_nt_time(&sfinfo.basic_info.in.change_time, 0);
sfinfo.basic_info.in.attrib = FILE_ATTRIBUTE_NORMAL;
CHECK_CALL_FNUM(BASIC_INFO, NT_STATUS_OK);
CHECK_TIME(ALL_INFO, all_info, create_time, basetime + 100);
CHECK_TIME(ALL_INFO, all_info, access_time, basetime + 200);
CHECK_TIME(ALL_INFO, all_info, write_time, basetime + 300);
CHECK_TIME(ALL_INFO, all_info, change_time, basetime + 400);
CHECK_VALUE(ALL_INFO, all_info, attrib, FILE_ATTRIBUTE_NORMAL);
/* test basic_information level */
basetime += 86400;
unix_to_nt_time(&sfinfo.basic_info.in.create_time, basetime + 100);
unix_to_nt_time(&sfinfo.basic_info.in.access_time, basetime + 200);
unix_to_nt_time(&sfinfo.basic_info.in.write_time, basetime + 300);
unix_to_nt_time(&sfinfo.basic_info.in.change_time, basetime + 400);
sfinfo.basic_info.in.attrib = FILE_ATTRIBUTE_READONLY;
CHECK_CALL_FNUM(BASIC_INFORMATION, NT_STATUS_OK);
CHECK_TIME(ALL_INFO, all_info, create_time, basetime + 100);
CHECK_TIME(ALL_INFO, all_info, access_time, basetime + 200);
CHECK_TIME(ALL_INFO, all_info, write_time, basetime + 300);
CHECK_TIME(ALL_INFO, all_info, change_time, basetime + 400);
CHECK_VALUE(ALL_INFO, all_info, attrib, FILE_ATTRIBUTE_READONLY);
CHECK_CALL_PATH(BASIC_INFORMATION, NT_STATUS_OK);
CHECK_TIME(ALL_INFO, all_info, create_time, basetime + 100);
CHECK_TIME(ALL_INFO, all_info, access_time, basetime + 200);
CHECK_TIME(ALL_INFO, all_info, write_time, basetime + 300);
CHECK_TIME(ALL_INFO, all_info, change_time, basetime + 400);
CHECK_VALUE(ALL_INFO, all_info, attrib, FILE_ATTRIBUTE_READONLY);
/* a zero time means don't change */
unix_to_nt_time(&sfinfo.basic_info.in.create_time, 0);
unix_to_nt_time(&sfinfo.basic_info.in.access_time, 0);
unix_to_nt_time(&sfinfo.basic_info.in.write_time, 0);
unix_to_nt_time(&sfinfo.basic_info.in.change_time, 0);
sfinfo.basic_info.in.attrib = FILE_ATTRIBUTE_NORMAL;
CHECK_CALL_FNUM(BASIC_INFORMATION, NT_STATUS_OK);
CHECK_TIME(ALL_INFO, all_info, create_time, basetime + 100);
CHECK_TIME(ALL_INFO, all_info, access_time, basetime + 200);
CHECK_TIME(ALL_INFO, all_info, write_time, basetime + 300);
CHECK_TIME(ALL_INFO, all_info, change_time, basetime + 400);
CHECK_VALUE(ALL_INFO, all_info, attrib, FILE_ATTRIBUTE_NORMAL);
CHECK_CALL_PATH(BASIC_INFORMATION, NT_STATUS_OK);
CHECK_TIME(ALL_INFO, all_info, create_time, basetime + 100);
CHECK_TIME(ALL_INFO, all_info, access_time, basetime + 200);
CHECK_TIME(ALL_INFO, all_info, write_time, basetime + 300);
/* interesting - w2k3 leaves change_time as current time for 0 change time
in setpathinfo
CHECK_TIME(ALL_INFO, all_info, change_time, basetime + 400);
*/
CHECK_VALUE(ALL_INFO, all_info, attrib, FILE_ATTRIBUTE_NORMAL);
/* test disposition_info level */
sfinfo.disposition_info.in.delete_on_close = 1;
CHECK_CALL_FNUM(DISPOSITION_INFO, NT_STATUS_OK);
CHECK_VALUE(ALL_INFO, all_info, delete_pending, 1);
CHECK_VALUE(ALL_INFO, all_info, nlink, 0);
sfinfo.disposition_info.in.delete_on_close = 0;
CHECK_CALL_FNUM(DISPOSITION_INFO, NT_STATUS_OK);
CHECK_VALUE(ALL_INFO, all_info, delete_pending, 0);
CHECK_VALUE(ALL_INFO, all_info, nlink, 1);
/* test disposition_information level */
sfinfo.disposition_info.in.delete_on_close = 1;
CHECK_CALL_FNUM(DISPOSITION_INFORMATION, NT_STATUS_OK);
CHECK_VALUE(ALL_INFO, all_info, delete_pending, 1);
CHECK_VALUE(ALL_INFO, all_info, nlink, 0);
/* this would delete the file! */
/*
CHECK_CALL_PATH(DISPOSITION_INFORMATION, NT_STATUS_OK);
CHECK_VALUE(ALL_INFO, all_info, delete_pending, 1);
CHECK_VALUE(ALL_INFO, all_info, nlink, 0);
*/
sfinfo.disposition_info.in.delete_on_close = 0;
CHECK_CALL_FNUM(DISPOSITION_INFORMATION, NT_STATUS_OK);
CHECK_VALUE(ALL_INFO, all_info, delete_pending, 0);
CHECK_VALUE(ALL_INFO, all_info, nlink, 1);
CHECK_CALL_PATH(DISPOSITION_INFORMATION, NT_STATUS_OK);
CHECK_VALUE(ALL_INFO, all_info, delete_pending, 0);
CHECK_VALUE(ALL_INFO, all_info, nlink, 1);
/* test allocation_info level - this can truncate the file
to the rounded up size */
sfinfo.allocation_info.in.alloc_size = 0;
CHECK_CALL_FNUM(ALLOCATION_INFO, NT_STATUS_OK);
CHECK_VALUE(ALL_INFO, all_info, size, 0);
CHECK_VALUE(ALL_INFO, all_info, alloc_size, 0);
sfinfo.allocation_info.in.alloc_size = 4096;
CHECK_CALL_FNUM(ALLOCATION_INFO, NT_STATUS_OK);
CHECK_VALUE(ALL_INFO, all_info, alloc_size, 4096);
CHECK_VALUE(ALL_INFO, all_info, size, 0);
RECREATE_BOTH;
sfinfo.allocation_info.in.alloc_size = 0;
CHECK_CALL_FNUM(ALLOCATION_INFORMATION, NT_STATUS_OK);
CHECK_VALUE(ALL_INFO, all_info, size, 0);
CHECK_VALUE(ALL_INFO, all_info, alloc_size, 0);
CHECK_CALL_PATH(ALLOCATION_INFORMATION, NT_STATUS_OK);
CHECK_VALUE(ALL_INFO, all_info, size, 0);
CHECK_VALUE(ALL_INFO, all_info, alloc_size, 0);
sfinfo.allocation_info.in.alloc_size = 4096;
CHECK_CALL_FNUM(ALLOCATION_INFORMATION, NT_STATUS_OK);
CHECK_VALUE(ALL_INFO, all_info, alloc_size, 4096);
CHECK_VALUE(ALL_INFO, all_info, size, 0);
/* setting the allocation size up via setpathinfo seems
to be broken in w2k3 */
CHECK_CALL_PATH(ALLOCATION_INFORMATION, NT_STATUS_OK);
CHECK_VALUE(ALL_INFO, all_info, alloc_size, 0);
CHECK_VALUE(ALL_INFO, all_info, size, 0);
/* test end_of_file_info level */
sfinfo.end_of_file_info.in.size = 37;
CHECK_CALL_FNUM(END_OF_FILE_INFO, NT_STATUS_OK);
CHECK_VALUE(ALL_INFO, all_info, size, 37);
sfinfo.end_of_file_info.in.size = 7;
CHECK_CALL_FNUM(END_OF_FILE_INFO, NT_STATUS_OK);
CHECK_VALUE(ALL_INFO, all_info, size, 7);
sfinfo.end_of_file_info.in.size = 37;
CHECK_CALL_FNUM(END_OF_FILE_INFORMATION, NT_STATUS_OK);
CHECK_VALUE(ALL_INFO, all_info, size, 37);
CHECK_CALL_PATH(END_OF_FILE_INFORMATION, NT_STATUS_OK);
CHECK_VALUE(ALL_INFO, all_info, size, 37);
sfinfo.end_of_file_info.in.size = 7;
CHECK_CALL_FNUM(END_OF_FILE_INFORMATION, NT_STATUS_OK);
CHECK_VALUE(ALL_INFO, all_info, size, 7);
CHECK_CALL_PATH(END_OF_FILE_INFORMATION, NT_STATUS_OK);
CHECK_VALUE(ALL_INFO, all_info, size, 7);
/* test position_information level */
sfinfo.position_information.in.position = 123456;
CHECK_CALL_FNUM(POSITION_INFORMATION, NT_STATUS_OK);
CHECK_VALUE(POSITION_INFORMATION, position_information, position, 123456);
CHECK_CALL_PATH(POSITION_INFORMATION, NT_STATUS_OK);
CHECK_VALUE(POSITION_INFORMATION, position_information, position, 0);
/* test mode_information level */
sfinfo.mode_information.in.mode = 2;
CHECK_CALL_FNUM(MODE_INFORMATION, NT_STATUS_OK);
CHECK_VALUE(MODE_INFORMATION, mode_information, mode, 2);
CHECK_CALL_PATH(MODE_INFORMATION, NT_STATUS_OK);
CHECK_VALUE(MODE_INFORMATION, mode_information, mode, 0);
sfinfo.mode_information.in.mode = 1;
CHECK_CALL_FNUM(MODE_INFORMATION, NT_STATUS_INVALID_PARAMETER);
CHECK_CALL_PATH(MODE_INFORMATION, NT_STATUS_INVALID_PARAMETER);
sfinfo.mode_information.in.mode = 0;
CHECK_CALL_FNUM(MODE_INFORMATION, NT_STATUS_OK);
CHECK_VALUE(MODE_INFORMATION, mode_information, mode, 0);
CHECK_CALL_PATH(MODE_INFORMATION, NT_STATUS_OK);
CHECK_VALUE(MODE_INFORMATION, mode_information, mode, 0);
/* finally the rename_information level */
cli_close(cli, create_complex_file(cli, mem_ctx, fnum_fname_new));
cli_close(cli, create_complex_file(cli, mem_ctx, path_fname_new));
sfinfo.rename_information.in.overwrite = 0;
sfinfo.rename_information.in.root_fid = 0;
sfinfo.rename_information.in.new_name = fnum_fname_new+1;
CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_OBJECT_NAME_COLLISION);
sfinfo.rename_information.in.new_name = path_fname_new+1;
CHECK_CALL_PATH(RENAME_INFORMATION, NT_STATUS_OBJECT_NAME_COLLISION);
sfinfo.rename_information.in.new_name = fnum_fname_new+1;
sfinfo.rename_information.in.overwrite = 1;
CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_OK);
CHECK_STR(NAME_INFO, name_info, fname.s, fnum_fname_new);
sfinfo.rename_information.in.new_name = path_fname_new+1;
CHECK_CALL_PATH(RENAME_INFORMATION, NT_STATUS_OK);
CHECK_STR(NAME_INFO, name_info, fname.s, path_fname_new);
sfinfo.rename_information.in.new_name = fnum_fname+1;
CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_OK);
CHECK_STR(NAME_INFO, name_info, fname.s, fnum_fname);
sfinfo.rename_information.in.new_name = path_fname+1;
CHECK_CALL_PATH(RENAME_INFORMATION, NT_STATUS_OK);
CHECK_STR(NAME_INFO, name_info, fname.s, path_fname);
done:
cli_close(cli, fnum);
if (!cli_unlink(cli, fnum_fname)) {
printf("Failed to delete %s - %s\n", fnum_fname, cli_errstr(cli));
}
if (!cli_unlink(cli, path_fname)) {
printf("Failed to delete %s - %s\n", path_fname, cli_errstr(cli));
}
torture_close_connection(cli);
talloc_destroy(mem_ctx);
return ret;
}
/*
look for the w2k3 setpathinfo STANDARD bug
*/
BOOL torture_sfileinfo_bug(int dummy)
{
struct cli_state *cli;
TALLOC_CTX *mem_ctx;
const char *fname = "\\bug3.txt";
union smb_setfileinfo sfinfo;
NTSTATUS status;
int fnum;
if (!torture_open_connection(&cli)) {
return False;
}
mem_ctx = talloc_init("torture_sfileinfo");
fnum = create_complex_file(cli, mem_ctx, fname);
cli_close(cli, fnum);
sfinfo.generic.level = RAW_SFILEINFO_STANDARD;
sfinfo.generic.file.fname = fname;
sfinfo.standard.in.create_time = 0;
sfinfo.standard.in.access_time = 0;
sfinfo.standard.in.write_time = 0;
status = smb_raw_setpathinfo(cli->tree, &sfinfo);
printf("%s - %s\n", fname, nt_errstr(status));
printf("now try and delete %s\n", fname);
return True;
}