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 47void KRB5_LIB_FUNCTION 48krb5_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 70void KRB5_LIB_FUNCTION 71krb5_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 94void KRB5_LIB_FUNCTION 95krb5_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 120char * KRB5_LIB_FUNCTION 121krb5_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 132krb5_boolean KRB5_LIB_FUNCTION 133krb5_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 155const char * KRB5_LIB_FUNCTION 156krb5_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 197void KRB5_LIB_FUNCTION 198krb5_free_error_message(krb5_context context, const char *msg) 199{ 200 free(rk_UNCONST(msg)); 201} 202