Coverage Report

Created: 2026-04-01 06:26

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/samba/libcli/util/nterr.c
Line
Count
Source
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
        { "STATUS_NO_MORE_FILES", STATUS_NO_MORE_FILES },
49
        { "STATUS_INVALID_EA_NAME", STATUS_INVALID_EA_NAME },
50
        { "STATUS_BUFFER_OVERFLOW", STATUS_BUFFER_OVERFLOW },
51
        { "STATUS_MORE_ENTRIES", STATUS_MORE_ENTRIES },
52
        { "STATUS_SOME_UNMAPPED", STATUS_SOME_UNMAPPED },
53
        { "NT_STATUS_ERROR_DS_OBJ_STRING_NAME_EXISTS", NT_STATUS_ERROR_DS_OBJ_STRING_NAME_EXISTS },
54
        { "NT_STATUS_ERROR_DS_INCOMPATIBLE_VERSION", NT_STATUS_ERROR_DS_INCOMPATIBLE_VERSION },
55
        { "NT_STATUS_SMB_NO_PREAUTH_INTEGRITY_HASH_OVERLAP", NT_STATUS_SMB_NO_PREAUTH_INTEGRITY_HASH_OVERLAP },
56
  { "NT_STATUS_ABIOS_NOT_PRESENT", NT_STATUS_ABIOS_NOT_PRESENT },
57
  { "NT_STATUS_ABIOS_LID_NOT_EXIST", NT_STATUS_ABIOS_LID_NOT_EXIST },
58
  { "NT_STATUS_ABIOS_LID_ALREADY_OWNED", NT_STATUS_ABIOS_LID_ALREADY_OWNED },
59
  { "NT_STATUS_ABIOS_NOT_LID_OWNER", NT_STATUS_ABIOS_NOT_LID_OWNER },
60
  { "NT_STATUS_ABIOS_INVALID_COMMAND", NT_STATUS_ABIOS_INVALID_COMMAND },
61
  { "NT_STATUS_ABIOS_INVALID_LID", NT_STATUS_ABIOS_INVALID_LID },
62
  { "NT_STATUS_ABIOS_SELECTOR_NOT_AVAILABLE", NT_STATUS_ABIOS_SELECTOR_NOT_AVAILABLE },
63
  { "NT_STATUS_ABIOS_INVALID_SELECTOR", NT_STATUS_ABIOS_INVALID_SELECTOR },
64
  { "NT_STATUS_HANDLE_NOT_WAITABLE", NT_STATUS_HANDLE_NOT_WAITABLE },
65
  { "NT_STATUS_DEVICE_POWER_FAILURE", NT_STATUS_DEVICE_POWER_FAILURE },
66
  { "NT_STATUS_VHD_SHARED", NT_STATUS_VHD_SHARED },
67
  { "NT_STATUS_SMB_BAD_CLUSTER_DIALECT", NT_STATUS_SMB_BAD_CLUSTER_DIALECT },
68
  { "NT_STATUS_NO_SUCH_JOB", NT_STATUS_NO_SUCH_JOB },
69
70
  DOS_CODE(ERRDOS, ERRsuccess),
71
  DOS_CODE(ERRDOS, ERRbadfunc),
72
  DOS_CODE(ERRDOS, ERRbadfile),
73
  DOS_CODE(ERRDOS, ERRbadpath),
74
  DOS_CODE(ERRDOS, ERRnofids),
75
  DOS_CODE(ERRDOS, ERRnoaccess),
76
  DOS_CODE(ERRDOS, ERRbadfid),
77
  DOS_CODE(ERRDOS, ERRbadmcb),
78
  DOS_CODE(ERRDOS, ERRnomem),
79
  DOS_CODE(ERRDOS, ERRbadmem),
80
  DOS_CODE(ERRDOS, ERRbadenv),
81
  DOS_CODE(ERRDOS, ERRbadaccess),
82
  DOS_CODE(ERRDOS, ERRbaddata),
83
  DOS_CODE(ERRDOS, ERRres),
84
  DOS_CODE(ERRDOS, ERRbaddrive),
85
  DOS_CODE(ERRDOS, ERRremcd),
86
  DOS_CODE(ERRDOS, ERRdiffdevice),
87
  DOS_CODE(ERRDOS, ERRnofiles),
88
  DOS_CODE(ERRDOS, ERRgeneral),
