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 6 : int cli_status_to_errno(NTSTATUS status) 70 : { 71 : int err; 72 : 73 6 : 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 6 : 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 6 : err = map_errno_from_nt_status(status); 89 : } 90 : 91 6 : DBG_NOTICE("0x%"PRIx32" -> %d\n", NT_STATUS_V(status), err); 92 : 93 6 : return err; 94 : } 95 : 96 : /* Return a UNIX errno appropriate for the error received in the last 97 : packet. */ 98 : 99 6 : int cli_errno(struct cli_state *cli) 100 : { 101 : bool connected; 102 : int err; 103 : 104 6 : connected = cli_state_is_connected(cli); 105 6 : if (!connected) { 106 0 : return EPIPE; 107 : } 108 : 109 6 : err = cli_status_to_errno(cli->raw_status); 110 6 : 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 24 : bool cli_state_is_connected(struct cli_state *cli) 156 : { 157 24 : if (cli == NULL) { 158 6 : return false; 159 : } 160 : 161 18 : if (!cli->initialised) { 162 0 : return false; 163 : } 164 : 165 18 : return smbXcli_conn_is_connected(cli->conn); 166 : }