From a71f3f66a1b47a70e402c4d82736f376449b923c Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 25 Nov 2001 02:35:37 +0000 Subject: Add a new torture test to extract a NT->DOS error map from an NT member of a samba domain. The PDC must be running a special authenticaion module that spits out NT errors based on username. Andrew Bartlett (This used to be commit adc7a6048c13342b79b6228beafb5142c50f318d) --- source3/libsmb/cliconnect.c | 5 +-- source3/libsmb/clientgen.c | 7 +++++ source3/libsmb/nterr.c | 21 +++++++++++++ source3/libsmb/smberr.c | 46 +++++++++++++++++++++++++++- source3/torture/torture.c | 74 +++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 148 insertions(+), 5 deletions(-) (limited to 'source3') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 4ea19db9ec..ed4bfcd9e3 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -117,10 +117,7 @@ static uint32 cli_session_setup_capabilities(struct cli_state *cli) { uint32 capabilities = CAP_NT_SMBS; - /* Set the CLI_FORCE_DOSERR environment variable to test - client routines using DOS errors instead of STATUS32 - ones. This intended only as a temporary hack. */ - if (!getenv("CLI_FORCE_DOSERR")) { + if (!cli->force_dos_errors) { capabilities |= CAP_STATUS32; } diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 0f1fa2e42e..0e09388803 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -198,6 +198,13 @@ struct cli_state *cli_initialise(struct cli_state *cli) cli->oplock_handler = cli_oplock_ack; cli->use_spnego = True; + /* Set the CLI_FORCE_DOSERR environment variable to test + client routines using DOS errors instead of STATUS32 + ones. This intended only as a temporary hack. */ + if (getenv("CLI_FORCE_DOSERR")) { + cli->force_dos_errors = True; + } + if (!cli->outbuf || !cli->inbuf) goto error; diff --git a/source3/libsmb/nterr.c b/source3/libsmb/nterr.c index 238908d6cd..25286156ee 100644 --- a/source3/libsmb/nterr.c +++ b/source3/libsmb/nterr.c @@ -558,3 +558,24 @@ char *get_nt_error_msg(NTSTATUS nt_code) return msg; } + +/***************************************************************************** + returns an NT_STATUS constant as a string for inclusion in autogen C code + *****************************************************************************/ +char *get_nt_error_c_code(NTSTATUS nt_code) +{ + static pstring out; + int idx = 0; + + while (nt_errs[idx].nt_errstr != NULL) { + if (NT_STATUS_V(nt_errs[idx].nt_errcode) == + NT_STATUS_V(nt_code)) { + return nt_errs[idx].nt_errstr; + } + idx++; + } + + slprintf(out, sizeof(out), "NT_STATUS(0x%08x)", NT_STATUS_V(nt_code)); + + return out; +} diff --git a/source3/libsmb/smberr.c b/source3/libsmb/smberr.c index a43e4764e8..d0aa8f6024 100644 --- a/source3/libsmb/smberr.c +++ b/source3/libsmb/smberr.c @@ -156,7 +156,51 @@ const struct /**************************************************************************** -return a SMB error string from a SMB buffer +return a SMB error name from a class and code +****************************************************************************/ +char *smb_dos_err_name(uint8 class, uint16 num) +{ + static pstring ret; + int i,j; + + for (i=0;err_classes[i].class;i++) + if (err_classes[i].code == class) { + if (err_classes[i].err_msgs) { + err_code_struct *err = err_classes[i].err_msgs; + for (j=0;err[j].name;j++) + if (num == err[j].code) { + return err[j].name; + } + } + slprintf(ret, sizeof(ret) - 1, "%d",num); + return ret; + } + + slprintf(ret, sizeof(ret) - 1, "Error: Unknown error class (%d,%d)",class,num); + return(ret); +} + + +/**************************************************************************** +return a SMB error class name as a string. +****************************************************************************/ +char *smb_dos_err_class(uint8 class) +{ + static pstring ret; + int i; + + for (i=0;err_classes[i].class;i++) { + if (err_classes[i].code == class) { + return err_classes[i].class; + } + } + + slprintf(ret, sizeof(ret) - 1, "Error: Unknown class (%d)",class); + return(ret); +} + +/**************************************************************************** +return a SMB string from an SMB buffer ****************************************************************************/ char *smb_dos_errstr(char *inbuf) { diff --git a/source3/torture/torture.c b/source3/torture/torture.c index e2c65bc1d3..234f3d3335 100644 --- a/source3/torture/torture.c +++ b/source3/torture/torture.c @@ -2856,7 +2856,80 @@ static BOOL run_dirtest(int dummy) return correct; } +static BOOL run_error_map_extract(int dummy) { + + static struct cli_state c_dos; + static struct cli_state c_nt; + + uint32 error; + + uint32 flgs2, errnum; + uint8 errclass; + + NTSTATUS nt_status; + + fstring user; + + open_nbt_connection(&c_nt); + open_nbt_connection(&c_dos); + + c_dos.force_dos_errors = True; + if (!cli_negprot(&c_dos)) { + printf("%s rejected the DOS-error negprot (%s)\n",host, cli_errstr(&c_dos)); + cli_shutdown(&c_dos); + return False; + } + if (!cli_negprot(&c_nt)) { + printf("%s rejected the NT-error negprot (%s)\n",host, cli_errstr(&c_nt)); + cli_shutdown(&c_nt); + return False; + } + + for (error=(0xc0000000 | 0x1); error < (0xc0000000| 0xFFF); error++) { + snprintf(user, sizeof(user), "%X", error); + + if (!cli_session_setup(&c_nt, user, + password, strlen(password), + password, strlen(password), + workgroup)) { + flgs2 = SVAL(c_nt.inbuf,smb_flg2); + + /* Case #1: 32-bit NT errors */ + if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) { + nt_status = NT_STATUS(IVAL(c_nt.inbuf,smb_rcls)); + } else { + printf("** Dos error on NT connection! (%s)\n", cli_errstr(&c_nt)); + nt_status = NT_STATUS(0xc0000000); + } + } else { + printf("** Session setup succeeded. This shouldn't happen...\n"); + } + + if (!cli_session_setup(&c_dos, user, + password, strlen(password), + password, strlen(password), + workgroup)) { + flgs2 = SVAL(c_dos.inbuf,smb_flg2), errnum; + + /* Case #1: 32-bit NT errors */ + if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) { + printf("** NT error on DOS connection! (%s)\n", cli_errstr(&c_nt)); + errnum = errclass = 0; + } else { + cli_dos_error(&c_dos, &errclass, &errnum); + } + } else { + printf("** Session setup succeeded. This shouldn't happen...\n"); + } + if (NT_STATUS_V(nt_status) == error) { + printf("\t{%s,\t%s,\t%s}\n", smb_dos_err_class(errclass), smb_dos_err_name(errclass, errnum), get_nt_error_c_code(nt_status)); + } else { + printf("/*\t{ This NT error code was 'sqashed'\n\t from %s to %s \n\t during the session setup }\n*/\n", get_nt_error_c_code(NT_STATUS(error)), get_nt_error_c_code(nt_status)); + } + } + return True; +} static double create_procs(BOOL (*fn)(int), BOOL *result) { @@ -2992,6 +3065,7 @@ static struct { {"NTTRANSSCAN", torture_nttrans_scan, 0}, {"UTABLE", torture_utable, 0}, {"CASETABLE", torture_casetable, 0}, + {"ERRMAPEXTRACT", run_error_map_extract, 0}, {NULL, NULL, 0}}; -- cgit