89
  DOS_CODE(ERRDOS, ERRbadshare),
90
  DOS_CODE(ERRDOS, ERRlock),
91
  DOS_CODE(ERRDOS, ERRunsup),
92
  DOS_CODE(ERRDOS, ERRnetnamedel),
93
  DOS_CODE(ERRDOS, ERRnosuchshare),
94
  DOS_CODE(ERRDOS, ERRfilexists),
95
  DOS_CODE(ERRDOS, ERRinvalidparam),
96
  DOS_CODE(ERRDOS, ERRcannotopen),
97
  DOS_CODE(ERRDOS, ERRinsufficientbuffer),
98
  DOS_CODE(ERRDOS, ERRinvalidname),
99
  DOS_CODE(ERRDOS, ERRunknownlevel),
100
  DOS_CODE(ERRDOS, ERRnotlocked),
101
  DOS_CODE(ERRDOS, ERRinvalidpath),
102
  DOS_CODE(ERRDOS, ERRcancelviolation),
103
  DOS_CODE(ERRDOS, ERRnoatomiclocks),
104
  DOS_CODE(ERRDOS, ERRrename),
105
  DOS_CODE(ERRDOS, ERRbadpipe),
106
  DOS_CODE(ERRDOS, ERRpipebusy),
107
  DOS_CODE(ERRDOS, ERRpipeclosing),
108
  DOS_CODE(ERRDOS, ERRnotconnected),
109
  DOS_CODE(ERRDOS, ERRmoredata),
110
  DOS_CODE(ERRDOS, ERRnomoreitems),
111
  DOS_CODE(ERRDOS, ERRbaddirectory),
112
  DOS_CODE(ERRDOS, ERReasnotsupported),
113
  DOS_CODE(ERRDOS, ERRlogonfailure),
114
  DOS_CODE(ERRDOS, ERRbuftoosmall),
115
  DOS_CODE(ERRDOS, ERRunknownipc),
116
  DOS_CODE(ERRDOS, ERRnosuchprintjob),
117
  DOS_CODE(ERRDOS, ERRinvgroup),
118
  DOS_CODE(ERRDOS, ERRnoipc),
119
  DOS_CODE(ERRDOS, ERRdriveralreadyinstalled),
120
  DOS_CODE(ERRDOS, ERRunknownprinterport),
121
  DOS_CODE(ERRDOS, ERRunknownprinterdriver),
122
  DOS_CODE(ERRDOS, ERRunknownprintprocessor),
123
  DOS_CODE(ERRDOS, ERRinvalidseparatorfile),
124
  DOS_CODE(ERRDOS, ERRinvalidjobpriority),
125
  DOS_CODE(ERRDOS, ERRinvalidprintername),
126
  DOS_CODE(ERRDOS, ERRprinteralreadyexists),
127
  DOS_CODE(ERRDOS, ERRinvalidprintercommand),
128
  DOS_CODE(ERRDOS, ERRinvaliddatatype),
129
  DOS_CODE(ERRDOS, ERRinvalidenvironment),
130
  DOS_CODE(ERRDOS, ERRunknownprintmonitor),
131
  DOS_CODE(ERRDOS, ERRprinterdriverinuse),
132
  DOS_CODE(ERRDOS, ERRspoolfilenotfound),
133
  DOS_CODE(ERRDOS, ERRnostartdoc),
134
  DOS_CODE(ERRDOS, ERRnoaddjob),
135
  DOS_CODE(ERRDOS, ERRprintprocessoralreadyinstalled),
136
  DOS_CODE(ERRDOS, ERRprintmonitoralreadyinstalled),
137
  DOS_CODE(ERRDOS, ERRinvalidprintmonitor),
138
  DOS_CODE(ERRDOS, ERRprintmonitorinuse),
139
  DOS_CODE(ERRDOS, ERRprinterhasjobsqueued),
140
  DOS_CODE(ERRDOS, ERReainconsistent),
141
142
  DOS_CODE(ERRSRV, ERRerror),
143
  DOS_CODE(ERRSRV, ERRbadpw),
144
  DOS_CODE(ERRSRV, ERRbadtype),
145
  DOS_CODE(ERRSRV, ERRaccess),
146
  DOS_CODE(ERRSRV, ERRinvnid),
