From 235aedae5030dac138fbaa5726022f5007586cd2 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 8 Jul 2011 10:52:22 +0200 Subject: [PATCH] s3:libsmb: don't use the cli->inbuf to store the last error We keep the raw error in cli->raw_status now, until we fixed all caller to get the NTSTATUS from the function calls. metze --- source3/include/async_smb.h | 12 ------- source3/include/client.h | 1 + source3/libsmb/async_smb.c | 50 +++++++++------------------- source3/libsmb/clientgen.c | 1 + source3/libsmb/clierror.c | 81 +++++++++++++-------------------------------- 5 files changed, 41 insertions(+), 104 deletions(-) diff --git a/source3/include/async_smb.h b/source3/include/async_smb.h index 1685d4985d4..40da862be22 100644 --- a/source3/include/async_smb.h +++ b/source3/include/async_smb.h @@ -22,18 +22,6 @@ struct cli_state; -/* - * Fetch an error out of a NBT packet - */ - -NTSTATUS cli_pull_error(char *buf); - -/* - * Compatibility helper for the sync APIs: Fake NTSTATUS in cli->inbuf - */ - -void cli_set_error(struct cli_state *cli, NTSTATUS status); - struct tevent_req *cli_smb_req_create(TALLOC_CTX *mem_ctx, struct event_context *ev, struct cli_state *cli, diff --git a/source3/include/client.h b/source3/include/client.h index fc591828ae9..bd6de4afb9c 100644 --- a/source3/include/client.h +++ b/source3/include/client.h @@ -60,6 +60,7 @@ struct cli_state { int protocol; int sec_mode; int rap_error; + NTSTATUS raw_status; /* maybe via NT_STATUS_DOS() */ int privileges; char *desthost; diff --git a/source3/libsmb/async_smb.c b/source3/libsmb/async_smb.c index ee15caee7a5..e932ddb1014 100644 --- a/source3/libsmb/async_smb.c +++ b/source3/libsmb/async_smb.c @@ -27,13 +27,7 @@ #include "libsmb/nmblib.h" #include "read_smb.h" -/** - * Fetch an error out of a NBT packet - * @param[in] buf The SMB packet - * @retval The error, converted to NTSTATUS - */ - -NTSTATUS cli_pull_error(char *buf) +static NTSTATUS cli_pull_raw_error(const uint8_t *buf) { uint32_t flags2 = SVAL(buf, smb_flg2); @@ -41,30 +35,7 @@ NTSTATUS cli_pull_error(char *buf) return NT_STATUS(IVAL(buf, smb_rcls)); } - return dos_to_ntstatus(CVAL(buf, smb_rcls), SVAL(buf,smb_err)); -} - -/** - * Compatibility helper for the sync APIs: Fake NTSTATUS in cli->inbuf - * @param[in] cli The client connection that just received an error - * @param[in] status The error to set on "cli" - */ - -void cli_set_error(struct cli_state *cli, NTSTATUS status) -{ - uint32_t flags2 = SVAL(cli->inbuf, smb_flg2); - - if (NT_STATUS_IS_DOS(status)) { - SSVAL(cli->inbuf, smb_flg2, - flags2 & ~FLAGS2_32_BIT_ERROR_CODES); - SCVAL(cli->inbuf, smb_rcls, NT_STATUS_DOS_CLASS(status)); - SSVAL(cli->inbuf, smb_err, NT_STATUS_DOS_CODE(status)); - return; - } - - SSVAL(cli->inbuf, smb_flg2, flags2 | FLAGS2_32_BIT_ERROR_CODES); - SIVAL(cli->inbuf, smb_rcls, NT_STATUS_V(status)); - return; + return NT_STATUS_DOS(CVAL(buf, smb_rcls), SVAL(buf,smb_err)); } /** @@ -781,9 +752,20 @@ NTSTATUS cli_smb_recv(struct tevent_req *req, cmd = CVAL(state->inbuf, wct_ofs + 1); } - status = cli_pull_error((char *)state->inbuf); - - cli_set_error(state->cli, status); + state->cli->raw_status = cli_pull_raw_error(state->inbuf); + if (NT_STATUS_IS_DOS(state->cli->raw_status)) { + uint8_t eclass = NT_STATUS_DOS_CLASS(state->cli->raw_status); + uint16_t ecode = NT_STATUS_DOS_CODE(state->cli->raw_status); + /* + * TODO: is it really a good idea to do a mapping here? + * + * The old cli_pull_error() also does it, so I do not change + * the behavior yet. + */ + status = dos_to_ntstatus(eclass, ecode); + } else { + status = state->cli->raw_status; + } if (!have_andx_command((char *)state->inbuf, wct_ofs)) { diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 676e48205e0..e874a8983ca 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -193,6 +193,7 @@ struct cli_state *cli_initialise_ex(int signing_state) } cli->port = 0; cli->fd = -1; + cli->raw_status = NT_STATUS_INTERNAL_ERROR; cli->cnum = -1; cli->pid = (uint16)sys_getpid(); cli->mid = 1; diff --git a/source3/libsmb/clierror.c b/source3/libsmb/clierror.c index 4b6f0448816..7541a690107 100644 --- a/source3/libsmb/clierror.c +++ b/source3/libsmb/clierror.c @@ -22,15 +22,6 @@ #include "includes.h" #include "libsmb/libsmb.h" -/**************************************************************************** - Return a description of an SMB error. -****************************************************************************/ - -static const char *cli_smb_errstr(struct cli_state *cli) -{ - return smb_dos_errstr(cli->inbuf); -} - /*************************************************************************** Return an error message - either an NT error, SMB error or a RAP error. Note some of the NT errors are actually warnings or "informational" errors @@ -40,8 +31,6 @@ static const char *cli_smb_errstr(struct cli_state *cli) const char *cli_errstr(struct cli_state *cli) { fstring cli_error_message; - uint32 flgs2 = SVAL(cli->inbuf,smb_flg2), errnum; - uint8 errclass; char *result; if (!cli->initialised) { @@ -56,19 +45,11 @@ const char *cli_errstr(struct cli_state *cli) goto done; } - /* Case #2: 32-bit NT errors */ - if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) { - NTSTATUS status = NT_STATUS(IVAL(cli->inbuf,smb_rcls)); - - return nt_errstr(status); - } - - cli_dos_error(cli, &errclass, &errnum); - - /* Case #3: SMB error */ - - return cli_smb_errstr(cli); + if (cli->fd == -1 && NT_STATUS_IS_OK(cli->raw_status)) { + return nt_errstr(NT_STATUS_CONNECTION_DISCONNECTED); + } + return nt_errstr(cli->raw_status); done: result = talloc_strdup(talloc_tos(), cli_error_message); SMB_ASSERT(result); @@ -82,20 +63,18 @@ const char *cli_errstr(struct cli_state *cli) NTSTATUS cli_nt_error(struct cli_state *cli) { - int flgs2 = SVAL(cli->inbuf,smb_flg2); - /* Deal with socket errors first. */ if (cli->fd == -1) { return NT_STATUS_CONNECTION_DISCONNECTED; } - if (!(flgs2 & FLAGS2_32_BIT_ERROR_CODES)) { - int e_class = CVAL(cli->inbuf,smb_rcls); - int code = SVAL(cli->inbuf,smb_err); + if (NT_STATUS_IS_DOS(cli->raw_status)) { + int e_class = NT_STATUS_DOS_CLASS(cli->raw_status); + int code = NT_STATUS_DOS_CODE(cli->raw_status); return dos_to_ntstatus(e_class, code); - } + } - return NT_STATUS(IVAL(cli->inbuf,smb_rcls)); + return cli->raw_status; } @@ -106,8 +85,6 @@ NTSTATUS cli_nt_error(struct cli_state *cli) void cli_dos_error(struct cli_state *cli, uint8 *eclass, uint32 *ecode) { - int flgs2; - if(!cli->initialised) { return; } @@ -118,16 +95,13 @@ void cli_dos_error(struct cli_state *cli, uint8 *eclass, uint32 *ecode) return; } - flgs2 = SVAL(cli->inbuf,smb_flg2); - - if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) { - NTSTATUS ntstatus = NT_STATUS(IVAL(cli->inbuf, smb_rcls)); - ntstatus_to_dos(ntstatus, eclass, ecode); - return; - } + if (!NT_STATUS_IS_DOS(cli->raw_status)) { + ntstatus_to_dos(cli->raw_status, eclass, ecode); + return; + } - *eclass = CVAL(cli->inbuf,smb_rcls); - *ecode = SVAL(cli->inbuf,smb_err); + *eclass = NT_STATUS_DOS_CLASS(cli->raw_status); + *ecode = NT_STATUS_DOS_CODE(cli->raw_status); } @@ -169,51 +143,42 @@ int cli_errno(struct cli_state *cli) bool cli_is_error(struct cli_state *cli) { - uint32 flgs2 = SVAL(cli->inbuf,smb_flg2), rcls = 0; - /* A socket error is always an error. */ if (cli->fd == -1) { return True; } - if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) { - /* Return error is error bits are set */ - rcls = IVAL(cli->inbuf, smb_rcls); - return (rcls & 0xF0000000) == 0xC0000000; - } - - /* Return error if error class in non-zero */ + if (NT_STATUS_IS_DOS(cli->raw_status)) { + /* Return error if error class in non-zero */ + uint8_t rcls = NT_STATUS_DOS_CLASS(cli->raw_status); + return rcls != 0; + } - rcls = CVAL(cli->inbuf, smb_rcls); - return rcls != 0; + return NT_STATUS_IS_ERR(cli->raw_status); } /* Return true if the last error was an NT error */ bool cli_is_nt_error(struct cli_state *cli) { - uint32 flgs2 = SVAL(cli->inbuf,smb_flg2); - /* A socket error is always an NT error. */ if (cli->fd == -1) { return True; } - return cli_is_error(cli) && (flgs2 & FLAGS2_32_BIT_ERROR_CODES); + return cli_is_error(cli) && !NT_STATUS_IS_DOS(cli->raw_status); } /* Return true if the last error was a DOS error */ bool cli_is_dos_error(struct cli_state *cli) { - uint32 flgs2 = SVAL(cli->inbuf,smb_flg2); - /* A socket error is always a DOS error. */ if (cli->fd == -1) { return True; } - return cli_is_error(cli) && !(flgs2 & FLAGS2_32_BIT_ERROR_CODES); + return cli_is_error(cli) && NT_STATUS_IS_DOS(cli->raw_status); } bool cli_state_is_connected(struct cli_state *cli) -- 2.11.4.GIT