/* seterror.c - sasl_seterror split out because glue libraries * can't pass varargs lists * Rob Siemborski * Tim Martin * split from common.c by Rolf Braun */ /* * Copyright (c) 1998-2016 Carnegie Mellon University. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The name "Carnegie Mellon University" must not be used to * endorse or promote products derived from this software without * prior written permission. For permission or any other legal * details, please contact * Carnegie Mellon University * Center for Technology Transfer and Enterprise Creation * 4615 Forbes Avenue * Suite 302 * Pittsburgh, PA 15213 * (412) 268-7393, fax: (412) 268-7395 * innovation@andrew.cmu.edu * * 4. Redistributions of any form whatsoever must retain the following * acknowledgment: * "This product includes software developed by Computing Services * at Carnegie Mellon University (http://www.cmu.edu/computing/)." * * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include #include #include #include #include #ifdef HAVE_SYSLOG #include #endif #include #include #include #include #include #include "saslint.h" #ifdef WIN32 /* need to handle the fact that errno has been defined as a function in a dll, not an extern int */ # ifdef errno # undef errno # endif /* errno */ #endif /* WIN32 */ #ifdef HAVE_UNISTD_H #include #endif /* this is apparently no longer a user function */ static int _sasl_seterror_usererr(int saslerr) { /* Hide the difference in a username failure and a password failure */ if (saslerr == SASL_NOUSER) return SASL_BADAUTH; /* otherwise return the error given; no transform necessary */ return saslerr; } /* set the error string which will be returned by sasl_errdetail() using * syslog()-style formatting (e.g. printf-style with %m as the string form * of an errno error) * * primarily for use by server callbacks such as the sasl_authorize_t * callback and internally to plug-ins * * This will also trigger a call to the SASL logging callback (if any) * with a level of SASL_LOG_FAIL unless the SASL_NOLOG flag is set. * * Messages should be sensitive to the current language setting. If there * is no SASL_CB_LANGUAGE callback messages MUST be US-ASCII otherwise UTF-8 * is used and use of RFC 2482 for mixed-language text is encouraged. * * if conn is NULL, function does nothing */ void sasl_seterror(sasl_conn_t *conn, unsigned flags, const char *fmt, ...) { size_t outlen=0; /* current length of output buffer */ size_t pos = 0; /* current position in format string */ size_t formatlen; int result; sasl_log_t *log_cb = NULL; void *log_ctx; int ival; char *cval; va_list ap; /* varargs thing */ char **error_buf; size_t *error_buf_len; if(!conn) { #ifndef SASL_OSX_CFMGLUE if(!(flags & SASL_NOLOG)) { /* See if we have a logging callback... */ result = _sasl_getcallback(NULL, SASL_CB_LOG, (sasl_callback_ft *)&log_cb, &log_ctx); if (result == SASL_OK && ! log_cb) result = SASL_FAIL; if (result != SASL_OK) return; log_cb(log_ctx, SASL_LOG_FAIL, "No sasl_conn_t passed to sasl_seterror"); } #endif /* SASL_OSX_CFMGLUE */ return; } else if(!fmt) return; /* we need to use a back end function to get the buffer because the cfm glue can't be rooting around in the internal structs */ _sasl_get_errorbuf(conn, &error_buf, &error_buf_len); formatlen = strlen(fmt); va_start(ap, fmt); /* start varargs */ while(pos9) done=1; } pos++; if (pos>formatlen) done=1; } } } (*error_buf)[outlen]='\0'; /* put 0 at end */ #ifndef SASL_OSX_CFMGLUE if(!(flags & SASL_NOLOG)) { /* See if we have a logging callback... */ result = _sasl_getcallback(conn, SASL_CB_LOG, (sasl_callback_ft *)&log_cb, &log_ctx); if (result == SASL_OK && ! log_cb) result = SASL_FAIL; if (result != SASL_OK) goto done; result = log_cb(log_ctx, SASL_LOG_FAIL, conn->error_buf); } #endif /* SASL_OSX_CFMGLUE */ done: va_end(ap); }