147
  DOS_CODE(ERRSRV, ERRinvnetname),
148
  DOS_CODE(ERRSRV, ERRinvdevice),
149
  DOS_CODE(ERRSRV, ERRqfull),
150
  DOS_CODE(ERRSRV, ERRqtoobig),
151
  DOS_CODE(ERRSRV, ERRinvpfid),
152
  DOS_CODE(ERRSRV, ERRsmbcmd),
153
  DOS_CODE(ERRSRV, ERRsrverror),
154
  DOS_CODE(ERRSRV, ERRfilespecs),
155
  DOS_CODE(ERRSRV, ERRbadlink),
156
  DOS_CODE(ERRSRV, ERRbadpermits),
157
  DOS_CODE(ERRSRV, ERRbadpid),
158
  DOS_CODE(ERRSRV, ERRsetattrmode),
159
  DOS_CODE(ERRSRV, ERRpaused),
160
  DOS_CODE(ERRSRV, ERRmsgoff),
161
  DOS_CODE(ERRSRV, ERRnoroom),
162
  DOS_CODE(ERRSRV, ERRrmuns),
163
  DOS_CODE(ERRSRV, ERRtimeout),
164
  DOS_CODE(ERRSRV, ERRnoresource),
165
  DOS_CODE(ERRSRV, ERRtoomanyuids),
166
  DOS_CODE(ERRSRV, ERRbaduid),
167
  DOS_CODE(ERRSRV, ERRuseMPX),
168
  DOS_CODE(ERRSRV, ERRuseSTD),
169
  DOS_CODE(ERRSRV, ERRcontMPX),
170
  DOS_CODE(ERRSRV, ERRnosupport),
171
  DOS_CODE(ERRSRV, ERRunknownsmb),
172
173
  DOS_CODE(ERRHRD, ERRnowrite),
174
  DOS_CODE(ERRHRD, ERRbadunit),
175
  DOS_CODE(ERRHRD, ERRnotready),
176
  DOS_CODE(ERRHRD, ERRbadcmd),
177
  DOS_CODE(ERRHRD, ERRdata),
178
  DOS_CODE(ERRHRD, ERRbadreq),
179
  DOS_CODE(ERRHRD, ERRseek),
180
  DOS_CODE(ERRHRD, ERRbadmedia),
181
  DOS_CODE(ERRHRD, ERRbadsector),
182
  DOS_CODE(ERRHRD, ERRnopaper),
183
  DOS_CODE(ERRHRD, ERRwrite),
184
  DOS_CODE(ERRHRD, ERRread),
185
  DOS_CODE(ERRHRD, ERRgeneral),
186
  DOS_CODE(ERRHRD, ERRwrongdisk),
187
  DOS_CODE(ERRHRD, ERRFCBunavail),
188
  DOS_CODE(ERRHRD, ERRsharebufexc),
189
  DOS_CODE(ERRHRD, ERRdiskfull),
190
191
  LDAP_CODE(LDAP_SUCCESS),
192
  LDAP_CODE(LDAP_OPERATIONS_ERROR),
193
  LDAP_CODE(LDAP_PROTOCOL_ERROR),
194
  LDAP_CODE(LDAP_TIME_LIMIT_EXCEEDED),
195
  LDAP_CODE(LDAP_SIZE_LIMIT_EXCEEDED),
196
  LDAP_CODE(LDAP_COMPARE_FALSE),
197
  LDAP_CODE(LDAP_COMPARE_TRUE),
198
  LDAP_CODE(LDAP_AUTH_METHOD_NOT_SUPPORTED),
199
  LDAP_CODE(LDAP_STRONG_AUTH_REQUIRED),
200
  LDAP_CODE(LDAP_REFERRAL),
201
  LDAP_CODE(LDAP_ADMIN_LIMIT_EXCEEDED),
202
  LDAP_CODE(LDAP_UNAVAILABLE_CRITICAL_EXTENSION),
203
  LDAP_CODE(LDAP_CONFIDENTIALITY_REQUIRED),
204
  LDAP_CODE(LDAP_SASL_BIND_IN_PROGRESS),
205
  LDAP_CODE(LDAP_NO_SUCH_ATTRIBUTE),
206
  LDAP_CODE(LDAP_UNDEFINED_ATTRIBUTE_TYPE),
207
  LDAP_CODE(LDAP_INAPPROPRIATE_MATCHING),
