libsmb: Factor out cli_status_to_errno() from cli_errno()
authorVolker Lendecke <vl@samba.org>
Tue, 15 Dec 2020 16:05:34 +0000 (17:05 +0100)
committerJeremy Allison <jra@samba.org>
Tue, 15 Jun 2021 18:11:35 +0000 (18:11 +0000)
cli_errno() calls far too many trivial but subtle functions, all
referencing cli->raw_status. This might be the first step towards
getting rid of that.

Signed-off-by: Volker Lendecke <vl@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
source3/libsmb/clierror.c
source3/libsmb/proto.h

index b92b31601740a997a5cbac634fcd248fd7ad9b96..cb75878bba3c05864096a066933bc800205e9cc7 100644 (file)
@@ -66,39 +66,48 @@ void cli_dos_error(struct cli_state *cli, uint8_t *eclass, uint32_t *ecode)
        *ecode = NT_STATUS_DOS_CODE(cli->raw_status);
 }
 
+int cli_status_to_errno(NTSTATUS status)
+{
+       int err;
+
+       if (NT_STATUS_IS_DOS(status)) {
+                uint8_t eclass = NT_STATUS_DOS_CLASS(status);
+                uint32_t ecode = NT_STATUS_DOS_CODE(status);
+               status = dos_to_ntstatus(eclass, ecode);
+       }
+
+       if (NT_STATUS_EQUAL(status, NT_STATUS_INACCESSIBLE_SYSTEM_SHORTCUT)) {
+               /*
+                * Legacy code from cli_errno, see Samba up to 4.13: A
+                * special case for this Vista error. Since its
+                * high-order byte isn't 0xc0, it won't match
+                * correctly in map_errno_from_nt_status().
+                */
+               err = EACCES;
+       } else {
+               err = map_errno_from_nt_status(status);
+       }
+
+       DBG_NOTICE("0x%"PRIx32" -> %d\n", NT_STATUS_V(status), err);
+
+       return err;
+}
 
 /* Return a UNIX errno appropriate for the error received in the last
    packet. */
 
 int cli_errno(struct cli_state *cli)
 {
-       NTSTATUS status;
+       bool connected;
+       int err;
 
-       if (cli_is_nt_error(cli)) {
-               status = cli_nt_error(cli);
-               return map_errno_from_nt_status(status);
+       connected = cli_state_is_connected(cli);
+       if (!connected) {
+               return EPIPE;
        }
 
-        if (cli_is_dos_error(cli)) {
-                uint8_t eclass;
-                uint32_t ecode;
-
-                cli_dos_error(cli, &eclass, &ecode);
-               status = dos_to_ntstatus(eclass, ecode);
-               return map_errno_from_nt_status(status);
-        }
-
-        /*
-         * Yuck!  A special case for this Vista error.  Since its high-order
-         * byte isn't 0xc0, it doesn't match cli_is_nt_error() above.
-         */
-        status = cli_nt_error(cli);
-        if (NT_STATUS_V(status) == NT_STATUS_V(NT_STATUS_INACCESSIBLE_SYSTEM_SHORTCUT)) {
-            return EACCES;
-        }
-
-       /* for other cases */
-       return EINVAL;
+       err = cli_status_to_errno(cli->raw_status);
+       return err;
 }
 
 /* Return true if the last packet was in error */
index e560e6697b83343d65b59cea4b915fb8b4795ba7..bd67e56b60f3328d0841f7c779e8b0264fff23bf 100644 (file)
@@ -203,6 +203,7 @@ NTSTATUS cli_smb(TALLOC_CTX *mem_ctx, struct cli_state *cli,
 
 NTSTATUS cli_nt_error(struct cli_state *cli);
 void cli_dos_error(struct cli_state *cli, uint8_t *eclass, uint32_t *ecode);
+int cli_status_to_errno(NTSTATUS status);
 int cli_errno(struct cli_state *cli);
 bool cli_is_error(struct cli_state *cli);
 bool cli_is_nt_error(struct cli_state *cli);