s4:heimdal: import lorikeet-heimdal-200906080040 (commit 904d0124b46eed7a8ad6e5b73e89...
[metze/samba/wip.git] / source4 / heimdal / lib / krb5 / error_string.c
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 void KRB5_LIB_FUNCTION
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  * @param context Kerberos 5 context
63  * @param ret The error code
64  * @param fmt Error string for the error code
65  * @param ... printf(3) style parameters.
66  *
67  * @ingroup krb5_error
68  */
69
70 void KRB5_LIB_FUNCTION
71 krb5_set_error_message(krb5_context context, krb5_error_code ret,
72                        const char *fmt, ...)
73     __attribute__ ((format (printf, 3, 4)))
74 {
75     va_list ap;
76
77     va_start(ap, fmt);
78     krb5_vset_error_message (context, ret, fmt, ap);
79     va_end(ap);
80 }
81
82 /**
83  * Set the context full error string for a specific error code.
84  *
85  * @param context Kerberos 5 context
86  * @param ret The error code
87  * @param fmt Error string for the error code
88  * @param args printf(3) style parameters.
89  *
90  * @ingroup krb5_error
91  */
92
93
94 void KRB5_LIB_FUNCTION
95 krb5_vset_error_message (krb5_context context, krb5_error_code ret,
96                          const char *fmt, va_list args)
97     __attribute__ ((format (printf, 3, 0)))
98 {
99
100     krb5_clear_error_message(context);
101     HEIMDAL_MUTEX_lock(context->mutex);
102     context->error_code = ret;
103     vasprintf(&context->error_string, fmt, args);
104     HEIMDAL_MUTEX_unlock(context->mutex);
105 }
106
107
108 /**
109  * Return the error message in context. On error or no error string,
110  * the function returns NULL.
111  *
112  * @param context Kerberos 5 context
113  *
114  * @return an error string, needs to be freed with
115  * krb5_free_error_message(). The functions return NULL on error.
116  *
117  * @ingroup krb5_error
118  */
119
120 char * KRB5_LIB_FUNCTION
121 krb5_get_error_string(krb5_context context)
122 {
123     char *ret = NULL;
124
125     HEIMDAL_MUTEX_lock(context->mutex);
126     if (context->error_string)
127         ret = strdup(context->error_string);
128     HEIMDAL_MUTEX_unlock(context->mutex);
129     return ret;
130 }
131
132 krb5_boolean KRB5_LIB_FUNCTION
133 krb5_have_error_string(krb5_context context)
134 {
135     char *str;
136     HEIMDAL_MUTEX_lock(context->mutex);
137     str = context->error_string;
138     HEIMDAL_MUTEX_unlock(context->mutex);
139     return str != NULL;
140 }
141
142 /**
143  * Return the error message for `code' in context. On memory
144  * allocation error the function returns NULL.
145  *
146  * @param context Kerberos 5 context
147  * @param code Error code related to the error
148  *
149  * @return an error string, needs to be freed with
150  * krb5_free_error_message(). The functions return NULL on error.
151  *
152  * @ingroup krb5_error
153  */
154
155 const char * KRB5_LIB_FUNCTION
156 krb5_get_error_message(krb5_context context, krb5_error_code code)
157 {
158     const char *cstr;
159     char *str;
160
161     HEIMDAL_MUTEX_lock(context->mutex);
162     if (context->error_string &&
163         (code == context->error_code || context->error_code == 0))
164     {
165         str = strdup(context->error_string);
166         if (str) {
167             HEIMDAL_MUTEX_unlock(context->mutex);
168             return str;
169         }
170     }
171     HEIMDAL_MUTEX_unlock(context->mutex);
172
173     if (code == 0)
174         return strdup("Success");
175
176     cstr = krb5_get_err_text(context, code);
177     if (cstr)
178         return strdup(cstr);
179
180     if (asprintf(&str, "<unknown error: %d>", (int)code) == -1)
181         return NULL;
182
183     return str;
184 }
185
186
187 /**
188  * Free the error message returned by krb5_get_error_message().
189  *
190  * @param context Kerberos context
191  * @param msg error message to free, returned byg
192  *        krb5_get_error_message().
193  *
194  * @ingroup krb5_error
195  */
196
197 void KRB5_LIB_FUNCTION
198 krb5_free_error_message(krb5_context context, const char *msg)
199 {
200     free(rk_UNCONST(msg));
201 }