208
  LDAP_CODE(LDAP_CONSTRAINT_VIOLATION),
209
  LDAP_CODE(LDAP_ATTRIBUTE_OR_VALUE_EXISTS),
210
  LDAP_CODE(LDAP_INVALID_ATTRIBUTE_SYNTAX),
211
  LDAP_CODE(LDAP_NO_SUCH_OBJECT),
212
  LDAP_CODE(LDAP_ALIAS_PROBLEM),
213
  LDAP_CODE(LDAP_INVALID_DN_SYNTAX),
214
  LDAP_CODE(LDAP_ALIAS_DEREFERENCING_PROBLEM),
215
  LDAP_CODE(LDAP_INAPPROPRIATE_AUTHENTICATION),
216
  LDAP_CODE(LDAP_INVALID_CREDENTIALS),
217
  LDAP_CODE(LDAP_INSUFFICIENT_ACCESS_RIGHTS),
218
  LDAP_CODE(LDAP_BUSY),
219
  LDAP_CODE(LDAP_UNAVAILABLE),
220
  LDAP_CODE(LDAP_UNWILLING_TO_PERFORM),
221
  LDAP_CODE(LDAP_LOOP_DETECT),
222
  LDAP_CODE(LDAP_NAMING_VIOLATION),
223
  LDAP_CODE(LDAP_OBJECT_CLASS_VIOLATION),
224
  LDAP_CODE(LDAP_NOT_ALLOWED_ON_NON_LEAF),
225
  LDAP_CODE(LDAP_NOT_ALLOWED_ON_RDN),
226
  LDAP_CODE(LDAP_ENTRY_ALREADY_EXISTS),
227
  LDAP_CODE(LDAP_OBJECT_CLASS_MODS_PROHIBITED),
228
  LDAP_CODE(LDAP_AFFECTS_MULTIPLE_DSAS),
229
  LDAP_CODE(LDAP_OTHER),
230
231
  { NULL, NT_STATUS(0) }
232
};
233
234
/*****************************************************************************
235
 Returns an NT_STATUS constant as a string for inclusion in autogen C code.
236
 *****************************************************************************/
237
238
const char *get_nt_error_c_code(TALLOC_CTX *mem_ctx, NTSTATUS nt_code)
239
0
{
240
0
  char *result;
241
0
  int idx = 0;
242
243
0
  while (special_errs[idx].nt_errstr != NULL) {
244
0
    if (NT_STATUS_V(special_errs[idx].nt_errcode) ==
245
0
        NT_STATUS_V(nt_code)) {
246
0
      result = talloc_strdup(mem_ctx, special_errs[idx].nt_errstr);
247
0
      return result;
248
0
    }
249
0
    idx++;
250
0
  }
251
252
0
  idx = 0;
253
254
0
  while (nt_errs[idx].nt_errstr != NULL) {
255
0
    if (NT_STATUS_V(nt_errs[idx].nt_errcode) ==
256
0
        NT_STATUS_V(nt_code)) {
257
0
      result = talloc_strdup(mem_ctx, nt_errs[idx].nt_errstr);
258
0
      return result;
259
0
    }
260
0
    idx++;
261
0
  }
262
263
0
  result = talloc_asprintf(mem_ctx, "NT_STATUS(0x%08x)",
264
0
         NT_STATUS_V(nt_code));
265
0
  return result;
266
0
}
267
268
/*****************************************************************************
269
 Returns the NT_STATUS constant matching the string supplied (as an NTSTATUS)
270
 *****************************************************************************/
271
272
NTSTATUS nt_status_string_to_code(const char *nt_status_str)
273
0
{
274
0
  int idx = 0;
275
276
0
  while (special_errs[idx].nt_errstr != NULL) {
277
0
    if (strcasecmp(special_errs[idx].nt_errstr, nt_status_str) == 0) {
278
0
      return special_errs[idx].nt_errcode;
279
0
    }
280
0
    idx++;
281
0
  }
282
283
0
  idx = 0;
284
285
0
  while (nt_errs[idx].nt_errstr != NULL) {
286
0
    if (strcasecmp(nt_errs[idx].nt_errstr, nt_status_str) == 0) {
287
0
      return nt_errs[idx].nt_errcode;
288
0
    }
289
0
    idx++;
290
0
  }
291
292
0
  return NT_STATUS_UNSUCCESSFUL;
293
0
}
294
295
/**
296
 * Squash an NT_STATUS in line with security requirements.
297
 * In an attempt to avoid giving the whole game away when users
298
 * are authenticating, NT replaces both NT_STATUS_NO_SUCH_USER and
299
 * NT_STATUS_WRONG_PASSWORD with NT_STATUS_LOGON_FAILURE in certain situations
300
 * (session setups in particular).
301
 *
302
 * @param nt_status NTSTATUS input for squashing.
303
 * @return the 'squashed' nt_status
304
 **/
