Line data Source code
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 0 : NTSTATUS cli_nt_error(struct cli_state *cli)
31 : {
32 : /* Deal with socket errors first. */
33 0 : if (!cli_state_is_connected(cli)) {
34 0 : return NT_STATUS_CONNECTION_DISCONNECTED;
35 : }
36 :
37 0 : if (NT_STATUS_IS_DOS(cli->raw_status)) {
38 0 : int e_class = NT_STATUS_DOS_CLASS(cli->raw_status);
39 0 : int code = NT_STATUS_DOS_CODE(cli->raw_status);
40 0 : return dos_to_ntstatus(e_class, code);
41 : }
42 :
43 0 : return cli->raw_status;
44 : }
45 :
46 :
47 : /****************************************************************************
48 : Return the DOS error from the last packet - an error class and an error
49 : code.
50 : ****************************************************************************/
51 :
52 0 : void cli_dos_error(struct cli_state *cli, uint8_t *eclass, uint32_t *ecode)
53 : {
54 0 : if (!cli_state_is_connected(cli)) {
55 0 : *eclass = ERRDOS;
56 0 : *ecode = ERRnotconnected;
57 0 : return;
58 : }
59 :
60 0 : if (!NT_STATUS_IS_DOS(cli->raw_status)) {
61 0 : ntstatus_to_dos(cli->raw_status, eclass, ecode);
62 0 : return;
63 : }
64 :
65 0 : *eclass = NT_STATUS_DOS_CLASS(cli->raw_status);
66 0 : *ecode = NT_STATUS_DOS_CODE(cli->raw_status);
67 : }
68 :
69 2 : int cli_status_to_errno(NTSTATUS status)
70 : {
71 : int err;
72 :
73 2 : if (NT_STATUS_IS_DOS(status)) {
74 0 : uint8_t eclass = NT_STATUS_DOS_CLASS(status);
75 0 : uint32_t ecode = NT_STATUS_DOS_CODE(status);
76 0 : status = dos_to_ntstatus(eclass, ecode);
77 : }
78 :
79 2 : if (NT_STATUS_EQUAL(status, NT_STATUS_STOPPED_ON_SYMLINK)) {
80 : /*
81 : * Legacy code from cli_errno, see Samba up to 4.13: A
82 : * special case for this Vista error. Since its
83 : * high-order byte isn't 0xc0, it won't match
84 : * correctly in map_errno_from_nt_status().
85 : */
86 0 : err = EACCES;
87 : } else {
88 2 : err = map_errno_from_nt_status(status);
89 : }
90 :
91 2 : DBG_NOTICE("0x%"PRIx32" -> %d\n", NT_STATUS_V(status), err);
92 :
93 2 : return err;
94 : }
95 :
96 : /* Return a UNIX errno appropriate for the error received in the last
97 : packet. */
98 :
99 2 : int cli_errno(struct cli_state *cli)
100 : {
101 : bool connected;
102 : int err;
103 :
104 2 : connected = cli_state_is_connected(cli);
105 2 : if (!connected) {
106 0 : return EPIPE;
107 : }
108 :
109 2 : err = cli_status_to_errno(cli->raw_status);
110 2 : return err;
111 : }
112 :
113 : /* Return true if the last packet was in error */
114 :
115 0 : bool cli_is_error(struct cli_state *cli)
116 : {
117 : /* A socket error is always an error. */
118 0 : if (!cli_state_is_connected(cli)) {
119 0 : return true;
120 : }
121 :
122 0 : if (NT_STATUS_IS_DOS(cli->raw_status)) {
123 : /* Return error if error class in non-zero */
124 0 : uint8_t rcls = NT_STATUS_DOS_CLASS(cli->raw_status);
125 0 : return rcls != 0;
126 : }
127 :
128 0 : return NT_STATUS_IS_ERR(cli->raw_status);
129 : }
130 :
131 : /* Return true if the last error was an NT error */
132 :
133 0 : bool cli_is_nt_error(struct cli_state *cli)
134 : {
135 : /* A socket error is always an NT error. */
136 0 : if (!cli_state_is_connected(cli)) {
137 0 : return true;
138 : }
139 :
140 0 : return cli_is_error(cli) && !NT_STATUS_IS_DOS(cli->raw_status);
141 : }
142 :
143 : /* Return true if the last error was a DOS error */
144 :
145 0 : bool cli_is_dos_error(struct cli_state *cli)
146 : {
147 : /* A socket error is always a DOS error. */
148 0 : if (!cli_state_is_connected(cli)) {
149 0 : return true;
150 : }
151 :
152 0 : return cli_is_error(cli) && NT_STATUS_IS_DOS(cli->raw_status);
153 : }
154 :
155 26 : bool cli_state_is_connected(struct cli_state *cli)
156 : {
157 26 : if (cli == NULL) {
158 12 : return false;
159 : }
160 :
161 14 : if (!cli->initialised) {
162 0 : return false;
163 : }
164 :
165 14 : return smbXcli_conn_is_connected(cli->conn);
166 : }
|