xref: /illumos-gate/usr/src/lib/libsasl/lib/seterror.c (revision 1da57d55)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
37c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
47c478bd9Sstevel@tonic-gate  */
57c478bd9Sstevel@tonic-gate 
67c478bd9Sstevel@tonic-gate /* seterror.c - sasl_seterror split out because glue libraries
77c478bd9Sstevel@tonic-gate  *              can't pass varargs lists
87c478bd9Sstevel@tonic-gate  * Rob Siemborski
97c478bd9Sstevel@tonic-gate  * Tim Martin
107c478bd9Sstevel@tonic-gate  * split from common.c by Rolf Braun
117c478bd9Sstevel@tonic-gate  * $Id: seterror.c,v 1.7 2003/02/13 19:55:55 rjs3 Exp $
127c478bd9Sstevel@tonic-gate  */
137c478bd9Sstevel@tonic-gate 
14*1da57d55SToomas Soome /*
157c478bd9Sstevel@tonic-gate  * Copyright (c) 1998-2003 Carnegie Mellon University.  All rights reserved.
167c478bd9Sstevel@tonic-gate  *
177c478bd9Sstevel@tonic-gate  * Redistribution and use in source and binary forms, with or without
187c478bd9Sstevel@tonic-gate  * modification, are permitted provided that the following conditions
197c478bd9Sstevel@tonic-gate  * are met:
207c478bd9Sstevel@tonic-gate  *
217c478bd9Sstevel@tonic-gate  * 1. Redistributions of source code must retain the above copyright
22*1da57d55SToomas Soome  *    notice, this list of conditions and the following disclaimer.
237c478bd9Sstevel@tonic-gate  *
247c478bd9Sstevel@tonic-gate  * 2. Redistributions in binary form must reproduce the above copyright
257c478bd9Sstevel@tonic-gate  *    notice, this list of conditions and the following disclaimer in
267c478bd9Sstevel@tonic-gate  *    the documentation and/or other materials provided with the
277c478bd9Sstevel@tonic-gate  *    distribution.
287c478bd9Sstevel@tonic-gate  *
297c478bd9Sstevel@tonic-gate  * 3. The name "Carnegie Mellon University" must not be used to
307c478bd9Sstevel@tonic-gate  *    endorse or promote products derived from this software without
317c478bd9Sstevel@tonic-gate  *    prior written permission. For permission or any other legal
32*1da57d55SToomas Soome  *    details, please contact
337c478bd9Sstevel@tonic-gate  *      Office of Technology Transfer
347c478bd9Sstevel@tonic-gate  *      Carnegie Mellon University
357c478bd9Sstevel@tonic-gate  *      5000 Forbes Avenue
367c478bd9Sstevel@tonic-gate  *      Pittsburgh, PA  15213-3890
377c478bd9Sstevel@tonic-gate  *      (412) 268-4387, fax: (412) 268-7395
387c478bd9Sstevel@tonic-gate  *      tech-transfer@andrew.cmu.edu
397c478bd9Sstevel@tonic-gate  *
407c478bd9Sstevel@tonic-gate  * 4. Redistributions of any form whatsoever must retain the following
417c478bd9Sstevel@tonic-gate  *    acknowledgment:
427c478bd9Sstevel@tonic-gate  *    "This product includes software developed by Computing Services
437c478bd9Sstevel@tonic-gate  *     at Carnegie Mellon University (http://www.cmu.edu/computing/)."
447c478bd9Sstevel@tonic-gate  *
457c478bd9Sstevel@tonic-gate  * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
467c478bd9Sstevel@tonic-gate  * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
477c478bd9Sstevel@tonic-gate  * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
487c478bd9Sstevel@tonic-gate  * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
497c478bd9Sstevel@tonic-gate  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
507c478bd9Sstevel@tonic-gate  * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
517c478bd9Sstevel@tonic-gate  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
527c478bd9Sstevel@tonic-gate  */
537c478bd9Sstevel@tonic-gate 
547c478bd9Sstevel@tonic-gate #include <config.h>
557c478bd9Sstevel@tonic-gate #include <stdio.h>
567c478bd9Sstevel@tonic-gate #include <string.h>
577c478bd9Sstevel@tonic-gate #include <stdlib.h>
587c478bd9Sstevel@tonic-gate #include <limits.h>
597c478bd9Sstevel@tonic-gate #ifdef HAVE_SYSLOG
607c478bd9Sstevel@tonic-gate #include <syslog.h>
617c478bd9Sstevel@tonic-gate #endif
627c478bd9Sstevel@tonic-gate #include <stdarg.h>
637c478bd9Sstevel@tonic-gate #include <ctype.h>
647c478bd9Sstevel@tonic-gate 
657c478bd9Sstevel@tonic-gate #include <sasl.h>
667c478bd9Sstevel@tonic-gate #include <saslutil.h>
677c478bd9Sstevel@tonic-gate #include <saslplug.h>
687c478bd9Sstevel@tonic-gate #include "saslint.h"
697c478bd9Sstevel@tonic-gate 
707c478bd9Sstevel@tonic-gate #ifdef WIN32
717c478bd9Sstevel@tonic-gate /* need to handle the fact that errno has been defined as a function
727c478bd9Sstevel@tonic-gate    in a dll, not an extern int */
737c478bd9Sstevel@tonic-gate # ifdef errno
747c478bd9Sstevel@tonic-gate #  undef errno
757c478bd9Sstevel@tonic-gate # endif /* errno */
767c478bd9Sstevel@tonic-gate #endif /* WIN32 */
777c478bd9Sstevel@tonic-gate #ifdef HAVE_UNISTD_H
787c478bd9Sstevel@tonic-gate #include <unistd.h>
797c478bd9Sstevel@tonic-gate #endif
807c478bd9Sstevel@tonic-gate 
817c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_
827c478bd9Sstevel@tonic-gate #include "plugin_common.h"
837c478bd9Sstevel@tonic-gate #include <wchar.h>
847c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */
857c478bd9Sstevel@tonic-gate 
867c478bd9Sstevel@tonic-gate /* this is apparently no longer a user function */
_sasl_seterror_usererr(int saslerr)877c478bd9Sstevel@tonic-gate static int _sasl_seterror_usererr(int saslerr)
887c478bd9Sstevel@tonic-gate {
897c478bd9Sstevel@tonic-gate     /* Hide the difference in a username failure and a password failure */
907c478bd9Sstevel@tonic-gate     if (saslerr == SASL_NOUSER)
917c478bd9Sstevel@tonic-gate 	return SASL_BADAUTH;
927c478bd9Sstevel@tonic-gate 
937c478bd9Sstevel@tonic-gate     /* otherwise return the error given; no transform necessary */
947c478bd9Sstevel@tonic-gate     return saslerr;
957c478bd9Sstevel@tonic-gate }
967c478bd9Sstevel@tonic-gate 
97*1da57d55SToomas Soome /* set the error string which will be returned by sasl_errdetail() using
987c478bd9Sstevel@tonic-gate  *  syslog()-style formatting (e.g. printf-style with %m as the string form
997c478bd9Sstevel@tonic-gate  *  of an errno error)
100*1da57d55SToomas Soome  *
1017c478bd9Sstevel@tonic-gate  *  primarily for use by server callbacks such as the sasl_authorize_t
1027c478bd9Sstevel@tonic-gate  *  callback and internally to plug-ins
1037c478bd9Sstevel@tonic-gate  *
1047c478bd9Sstevel@tonic-gate  * This will also trigger a call to the SASL logging callback (if any)
1057c478bd9Sstevel@tonic-gate  * with a level of SASL_LOG_FAIL unless the SASL_NOLOG flag is set.
1067c478bd9Sstevel@tonic-gate  *
1077c478bd9Sstevel@tonic-gate  * Messages should be sensitive to the current language setting.  If there
1087c478bd9Sstevel@tonic-gate  * is no SASL_CB_LANGUAGE callback messages MUST be US-ASCII otherwise UTF-8
1097c478bd9Sstevel@tonic-gate  * is used and use of RFC 2482 for mixed-language text is encouraged.
110*1da57d55SToomas Soome  *
1117c478bd9Sstevel@tonic-gate  * if conn is NULL, function does nothing
1127c478bd9Sstevel@tonic-gate  */
sasl_seterror(sasl_conn_t * conn,unsigned flags,const char * fmt,...)1137c478bd9Sstevel@tonic-gate void sasl_seterror(sasl_conn_t *conn,
1147c478bd9Sstevel@tonic-gate 		   unsigned flags,
115*1da57d55SToomas Soome 		   const char *fmt, ...)
1167c478bd9Sstevel@tonic-gate {
1177c478bd9Sstevel@tonic-gate   size_t outlen=0; /* current length of output buffer */
1187c478bd9Sstevel@tonic-gate   int pos=0; /* current position in format string */
1197c478bd9Sstevel@tonic-gate   int formatlen;
1207c478bd9Sstevel@tonic-gate   int result;
1217c478bd9Sstevel@tonic-gate   sasl_log_t *log_cb;
1227c478bd9Sstevel@tonic-gate   void *log_ctx;
1237c478bd9Sstevel@tonic-gate   int ival;
1247c478bd9Sstevel@tonic-gate   char *cval;
1257c478bd9Sstevel@tonic-gate   va_list ap; /* varargs thing */
1267c478bd9Sstevel@tonic-gate   char **error_buf;
1277c478bd9Sstevel@tonic-gate   size_t *error_buf_len;
1287c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_
1297c478bd9Sstevel@tonic-gate   _sasl_global_context_t *gctx;
1307c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */
1317c478bd9Sstevel@tonic-gate #ifdef _INTEGRATED_SOLARIS_
1327c478bd9Sstevel@tonic-gate   sasl_getsimple_t *simple_cb;
1337c478bd9Sstevel@tonic-gate   void *simple_context;
1347c478bd9Sstevel@tonic-gate   const char *lang = NULL;
1357c478bd9Sstevel@tonic-gate   int ret;
1367c478bd9Sstevel@tonic-gate   const sasl_utils_t *utils;
1377c478bd9Sstevel@tonic-gate   int char_len;
1387c478bd9Sstevel@tonic-gate   char *utf8_buf;
1397c478bd9Sstevel@tonic-gate   const char *orig_fmt = fmt;
1407c478bd9Sstevel@tonic-gate   int is_client;
1417c478bd9Sstevel@tonic-gate #endif /* _INTEGRATED_SOLARIS_ */
1427c478bd9Sstevel@tonic-gate 
1437c478bd9Sstevel@tonic-gate   if(!conn) {
1447c478bd9Sstevel@tonic-gate #ifndef SASL_OSX_CFMGLUE
1457c478bd9Sstevel@tonic-gate       if(!(flags & SASL_NOLOG)) {
1467c478bd9Sstevel@tonic-gate 	  /* See if we have a logging callback... */
1477c478bd9Sstevel@tonic-gate 	  result = _sasl_getcallback(NULL, SASL_CB_LOG, &log_cb, &log_ctx);
1487c478bd9Sstevel@tonic-gate 	  if (result == SASL_OK && ! log_cb)
1497c478bd9Sstevel@tonic-gate 	      result = SASL_FAIL;
1507c478bd9Sstevel@tonic-gate 	  if (result != SASL_OK)
1517c478bd9Sstevel@tonic-gate 	      return;
152*1da57d55SToomas Soome 
1537c478bd9Sstevel@tonic-gate 	  log_cb(log_ctx, SASL_LOG_FAIL,
1547c478bd9Sstevel@tonic-gate 		 "No sasl_conn_t passed to sasl_seterror");
155*1da57d55SToomas Soome       }
1567c478bd9Sstevel@tonic-gate #endif /* SASL_OSX_CFMGLUE */
1577c478bd9Sstevel@tonic-gate       return;
158*1da57d55SToomas Soome   } else if(!fmt) return;
1597c478bd9Sstevel@tonic-gate 
1607c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_
1617c478bd9Sstevel@tonic-gate   gctx = conn->gctx;
1627c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */
1637c478bd9Sstevel@tonic-gate 
1647c478bd9Sstevel@tonic-gate #ifdef _INTEGRATED_SOLARIS_
1657c478bd9Sstevel@tonic-gate   if (conn->type == SASL_CONN_SERVER) {
1667c478bd9Sstevel@tonic-gate     utils = ((sasl_server_conn_t *)conn)->sparams->utils;
1677c478bd9Sstevel@tonic-gate     is_client = 0;
1687c478bd9Sstevel@tonic-gate   } else if (conn->type == SASL_CONN_CLIENT) {
1697c478bd9Sstevel@tonic-gate     utils = ((sasl_client_conn_t *)conn)->cparams->utils;
1707c478bd9Sstevel@tonic-gate     is_client = 1;
1717c478bd9Sstevel@tonic-gate   } else
1727c478bd9Sstevel@tonic-gate     utils = NULL;
1737c478bd9Sstevel@tonic-gate 
1747c478bd9Sstevel@tonic-gate   if (utils != NULL) {
1757c478bd9Sstevel@tonic-gate     ret = utils->getcallback(conn, SASL_CB_LANGUAGE, &simple_cb,
1767c478bd9Sstevel@tonic-gate 	&simple_context);
1777c478bd9Sstevel@tonic-gate 
1787c478bd9Sstevel@tonic-gate     if (ret == SASL_OK && simple_cb)
1797c478bd9Sstevel@tonic-gate 	(void) simple_cb(simple_context, SASL_CB_LANGUAGE, &lang, NULL);
1807c478bd9Sstevel@tonic-gate 
1817c478bd9Sstevel@tonic-gate     if (use_locale(lang, is_client))
1827c478bd9Sstevel@tonic-gate 	fmt = dgettext(TEXT_DOMAIN, fmt);
1837c478bd9Sstevel@tonic-gate   }
1847c478bd9Sstevel@tonic-gate #endif /* _INTEGRATED_SOLARIS_ */
1857c478bd9Sstevel@tonic-gate 
1867c478bd9Sstevel@tonic-gate /* we need to use a back end function to get the buffer because the
1877c478bd9Sstevel@tonic-gate    cfm glue can't be rooting around in the internal structs */
1887c478bd9Sstevel@tonic-gate   _sasl_get_errorbuf(conn, &error_buf, &error_buf_len);
1897c478bd9Sstevel@tonic-gate 
1907c478bd9Sstevel@tonic-gate   formatlen = strlen(fmt);
1917c478bd9Sstevel@tonic-gate 
1927c478bd9Sstevel@tonic-gate   va_start(ap, fmt); /* start varargs */
1937c478bd9Sstevel@tonic-gate 
1947c478bd9Sstevel@tonic-gate   while(pos<formatlen)
1957c478bd9Sstevel@tonic-gate   {
1967c478bd9Sstevel@tonic-gate     if (fmt[pos]!='%') /* regular character */
1977c478bd9Sstevel@tonic-gate     {
1987c478bd9Sstevel@tonic-gate #ifdef _INTEGRATED_SOLARIS_
1997c478bd9Sstevel@tonic-gate       char_len =  mbrlen(fmt + pos, formatlen - pos, NULL);
2007c478bd9Sstevel@tonic-gate       result = _buf_alloc(error_buf, error_buf_len, outlen + char_len);
2017c478bd9Sstevel@tonic-gate       if (result != SASL_OK)
2027c478bd9Sstevel@tonic-gate 	return;
2037c478bd9Sstevel@tonic-gate       while (char_len-- > 0) {
2047c478bd9Sstevel@tonic-gate 	(*error_buf)[outlen]=fmt[pos];
2057c478bd9Sstevel@tonic-gate 	outlen++;
2067c478bd9Sstevel@tonic-gate 	pos++;
2077c478bd9Sstevel@tonic-gate       }
2087c478bd9Sstevel@tonic-gate #else
2097c478bd9Sstevel@tonic-gate       result = _buf_alloc(error_buf, error_buf_len, outlen+1);
2107c478bd9Sstevel@tonic-gate       if (result != SASL_OK)
2117c478bd9Sstevel@tonic-gate 	return;
2127c478bd9Sstevel@tonic-gate       (*error_buf)[outlen]=fmt[pos];
2137c478bd9Sstevel@tonic-gate       outlen++;
2147c478bd9Sstevel@tonic-gate       pos++;
2157c478bd9Sstevel@tonic-gate #endif /* _INTEGRATED_SOLARIS_ */
2167c478bd9Sstevel@tonic-gate     } else { /* formating thing */
2177c478bd9Sstevel@tonic-gate       int done=0;
2187c478bd9Sstevel@tonic-gate       char frmt[10];
2197c478bd9Sstevel@tonic-gate       int frmtpos=1;
2207c478bd9Sstevel@tonic-gate       char tempbuf[21];
2217c478bd9Sstevel@tonic-gate       frmt[0]='%';
2227c478bd9Sstevel@tonic-gate       pos++;
2237c478bd9Sstevel@tonic-gate 
2247c478bd9Sstevel@tonic-gate       while (done==0)
2257c478bd9Sstevel@tonic-gate       {
2267c478bd9Sstevel@tonic-gate 	switch(fmt[pos])
2277c478bd9Sstevel@tonic-gate 	  {
2287c478bd9Sstevel@tonic-gate 	  case 's': /* need to handle this */
2297c478bd9Sstevel@tonic-gate 	    cval = va_arg(ap, char *); /* get the next arg */
2307c478bd9Sstevel@tonic-gate 	    result = _sasl_add_string(error_buf, error_buf_len,
2317c478bd9Sstevel@tonic-gate 				      &outlen, cval);
232*1da57d55SToomas Soome 
2337c478bd9Sstevel@tonic-gate 	    if (result != SASL_OK) /* add the string */
2347c478bd9Sstevel@tonic-gate 	      return;
2357c478bd9Sstevel@tonic-gate 
2367c478bd9Sstevel@tonic-gate 	    done=1;
2377c478bd9Sstevel@tonic-gate 	    break;
2387c478bd9Sstevel@tonic-gate 
2397c478bd9Sstevel@tonic-gate 	  case '%': /* double % output the '%' character */
2407c478bd9Sstevel@tonic-gate 	    result = _buf_alloc(error_buf, error_buf_len, outlen+1);
2417c478bd9Sstevel@tonic-gate 	    if (result != SASL_OK)
2427c478bd9Sstevel@tonic-gate 	      return;
2437c478bd9Sstevel@tonic-gate 	    (*error_buf)[outlen]='%';
2447c478bd9Sstevel@tonic-gate 	    outlen++;
2457c478bd9Sstevel@tonic-gate 	    done=1;
2467c478bd9Sstevel@tonic-gate 	    break;
2477c478bd9Sstevel@tonic-gate 
2487c478bd9Sstevel@tonic-gate 	  case 'm': /* insert the errno string */
2497c478bd9Sstevel@tonic-gate 	    result = _sasl_add_string(error_buf, error_buf_len,
2507c478bd9Sstevel@tonic-gate 				      &outlen,
2517c478bd9Sstevel@tonic-gate 				      strerror(va_arg(ap, int)));
2527c478bd9Sstevel@tonic-gate 	    if (result != SASL_OK)
2537c478bd9Sstevel@tonic-gate 	      return;
2547c478bd9Sstevel@tonic-gate 	    done=1;
2557c478bd9Sstevel@tonic-gate 	    break;
2567c478bd9Sstevel@tonic-gate 
2577c478bd9Sstevel@tonic-gate 	  case 'z': /* insert the sasl error string */
2587c478bd9Sstevel@tonic-gate #ifdef _INTEGRATED_SOLARIS_
2597c478bd9Sstevel@tonic-gate 	    result = _sasl_add_string(error_buf, error_buf_len,	&outlen,
2607c478bd9Sstevel@tonic-gate 			 (char *)sasl_errstring(_sasl_seterror_usererr(
2617c478bd9Sstevel@tonic-gate 					        va_arg(ap, int)), lang, NULL));
2627c478bd9Sstevel@tonic-gate #else
2637c478bd9Sstevel@tonic-gate 	    result = _sasl_add_string(error_buf, error_buf_len,	&outlen,
2647c478bd9Sstevel@tonic-gate 			 (char *)sasl_errstring(_sasl_seterror_usererr(
2657c478bd9Sstevel@tonic-gate 					        va_arg(ap, int)),NULL,NULL));
2667c478bd9Sstevel@tonic-gate #endif /* _INTEGRATED_SOLARIS_ */
2677c478bd9Sstevel@tonic-gate 	    if (result != SASL_OK)
2687c478bd9Sstevel@tonic-gate 	      return;
2697c478bd9Sstevel@tonic-gate 	    done=1;
2707c478bd9Sstevel@tonic-gate 	    break;
2717c478bd9Sstevel@tonic-gate 
2727c478bd9Sstevel@tonic-gate 	  case 'c':
2737c478bd9Sstevel@tonic-gate #ifndef _SUN_SDK_
2747c478bd9Sstevel@tonic-gate 	    frmt[frmtpos++]=fmt[pos];
2757c478bd9Sstevel@tonic-gate 	    frmt[frmtpos]=0;
2767c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */
2777c478bd9Sstevel@tonic-gate 	    tempbuf[0] = (char) va_arg(ap, int); /* get the next arg */
2787c478bd9Sstevel@tonic-gate 	    tempbuf[1]='\0';
279*1da57d55SToomas Soome 
2807c478bd9Sstevel@tonic-gate 	    /* now add the character */
2817c478bd9Sstevel@tonic-gate 	    result = _sasl_add_string(error_buf, error_buf_len,
2827c478bd9Sstevel@tonic-gate 				      &outlen, tempbuf);
2837c478bd9Sstevel@tonic-gate 	    if (result != SASL_OK)
2847c478bd9Sstevel@tonic-gate 	      return;
2857c478bd9Sstevel@tonic-gate 	    done=1;
2867c478bd9Sstevel@tonic-gate 	    break;
2877c478bd9Sstevel@tonic-gate 
2887c478bd9Sstevel@tonic-gate 	  case 'd':
2897c478bd9Sstevel@tonic-gate 	  case 'i':
2907c478bd9Sstevel@tonic-gate 	    frmt[frmtpos++]=fmt[pos];
2917c478bd9Sstevel@tonic-gate 	    frmt[frmtpos]=0;
2927c478bd9Sstevel@tonic-gate 	    ival = va_arg(ap, int); /* get the next arg */
2937c478bd9Sstevel@tonic-gate 
2947c478bd9Sstevel@tonic-gate 	    snprintf(tempbuf,20,frmt,ival); /* have snprintf do the work */
2957c478bd9Sstevel@tonic-gate 	    /* now add the string */
2967c478bd9Sstevel@tonic-gate 	    result = _sasl_add_string(error_buf, error_buf_len,
2977c478bd9Sstevel@tonic-gate 				      &outlen, tempbuf);
2987c478bd9Sstevel@tonic-gate 	    if (result != SASL_OK)
2997c478bd9Sstevel@tonic-gate 	      return;
3007c478bd9Sstevel@tonic-gate 	    done=1;
3017c478bd9Sstevel@tonic-gate 
3027c478bd9Sstevel@tonic-gate 	    break;
303*1da57d55SToomas Soome 	  default:
3047c478bd9Sstevel@tonic-gate 	    frmt[frmtpos++]=fmt[pos]; /* add to the formating */
305*1da57d55SToomas Soome 	    frmt[frmtpos]=0;
3067c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_
307*1da57d55SToomas Soome 	    if (frmtpos > sizeof (frmt) - 2)
3087c478bd9Sstevel@tonic-gate #else
309*1da57d55SToomas Soome 	    if (frmtpos>9)
3107c478bd9Sstevel@tonic-gate #endif	/* _SUN_SDK_ */
3117c478bd9Sstevel@tonic-gate 	      done=1;
3127c478bd9Sstevel@tonic-gate 	  }
3137c478bd9Sstevel@tonic-gate 	pos++;
3147c478bd9Sstevel@tonic-gate 	if (pos>formatlen)
3157c478bd9Sstevel@tonic-gate 	  done=1;
3167c478bd9Sstevel@tonic-gate       }
3177c478bd9Sstevel@tonic-gate 
3187c478bd9Sstevel@tonic-gate     }
3197c478bd9Sstevel@tonic-gate   }
3207c478bd9Sstevel@tonic-gate 
3217c478bd9Sstevel@tonic-gate   (*error_buf)[outlen]='\0'; /* put 0 at end */
3227c478bd9Sstevel@tonic-gate 
323*1da57d55SToomas Soome   va_end(ap);
3247c478bd9Sstevel@tonic-gate 
3257c478bd9Sstevel@tonic-gate #ifdef _INTEGRATED_SOLARIS_
3267c478bd9Sstevel@tonic-gate   if (orig_fmt != fmt) {
3277c478bd9Sstevel@tonic-gate     utf8_buf = local_to_utf(utils, *error_buf);
3287c478bd9Sstevel@tonic-gate     if (utf8_buf != NULL) {
3297c478bd9Sstevel@tonic-gate       outlen = strlen(utf8_buf);
3307c478bd9Sstevel@tonic-gate       result = SASL_OK;
3317c478bd9Sstevel@tonic-gate       if (outlen >= *error_buf_len)
3327c478bd9Sstevel@tonic-gate       result = _buf_alloc(error_buf, error_buf_len, outlen+1);
3337c478bd9Sstevel@tonic-gate       if (result != SASL_OK) {
3347c478bd9Sstevel@tonic-gate 	utils->free(utf8_buf);
3357c478bd9Sstevel@tonic-gate 	return;
3367c478bd9Sstevel@tonic-gate       }
3377c478bd9Sstevel@tonic-gate       strcpy(*error_buf, utf8_buf);
3387c478bd9Sstevel@tonic-gate       utils->free(utf8_buf);
3397c478bd9Sstevel@tonic-gate     }
3407c478bd9Sstevel@tonic-gate   }
3417c478bd9Sstevel@tonic-gate #endif /* _INTEGRATED_SOLARIS_ */
3427c478bd9Sstevel@tonic-gate 
3437c478bd9Sstevel@tonic-gate #ifndef SASL_OSX_CFMGLUE
3447c478bd9Sstevel@tonic-gate   if(!(flags & SASL_NOLOG)) {
3457c478bd9Sstevel@tonic-gate       /* See if we have a logging callback... */
3467c478bd9Sstevel@tonic-gate       result = _sasl_getcallback(conn, SASL_CB_LOG, &log_cb, &log_ctx);
3477c478bd9Sstevel@tonic-gate       if (result == SASL_OK && ! log_cb)
3487c478bd9Sstevel@tonic-gate 	  result = SASL_FAIL;
3497c478bd9Sstevel@tonic-gate       if (result != SASL_OK)
3507c478bd9Sstevel@tonic-gate 	  return;
351*1da57d55SToomas Soome 
3527c478bd9Sstevel@tonic-gate       result = log_cb(log_ctx, SASL_LOG_FAIL, conn->error_buf);
3537c478bd9Sstevel@tonic-gate   }
3547c478bd9Sstevel@tonic-gate #endif /* SASL_OSX_CFMGLUE */
3557c478bd9Sstevel@tonic-gate }
356