summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/include/async_smb.h12
-rw-r--r--source3/include/client.h1
-rw-r--r--source3/libsmb/async_smb.c50
-rw-r--r--source3/libsmb/clientgen.c1
-rw-r--r--source3/libsmb/clierror.c81
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)