📄 smbtorture.c
字号:
/* Unix SMB/CIFS implementation. SMB torture tester Copyright (C) Andrew Tridgell 1997-2003 Copyright (C) Jelmer Vernooij 2006-2008 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 3 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, see <http://www.gnu.org/licenses/>.*/#include "includes.h"#include "lib/cmdline/popt_common.h"#include "system/time.h"#include "system/wait.h"#include "system/filesys.h"#include "system/readline.h"#include "lib/smbreadline/smbreadline.h"#include "libcli/libcli.h"#include "lib/ldb/include/ldb.h"#include "lib/events/events.h"#include "dynconfig/dynconfig.h"#include "torture/smbtorture.h"#include "lib/util/dlinklist.h"#include "librpc/rpc/dcerpc.h"#include "param/param.h"#include "auth/credentials/credentials.h"static bool run_matching(struct torture_context *torture, const char *prefix, const char *expr, struct torture_suite *suite, bool *matched){ bool ret = true; if (suite == NULL) { struct torture_suite *o; for (o = torture_root->children; o; o = o->next) { if (gen_fnmatch(expr, o->name) == 0) { *matched = true; reload_charcnv(torture->lp_ctx); ret &= torture_run_suite(torture, o); continue; } ret &= run_matching(torture, o->name, expr, o, matched); } } else { char *name; struct torture_suite *c; struct torture_tcase *t; for (c = suite->children; c; c = c->next) { asprintf(&name, "%s-%s", prefix, c->name); if (gen_fnmatch(expr, name) == 0) { *matched = true; reload_charcnv(torture->lp_ctx); torture->active_testname = talloc_strdup(torture, prefix); ret &= torture_run_suite(torture, c); free(name); continue; } ret &= run_matching(torture, name, expr, c, matched); free(name); } for (t = suite->testcases; t; t = t->next) { asprintf(&name, "%s-%s", prefix, t->name); if (gen_fnmatch(expr, name) == 0) { *matched = true; reload_charcnv(torture->lp_ctx); torture->active_testname = talloc_strdup(torture, prefix); ret &= torture_run_tcase(torture, t); talloc_free(torture->active_testname); } free(name); } } return ret;}#define MAX_COLS 80 /* FIXME: Determine this at run-time *//****************************************************************************run a specified test or "ALL"****************************************************************************/static bool run_test(struct torture_context *torture, const char *name){ bool ret = true; bool matched = false; struct torture_suite *o; if (strequal(name, "ALL")) { for (o = torture_root->children; o; o = o->next) { ret &= torture_run_suite(torture, o); } return ret; } ret = run_matching(torture, NULL, name, NULL, &matched); if (!matched) { printf("Unknown torture operation '%s'\n", name); return false; } return ret;}static bool parse_target(struct loadparm_context *lp_ctx, const char *target){ char *host = NULL, *share = NULL; struct dcerpc_binding *binding_struct; NTSTATUS status; /* see if its a RPC transport specifier */ if (!smbcli_parse_unc(target, NULL, &host, &share)) { status = dcerpc_parse_binding(talloc_autofree_context(), target, &binding_struct); if (NT_STATUS_IS_ERR(status)) { d_printf("Invalid option: %s is not a valid torture target (share or binding string)\n\n", target); return false; } lp_set_cmdline(lp_ctx, "torture:host", binding_struct->host); if (lp_parm_string(lp_ctx, NULL, "torture", "share") == NULL) lp_set_cmdline(lp_ctx, "torture:share", "IPC$"); lp_set_cmdline(lp_ctx, "torture:binding", target); } else { lp_set_cmdline(lp_ctx, "torture:host", host); lp_set_cmdline(lp_ctx, "torture:share", share); lp_set_cmdline(lp_ctx, "torture:binding", host); } return true;}static void parse_dns(struct loadparm_context *lp_ctx, const char *dns){ char *userdn, *basedn, *secret; char *p, *d; /* retrievieng the userdn */ p = strchr_m(dns, '#'); if (!p) { lp_set_cmdline(lp_ctx, "torture:ldap_userdn", ""); lp_set_cmdline(lp_ctx, "torture:ldap_basedn", ""); lp_set_cmdline(lp_ctx, "torture:ldap_secret", ""); return; } userdn = strndup(dns, p - dns); lp_set_cmdline(lp_ctx, "torture:ldap_userdn", userdn); /* retrieve the basedn */ d = p + 1; p = strchr_m(d, '#'); if (!p) { lp_set_cmdline(lp_ctx, "torture:ldap_basedn", ""); lp_set_cmdline(lp_ctx, "torture:ldap_secret", ""); return; } basedn = strndup(d, p - d); lp_set_cmdline(lp_ctx, "torture:ldap_basedn", basedn); /* retrieve the secret */ p = p + 1; if (!p) { lp_set_cmdline(lp_ctx, "torture:ldap_secret", ""); return; } secret = strdup(p); lp_set_cmdline(lp_ctx, "torture:ldap_secret", secret); printf ("%s - %s - %s\n", userdn, basedn, secret);}static void print_test_list(void){ struct torture_suite *o; struct torture_suite *s; struct torture_tcase *t; if (torture_root == NULL) return; for (o = torture_root->children; o; o = o->next) { for (s = o->children; s; s = s->next) { printf("%s-%s\n", o->name, s->name); } for (t = o->testcases; t; t = t->next) { printf("%s-%s\n", o->name, t->name); } }}_NORETURN_ static void usage(poptContext pc){ struct torture_suite *o; struct torture_suite *s; struct torture_tcase *t; int i; poptPrintUsage(pc, stdout, 0); printf("\n"); printf("The binding format is:\n\n"); printf(" TRANSPORT:host[flags]\n\n"); printf(" where TRANSPORT is either ncacn_np for SMB, ncacn_ip_tcp for RPC/TCP\n"); printf(" or ncalrpc for local connections.\n\n"); printf(" 'host' is an IP or hostname or netbios name. If the binding string\n"); printf(" identifies the server side of an endpoint, 'host' may be an empty\n"); printf(" string.\n\n"); printf(" 'flags' can include a SMB pipe name if using the ncacn_np transport or\n"); printf(" a TCP port number if using the ncacn_ip_tcp transport, otherwise they\n"); printf(" will be auto-determined.\n\n"); printf(" other recognised flags are:\n\n"); printf(" sign : enable ntlmssp signing\n"); printf(" seal : enable ntlmssp sealing\n"); printf(" connect : enable rpc connect level auth (auth, but no sign or seal)\n"); printf(" validate: enable the NDR validator\n"); printf(" print: enable debugging of the packets\n"); printf(" bigendian: use bigendian RPC\n"); printf(" padcheck: check reply data for non-zero pad bytes\n\n"); printf(" For example, these all connect to the samr pipe:\n\n"); printf(" ncacn_np:myserver\n"); printf(" ncacn_np:myserver[samr]\n"); printf(" ncacn_np:myserver[\\pipe\\samr]\n"); printf(" ncacn_np:myserver[/pipe/samr]\n"); printf(" ncacn_np:myserver[samr,sign,print]\n"); printf(" ncacn_np:myserver[\\pipe\\samr,sign,seal,bigendian]\n"); printf(" ncacn_np:myserver[/pipe/samr,seal,validate]\n"); printf(" ncacn_np:\n"); printf(" ncacn_np:[/pipe/samr]\n\n"); printf(" ncacn_ip_tcp:myserver\n"); printf(" ncacn_ip_tcp:myserver[1024]\n"); printf(" ncacn_ip_tcp:myserver[1024,sign,seal]\n\n"); printf(" ncalrpc:\n\n"); printf("The UNC format is:\n\n"); printf(" //server/share\n\n"); printf("Tests are:"); if (torture_root == NULL) { printf("NO TESTS LOADED\n"); exit(1); } for (o = torture_root->children; o; o = o->next) { printf("\n%s (%s):\n ", o->description, o->name); i = 0; for (s = o->children; s; s = s->next) { if (i + strlen(o->name) + strlen(s->name) >= (MAX_COLS - 3)) { printf("\n "); i = 0; } i+=printf("%s-%s ", o->name, s->name); } for (t = o->testcases; t; t = t->next) { if (i + strlen(o->name) + strlen(t->name) >= (MAX_COLS - 3)) { printf("\n "); i = 0; } i+=printf("%s-%s ", o->name, t->name); } if (i) printf("\n"); } printf("\nThe default test is ALL.\n"); exit(1);}_NORETURN_ static void max_runtime_handler(int sig){ DEBUG(0,("maximum runtime exceeded for smbtorture - terminating\n")); exit(1);}struct timeval last_suite_started;static void simple_suite_start(struct torture_context *ctx, struct torture_suite *suite){ last_suite_started = timeval_current(); printf("Running %s\n", suite->name);}static void simple_suite_finish(struct torture_context *ctx, struct torture_suite *suite){ printf("%s took %g secs\n\n", suite->name, timeval_elapsed(&last_suite_started));}static void simple_test_result(struct torture_context *context, enum torture_result res, const char *reason){ switch (res) { case TORTURE_OK: if (reason) printf("OK: %s\n", reason); break; case TORTURE_FAIL: printf("TEST %s FAILED! - %s\n", context->active_test->name, reason); break; case TORTURE_ERROR: printf("ERROR IN TEST %s! - %s\n", context->active_test->name, reason); break; case TORTURE_SKIP: printf("SKIP: %s - %s\n", context->active_test->name, reason); break; }}static void simple_comment(struct torture_context *test, const char *comment){ printf("%s", comment);}static void simple_warning(struct torture_context *test, const char *comment){ fprintf(stderr, "WARNING: %s\n", comment);}const static struct torture_ui_ops std_ui_ops = { .comment = simple_comment, .warning = simple_warning, .suite_start = simple_suite_start, .suite_finish = simple_suite_finish,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -