0a5df8b9ae35ecac825742593d07e2927f923c38
[samba.git] / source3 / libsmb / clierror.c
1 /* 
2    Unix SMB/CIFS implementation.
3    client error handling routines
4    Copyright (C) Andrew Tridgell 1994-1998
5    Copyright (C) Jelmer Vernooij 2003
6    Copyright (C) Jeremy Allison 2006
7
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 3 of the License, or
11    (at your option) any later version.
12
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with this program.  If not, see <http://www.gnu.org/licenses/>.
20 */
21
22 #include "includes.h"
23 #include "libsmb/libsmb.h"
24 #include "../libcli/smb/smbXcli_base.h"
25
26 /****************************************************************************
27  Return the 32-bit NT status code from the last packet.
28 ****************************************************************************/
29
30 NTSTATUS cli_nt_error(struct cli_state *cli)
31 {
32         /* Deal with socket errors first. */
33         if (!cli_state_is_connected(cli)) {
34                 return NT_STATUS_CONNECTION_DISCONNECTED;
35         }
36
37         if (NT_STATUS_IS_DOS(cli->raw_status)) {
38                 int e_class = NT_STATUS_DOS_CLASS(cli->raw_status);
39                 int code = NT_STATUS_DOS_CODE(cli->raw_status);
40                 return dos_to_ntstatus(e_class, code);
41         }
42
43         return cli->raw_status;
44 }
45
46 int cli_status_to_errno(NTSTATUS status)
47 {
48         int err;
49
50         if (NT_STATUS_IS_DOS(status)) {
51                 uint8_t eclass = NT_STATUS_DOS_CLASS(status);
52                 uint32_t ecode = NT_STATUS_DOS_CODE(status);
53                 status = dos_to_ntstatus(eclass, ecode);
54         }
55
56         if (NT_STATUS_EQUAL(status, NT_STATUS_STOPPED_ON_SYMLINK)) {
57                 /*
58                  * Legacy code from cli_errno, see Samba up to 4.13: A
59                  * special case for this Vista error. Since its
60                  * high-order byte isn't 0xc0, it won't match
61                  * correctly in map_errno_from_nt_status().
62                  */
63                 err = EACCES;
64         } else {
65                 err = map_errno_from_nt_status(status);
66         }
67
68         DBG_NOTICE("0x%"PRIx32" -> %d\n", NT_STATUS_V(status), err);
69
70         return err;
71 }
72
73 /* Return a UNIX errno appropriate for the error received in the last
74    packet. */
75
76 int cli_errno(struct cli_state *cli)
77 {
78         bool connected;
79         int err;
80
81         connected = cli_state_is_connected(cli);
82         if (!connected) {
83                 return EPIPE;
84         }
85
86         err = cli_status_to_errno(cli->raw_status);
87         return err;
88 }
89
90 /* Return true if the last packet was in error */
91
92 bool cli_is_error(struct cli_state *cli)
93 {
94         /* A socket error is always an error. */
95         if (!cli_state_is_connected(cli)) {
96                 return true;
97         }
98
99         if (NT_STATUS_IS_DOS(cli->raw_status)) {
100                 /* Return error if error class in non-zero */
101                 uint8_t rcls = NT_STATUS_DOS_CLASS(cli->raw_status);
102                 return rcls != 0;
103         }
104
105         return NT_STATUS_IS_ERR(cli->raw_status);
106 }
107
108 bool cli_state_is_connected(struct cli_state *cli)
109 {
110         if (cli == NULL) {
111                 return false;
112         }
113
114         if (!cli->initialised) {
115                 return false;
116         }
117
118         return smbXcli_conn_is_connected(cli->conn);
119 }