1 /*
2  *  Unix SMB/CIFS implementation.
3  *  RPC Pipe client / server routines
4  *
5  *  Copyright (C) Luke Kenneth Casson Leighton 1997-2001.
6  *  Copyright (C) Andrew Bartlett
7  *  Copyright (C) Andrew Tridgell
8  *
9  *  This program is free software; you can redistribute it and/or modify
10  *  it under the terms of the GNU General Public License as published by
11  *  the Free Software Foundation; either version 3 of the License, or
12  *  (at your option) any later version.
13  *
14  *  This program is distributed in the hope that it will be useful,
15  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  *  GNU General Public License for more details.
18  *
19  *  You should have received a copy of the GNU General Public License
20  *  along with this program; if not, see <http://www.gnu.org/licenses/>.
21  */
22 
23 /* NT error codes.  please read nterr.h */
24 
25 #include "includes.h"
26 #include "../libcli/ldap/ldap_errors.h"
27 #undef strcasecmp
28 
29 #if !defined(N_)
30 #define N_(string) string
31 #endif
32 
33 #define DOS_CODE(class, code) { #class ":" #code, NT_STATUS_DOS(class, code) }
34 #define LDAP_CODE(code) { #code, NT_STATUS_LDAP(code) }
35 
36 typedef struct
37 {
38 	const char *nt_errstr;
39 	NTSTATUS nt_errcode;
40 } nt_err_code_struct;
41 
42 #include "nterr_gen.c"
43 
44 /* Errors which aren't in the generated code because they're not in the
45  * same table as the other ones. */
46 static const nt_err_code_struct special_errs[] =
47 {
48         { "NT_STATUS_OK", NT_STATUS_OK },
49         { "STATUS_NO_MORE_FILES", STATUS_NO_MORE_FILES },
50         { "STATUS_STOPPED_ON_SYMLINK", STATUS_STOPPED_ON_SYMLINK },
51         { "STATUS_NO_MORE_EAS", STATUS_NO_MORE_EAS },
52         { "STATUS_INVALID_EA_NAME", STATUS_INVALID_EA_NAME },
53         { "STATUS_EA_LIST_INCONSISTENT", STATUS_EA_LIST_INCONSISTENT },
54         { "STATUS_INVALID_EA_FLAG", STATUS_INVALID_EA_FLAG },
55         { "STATUS_BUFFER_OVERFLOW", STATUS_BUFFER_OVERFLOW },
56         { "STATUS_MORE_ENTRIES", STATUS_MORE_ENTRIES },
57         { "STATUS_SOME_UNMAPPED", STATUS_SOME_UNMAPPED },
58         { "STATUS_NOTIFY_CLEANUP", STATUS_NOTIFY_CLEANUP },
59         { "STATUS_NOTIFY_ENUM_DIR", STATUS_NOTIFY_ENUM_DIR },
60         { "NT_STATUS_ERROR_DS_OBJ_STRING_NAME_EXISTS", NT_STATUS_ERROR_DS_OBJ_STRING_NAME_EXISTS },
61         { "NT_STATUS_ERROR_DS_INCOMPATIBLE_VERSION", NT_STATUS_ERROR_DS_INCOMPATIBLE_VERSION },
62         { "NT_STATUS_SMB_NO_PREAUTH_INTEGRITY_HASH_OVERLAP", NT_STATUS_SMB_NO_PREAUTH_INTEGRITY_HASH_OVERLAP },
63 	{ "NT_STATUS_INACCESSIBLE_SYSTEM_SHORTCUT", NT_STATUS_INACCESSIBLE_SYSTEM_SHORTCUT },
64 	{ "NT_STATUS_ABIOS_NOT_PRESENT", NT_STATUS_ABIOS_NOT_PRESENT },
65 	{ "NT_STATUS_ABIOS_LID_NOT_EXIST", NT_STATUS_ABIOS_LID_NOT_EXIST },
66 	{ "NT_STATUS_ABIOS_LID_ALREADY_OWNED", NT_STATUS_ABIOS_LID_ALREADY_OWNED },
67 	{ "NT_STATUS_ABIOS_NOT_LID_OWNER", NT_STATUS_ABIOS_NOT_LID_OWNER },
68 	{ "NT_STATUS_ABIOS_INVALID_COMMAND", NT_STATUS_ABIOS_INVALID_COMMAND },
69 	{ "NT_STATUS_ABIOS_INVALID_LID", NT_STATUS_ABIOS_INVALID_LID },
70 	{ "NT_STATUS_ABIOS_SELECTOR_NOT_AVAILABLE", NT_STATUS_ABIOS_SELECTOR_NOT_AVAILABLE },
71 	{ "NT_STATUS_ABIOS_INVALID_SELECTOR", NT_STATUS_ABIOS_INVALID_SELECTOR },
72 	{ "NT_STATUS_HANDLE_NOT_WAITABLE", NT_STATUS_HANDLE_NOT_WAITABLE },
73 	{ "NT_STATUS_DEVICE_POWER_FAILURE", NT_STATUS_DEVICE_POWER_FAILURE },
74 	{ "NT_STATUS_VHD_SHARED", NT_STATUS_VHD_SHARED },
75 	{ "NT_STATUS_SMB_BAD_CLUSTER_DIALECT", NT_STATUS_SMB_BAD_CLUSTER_DIALECT },
76 	{ "NT_STATUS_NO_SUCH_JOB", NT_STATUS_NO_SUCH_JOB },
77 
78 	DOS_CODE(ERRDOS, ERRsuccess),
79 	DOS_CODE(ERRDOS, ERRbadfunc),
80 	DOS_CODE(ERRDOS, ERRbadfile),
81 	DOS_CODE(ERRDOS, ERRbadpath),
82 	DOS_CODE(ERRDOS, ERRnofids),
83 	DOS_CODE(ERRDOS, ERRnoaccess),
84 	DOS_CODE(ERRDOS, ERRbadfid),
85 	DOS_CODE(ERRDOS, ERRbadmcb),
86 	DOS_CODE(ERRDOS, ERRnomem),
87 	DOS_CODE(ERRDOS, ERRbadmem),
88 	DOS_CODE(ERRDOS, ERRbadenv),
89 	DOS_CODE(ERRDOS, ERRbadaccess),
90 	DOS_CODE(ERRDOS, ERRbaddata),
91 	DOS_CODE(ERRDOS, ERRres),
92 	DOS_CODE(ERRDOS, ERRbaddrive),
93 	DOS_CODE(ERRDOS, ERRremcd),
94 	DOS_CODE(ERRDOS, ERRdiffdevice),
95 	DOS_CODE(ERRDOS, ERRnofiles),
96 	DOS_CODE(ERRDOS, ERRgeneral),
97 	DOS_CODE(ERRDOS, ERRbadshare),
98 	DOS_CODE(ERRDOS, ERRlock),
99 	DOS_CODE(ERRDOS, ERRunsup),
100 	DOS_CODE(ERRDOS, ERRnetnamedel),
101 	DOS_CODE(ERRDOS, ERRnosuchshare),
102 	DOS_CODE(ERRDOS, ERRfilexists),
103 	DOS_CODE(ERRDOS, ERRinvalidparam),
104 	DOS_CODE(ERRDOS, ERRcannotopen),
105 	DOS_CODE(ERRDOS, ERRinsufficientbuffer),
106 	DOS_CODE(ERRDOS, ERRinvalidname),
107 	DOS_CODE(ERRDOS, ERRunknownlevel),
108 	DOS_CODE(ERRDOS, ERRnotlocked),
109 	DOS_CODE(ERRDOS, ERRinvalidpath),
110 	DOS_CODE(ERRDOS, ERRcancelviolation),
111 	DOS_CODE(ERRDOS, ERRnoatomiclocks),
112 	DOS_CODE(ERRDOS, ERRrename),
113 	DOS_CODE(ERRDOS, ERRbadpipe),
114 	DOS_CODE(ERRDOS, ERRpipebusy),
115 	DOS_CODE(ERRDOS, ERRpipeclosing),
116 	DOS_CODE(ERRDOS, ERRnotconnected),
117 	DOS_CODE(ERRDOS, ERRmoredata),
118 	DOS_CODE(ERRDOS, ERRnomoreitems),
119 	DOS_CODE(ERRDOS, ERRbaddirectory),
120 	DOS_CODE(ERRDOS, ERReasnotsupported),
121 	DOS_CODE(ERRDOS, ERRlogonfailure),
122 	DOS_CODE(ERRDOS, ERRbuftoosmall),
123 	DOS_CODE(ERRDOS, ERRunknownipc),
124 	DOS_CODE(ERRDOS, ERRnosuchprintjob),
125 	DOS_CODE(ERRDOS, ERRinvgroup),
126 	DOS_CODE(ERRDOS, ERRnoipc),
127 	DOS_CODE(ERRDOS, ERRdriveralreadyinstalled),
128 	DOS_CODE(ERRDOS, ERRunknownprinterport),
129 	DOS_CODE(ERRDOS, ERRunknownprinterdriver),
130 	DOS_CODE(ERRDOS, ERRunknownprintprocessor),
131 	DOS_CODE(ERRDOS, ERRinvalidseparatorfile),
132 	DOS_CODE(ERRDOS, ERRinvalidjobpriority),
133 	DOS_CODE(ERRDOS, ERRinvalidprintername),
134 	DOS_CODE(ERRDOS, ERRprinteralreadyexists),
135 	DOS_CODE(ERRDOS, ERRinvalidprintercommand),
136 	DOS_CODE(ERRDOS, ERRinvaliddatatype),
137 	DOS_CODE(ERRDOS, ERRinvalidenvironment),
138 	DOS_CODE(ERRDOS, ERRunknownprintmonitor),
139 	DOS_CODE(ERRDOS, ERRprinterdriverinuse),
140 	DOS_CODE(ERRDOS, ERRspoolfilenotfound),
141 	DOS_CODE(ERRDOS, ERRnostartdoc),
142 	DOS_CODE(ERRDOS, ERRnoaddjob),
143 	DOS_CODE(ERRDOS, ERRprintprocessoralreadyinstalled),
144 	DOS_CODE(ERRDOS, ERRprintmonitoralreadyinstalled),
145 	DOS_CODE(ERRDOS, ERRinvalidprintmonitor),
146 	DOS_CODE(ERRDOS, ERRprintmonitorinuse),
147 	DOS_CODE(ERRDOS, ERRprinterhasjobsqueued),
148 	DOS_CODE(ERRDOS, ERReainconsistent),
149 
150 	DOS_CODE(ERRSRV, ERRerror),
151 	DOS_CODE(ERRSRV, ERRbadpw),
152 	DOS_CODE(ERRSRV, ERRbadtype),
153 	DOS_CODE(ERRSRV, ERRaccess),
154 	DOS_CODE(ERRSRV, ERRinvnid),
155 	DOS_CODE(ERRSRV, ERRinvnetname),
156 	DOS_CODE(ERRSRV, ERRinvdevice),
157 	DOS_CODE(ERRSRV, ERRqfull),
158 	DOS_CODE(ERRSRV, ERRqtoobig),
159 	DOS_CODE(ERRSRV, ERRinvpfid),
160 	DOS_CODE(ERRSRV, ERRsmbcmd),
161 	DOS_CODE(ERRSRV, ERRsrverror),
162 	DOS_CODE(ERRSRV, ERRfilespecs),
163 	DOS_CODE(ERRSRV, ERRbadlink),
164 	DOS_CODE(ERRSRV, ERRbadpermits),
165 	DOS_CODE(ERRSRV, ERRbadpid),
166 	DOS_CODE(ERRSRV, ERRsetattrmode),
167 	DOS_CODE(ERRSRV, ERRpaused),
168 	DOS_CODE(ERRSRV, ERRmsgoff),
169 	DOS_CODE(ERRSRV, ERRnoroom),
170 	DOS_CODE(ERRSRV, ERRrmuns),
171 	DOS_CODE(ERRSRV, ERRtimeout),
172 	DOS_CODE(ERRSRV, ERRnoresource),
173 	DOS_CODE(ERRSRV, ERRtoomanyuids),
174 	DOS_CODE(ERRSRV, ERRbaduid),
175 	DOS_CODE(ERRSRV, ERRuseMPX),
176 	DOS_CODE(ERRSRV, ERRuseSTD),
177 	DOS_CODE(ERRSRV, ERRcontMPX),
178 	DOS_CODE(ERRSRV, ERRnosupport),
179 	DOS_CODE(ERRSRV, ERRunknownsmb),
180 
181 	DOS_CODE(ERRHRD, ERRnowrite),
182 	DOS_CODE(ERRHRD, ERRbadunit),
183 	DOS_CODE(ERRHRD, ERRnotready),
184 	DOS_CODE(ERRHRD, ERRbadcmd),
185 	DOS_CODE(ERRHRD, ERRdata),
186 	DOS_CODE(ERRHRD, ERRbadreq),
187 	DOS_CODE(ERRHRD, ERRseek),
188 	DOS_CODE(ERRHRD, ERRbadmedia),
189 	DOS_CODE(ERRHRD, ERRbadsector),
190 	DOS_CODE(ERRHRD, ERRnopaper),
191 	DOS_CODE(ERRHRD, ERRwrite),
192 	DOS_CODE(ERRHRD, ERRread),
193 	DOS_CODE(ERRHRD, ERRgeneral),
194 	DOS_CODE(ERRHRD, ERRwrongdisk),
195 	DOS_CODE(ERRHRD, ERRFCBunavail),
196 	DOS_CODE(ERRHRD, ERRsharebufexc),
197 	DOS_CODE(ERRHRD, ERRdiskfull),
198 
199 	LDAP_CODE(LDAP_SUCCESS),
200 	LDAP_CODE(LDAP_OPERATIONS_ERROR),
201 	LDAP_CODE(LDAP_PROTOCOL_ERROR),
202 	LDAP_CODE(LDAP_TIME_LIMIT_EXCEEDED),
203 	LDAP_CODE(LDAP_SIZE_LIMIT_EXCEEDED),
204 	LDAP_CODE(LDAP_COMPARE_FALSE),
205 	LDAP_CODE(LDAP_COMPARE_TRUE),
206 	LDAP_CODE(LDAP_AUTH_METHOD_NOT_SUPPORTED),
207 	LDAP_CODE(LDAP_STRONG_AUTH_REQUIRED),
208 	LDAP_CODE(LDAP_REFERRAL),
209 	LDAP_CODE(LDAP_ADMIN_LIMIT_EXCEEDED),
210 	LDAP_CODE(LDAP_UNAVAILABLE_CRITICAL_EXTENSION),
211 	LDAP_CODE(LDAP_CONFIDENTIALITY_REQUIRED),
212 	LDAP_CODE(LDAP_SASL_BIND_IN_PROGRESS),
213 	LDAP_CODE(LDAP_NO_SUCH_ATTRIBUTE),
214 	LDAP_CODE(LDAP_UNDEFINED_ATTRIBUTE_TYPE),
215 	LDAP_CODE(LDAP_INAPPROPRIATE_MATCHING),
216 	LDAP_CODE(LDAP_CONSTRAINT_VIOLATION),
217 	LDAP_CODE(LDAP_ATTRIBUTE_OR_VALUE_EXISTS),
218 	LDAP_CODE(LDAP_INVALID_ATTRIBUTE_SYNTAX),
219 	LDAP_CODE(LDAP_NO_SUCH_OBJECT),
220 	LDAP_CODE(LDAP_ALIAS_PROBLEM),
221 	LDAP_CODE(LDAP_INVALID_DN_SYNTAX),
222 	LDAP_CODE(LDAP_ALIAS_DEREFERENCING_PROBLEM),
223 	LDAP_CODE(LDAP_INAPPROPRIATE_AUTHENTICATION),
224 	LDAP_CODE(LDAP_INVALID_CREDENTIALS),
225 	LDAP_CODE(LDAP_INSUFFICIENT_ACCESS_RIGHTS),
226 	LDAP_CODE(LDAP_BUSY),
227 	LDAP_CODE(LDAP_UNAVAILABLE),
228 	LDAP_CODE(LDAP_UNWILLING_TO_PERFORM),
229 	LDAP_CODE(LDAP_LOOP_DETECT),
230 	LDAP_CODE(LDAP_NAMING_VIOLATION),
231 	LDAP_CODE(LDAP_OBJECT_CLASS_VIOLATION),
232 	LDAP_CODE(LDAP_NOT_ALLOWED_ON_NON_LEAF),
233 	LDAP_CODE(LDAP_NOT_ALLOWED_ON_RDN),
234 	LDAP_CODE(LDAP_ENTRY_ALREADY_EXISTS),
235 	LDAP_CODE(LDAP_OBJECT_CLASS_MODS_PROHIBITED),
236 	LDAP_CODE(LDAP_AFFECTS_MULTIPLE_DSAS),
237 	LDAP_CODE(LDAP_OTHER),
238 
239 	{ NULL, NT_STATUS(0) }
240 };
241 
242 /*****************************************************************************
243  Returns an NT_STATUS constant as a string for inclusion in autogen C code.
244  *****************************************************************************/
245 
get_nt_error_c_code(TALLOC_CTX * mem_ctx,NTSTATUS nt_code)246 const char *get_nt_error_c_code(TALLOC_CTX *mem_ctx, NTSTATUS nt_code)
247 {
248 	char *result;
249 	int idx = 0;
250 
251 	while (special_errs[idx].nt_errstr != NULL) {
252 		if (NT_STATUS_V(special_errs[idx].nt_errcode) ==
253 		    NT_STATUS_V(nt_code)) {
254 			result = talloc_strdup(mem_ctx, special_errs[idx].nt_errstr);
255 			return result;
256 		}
257 		idx++;
258 	}
259 
260 	idx = 0;
261 
262 	while (nt_errs[idx].nt_errstr != NULL) {
263 		if (NT_STATUS_V(nt_errs[idx].nt_errcode) ==
264 		    NT_STATUS_V(nt_code)) {
265 			result = talloc_strdup(mem_ctx, nt_errs[idx].nt_errstr);
266 			return result;
267 		}
268 		idx++;
269 	}
270 
271 	result = talloc_asprintf(mem_ctx, "NT_STATUS(0x%08x)",
272 				 NT_STATUS_V(nt_code));
273 	return result;
274 }
275 
276 /*****************************************************************************
277  Returns the NT_STATUS constant matching the string supplied (as an NTSTATUS)
278  *****************************************************************************/
279 
nt_status_string_to_code(const char * nt_status_str)280 NTSTATUS nt_status_string_to_code(const char *nt_status_str)
281 {
282 	int idx = 0;
283 
284 	while (special_errs[idx].nt_errstr != NULL) {
285 		if (strcasecmp(special_errs[idx].nt_errstr, nt_status_str) == 0) {
286 			return special_errs[idx].nt_errcode;
287 		}
288 		idx++;
289 	}
290 
291 	idx = 0;
292 
293 	while (nt_errs[idx].nt_errstr != NULL) {
294 		if (strcasecmp(nt_errs[idx].nt_errstr, nt_status_str) == 0) {
295 			return nt_errs[idx].nt_errcode;
296 		}
297 		idx++;
298 	}
299 
300 	return NT_STATUS_UNSUCCESSFUL;
301 }
302 
303 /**
304  * Squash an NT_STATUS in line with security requirements.
305  * In an attempt to avoid giving the whole game away when users
306  * are authenticating, NT replaces both NT_STATUS_NO_SUCH_USER and
307  * NT_STATUS_WRONG_PASSWORD with NT_STATUS_LOGON_FAILURE in certain situations
308  * (session setups in particular).
309  *
310  * @param nt_status NTSTATUS input for squashing.
311  * @return the 'squashed' nt_status
312  **/
313 
nt_status_squash(NTSTATUS nt_status)314 NTSTATUS nt_status_squash(NTSTATUS nt_status)
315 {
316 	if NT_STATUS_IS_OK(nt_status) {
317 		return nt_status;
318 	} else if NT_STATUS_EQUAL(nt_status, NT_STATUS_NO_SUCH_USER) {
319 		/* Match WinXP and don't give the game away */
320 		return NT_STATUS_LOGON_FAILURE;
321 
322 	} else if NT_STATUS_EQUAL(nt_status, NT_STATUS_WRONG_PASSWORD) {
323 		/* Match WinXP and don't give the game away */
324 		return NT_STATUS_LOGON_FAILURE;
325 	} else {
326 		return nt_status;
327 	}
328 }
329 
330 /*****************************************************************************
331  Returns an NT error message.  not amazingly helpful, but better than a number.
332  *****************************************************************************/
333 
nt_errstr(NTSTATUS nt_code)334 const char *nt_errstr(NTSTATUS nt_code)
335 {
336 	static char msg[20];
337 	int idx = 0;
338 
339 	while (special_errs[idx].nt_errstr != NULL) {
340 		if (NT_STATUS_V(special_errs[idx].nt_errcode) ==
341 		    NT_STATUS_V(nt_code)) {
342 			return special_errs[idx].nt_errstr;
343 		}
344 		idx++;
345 	}
346 
347 	idx = 0;
348 
349 	while (nt_errs[idx].nt_errstr != NULL) {
350 		if (NT_STATUS_V(nt_errs[idx].nt_errcode) ==
351 		    NT_STATUS_V(nt_code)) {
352 			return nt_errs[idx].nt_errstr;
353 		}
354 		idx++;
355 	}
356 
357 	/*
358 	 * This should not really happen, we should have all error codes
359 	 * available. We have a problem that this might get wrongly
360 	 * overwritten by later calls in the same DEBUG statement.
361 	 */
362 
363 	snprintf(msg, sizeof(msg), "NT code 0x%08x", NT_STATUS_V(nt_code));
364 	return msg;
365 }
366 
367 /************************************************************************
368  Print friendler version fo NT error code
369  ***********************************************************************/
370 
get_friendly_nt_error_msg(NTSTATUS nt_code)371 const char *get_friendly_nt_error_msg(NTSTATUS nt_code)
372 {
373 	int idx = 0;
374 
375 	while (nt_err_desc[idx].nt_errstr != NULL) {
376 		if (NT_STATUS_V(nt_err_desc[idx].nt_errcode) == NT_STATUS_V(nt_code)) {
377 			return nt_err_desc[idx].nt_errstr;
378 		}
379 		idx++;
380 	}
381 
382 	/* fall back to NT_STATUS_XXX string */
383 
384 	return nt_errstr(nt_code);
385 }
386