Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/crypto/heimdal/lib/krb5/error_string.c
34878 views
1
/*
2
* Copyright (c) 2001, 2003, 2005 - 2006 Kungliga Tekniska Högskolan
3
* (Royal Institute of Technology, Stockholm, Sweden).
4
* All rights reserved.
5
*
6
* Redistribution and use in source and binary forms, with or without
7
* modification, are permitted provided that the following conditions
8
* are met:
9
*
10
* 1. Redistributions of source code must retain the above copyright
11
* notice, this list of conditions and the following disclaimer.
12
*
13
* 2. Redistributions in binary form must reproduce the above copyright
14
* notice, this list of conditions and the following disclaimer in the
15
* documentation and/or other materials provided with the distribution.
16
*
17
* 3. Neither the name of the Institute nor the names of its contributors
18
* may be used to endorse or promote products derived from this software
19
* without specific prior written permission.
20
*
21
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
22
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
25
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31
* SUCH DAMAGE.
32
*/
33
34
#include "krb5_locl.h"
35
36
#undef __attribute__
37
#define __attribute__(x)
38
39
/**
40
* Clears the error message from the Kerberos 5 context.
41
*
42
* @param context The Kerberos 5 context to clear
43
*
44
* @ingroup krb5_error
45
*/
46
47
KRB5_LIB_FUNCTION void KRB5_LIB_CALL
48
krb5_clear_error_message(krb5_context context)
49
{
50
HEIMDAL_MUTEX_lock(context->mutex);
51
if (context->error_string)
52
free(context->error_string);
53
context->error_code = 0;
54
context->error_string = NULL;
55
HEIMDAL_MUTEX_unlock(context->mutex);
56
}
57
58
/**
59
* Set the context full error string for a specific error code.
60
* The error that is stored should be internationalized.
61
*
62
* The if context is NULL, no error string is stored.
63
*
64
* @param context Kerberos 5 context
65
* @param ret The error code
66
* @param fmt Error string for the error code
67
* @param ... printf(3) style parameters.
68
*
69
* @ingroup krb5_error
70
*/
71
72
KRB5_LIB_FUNCTION void KRB5_LIB_CALL
73
krb5_set_error_message(krb5_context context, krb5_error_code ret,
74
const char *fmt, ...)
75
__attribute__ ((format (printf, 3, 4)))
76
{
77
va_list ap;
78
79
va_start(ap, fmt);
80
krb5_vset_error_message (context, ret, fmt, ap);
81
va_end(ap);
82
}
83
84
/**
85
* Set the context full error string for a specific error code.
86
*
87
* The if context is NULL, no error string is stored.
88
*
89
* @param context Kerberos 5 context
90
* @param ret The error code
91
* @param fmt Error string for the error code
92
* @param args printf(3) style parameters.
93
*
94
* @ingroup krb5_error
95
*/
96
97
98
KRB5_LIB_FUNCTION void KRB5_LIB_CALL
99
krb5_vset_error_message (krb5_context context, krb5_error_code ret,
100
const char *fmt, va_list args)
101
__attribute__ ((format (printf, 3, 0)))
102
{
103
int r;
104
105
if (context == NULL)
106
return;
107
108
HEIMDAL_MUTEX_lock(context->mutex);
109
if (context->error_string) {
110
free(context->error_string);
111
context->error_string = NULL;
112
}
113
context->error_code = ret;
114
r = vasprintf(&context->error_string, fmt, args);
115
if (r < 0)
116
context->error_string = NULL;
117
HEIMDAL_MUTEX_unlock(context->mutex);
118
}
119
120
/**
121
* Prepend the context full error string for a specific error code.
122
* The error that is stored should be internationalized.
123
*
124
* The if context is NULL, no error string is stored.
125
*
126
* @param context Kerberos 5 context
127
* @param ret The error code
128
* @param fmt Error string for the error code
129
* @param ... printf(3) style parameters.
130
*
131
* @ingroup krb5_error
132
*/
133
134
KRB5_LIB_FUNCTION void KRB5_LIB_CALL
135
krb5_prepend_error_message(krb5_context context, krb5_error_code ret,
136
const char *fmt, ...)
137
__attribute__ ((format (printf, 3, 4)))
138
{
139
va_list ap;
140
141
va_start(ap, fmt);
142
krb5_vprepend_error_message(context, ret, fmt, ap);
143
va_end(ap);
144
}
145
146
/**
147
* Prepend the contexts's full error string for a specific error code.
148
*
149
* The if context is NULL, no error string is stored.
150
*
151
* @param context Kerberos 5 context
152
* @param ret The error code
153
* @param fmt Error string for the error code
154
* @param args printf(3) style parameters.
155
*
156
* @ingroup krb5_error
157
*/
158
159
KRB5_LIB_FUNCTION void KRB5_LIB_CALL
160
krb5_vprepend_error_message(krb5_context context, krb5_error_code ret,
161
const char *fmt, va_list args)
162
__attribute__ ((format (printf, 3, 0)))
163
{
164
char *str = NULL, *str2 = NULL;
165
166
if (context == NULL)
167
return;
168
169
HEIMDAL_MUTEX_lock(context->mutex);
170
if (context->error_code != ret) {
171
HEIMDAL_MUTEX_unlock(context->mutex);
172
return;
173
}
174
if (vasprintf(&str, fmt, args) < 0 || str == NULL) {
175
HEIMDAL_MUTEX_unlock(context->mutex);
176
return;
177
}
178
if (context->error_string) {
179
int e;
180
181
e = asprintf(&str2, "%s: %s", str, context->error_string);
182
free(context->error_string);
183
if (e < 0 || str2 == NULL)
184
context->error_string = NULL;
185
else
186
context->error_string = str2;
187
free(str);
188
} else
189
context->error_string = str;
190
HEIMDAL_MUTEX_unlock(context->mutex);
191
}
192
193
194
/**
195
* Return the error message in context. On error or no error string,
196
* the function returns NULL.
197
*
198
* @param context Kerberos 5 context
199
*
200
* @return an error string, needs to be freed with
201
* krb5_free_error_message(). The functions return NULL on error.
202
*
203
* @ingroup krb5_error
204
*/
205
206
KRB5_LIB_FUNCTION char * KRB5_LIB_CALL
207
krb5_get_error_string(krb5_context context)
208
{
209
char *ret = NULL;
210
211
HEIMDAL_MUTEX_lock(context->mutex);
212
if (context->error_string)
213
ret = strdup(context->error_string);
214
HEIMDAL_MUTEX_unlock(context->mutex);
215
return ret;
216
}
217
218
KRB5_LIB_FUNCTION krb5_boolean KRB5_LIB_CALL
219
krb5_have_error_string(krb5_context context)
220
{
221
char *str;
222
HEIMDAL_MUTEX_lock(context->mutex);
223
str = context->error_string;
224
HEIMDAL_MUTEX_unlock(context->mutex);
225
return str != NULL;
226
}
227
228
/**
229
* Return the error message for `code' in context. On memory
230
* allocation error the function returns NULL.
231
*
232
* @param context Kerberos 5 context
233
* @param code Error code related to the error
234
*
235
* @return an error string, needs to be freed with
236
* krb5_free_error_message(). The functions return NULL on error.
237
*
238
* @ingroup krb5_error
239
*/
240
241
KRB5_LIB_FUNCTION const char * KRB5_LIB_CALL
242
krb5_get_error_message(krb5_context context, krb5_error_code code)
243
{
244
char *str = NULL;
245
const char *cstr = NULL;
246
char buf[128];
247
int free_context = 0;
248
249
if (code == 0)
250
return strdup("Success");
251
252
/*
253
* The MIT version of this function ignores the krb5_context
254
* and several widely deployed applications call krb5_get_error_message()
255
* with a NULL context in order to translate an error code as a
256
* replacement for error_message(). Another reason a NULL context
257
* might be provided is if the krb5_init_context() call itself
258
* failed.
259
*/
260
if (context)
261
{
262
HEIMDAL_MUTEX_lock(context->mutex);
263
if (context->error_string &&
264
(code == context->error_code || context->error_code == 0))
265
{
266
str = strdup(context->error_string);
267
}
268
HEIMDAL_MUTEX_unlock(context->mutex);
269
270
if (str)
271
return str;
272
}
273
else
274
{
275
if (krb5_init_context(&context) == 0)
276
free_context = 1;
277
}
278
279
if (context)
280
cstr = com_right_r(context->et_list, code, buf, sizeof(buf));
281
282
if (free_context)
283
krb5_free_context(context);
284
285
if (cstr)
286
return strdup(cstr);
287
288
cstr = error_message(code);
289
if (cstr)
290
return strdup(cstr);
291
292
if (asprintf(&str, "<unknown error: %d>", (int)code) == -1 || str == NULL)
293
return NULL;
294
295
return str;
296
}
297
298
299
/**
300
* Free the error message returned by krb5_get_error_message().
301
*
302
* @param context Kerberos context
303
* @param msg error message to free, returned byg
304
* krb5_get_error_message().
305
*
306
* @ingroup krb5_error
307
*/
308
309
KRB5_LIB_FUNCTION void KRB5_LIB_CALL
310
krb5_free_error_message(krb5_context context, const char *msg)
311
{
312
free(rk_UNCONST(msg));
313
}
314
315
316
/**
317
* Return the error string for the error code. The caller must not
318
* free the string.
319
*
320
* This function is deprecated since its not threadsafe.
321
*
322
* @param context Kerberos 5 context.
323
* @param code Kerberos error code.
324
*
325
* @return the error message matching code
326
*
327
* @ingroup krb5
328
*/
329
330
KRB5_LIB_FUNCTION const char* KRB5_LIB_CALL
331
krb5_get_err_text(krb5_context context, krb5_error_code code)
332
KRB5_DEPRECATED_FUNCTION("Use X instead")
333
{
334
const char *p = NULL;
335
if(context != NULL)
336
p = com_right(context->et_list, code);
337
if(p == NULL)
338
p = strerror(code);
339
if (p == NULL)
340
p = "Unknown error";
341
return p;
342
}
343
344