s3:libsmb: don't use the cli->inbuf to store the last error
authorStefan Metzmacher <metze@samba.org>
Fri, 8 Jul 2011 08:52:22 +0000 (10:52 +0200)
committerStefan Metzmacher <metze@samba.org>
Fri, 8 Jul 2011 12:09:09 +0000 (14:09 +0200)
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
source3/include/client.h
source3/libsmb/async_smb.c
source3/libsmb/clientgen.c
source3/libsmb/clierror.c

index 1685d4985d44f119a98dc7c8883b73d4b06d68ae..40da862be22eb9a2ce5a0a6855640fc0a8084bf1 100644 (file)
 
 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,
index fc591828ae9b300a95d2e57ea014e753d0adcc29..bd6de4afb9c3e1bcbe8b853ed0995272f1b66e45 100644 (file)
@@ -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;
index ee15caee7a555c4da5525a021d78d2d0a999fe95..e932ddb10141f4c0a77d55320771fec00a70fcde 100644 (file)
 #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)) {
 
index 676e48205e0359b3fe78e00a58a19ddc720b1485..e874a8983ca615423ad8333f398e68157ff87fbc 100644 (file)
@@ -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;
index 4b6f0448816ebd42a174b980af233fa3925d60ba..7541a690107e2330a9dfb516c0d4bdbec6d85200 100644 (file)
 #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)