305
306
NTSTATUS nt_status_squash(NTSTATUS nt_status)
307
0
{
308
0
  if NT_STATUS_IS_OK(nt_status) {
309
0
    return nt_status;
310
0
  } else if NT_STATUS_EQUAL(nt_status, NT_STATUS_NO_SUCH_USER) {
311
    /* Match WinXP and don't give the game away */
312
0
    return NT_STATUS_LOGON_FAILURE;
313
314
0
  } else if NT_STATUS_EQUAL(nt_status, NT_STATUS_WRONG_PASSWORD) {
315
    /* Match WinXP and don't give the game away */
316
0
    return NT_STATUS_LOGON_FAILURE;
317
0
  } else {
318
0
    return nt_status;
319
0
  }
320
0
}
321
322
/*****************************************************************************
323
 Returns an NT error message.  not amazingly helpful, but better than a number.
324
 *****************************************************************************/
325
326
const char *nt_errstr(NTSTATUS nt_code)
327
289k
{
328
289k
  static char msg[20];
329
289k
  int idx = 0;
330
331
51.0M
  while (special_errs[idx].nt_errstr != NULL) {
332
50.7M
    if (NT_STATUS_V(special_errs[idx].nt_errcode) ==
333
50.7M
        NT_STATUS_V(nt_code)) {
334
4.53k
      return special_errs[idx].nt_errstr;
335
4.53k
    }
336
50.7M
    idx++;
337
50.7M
  }
338
339
285k
  idx = 0;
340
341
501M
  while (nt_errs[idx].nt_errstr != NULL) {
342
501M
    if (NT_STATUS_V(nt_errs[idx].nt_errcode) ==
343
501M
        NT_STATUS_V(nt_code)) {
344
5.94k
      return nt_errs[idx].nt_errstr;
345
5.94k
    }
346
501M
    idx++;
347
501M
  }
348
349
  /*
350
   * NTSTATUS codes have 0xC000 in the upper 16-bit, if the
351
   * upper 16-bit are not 0 and not 0xC000, it's likely
352
   * an HRESULT.
353
   *
354
   * E.g. we should display HRES_SEC_E_WRONG_PRINCIPAL instead of
355
   * 'NT code 0x80090322'
356
   */
357
279k
  if ((NT_STATUS_V(nt_code) & 0xFFFF0000) != 0 &&
358
275k
      (NT_STATUS_V(nt_code) & 0xFFFF0000) != 0xC0000000)
359
275k
  {
360
275k
    HRESULT hres = HRES_ERROR(NT_STATUS_V(nt_code));
361
275k
    return hresult_errstr(hres);
362
275k
  }
363
364
  /*
365
   * This should not really happen, we should have all error codes
366
   * available. We have a problem that this might get wrongly
367
   * overwritten by later calls in the same DEBUG statement.
368
   */
369
370
279k
  snprintf(msg, sizeof(msg), "NT code 0x%08x", NT_STATUS_V(nt_code));
371
3.61k
  return msg;
372
279k
}
373
374
/************************************************************************
375
 Print friendlier version of NT error code
376
 ***********************************************************************/
377
378
const char *get_friendly_nt_error_msg(NTSTATUS nt_code)
379
0
{
380
0
  int idx = 0;
381
382
0
  while (nt_err_desc[idx].nt_errstr != NULL) {
383
0
    if (NT_STATUS_V(nt_err_desc[idx].nt_errcode) == NT_STATUS_V(nt_code)) {
384
0
      return nt_err_desc[idx].nt_errstr;
385
0
    }
386
0
    idx++;
387
0
  }
388
389
  /* fall back to NT_STATUS_XXX string */
390
391
0
  return nt_errstr(nt_code);
392
0
}