1 /* 2 * Copyright (c) 1997 - 2001 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 #include <err.h> 36 37 static krb5_error_code _warnerr(krb5_context context, int do_errtext, 38 krb5_error_code code, int level, const char *fmt, va_list ap) 39 __attribute__((__format__(__printf__, 5, 0))); 40 41 static krb5_error_code 42 _warnerr(krb5_context context, int do_errtext, 43 krb5_error_code code, int level, const char *fmt, va_list ap) 44 { 45 char xfmt[7] = ""; 46 const char *args[2], **arg; 47 char *msg = NULL; 48 const char *err_str = NULL; 49 krb5_error_code ret; 50 51 args[0] = args[1] = NULL; 52 arg = args; 53 if(fmt){ 54 strlcat(xfmt, "%s", sizeof(xfmt)); 55 if(do_errtext) 56 strlcat(xfmt, ": ", sizeof(xfmt)); 57 ret = vasprintf(&msg, fmt, ap); 58 if(ret < 0 || msg == NULL) 59 return ENOMEM; 60 *arg++ = msg; 61 } 62 if(context && do_errtext){ 63 strlcat(xfmt, "%s", sizeof(xfmt)); 64 65 err_str = krb5_get_error_message(context, code); 66 if (err_str != NULL) { 67 *arg = err_str; 68 } else { 69 *arg= "<unknown error>"; 70 } 71 } 72 73 if(context && context->warn_dest) 74 krb5_log(context, context->warn_dest, level, xfmt, args[0], args[1]); 75 else 76 warnx(xfmt, args[0], args[1]); 77 free(msg); 78 krb5_free_error_message(context, err_str); 79 return 0; 80 } 81 82 #define FUNC(ETEXT, CODE, LEVEL) \ 83 krb5_error_code ret; \ 84 va_list ap; \ 85 va_start(ap, fmt); \ 86 ret = _warnerr(context, ETEXT, CODE, LEVEL, fmt, ap); \ 87 va_end(ap); 88 89 #undef __attribute__ 90 #define __attribute__(X) 91 92 /** 93 * Log a warning to the log, default stderr, include the error from 94 * the last failure. 95 * 96 * @param context A Kerberos 5 context. 97 * @param code error code of the last error 98 * @param fmt message to print 99 * @param ap arguments 100 * 101 * @ingroup krb5_error 102 */ 103 104 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 105 krb5_vwarn(krb5_context context, krb5_error_code code, 106 const char *fmt, va_list ap) 107 __attribute__ ((format (printf, 3, 0))) 108 { 109 return _warnerr(context, 1, code, 1, fmt, ap); 110 } 111 112 /** 113 * Log a warning to the log, default stderr, include the error from 114 * the last failure. 115 * 116 * @param context A Kerberos 5 context. 117 * @param code error code of the last error 118 * @param fmt message to print 119 * 120 * @ingroup krb5_error 121 */ 122 123 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 124 krb5_warn(krb5_context context, krb5_error_code code, const char *fmt, ...) 125 __attribute__ ((format (printf, 3, 4))) 126 { 127 FUNC(1, code, 1); 128 return ret; 129 } 130 131 /** 132 * Log a warning to the log, default stderr. 133 * 134 * @param context A Kerberos 5 context. 135 * @param fmt message to print 136 * @param ap arguments 137 * 138 * @ingroup krb5_error 139 */ 140 141 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 142 krb5_vwarnx(krb5_context context, const char *fmt, va_list ap) 143 __attribute__ ((format (printf, 2, 0))) 144 { 145 return _warnerr(context, 0, 0, 1, fmt, ap); 146 } 147 148 /** 149 * Log a warning to the log, default stderr. 150 * 151 * @param context A Kerberos 5 context. 152 * @param fmt message to print 153 * 154 * @ingroup krb5_error 155 */ 156 157 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 158 krb5_warnx(krb5_context context, const char *fmt, ...) 159 __attribute__ ((format (printf, 2, 3))) 160 { 161 FUNC(0, 0, 1); 162 return ret; 163 } 164 165 /** 166 * Log a warning to the log, default stderr, include bthe error from 167 * the last failure and then exit. 168 * 169 * @param context A Kerberos 5 context 170 * @param eval the exit code to exit with 171 * @param code error code of the last error 172 * @param fmt message to print 173 * @param ap arguments 174 * 175 * @ingroup krb5_error 176 */ 177 178 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 179 krb5_verr(krb5_context context, int eval, krb5_error_code code, 180 const char *fmt, va_list ap) 181 __attribute__ ((noreturn, format (printf, 4, 0))) 182 { 183 _warnerr(context, 1, code, 0, fmt, ap); 184 exit(eval); 185 UNREACHABLE(return 0); 186 } 187 188 /** 189 * Log a warning to the log, default stderr, include bthe error from 190 * the last failure and then exit. 191 * 192 * @param context A Kerberos 5 context 193 * @param eval the exit code to exit with 194 * @param code error code of the last error 195 * @param fmt message to print 196 * 197 * @ingroup krb5_error 198 */ 199 200 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 201 krb5_err(krb5_context context, int eval, krb5_error_code code, 202 const char *fmt, ...) 203 __attribute__ ((noreturn, format (printf, 4, 5))) 204 { 205 FUNC(1, code, 0); 206 exit(eval); 207 UNREACHABLE(return 0); 208 } 209 210 /** 211 * Log a warning to the log, default stderr, and then exit. 212 * 213 * @param context A Kerberos 5 context 214 * @param eval the exit code to exit with 215 * @param fmt message to print 216 * @param ap arguments 217 * 218 * @ingroup krb5_error 219 */ 220 221 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 222 krb5_verrx(krb5_context context, int eval, const char *fmt, va_list ap) 223 __attribute__ ((noreturn, format (printf, 3, 0))) 224 { 225 _warnerr(context, 0, 0, 0, fmt, ap); 226 exit(eval); 227 UNREACHABLE(return 0); 228 } 229 230 /** 231 * Log a warning to the log, default stderr, and then exit. 232 * 233 * @param context A Kerberos 5 context 234 * @param eval the exit code to exit with 235 * @param fmt message to print 236 * 237 * @ingroup krb5_error 238 */ 239 240 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 241 krb5_errx(krb5_context context, int eval, const char *fmt, ...) 242 __attribute__ ((noreturn, format (printf, 3, 4))) 243 { 244 FUNC(0, 0, 0); 245 exit(eval); 246 UNREACHABLE(return 0); 247 } 248 249 /** 250 * Log a warning to the log, default stderr, include bthe error from 251 * the last failure and then abort. 252 * 253 * @param context A Kerberos 5 context 254 * @param code error code of the last error 255 * @param fmt message to print 256 * @param ap arguments 257 * 258 * @ingroup krb5_error 259 */ 260 261 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 262 krb5_vabort(krb5_context context, krb5_error_code code, 263 const char *fmt, va_list ap) 264 __attribute__ ((noreturn, format (printf, 3, 0))) 265 { 266 _warnerr(context, 1, code, 0, fmt, ap); 267 abort(); 268 UNREACHABLE(return 0); 269 } 270 271 /** 272 * Log a warning to the log, default stderr, include the error from 273 * the last failure and then abort. 274 * 275 * @param context A Kerberos 5 context 276 * @param code error code of the last error 277 * @param fmt message to print 278 * 279 * @ingroup krb5_error 280 */ 281 282 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 283 krb5_abort(krb5_context context, krb5_error_code code, const char *fmt, ...) 284 __attribute__ ((noreturn, format (printf, 3, 4))) 285 { 286 FUNC(1, code, 0); 287 abort(); 288 UNREACHABLE(return 0); 289 } 290 291 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 292 krb5_vabortx(krb5_context context, const char *fmt, va_list ap) 293 __attribute__ ((noreturn, format (printf, 2, 0))) 294 { 295 _warnerr(context, 0, 0, 0, fmt, ap); 296 abort(); 297 UNREACHABLE(return 0); 298 } 299 300 /** 301 * Log a warning to the log, default stderr, and then abort. 302 * 303 * @param context A Kerberos 5 context 304 * @param code error code of the last error 305 * @param fmt message to print 306 * 307 * @ingroup krb5_error 308 */ 309 310 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 311 krb5_abortx(krb5_context context, const char *fmt, ...) 312 __attribute__ ((noreturn, format (printf, 2, 3))) 313 { 314 FUNC(0, 0, 0); 315 abort(); 316 UNREACHABLE(return 0); 317 } 318 319 /** 320 * Set the default logging facility. 321 * 322 * @param context A Kerberos 5 context 323 * @param fac Facility to use for logging. 324 * 325 * @ingroup krb5_error 326 */ 327 328 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 329 krb5_set_warn_dest(krb5_context context, krb5_log_facility *fac) 330 { 331 context->warn_dest = fac; 332 return 0; 333 } 334 335 /** 336 * Get the default logging facility. 337 * 338 * @param context A Kerberos 5 context 339 * 340 * @ingroup krb5_error 341 */ 342 343 KRB5_LIB_FUNCTION krb5_log_facility * KRB5_LIB_CALL 344 krb5_get_warn_dest(krb5_context context) 345 { 346 return context->warn_dest; 347 } 348