xref: /illumos-gate/usr/src/lib/libsasl/lib/common.c (revision 55fea89dcaa64928bed4327112404dcb3e07b79f)
17c478bd9Sstevel@tonic-gate /*
2cb620785Sraf  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
37c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
47c478bd9Sstevel@tonic-gate  */
5cb620785Sraf 
67c478bd9Sstevel@tonic-gate /* common.c - Functions that are common to server and clinet
77c478bd9Sstevel@tonic-gate  * Rob Siemborski
87c478bd9Sstevel@tonic-gate  * Tim Martin
97c478bd9Sstevel@tonic-gate  * $Id: common.c,v 1.92 2003/04/16 19:36:00 rjs3 Exp $
107c478bd9Sstevel@tonic-gate  */
117c478bd9Sstevel@tonic-gate /*
127c478bd9Sstevel@tonic-gate  * Copyright (c) 1998-2003 Carnegie Mellon University.  All rights reserved.
137c478bd9Sstevel@tonic-gate  *
147c478bd9Sstevel@tonic-gate  * Redistribution and use in source and binary forms, with or without
157c478bd9Sstevel@tonic-gate  * modification, are permitted provided that the following conditions
167c478bd9Sstevel@tonic-gate  * are met:
177c478bd9Sstevel@tonic-gate  *
187c478bd9Sstevel@tonic-gate  * 1. Redistributions of source code must retain the above copyright
197c478bd9Sstevel@tonic-gate  *    notice, this list of conditions and the following disclaimer.
207c478bd9Sstevel@tonic-gate  *
217c478bd9Sstevel@tonic-gate  * 2. Redistributions in binary form must reproduce the above copyright
227c478bd9Sstevel@tonic-gate  *    notice, this list of conditions and the following disclaimer in
237c478bd9Sstevel@tonic-gate  *    the documentation and/or other materials provided with the
247c478bd9Sstevel@tonic-gate  *    distribution.
257c478bd9Sstevel@tonic-gate  *
267c478bd9Sstevel@tonic-gate  * 3. The name "Carnegie Mellon University" must not be used to
277c478bd9Sstevel@tonic-gate  *    endorse or promote products derived from this software without
287c478bd9Sstevel@tonic-gate  *    prior written permission. For permission or any other legal
297c478bd9Sstevel@tonic-gate  *    details, please contact
307c478bd9Sstevel@tonic-gate  *      Office of Technology Transfer
317c478bd9Sstevel@tonic-gate  *      Carnegie Mellon University
327c478bd9Sstevel@tonic-gate  *      5000 Forbes Avenue
337c478bd9Sstevel@tonic-gate  *      Pittsburgh, PA  15213-3890
347c478bd9Sstevel@tonic-gate  *      (412) 268-4387, fax: (412) 268-7395
357c478bd9Sstevel@tonic-gate  *      tech-transfer@andrew.cmu.edu
367c478bd9Sstevel@tonic-gate  *
377c478bd9Sstevel@tonic-gate  * 4. Redistributions of any form whatsoever must retain the following
387c478bd9Sstevel@tonic-gate  *    acknowledgment:
397c478bd9Sstevel@tonic-gate  *    "This product includes software developed by Computing Services
407c478bd9Sstevel@tonic-gate  *     at Carnegie Mellon University (http://www.cmu.edu/computing/)."
417c478bd9Sstevel@tonic-gate  *
427c478bd9Sstevel@tonic-gate  * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
437c478bd9Sstevel@tonic-gate  * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
447c478bd9Sstevel@tonic-gate  * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
457c478bd9Sstevel@tonic-gate  * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
467c478bd9Sstevel@tonic-gate  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
477c478bd9Sstevel@tonic-gate  * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
487c478bd9Sstevel@tonic-gate  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
497c478bd9Sstevel@tonic-gate  */
507c478bd9Sstevel@tonic-gate 
517c478bd9Sstevel@tonic-gate #include <config.h>
527c478bd9Sstevel@tonic-gate #include <stdio.h>
537c478bd9Sstevel@tonic-gate #include <string.h>
547c478bd9Sstevel@tonic-gate #include <stdlib.h>
557c478bd9Sstevel@tonic-gate #include <limits.h>
567c478bd9Sstevel@tonic-gate #ifdef HAVE_SYSLOG
577c478bd9Sstevel@tonic-gate #include <syslog.h>
587c478bd9Sstevel@tonic-gate #endif
597c478bd9Sstevel@tonic-gate #include <stdarg.h>
607c478bd9Sstevel@tonic-gate #include <ctype.h>
617c478bd9Sstevel@tonic-gate 
627c478bd9Sstevel@tonic-gate #include <sasl.h>
637c478bd9Sstevel@tonic-gate #include <saslutil.h>
647c478bd9Sstevel@tonic-gate #include <saslplug.h>
657c478bd9Sstevel@tonic-gate #include "saslint.h"
667c478bd9Sstevel@tonic-gate 
677c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_
687c478bd9Sstevel@tonic-gate #include "md5_private.h"
697c478bd9Sstevel@tonic-gate #include "hmac-md5.h"
707c478bd9Sstevel@tonic-gate #include "plugin_common.h"
717c478bd9Sstevel@tonic-gate #endif
727c478bd9Sstevel@tonic-gate 
737c478bd9Sstevel@tonic-gate 
747c478bd9Sstevel@tonic-gate #ifdef WIN32
757c478bd9Sstevel@tonic-gate /* need to handle the fact that errno has been defined as a function
767c478bd9Sstevel@tonic-gate    in a dll, not an extern int */
777c478bd9Sstevel@tonic-gate # ifdef errno
787c478bd9Sstevel@tonic-gate #  undef errno
797c478bd9Sstevel@tonic-gate # endif /* errno */
807c478bd9Sstevel@tonic-gate #endif /* WIN32 */
817c478bd9Sstevel@tonic-gate #ifdef HAVE_UNISTD_H
827c478bd9Sstevel@tonic-gate #include <unistd.h>
837c478bd9Sstevel@tonic-gate #endif
847c478bd9Sstevel@tonic-gate 
857c478bd9Sstevel@tonic-gate static int _sasl_getpath(void *context __attribute__((unused)), const char **path);
867c478bd9Sstevel@tonic-gate 
877c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_
887c478bd9Sstevel@tonic-gate DEFINE_STATIC_MUTEX(global_mutex);
897c478bd9Sstevel@tonic-gate DEFINE_STATIC_MUTEX(malloc_global_mutex);
907c478bd9Sstevel@tonic-gate static void _sasl_dispose_context(_sasl_global_context_t *ctx);
917c478bd9Sstevel@tonic-gate static int _sasl_getconf(void *context, const char **conf);
927c478bd9Sstevel@tonic-gate 
937c478bd9Sstevel@tonic-gate #ifdef _INTEGRATED_SOLARIS_
94cb620785Sraf static pthread_key_t errstring_key = PTHREAD_ONCE_KEY_NP;
957c478bd9Sstevel@tonic-gate #endif /* _INTEGRATED_SOLARIS_ */
967c478bd9Sstevel@tonic-gate #else
977c478bd9Sstevel@tonic-gate static const char build_ident[] = "$Build: libsasl " PACKAGE "-" VERSION " $";
987c478bd9Sstevel@tonic-gate 
997c478bd9Sstevel@tonic-gate /* It turns out to be conveinent to have a shared sasl_utils_t */
1007c478bd9Sstevel@tonic-gate LIBSASL_VAR const sasl_utils_t *sasl_global_utils = NULL;
1017c478bd9Sstevel@tonic-gate 
1027c478bd9Sstevel@tonic-gate /* Should be a null-terminated array that lists the available mechanisms */
1037c478bd9Sstevel@tonic-gate static char **global_mech_list = NULL;
1047c478bd9Sstevel@tonic-gate 
1057c478bd9Sstevel@tonic-gate void *free_mutex = NULL;
1067c478bd9Sstevel@tonic-gate 
1077c478bd9Sstevel@tonic-gate int (*_sasl_client_cleanup_hook)(void) = NULL;
1087c478bd9Sstevel@tonic-gate int (*_sasl_server_cleanup_hook)(void) = NULL;
1097c478bd9Sstevel@tonic-gate int (*_sasl_client_idle_hook)(sasl_conn_t *conn) = NULL;
1107c478bd9Sstevel@tonic-gate int (*_sasl_server_idle_hook)(sasl_conn_t *conn) = NULL;
1117c478bd9Sstevel@tonic-gate 
1127c478bd9Sstevel@tonic-gate sasl_allocation_utils_t _sasl_allocation_utils={
1137c478bd9Sstevel@tonic-gate   (sasl_malloc_t *)  &malloc,
1147c478bd9Sstevel@tonic-gate   (sasl_calloc_t *)  &calloc,
1157c478bd9Sstevel@tonic-gate   (sasl_realloc_t *) &realloc,
1167c478bd9Sstevel@tonic-gate   (sasl_free_t *) &free
1177c478bd9Sstevel@tonic-gate };
1187c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */
1197c478bd9Sstevel@tonic-gate 
1207c478bd9Sstevel@tonic-gate #ifdef USE_PTHREADS
sasl_mutex_alloc(void)1217c478bd9Sstevel@tonic-gate static void *sasl_mutex_alloc(void)
1227c478bd9Sstevel@tonic-gate {
1237c478bd9Sstevel@tonic-gate     pthread_mutex_t *mutex =
1247c478bd9Sstevel@tonic-gate 	(pthread_mutex_t *)malloc(sizeof (pthread_mutex_t));
1257c478bd9Sstevel@tonic-gate 
1267c478bd9Sstevel@tonic-gate     if (mutex != NULL) {
1277c478bd9Sstevel@tonic-gate 	if (pthread_mutex_init(mutex, NULL) != 0) {
1287c478bd9Sstevel@tonic-gate 	    free(mutex);
1297c478bd9Sstevel@tonic-gate 	    mutex = NULL;
1307c478bd9Sstevel@tonic-gate 	}
1317c478bd9Sstevel@tonic-gate     }
1327c478bd9Sstevel@tonic-gate     return (mutex);
1337c478bd9Sstevel@tonic-gate }
1347c478bd9Sstevel@tonic-gate 
sasl_mutex_lock(void * mutex)1357c478bd9Sstevel@tonic-gate static int sasl_mutex_lock(void *mutex)
1367c478bd9Sstevel@tonic-gate {
1377c478bd9Sstevel@tonic-gate     int ret = SASL_BADPARAM;
1387c478bd9Sstevel@tonic-gate 
1397c478bd9Sstevel@tonic-gate     if (mutex != NULL)
1407c478bd9Sstevel@tonic-gate 	ret = pthread_mutex_lock((pthread_mutex_t *)mutex);
1417c478bd9Sstevel@tonic-gate 
1427c478bd9Sstevel@tonic-gate     return ret;
1437c478bd9Sstevel@tonic-gate }
1447c478bd9Sstevel@tonic-gate 
sasl_mutex_unlock(void * mutex)1457c478bd9Sstevel@tonic-gate static int sasl_mutex_unlock(void *mutex)
1467c478bd9Sstevel@tonic-gate {
1477c478bd9Sstevel@tonic-gate     int ret = SASL_BADPARAM;
1487c478bd9Sstevel@tonic-gate 
1497c478bd9Sstevel@tonic-gate     if (mutex != NULL)
1507c478bd9Sstevel@tonic-gate 	ret = pthread_mutex_unlock((pthread_mutex_t *)mutex);
1517c478bd9Sstevel@tonic-gate 
1527c478bd9Sstevel@tonic-gate     return ret;
1537c478bd9Sstevel@tonic-gate }
1547c478bd9Sstevel@tonic-gate 
sasl_mutex_free(void * mutex)1557c478bd9Sstevel@tonic-gate static void sasl_mutex_free(void *mutex __attribute__((unused)))
1567c478bd9Sstevel@tonic-gate {
1577c478bd9Sstevel@tonic-gate   if (mutex != NULL) {
1587c478bd9Sstevel@tonic-gate      pthread_mutex_destroy((pthread_mutex_t *)mutex);
1597c478bd9Sstevel@tonic-gate      free(mutex);
1607c478bd9Sstevel@tonic-gate   }
1617c478bd9Sstevel@tonic-gate }
1627c478bd9Sstevel@tonic-gate #else
1637c478bd9Sstevel@tonic-gate /* Intenal mutex functions do as little as possible (no thread protection) */
sasl_mutex_alloc(void)1647c478bd9Sstevel@tonic-gate static void *sasl_mutex_alloc(void)
1657c478bd9Sstevel@tonic-gate {
1667c478bd9Sstevel@tonic-gate   return (void *)0x1;
1677c478bd9Sstevel@tonic-gate }
1687c478bd9Sstevel@tonic-gate 
sasl_mutex_lock(void * mutex)1697c478bd9Sstevel@tonic-gate static int sasl_mutex_lock(void *mutex __attribute__((unused)))
1707c478bd9Sstevel@tonic-gate {
1717c478bd9Sstevel@tonic-gate     return SASL_OK;
1727c478bd9Sstevel@tonic-gate }
1737c478bd9Sstevel@tonic-gate 
sasl_mutex_unlock(void * mutex)1747c478bd9Sstevel@tonic-gate static int sasl_mutex_unlock(void *mutex __attribute__((unused)))
1757c478bd9Sstevel@tonic-gate {
1767c478bd9Sstevel@tonic-gate     return SASL_OK;
1777c478bd9Sstevel@tonic-gate }
1787c478bd9Sstevel@tonic-gate 
sasl_mutex_free(void * mutex)1797c478bd9Sstevel@tonic-gate static void sasl_mutex_free(void *mutex __attribute__((unused)))
1807c478bd9Sstevel@tonic-gate {
1817c478bd9Sstevel@tonic-gate     return;
1827c478bd9Sstevel@tonic-gate }
1837c478bd9Sstevel@tonic-gate #endif /* USE_PTHREADS */
1847c478bd9Sstevel@tonic-gate 
1857c478bd9Sstevel@tonic-gate #ifndef _SUN_SDK_
1867c478bd9Sstevel@tonic-gate sasl_mutex_utils_t _sasl_mutex_utils={
1877c478bd9Sstevel@tonic-gate   &sasl_mutex_alloc,
1887c478bd9Sstevel@tonic-gate   &sasl_mutex_lock,
1897c478bd9Sstevel@tonic-gate   &sasl_mutex_unlock,
1907c478bd9Sstevel@tonic-gate   &sasl_mutex_free
1917c478bd9Sstevel@tonic-gate };
1927c478bd9Sstevel@tonic-gate #endif /* !_SUN_SDK_ */
1937c478bd9Sstevel@tonic-gate 
sasl_set_mutex(sasl_mutex_alloc_t * n,sasl_mutex_lock_t * l,sasl_mutex_unlock_t * u,sasl_mutex_free_t * d)1947c478bd9Sstevel@tonic-gate void sasl_set_mutex(sasl_mutex_alloc_t *n, sasl_mutex_lock_t *l,
1957c478bd9Sstevel@tonic-gate 		    sasl_mutex_unlock_t *u, sasl_mutex_free_t *d)
1967c478bd9Sstevel@tonic-gate {
1977c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_
1987c478bd9Sstevel@tonic-gate   _sasl_global_context_t *gctx =  _sasl_gbl_ctx();
1997c478bd9Sstevel@tonic-gate 
2007c478bd9Sstevel@tonic-gate   gctx->sasl_mutex_utils.alloc=n;
2017c478bd9Sstevel@tonic-gate   gctx->sasl_mutex_utils.lock=l;
2027c478bd9Sstevel@tonic-gate   gctx->sasl_mutex_utils.unlock=u;
2037c478bd9Sstevel@tonic-gate   gctx->sasl_mutex_utils.free=d;
2047c478bd9Sstevel@tonic-gate #else
2057c478bd9Sstevel@tonic-gate   _sasl_mutex_utils.alloc=n;
2067c478bd9Sstevel@tonic-gate   _sasl_mutex_utils.lock=l;
2077c478bd9Sstevel@tonic-gate   _sasl_mutex_utils.unlock=u;
2087c478bd9Sstevel@tonic-gate   _sasl_mutex_utils.free=d;
2097c478bd9Sstevel@tonic-gate #endif
2107c478bd9Sstevel@tonic-gate }
2117c478bd9Sstevel@tonic-gate 
2127c478bd9Sstevel@tonic-gate /* copy a string to malloced memory */
2137c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_
__sasl_strdup(const _sasl_global_context_t * gctx,const char * in,char ** out,size_t * outlen)2147c478bd9Sstevel@tonic-gate int __sasl_strdup(const _sasl_global_context_t *gctx, const char *in,
2157c478bd9Sstevel@tonic-gate 	char **out, size_t *outlen)
2167c478bd9Sstevel@tonic-gate #else
2177c478bd9Sstevel@tonic-gate int _sasl_strdup(const char *in, char **out, size_t *outlen)
2187c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */
2197c478bd9Sstevel@tonic-gate {
2207c478bd9Sstevel@tonic-gate   size_t len = strlen(in);
2217c478bd9Sstevel@tonic-gate   if (outlen) *outlen = len;
2227c478bd9Sstevel@tonic-gate   *out=sasl_ALLOC(len + 1);
2237c478bd9Sstevel@tonic-gate   if (! *out) return SASL_NOMEM;
2247c478bd9Sstevel@tonic-gate   strcpy((char *) *out, in);
2257c478bd9Sstevel@tonic-gate   return SASL_OK;
2267c478bd9Sstevel@tonic-gate }
2277c478bd9Sstevel@tonic-gate 
2287c478bd9Sstevel@tonic-gate /* adds a string to the buffer; reallocing if need be */
2297c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_
__sasl_add_string(const _sasl_global_context_t * gctx,char ** out,size_t * alloclen,size_t * outlen,const char * add)2307c478bd9Sstevel@tonic-gate int __sasl_add_string(const _sasl_global_context_t *gctx, char **out,
2317c478bd9Sstevel@tonic-gate 		     size_t *alloclen, size_t *outlen,
2327c478bd9Sstevel@tonic-gate 		     const char *add)
2337c478bd9Sstevel@tonic-gate #else
2347c478bd9Sstevel@tonic-gate int _sasl_add_string(char **out, size_t *alloclen,
2357c478bd9Sstevel@tonic-gate 		     size_t *outlen, const char *add)
2367c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */
2377c478bd9Sstevel@tonic-gate {
2387c478bd9Sstevel@tonic-gate   size_t addlen;
2397c478bd9Sstevel@tonic-gate 
2407c478bd9Sstevel@tonic-gate   if (add==NULL) add = "(null)";
2417c478bd9Sstevel@tonic-gate 
2427c478bd9Sstevel@tonic-gate   addlen=strlen(add); /* only compute once */
2437c478bd9Sstevel@tonic-gate   if (_buf_alloc(out, alloclen, (*outlen)+addlen)!=SASL_OK)
2447c478bd9Sstevel@tonic-gate     return SASL_NOMEM;
2457c478bd9Sstevel@tonic-gate 
2467c478bd9Sstevel@tonic-gate   strncpy(*out + *outlen, add, addlen);
2477c478bd9Sstevel@tonic-gate   *outlen += addlen;
2487c478bd9Sstevel@tonic-gate 
2497c478bd9Sstevel@tonic-gate   return SASL_OK;
2507c478bd9Sstevel@tonic-gate }
2517c478bd9Sstevel@tonic-gate 
2527c478bd9Sstevel@tonic-gate /* return the version of the cyrus sasl library as compiled,
2537c478bd9Sstevel@tonic-gate  * using 32 bits: high byte is major version, second byte is minor version,
2547c478bd9Sstevel@tonic-gate  * low 16 bits are step # */
sasl_version(const char ** implementation,int * version)2557c478bd9Sstevel@tonic-gate void sasl_version(const char **implementation, int *version)
2567c478bd9Sstevel@tonic-gate {
2577c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_
2587c478bd9Sstevel@tonic-gate     const char *implementation_string = "Sun SASL";
2597c478bd9Sstevel@tonic-gate #else
2607c478bd9Sstevel@tonic-gate     const char *implementation_string = "Cyrus SASL";
2617c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */
2627c478bd9Sstevel@tonic-gate     if(implementation) *implementation = implementation_string;
2637c478bd9Sstevel@tonic-gate     if(version) *version = (SASL_VERSION_MAJOR << 24) |
2647c478bd9Sstevel@tonic-gate 		           (SASL_VERSION_MINOR << 16) |
2657c478bd9Sstevel@tonic-gate 		           (SASL_VERSION_STEP);
2667c478bd9Sstevel@tonic-gate }
2677c478bd9Sstevel@tonic-gate 
2687c478bd9Sstevel@tonic-gate /* security-encode a regular string.  Mostly a wrapper for sasl_encodev */
2697c478bd9Sstevel@tonic-gate /* output is only valid until next call to sasl_encode or sasl_encodev */
sasl_encode(sasl_conn_t * conn,const char * input,unsigned inputlen,const char ** output,unsigned * outputlen)2707c478bd9Sstevel@tonic-gate int sasl_encode(sasl_conn_t *conn, const char *input,
2717c478bd9Sstevel@tonic-gate 		unsigned inputlen,
2727c478bd9Sstevel@tonic-gate 		const char **output, unsigned *outputlen)
2737c478bd9Sstevel@tonic-gate {
2747c478bd9Sstevel@tonic-gate     int result;
2757c478bd9Sstevel@tonic-gate     struct iovec tmp;
2767c478bd9Sstevel@tonic-gate 
2777c478bd9Sstevel@tonic-gate     if(!conn) return SASL_BADPARAM;
2787c478bd9Sstevel@tonic-gate     if(!input || !inputlen || !output || !outputlen)
2797c478bd9Sstevel@tonic-gate 	PARAMERROR(conn);
2807c478bd9Sstevel@tonic-gate 
2817c478bd9Sstevel@tonic-gate     /* maxoutbuf checking is done in sasl_encodev */
2827c478bd9Sstevel@tonic-gate 
2837c478bd9Sstevel@tonic-gate     /* Note: We are casting a const pointer here, but it's okay
2847c478bd9Sstevel@tonic-gate      * because we believe people downstream of us are well-behaved, and the
2857c478bd9Sstevel@tonic-gate      * alternative is an absolute mess, performance-wise. */
2867c478bd9Sstevel@tonic-gate     tmp.iov_base = (void *)input;
2877c478bd9Sstevel@tonic-gate     tmp.iov_len = inputlen;
2887c478bd9Sstevel@tonic-gate 
2897c478bd9Sstevel@tonic-gate     result = sasl_encodev(conn, &tmp, 1, output, outputlen);
2907c478bd9Sstevel@tonic-gate 
2917c478bd9Sstevel@tonic-gate     RETURN(conn, result);
2927c478bd9Sstevel@tonic-gate }
2937c478bd9Sstevel@tonic-gate 
2947c478bd9Sstevel@tonic-gate /* security-encode an iovec */
2957c478bd9Sstevel@tonic-gate /* output is only valid until next call to sasl_encode or sasl_encodev */
sasl_encodev(sasl_conn_t * conn,const struct iovec * invec,unsigned numiov,const char ** output,unsigned * outputlen)2967c478bd9Sstevel@tonic-gate int sasl_encodev(sasl_conn_t *conn,
2977c478bd9Sstevel@tonic-gate 		 const struct iovec *invec, unsigned numiov,
2987c478bd9Sstevel@tonic-gate 		 const char **output, unsigned *outputlen)
2997c478bd9Sstevel@tonic-gate {
3007c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_
3017c478bd9Sstevel@tonic-gate     int result = SASL_FAIL;
3027c478bd9Sstevel@tonic-gate #else
3037c478bd9Sstevel@tonic-gate     int result;
3047c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */
3057c478bd9Sstevel@tonic-gate     unsigned i;
3067c478bd9Sstevel@tonic-gate     size_t total_size = 0;
3077c478bd9Sstevel@tonic-gate 
3087c478bd9Sstevel@tonic-gate     if (!conn) return SASL_BADPARAM;
3097c478bd9Sstevel@tonic-gate     if (! invec || ! output || ! outputlen || numiov < 1)
3107c478bd9Sstevel@tonic-gate 	PARAMERROR(conn);
3117c478bd9Sstevel@tonic-gate 
3127c478bd9Sstevel@tonic-gate     if(!conn->props.maxbufsize) {
3137c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_
3147c478bd9Sstevel@tonic-gate 	_sasl_log(conn, SASL_LOG_ERR,
3157c478bd9Sstevel@tonic-gate 		  "called sasl_encode[v] with application that does not support security layers");
3167c478bd9Sstevel@tonic-gate #else
3177c478bd9Sstevel@tonic-gate 	sasl_seterror(conn, 0,
3187c478bd9Sstevel@tonic-gate 		      "called sasl_encode[v] with application that does not support security layers");
3197c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */
3207c478bd9Sstevel@tonic-gate 	return SASL_TOOWEAK;
3217c478bd9Sstevel@tonic-gate     }
3227c478bd9Sstevel@tonic-gate 
3237c478bd9Sstevel@tonic-gate     /* This might be better to check on a per-plugin basis, but I think
3247c478bd9Sstevel@tonic-gate      * it's cleaner and more effective here.  It also encourages plugins
3257c478bd9Sstevel@tonic-gate      * to be honest about what they accept */
3267c478bd9Sstevel@tonic-gate 
3277c478bd9Sstevel@tonic-gate     for(i=0; i<numiov;i++) {
3287c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_
3297c478bd9Sstevel@tonic-gate 	if (invec[i].iov_base == NULL)
3307c478bd9Sstevel@tonic-gate 	    PARAMERROR(conn);
3317c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */
3327c478bd9Sstevel@tonic-gate 	total_size += invec[i].iov_len;
3337c478bd9Sstevel@tonic-gate     }
3347c478bd9Sstevel@tonic-gate     if(total_size > conn->oparams.maxoutbuf)
3357c478bd9Sstevel@tonic-gate 	PARAMERROR(conn);
3367c478bd9Sstevel@tonic-gate 
3377c478bd9Sstevel@tonic-gate     if(conn->oparams.encode == NULL)  {
3387c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_
3397c478bd9Sstevel@tonic-gate 	result = _iovec_to_buf(conn->gctx, invec, numiov, &conn->encode_buf);
3407c478bd9Sstevel@tonic-gate #else
3417c478bd9Sstevel@tonic-gate 	result = _iovec_to_buf(invec, numiov, &conn->encode_buf);
3427c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */
3437c478bd9Sstevel@tonic-gate 	if(result != SASL_OK) INTERROR(conn, result);
3447c478bd9Sstevel@tonic-gate 
3457c478bd9Sstevel@tonic-gate 	*output = conn->encode_buf->data;
3467c478bd9Sstevel@tonic-gate 	*outputlen = conn->encode_buf->curlen;
3477c478bd9Sstevel@tonic-gate 
3487c478bd9Sstevel@tonic-gate #ifdef _INTEGRATED_SOLARIS_
3497c478bd9Sstevel@tonic-gate     } else if (!conn->sun_reg) {
3507c478bd9Sstevel@tonic-gate 	    INTERROR(conn, SASL_FAIL);
3517c478bd9Sstevel@tonic-gate #endif /* _INTEGRATED_SOLARIS_ */
3527c478bd9Sstevel@tonic-gate     } else {
3537c478bd9Sstevel@tonic-gate 	result = conn->oparams.encode(conn->context, invec, numiov,
3547c478bd9Sstevel@tonic-gate 				      output, outputlen);
3557c478bd9Sstevel@tonic-gate     }
3567c478bd9Sstevel@tonic-gate 
3577c478bd9Sstevel@tonic-gate     RETURN(conn, result);
3587c478bd9Sstevel@tonic-gate }
3597c478bd9Sstevel@tonic-gate 
3607c478bd9Sstevel@tonic-gate /* output is only valid until next call to sasl_decode */
sasl_decode(sasl_conn_t * conn,const char * input,unsigned inputlen,const char ** output,unsigned * outputlen)3617c478bd9Sstevel@tonic-gate int sasl_decode(sasl_conn_t *conn,
3627c478bd9Sstevel@tonic-gate 		const char *input, unsigned inputlen,
3637c478bd9Sstevel@tonic-gate 		const char **output, unsigned *outputlen)
3647c478bd9Sstevel@tonic-gate {
3657c478bd9Sstevel@tonic-gate     int result;
3667c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_
3677c478bd9Sstevel@tonic-gate     const _sasl_global_context_t *gctx;
3687c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */
3697c478bd9Sstevel@tonic-gate 
3707c478bd9Sstevel@tonic-gate     if(!conn) return SASL_BADPARAM;
3717c478bd9Sstevel@tonic-gate     if(!input || !output || !outputlen)
3727c478bd9Sstevel@tonic-gate 	PARAMERROR(conn);
3737c478bd9Sstevel@tonic-gate 
3747c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_
3757c478bd9Sstevel@tonic-gate     gctx = conn->gctx;
3767c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */
3777c478bd9Sstevel@tonic-gate 
3787c478bd9Sstevel@tonic-gate     if(!conn->props.maxbufsize) {
3797c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_
3807c478bd9Sstevel@tonic-gate 	_sasl_log(conn, SASL_LOG_ERR,
3817c478bd9Sstevel@tonic-gate 		  "called sasl_decode with application that does not support security layers");
3827c478bd9Sstevel@tonic-gate #else
3837c478bd9Sstevel@tonic-gate 	sasl_seterror(conn, 0,
3847c478bd9Sstevel@tonic-gate 		      "called sasl_decode with application that does not support security layers");
3857c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */
3867c478bd9Sstevel@tonic-gate 	RETURN(conn, SASL_TOOWEAK);
3877c478bd9Sstevel@tonic-gate     }
3887c478bd9Sstevel@tonic-gate 
3897c478bd9Sstevel@tonic-gate     if(conn->oparams.decode == NULL)
3907c478bd9Sstevel@tonic-gate     {
3917c478bd9Sstevel@tonic-gate 	/* Since we know how long the output is maximally, we can
3927c478bd9Sstevel@tonic-gate 	 * just allocate it to begin with, and never need another
3937c478bd9Sstevel@tonic-gate          * allocation! */
3947c478bd9Sstevel@tonic-gate 
3957c478bd9Sstevel@tonic-gate 	/* However, if they pass us more than they actually can take,
3967c478bd9Sstevel@tonic-gate 	 * we cannot help them... */
3977c478bd9Sstevel@tonic-gate 	if(inputlen > conn->props.maxbufsize) {
3987c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_
3997c478bd9Sstevel@tonic-gate 	    _sasl_log(conn, SASL_LOG_ERR,
4007c478bd9Sstevel@tonic-gate 		      "input too large for default sasl_decode");
4017c478bd9Sstevel@tonic-gate #else
4027c478bd9Sstevel@tonic-gate 	    sasl_seterror(conn, 0,
4037c478bd9Sstevel@tonic-gate 			  "input too large for default sasl_decode");
4047c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */
4057c478bd9Sstevel@tonic-gate 	    RETURN(conn,SASL_BUFOVER);
4067c478bd9Sstevel@tonic-gate 	}
4077c478bd9Sstevel@tonic-gate 
4087c478bd9Sstevel@tonic-gate 	if(!conn->decode_buf)
4097c478bd9Sstevel@tonic-gate 	    conn->decode_buf = sasl_ALLOC(conn->props.maxbufsize + 1);
4107c478bd9Sstevel@tonic-gate 	if(!conn->decode_buf)
4117c478bd9Sstevel@tonic-gate 	    MEMERROR(conn);
4127c478bd9Sstevel@tonic-gate 
4137c478bd9Sstevel@tonic-gate 	memcpy(conn->decode_buf, input, inputlen);
4147c478bd9Sstevel@tonic-gate 	conn->decode_buf[inputlen] = '\0';
4157c478bd9Sstevel@tonic-gate 	*output = conn->decode_buf;
4167c478bd9Sstevel@tonic-gate 	*outputlen = inputlen;
4177c478bd9Sstevel@tonic-gate 
4187c478bd9Sstevel@tonic-gate         return SASL_OK;
4197c478bd9Sstevel@tonic-gate #ifdef _INTEGRATED_SOLARIS_
4207c478bd9Sstevel@tonic-gate     } else if (!conn->sun_reg) {
4217c478bd9Sstevel@tonic-gate 	    INTERROR(conn, SASL_FAIL);
4227c478bd9Sstevel@tonic-gate #endif /* _INTEGRATED_SOLARIS_ */
4237c478bd9Sstevel@tonic-gate     } else {
4247c478bd9Sstevel@tonic-gate         result = conn->oparams.decode(conn->context, input, inputlen,
4257c478bd9Sstevel@tonic-gate                                       output, outputlen);
4267c478bd9Sstevel@tonic-gate 
4277c478bd9Sstevel@tonic-gate 	/* NULL an empty buffer (for misbehaved applications) */
4287c478bd9Sstevel@tonic-gate 	if (*outputlen == 0) *output = NULL;
4297c478bd9Sstevel@tonic-gate 
4307c478bd9Sstevel@tonic-gate         RETURN(conn, result);
4317c478bd9Sstevel@tonic-gate     }
4327c478bd9Sstevel@tonic-gate 
4337c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_
4347c478bd9Sstevel@tonic-gate     return SASL_FAIL;
4357c478bd9Sstevel@tonic-gate #else
4367c478bd9Sstevel@tonic-gate     INTERROR(conn, SASL_FAIL);
4377c478bd9Sstevel@tonic-gate #endif	/* _SUN_SDK_ */
4387c478bd9Sstevel@tonic-gate }
4397c478bd9Sstevel@tonic-gate 
4407c478bd9Sstevel@tonic-gate 
4417c478bd9Sstevel@tonic-gate void
sasl_set_alloc(sasl_malloc_t * m,sasl_calloc_t * c,sasl_realloc_t * r,sasl_free_t * f)4427c478bd9Sstevel@tonic-gate sasl_set_alloc(sasl_malloc_t *m,
4437c478bd9Sstevel@tonic-gate 	       sasl_calloc_t *c,
4447c478bd9Sstevel@tonic-gate 	       sasl_realloc_t *r,
4457c478bd9Sstevel@tonic-gate 	       sasl_free_t *f)
4467c478bd9Sstevel@tonic-gate {
4477c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_
4487c478bd9Sstevel@tonic-gate   _sasl_global_context_t *gctx =  _sasl_gbl_ctx();
4497c478bd9Sstevel@tonic-gate 
4507c478bd9Sstevel@tonic-gate   LOCK_MUTEX(&malloc_global_mutex);
4517c478bd9Sstevel@tonic-gate   gctx->sasl_allocation_utils.malloc=m;
4527c478bd9Sstevel@tonic-gate   gctx->sasl_allocation_utils.calloc=c;
4537c478bd9Sstevel@tonic-gate   gctx->sasl_allocation_utils.realloc=r;
4547c478bd9Sstevel@tonic-gate   gctx->sasl_allocation_utils.free=f;
4557c478bd9Sstevel@tonic-gate   UNLOCK_MUTEX(&malloc_global_mutex);
4567c478bd9Sstevel@tonic-gate #else
4577c478bd9Sstevel@tonic-gate   _sasl_allocation_utils.malloc=m;
4587c478bd9Sstevel@tonic-gate   _sasl_allocation_utils.calloc=c;
4597c478bd9Sstevel@tonic-gate   _sasl_allocation_utils.realloc=r;
4607c478bd9Sstevel@tonic-gate   _sasl_allocation_utils.free=f;
4617c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */
4627c478bd9Sstevel@tonic-gate }
4637c478bd9Sstevel@tonic-gate 
sasl_done(void)4647c478bd9Sstevel@tonic-gate void sasl_done(void)
4657c478bd9Sstevel@tonic-gate {
4667c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_
4677c478bd9Sstevel@tonic-gate    _sasl_dispose_context(_sasl_gbl_ctx());
4687c478bd9Sstevel@tonic-gate #else
4697c478bd9Sstevel@tonic-gate     if (_sasl_server_cleanup_hook && _sasl_server_cleanup_hook() == SASL_OK) {
4707c478bd9Sstevel@tonic-gate 	_sasl_server_idle_hook = NULL;
4717c478bd9Sstevel@tonic-gate 	_sasl_server_cleanup_hook = NULL;
4727c478bd9Sstevel@tonic-gate     }
4737c478bd9Sstevel@tonic-gate 
4747c478bd9Sstevel@tonic-gate     if (_sasl_client_cleanup_hook && _sasl_client_cleanup_hook() == SASL_OK) {
4757c478bd9Sstevel@tonic-gate 	_sasl_client_idle_hook = NULL;
4767c478bd9Sstevel@tonic-gate 	_sasl_client_cleanup_hook = NULL;
4777c478bd9Sstevel@tonic-gate     }
4787c478bd9Sstevel@tonic-gate 
4797c478bd9Sstevel@tonic-gate     if(_sasl_server_cleanup_hook || _sasl_client_cleanup_hook)
4807c478bd9Sstevel@tonic-gate 	return;
4817c478bd9Sstevel@tonic-gate 
4827c478bd9Sstevel@tonic-gate 
4837c478bd9Sstevel@tonic-gate     _sasl_canonuser_free();
4847c478bd9Sstevel@tonic-gate     _sasl_done_with_plugins();
4857c478bd9Sstevel@tonic-gate 
4867c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_
4877c478bd9Sstevel@tonic-gate     sasl_config_free();
4887c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */
4897c478bd9Sstevel@tonic-gate 
4907c478bd9Sstevel@tonic-gate     sasl_MUTEX_FREE(free_mutex);
4917c478bd9Sstevel@tonic-gate     free_mutex = NULL;
4927c478bd9Sstevel@tonic-gate 
4937c478bd9Sstevel@tonic-gate     _sasl_free_utils(&sasl_global_utils);
4947c478bd9Sstevel@tonic-gate 
4957c478bd9Sstevel@tonic-gate     if(global_mech_list) sasl_FREE(global_mech_list);
4967c478bd9Sstevel@tonic-gate     global_mech_list = NULL;
4977c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */
4987c478bd9Sstevel@tonic-gate }
4997c478bd9Sstevel@tonic-gate 
5007c478bd9Sstevel@tonic-gate /* fills in the base sasl_conn_t info */
_sasl_conn_init(sasl_conn_t * conn,const char * service,unsigned int flags,enum Sasl_conn_type type,int (* idle_hook)(sasl_conn_t * conn),const char * serverFQDN,const char * iplocalport,const char * ipremoteport,const sasl_callback_t * callbacks,const sasl_global_callbacks_t * global_callbacks)5017c478bd9Sstevel@tonic-gate int _sasl_conn_init(sasl_conn_t *conn,
5027c478bd9Sstevel@tonic-gate 		    const char *service,
5037c478bd9Sstevel@tonic-gate 		    unsigned int flags,
5047c478bd9Sstevel@tonic-gate 		    enum Sasl_conn_type type,
5057c478bd9Sstevel@tonic-gate 		    int (*idle_hook)(sasl_conn_t *conn),
5067c478bd9Sstevel@tonic-gate 		    const char *serverFQDN,
5077c478bd9Sstevel@tonic-gate 		    const char *iplocalport,
5087c478bd9Sstevel@tonic-gate 		    const char *ipremoteport,
5097c478bd9Sstevel@tonic-gate 		    const sasl_callback_t *callbacks,
5107c478bd9Sstevel@tonic-gate 		    const sasl_global_callbacks_t *global_callbacks) {
5117c478bd9Sstevel@tonic-gate   int result = SASL_OK;
5127c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_
5137c478bd9Sstevel@tonic-gate   const _sasl_global_context_t *gctx = conn->gctx;
5147c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */
5157c478bd9Sstevel@tonic-gate 
5167c478bd9Sstevel@tonic-gate   conn->type = type;
5177c478bd9Sstevel@tonic-gate 
5187c478bd9Sstevel@tonic-gate   result = _sasl_strdup(service, &conn->service, NULL);
5197c478bd9Sstevel@tonic-gate   if (result != SASL_OK)
5207c478bd9Sstevel@tonic-gate       MEMERROR(conn);
5217c478bd9Sstevel@tonic-gate 
5227c478bd9Sstevel@tonic-gate   memset(&conn->oparams, 0, sizeof(sasl_out_params_t));
5237c478bd9Sstevel@tonic-gate   memset(&conn->external, 0, sizeof(_sasl_external_properties_t));
5247c478bd9Sstevel@tonic-gate 
5257c478bd9Sstevel@tonic-gate   conn->flags = flags;
5267c478bd9Sstevel@tonic-gate 
5277c478bd9Sstevel@tonic-gate   result = sasl_setprop(conn, SASL_IPLOCALPORT, iplocalport);
5287c478bd9Sstevel@tonic-gate   if(result != SASL_OK)
5297c478bd9Sstevel@tonic-gate       RETURN(conn, result);
5307c478bd9Sstevel@tonic-gate 
5317c478bd9Sstevel@tonic-gate   result = sasl_setprop(conn, SASL_IPREMOTEPORT, ipremoteport);
5327c478bd9Sstevel@tonic-gate   if(result != SASL_OK)
5337c478bd9Sstevel@tonic-gate       RETURN(conn, result);
5347c478bd9Sstevel@tonic-gate 
5357c478bd9Sstevel@tonic-gate   conn->encode_buf = NULL;
5367c478bd9Sstevel@tonic-gate   conn->context = NULL;
5377c478bd9Sstevel@tonic-gate #ifndef _SUN_SDK_
5387c478bd9Sstevel@tonic-gate   conn->secret = NULL;
5397c478bd9Sstevel@tonic-gate #endif /* !_SUN_SDK_ */
5407c478bd9Sstevel@tonic-gate   conn->idle_hook = idle_hook;
5417c478bd9Sstevel@tonic-gate   conn->callbacks = callbacks;
5427c478bd9Sstevel@tonic-gate   conn->global_callbacks = global_callbacks;
5437c478bd9Sstevel@tonic-gate 
5447c478bd9Sstevel@tonic-gate   memset(&conn->props, 0, sizeof(conn->props));
5457c478bd9Sstevel@tonic-gate 
5467c478bd9Sstevel@tonic-gate   /* Start this buffer out as an empty string */
5477c478bd9Sstevel@tonic-gate   conn->error_code = SASL_OK;
5487c478bd9Sstevel@tonic-gate   conn->errdetail_buf = conn->error_buf = NULL;
5497c478bd9Sstevel@tonic-gate   conn->errdetail_buf_len = conn->error_buf_len = 150;
5507c478bd9Sstevel@tonic-gate 
5517c478bd9Sstevel@tonic-gate   result = _buf_alloc(&conn->error_buf, &conn->error_buf_len, 150);
5527c478bd9Sstevel@tonic-gate   if(result != SASL_OK) MEMERROR(conn);
5537c478bd9Sstevel@tonic-gate   result = _buf_alloc(&conn->errdetail_buf, &conn->errdetail_buf_len, 150);
5547c478bd9Sstevel@tonic-gate   if(result != SASL_OK) MEMERROR(conn);
5557c478bd9Sstevel@tonic-gate 
5567c478bd9Sstevel@tonic-gate   conn->error_buf[0] = '\0';
5577c478bd9Sstevel@tonic-gate   conn->errdetail_buf[0] = '\0';
5587c478bd9Sstevel@tonic-gate 
5597c478bd9Sstevel@tonic-gate   conn->decode_buf = NULL;
5607c478bd9Sstevel@tonic-gate 
5617c478bd9Sstevel@tonic-gate   if(serverFQDN) {
5627c478bd9Sstevel@tonic-gate       result = _sasl_strdup(serverFQDN, &conn->serverFQDN, NULL);
5637c478bd9Sstevel@tonic-gate   } else if (conn->type == SASL_CONN_SERVER) {
5647c478bd9Sstevel@tonic-gate       /* We can fake it because we *are* the server */
5657c478bd9Sstevel@tonic-gate       char name[MAXHOSTNAMELEN];
5667c478bd9Sstevel@tonic-gate       memset(name, 0, sizeof(name));
5677c478bd9Sstevel@tonic-gate       gethostname(name, MAXHOSTNAMELEN);
5687c478bd9Sstevel@tonic-gate 
5697c478bd9Sstevel@tonic-gate       result = _sasl_strdup(name, &conn->serverFQDN, NULL);
5707c478bd9Sstevel@tonic-gate   } else {
5717c478bd9Sstevel@tonic-gate       conn->serverFQDN = NULL;
5727c478bd9Sstevel@tonic-gate   }
5737c478bd9Sstevel@tonic-gate 
5747c478bd9Sstevel@tonic-gate 
5757c478bd9Sstevel@tonic-gate   if(result != SASL_OK) MEMERROR( conn );
5767c478bd9Sstevel@tonic-gate 
5777c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_
5787c478bd9Sstevel@tonic-gate   return (SASL_OK);
5797c478bd9Sstevel@tonic-gate #else
5807c478bd9Sstevel@tonic-gate   RETURN(conn, SASL_OK);
5817c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */
5827c478bd9Sstevel@tonic-gate }
5837c478bd9Sstevel@tonic-gate 
5847c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_
_sasl_common_init(_sasl_global_context_t * gctx,sasl_global_callbacks_t * global_callbacks,int server)5857c478bd9Sstevel@tonic-gate int _sasl_common_init(_sasl_global_context_t *gctx,
5867c478bd9Sstevel@tonic-gate 		      sasl_global_callbacks_t *global_callbacks,
5877c478bd9Sstevel@tonic-gate 		      int server)
5887c478bd9Sstevel@tonic-gate {
5897c478bd9Sstevel@tonic-gate     int result;
5907c478bd9Sstevel@tonic-gate     sasl_utils_t *sasl_global_utils;
5917c478bd9Sstevel@tonic-gate 
5927c478bd9Sstevel@tonic-gate     sasl_global_utils = (sasl_utils_t *)gctx->sasl_canonusr_global_utils;
5937c478bd9Sstevel@tonic-gate 
5947c478bd9Sstevel@tonic-gate     if(!sasl_global_utils) {
5957c478bd9Sstevel@tonic-gate         sasl_global_utils = _sasl_alloc_utils(gctx, NULL, global_callbacks);
5967c478bd9Sstevel@tonic-gate         if(sasl_global_utils == NULL) return SASL_NOMEM;
5977c478bd9Sstevel@tonic-gate 	gctx->sasl_canonusr_global_utils = sasl_global_utils;
5987c478bd9Sstevel@tonic-gate     }
5997c478bd9Sstevel@tonic-gate 
6007c478bd9Sstevel@tonic-gate     if (server) {
6017c478bd9Sstevel@tonic-gate 	sasl_global_utils = (sasl_utils_t *)gctx->sasl_server_global_utils;
6027c478bd9Sstevel@tonic-gate 
6037c478bd9Sstevel@tonic-gate 	if(!sasl_global_utils) {
6047c478bd9Sstevel@tonic-gate             sasl_global_utils = _sasl_alloc_utils(gctx, NULL, global_callbacks);
6057c478bd9Sstevel@tonic-gate             if(sasl_global_utils == NULL) return SASL_NOMEM;
6067c478bd9Sstevel@tonic-gate 	    gctx->sasl_server_global_utils = sasl_global_utils;
6077c478bd9Sstevel@tonic-gate 	}
6087c478bd9Sstevel@tonic-gate     }
6097c478bd9Sstevel@tonic-gate 
6107c478bd9Sstevel@tonic-gate     /* Init the canon_user plugin */
6117c478bd9Sstevel@tonic-gate     result = _sasl_canonuser_add_plugin(gctx, "INTERNAL",
6127c478bd9Sstevel@tonic-gate 	internal_canonuser_init);
6137c478bd9Sstevel@tonic-gate     if(result != SASL_OK) return result;
6147c478bd9Sstevel@tonic-gate 
6157c478bd9Sstevel@tonic-gate     if (!gctx->free_mutex)
6167c478bd9Sstevel@tonic-gate         gctx->free_mutex = sasl_MUTEX_ALLOC();
6177c478bd9Sstevel@tonic-gate     if (!gctx->free_mutex) return SASL_FAIL;
6187c478bd9Sstevel@tonic-gate 
6197c478bd9Sstevel@tonic-gate     return SASL_OK;
6207c478bd9Sstevel@tonic-gate }
6217c478bd9Sstevel@tonic-gate #else
_sasl_common_init(sasl_global_callbacks_t * global_callbacks)6227c478bd9Sstevel@tonic-gate int _sasl_common_init(sasl_global_callbacks_t *global_callbacks)
6237c478bd9Sstevel@tonic-gate {
6247c478bd9Sstevel@tonic-gate     int result;
6257c478bd9Sstevel@tonic-gate 
6267c478bd9Sstevel@tonic-gate     /* Setup the global utilities */
6277c478bd9Sstevel@tonic-gate     if(!sasl_global_utils) {
6287c478bd9Sstevel@tonic-gate 	sasl_global_utils = _sasl_alloc_utils(NULL, global_callbacks);
6297c478bd9Sstevel@tonic-gate 	if(sasl_global_utils == NULL) return SASL_NOMEM;
6307c478bd9Sstevel@tonic-gate     }
6317c478bd9Sstevel@tonic-gate 
6327c478bd9Sstevel@tonic-gate     /* Init the canon_user plugin */
6337c478bd9Sstevel@tonic-gate     result = sasl_canonuser_add_plugin("INTERNAL", internal_canonuser_init);
6347c478bd9Sstevel@tonic-gate     if(result != SASL_OK) return result;
6357c478bd9Sstevel@tonic-gate 
6367c478bd9Sstevel@tonic-gate     if (!free_mutex)
6377c478bd9Sstevel@tonic-gate 	free_mutex = sasl_MUTEX_ALLOC();
6387c478bd9Sstevel@tonic-gate     if (!free_mutex) return SASL_FAIL;
6397c478bd9Sstevel@tonic-gate 
6407c478bd9Sstevel@tonic-gate     return SASL_OK;
6417c478bd9Sstevel@tonic-gate }
6427c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */
6437c478bd9Sstevel@tonic-gate 
6447c478bd9Sstevel@tonic-gate /* dispose connection state, sets it to NULL
6457c478bd9Sstevel@tonic-gate  *  checks for pointer to NULL
6467c478bd9Sstevel@tonic-gate  */
sasl_dispose(sasl_conn_t ** pconn)6477c478bd9Sstevel@tonic-gate void sasl_dispose(sasl_conn_t **pconn)
6487c478bd9Sstevel@tonic-gate {
6497c478bd9Sstevel@tonic-gate   int result;
6507c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_
6517c478bd9Sstevel@tonic-gate   _sasl_global_context_t *gctx;
6527c478bd9Sstevel@tonic-gate   void *free_mutex;
6537c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */
6547c478bd9Sstevel@tonic-gate 
6557c478bd9Sstevel@tonic-gate   if (! pconn) return;
6567c478bd9Sstevel@tonic-gate   if (! *pconn) return;
6577c478bd9Sstevel@tonic-gate 
6587c478bd9Sstevel@tonic-gate   /* serialize disposes. this is necessary because we can't
6597c478bd9Sstevel@tonic-gate      dispose of conn->mutex if someone else is locked on it */
6607c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_
6617c478bd9Sstevel@tonic-gate   gctx = (*pconn)->gctx;
6627c478bd9Sstevel@tonic-gate   free_mutex = gctx->free_mutex;
6637c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */
6647c478bd9Sstevel@tonic-gate   result = sasl_MUTEX_LOCK(free_mutex);
6657c478bd9Sstevel@tonic-gate   if (result!=SASL_OK) return;
6667c478bd9Sstevel@tonic-gate 
6677c478bd9Sstevel@tonic-gate   /* *pconn might have become NULL by now */
6687c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_
6697c478bd9Sstevel@tonic-gate   if (! (*pconn)) {
6707c478bd9Sstevel@tonic-gate 	sasl_MUTEX_UNLOCK(free_mutex);
6717c478bd9Sstevel@tonic-gate 	return;
6727c478bd9Sstevel@tonic-gate   }
6737c478bd9Sstevel@tonic-gate #else
6747c478bd9Sstevel@tonic-gate   if (! (*pconn)) return;
6757c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */
6767c478bd9Sstevel@tonic-gate 
6777c478bd9Sstevel@tonic-gate   (*pconn)->destroy_conn(*pconn);
6787c478bd9Sstevel@tonic-gate   sasl_FREE(*pconn);
6797c478bd9Sstevel@tonic-gate   *pconn=NULL;
6807c478bd9Sstevel@tonic-gate 
6817c478bd9Sstevel@tonic-gate   sasl_MUTEX_UNLOCK(free_mutex);
6827c478bd9Sstevel@tonic-gate }
6837c478bd9Sstevel@tonic-gate 
_sasl_conn_dispose(sasl_conn_t * conn)6847c478bd9Sstevel@tonic-gate void _sasl_conn_dispose(sasl_conn_t *conn) {
6857c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_
6867c478bd9Sstevel@tonic-gate   const _sasl_global_context_t *gctx = conn->gctx;
6877c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */
6887c478bd9Sstevel@tonic-gate 
6897c478bd9Sstevel@tonic-gate   if (conn->serverFQDN)
6907c478bd9Sstevel@tonic-gate       sasl_FREE(conn->serverFQDN);
6917c478bd9Sstevel@tonic-gate 
6927c478bd9Sstevel@tonic-gate   if (conn->external.auth_id)
6937c478bd9Sstevel@tonic-gate       sasl_FREE(conn->external.auth_id);
6947c478bd9Sstevel@tonic-gate 
6957c478bd9Sstevel@tonic-gate   if(conn->encode_buf) {
6967c478bd9Sstevel@tonic-gate       if(conn->encode_buf->data) sasl_FREE(conn->encode_buf->data);
6977c478bd9Sstevel@tonic-gate       sasl_FREE(conn->encode_buf);
6987c478bd9Sstevel@tonic-gate   }
6997c478bd9Sstevel@tonic-gate 
7007c478bd9Sstevel@tonic-gate   if(conn->error_buf)
7017c478bd9Sstevel@tonic-gate       sasl_FREE(conn->error_buf);
7027c478bd9Sstevel@tonic-gate 
7037c478bd9Sstevel@tonic-gate   if(conn->errdetail_buf)
7047c478bd9Sstevel@tonic-gate       sasl_FREE(conn->errdetail_buf);
7057c478bd9Sstevel@tonic-gate 
7067c478bd9Sstevel@tonic-gate   if(conn->decode_buf)
7077c478bd9Sstevel@tonic-gate       sasl_FREE(conn->decode_buf);
7087c478bd9Sstevel@tonic-gate 
7097c478bd9Sstevel@tonic-gate   if(conn->mechlist_buf)
7107c478bd9Sstevel@tonic-gate       sasl_FREE(conn->mechlist_buf);
7117c478bd9Sstevel@tonic-gate 
7127c478bd9Sstevel@tonic-gate   if(conn->service)
7137c478bd9Sstevel@tonic-gate       sasl_FREE(conn->service);
7147c478bd9Sstevel@tonic-gate 
7157c478bd9Sstevel@tonic-gate   /* oparams sub-members should be freed by the plugin, in so much
7167c478bd9Sstevel@tonic-gate    * as they were allocated by the plugin */
7177c478bd9Sstevel@tonic-gate }
7187c478bd9Sstevel@tonic-gate 
7197c478bd9Sstevel@tonic-gate 
7207c478bd9Sstevel@tonic-gate /* get property from SASL connection state
7217c478bd9Sstevel@tonic-gate  *  propnum       -- property number
7227c478bd9Sstevel@tonic-gate  *  pvalue        -- pointer to value
7237c478bd9Sstevel@tonic-gate  * returns:
7247c478bd9Sstevel@tonic-gate  *  SASL_OK       -- no error
7257c478bd9Sstevel@tonic-gate  *  SASL_NOTDONE  -- property not available yet
7267c478bd9Sstevel@tonic-gate  *  SASL_BADPARAM -- bad property number
7277c478bd9Sstevel@tonic-gate  */
sasl_getprop(sasl_conn_t * conn,int propnum,const void ** pvalue)7287c478bd9Sstevel@tonic-gate int sasl_getprop(sasl_conn_t *conn, int propnum, const void **pvalue)
7297c478bd9Sstevel@tonic-gate {
7307c478bd9Sstevel@tonic-gate   int result = SASL_OK;
7317c478bd9Sstevel@tonic-gate   sasl_getopt_t *getopt;
7327c478bd9Sstevel@tonic-gate   void *context;
7337c478bd9Sstevel@tonic-gate 
7347c478bd9Sstevel@tonic-gate   if (! conn) return SASL_BADPARAM;
7357c478bd9Sstevel@tonic-gate   if (! pvalue) PARAMERROR(conn);
7367c478bd9Sstevel@tonic-gate 
7377c478bd9Sstevel@tonic-gate   switch(propnum)
7387c478bd9Sstevel@tonic-gate   {
7397c478bd9Sstevel@tonic-gate   case SASL_SSF:
7407c478bd9Sstevel@tonic-gate #ifdef _INTEGRATED_SOLARIS_
7417c478bd9Sstevel@tonic-gate       if (!conn->sun_reg)
7427c478bd9Sstevel@tonic-gate 	conn->oparams.mech_ssf = 0;
7437c478bd9Sstevel@tonic-gate #endif /* _INTEGRATED_SOLARIS_ */
7447c478bd9Sstevel@tonic-gate       *(sasl_ssf_t **)pvalue= &conn->oparams.mech_ssf;
7457c478bd9Sstevel@tonic-gate       break;
7467c478bd9Sstevel@tonic-gate   case SASL_MAXOUTBUF:
7477c478bd9Sstevel@tonic-gate       *(unsigned **)pvalue = &conn->oparams.maxoutbuf;
7487c478bd9Sstevel@tonic-gate       break;
7497c478bd9Sstevel@tonic-gate   case SASL_GETOPTCTX:
7507c478bd9Sstevel@tonic-gate       result = _sasl_getcallback(conn, SASL_CB_GETOPT, &getopt, &context);
7517c478bd9Sstevel@tonic-gate       if(result != SASL_OK) break;
7527c478bd9Sstevel@tonic-gate 
7537c478bd9Sstevel@tonic-gate       *(void **)pvalue = context;
7547c478bd9Sstevel@tonic-gate       break;
7557c478bd9Sstevel@tonic-gate   case SASL_CALLBACK:
7567c478bd9Sstevel@tonic-gate       *(const sasl_callback_t **)pvalue = conn->callbacks;
7577c478bd9Sstevel@tonic-gate       break;
7587c478bd9Sstevel@tonic-gate   case SASL_IPLOCALPORT:
7597c478bd9Sstevel@tonic-gate       if(conn->got_ip_local)
7607c478bd9Sstevel@tonic-gate 	  *(const char **)pvalue = conn->iplocalport;
7617c478bd9Sstevel@tonic-gate       else {
7627c478bd9Sstevel@tonic-gate 	  *(const char **)pvalue = NULL;
7637c478bd9Sstevel@tonic-gate 	  result = SASL_NOTDONE;
7647c478bd9Sstevel@tonic-gate       }
7657c478bd9Sstevel@tonic-gate       break;
7667c478bd9Sstevel@tonic-gate   case SASL_IPREMOTEPORT:
7677c478bd9Sstevel@tonic-gate       if(conn->got_ip_remote)
7687c478bd9Sstevel@tonic-gate 	  *(const char **)pvalue = conn->ipremoteport;
7697c478bd9Sstevel@tonic-gate       else {
7707c478bd9Sstevel@tonic-gate 	  *(const char **)pvalue = NULL;
7717c478bd9Sstevel@tonic-gate 	  result = SASL_NOTDONE;
7727c478bd9Sstevel@tonic-gate       }
7737c478bd9Sstevel@tonic-gate       break;
7747c478bd9Sstevel@tonic-gate   case SASL_USERNAME:
7757c478bd9Sstevel@tonic-gate       if(! conn->oparams.user)
7767c478bd9Sstevel@tonic-gate 	  result = SASL_NOTDONE;
7777c478bd9Sstevel@tonic-gate       else
7787c478bd9Sstevel@tonic-gate 	  *((const char **)pvalue) = conn->oparams.user;
7797c478bd9Sstevel@tonic-gate       break;
7807c478bd9Sstevel@tonic-gate   case SASL_AUTHUSER:
7817c478bd9Sstevel@tonic-gate       if(! conn->oparams.authid)
7827c478bd9Sstevel@tonic-gate 	  result = SASL_NOTDONE;
7837c478bd9Sstevel@tonic-gate       else
7847c478bd9Sstevel@tonic-gate 	  *((const char **)pvalue) = conn->oparams.authid;
7857c478bd9Sstevel@tonic-gate       break;
7867c478bd9Sstevel@tonic-gate   case SASL_SERVERFQDN:
7877c478bd9Sstevel@tonic-gate       *((const char **)pvalue) = conn->serverFQDN;
7887c478bd9Sstevel@tonic-gate       break;
7897c478bd9Sstevel@tonic-gate   case SASL_DEFUSERREALM:
7907c478bd9Sstevel@tonic-gate       if(conn->type != SASL_CONN_SERVER) result = SASL_BADPROT;
7917c478bd9Sstevel@tonic-gate       else
7927c478bd9Sstevel@tonic-gate 	  *((const char **)pvalue) = ((sasl_server_conn_t *)conn)->user_realm;
7937c478bd9Sstevel@tonic-gate       break;
7947c478bd9Sstevel@tonic-gate   case SASL_SERVICE:
7957c478bd9Sstevel@tonic-gate       *((const char **)pvalue) = conn->service;
7967c478bd9Sstevel@tonic-gate       break;
7977c478bd9Sstevel@tonic-gate   case SASL_AUTHSOURCE: /* name of plugin (not name of mech) */
7987c478bd9Sstevel@tonic-gate       if(conn->type == SASL_CONN_CLIENT) {
7997c478bd9Sstevel@tonic-gate 	  if(!((sasl_client_conn_t *)conn)->mech) {
8007c478bd9Sstevel@tonic-gate 	      result = SASL_NOTDONE;
8017c478bd9Sstevel@tonic-gate 	      break;
8027c478bd9Sstevel@tonic-gate 	  }
8037c478bd9Sstevel@tonic-gate 	  *((const char **)pvalue) =
8047c478bd9Sstevel@tonic-gate 	      ((sasl_client_conn_t *)conn)->mech->plugname;
8057c478bd9Sstevel@tonic-gate       } else if (conn->type == SASL_CONN_SERVER) {
8067c478bd9Sstevel@tonic-gate 	  if(!((sasl_server_conn_t *)conn)->mech) {
8077c478bd9Sstevel@tonic-gate 	      result = SASL_NOTDONE;
8087c478bd9Sstevel@tonic-gate 	      break;
8097c478bd9Sstevel@tonic-gate 	  }
8107c478bd9Sstevel@tonic-gate 	  *((const char **)pvalue) =
8117c478bd9Sstevel@tonic-gate 	      ((sasl_server_conn_t *)conn)->mech->plugname;
8127c478bd9Sstevel@tonic-gate       } else {
8137c478bd9Sstevel@tonic-gate 	  result = SASL_BADPARAM;
8147c478bd9Sstevel@tonic-gate       }
8157c478bd9Sstevel@tonic-gate       break;
8167c478bd9Sstevel@tonic-gate   case SASL_MECHNAME: /* name of mech */
8177c478bd9Sstevel@tonic-gate       if(conn->type == SASL_CONN_CLIENT) {
8187c478bd9Sstevel@tonic-gate 	  if(!((sasl_client_conn_t *)conn)->mech) {
8197c478bd9Sstevel@tonic-gate 	      result = SASL_NOTDONE;
8207c478bd9Sstevel@tonic-gate 	      break;
8217c478bd9Sstevel@tonic-gate 	  }
8227c478bd9Sstevel@tonic-gate 	  *((const char **)pvalue) =
8237c478bd9Sstevel@tonic-gate 	      ((sasl_client_conn_t *)conn)->mech->plug->mech_name;
8247c478bd9Sstevel@tonic-gate       } else if (conn->type == SASL_CONN_SERVER) {
8257c478bd9Sstevel@tonic-gate 	  if(!((sasl_server_conn_t *)conn)->mech) {
8267c478bd9Sstevel@tonic-gate 	      result = SASL_NOTDONE;
8277c478bd9Sstevel@tonic-gate 	      break;
8287c478bd9Sstevel@tonic-gate 	  }
8297c478bd9Sstevel@tonic-gate 	  *((const char **)pvalue) =
8307c478bd9Sstevel@tonic-gate 	      ((sasl_server_conn_t *)conn)->mech->plug->mech_name;
8317c478bd9Sstevel@tonic-gate       } else {
8327c478bd9Sstevel@tonic-gate 	  result = SASL_BADPARAM;
8337c478bd9Sstevel@tonic-gate       }
8347c478bd9Sstevel@tonic-gate 
8357c478bd9Sstevel@tonic-gate       if(!(*pvalue) && result == SASL_OK) result = SASL_NOTDONE;
8367c478bd9Sstevel@tonic-gate       break;
8377c478bd9Sstevel@tonic-gate   case SASL_PLUGERR:
8387c478bd9Sstevel@tonic-gate       *((const char **)pvalue) = conn->error_buf;
8397c478bd9Sstevel@tonic-gate       break;
8407c478bd9Sstevel@tonic-gate   case SASL_SSF_EXTERNAL:
8417c478bd9Sstevel@tonic-gate       *((const sasl_ssf_t **)pvalue) = &conn->external.ssf;
8427c478bd9Sstevel@tonic-gate       break;
8437c478bd9Sstevel@tonic-gate   case SASL_AUTH_EXTERNAL:
8447c478bd9Sstevel@tonic-gate       *((const char **)pvalue) = conn->external.auth_id;
8457c478bd9Sstevel@tonic-gate       break;
8467c478bd9Sstevel@tonic-gate   case SASL_SEC_PROPS:
8477c478bd9Sstevel@tonic-gate       *((const sasl_security_properties_t **)pvalue) = &conn->props;
8487c478bd9Sstevel@tonic-gate       break;
8497c478bd9Sstevel@tonic-gate   default:
8507c478bd9Sstevel@tonic-gate       result = SASL_BADPARAM;
8517c478bd9Sstevel@tonic-gate   }
8527c478bd9Sstevel@tonic-gate 
8537c478bd9Sstevel@tonic-gate   if(result == SASL_BADPARAM) {
8547c478bd9Sstevel@tonic-gate       PARAMERROR(conn);
8557c478bd9Sstevel@tonic-gate   } else if(result == SASL_NOTDONE) {
8567c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_
8577c478bd9Sstevel@tonic-gate       _sasl_log(conn, SASL_LOG_NONE,
8587c478bd9Sstevel@tonic-gate 		"Information that was requested is not yet available.");
8597c478bd9Sstevel@tonic-gate #else
8607c478bd9Sstevel@tonic-gate       sasl_seterror(conn, SASL_NOLOG,
8617c478bd9Sstevel@tonic-gate 		    "Information that was requested is not yet available.");
8627c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */
8637c478bd9Sstevel@tonic-gate       RETURN(conn, result);
8647c478bd9Sstevel@tonic-gate   } else if(result != SASL_OK) {
8657c478bd9Sstevel@tonic-gate       INTERROR(conn, result);
8667c478bd9Sstevel@tonic-gate   } else
8677c478bd9Sstevel@tonic-gate       RETURN(conn, result);
8687c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_
8697c478bd9Sstevel@tonic-gate   return SASL_OK;
8707c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */
8717c478bd9Sstevel@tonic-gate }
8727c478bd9Sstevel@tonic-gate 
8737c478bd9Sstevel@tonic-gate /* set property in SASL connection state
8747c478bd9Sstevel@tonic-gate  * returns:
8757c478bd9Sstevel@tonic-gate  *  SASL_OK       -- value set
8767c478bd9Sstevel@tonic-gate  *  SASL_BADPARAM -- invalid property or value
8777c478bd9Sstevel@tonic-gate  */
sasl_setprop(sasl_conn_t * conn,int propnum,const void * value)8787c478bd9Sstevel@tonic-gate int sasl_setprop(sasl_conn_t *conn, int propnum, const void *value)
8797c478bd9Sstevel@tonic-gate {
8807c478bd9Sstevel@tonic-gate   int result = SASL_OK;
8817c478bd9Sstevel@tonic-gate   char *str;
8827c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_
8837c478bd9Sstevel@tonic-gate   const _sasl_global_context_t *gctx;
8847c478bd9Sstevel@tonic-gate #endif	/* _SUN_SDK_ */
8857c478bd9Sstevel@tonic-gate 
8867c478bd9Sstevel@tonic-gate   /* make sure the sasl context is valid */
8877c478bd9Sstevel@tonic-gate   if (!conn)
8887c478bd9Sstevel@tonic-gate     return SASL_BADPARAM;
8897c478bd9Sstevel@tonic-gate 
8907c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_
8917c478bd9Sstevel@tonic-gate   gctx = conn->gctx;
8927c478bd9Sstevel@tonic-gate #endif	/* _SUN_SDK_ */
8937c478bd9Sstevel@tonic-gate 
8947c478bd9Sstevel@tonic-gate   switch(propnum)
8957c478bd9Sstevel@tonic-gate   {
8967c478bd9Sstevel@tonic-gate   case SASL_SSF_EXTERNAL:
8977c478bd9Sstevel@tonic-gate       conn->external.ssf = *((sasl_ssf_t *)value);
8987c478bd9Sstevel@tonic-gate       if(conn->type == SASL_CONN_SERVER) {
8997c478bd9Sstevel@tonic-gate 	((sasl_server_conn_t*)conn)->sparams->external_ssf =
9007c478bd9Sstevel@tonic-gate 	  conn->external.ssf;
9017c478bd9Sstevel@tonic-gate       } else {
9027c478bd9Sstevel@tonic-gate 	((sasl_client_conn_t*)conn)->cparams->external_ssf =
9037c478bd9Sstevel@tonic-gate 	  conn->external.ssf;
9047c478bd9Sstevel@tonic-gate       }
9057c478bd9Sstevel@tonic-gate       break;
9067c478bd9Sstevel@tonic-gate 
9077c478bd9Sstevel@tonic-gate   case SASL_AUTH_EXTERNAL:
9087c478bd9Sstevel@tonic-gate       if(value && strlen(value)) {
9097c478bd9Sstevel@tonic-gate 	  result = _sasl_strdup(value, &str, NULL);
9107c478bd9Sstevel@tonic-gate 	  if(result != SASL_OK) MEMERROR(conn);
9117c478bd9Sstevel@tonic-gate       } else {
9127c478bd9Sstevel@tonic-gate 	  str = NULL;
9137c478bd9Sstevel@tonic-gate       }
9147c478bd9Sstevel@tonic-gate 
9157c478bd9Sstevel@tonic-gate       if(conn->external.auth_id)
9167c478bd9Sstevel@tonic-gate 	  sasl_FREE(conn->external.auth_id);
9177c478bd9Sstevel@tonic-gate 
9187c478bd9Sstevel@tonic-gate       conn->external.auth_id = str;
9197c478bd9Sstevel@tonic-gate 
9207c478bd9Sstevel@tonic-gate       break;
9217c478bd9Sstevel@tonic-gate 
9227c478bd9Sstevel@tonic-gate   case SASL_DEFUSERREALM:
9237c478bd9Sstevel@tonic-gate       if(conn->type != SASL_CONN_SERVER) {
9247c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_
9257c478bd9Sstevel@tonic-gate 	_sasl_log(conn, SASL_LOG_WARN,
9267c478bd9Sstevel@tonic-gate 		  "Tried to set realm on non-server connection");
9277c478bd9Sstevel@tonic-gate #else
9287c478bd9Sstevel@tonic-gate 	sasl_seterror(conn, 0, "Tried to set realm on non-server connection");
9297c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */
9307c478bd9Sstevel@tonic-gate 	result = SASL_BADPROT;
9317c478bd9Sstevel@tonic-gate 	break;
9327c478bd9Sstevel@tonic-gate       }
9337c478bd9Sstevel@tonic-gate 
9347c478bd9Sstevel@tonic-gate       if(value && strlen(value)) {
9357c478bd9Sstevel@tonic-gate 	  result = _sasl_strdup(value, &str, NULL);
9367c478bd9Sstevel@tonic-gate 	  if(result != SASL_OK) MEMERROR(conn);
9377c478bd9Sstevel@tonic-gate       } else {
9387c478bd9Sstevel@tonic-gate 	  PARAMERROR(conn);
9397c478bd9Sstevel@tonic-gate       }
9407c478bd9Sstevel@tonic-gate 
9417c478bd9Sstevel@tonic-gate       if(((sasl_server_conn_t *)conn)->user_realm)
9427c478bd9Sstevel@tonic-gate       	  sasl_FREE(((sasl_server_conn_t *)conn)->user_realm);
9437c478bd9Sstevel@tonic-gate 
9447c478bd9Sstevel@tonic-gate       ((sasl_server_conn_t *)conn)->user_realm = str;
9457c478bd9Sstevel@tonic-gate       ((sasl_server_conn_t *)conn)->sparams->user_realm = str;
9467c478bd9Sstevel@tonic-gate 
9477c478bd9Sstevel@tonic-gate       break;
9487c478bd9Sstevel@tonic-gate 
9497c478bd9Sstevel@tonic-gate   case SASL_SEC_PROPS:
9507c478bd9Sstevel@tonic-gate   {
9517c478bd9Sstevel@tonic-gate       sasl_security_properties_t *props = (sasl_security_properties_t *)value;
9527c478bd9Sstevel@tonic-gate 
9537c478bd9Sstevel@tonic-gate       if(props->maxbufsize == 0 && props->min_ssf != 0) {
9547c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_
9557c478bd9Sstevel@tonic-gate 	  _sasl_log(conn, SASL_LOG_ERR,
9567c478bd9Sstevel@tonic-gate 		    "Attempt to disable security layers (maxoutbuf == 0) with min_ssf > 0");
9577c478bd9Sstevel@tonic-gate #else
9587c478bd9Sstevel@tonic-gate 	  sasl_seterror(conn, 0,
9597c478bd9Sstevel@tonic-gate 			"Attempt to disable security layers (maxoutbuf == 0) with min_ssf > 0");
9607c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */
9617c478bd9Sstevel@tonic-gate 	  RETURN(conn, SASL_TOOWEAK);
9627c478bd9Sstevel@tonic-gate       }
9637c478bd9Sstevel@tonic-gate 
9647c478bd9Sstevel@tonic-gate       conn->props = *props;
9657c478bd9Sstevel@tonic-gate 
9667c478bd9Sstevel@tonic-gate       if(conn->type == SASL_CONN_SERVER) {
9677c478bd9Sstevel@tonic-gate 	((sasl_server_conn_t*)conn)->sparams->props = *props;
9687c478bd9Sstevel@tonic-gate       } else {
9697c478bd9Sstevel@tonic-gate 	((sasl_client_conn_t*)conn)->cparams->props = *props;
9707c478bd9Sstevel@tonic-gate       }
9717c478bd9Sstevel@tonic-gate 
9727c478bd9Sstevel@tonic-gate       break;
9737c478bd9Sstevel@tonic-gate   }
9747c478bd9Sstevel@tonic-gate 
9757c478bd9Sstevel@tonic-gate   case SASL_IPREMOTEPORT:
9767c478bd9Sstevel@tonic-gate   {
9777c478bd9Sstevel@tonic-gate       const char *ipremoteport = (const char *)value;
9787c478bd9Sstevel@tonic-gate       if(!value) {
9797c478bd9Sstevel@tonic-gate 	  conn->got_ip_remote = 0;
9807c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_
9817c478bd9Sstevel@tonic-gate       } else if (strlen(ipremoteport) >= sizeof (conn->ipremoteport)) {
9827c478bd9Sstevel@tonic-gate 	  RETURN(conn, SASL_BADPARAM);
9837c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */
9847c478bd9Sstevel@tonic-gate       } else if (_sasl_ipfromstring(ipremoteport, NULL, 0)
9857c478bd9Sstevel@tonic-gate 		 != SASL_OK) {
9867c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_
9877c478bd9Sstevel@tonic-gate 	  _sasl_log(conn, SASL_LOG_ERR, "Bad IPREMOTEPORT value");
9887c478bd9Sstevel@tonic-gate #else
9897c478bd9Sstevel@tonic-gate 	  sasl_seterror(conn, 0, "Bad IPREMOTEPORT value");
9907c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */
9917c478bd9Sstevel@tonic-gate 	  RETURN(conn, SASL_BADPARAM);
9927c478bd9Sstevel@tonic-gate       } else {
9937c478bd9Sstevel@tonic-gate 	  strcpy(conn->ipremoteport, ipremoteport);
9947c478bd9Sstevel@tonic-gate 	  conn->got_ip_remote = 1;
9957c478bd9Sstevel@tonic-gate       }
9967c478bd9Sstevel@tonic-gate 
9977c478bd9Sstevel@tonic-gate       if(conn->got_ip_remote) {
9987c478bd9Sstevel@tonic-gate 	  if(conn->type == SASL_CONN_CLIENT) {
9997c478bd9Sstevel@tonic-gate 	      ((sasl_client_conn_t *)conn)->cparams->ipremoteport
10007c478bd9Sstevel@tonic-gate 		  = conn->ipremoteport;
10017c478bd9Sstevel@tonic-gate 	      ((sasl_client_conn_t *)conn)->cparams->ipremlen =
10027c478bd9Sstevel@tonic-gate 		  strlen(conn->ipremoteport);
10037c478bd9Sstevel@tonic-gate 	  } else if (conn->type == SASL_CONN_SERVER) {
10047c478bd9Sstevel@tonic-gate 	      ((sasl_server_conn_t *)conn)->sparams->ipremoteport
10057c478bd9Sstevel@tonic-gate 		  = conn->ipremoteport;
10067c478bd9Sstevel@tonic-gate 	      ((sasl_server_conn_t *)conn)->sparams->ipremlen =
10077c478bd9Sstevel@tonic-gate 		  strlen(conn->ipremoteport);
10087c478bd9Sstevel@tonic-gate 	  }
10097c478bd9Sstevel@tonic-gate       } else {
10107c478bd9Sstevel@tonic-gate 	  if(conn->type == SASL_CONN_CLIENT) {
10117c478bd9Sstevel@tonic-gate 	      ((sasl_client_conn_t *)conn)->cparams->ipremoteport
10127c478bd9Sstevel@tonic-gate 		  = NULL;
10137c478bd9Sstevel@tonic-gate 	      ((sasl_client_conn_t *)conn)->cparams->ipremlen = 0;
10147c478bd9Sstevel@tonic-gate 	  } else if (conn->type == SASL_CONN_SERVER) {
10157c478bd9Sstevel@tonic-gate 	      ((sasl_server_conn_t *)conn)->sparams->ipremoteport
10167c478bd9Sstevel@tonic-gate 		  = NULL;
10177c478bd9Sstevel@tonic-gate 	      ((sasl_server_conn_t *)conn)->sparams->ipremlen = 0;
10187c478bd9Sstevel@tonic-gate 	  }
10197c478bd9Sstevel@tonic-gate       }
10207c478bd9Sstevel@tonic-gate 
10217c478bd9Sstevel@tonic-gate       break;
10227c478bd9Sstevel@tonic-gate   }
10237c478bd9Sstevel@tonic-gate 
10247c478bd9Sstevel@tonic-gate   case SASL_IPLOCALPORT:
10257c478bd9Sstevel@tonic-gate   {
10267c478bd9Sstevel@tonic-gate       const char *iplocalport = (const char *)value;
10277c478bd9Sstevel@tonic-gate       if(!value) {
10287c478bd9Sstevel@tonic-gate 	  conn->got_ip_local = 0;
10297c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_
10307c478bd9Sstevel@tonic-gate       } else if (strlen(iplocalport) >= sizeof (conn->iplocalport)) {
10317c478bd9Sstevel@tonic-gate 	  RETURN(conn, SASL_BADPARAM);
10327c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */
10337c478bd9Sstevel@tonic-gate       } else if (_sasl_ipfromstring(iplocalport, NULL, 0)
10347c478bd9Sstevel@tonic-gate 		 != SASL_OK) {
10357c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_
10367c478bd9Sstevel@tonic-gate 	  _sasl_log(conn, SASL_LOG_ERR, "Bad IPLOCALPORT value");
10377c478bd9Sstevel@tonic-gate #else
10387c478bd9Sstevel@tonic-gate 	  sasl_seterror(conn, 0, "Bad IPLOCALPORT value");
10397c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */
10407c478bd9Sstevel@tonic-gate 	  RETURN(conn, SASL_BADPARAM);
10417c478bd9Sstevel@tonic-gate       } else {
10427c478bd9Sstevel@tonic-gate 	  strcpy(conn->iplocalport, iplocalport);
10437c478bd9Sstevel@tonic-gate 	  conn->got_ip_local = 1;
10447c478bd9Sstevel@tonic-gate       }
10457c478bd9Sstevel@tonic-gate 
10467c478bd9Sstevel@tonic-gate       if(conn->got_ip_local) {
10477c478bd9Sstevel@tonic-gate 	  if(conn->type == SASL_CONN_CLIENT) {
10487c478bd9Sstevel@tonic-gate 	      ((sasl_client_conn_t *)conn)->cparams->iplocalport
10497c478bd9Sstevel@tonic-gate 		  = conn->iplocalport;
10507c478bd9Sstevel@tonic-gate 	      ((sasl_client_conn_t *)conn)->cparams->iploclen
10517c478bd9Sstevel@tonic-gate 		  = strlen(conn->iplocalport);
10527c478bd9Sstevel@tonic-gate 	  } else if (conn->type == SASL_CONN_SERVER) {
10537c478bd9Sstevel@tonic-gate 	      ((sasl_server_conn_t *)conn)->sparams->iplocalport
10547c478bd9Sstevel@tonic-gate 		  = conn->iplocalport;
10557c478bd9Sstevel@tonic-gate 	      ((sasl_server_conn_t *)conn)->sparams->iploclen
10567c478bd9Sstevel@tonic-gate 		  = strlen(conn->iplocalport);
10577c478bd9Sstevel@tonic-gate 	  }
10587c478bd9Sstevel@tonic-gate       } else {
10597c478bd9Sstevel@tonic-gate 	  if(conn->type == SASL_CONN_CLIENT) {
10607c478bd9Sstevel@tonic-gate 	      ((sasl_client_conn_t *)conn)->cparams->iplocalport
10617c478bd9Sstevel@tonic-gate 		  = NULL;
10627c478bd9Sstevel@tonic-gate 	      ((sasl_client_conn_t *)conn)->cparams->iploclen = 0;
10637c478bd9Sstevel@tonic-gate 	  } else if (conn->type == SASL_CONN_SERVER) {
10647c478bd9Sstevel@tonic-gate 	      ((sasl_server_conn_t *)conn)->sparams->iplocalport
10657c478bd9Sstevel@tonic-gate 		  = NULL;
10667c478bd9Sstevel@tonic-gate 	      ((sasl_server_conn_t *)conn)->sparams->iploclen = 0;
10677c478bd9Sstevel@tonic-gate 	  }
10687c478bd9Sstevel@tonic-gate       }
10697c478bd9Sstevel@tonic-gate       break;
10707c478bd9Sstevel@tonic-gate   }
10717c478bd9Sstevel@tonic-gate 
10727c478bd9Sstevel@tonic-gate   default:
10737c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_
10747c478bd9Sstevel@tonic-gate       _sasl_log(conn, SASL_LOG_WARN, "Unknown parameter type");
10757c478bd9Sstevel@tonic-gate #else
10767c478bd9Sstevel@tonic-gate       sasl_seterror(conn, 0, "Unknown parameter type");
10777c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */
10787c478bd9Sstevel@tonic-gate       result = SASL_BADPARAM;
10797c478bd9Sstevel@tonic-gate   }
10807c478bd9Sstevel@tonic-gate 
10817c478bd9Sstevel@tonic-gate   RETURN(conn, result);
10827c478bd9Sstevel@tonic-gate }
10837c478bd9Sstevel@tonic-gate 
10847c478bd9Sstevel@tonic-gate /* this is apparently no longer a user function */
sasl_usererr(int saslerr)10857c478bd9Sstevel@tonic-gate static int sasl_usererr(int saslerr)
10867c478bd9Sstevel@tonic-gate {
10877c478bd9Sstevel@tonic-gate     /* Hide the difference in a username failure and a password failure */
10887c478bd9Sstevel@tonic-gate     if (saslerr == SASL_NOUSER)
10897c478bd9Sstevel@tonic-gate 	return SASL_BADAUTH;
10907c478bd9Sstevel@tonic-gate 
10917c478bd9Sstevel@tonic-gate     /* otherwise return the error given; no transform necessary */
10927c478bd9Sstevel@tonic-gate     return saslerr;
10937c478bd9Sstevel@tonic-gate }
10947c478bd9Sstevel@tonic-gate 
10957c478bd9Sstevel@tonic-gate #ifdef _INTEGRATED_SOLARIS_
free_err_tsd(void * key)10967c478bd9Sstevel@tonic-gate static void free_err_tsd(void *key)
10977c478bd9Sstevel@tonic-gate {
10987c478bd9Sstevel@tonic-gate     free(key);
10997c478bd9Sstevel@tonic-gate }
11007c478bd9Sstevel@tonic-gate #endif /* _INTEGRATED_SOLARIS_ */
11017c478bd9Sstevel@tonic-gate 
sasl_errstring(int saslerr,const char * langlist,const char ** outlang)11027c478bd9Sstevel@tonic-gate const char *sasl_errstring(int saslerr,
11037c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_
11047c478bd9Sstevel@tonic-gate 			   const char *langlist,
11057c478bd9Sstevel@tonic-gate #else
11067c478bd9Sstevel@tonic-gate 			   const char *langlist __attribute__((unused)),
11077c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */
11087c478bd9Sstevel@tonic-gate 			   const char **outlang)
11097c478bd9Sstevel@tonic-gate {
11107c478bd9Sstevel@tonic-gate #ifdef _INTEGRATED_SOLARIS_
11117c478bd9Sstevel@tonic-gate   const char *s;
11127c478bd9Sstevel@tonic-gate   const char *s_locale;
11137c478bd9Sstevel@tonic-gate   char *s_utf8;
11147c478bd9Sstevel@tonic-gate   void *tsd;
11157c478bd9Sstevel@tonic-gate 
11167c478bd9Sstevel@tonic-gate   if (outlang) *outlang="i-default";
11177c478bd9Sstevel@tonic-gate #else
11187c478bd9Sstevel@tonic-gate   if (outlang) *outlang="en-us";
11197c478bd9Sstevel@tonic-gate #endif /* _INTEGRATED_SOLARIS_ */
11207c478bd9Sstevel@tonic-gate 
11217c478bd9Sstevel@tonic-gate #ifdef _INTEGRATED_SOLARIS_
11227c478bd9Sstevel@tonic-gate   switch(saslerr)
11237c478bd9Sstevel@tonic-gate     {
11247c478bd9Sstevel@tonic-gate     case SASL_CONTINUE: s = gettext("another step is needed in authentication");
11257c478bd9Sstevel@tonic-gate 	break;
11267c478bd9Sstevel@tonic-gate     case SASL_OK:       s = gettext("successful result");
11277c478bd9Sstevel@tonic-gate 	break;
11287c478bd9Sstevel@tonic-gate     case SASL_FAIL:     s = gettext("generic failure");
11297c478bd9Sstevel@tonic-gate 	break;
11307c478bd9Sstevel@tonic-gate     case SASL_NOMEM:    s = gettext("no memory available");
11317c478bd9Sstevel@tonic-gate 	break;
11327c478bd9Sstevel@tonic-gate     case SASL_BUFOVER:  s = gettext("overflowed buffer");
11337c478bd9Sstevel@tonic-gate 	break;
11347c478bd9Sstevel@tonic-gate     case SASL_NOMECH:   s = gettext("no mechanism available");
11357c478bd9Sstevel@tonic-gate 	break;
11367c478bd9Sstevel@tonic-gate     case SASL_BADPROT:  s = gettext("bad protocol / cancel");
11377c478bd9Sstevel@tonic-gate 	break;
11387c478bd9Sstevel@tonic-gate     case SASL_NOTDONE:  s = gettext("can't request info until later in exchange");
11397c478bd9Sstevel@tonic-gate 	break;
11407c478bd9Sstevel@tonic-gate     case SASL_BADPARAM: s = gettext("invalid parameter supplied");
11417c478bd9Sstevel@tonic-gate 	break;
11427c478bd9Sstevel@tonic-gate     case SASL_TRYAGAIN: s = gettext("transient failure (e.g., weak key)");
11437c478bd9Sstevel@tonic-gate 	break;
11447c478bd9Sstevel@tonic-gate     case SASL_BADMAC:   s = gettext("integrity check failed");
11457c478bd9Sstevel@tonic-gate 	break;
11467c478bd9Sstevel@tonic-gate     case SASL_NOTINIT:  s = gettext("SASL library not initialized");
11477c478bd9Sstevel@tonic-gate 	break;
11487c478bd9Sstevel@tonic-gate                              /* -- client only codes -- */
11497c478bd9Sstevel@tonic-gate     case SASL_INTERACT:   s = gettext("needs user interaction");
11507c478bd9Sstevel@tonic-gate 	break;
11517c478bd9Sstevel@tonic-gate     case SASL_BADSERV:    s = gettext("server failed mutual authentication step");
11527c478bd9Sstevel@tonic-gate 	break;
11537c478bd9Sstevel@tonic-gate     case SASL_WRONGMECH:  s = gettext("mechanism doesn't support requested feature");
11547c478bd9Sstevel@tonic-gate 	break;
11557c478bd9Sstevel@tonic-gate                              /* -- server only codes -- */
11567c478bd9Sstevel@tonic-gate     case SASL_BADAUTH:    s = gettext("authentication failure");
11577c478bd9Sstevel@tonic-gate 	break;
11587c478bd9Sstevel@tonic-gate     case SASL_NOAUTHZ:    s = gettext("authorization failure");
11597c478bd9Sstevel@tonic-gate 	break;
11607c478bd9Sstevel@tonic-gate     case SASL_TOOWEAK:    s = gettext("mechanism too weak for this user");
11617c478bd9Sstevel@tonic-gate 	break;
11627c478bd9Sstevel@tonic-gate     case SASL_ENCRYPT:    s = gettext("encryption needed to use mechanism");
11637c478bd9Sstevel@tonic-gate 	break;
11647c478bd9Sstevel@tonic-gate     case SASL_TRANS:      s = gettext("One time use of a plaintext password will enable requested mechanism for user");
11657c478bd9Sstevel@tonic-gate 	break;
11667c478bd9Sstevel@tonic-gate     case SASL_EXPIRED:    s = gettext("passphrase expired, has to be reset");
11677c478bd9Sstevel@tonic-gate 	break;
11687c478bd9Sstevel@tonic-gate     case SASL_DISABLED:   s = gettext("account disabled");
11697c478bd9Sstevel@tonic-gate 	break;
11707c478bd9Sstevel@tonic-gate     case SASL_NOUSER:     s = gettext("user not found");
11717c478bd9Sstevel@tonic-gate 	break;
11727c478bd9Sstevel@tonic-gate     case SASL_BADVERS:    s = gettext("version mismatch with plug-in");
11737c478bd9Sstevel@tonic-gate 	break;
11747c478bd9Sstevel@tonic-gate     case SASL_UNAVAIL:    s = gettext("remote authentication server unavailable");
11757c478bd9Sstevel@tonic-gate 	break;
11767c478bd9Sstevel@tonic-gate     case SASL_NOVERIFY:   s = gettext("user exists, but no verifier for user");
11777c478bd9Sstevel@tonic-gate 	break;
11787c478bd9Sstevel@tonic-gate     case SASL_PWLOCK:     s = gettext("passphrase locked");
11797c478bd9Sstevel@tonic-gate 	break;
11807c478bd9Sstevel@tonic-gate     case SASL_NOCHANGE:   s = gettext("requested change was not needed");
11817c478bd9Sstevel@tonic-gate 	break;
11827c478bd9Sstevel@tonic-gate     case SASL_WEAKPASS:   s = gettext("passphrase is too weak for security policy");
11837c478bd9Sstevel@tonic-gate 	break;
11847c478bd9Sstevel@tonic-gate     case SASL_NOUSERPASS: s = gettext("user supplied passwords are not permitted");
11857c478bd9Sstevel@tonic-gate 
11867c478bd9Sstevel@tonic-gate 	break;
11877c478bd9Sstevel@tonic-gate     default:   s = gettext("undefined error!");
11887c478bd9Sstevel@tonic-gate 	break;
11897c478bd9Sstevel@tonic-gate   }
11907c478bd9Sstevel@tonic-gate 
11917c478bd9Sstevel@tonic-gate   if (use_locale(langlist, 0))
11927c478bd9Sstevel@tonic-gate     s_locale = dgettext(TEXT_DOMAIN, s);
11937c478bd9Sstevel@tonic-gate   else
11947c478bd9Sstevel@tonic-gate     s_locale = s;
11957c478bd9Sstevel@tonic-gate 
11967c478bd9Sstevel@tonic-gate   if (s == s_locale)
11977c478bd9Sstevel@tonic-gate     return s;
11987c478bd9Sstevel@tonic-gate 
11997c478bd9Sstevel@tonic-gate   s_utf8 = local_to_utf(NULL, s_locale);
12007c478bd9Sstevel@tonic-gate   if (s_utf8 == NULL)
12017c478bd9Sstevel@tonic-gate     return s;
12027c478bd9Sstevel@tonic-gate 
1203cb620785Sraf   if (pthread_key_create_once_np(&errstring_key, free_err_tsd) != 0) {
12047c478bd9Sstevel@tonic-gate     free(s_utf8);
12057c478bd9Sstevel@tonic-gate     return s;
12067c478bd9Sstevel@tonic-gate   }
12077c478bd9Sstevel@tonic-gate 
12087c478bd9Sstevel@tonic-gate   tsd = pthread_getspecific(errstring_key);
1209cb620785Sraf   if (tsd != NULL)
12107c478bd9Sstevel@tonic-gate     free(tsd);
12117c478bd9Sstevel@tonic-gate   pthread_setspecific(errstring_key, s_utf8);
12127c478bd9Sstevel@tonic-gate 
12137c478bd9Sstevel@tonic-gate   if (outlang) *outlang="*";
12147c478bd9Sstevel@tonic-gate   return s_utf8;
12157c478bd9Sstevel@tonic-gate #else
12167c478bd9Sstevel@tonic-gate   switch(saslerr)
12177c478bd9Sstevel@tonic-gate     {
12187c478bd9Sstevel@tonic-gate     case SASL_CONTINUE: return "another step is needed in authentication";
12197c478bd9Sstevel@tonic-gate     case SASL_OK:       return "successful result";
12207c478bd9Sstevel@tonic-gate     case SASL_FAIL:     return "generic failure";
12217c478bd9Sstevel@tonic-gate     case SASL_NOMEM:    return "no memory available";
12227c478bd9Sstevel@tonic-gate     case SASL_BUFOVER:  return "overflowed buffer";
12237c478bd9Sstevel@tonic-gate     case SASL_NOMECH:   return "no mechanism available";
12247c478bd9Sstevel@tonic-gate     case SASL_BADPROT:  return "bad protocol / cancel";
12257c478bd9Sstevel@tonic-gate     case SASL_NOTDONE:  return "can't request info until later in exchange";
12267c478bd9Sstevel@tonic-gate     case SASL_BADPARAM: return "invalid parameter supplied";
12277c478bd9Sstevel@tonic-gate     case SASL_TRYAGAIN: return "transient failure (e.g., weak key)";
12287c478bd9Sstevel@tonic-gate     case SASL_BADMAC:   return "integrity check failed";
12297c478bd9Sstevel@tonic-gate     case SASL_NOTINIT:  return "SASL library not initialized";
12307c478bd9Sstevel@tonic-gate                              /* -- client only codes -- */
12317c478bd9Sstevel@tonic-gate     case SASL_INTERACT:   return "needs user interaction";
12327c478bd9Sstevel@tonic-gate     case SASL_BADSERV:    return "server failed mutual authentication step";
12337c478bd9Sstevel@tonic-gate     case SASL_WRONGMECH:  return "mechanism doesn't support requested feature";
12347c478bd9Sstevel@tonic-gate                              /* -- server only codes -- */
12357c478bd9Sstevel@tonic-gate     case SASL_BADAUTH:    return "authentication failure";
12367c478bd9Sstevel@tonic-gate     case SASL_NOAUTHZ:    return "authorization failure";
12377c478bd9Sstevel@tonic-gate     case SASL_TOOWEAK:    return "mechanism too weak for this user";
12387c478bd9Sstevel@tonic-gate     case SASL_ENCRYPT:    return "encryption needed to use mechanism";
12397c478bd9Sstevel@tonic-gate     case SASL_TRANS:      return "One time use of a plaintext password will enable requested mechanism for user";
12407c478bd9Sstevel@tonic-gate     case SASL_EXPIRED:    return "passphrase expired, has to be reset";
12417c478bd9Sstevel@tonic-gate     case SASL_DISABLED:   return "account disabled";
12427c478bd9Sstevel@tonic-gate     case SASL_NOUSER:     return "user not found";
12437c478bd9Sstevel@tonic-gate     case SASL_BADVERS:    return "version mismatch with plug-in";
12447c478bd9Sstevel@tonic-gate     case SASL_UNAVAIL:    return "remote authentication server unavailable";
12457c478bd9Sstevel@tonic-gate     case SASL_NOVERIFY:   return "user exists, but no verifier for user";
12467c478bd9Sstevel@tonic-gate     case SASL_PWLOCK:     return "passphrase locked";
12477c478bd9Sstevel@tonic-gate     case SASL_NOCHANGE:   return "requested change was not needed";
12487c478bd9Sstevel@tonic-gate     case SASL_WEAKPASS:   return "passphrase is too weak for security policy";
12497c478bd9Sstevel@tonic-gate     case SASL_NOUSERPASS: return "user supplied passwords are not permitted";
12507c478bd9Sstevel@tonic-gate 
12517c478bd9Sstevel@tonic-gate     default:   return "undefined error!";
12527c478bd9Sstevel@tonic-gate     }
12537c478bd9Sstevel@tonic-gate #endif /* _INTEGRATED_SOLARIS_ */
12547c478bd9Sstevel@tonic-gate 
12557c478bd9Sstevel@tonic-gate }
12567c478bd9Sstevel@tonic-gate 
12577c478bd9Sstevel@tonic-gate /* Return the sanitized error detail about the last error that occured for
12587c478bd9Sstevel@tonic-gate  * a connection */
sasl_errdetail(sasl_conn_t * conn)12597c478bd9Sstevel@tonic-gate const char *sasl_errdetail(sasl_conn_t *conn)
12607c478bd9Sstevel@tonic-gate {
12617c478bd9Sstevel@tonic-gate     unsigned need_len;
12627c478bd9Sstevel@tonic-gate     const char *errstr;
12637c478bd9Sstevel@tonic-gate     char leader[128];
12647c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_
12657c478bd9Sstevel@tonic-gate     int ret;
12667c478bd9Sstevel@tonic-gate     const _sasl_global_context_t *gctx;
12677c478bd9Sstevel@tonic-gate 
12687c478bd9Sstevel@tonic-gate     if(!conn) return "invalid parameter supplied";
12697c478bd9Sstevel@tonic-gate 
12707c478bd9Sstevel@tonic-gate     gctx = conn->gctx;
12717c478bd9Sstevel@tonic-gate #else
12727c478bd9Sstevel@tonic-gate     if(!conn) return NULL;
12737c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */
12747c478bd9Sstevel@tonic-gate 
12757c478bd9Sstevel@tonic-gate     errstr = sasl_errstring(conn->error_code, NULL, NULL);
12767c478bd9Sstevel@tonic-gate     snprintf(leader,128,"SASL(%d): %s: ",
12777c478bd9Sstevel@tonic-gate 	     sasl_usererr(conn->error_code), errstr);
12787c478bd9Sstevel@tonic-gate 
12797c478bd9Sstevel@tonic-gate     need_len = strlen(leader) + strlen(conn->error_buf) + 12;
12807c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_
12817c478bd9Sstevel@tonic-gate     ret = _buf_alloc(&conn->errdetail_buf, &conn->errdetail_buf_len, need_len);
12827c478bd9Sstevel@tonic-gate     if (ret != SASL_OK)
12837c478bd9Sstevel@tonic-gate 	return "no memory available";
12847c478bd9Sstevel@tonic-gate #else
12857c478bd9Sstevel@tonic-gate     _buf_alloc(&conn->errdetail_buf, &conn->errdetail_buf_len, need_len);
12867c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */
12877c478bd9Sstevel@tonic-gate 
12887c478bd9Sstevel@tonic-gate     snprintf(conn->errdetail_buf, need_len, "%s%s", leader, conn->error_buf);
12897c478bd9Sstevel@tonic-gate 
12907c478bd9Sstevel@tonic-gate     return conn->errdetail_buf;
12917c478bd9Sstevel@tonic-gate }
12927c478bd9Sstevel@tonic-gate 
12937c478bd9Sstevel@tonic-gate #ifdef _INTEGRATED_SOLARIS_
12947c478bd9Sstevel@tonic-gate DEFINE_STATIC_MUTEX(reg_mutex);
12957c478bd9Sstevel@tonic-gate typedef struct reg_list {
12967c478bd9Sstevel@tonic-gate 	struct reg_list *next;
12977c478bd9Sstevel@tonic-gate 	void *mech;
12987c478bd9Sstevel@tonic-gate } reg_list_t;
12997c478bd9Sstevel@tonic-gate 
13007c478bd9Sstevel@tonic-gate static reg_list_t *reg_list_base = NULL;
13017c478bd9Sstevel@tonic-gate 
_is_sun_reg(void * mech)13027c478bd9Sstevel@tonic-gate int _is_sun_reg(void *mech)
13037c478bd9Sstevel@tonic-gate {
13044e5ef1ceSToomas Soome 	reg_list_t *r, *prev = NULL;
13057c478bd9Sstevel@tonic-gate 	int is_reg = 0;
13067c478bd9Sstevel@tonic-gate 
13077c478bd9Sstevel@tonic-gate 	LOCK_MUTEX(&reg_mutex);
13087c478bd9Sstevel@tonic-gate 	for (r = reg_list_base; r != NULL; r = r->next) {
13097c478bd9Sstevel@tonic-gate 		if (r->mech != mech) {
13107c478bd9Sstevel@tonic-gate 			prev = r;
13117c478bd9Sstevel@tonic-gate 			continue;
13127c478bd9Sstevel@tonic-gate 		}
13137c478bd9Sstevel@tonic-gate 		is_reg = 1;
1314*9841a15cSToomas Soome 		if (prev == NULL) {
13157c478bd9Sstevel@tonic-gate 			reg_list_base = reg_list_base->next;
13167c478bd9Sstevel@tonic-gate 		} else {
13177c478bd9Sstevel@tonic-gate 			prev->next = r->next;
13187c478bd9Sstevel@tonic-gate 		}
13197c478bd9Sstevel@tonic-gate 		free(r);
13207c478bd9Sstevel@tonic-gate 		break;
13217c478bd9Sstevel@tonic-gate 	}
13227c478bd9Sstevel@tonic-gate 	UNLOCK_MUTEX(&reg_mutex);
13237c478bd9Sstevel@tonic-gate 	return (is_reg);
13247c478bd9Sstevel@tonic-gate }
13257c478bd9Sstevel@tonic-gate 
13267c478bd9Sstevel@tonic-gate static void
_register_plugin(void * arg)13277c478bd9Sstevel@tonic-gate _register_plugin(void *arg)
13287c478bd9Sstevel@tonic-gate {
13297c478bd9Sstevel@tonic-gate 	reg_list_t *r = (reg_list_t *)calloc(1, sizeof (reg_list_t));
13307c478bd9Sstevel@tonic-gate 
13317c478bd9Sstevel@tonic-gate 	if (r != NULL) {
13327c478bd9Sstevel@tonic-gate 		r->mech = arg;
13337c478bd9Sstevel@tonic-gate 		LOCK_MUTEX(&reg_mutex);
13347c478bd9Sstevel@tonic-gate 		r->next = reg_list_base;
13357c478bd9Sstevel@tonic-gate 		reg_list_base = r;
13367c478bd9Sstevel@tonic-gate 		UNLOCK_MUTEX(&reg_mutex);
13377c478bd9Sstevel@tonic-gate 	}
13387c478bd9Sstevel@tonic-gate }
13397c478bd9Sstevel@tonic-gate #endif /* _INTEGRATED_SOLARIS_ */
13407c478bd9Sstevel@tonic-gate 
13417c478bd9Sstevel@tonic-gate /* Note that this needs the global callbacks, so if you don't give getcallbacks
13427c478bd9Sstevel@tonic-gate  * a sasl_conn_t, you're going to need to pass it yourself (or else we couldn't
13437c478bd9Sstevel@tonic-gate  * have client and server at the same time */
_sasl_global_getopt(void * context,const char * plugin_name,const char * option,const char ** result,unsigned * len)13447c478bd9Sstevel@tonic-gate static int _sasl_global_getopt(void *context,
13457c478bd9Sstevel@tonic-gate 			       const char *plugin_name,
13467c478bd9Sstevel@tonic-gate 			       const char *option,
13477c478bd9Sstevel@tonic-gate 			       const char ** result,
13487c478bd9Sstevel@tonic-gate 			       unsigned *len)
13497c478bd9Sstevel@tonic-gate {
13507c478bd9Sstevel@tonic-gate   const sasl_global_callbacks_t * global_callbacks;
13517c478bd9Sstevel@tonic-gate   const sasl_callback_t *callback;
13527c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_
13537c478bd9Sstevel@tonic-gate   _sasl_global_context_t *gctx;
13547c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */
13557c478bd9Sstevel@tonic-gate 
13567c478bd9Sstevel@tonic-gate   global_callbacks = (const sasl_global_callbacks_t *) context;
13577c478bd9Sstevel@tonic-gate 
13587c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_
13597c478bd9Sstevel@tonic-gate #ifdef _INTEGRATED_SOLARIS_
13607c478bd9Sstevel@tonic-gate   if (strcmp("reg_sun_plug", option) == 0) {
13617c478bd9Sstevel@tonic-gate         *result = (const char *)_register_plugin;
13627c478bd9Sstevel@tonic-gate         *len = 0;
13637c478bd9Sstevel@tonic-gate         return (SASL_OK);
13647c478bd9Sstevel@tonic-gate   }
13657c478bd9Sstevel@tonic-gate #endif /* _INTEGRATED_SOLARIS_ */
13667c478bd9Sstevel@tonic-gate 
13677c478bd9Sstevel@tonic-gate   if (global_callbacks)
13687c478bd9Sstevel@tonic-gate     gctx = global_callbacks->gctx;
13697c478bd9Sstevel@tonic-gate   else
13707c478bd9Sstevel@tonic-gate     gctx = _sasl_gbl_ctx();
13717c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */
13727c478bd9Sstevel@tonic-gate 
13737c478bd9Sstevel@tonic-gate   if (global_callbacks && global_callbacks->callbacks) {
13747c478bd9Sstevel@tonic-gate       for (callback = global_callbacks->callbacks;
13757c478bd9Sstevel@tonic-gate 	   callback->id != SASL_CB_LIST_END;
13767c478bd9Sstevel@tonic-gate 	   callback++) {
13777c478bd9Sstevel@tonic-gate 	if (callback->id == SASL_CB_GETOPT) {
13787c478bd9Sstevel@tonic-gate 	  if (!callback->proc) return SASL_FAIL;
13797c478bd9Sstevel@tonic-gate 	  if (((sasl_getopt_t *)(callback->proc))(callback->context,
13807c478bd9Sstevel@tonic-gate 						  plugin_name,
13817c478bd9Sstevel@tonic-gate 						  option,
13827c478bd9Sstevel@tonic-gate 						  result,
13837c478bd9Sstevel@tonic-gate 						  len)
13847c478bd9Sstevel@tonic-gate 	      == SASL_OK)
13857c478bd9Sstevel@tonic-gate 	    return SASL_OK;
13867c478bd9Sstevel@tonic-gate 	}
13877c478bd9Sstevel@tonic-gate       }
13887c478bd9Sstevel@tonic-gate   }
13897c478bd9Sstevel@tonic-gate 
13907c478bd9Sstevel@tonic-gate   /* look it up in our configuration file */
13917c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_
13927c478bd9Sstevel@tonic-gate   *result = sasl_config_getstring(gctx, option, NULL);
13937c478bd9Sstevel@tonic-gate #else
13947c478bd9Sstevel@tonic-gate   *result = sasl_config_getstring(option, NULL);
13957c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */
13967c478bd9Sstevel@tonic-gate   if (*result != NULL) {
13977c478bd9Sstevel@tonic-gate       if (len) { *len = strlen(*result); }
13987c478bd9Sstevel@tonic-gate       return SASL_OK;
13997c478bd9Sstevel@tonic-gate   }
14007c478bd9Sstevel@tonic-gate 
14017c478bd9Sstevel@tonic-gate   return SASL_FAIL;
14027c478bd9Sstevel@tonic-gate }
14037c478bd9Sstevel@tonic-gate 
14047c478bd9Sstevel@tonic-gate static int
_sasl_conn_getopt(void * context,const char * plugin_name,const char * option,const char ** result,unsigned * len)14057c478bd9Sstevel@tonic-gate _sasl_conn_getopt(void *context,
14067c478bd9Sstevel@tonic-gate 		  const char *plugin_name,
14077c478bd9Sstevel@tonic-gate 		  const char *option,
14087c478bd9Sstevel@tonic-gate 		  const char ** result,
14097c478bd9Sstevel@tonic-gate 		  unsigned *len)
14107c478bd9Sstevel@tonic-gate {
14117c478bd9Sstevel@tonic-gate   sasl_conn_t * conn;
14127c478bd9Sstevel@tonic-gate   const sasl_callback_t *callback;
14137c478bd9Sstevel@tonic-gate 
14147c478bd9Sstevel@tonic-gate   if (! context)
14157c478bd9Sstevel@tonic-gate     return SASL_BADPARAM;
14167c478bd9Sstevel@tonic-gate 
14177c478bd9Sstevel@tonic-gate   conn = (sasl_conn_t *) context;
14187c478bd9Sstevel@tonic-gate 
14197c478bd9Sstevel@tonic-gate   if (conn->callbacks)
14207c478bd9Sstevel@tonic-gate     for (callback = conn->callbacks;
14217c478bd9Sstevel@tonic-gate 	 callback->id != SASL_CB_LIST_END;
14227c478bd9Sstevel@tonic-gate 	 callback++)
14237c478bd9Sstevel@tonic-gate       if (callback->id == SASL_CB_GETOPT
14247c478bd9Sstevel@tonic-gate 	  && (((sasl_getopt_t *)(callback->proc))(callback->context,
14257c478bd9Sstevel@tonic-gate 						  plugin_name,
14267c478bd9Sstevel@tonic-gate 						  option,
14277c478bd9Sstevel@tonic-gate 						  result,
14287c478bd9Sstevel@tonic-gate 						  len)
14297c478bd9Sstevel@tonic-gate 	      == SASL_OK))
14307c478bd9Sstevel@tonic-gate 	return SASL_OK;
14317c478bd9Sstevel@tonic-gate 
14327c478bd9Sstevel@tonic-gate   /* If we made it here, we didn't find an appropriate callback
14337c478bd9Sstevel@tonic-gate    * in the connection's callback list, or the callback we did
14347c478bd9Sstevel@tonic-gate    * find didn't return SASL_OK.  So we attempt to use the
14357c478bd9Sstevel@tonic-gate    * global callback for this connection... */
14367c478bd9Sstevel@tonic-gate   return _sasl_global_getopt((void *)conn->global_callbacks,
14377c478bd9Sstevel@tonic-gate 			     plugin_name,
14387c478bd9Sstevel@tonic-gate 			     option,
14397c478bd9Sstevel@tonic-gate 			     result,
14407c478bd9Sstevel@tonic-gate 			     len);
14417c478bd9Sstevel@tonic-gate }
14427c478bd9Sstevel@tonic-gate 
14437c478bd9Sstevel@tonic-gate #ifdef HAVE_SYSLOG
14447c478bd9Sstevel@tonic-gate /* this is the default logging */
_sasl_syslog(void * context,int priority,const char * message)14457c478bd9Sstevel@tonic-gate static int _sasl_syslog(void *context __attribute__((unused)),
14467c478bd9Sstevel@tonic-gate 			int priority,
14477c478bd9Sstevel@tonic-gate 			const char *message)
14487c478bd9Sstevel@tonic-gate {
14497c478bd9Sstevel@tonic-gate     int syslog_priority;
14507c478bd9Sstevel@tonic-gate 
14517c478bd9Sstevel@tonic-gate     /* set syslog priority */
14527c478bd9Sstevel@tonic-gate     switch(priority) {
14537c478bd9Sstevel@tonic-gate     case SASL_LOG_NONE:
14547c478bd9Sstevel@tonic-gate 	return SASL_OK;
14557c478bd9Sstevel@tonic-gate 	break;
14567c478bd9Sstevel@tonic-gate     case SASL_LOG_ERR:
14577c478bd9Sstevel@tonic-gate 	syslog_priority = LOG_ERR;
14587c478bd9Sstevel@tonic-gate 	break;
14597c478bd9Sstevel@tonic-gate     case SASL_LOG_WARN:
14607c478bd9Sstevel@tonic-gate 	syslog_priority = LOG_WARNING;
14617c478bd9Sstevel@tonic-gate 	break;
14627c478bd9Sstevel@tonic-gate     case SASL_LOG_NOTE:
14637c478bd9Sstevel@tonic-gate     case SASL_LOG_FAIL:
14647c478bd9Sstevel@tonic-gate 	syslog_priority = LOG_NOTICE;
14657c478bd9Sstevel@tonic-gate 	break;
14667c478bd9Sstevel@tonic-gate     case SASL_LOG_PASS:
14677c478bd9Sstevel@tonic-gate     case SASL_LOG_TRACE:
14687c478bd9Sstevel@tonic-gate     case SASL_LOG_DEBUG:
14697c478bd9Sstevel@tonic-gate     default:
14707c478bd9Sstevel@tonic-gate 	syslog_priority = LOG_DEBUG;
14717c478bd9Sstevel@tonic-gate 	break;
14727c478bd9Sstevel@tonic-gate     }
14737c478bd9Sstevel@tonic-gate 
14747c478bd9Sstevel@tonic-gate     /* do the syslog call. do not need to call openlog */
14757c478bd9Sstevel@tonic-gate     syslog(syslog_priority | LOG_AUTH, "%s", message);
14767c478bd9Sstevel@tonic-gate 
14777c478bd9Sstevel@tonic-gate     return SASL_OK;
14787c478bd9Sstevel@tonic-gate }
14797c478bd9Sstevel@tonic-gate #endif				/* HAVE_SYSLOG */
14807c478bd9Sstevel@tonic-gate 
14817c478bd9Sstevel@tonic-gate static int
_sasl_getsimple(void * context,int id,const char ** result,size_t * len)14827c478bd9Sstevel@tonic-gate _sasl_getsimple(void *context,
14837c478bd9Sstevel@tonic-gate 		int id,
14847c478bd9Sstevel@tonic-gate 		const char ** result,
14857c478bd9Sstevel@tonic-gate 		size_t *len)
14867c478bd9Sstevel@tonic-gate {
14877c478bd9Sstevel@tonic-gate   const char *userid;
14887c478bd9Sstevel@tonic-gate #ifndef _SUN_SDK_
14897c478bd9Sstevel@tonic-gate   sasl_conn_t *conn;
14907c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */
14917c478bd9Sstevel@tonic-gate 
14927c478bd9Sstevel@tonic-gate   if (! context || ! result) return SASL_BADPARAM;
14937c478bd9Sstevel@tonic-gate 
14947c478bd9Sstevel@tonic-gate #ifndef _SUN_SDK_
14957c478bd9Sstevel@tonic-gate   conn = (sasl_conn_t *)context;
14967c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */
14977c478bd9Sstevel@tonic-gate 
14987c478bd9Sstevel@tonic-gate   switch(id) {
14997c478bd9Sstevel@tonic-gate   case SASL_CB_AUTHNAME:
15007c478bd9Sstevel@tonic-gate #ifdef _INTEGRATED_SOLARIS_
15017c478bd9Sstevel@tonic-gate     userid = getenv("LOGNAME");
15027c478bd9Sstevel@tonic-gate     if (userid != NULL) {
15037c478bd9Sstevel@tonic-gate 	*result = userid;
15047c478bd9Sstevel@tonic-gate 	if (len) *len = strlen(userid);
15057c478bd9Sstevel@tonic-gate 	return SASL_OK;
15067c478bd9Sstevel@tonic-gate     }
15077c478bd9Sstevel@tonic-gate #else
15087c478bd9Sstevel@tonic-gate     userid = getenv("USER");
15097c478bd9Sstevel@tonic-gate     if (userid != NULL) {
15107c478bd9Sstevel@tonic-gate 	*result = userid;
15117c478bd9Sstevel@tonic-gate 	if (len) *len = strlen(userid);
15127c478bd9Sstevel@tonic-gate 	return SASL_OK;
15137c478bd9Sstevel@tonic-gate     }
15147c478bd9Sstevel@tonic-gate     userid = getenv("USERNAME");
15157c478bd9Sstevel@tonic-gate     if (userid != NULL) {
15167c478bd9Sstevel@tonic-gate 	*result = userid;
15177c478bd9Sstevel@tonic-gate 	if (len) *len = strlen(userid);
15187c478bd9Sstevel@tonic-gate 	return SASL_OK;
15197c478bd9Sstevel@tonic-gate     }
15207c478bd9Sstevel@tonic-gate #endif /* _INTEGRATED_SOLARIS_ */
15217c478bd9Sstevel@tonic-gate #ifdef WIN32
15227c478bd9Sstevel@tonic-gate     /* for win32, try using the GetUserName standard call */
15237c478bd9Sstevel@tonic-gate     {
15247c478bd9Sstevel@tonic-gate 	DWORD i;
15257c478bd9Sstevel@tonic-gate 	BOOL rval;
15267c478bd9Sstevel@tonic-gate 	static char sender[128];
15277c478bd9Sstevel@tonic-gate 
15287c478bd9Sstevel@tonic-gate 	i = sizeof(sender);
15297c478bd9Sstevel@tonic-gate 	rval = GetUserName(sender, &i);
15307c478bd9Sstevel@tonic-gate 	if ( rval) { /* got a userid */
15317c478bd9Sstevel@tonic-gate 		*result = sender;
15327c478bd9Sstevel@tonic-gate 		if (len) *len = strlen(sender);
15337c478bd9Sstevel@tonic-gate 		return SASL_OK;
15347c478bd9Sstevel@tonic-gate 	}
15357c478bd9Sstevel@tonic-gate     }
15367c478bd9Sstevel@tonic-gate #endif /* WIN32 */
15377c478bd9Sstevel@tonic-gate     return SASL_FAIL;
15387c478bd9Sstevel@tonic-gate   default:
15397c478bd9Sstevel@tonic-gate     return SASL_BADPARAM;
15407c478bd9Sstevel@tonic-gate   }
15417c478bd9Sstevel@tonic-gate }
15427c478bd9Sstevel@tonic-gate 
15437c478bd9Sstevel@tonic-gate static int
_sasl_verifyfile(void * context,char * file,int type)15447c478bd9Sstevel@tonic-gate _sasl_verifyfile(void *context __attribute__((unused)),
15457c478bd9Sstevel@tonic-gate 		 char *file  __attribute__((unused)),
15467c478bd9Sstevel@tonic-gate 		 int type  __attribute__((unused)))
15477c478bd9Sstevel@tonic-gate {
15487c478bd9Sstevel@tonic-gate   /* always say ok */
15497c478bd9Sstevel@tonic-gate   return SASL_OK;
15507c478bd9Sstevel@tonic-gate }
15517c478bd9Sstevel@tonic-gate 
15527c478bd9Sstevel@tonic-gate 
15537c478bd9Sstevel@tonic-gate static int
_sasl_proxy_policy(sasl_conn_t * conn,void * context,const char * requested_user,unsigned rlen,const char * auth_identity,unsigned alen,const char * def_realm,unsigned urlen,struct propctx * propctx)15547c478bd9Sstevel@tonic-gate _sasl_proxy_policy(sasl_conn_t *conn,
15557c478bd9Sstevel@tonic-gate 		   void *context __attribute__((unused)),
15567c478bd9Sstevel@tonic-gate 		   const char *requested_user, unsigned rlen,
15577c478bd9Sstevel@tonic-gate 		   const char *auth_identity, unsigned alen,
15587c478bd9Sstevel@tonic-gate 		   const char *def_realm __attribute__((unused)),
15597c478bd9Sstevel@tonic-gate 		   unsigned urlen __attribute__((unused)),
15607c478bd9Sstevel@tonic-gate 		   struct propctx *propctx __attribute__((unused)))
15617c478bd9Sstevel@tonic-gate {
15627c478bd9Sstevel@tonic-gate     if (!conn)
15637c478bd9Sstevel@tonic-gate 	return SASL_BADPARAM;
15647c478bd9Sstevel@tonic-gate 
15657c478bd9Sstevel@tonic-gate     if (!requested_user || *requested_user == '\0')
15667c478bd9Sstevel@tonic-gate 	return SASL_OK;
15677c478bd9Sstevel@tonic-gate 
15687c478bd9Sstevel@tonic-gate     if (!auth_identity || !requested_user || rlen != alen ||
15697c478bd9Sstevel@tonic-gate 	(memcmp(auth_identity, requested_user, rlen) != 0)) {
15707c478bd9Sstevel@tonic-gate #ifdef _INTEGRATED_SOLARIS_
15717c478bd9Sstevel@tonic-gate 	sasl_seterror(conn, 0,
15727c478bd9Sstevel@tonic-gate 		      gettext("Requested identity not authenticated identity"));
15737c478bd9Sstevel@tonic-gate #else
15747c478bd9Sstevel@tonic-gate 	sasl_seterror(conn, 0,
15757c478bd9Sstevel@tonic-gate 		      "Requested identity not authenticated identity");
15767c478bd9Sstevel@tonic-gate #endif /* _INTEGRATED_SOLARIS_ */
15777c478bd9Sstevel@tonic-gate 	RETURN(conn, SASL_BADAUTH);
15787c478bd9Sstevel@tonic-gate     }
15797c478bd9Sstevel@tonic-gate 
15807c478bd9Sstevel@tonic-gate     return SASL_OK;
15817c478bd9Sstevel@tonic-gate }
15827c478bd9Sstevel@tonic-gate 
_sasl_getcallback(sasl_conn_t * conn,unsigned long callbackid,int (** pproc)(),void ** pcontext)15837c478bd9Sstevel@tonic-gate int _sasl_getcallback(sasl_conn_t * conn,
15847c478bd9Sstevel@tonic-gate 		      unsigned long callbackid,
15857c478bd9Sstevel@tonic-gate 		      int (**pproc)(),
15867c478bd9Sstevel@tonic-gate 		      void **pcontext)
15877c478bd9Sstevel@tonic-gate {
15887c478bd9Sstevel@tonic-gate   const sasl_callback_t *callback;
15897c478bd9Sstevel@tonic-gate 
15907c478bd9Sstevel@tonic-gate   if (!pproc || !pcontext)
15917c478bd9Sstevel@tonic-gate       PARAMERROR(conn);
15927c478bd9Sstevel@tonic-gate 
15937c478bd9Sstevel@tonic-gate   /* Some callbacks are always provided by the library */
15947c478bd9Sstevel@tonic-gate   switch (callbackid) {
15957c478bd9Sstevel@tonic-gate   case SASL_CB_LIST_END:
15967c478bd9Sstevel@tonic-gate     /* Nothing ever gets to provide this */
15977c478bd9Sstevel@tonic-gate       INTERROR(conn, SASL_FAIL);
15987c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_
15997c478bd9Sstevel@tonic-gate       break;
16007c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */
16017c478bd9Sstevel@tonic-gate   case SASL_CB_GETOPT:
16027c478bd9Sstevel@tonic-gate       if (conn) {
16037c478bd9Sstevel@tonic-gate 	  *pproc = &_sasl_conn_getopt;
16047c478bd9Sstevel@tonic-gate 	  *pcontext = conn;
16057c478bd9Sstevel@tonic-gate       } else {
16067c478bd9Sstevel@tonic-gate 	  *pproc = &_sasl_global_getopt;
16077c478bd9Sstevel@tonic-gate 	  *pcontext = NULL;
16087c478bd9Sstevel@tonic-gate       }
16097c478bd9Sstevel@tonic-gate       return SASL_OK;
16107c478bd9Sstevel@tonic-gate   }
16117c478bd9Sstevel@tonic-gate 
16127c478bd9Sstevel@tonic-gate   /* If it's not always provided by the library, see if there's
16137c478bd9Sstevel@tonic-gate    * a version provided by the application for this connection... */
16147c478bd9Sstevel@tonic-gate   if (conn && conn->callbacks) {
16157c478bd9Sstevel@tonic-gate     for (callback = conn->callbacks; callback->id != SASL_CB_LIST_END;
16167c478bd9Sstevel@tonic-gate 	 callback++) {
16177c478bd9Sstevel@tonic-gate 	if (callback->id == callbackid) {
16187c478bd9Sstevel@tonic-gate 	    *pproc = callback->proc;
16197c478bd9Sstevel@tonic-gate 	    *pcontext = callback->context;
16207c478bd9Sstevel@tonic-gate 	    if (callback->proc) {
16217c478bd9Sstevel@tonic-gate 		return SASL_OK;
16227c478bd9Sstevel@tonic-gate 	    } else {
16237c478bd9Sstevel@tonic-gate 		return SASL_INTERACT;
16247c478bd9Sstevel@tonic-gate 	    }
16257c478bd9Sstevel@tonic-gate 	}
16267c478bd9Sstevel@tonic-gate     }
16277c478bd9Sstevel@tonic-gate   }
16287c478bd9Sstevel@tonic-gate 
16297c478bd9Sstevel@tonic-gate   /* And, if not for this connection, see if there's one
16307c478bd9Sstevel@tonic-gate    * for all {server,client} connections... */
16317c478bd9Sstevel@tonic-gate   if (conn && conn->global_callbacks && conn->global_callbacks->callbacks) {
16327c478bd9Sstevel@tonic-gate       for (callback = conn->global_callbacks->callbacks;
16337c478bd9Sstevel@tonic-gate 	   callback->id != SASL_CB_LIST_END;
16347c478bd9Sstevel@tonic-gate 	   callback++) {
16357c478bd9Sstevel@tonic-gate 	  if (callback->id == callbackid) {
16367c478bd9Sstevel@tonic-gate 	      *pproc = callback->proc;
16377c478bd9Sstevel@tonic-gate 	      *pcontext = callback->context;
16387c478bd9Sstevel@tonic-gate 	      if (callback->proc) {
16397c478bd9Sstevel@tonic-gate 		  return SASL_OK;
16407c478bd9Sstevel@tonic-gate 	      } else {
16417c478bd9Sstevel@tonic-gate 		  return SASL_INTERACT;
16427c478bd9Sstevel@tonic-gate 	      }
16437c478bd9Sstevel@tonic-gate 	  }
16447c478bd9Sstevel@tonic-gate       }
16457c478bd9Sstevel@tonic-gate   }
16467c478bd9Sstevel@tonic-gate 
16477c478bd9Sstevel@tonic-gate   /* Otherwise, see if the library provides a default callback. */
16487c478bd9Sstevel@tonic-gate   switch (callbackid) {
16497c478bd9Sstevel@tonic-gate #ifdef HAVE_SYSLOG
16507c478bd9Sstevel@tonic-gate   case SASL_CB_LOG:
16517c478bd9Sstevel@tonic-gate     *pproc = (int (*)()) &_sasl_syslog;
16527c478bd9Sstevel@tonic-gate     *pcontext = NULL;
16537c478bd9Sstevel@tonic-gate     return SASL_OK;
16547c478bd9Sstevel@tonic-gate #endif /* HAVE_SYSLOG */
16557c478bd9Sstevel@tonic-gate   case SASL_CB_GETPATH:
16567c478bd9Sstevel@tonic-gate     *pproc = (int (*)()) &_sasl_getpath;
16577c478bd9Sstevel@tonic-gate     *pcontext = NULL;
16587c478bd9Sstevel@tonic-gate     return SASL_OK;
16597c478bd9Sstevel@tonic-gate   case SASL_CB_AUTHNAME:
16607c478bd9Sstevel@tonic-gate     *pproc = (int (*)()) &_sasl_getsimple;
16617c478bd9Sstevel@tonic-gate     *pcontext = conn;
16627c478bd9Sstevel@tonic-gate     return SASL_OK;
16637c478bd9Sstevel@tonic-gate   case SASL_CB_VERIFYFILE:
16647c478bd9Sstevel@tonic-gate     *pproc = & _sasl_verifyfile;
16657c478bd9Sstevel@tonic-gate     *pcontext = NULL;
16667c478bd9Sstevel@tonic-gate     return SASL_OK;
16677c478bd9Sstevel@tonic-gate   case SASL_CB_PROXY_POLICY:
16687c478bd9Sstevel@tonic-gate     *pproc = (int (*)()) &_sasl_proxy_policy;
16697c478bd9Sstevel@tonic-gate     *pcontext = NULL;
16707c478bd9Sstevel@tonic-gate     return SASL_OK;
16717c478bd9Sstevel@tonic-gate   }
16727c478bd9Sstevel@tonic-gate 
16737c478bd9Sstevel@tonic-gate   /* Unable to find a callback... */
16747c478bd9Sstevel@tonic-gate   *pproc = NULL;
16757c478bd9Sstevel@tonic-gate   *pcontext = NULL;
16767c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_
16777c478bd9Sstevel@tonic-gate   if (callbackid != SASL_CB_LANGUAGE)
16787c478bd9Sstevel@tonic-gate     _sasl_log(conn, SASL_LOG_NONE, "Unable to find a callback: %d", callbackid);
16797c478bd9Sstevel@tonic-gate #else
16807c478bd9Sstevel@tonic-gate   sasl_seterror(conn, SASL_NOLOG, "Unable to find a callback: %d", callbackid);
16817c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */
16827c478bd9Sstevel@tonic-gate   RETURN(conn,SASL_FAIL);
16837c478bd9Sstevel@tonic-gate }
16847c478bd9Sstevel@tonic-gate 
16857c478bd9Sstevel@tonic-gate 
16867c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_
16877c478bd9Sstevel@tonic-gate static void ___sasl_log (const _sasl_global_context_t *gctx,
16887c478bd9Sstevel@tonic-gate 			sasl_log_t *log_cb, void *log_ctx,
16897c478bd9Sstevel@tonic-gate 			int level, const char *fmt, va_list ap);
16907c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */
16917c478bd9Sstevel@tonic-gate /*
16927c478bd9Sstevel@tonic-gate  * This function is typically called from a plugin.
16937c478bd9Sstevel@tonic-gate  * It creates a string from the formatting and varargs given
16947c478bd9Sstevel@tonic-gate  * and calls the logging callback (syslog by default)
16957c478bd9Sstevel@tonic-gate  *
16967c478bd9Sstevel@tonic-gate  * %m will parse the value in the next argument as an errno string
16977c478bd9Sstevel@tonic-gate  * %z will parse the next argument as a SASL error code.
16987c478bd9Sstevel@tonic-gate  */
16997c478bd9Sstevel@tonic-gate 
17007c478bd9Sstevel@tonic-gate void
_sasl_log(sasl_conn_t * conn,int level,const char * fmt,...)17017c478bd9Sstevel@tonic-gate _sasl_log (sasl_conn_t *conn,
17027c478bd9Sstevel@tonic-gate 	   int level,
17037c478bd9Sstevel@tonic-gate 	   const char *fmt,
17047c478bd9Sstevel@tonic-gate 	   ...)
17057c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_
17067c478bd9Sstevel@tonic-gate {
17077c478bd9Sstevel@tonic-gate   _sasl_global_context_t *gctx = conn==NULL ? _sasl_gbl_ctx() : conn->gctx;
17087c478bd9Sstevel@tonic-gate   sasl_log_t *log_cb;
17097c478bd9Sstevel@tonic-gate   void *log_ctx;
17107c478bd9Sstevel@tonic-gate   int result;
17117c478bd9Sstevel@tonic-gate   va_list ap;
17127c478bd9Sstevel@tonic-gate 
17137c478bd9Sstevel@tonic-gate   /* See if we have a logging callback... */
17147c478bd9Sstevel@tonic-gate   result = _sasl_getcallback(conn, SASL_CB_LOG, &log_cb, &log_ctx);
17157c478bd9Sstevel@tonic-gate   if (result == SASL_OK && ! log_cb)
17167c478bd9Sstevel@tonic-gate     return;
17177c478bd9Sstevel@tonic-gate 
17187c478bd9Sstevel@tonic-gate   va_start(ap, fmt); /* start varargs */
17197c478bd9Sstevel@tonic-gate   ___sasl_log(gctx, log_cb, log_ctx, level, fmt, ap);
17207c478bd9Sstevel@tonic-gate   va_end(ap);
17217c478bd9Sstevel@tonic-gate }
17227c478bd9Sstevel@tonic-gate 
17237c478bd9Sstevel@tonic-gate void
__sasl_log(const _sasl_global_context_t * gctx,const sasl_callback_t * callbacks,int level,const char * fmt,...)17247c478bd9Sstevel@tonic-gate __sasl_log(const _sasl_global_context_t *gctx,
17257c478bd9Sstevel@tonic-gate 	   const sasl_callback_t *callbacks,
17267c478bd9Sstevel@tonic-gate 	   int level,
17277c478bd9Sstevel@tonic-gate 	   const char *fmt,
17287c478bd9Sstevel@tonic-gate 	   ...)
17297c478bd9Sstevel@tonic-gate {
17307c478bd9Sstevel@tonic-gate   sasl_log_t *log_cb = NULL;
17317c478bd9Sstevel@tonic-gate   void *log_ctx = NULL;
17327c478bd9Sstevel@tonic-gate   int result;
17337c478bd9Sstevel@tonic-gate   va_list ap;
17347c478bd9Sstevel@tonic-gate 
17357c478bd9Sstevel@tonic-gate   if (callbacks)
17367c478bd9Sstevel@tonic-gate     while (callbacks->id != SASL_CB_LIST_END) {
17377c478bd9Sstevel@tonic-gate       if (callbacks->id == SASL_CB_LOG) {
17387c478bd9Sstevel@tonic-gate 	log_cb = callbacks->proc;
17397c478bd9Sstevel@tonic-gate 	log_ctx = callbacks->context;
17407c478bd9Sstevel@tonic-gate 	break;
17417c478bd9Sstevel@tonic-gate       }
17427c478bd9Sstevel@tonic-gate       ++callbacks;
17437c478bd9Sstevel@tonic-gate     }
17447c478bd9Sstevel@tonic-gate 
17457c478bd9Sstevel@tonic-gate   if (log_cb == NULL) {
17467c478bd9Sstevel@tonic-gate     result = _sasl_getcallback(NULL, SASL_CB_LOG, &log_cb, &log_ctx);
17477c478bd9Sstevel@tonic-gate     if (result != SASL_OK || ! log_cb)
17487c478bd9Sstevel@tonic-gate 	return;
17497c478bd9Sstevel@tonic-gate   }
17507c478bd9Sstevel@tonic-gate 
17517c478bd9Sstevel@tonic-gate   if (gctx == NULL)
17527c478bd9Sstevel@tonic-gate     gctx = _sasl_gbl_ctx();
17537c478bd9Sstevel@tonic-gate 
17547c478bd9Sstevel@tonic-gate   va_start(ap, fmt); /* start varargs */
17557c478bd9Sstevel@tonic-gate   ___sasl_log(gctx, log_cb, log_ctx, level, fmt, ap);
17567c478bd9Sstevel@tonic-gate   va_end(ap);
17577c478bd9Sstevel@tonic-gate }
17587c478bd9Sstevel@tonic-gate 
17597c478bd9Sstevel@tonic-gate static void
___sasl_log(const _sasl_global_context_t * gctx,sasl_log_t * log_cb,void * log_ctx,int level,const char * fmt,va_list ap)17607c478bd9Sstevel@tonic-gate ___sasl_log(const _sasl_global_context_t *gctx,
17617c478bd9Sstevel@tonic-gate 	    sasl_log_t *log_cb,
17627c478bd9Sstevel@tonic-gate 	    void *log_ctx,
17637c478bd9Sstevel@tonic-gate 	    int level,
17647c478bd9Sstevel@tonic-gate 	    const char *fmt,
17657c478bd9Sstevel@tonic-gate 	    va_list ap)
17667c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */
17677c478bd9Sstevel@tonic-gate {
17687c478bd9Sstevel@tonic-gate   char *out=(char *) sasl_ALLOC(250);
17697c478bd9Sstevel@tonic-gate   size_t alloclen=100; /* current allocated length */
17707c478bd9Sstevel@tonic-gate   size_t outlen=0; /* current length of output buffer */
17717c478bd9Sstevel@tonic-gate   size_t formatlen;
17727c478bd9Sstevel@tonic-gate   size_t pos=0; /* current position in format string */
17737c478bd9Sstevel@tonic-gate   int result;
17747c478bd9Sstevel@tonic-gate #ifndef _SUN_SDK_
17757c478bd9Sstevel@tonic-gate   sasl_log_t *log_cb;
17767c478bd9Sstevel@tonic-gate   void *log_ctx;
17777c478bd9Sstevel@tonic-gate #endif /* !_SUN_SDK_ */
17787c478bd9Sstevel@tonic-gate 
17797c478bd9Sstevel@tonic-gate   int ival;
17807c478bd9Sstevel@tonic-gate   char *cval;
17817c478bd9Sstevel@tonic-gate #ifndef _SUN_SDK_
17827c478bd9Sstevel@tonic-gate   va_list ap; /* varargs thing */
17837c478bd9Sstevel@tonic-gate #endif /* !_SUN_SDK_ */
17847c478bd9Sstevel@tonic-gate 
17857c478bd9Sstevel@tonic-gate   if(!fmt) goto done;
17867c478bd9Sstevel@tonic-gate   if(!out) return;
17877c478bd9Sstevel@tonic-gate 
17887c478bd9Sstevel@tonic-gate   formatlen = strlen(fmt);
17897c478bd9Sstevel@tonic-gate 
17907c478bd9Sstevel@tonic-gate #ifndef _SUN_SDK_
17917c478bd9Sstevel@tonic-gate   /* See if we have a logging callback... */
17927c478bd9Sstevel@tonic-gate   result = _sasl_getcallback(conn, SASL_CB_LOG, &log_cb, &log_ctx);
17937c478bd9Sstevel@tonic-gate   if (result == SASL_OK && ! log_cb)
17947c478bd9Sstevel@tonic-gate     result = SASL_FAIL;
17957c478bd9Sstevel@tonic-gate   if (result != SASL_OK) goto done;
17967c478bd9Sstevel@tonic-gate 
17977c478bd9Sstevel@tonic-gate   va_start(ap, fmt); /* start varargs */
17987c478bd9Sstevel@tonic-gate #endif /* !_SUN_SDK_ */
17997c478bd9Sstevel@tonic-gate 
18007c478bd9Sstevel@tonic-gate   while(pos<formatlen)
18017c478bd9Sstevel@tonic-gate   {
18027c478bd9Sstevel@tonic-gate     if (fmt[pos]!='%') /* regular character */
18037c478bd9Sstevel@tonic-gate     {
18047c478bd9Sstevel@tonic-gate       result = _buf_alloc(&out, &alloclen, outlen+1);
18057c478bd9Sstevel@tonic-gate       if (result != SASL_OK) goto done;
18067c478bd9Sstevel@tonic-gate       out[outlen]=fmt[pos];
18077c478bd9Sstevel@tonic-gate       outlen++;
18087c478bd9Sstevel@tonic-gate       pos++;
18097c478bd9Sstevel@tonic-gate 
18107c478bd9Sstevel@tonic-gate     } else { /* formating thing */
18117c478bd9Sstevel@tonic-gate       int done=0;
18127c478bd9Sstevel@tonic-gate       char frmt[10];
18137c478bd9Sstevel@tonic-gate       int frmtpos=1;
18147c478bd9Sstevel@tonic-gate       char tempbuf[21];
18157c478bd9Sstevel@tonic-gate       frmt[0]='%';
18167c478bd9Sstevel@tonic-gate       pos++;
18177c478bd9Sstevel@tonic-gate 
18187c478bd9Sstevel@tonic-gate       while (done==0)
18197c478bd9Sstevel@tonic-gate       {
18207c478bd9Sstevel@tonic-gate 	switch(fmt[pos])
18217c478bd9Sstevel@tonic-gate 	  {
18227c478bd9Sstevel@tonic-gate 	  case 's': /* need to handle this */
18237c478bd9Sstevel@tonic-gate 	    cval = va_arg(ap, char *); /* get the next arg */
18247c478bd9Sstevel@tonic-gate 	    result = _sasl_add_string(&out, &alloclen,
18257c478bd9Sstevel@tonic-gate 				&outlen, cval);
18267c478bd9Sstevel@tonic-gate 
18277c478bd9Sstevel@tonic-gate 	    if (result != SASL_OK) /* add the string */
18287c478bd9Sstevel@tonic-gate 		goto done;
18297c478bd9Sstevel@tonic-gate 
18307c478bd9Sstevel@tonic-gate 	    done=1;
18317c478bd9Sstevel@tonic-gate 	    break;
18327c478bd9Sstevel@tonic-gate 
18337c478bd9Sstevel@tonic-gate 	  case '%': /* double % output the '%' character */
18347c478bd9Sstevel@tonic-gate 	    result = _buf_alloc(&out,&alloclen,outlen+1);
18357c478bd9Sstevel@tonic-gate 	    if (result != SASL_OK)
18367c478bd9Sstevel@tonic-gate 		goto done;
18377c478bd9Sstevel@tonic-gate 
18387c478bd9Sstevel@tonic-gate 	    out[outlen]='%';
18397c478bd9Sstevel@tonic-gate 	    outlen++;
18407c478bd9Sstevel@tonic-gate 	    done=1;
18417c478bd9Sstevel@tonic-gate 	    break;
18427c478bd9Sstevel@tonic-gate 
18437c478bd9Sstevel@tonic-gate 	  case 'm': /* insert the errno string */
18447c478bd9Sstevel@tonic-gate 	    result = _sasl_add_string(&out, &alloclen, &outlen,
18457c478bd9Sstevel@tonic-gate 				strerror(va_arg(ap, int)));
18467c478bd9Sstevel@tonic-gate 	    if (result != SASL_OK)
18477c478bd9Sstevel@tonic-gate 		goto done;
18487c478bd9Sstevel@tonic-gate 
18497c478bd9Sstevel@tonic-gate 	    done=1;
18507c478bd9Sstevel@tonic-gate 	    break;
18517c478bd9Sstevel@tonic-gate 
18527c478bd9Sstevel@tonic-gate 	  case 'z': /* insert the sasl error string */
18537c478bd9Sstevel@tonic-gate 	    result = _sasl_add_string(&out, &alloclen, &outlen,
18547c478bd9Sstevel@tonic-gate 				(char *) sasl_errstring(va_arg(ap, int),NULL,NULL));
18557c478bd9Sstevel@tonic-gate 	    if (result != SASL_OK)
18567c478bd9Sstevel@tonic-gate 		goto done;
18577c478bd9Sstevel@tonic-gate 
18587c478bd9Sstevel@tonic-gate 	    done=1;
18597c478bd9Sstevel@tonic-gate 	    break;
18607c478bd9Sstevel@tonic-gate 
18617c478bd9Sstevel@tonic-gate 	  case 'c':
18627c478bd9Sstevel@tonic-gate #ifndef _SUN_SDK_
18637c478bd9Sstevel@tonic-gate 	    frmt[frmtpos++]=fmt[pos];
18647c478bd9Sstevel@tonic-gate 	    frmt[frmtpos]=0;
18657c478bd9Sstevel@tonic-gate #endif /* !_SUN_SDK_ */
18667c478bd9Sstevel@tonic-gate 	    tempbuf[0] = (char) va_arg(ap, int); /* get the next arg */
18677c478bd9Sstevel@tonic-gate 	    tempbuf[1]='\0';
18687c478bd9Sstevel@tonic-gate 
18697c478bd9Sstevel@tonic-gate 	    /* now add the character */
18707c478bd9Sstevel@tonic-gate 	    result = _sasl_add_string(&out, &alloclen, &outlen, tempbuf);
18717c478bd9Sstevel@tonic-gate 	    if (result != SASL_OK)
18727c478bd9Sstevel@tonic-gate 		goto done;
18737c478bd9Sstevel@tonic-gate 
18747c478bd9Sstevel@tonic-gate 	    done=1;
18757c478bd9Sstevel@tonic-gate 	    break;
18767c478bd9Sstevel@tonic-gate 
18777c478bd9Sstevel@tonic-gate 	  case 'd':
18787c478bd9Sstevel@tonic-gate 	  case 'i':
18797c478bd9Sstevel@tonic-gate 	    frmt[frmtpos++]=fmt[pos];
18807c478bd9Sstevel@tonic-gate 	    frmt[frmtpos]=0;
18817c478bd9Sstevel@tonic-gate 	    ival = va_arg(ap, int); /* get the next arg */
18827c478bd9Sstevel@tonic-gate 
18837c478bd9Sstevel@tonic-gate 	    snprintf(tempbuf,20,frmt,ival); /* have snprintf do the work */
18847c478bd9Sstevel@tonic-gate 	    /* now add the string */
18857c478bd9Sstevel@tonic-gate 	    result = _sasl_add_string(&out, &alloclen, &outlen, tempbuf);
18867c478bd9Sstevel@tonic-gate 	    if (result != SASL_OK)
18877c478bd9Sstevel@tonic-gate 		goto done;
18887c478bd9Sstevel@tonic-gate 
18897c478bd9Sstevel@tonic-gate 	    done=1;
18907c478bd9Sstevel@tonic-gate 
18917c478bd9Sstevel@tonic-gate 	    break;
18927c478bd9Sstevel@tonic-gate 	  default:
18937c478bd9Sstevel@tonic-gate 	    frmt[frmtpos++]=fmt[pos]; /* add to the formating */
18947c478bd9Sstevel@tonic-gate 	    frmt[frmtpos]=0;
18957c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_
18967c478bd9Sstevel@tonic-gate 	    if (frmtpos > sizeof (frmt) - 2)
18977c478bd9Sstevel@tonic-gate #else
18987c478bd9Sstevel@tonic-gate 	    if (frmtpos>9)
18997c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */
19007c478bd9Sstevel@tonic-gate 	      done=1;
19017c478bd9Sstevel@tonic-gate 	  }
19027c478bd9Sstevel@tonic-gate 	pos++;
19037c478bd9Sstevel@tonic-gate 	if (pos>formatlen)
19047c478bd9Sstevel@tonic-gate 	  done=1;
19057c478bd9Sstevel@tonic-gate       }
19067c478bd9Sstevel@tonic-gate 
19077c478bd9Sstevel@tonic-gate     }
19087c478bd9Sstevel@tonic-gate   }
19097c478bd9Sstevel@tonic-gate 
19107c478bd9Sstevel@tonic-gate   /* put 0 at end */
19117c478bd9Sstevel@tonic-gate   result = _buf_alloc(&out, &alloclen, outlen+1);
19127c478bd9Sstevel@tonic-gate   if (result != SASL_OK) goto done;
19137c478bd9Sstevel@tonic-gate   out[outlen]=0;
19147c478bd9Sstevel@tonic-gate 
19157c478bd9Sstevel@tonic-gate   va_end(ap);
19167c478bd9Sstevel@tonic-gate 
19177c478bd9Sstevel@tonic-gate   /* send log message */
19187c478bd9Sstevel@tonic-gate   result = log_cb(log_ctx, level, out);
19197c478bd9Sstevel@tonic-gate 
19207c478bd9Sstevel@tonic-gate  done:
19217c478bd9Sstevel@tonic-gate   if(out) sasl_FREE(out);
19227c478bd9Sstevel@tonic-gate }
19237c478bd9Sstevel@tonic-gate 
19247c478bd9Sstevel@tonic-gate 
19257c478bd9Sstevel@tonic-gate 
19267c478bd9Sstevel@tonic-gate /* Allocate and Init a sasl_utils_t structure */
19277c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_
19287c478bd9Sstevel@tonic-gate sasl_utils_t *
_sasl_alloc_utils(_sasl_global_context_t * gctx,sasl_conn_t * conn,sasl_global_callbacks_t * global_callbacks)19297c478bd9Sstevel@tonic-gate _sasl_alloc_utils(_sasl_global_context_t *gctx, sasl_conn_t *conn,
19307c478bd9Sstevel@tonic-gate 		  sasl_global_callbacks_t *global_callbacks)
19317c478bd9Sstevel@tonic-gate #else
19327c478bd9Sstevel@tonic-gate sasl_utils_t *
19337c478bd9Sstevel@tonic-gate _sasl_alloc_utils(sasl_conn_t *conn,
19347c478bd9Sstevel@tonic-gate 		  sasl_global_callbacks_t *global_callbacks)
19357c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */
19367c478bd9Sstevel@tonic-gate {
19377c478bd9Sstevel@tonic-gate   sasl_utils_t *utils;
19387c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_
19397c478bd9Sstevel@tonic-gate   sasl_allocation_utils_t alloc;
19407c478bd9Sstevel@tonic-gate   sasl_mutex_utils_t mutex;
19417c478bd9Sstevel@tonic-gate 
19427c478bd9Sstevel@tonic-gate   LOCK_MUTEX(&malloc_global_mutex);
19437c478bd9Sstevel@tonic-gate   alloc = gctx->sasl_allocation_utils;
19447c478bd9Sstevel@tonic-gate   mutex = gctx->sasl_mutex_utils;
19457c478bd9Sstevel@tonic-gate   UNLOCK_MUTEX(&malloc_global_mutex);
19467c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */
19477c478bd9Sstevel@tonic-gate 
19487c478bd9Sstevel@tonic-gate   /* set util functions - need to do rest*/
19497c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_
19507c478bd9Sstevel@tonic-gate   utils=alloc.malloc(sizeof(sasl_utils_t));
19517c478bd9Sstevel@tonic-gate #else
19527c478bd9Sstevel@tonic-gate   utils=sasl_ALLOC(sizeof(sasl_utils_t));
19537c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */
19547c478bd9Sstevel@tonic-gate   if (utils==NULL)
19557c478bd9Sstevel@tonic-gate     return NULL;
19567c478bd9Sstevel@tonic-gate 
19577c478bd9Sstevel@tonic-gate   utils->conn = conn;
19587c478bd9Sstevel@tonic-gate 
19597c478bd9Sstevel@tonic-gate   sasl_randcreate(&utils->rpool);
19607c478bd9Sstevel@tonic-gate 
19617c478bd9Sstevel@tonic-gate   if (conn) {
19627c478bd9Sstevel@tonic-gate     utils->getopt = &_sasl_conn_getopt;
19637c478bd9Sstevel@tonic-gate     utils->getopt_context = conn;
19647c478bd9Sstevel@tonic-gate   } else {
19657c478bd9Sstevel@tonic-gate     utils->getopt = &_sasl_global_getopt;
19667c478bd9Sstevel@tonic-gate     utils->getopt_context = global_callbacks;
19677c478bd9Sstevel@tonic-gate   }
19687c478bd9Sstevel@tonic-gate 
19697c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_
19707c478bd9Sstevel@tonic-gate   utils->malloc=alloc.malloc;
19717c478bd9Sstevel@tonic-gate   utils->calloc=alloc.calloc;
19727c478bd9Sstevel@tonic-gate   utils->realloc=alloc.realloc;
19737c478bd9Sstevel@tonic-gate   utils->free=alloc.free;
19747c478bd9Sstevel@tonic-gate 
19757c478bd9Sstevel@tonic-gate   utils->mutex_alloc = mutex.alloc;
19767c478bd9Sstevel@tonic-gate   utils->mutex_lock = mutex.lock;
19777c478bd9Sstevel@tonic-gate   utils->mutex_unlock = mutex.unlock;
19787c478bd9Sstevel@tonic-gate   utils->mutex_free = mutex.free;
19797c478bd9Sstevel@tonic-gate #else
19807c478bd9Sstevel@tonic-gate   utils->malloc=_sasl_allocation_utils.malloc;
19817c478bd9Sstevel@tonic-gate   utils->calloc=_sasl_allocation_utils.calloc;
19827c478bd9Sstevel@tonic-gate   utils->realloc=_sasl_allocation_utils.realloc;
19837c478bd9Sstevel@tonic-gate   utils->free=_sasl_allocation_utils.free;
19847c478bd9Sstevel@tonic-gate 
19857c478bd9Sstevel@tonic-gate   utils->mutex_alloc = _sasl_mutex_utils.alloc;
19867c478bd9Sstevel@tonic-gate   utils->mutex_lock = _sasl_mutex_utils.lock;
19877c478bd9Sstevel@tonic-gate   utils->mutex_unlock = _sasl_mutex_utils.unlock;
19887c478bd9Sstevel@tonic-gate   utils->mutex_free = _sasl_mutex_utils.free;
19897c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */
19907c478bd9Sstevel@tonic-gate 
19917c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_
19927c478bd9Sstevel@tonic-gate   utils->MD5Init  = (void (*)(MD5_CTX *))&MD5Init;
19937c478bd9Sstevel@tonic-gate   utils->MD5Update= (void (*)
19947c478bd9Sstevel@tonic-gate 	(MD5_CTX *, const unsigned char *, unsigned int ))&MD5Update;
19957c478bd9Sstevel@tonic-gate   utils->MD5Final = (void (*)(unsigned char [16], MD5_CTX *))&MD5Final;
19967c478bd9Sstevel@tonic-gate #else
19977c478bd9Sstevel@tonic-gate   utils->MD5Init  = &_sasl_MD5Init;
19987c478bd9Sstevel@tonic-gate   utils->MD5Update= &_sasl_MD5Update;
19997c478bd9Sstevel@tonic-gate   utils->MD5Final = &_sasl_MD5Final;
20007c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */
20017c478bd9Sstevel@tonic-gate   utils->hmac_md5 = &_sasl_hmac_md5;
20027c478bd9Sstevel@tonic-gate   utils->hmac_md5_init = &_sasl_hmac_md5_init;
20037c478bd9Sstevel@tonic-gate   utils->hmac_md5_final = &_sasl_hmac_md5_final;
20047c478bd9Sstevel@tonic-gate   utils->hmac_md5_precalc = &_sasl_hmac_md5_precalc;
20057c478bd9Sstevel@tonic-gate   utils->hmac_md5_import = &_sasl_hmac_md5_import;
20067c478bd9Sstevel@tonic-gate   utils->mkchal = &sasl_mkchal;
20077c478bd9Sstevel@tonic-gate   utils->utf8verify = &sasl_utf8verify;
20087c478bd9Sstevel@tonic-gate   utils->rand=&sasl_rand;
20097c478bd9Sstevel@tonic-gate   utils->churn=&sasl_churn;
20107c478bd9Sstevel@tonic-gate   utils->checkpass=NULL;
20117c478bd9Sstevel@tonic-gate 
20127c478bd9Sstevel@tonic-gate   utils->encode64=&sasl_encode64;
20137c478bd9Sstevel@tonic-gate   utils->decode64=&sasl_decode64;
20147c478bd9Sstevel@tonic-gate 
20157c478bd9Sstevel@tonic-gate   utils->erasebuffer=&sasl_erasebuffer;
20167c478bd9Sstevel@tonic-gate 
20177c478bd9Sstevel@tonic-gate   utils->getprop=&sasl_getprop;
20187c478bd9Sstevel@tonic-gate   utils->setprop=&sasl_setprop;
20197c478bd9Sstevel@tonic-gate 
20207c478bd9Sstevel@tonic-gate   utils->getcallback=&_sasl_getcallback;
20217c478bd9Sstevel@tonic-gate 
20227c478bd9Sstevel@tonic-gate   utils->log=&_sasl_log;
20237c478bd9Sstevel@tonic-gate 
20247c478bd9Sstevel@tonic-gate   utils->seterror=&sasl_seterror;
20257c478bd9Sstevel@tonic-gate 
20267c478bd9Sstevel@tonic-gate #ifndef macintosh
20277c478bd9Sstevel@tonic-gate   /* Aux Property Utilities */
20287c478bd9Sstevel@tonic-gate   utils->prop_new=&prop_new;
20297c478bd9Sstevel@tonic-gate   utils->prop_dup=&prop_dup;
20307c478bd9Sstevel@tonic-gate   utils->prop_request=&prop_request;
20317c478bd9Sstevel@tonic-gate   utils->prop_get=&prop_get;
20327c478bd9Sstevel@tonic-gate   utils->prop_getnames=&prop_getnames;
20337c478bd9Sstevel@tonic-gate   utils->prop_clear=&prop_clear;
20347c478bd9Sstevel@tonic-gate   utils->prop_dispose=&prop_dispose;
20357c478bd9Sstevel@tonic-gate   utils->prop_format=&prop_format;
20367c478bd9Sstevel@tonic-gate   utils->prop_set=&prop_set;
20377c478bd9Sstevel@tonic-gate   utils->prop_setvals=&prop_setvals;
20387c478bd9Sstevel@tonic-gate   utils->prop_erase=&prop_erase;
20397c478bd9Sstevel@tonic-gate #endif
20407c478bd9Sstevel@tonic-gate 
20417c478bd9Sstevel@tonic-gate   /* Spares */
20427c478bd9Sstevel@tonic-gate   utils->spare_fptr = NULL;
20437c478bd9Sstevel@tonic-gate   utils->spare_fptr1 = utils->spare_fptr2 =
20447c478bd9Sstevel@tonic-gate       utils->spare_fptr3 = NULL;
20457c478bd9Sstevel@tonic-gate 
20467c478bd9Sstevel@tonic-gate   return utils;
20477c478bd9Sstevel@tonic-gate }
20487c478bd9Sstevel@tonic-gate 
20497c478bd9Sstevel@tonic-gate int
_sasl_free_utils(const sasl_utils_t ** utils)20507c478bd9Sstevel@tonic-gate _sasl_free_utils(const sasl_utils_t ** utils)
20517c478bd9Sstevel@tonic-gate {
20527c478bd9Sstevel@tonic-gate     sasl_utils_t *nonconst;
20537c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_
20547c478bd9Sstevel@tonic-gate     sasl_free_t *free_func;
20557c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */
20567c478bd9Sstevel@tonic-gate 
20577c478bd9Sstevel@tonic-gate     if(!utils) return SASL_BADPARAM;
20587c478bd9Sstevel@tonic-gate     if(!*utils) return SASL_OK;
20597c478bd9Sstevel@tonic-gate 
20607c478bd9Sstevel@tonic-gate     /* I wish we could avoid this cast, it's pretty gratuitous but it
20617c478bd9Sstevel@tonic-gate      * does make life easier to have it const everywhere else. */
20627c478bd9Sstevel@tonic-gate     nonconst = (sasl_utils_t *)(*utils);
20637c478bd9Sstevel@tonic-gate 
20647c478bd9Sstevel@tonic-gate     sasl_randfree(&(nonconst->rpool));
20657c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_
20667c478bd9Sstevel@tonic-gate     free_func = (*utils)->free;
20677c478bd9Sstevel@tonic-gate     free_func(nonconst);
20687c478bd9Sstevel@tonic-gate #else
20697c478bd9Sstevel@tonic-gate     sasl_FREE(nonconst);
20707c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */
20717c478bd9Sstevel@tonic-gate 
20727c478bd9Sstevel@tonic-gate     *utils = NULL;
20737c478bd9Sstevel@tonic-gate     return SASL_OK;
20747c478bd9Sstevel@tonic-gate }
20757c478bd9Sstevel@tonic-gate 
sasl_idle(sasl_conn_t * conn)20767c478bd9Sstevel@tonic-gate int sasl_idle(sasl_conn_t *conn)
20777c478bd9Sstevel@tonic-gate {
20787c478bd9Sstevel@tonic-gate   if (! conn) {
20797c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_
20807c478bd9Sstevel@tonic-gate     _sasl_global_context_t *gctx = _sasl_gbl_ctx();
20817c478bd9Sstevel@tonic-gate 
20827c478bd9Sstevel@tonic-gate     if (gctx->sasl_server_idle_hook
20837c478bd9Sstevel@tonic-gate         && gctx->sasl_server_idle_hook(NULL))
20847c478bd9Sstevel@tonic-gate       return 1;
20857c478bd9Sstevel@tonic-gate     if (gctx->sasl_client_idle_hook
20867c478bd9Sstevel@tonic-gate         && gctx->sasl_client_idle_hook(NULL))
20877c478bd9Sstevel@tonic-gate       return 1;
20887c478bd9Sstevel@tonic-gate #else
20897c478bd9Sstevel@tonic-gate     if (_sasl_server_idle_hook
20907c478bd9Sstevel@tonic-gate 	&& _sasl_server_idle_hook(NULL))
20917c478bd9Sstevel@tonic-gate       return 1;
20927c478bd9Sstevel@tonic-gate     if (_sasl_client_idle_hook
20937c478bd9Sstevel@tonic-gate 	&& _sasl_client_idle_hook(NULL))
20947c478bd9Sstevel@tonic-gate       return 1;
20957c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */
20967c478bd9Sstevel@tonic-gate     return 0;
20977c478bd9Sstevel@tonic-gate   }
20987c478bd9Sstevel@tonic-gate 
20997c478bd9Sstevel@tonic-gate   if (conn->idle_hook)
21007c478bd9Sstevel@tonic-gate     return conn->idle_hook(conn);
21017c478bd9Sstevel@tonic-gate 
21027c478bd9Sstevel@tonic-gate   return 0;
21037c478bd9Sstevel@tonic-gate }
21047c478bd9Sstevel@tonic-gate 
21057c478bd9Sstevel@tonic-gate const sasl_callback_t *
_sasl_find_getpath_callback(const sasl_callback_t * callbacks)21067c478bd9Sstevel@tonic-gate _sasl_find_getpath_callback(const sasl_callback_t *callbacks)
21077c478bd9Sstevel@tonic-gate {
21087c478bd9Sstevel@tonic-gate   static const sasl_callback_t default_getpath_cb = {
21097c478bd9Sstevel@tonic-gate     SASL_CB_GETPATH,
21107c478bd9Sstevel@tonic-gate     &_sasl_getpath,
21117c478bd9Sstevel@tonic-gate     NULL
21127c478bd9Sstevel@tonic-gate   };
21137c478bd9Sstevel@tonic-gate 
21147c478bd9Sstevel@tonic-gate   if (callbacks)
21157c478bd9Sstevel@tonic-gate     while (callbacks->id != SASL_CB_LIST_END)
21167c478bd9Sstevel@tonic-gate     {
21177c478bd9Sstevel@tonic-gate       if (callbacks->id == SASL_CB_GETPATH)
21187c478bd9Sstevel@tonic-gate       {
21197c478bd9Sstevel@tonic-gate 	return callbacks;
21207c478bd9Sstevel@tonic-gate       } else {
21217c478bd9Sstevel@tonic-gate 	++callbacks;
21227c478bd9Sstevel@tonic-gate       }
21237c478bd9Sstevel@tonic-gate     }
21247c478bd9Sstevel@tonic-gate 
21257c478bd9Sstevel@tonic-gate   return &default_getpath_cb;
21267c478bd9Sstevel@tonic-gate }
21277c478bd9Sstevel@tonic-gate 
21287c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_
21297c478bd9Sstevel@tonic-gate extern const sasl_callback_t *
_sasl_find_getconf_callback(const sasl_callback_t * callbacks)21307c478bd9Sstevel@tonic-gate _sasl_find_getconf_callback(const sasl_callback_t *callbacks)
21317c478bd9Sstevel@tonic-gate {
21327c478bd9Sstevel@tonic-gate   static const sasl_callback_t default_getconf_cb = {
21337c478bd9Sstevel@tonic-gate     SASL_CB_GETCONF,
21347c478bd9Sstevel@tonic-gate     &_sasl_getconf,
21357c478bd9Sstevel@tonic-gate     NULL
21367c478bd9Sstevel@tonic-gate   };
21377c478bd9Sstevel@tonic-gate 
21387c478bd9Sstevel@tonic-gate   if (callbacks)
21397c478bd9Sstevel@tonic-gate     while (callbacks->id != SASL_CB_LIST_END)
21407c478bd9Sstevel@tonic-gate     {
21417c478bd9Sstevel@tonic-gate       if (callbacks->id == SASL_CB_GETCONF)
21427c478bd9Sstevel@tonic-gate       {
21437c478bd9Sstevel@tonic-gate 	return callbacks;
21447c478bd9Sstevel@tonic-gate       } else {
21457c478bd9Sstevel@tonic-gate 	++callbacks;
21467c478bd9Sstevel@tonic-gate       }
21477c478bd9Sstevel@tonic-gate     }
21487c478bd9Sstevel@tonic-gate 
21497c478bd9Sstevel@tonic-gate   return &default_getconf_cb;
21507c478bd9Sstevel@tonic-gate }
21517c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */
21527c478bd9Sstevel@tonic-gate 
21537c478bd9Sstevel@tonic-gate const sasl_callback_t *
_sasl_find_verifyfile_callback(const sasl_callback_t * callbacks)21547c478bd9Sstevel@tonic-gate _sasl_find_verifyfile_callback(const sasl_callback_t *callbacks)
21557c478bd9Sstevel@tonic-gate {
21567c478bd9Sstevel@tonic-gate   static const sasl_callback_t default_verifyfile_cb = {
21577c478bd9Sstevel@tonic-gate     SASL_CB_VERIFYFILE,
21587c478bd9Sstevel@tonic-gate     &_sasl_verifyfile,
21597c478bd9Sstevel@tonic-gate     NULL
21607c478bd9Sstevel@tonic-gate   };
21617c478bd9Sstevel@tonic-gate 
21627c478bd9Sstevel@tonic-gate   if (callbacks)
21637c478bd9Sstevel@tonic-gate     while (callbacks->id != SASL_CB_LIST_END)
21647c478bd9Sstevel@tonic-gate     {
21657c478bd9Sstevel@tonic-gate       if (callbacks->id == SASL_CB_VERIFYFILE)
21667c478bd9Sstevel@tonic-gate       {
21677c478bd9Sstevel@tonic-gate 	return callbacks;
21687c478bd9Sstevel@tonic-gate       } else {
21697c478bd9Sstevel@tonic-gate 	++callbacks;
21707c478bd9Sstevel@tonic-gate       }
21717c478bd9Sstevel@tonic-gate     }
21727c478bd9Sstevel@tonic-gate 
21737c478bd9Sstevel@tonic-gate   return &default_verifyfile_cb;
21747c478bd9Sstevel@tonic-gate }
21757c478bd9Sstevel@tonic-gate 
21767c478bd9Sstevel@tonic-gate /* Basically a conditional call to realloc(), if we need more */
21777c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_
__buf_alloc(const _sasl_global_context_t * gctx,char ** rwbuf,size_t * curlen,size_t newlen)21787c478bd9Sstevel@tonic-gate int __buf_alloc(const _sasl_global_context_t *gctx, char **rwbuf,
21797c478bd9Sstevel@tonic-gate 		size_t *curlen, size_t newlen)
21807c478bd9Sstevel@tonic-gate #else
21817c478bd9Sstevel@tonic-gate int _buf_alloc(char **rwbuf, size_t *curlen, size_t newlen)
21827c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */
21837c478bd9Sstevel@tonic-gate {
21847c478bd9Sstevel@tonic-gate     if(!(*rwbuf)) {
21857c478bd9Sstevel@tonic-gate 	*rwbuf = sasl_ALLOC(newlen);
21867c478bd9Sstevel@tonic-gate 	if (*rwbuf == NULL) {
21877c478bd9Sstevel@tonic-gate 	    *curlen = 0;
21887c478bd9Sstevel@tonic-gate 	    return SASL_NOMEM;
21897c478bd9Sstevel@tonic-gate 	}
21907c478bd9Sstevel@tonic-gate 	*curlen = newlen;
21917c478bd9Sstevel@tonic-gate     } else if(*rwbuf && *curlen < newlen) {
21927c478bd9Sstevel@tonic-gate 	size_t needed = 2*(*curlen);
21937c478bd9Sstevel@tonic-gate 
21947c478bd9Sstevel@tonic-gate 	while(needed < newlen)
21957c478bd9Sstevel@tonic-gate 	    needed *= 2;
21967c478bd9Sstevel@tonic-gate 
21977c478bd9Sstevel@tonic-gate 	*rwbuf = sasl_REALLOC(*rwbuf, needed);
21987c478bd9Sstevel@tonic-gate 
21997c478bd9Sstevel@tonic-gate 	if (*rwbuf == NULL) {
22007c478bd9Sstevel@tonic-gate 	    *curlen = 0;
22017c478bd9Sstevel@tonic-gate 	    return SASL_NOMEM;
22027c478bd9Sstevel@tonic-gate 	}
22037c478bd9Sstevel@tonic-gate 	*curlen = needed;
22047c478bd9Sstevel@tonic-gate     }
22057c478bd9Sstevel@tonic-gate 
22067c478bd9Sstevel@tonic-gate     return SASL_OK;
22077c478bd9Sstevel@tonic-gate }
22087c478bd9Sstevel@tonic-gate 
22097c478bd9Sstevel@tonic-gate /* for the mac os x cfm glue: this lets the calling function
22107c478bd9Sstevel@tonic-gate    get pointers to the error buffer without having to touch the sasl_conn_t struct */
_sasl_get_errorbuf(sasl_conn_t * conn,char *** bufhdl,size_t ** lenhdl)22117c478bd9Sstevel@tonic-gate void _sasl_get_errorbuf(sasl_conn_t *conn, char ***bufhdl, size_t **lenhdl)
22127c478bd9Sstevel@tonic-gate {
22137c478bd9Sstevel@tonic-gate 	*bufhdl = &conn->error_buf;
22147c478bd9Sstevel@tonic-gate 	*lenhdl = &conn->error_buf_len;
22157c478bd9Sstevel@tonic-gate }
22167c478bd9Sstevel@tonic-gate 
22177c478bd9Sstevel@tonic-gate /* convert an iovec to a single buffer */
22187c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_
_iovec_to_buf(const _sasl_global_context_t * gctx,const struct iovec * vec,unsigned numiov,buffer_info_t ** output)22197c478bd9Sstevel@tonic-gate int _iovec_to_buf(const _sasl_global_context_t *gctx, const struct iovec *vec,
22207c478bd9Sstevel@tonic-gate 		  unsigned numiov, buffer_info_t **output)
22217c478bd9Sstevel@tonic-gate #else
22227c478bd9Sstevel@tonic-gate int _iovec_to_buf(const struct iovec *vec,
22237c478bd9Sstevel@tonic-gate 		  unsigned numiov, buffer_info_t **output)
22247c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */
22257c478bd9Sstevel@tonic-gate {
22267c478bd9Sstevel@tonic-gate     unsigned i;
22277c478bd9Sstevel@tonic-gate     int ret;
22287c478bd9Sstevel@tonic-gate     buffer_info_t *out;
22297c478bd9Sstevel@tonic-gate     char *pos;
22307c478bd9Sstevel@tonic-gate 
22317c478bd9Sstevel@tonic-gate     if(!vec || !output) return SASL_BADPARAM;
22327c478bd9Sstevel@tonic-gate 
22337c478bd9Sstevel@tonic-gate     if(!(*output)) {
22347c478bd9Sstevel@tonic-gate 	*output = sasl_ALLOC(sizeof(buffer_info_t));
22357c478bd9Sstevel@tonic-gate 	if(!*output) return SASL_NOMEM;
22367c478bd9Sstevel@tonic-gate 	memset(*output,0,sizeof(buffer_info_t));
22377c478bd9Sstevel@tonic-gate     }
22387c478bd9Sstevel@tonic-gate 
22397c478bd9Sstevel@tonic-gate     out = *output;
22407c478bd9Sstevel@tonic-gate 
22417c478bd9Sstevel@tonic-gate     out->curlen = 0;
22427c478bd9Sstevel@tonic-gate     for(i=0; i<numiov; i++)
22437c478bd9Sstevel@tonic-gate 	out->curlen += vec[i].iov_len;
22447c478bd9Sstevel@tonic-gate 
22457c478bd9Sstevel@tonic-gate     ret = _buf_alloc(&out->data, &out->reallen, out->curlen);
22467c478bd9Sstevel@tonic-gate 
22477c478bd9Sstevel@tonic-gate     if(ret != SASL_OK) return SASL_NOMEM;
22487c478bd9Sstevel@tonic-gate 
22497c478bd9Sstevel@tonic-gate     memset(out->data, 0, out->reallen);
22507c478bd9Sstevel@tonic-gate     pos = out->data;
22517c478bd9Sstevel@tonic-gate 
22527c478bd9Sstevel@tonic-gate     for(i=0; i<numiov; i++) {
22537c478bd9Sstevel@tonic-gate 	memcpy(pos, vec[i].iov_base, vec[i].iov_len);
22547c478bd9Sstevel@tonic-gate 	pos += vec[i].iov_len;
22557c478bd9Sstevel@tonic-gate     }
22567c478bd9Sstevel@tonic-gate 
22577c478bd9Sstevel@tonic-gate     return SASL_OK;
22587c478bd9Sstevel@tonic-gate }
22597c478bd9Sstevel@tonic-gate 
22607c478bd9Sstevel@tonic-gate /* This code might be useful in the future, but it isn't now, so.... */
22617c478bd9Sstevel@tonic-gate #if 0
22627c478bd9Sstevel@tonic-gate int _sasl_iptostring(const struct sockaddr *addr, socklen_t addrlen,
22637c478bd9Sstevel@tonic-gate 		     char *out, unsigned outlen) {
22647c478bd9Sstevel@tonic-gate     char hbuf[NI_MAXHOST], pbuf[NI_MAXSERV];
22657c478bd9Sstevel@tonic-gate 
22667c478bd9Sstevel@tonic-gate     if(!addr || !out) return SASL_BADPARAM;
22677c478bd9Sstevel@tonic-gate 
22687c478bd9Sstevel@tonic-gate     getnameinfo(addr, addrlen, hbuf, sizeof(hbuf), pbuf, sizeof(pbuf),
22697c478bd9Sstevel@tonic-gate 		NI_NUMERICHOST | NI_WITHSCOPEID | NI_NUMERICSERV);
22707c478bd9Sstevel@tonic-gate 
22717c478bd9Sstevel@tonic-gate     if(outlen < strlen(hbuf) + strlen(pbuf) + 2)
22727c478bd9Sstevel@tonic-gate 	return SASL_BUFOVER;
22737c478bd9Sstevel@tonic-gate 
22747c478bd9Sstevel@tonic-gate     snprintf(out, outlen, "%s;%s", hbuf, pbuf);
22757c478bd9Sstevel@tonic-gate 
22767c478bd9Sstevel@tonic-gate     return SASL_OK;
22777c478bd9Sstevel@tonic-gate }
22787c478bd9Sstevel@tonic-gate #endif
22797c478bd9Sstevel@tonic-gate 
22807c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_
22817c478bd9Sstevel@tonic-gate /* An ipv6 address will contain at least two colons */
can_be_ipv6(const char * addr)22827c478bd9Sstevel@tonic-gate static int can_be_ipv6(const char *addr)
22837c478bd9Sstevel@tonic-gate {
22847c478bd9Sstevel@tonic-gate    const char *p;
22857c478bd9Sstevel@tonic-gate 
22867c478bd9Sstevel@tonic-gate    if ((p = strchr(addr, ':')) == NULL)
22877c478bd9Sstevel@tonic-gate 	return (0);
22887c478bd9Sstevel@tonic-gate 
22897c478bd9Sstevel@tonic-gate    p = strchr(p + 1, ':');
22907c478bd9Sstevel@tonic-gate 
22917c478bd9Sstevel@tonic-gate    return (p != NULL);
22927c478bd9Sstevel@tonic-gate }
22937c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */
22947c478bd9Sstevel@tonic-gate 
_sasl_ipfromstring(const char * addr,struct sockaddr * out,socklen_t outlen)22957c478bd9Sstevel@tonic-gate int _sasl_ipfromstring(const char *addr,
22967c478bd9Sstevel@tonic-gate 		       struct sockaddr *out, socklen_t outlen)
22977c478bd9Sstevel@tonic-gate {
22987c478bd9Sstevel@tonic-gate     int i, j;
22997c478bd9Sstevel@tonic-gate     struct addrinfo hints, *ai = NULL;
23007c478bd9Sstevel@tonic-gate     char hbuf[NI_MAXHOST];
23017c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_
23027c478bd9Sstevel@tonic-gate     const char *start, *end, *p;
23037c478bd9Sstevel@tonic-gate     int addr_only = 1;
23047c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */
23057c478bd9Sstevel@tonic-gate 
23067c478bd9Sstevel@tonic-gate     /* A NULL out pointer just implies we don't do a copy, just verify it */
23077c478bd9Sstevel@tonic-gate 
23087c478bd9Sstevel@tonic-gate     if(!addr) return SASL_BADPARAM;
23097c478bd9Sstevel@tonic-gate 
23107c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_
23117c478bd9Sstevel@tonic-gate     end = strchr(addr, ']');
23127c478bd9Sstevel@tonic-gate     if (end != NULL) {
23137c478bd9Sstevel@tonic-gate 	/* This an rfc 2732 ipv6 address */
23147c478bd9Sstevel@tonic-gate 	start = strchr(addr, '[');
23157c478bd9Sstevel@tonic-gate 	if (start >= end || start == NULL)
23167c478bd9Sstevel@tonic-gate 	    return SASL_BADPARAM;
23177c478bd9Sstevel@tonic-gate 	for (i = 0, p = start + 1; p < end; p++) {
23187c478bd9Sstevel@tonic-gate 	    hbuf[i++] = *p;
23197c478bd9Sstevel@tonic-gate 	    if (i >= NI_MAXHOST)
23207c478bd9Sstevel@tonic-gate 		return SASL_BADPARAM;
23217c478bd9Sstevel@tonic-gate 	}
23227c478bd9Sstevel@tonic-gate 	p = strchr(end, ':');
23237c478bd9Sstevel@tonic-gate 	if (p == NULL)
23247c478bd9Sstevel@tonic-gate 		p = end + 1;
23257c478bd9Sstevel@tonic-gate 	else
23267c478bd9Sstevel@tonic-gate 		p = p + 1;
23277c478bd9Sstevel@tonic-gate     } else if (can_be_ipv6(addr) != 0) {
23287c478bd9Sstevel@tonic-gate 	/* Parse the address */
23297c478bd9Sstevel@tonic-gate 	for (i = 0; addr[i] != '\0' && addr[i] != ';'; ) {
23307c478bd9Sstevel@tonic-gate 	    hbuf[i] = addr[i];
23317c478bd9Sstevel@tonic-gate 	    if (++i >= NI_MAXHOST)
23327c478bd9Sstevel@tonic-gate 		return SASL_BADPARAM;
23337c478bd9Sstevel@tonic-gate 	}
23347c478bd9Sstevel@tonic-gate 	if (addr[i] == ';')
23357c478bd9Sstevel@tonic-gate 	     p = &addr[i+1];
23367c478bd9Sstevel@tonic-gate 	else
23377c478bd9Sstevel@tonic-gate 	     p = &addr[i];
23387c478bd9Sstevel@tonic-gate     } else {
23397c478bd9Sstevel@tonic-gate 	for (i = 0; addr[i] != '\0' && addr[i] != ';' && addr[i] != ':'; ) {
23407c478bd9Sstevel@tonic-gate 	    hbuf[i] = addr[i];
23417c478bd9Sstevel@tonic-gate 	    if (isalpha(addr[i]))
23427c478bd9Sstevel@tonic-gate 		addr_only = 0;
23437c478bd9Sstevel@tonic-gate 	    if (++i >= NI_MAXHOST)
23447c478bd9Sstevel@tonic-gate 		return SASL_BADPARAM;
23457c478bd9Sstevel@tonic-gate 	}
23467c478bd9Sstevel@tonic-gate 	if (addr[i] == ';' || addr[i] == ':')
23477c478bd9Sstevel@tonic-gate 	     p = &addr[i+1];
23487c478bd9Sstevel@tonic-gate 	else
23497c478bd9Sstevel@tonic-gate 	     p = &addr[i];
23507c478bd9Sstevel@tonic-gate     }
23517c478bd9Sstevel@tonic-gate     hbuf[i] = '\0';
23527c478bd9Sstevel@tonic-gate     for (j = 0; p[j] != '\0'; j++)
23537c478bd9Sstevel@tonic-gate 	if (!isdigit((int)(p[j])))
23547c478bd9Sstevel@tonic-gate 	    return SASL_BADPARAM;
23557c478bd9Sstevel@tonic-gate     if (atoi(p) == 0)
23567c478bd9Sstevel@tonic-gate 	p = NULL;
23577c478bd9Sstevel@tonic-gate #else
23587c478bd9Sstevel@tonic-gate     /* Parse the address */
23597c478bd9Sstevel@tonic-gate     for (i = 0; addr[i] != '\0' && addr[i] != ';'; i++) {
23607c478bd9Sstevel@tonic-gate 	if (i >= NI_MAXHOST)
23617c478bd9Sstevel@tonic-gate 	    return SASL_BADPARAM;
23627c478bd9Sstevel@tonic-gate 	hbuf[i] = addr[i];
23637c478bd9Sstevel@tonic-gate     }
23647c478bd9Sstevel@tonic-gate     hbuf[i] = '\0';
23657c478bd9Sstevel@tonic-gate 
23667c478bd9Sstevel@tonic-gate     if (addr[i] == ';')
23677c478bd9Sstevel@tonic-gate 	i++;
23687c478bd9Sstevel@tonic-gate     /* XXX: Do we need this check? */
23697c478bd9Sstevel@tonic-gate     for (j = i; addr[j] != '\0'; j++)
23707c478bd9Sstevel@tonic-gate 	if (!isdigit((int)(addr[j])))
23717c478bd9Sstevel@tonic-gate 	    return SASL_BADPARAM;
23727c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */
23737c478bd9Sstevel@tonic-gate 
23747c478bd9Sstevel@tonic-gate     memset(&hints, 0, sizeof(hints));
23757c478bd9Sstevel@tonic-gate     hints.ai_family = PF_UNSPEC;
23767c478bd9Sstevel@tonic-gate     hints.ai_socktype = SOCK_STREAM;
23777c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_
23787c478bd9Sstevel@tonic-gate     hints.ai_flags = addr_only ? AI_PASSIVE | AI_NUMERICHOST : AI_PASSIVE;
23797c478bd9Sstevel@tonic-gate     if (getaddrinfo(hbuf, p, &hints, &ai) != 0)
23807c478bd9Sstevel@tonic-gate #else
23817c478bd9Sstevel@tonic-gate     hints.ai_flags = AI_PASSIVE | AI_NUMERICHOST;
23827c478bd9Sstevel@tonic-gate     if (getaddrinfo(hbuf, &addr[i], &hints, &ai) != 0)
23837c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */
23847c478bd9Sstevel@tonic-gate 	return SASL_BADPARAM;
23857c478bd9Sstevel@tonic-gate 
23867c478bd9Sstevel@tonic-gate     if (out) {
23877c478bd9Sstevel@tonic-gate 	if (outlen < (socklen_t)ai->ai_addrlen) {
23887c478bd9Sstevel@tonic-gate 	    freeaddrinfo(ai);
23897c478bd9Sstevel@tonic-gate 	    return SASL_BUFOVER;
23907c478bd9Sstevel@tonic-gate 	}
23917c478bd9Sstevel@tonic-gate 	memcpy(out, ai->ai_addr, ai->ai_addrlen);
23927c478bd9Sstevel@tonic-gate     }
23937c478bd9Sstevel@tonic-gate 
23947c478bd9Sstevel@tonic-gate     freeaddrinfo(ai);
23957c478bd9Sstevel@tonic-gate 
23967c478bd9Sstevel@tonic-gate     return SASL_OK;
23977c478bd9Sstevel@tonic-gate }
23987c478bd9Sstevel@tonic-gate 
23997c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_
_sasl_build_mechlist(_sasl_global_context_t * gctx)24007c478bd9Sstevel@tonic-gate int _sasl_build_mechlist(_sasl_global_context_t *gctx)
24017c478bd9Sstevel@tonic-gate #else
24027c478bd9Sstevel@tonic-gate int _sasl_build_mechlist(void)
24037c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */
24047c478bd9Sstevel@tonic-gate {
24057c478bd9Sstevel@tonic-gate     int count = 0;
24067c478bd9Sstevel@tonic-gate     sasl_string_list_t *clist = NULL, *slist = NULL, *olist = NULL;
24077c478bd9Sstevel@tonic-gate     sasl_string_list_t *p, *q, **last, *p_next;
24087c478bd9Sstevel@tonic-gate 
24097c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_
24107c478bd9Sstevel@tonic-gate     char **global_mech_list;
24117c478bd9Sstevel@tonic-gate 
24127c478bd9Sstevel@tonic-gate     LOCK_MUTEX(&global_mutex);
24137c478bd9Sstevel@tonic-gate 
24147c478bd9Sstevel@tonic-gate     clist = _sasl_client_mechs(gctx);
24157c478bd9Sstevel@tonic-gate     slist = _sasl_server_mechs(gctx);
24167c478bd9Sstevel@tonic-gate 
24177c478bd9Sstevel@tonic-gate     global_mech_list = gctx->global_mech_list;
24187c478bd9Sstevel@tonic-gate #else
24197c478bd9Sstevel@tonic-gate     clist = _sasl_client_mechs();
24207c478bd9Sstevel@tonic-gate     slist = _sasl_server_mechs();
24217c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */
24227c478bd9Sstevel@tonic-gate 
24237c478bd9Sstevel@tonic-gate     if(!clist) {
24247c478bd9Sstevel@tonic-gate 	olist = slist;
24257c478bd9Sstevel@tonic-gate     } else {
24267c478bd9Sstevel@tonic-gate 	int flag;
24277c478bd9Sstevel@tonic-gate 
24287c478bd9Sstevel@tonic-gate 	/* append slist to clist, and set olist to clist */
24297c478bd9Sstevel@tonic-gate 	for(p = slist; p; p = p_next) {
24307c478bd9Sstevel@tonic-gate 	    flag = 0;
24317c478bd9Sstevel@tonic-gate 	    p_next = p->next;
24327c478bd9Sstevel@tonic-gate 
24337c478bd9Sstevel@tonic-gate 	    last = &clist;
24347c478bd9Sstevel@tonic-gate 	    for(q = clist; q; q = q->next) {
24357c478bd9Sstevel@tonic-gate 		if(!strcmp(q->d, p->d)) {
24367c478bd9Sstevel@tonic-gate 		    /* They match, set the flag */
24377c478bd9Sstevel@tonic-gate 		    flag = 1;
24387c478bd9Sstevel@tonic-gate 		    break;
24397c478bd9Sstevel@tonic-gate 		}
24407c478bd9Sstevel@tonic-gate 		last = &(q->next);
24417c478bd9Sstevel@tonic-gate 	    }
24427c478bd9Sstevel@tonic-gate 
24437c478bd9Sstevel@tonic-gate 	    if(!flag) {
24447c478bd9Sstevel@tonic-gate 		*last = p;
24457c478bd9Sstevel@tonic-gate 		p->next = NULL;
24467c478bd9Sstevel@tonic-gate 	    } else {
24477c478bd9Sstevel@tonic-gate 		sasl_FREE(p);
24487c478bd9Sstevel@tonic-gate 	    }
24497c478bd9Sstevel@tonic-gate 	}
24507c478bd9Sstevel@tonic-gate 
24517c478bd9Sstevel@tonic-gate 	olist = clist;
24527c478bd9Sstevel@tonic-gate     }
24537c478bd9Sstevel@tonic-gate 
24547c478bd9Sstevel@tonic-gate     if(!olist) {
24557c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_
24567c478bd9Sstevel@tonic-gate 	UNLOCK_MUTEX(&global_mutex);
24577c478bd9Sstevel@tonic-gate #else
24587c478bd9Sstevel@tonic-gate 	printf ("no olist");
24597c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */
24607c478bd9Sstevel@tonic-gate 	return SASL_FAIL;
24617c478bd9Sstevel@tonic-gate     }
24627c478bd9Sstevel@tonic-gate 
24637c478bd9Sstevel@tonic-gate     for (p = olist; p; p = p->next) count++;
24647c478bd9Sstevel@tonic-gate 
24657c478bd9Sstevel@tonic-gate     if(global_mech_list) {
24667c478bd9Sstevel@tonic-gate 	sasl_FREE(global_mech_list);
24677c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_
24687c478bd9Sstevel@tonic-gate 	gctx->global_mech_list = NULL;
24697c478bd9Sstevel@tonic-gate #else
24707c478bd9Sstevel@tonic-gate 	global_mech_list = NULL;
24717c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */
24727c478bd9Sstevel@tonic-gate     }
24737c478bd9Sstevel@tonic-gate 
24747c478bd9Sstevel@tonic-gate     global_mech_list = sasl_ALLOC((count + 1) * sizeof(char *));
24757c478bd9Sstevel@tonic-gate     if(!global_mech_list) return SASL_NOMEM;
24767c478bd9Sstevel@tonic-gate 
24777c478bd9Sstevel@tonic-gate     memset(global_mech_list, 0, (count + 1) * sizeof(char *));
24787c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_
24797c478bd9Sstevel@tonic-gate     gctx->global_mech_list = global_mech_list;
24807c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */
24817c478bd9Sstevel@tonic-gate 
24827c478bd9Sstevel@tonic-gate     count = 0;
24837c478bd9Sstevel@tonic-gate     for (p = olist; p; p = p_next) {
24847c478bd9Sstevel@tonic-gate 	p_next = p->next;
24857c478bd9Sstevel@tonic-gate 
24867c478bd9Sstevel@tonic-gate 	global_mech_list[count++] = (char *) p->d;
24877c478bd9Sstevel@tonic-gate 
24887c478bd9Sstevel@tonic-gate     	sasl_FREE(p);
24897c478bd9Sstevel@tonic-gate     }
24907c478bd9Sstevel@tonic-gate 
24917c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_
24927c478bd9Sstevel@tonic-gate     UNLOCK_MUTEX(&global_mutex);
24937c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */
24947c478bd9Sstevel@tonic-gate 
24957c478bd9Sstevel@tonic-gate     return SASL_OK;
24967c478bd9Sstevel@tonic-gate }
24977c478bd9Sstevel@tonic-gate 
sasl_global_listmech(void)24987c478bd9Sstevel@tonic-gate const char ** sasl_global_listmech(void)
24997c478bd9Sstevel@tonic-gate {
25007c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_
25017c478bd9Sstevel@tonic-gate     _sasl_global_context_t *gctx = _sasl_gbl_ctx();
25027c478bd9Sstevel@tonic-gate 
25037c478bd9Sstevel@tonic-gate     return (const char **)gctx->global_mech_list;
25047c478bd9Sstevel@tonic-gate #else
25057c478bd9Sstevel@tonic-gate     return (const char **)global_mech_list;
25067c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */
25077c478bd9Sstevel@tonic-gate }
25087c478bd9Sstevel@tonic-gate 
sasl_listmech(sasl_conn_t * conn,const char * user,const char * prefix,const char * sep,const char * suffix,const char ** result,unsigned * plen,int * pcount)25097c478bd9Sstevel@tonic-gate int sasl_listmech(sasl_conn_t *conn,
25107c478bd9Sstevel@tonic-gate 		  const char *user,
25117c478bd9Sstevel@tonic-gate 		  const char *prefix,
25127c478bd9Sstevel@tonic-gate 		  const char *sep,
25137c478bd9Sstevel@tonic-gate 		  const char *suffix,
25147c478bd9Sstevel@tonic-gate 		  const char **result,
25157c478bd9Sstevel@tonic-gate 		  unsigned *plen,
25167c478bd9Sstevel@tonic-gate 		  int *pcount)
25177c478bd9Sstevel@tonic-gate {
25187c478bd9Sstevel@tonic-gate     if(!conn) {
25197c478bd9Sstevel@tonic-gate 	return SASL_BADPARAM;
25207c478bd9Sstevel@tonic-gate     } else if(conn->type == SASL_CONN_SERVER) {
25217c478bd9Sstevel@tonic-gate 	RETURN(conn, _sasl_server_listmech(conn, user, prefix, sep, suffix,
25227c478bd9Sstevel@tonic-gate 					   result, plen, pcount));
25237c478bd9Sstevel@tonic-gate     } else if (conn->type == SASL_CONN_CLIENT) {
25247c478bd9Sstevel@tonic-gate 	RETURN(conn, _sasl_client_listmech(conn, prefix, sep, suffix,
25257c478bd9Sstevel@tonic-gate 					   result, plen, pcount));
25267c478bd9Sstevel@tonic-gate     }
25277c478bd9Sstevel@tonic-gate 
25287c478bd9Sstevel@tonic-gate     PARAMERROR(conn);
25297c478bd9Sstevel@tonic-gate }
25307c478bd9Sstevel@tonic-gate 
25317c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_
25327c478bd9Sstevel@tonic-gate /*
25337c478bd9Sstevel@tonic-gate  * Creates a context so that libraries may use libsasl independently
25347c478bd9Sstevel@tonic-gate  * of applications using libsasl.
25357c478bd9Sstevel@tonic-gate  * Returns NULL on failure.
25367c478bd9Sstevel@tonic-gate  *
25377c478bd9Sstevel@tonic-gate  * sasl_free_context frees the context
25387c478bd9Sstevel@tonic-gate  * To use libsasl independently of the default context, use
25397c478bd9Sstevel@tonic-gate  * _sasl_server_init()		instead of	sasl_server_init()
25407c478bd9Sstevel@tonic-gate  * _sasl_server_new()		instead of	sasl_server_new()
25417c478bd9Sstevel@tonic-gate  * _sasl_client_init()		instead of	sasl_client_init()
25427c478bd9Sstevel@tonic-gate  * _sasl_client_new()		instead of	sasl_client_new()
25437c478bd9Sstevel@tonic-gate  * _sasl_client_add_plugin()	instead of	sasl_client_add_plugin()
25447c478bd9Sstevel@tonic-gate  * _sasl_server_add_plugin()	instead of	sasl_server_add_plugin()
25457c478bd9Sstevel@tonic-gate  * _sasl_canonuser_add_plugin()	instead of	sasl_canonuser_add_plugin()
25467c478bd9Sstevel@tonic-gate  * _sasl_auxprop_add_plugin()	instead of	sasl_auxprop_add_plugin()
25477c478bd9Sstevel@tonic-gate  */
25487c478bd9Sstevel@tonic-gate 
sasl_create_context(void)25497c478bd9Sstevel@tonic-gate void *sasl_create_context(void)
25507c478bd9Sstevel@tonic-gate {
25517c478bd9Sstevel@tonic-gate   _sasl_global_context_t *gctx;
25527c478bd9Sstevel@tonic-gate 
25537c478bd9Sstevel@tonic-gate   gctx = (_sasl_global_context_t *)
25547c478bd9Sstevel@tonic-gate 	sasl_sun_ALLOC(sizeof(_sasl_global_context_t));
25557c478bd9Sstevel@tonic-gate 
25567c478bd9Sstevel@tonic-gate   if (gctx != NULL) {
25577c478bd9Sstevel@tonic-gate     memset(gctx, 0, sizeof(_sasl_global_context_t));
25587c478bd9Sstevel@tonic-gate 
25597c478bd9Sstevel@tonic-gate     gctx->server_global_callbacks.gctx = gctx;
25607c478bd9Sstevel@tonic-gate     gctx->client_global_callbacks.gctx = gctx;
25617c478bd9Sstevel@tonic-gate     LOCK_MUTEX(&malloc_global_mutex);
25627c478bd9Sstevel@tonic-gate     gctx->sasl_allocation_utils.malloc = (sasl_malloc_t *)&malloc;
25637c478bd9Sstevel@tonic-gate     gctx->sasl_allocation_utils.calloc = (sasl_calloc_t *)&calloc;
25647c478bd9Sstevel@tonic-gate     gctx->sasl_allocation_utils.realloc = (sasl_realloc_t *)&realloc;
25657c478bd9Sstevel@tonic-gate     gctx->sasl_allocation_utils.free = (sasl_free_t *)&free;
25667c478bd9Sstevel@tonic-gate     gctx->sasl_mutex_utils.alloc = sasl_mutex_alloc;
25677c478bd9Sstevel@tonic-gate     gctx->sasl_mutex_utils.lock = sasl_mutex_lock;
25687c478bd9Sstevel@tonic-gate     gctx->sasl_mutex_utils.unlock = sasl_mutex_unlock;
25697c478bd9Sstevel@tonic-gate     gctx->sasl_mutex_utils.free = sasl_mutex_free;
25707c478bd9Sstevel@tonic-gate     UNLOCK_MUTEX(&malloc_global_mutex);
25717c478bd9Sstevel@tonic-gate   }
25727c478bd9Sstevel@tonic-gate   return gctx;
25737c478bd9Sstevel@tonic-gate }
25747c478bd9Sstevel@tonic-gate 
25757c478bd9Sstevel@tonic-gate /* Frees the context created by sasl_create_context() */
sasl_free_context(void * context)25767c478bd9Sstevel@tonic-gate void sasl_free_context(void *context)
25777c478bd9Sstevel@tonic-gate {
25787c478bd9Sstevel@tonic-gate   _sasl_dispose_context(context);
25797c478bd9Sstevel@tonic-gate   if (context != NULL) {
25807c478bd9Sstevel@tonic-gate     sasl_sun_FREE(context);
25817c478bd9Sstevel@tonic-gate   }
25827c478bd9Sstevel@tonic-gate }
25837c478bd9Sstevel@tonic-gate 
25847c478bd9Sstevel@tonic-gate /* Used by both sasl_done() and sasl_free_context() to free context */
_sasl_dispose_context(_sasl_global_context_t * gctx)25857c478bd9Sstevel@tonic-gate static void _sasl_dispose_context(_sasl_global_context_t *gctx)
25867c478bd9Sstevel@tonic-gate {
25877c478bd9Sstevel@tonic-gate   if (gctx == NULL)
25887c478bd9Sstevel@tonic-gate         return;
25897c478bd9Sstevel@tonic-gate 
25907c478bd9Sstevel@tonic-gate   if (gctx->sasl_server_cleanup_hook &&
25917c478bd9Sstevel@tonic-gate 		gctx->sasl_server_cleanup_hook(gctx) == SASL_OK) {
25927c478bd9Sstevel@tonic-gate 	gctx->sasl_server_idle_hook = NULL;
25937c478bd9Sstevel@tonic-gate 	gctx->sasl_server_cleanup_hook = NULL;
25947c478bd9Sstevel@tonic-gate   }
25957c478bd9Sstevel@tonic-gate 
25967c478bd9Sstevel@tonic-gate   if (gctx->sasl_client_cleanup_hook &&
25977c478bd9Sstevel@tonic-gate 		gctx->sasl_client_cleanup_hook(gctx) == SASL_OK) {
25987c478bd9Sstevel@tonic-gate 	gctx->sasl_client_idle_hook = NULL;
25997c478bd9Sstevel@tonic-gate 	gctx->sasl_client_cleanup_hook = NULL;
26007c478bd9Sstevel@tonic-gate   }
26017c478bd9Sstevel@tonic-gate 
26027c478bd9Sstevel@tonic-gate   if(gctx->sasl_server_cleanup_hook || gctx->sasl_client_cleanup_hook)
26037c478bd9Sstevel@tonic-gate 	return;
26047c478bd9Sstevel@tonic-gate 
26057c478bd9Sstevel@tonic-gate   _sasl_canonuser_free(gctx);
26067c478bd9Sstevel@tonic-gate   _sasl_done_with_plugins(gctx);
26077c478bd9Sstevel@tonic-gate 
26087c478bd9Sstevel@tonic-gate   sasl_config_free(gctx);
26097c478bd9Sstevel@tonic-gate 
26107c478bd9Sstevel@tonic-gate   if (gctx->free_mutex != NULL)
26117c478bd9Sstevel@tonic-gate     sasl_MUTEX_FREE(gctx->free_mutex);
26127c478bd9Sstevel@tonic-gate   gctx->free_mutex = NULL;
26137c478bd9Sstevel@tonic-gate 
26147c478bd9Sstevel@tonic-gate   _sasl_free_utils(&(gctx->sasl_server_global_utils));
26157c478bd9Sstevel@tonic-gate   _sasl_free_utils(&(gctx->sasl_canonusr_global_utils));
26167c478bd9Sstevel@tonic-gate 
26177c478bd9Sstevel@tonic-gate   LOCK_MUTEX(&global_mutex);
26187c478bd9Sstevel@tonic-gate   sasl_FREE((void *)gctx->global_mech_list);
26197c478bd9Sstevel@tonic-gate   gctx->global_mech_list = NULL;
26207c478bd9Sstevel@tonic-gate   UNLOCK_MUTEX(&global_mutex);
26217c478bd9Sstevel@tonic-gate 
26227c478bd9Sstevel@tonic-gate   /* in case of another init/done */
26237c478bd9Sstevel@tonic-gate   gctx->sasl_server_cleanup_hook = NULL;
26247c478bd9Sstevel@tonic-gate   gctx->sasl_client_cleanup_hook = NULL;
26257c478bd9Sstevel@tonic-gate 
26267c478bd9Sstevel@tonic-gate   gctx->sasl_client_idle_hook = NULL;
26277c478bd9Sstevel@tonic-gate   gctx->sasl_server_idle_hook = NULL;
26287c478bd9Sstevel@tonic-gate }
26297c478bd9Sstevel@tonic-gate 
_sasl_gbl_ctx(void)26307c478bd9Sstevel@tonic-gate _sasl_global_context_t *_sasl_gbl_ctx(void)
26317c478bd9Sstevel@tonic-gate {
26327c478bd9Sstevel@tonic-gate   static _sasl_global_context_t gbl_ctx = {
26337c478bd9Sstevel@tonic-gate         0,                      /* sasl_server_active */
26347c478bd9Sstevel@tonic-gate         NULL,                   /* mechlist */
26357c478bd9Sstevel@tonic-gate 	NULL,			/* splug_path_info */
26367c478bd9Sstevel@tonic-gate         {NULL, NULL, &gbl_ctx}, /* server_global_callbacks */
26377c478bd9Sstevel@tonic-gate         NULL,                   /* sasl_server_cleanup_hook */
26387c478bd9Sstevel@tonic-gate         NULL,                   /* sasl_server_idle_hook */
26397c478bd9Sstevel@tonic-gate         NULL,                   /* cmechlist */
26407c478bd9Sstevel@tonic-gate 	NULL,			/* cplug_path_info */
26417c478bd9Sstevel@tonic-gate         {NULL, NULL, &gbl_ctx}, /* client_global_callbacks */
26427c478bd9Sstevel@tonic-gate         0,                      /* sasl_client_active */
26437c478bd9Sstevel@tonic-gate         NULL,                   /* sasl_client_cleanup_hook */
26447c478bd9Sstevel@tonic-gate         NULL,                   /* sasl_client_idle_hook */
26457c478bd9Sstevel@tonic-gate         NULL,                   /* sasl_server_global_utils */
26467c478bd9Sstevel@tonic-gate         NULL,                   /* sasl_client_global_utils */
26477c478bd9Sstevel@tonic-gate         NULL,                   /* configlist */
26487c478bd9Sstevel@tonic-gate         0,                      /* nconfiglist */
26497c478bd9Sstevel@tonic-gate 	NULL,			/* config_path */
26507c478bd9Sstevel@tonic-gate 	0,			/* config_last_read */
26517c478bd9Sstevel@tonic-gate         NULL,                   /* auxprop_head */
26527c478bd9Sstevel@tonic-gate         NULL,                   /* canonuser_head */
26537c478bd9Sstevel@tonic-gate         NULL,                   /* global_mech_list */
26547c478bd9Sstevel@tonic-gate         NULL,                   /* free_mutex */
26557c478bd9Sstevel@tonic-gate         {(sasl_malloc_t *)&malloc, (sasl_calloc_t *)&calloc,
26567c478bd9Sstevel@tonic-gate             (sasl_realloc_t *)&realloc, (sasl_free_t *)&free},
26577c478bd9Sstevel@tonic-gate                                 /* sasl_allocation_utils */
26587c478bd9Sstevel@tonic-gate         {&sasl_mutex_alloc, &sasl_mutex_lock, &sasl_mutex_unlock,
26597c478bd9Sstevel@tonic-gate             &sasl_mutex_free},  /* sasl_mutex_utils */
26607c478bd9Sstevel@tonic-gate         NULL			/* lib_list_head */
26617c478bd9Sstevel@tonic-gate   };
26627c478bd9Sstevel@tonic-gate 
26637c478bd9Sstevel@tonic-gate   return (&gbl_ctx);
26647c478bd9Sstevel@tonic-gate }
26657c478bd9Sstevel@tonic-gate 
26667c478bd9Sstevel@tonic-gate static int
_sasl_getconf(void * context,const char ** conf)26677c478bd9Sstevel@tonic-gate _sasl_getconf(void *context __attribute__((unused)), const char **conf)
26687c478bd9Sstevel@tonic-gate {
26697c478bd9Sstevel@tonic-gate     if (! conf)
26707c478bd9Sstevel@tonic-gate 	return SASL_BADPARAM;
26717c478bd9Sstevel@tonic-gate 
26727c478bd9Sstevel@tonic-gate     *conf = SASL_CONFDIR;
26737c478bd9Sstevel@tonic-gate 
26747c478bd9Sstevel@tonic-gate     return SASL_OK;
26757c478bd9Sstevel@tonic-gate }
26767c478bd9Sstevel@tonic-gate 
26777c478bd9Sstevel@tonic-gate #ifdef _INTEGRATED_SOLARIS_
26787c478bd9Sstevel@tonic-gate #pragma fini(sasl_fini)
26797c478bd9Sstevel@tonic-gate int
sasl_fini(void)26807c478bd9Sstevel@tonic-gate sasl_fini(void)
26817c478bd9Sstevel@tonic-gate {
26827c478bd9Sstevel@tonic-gate     reg_list_t *next;
26837c478bd9Sstevel@tonic-gate 
26847c478bd9Sstevel@tonic-gate     while (reg_list_base != NULL) {
26857c478bd9Sstevel@tonic-gate 	next = reg_list_base->next;
26867c478bd9Sstevel@tonic-gate 	free(reg_list_base);
26877c478bd9Sstevel@tonic-gate 	reg_list_base = next;
26887c478bd9Sstevel@tonic-gate     }
26897c478bd9Sstevel@tonic-gate     return (0);
26907c478bd9Sstevel@tonic-gate }
26917c478bd9Sstevel@tonic-gate #endif /* _INTEGRATED_SOLARIS_ */
26927c478bd9Sstevel@tonic-gate 
26937c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */
26947c478bd9Sstevel@tonic-gate 
26957c478bd9Sstevel@tonic-gate #ifndef WIN32
26967c478bd9Sstevel@tonic-gate static int
_sasl_getpath(void * context,const char ** path)26977c478bd9Sstevel@tonic-gate _sasl_getpath(void *context __attribute__((unused)),
26987c478bd9Sstevel@tonic-gate 	      const char **path)
26997c478bd9Sstevel@tonic-gate {
27007c478bd9Sstevel@tonic-gate   if (! path)
27017c478bd9Sstevel@tonic-gate     return SASL_BADPARAM;
27027c478bd9Sstevel@tonic-gate 
27037c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_
27047c478bd9Sstevel@tonic-gate /* SASL_PATH is not allowed for SUN SDK */
27057c478bd9Sstevel@tonic-gate #else
27067c478bd9Sstevel@tonic-gate   *path = getenv(SASL_PATH_ENV_VAR);
27077c478bd9Sstevel@tonic-gate   if (! *path)
27087c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */
27097c478bd9Sstevel@tonic-gate     *path = PLUGINDIR;
27107c478bd9Sstevel@tonic-gate 
27117c478bd9Sstevel@tonic-gate   return SASL_OK;
27127c478bd9Sstevel@tonic-gate }
27137c478bd9Sstevel@tonic-gate 
27147c478bd9Sstevel@tonic-gate #else
27157c478bd9Sstevel@tonic-gate /* Return NULL on failure */
27167c478bd9Sstevel@tonic-gate static int
_sasl_getpath(void * context,const char ** path)27177c478bd9Sstevel@tonic-gate _sasl_getpath(void *context __attribute__((unused)), const char **path)
27187c478bd9Sstevel@tonic-gate {
27197c478bd9Sstevel@tonic-gate     /* Open registry entry, and find all registered SASL libraries.
27207c478bd9Sstevel@tonic-gate      *
27217c478bd9Sstevel@tonic-gate      * Registry location:
27227c478bd9Sstevel@tonic-gate      *
27237c478bd9Sstevel@tonic-gate      *     SOFTWARE\\Carnegie Mellon\\Project Cyrus\\SASL Library
27247c478bd9Sstevel@tonic-gate      *
27257c478bd9Sstevel@tonic-gate      * Key - value:
27267c478bd9Sstevel@tonic-gate      *
27277c478bd9Sstevel@tonic-gate      *     "SearchPath" - value: PATH like (';' delimited) list
27287c478bd9Sstevel@tonic-gate      *                    of directories where to search for plugins
27297c478bd9Sstevel@tonic-gate      *                    The list may contain references to environment
27307c478bd9Sstevel@tonic-gate      *                    variables (e.g. %PATH%).
27317c478bd9Sstevel@tonic-gate      *
27327c478bd9Sstevel@tonic-gate      */
27337c478bd9Sstevel@tonic-gate     HKEY  hKey;
27347c478bd9Sstevel@tonic-gate     DWORD ret;
27357c478bd9Sstevel@tonic-gate     DWORD ValueType;		    /* value type */
27367c478bd9Sstevel@tonic-gate     DWORD cbData;		    /* value size */
27377c478bd9Sstevel@tonic-gate     BYTE * ValueData;		    /* value */
27387c478bd9Sstevel@tonic-gate     DWORD cbExpandedData;	    /* "expanded" value size */
27397c478bd9Sstevel@tonic-gate     BYTE * ExpandedValueData;	    /* "expanded" value */
27407c478bd9Sstevel@tonic-gate     char * return_value;	    /* function return value */
27417c478bd9Sstevel@tonic-gate     char * tmp;
27427c478bd9Sstevel@tonic-gate 
27437c478bd9Sstevel@tonic-gate     /* Initialization */
27447c478bd9Sstevel@tonic-gate     ExpandedValueData = NULL;
27457c478bd9Sstevel@tonic-gate     ValueData = NULL;
27467c478bd9Sstevel@tonic-gate     return_value = NULL;
27477c478bd9Sstevel@tonic-gate 
27487c478bd9Sstevel@tonic-gate     /* Open the registry */
27497c478bd9Sstevel@tonic-gate     ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
27507c478bd9Sstevel@tonic-gate 		       SASL_ROOT_KEY,
27517c478bd9Sstevel@tonic-gate 		       0,
27527c478bd9Sstevel@tonic-gate 		       KEY_READ,
27537c478bd9Sstevel@tonic-gate 		       &hKey);
27547c478bd9Sstevel@tonic-gate 
27557c478bd9Sstevel@tonic-gate     if (ret != ERROR_SUCCESS) {
27567c478bd9Sstevel@tonic-gate 		/* no registry entry */
27577c478bd9Sstevel@tonic-gate 		*path = PLUGINDIR;
27587c478bd9Sstevel@tonic-gate 		return SASL_OK;
27597c478bd9Sstevel@tonic-gate 	}
27607c478bd9Sstevel@tonic-gate 
27617c478bd9Sstevel@tonic-gate     /* figure out value type and required buffer size */
27627c478bd9Sstevel@tonic-gate     /* the size will include space for terminating NUL if required */
27637c478bd9Sstevel@tonic-gate     RegQueryValueEx (hKey,
27647c478bd9Sstevel@tonic-gate 		     SASL_PATH_SUBKEY,
27657c478bd9Sstevel@tonic-gate 		     NULL,	    /* reserved */
27667c478bd9Sstevel@tonic-gate 		     &ValueType,
27677c478bd9Sstevel@tonic-gate 		     NULL,
27687c478bd9Sstevel@tonic-gate 		     &cbData);
27697c478bd9Sstevel@tonic-gate 
27707c478bd9Sstevel@tonic-gate     /* Only accept string related types */
27717c478bd9Sstevel@tonic-gate     if (ValueType != REG_EXPAND_SZ &&
27727c478bd9Sstevel@tonic-gate 	ValueType != REG_MULTI_SZ &&
27737c478bd9Sstevel@tonic-gate 	ValueType != REG_SZ) {
27747c478bd9Sstevel@tonic-gate 	return_value = NULL;
27757c478bd9Sstevel@tonic-gate 	goto CLEANUP;
27767c478bd9Sstevel@tonic-gate     }
27777c478bd9Sstevel@tonic-gate 
27787c478bd9Sstevel@tonic-gate     /* Any high water mark? */
27797c478bd9Sstevel@tonic-gate     ValueData = sasl_ALLOC(cbData);
27807c478bd9Sstevel@tonic-gate     if (ValueData == NULL) {
27817c478bd9Sstevel@tonic-gate 	return_value = NULL;
27827c478bd9Sstevel@tonic-gate 	goto CLEANUP;
27837c478bd9Sstevel@tonic-gate     };
27847c478bd9Sstevel@tonic-gate 
27857c478bd9Sstevel@tonic-gate     RegQueryValueEx (hKey,
27867c478bd9Sstevel@tonic-gate 		     SASL_PATH_SUBKEY,
27877c478bd9Sstevel@tonic-gate 		     NULL,	    /* reserved */
27887c478bd9Sstevel@tonic-gate 		     &ValueType,
27897c478bd9Sstevel@tonic-gate 		     ValueData,
27907c478bd9Sstevel@tonic-gate 		     &cbData);
27917c478bd9Sstevel@tonic-gate 
27927c478bd9Sstevel@tonic-gate     switch (ValueType) {
27937c478bd9Sstevel@tonic-gate     case REG_EXPAND_SZ:
27947c478bd9Sstevel@tonic-gate         /* : A random starting guess */
27957c478bd9Sstevel@tonic-gate         cbExpandedData = cbData + 1024;
27967c478bd9Sstevel@tonic-gate         ExpandedValueData = sasl_ALLOC(cbExpandedData);
27977c478bd9Sstevel@tonic-gate         if (ExpandedValueData == NULL) {
27987c478bd9Sstevel@tonic-gate             return_value = NULL;
27997c478bd9Sstevel@tonic-gate             goto CLEANUP;
28007c478bd9Sstevel@tonic-gate         };
28017c478bd9Sstevel@tonic-gate 
28027c478bd9Sstevel@tonic-gate         cbExpandedData = ExpandEnvironmentStrings(
28037c478bd9Sstevel@tonic-gate                                                   ValueData,
28047c478bd9Sstevel@tonic-gate                                                   ExpandedValueData,
28057c478bd9Sstevel@tonic-gate                                                   cbExpandedData);
28067c478bd9Sstevel@tonic-gate 
28077c478bd9Sstevel@tonic-gate         if (cbExpandedData == 0) {
28087c478bd9Sstevel@tonic-gate             /* : GetLastError() contains the reason for failure */
28097c478bd9Sstevel@tonic-gate             return_value = NULL;
28107c478bd9Sstevel@tonic-gate             goto CLEANUP;
28117c478bd9Sstevel@tonic-gate         }
28127c478bd9Sstevel@tonic-gate 
28137c478bd9Sstevel@tonic-gate         /* : Must retry expansion with the bigger buffer */
28147c478bd9Sstevel@tonic-gate         if (cbExpandedData > cbData + 1024) {
28157c478bd9Sstevel@tonic-gate             /* : Memory leak here if can't realloc */
28167c478bd9Sstevel@tonic-gate             ExpandedValueData = sasl_REALLOC(ExpandedValueData, cbExpandedData);
28177c478bd9Sstevel@tonic-gate             if (ExpandedValueData == NULL) {
28187c478bd9Sstevel@tonic-gate                 return_value = NULL;
28197c478bd9Sstevel@tonic-gate                 goto CLEANUP;
28207c478bd9Sstevel@tonic-gate             };
28217c478bd9Sstevel@tonic-gate 
28227c478bd9Sstevel@tonic-gate             cbExpandedData = ExpandEnvironmentStrings(
28237c478bd9Sstevel@tonic-gate                                                       ValueData,
28247c478bd9Sstevel@tonic-gate                                                       ExpandedValueData,
28257c478bd9Sstevel@tonic-gate                                                       cbExpandedData);
28267c478bd9Sstevel@tonic-gate 
28277c478bd9Sstevel@tonic-gate             /* : This should not happen */
28287c478bd9Sstevel@tonic-gate             if (cbExpandedData == 0) {
28297c478bd9Sstevel@tonic-gate                 /* : GetLastError() contains the reason for failure */
28307c478bd9Sstevel@tonic-gate                 return_value = NULL;
28317c478bd9Sstevel@tonic-gate                 goto CLEANUP;
28327c478bd9Sstevel@tonic-gate             }
28337c478bd9Sstevel@tonic-gate         }
28347c478bd9Sstevel@tonic-gate 
28357c478bd9Sstevel@tonic-gate         sasl_FREE(ValueData);
28367c478bd9Sstevel@tonic-gate         ValueData = ExpandedValueData;
28377c478bd9Sstevel@tonic-gate         /* : This is to prevent automatical freeing of this block on cleanup */
28387c478bd9Sstevel@tonic-gate         ExpandedValueData = NULL;
28397c478bd9Sstevel@tonic-gate 
28407c478bd9Sstevel@tonic-gate         break;
28417c478bd9Sstevel@tonic-gate 
28427c478bd9Sstevel@tonic-gate     case REG_MULTI_SZ:
28437c478bd9Sstevel@tonic-gate         tmp = ValueData;
28447c478bd9Sstevel@tonic-gate 
28457c478bd9Sstevel@tonic-gate         /* : We shouldn't overflow here, as the buffer is guarantied
28467c478bd9Sstevel@tonic-gate            : to contain at least two consequent NULs */
28477c478bd9Sstevel@tonic-gate         while (1) {
28487c478bd9Sstevel@tonic-gate             if (tmp[0] == '\0') {
28497c478bd9Sstevel@tonic-gate                 /* : Stop the process if we found the end of the string (two consequent NULs) */
28507c478bd9Sstevel@tonic-gate                 if (tmp[1] == '\0') {
28517c478bd9Sstevel@tonic-gate                     break;
28527c478bd9Sstevel@tonic-gate                 }
28537c478bd9Sstevel@tonic-gate 
28547c478bd9Sstevel@tonic-gate                 /* : Replace delimiting NUL with our delimiter characted */
28557c478bd9Sstevel@tonic-gate                 tmp[0] = PATHS_DELIMITER;
28567c478bd9Sstevel@tonic-gate             }
28577c478bd9Sstevel@tonic-gate             tmp += strlen(tmp);
28587c478bd9Sstevel@tonic-gate         }
28597c478bd9Sstevel@tonic-gate         break;
28607c478bd9Sstevel@tonic-gate 
28617c478bd9Sstevel@tonic-gate     case REG_SZ:
28627c478bd9Sstevel@tonic-gate         /* Do nothing, it is good as is */
28637c478bd9Sstevel@tonic-gate         break;
28647c478bd9Sstevel@tonic-gate 
28657c478bd9Sstevel@tonic-gate     default:
28667c478bd9Sstevel@tonic-gate         return_value = NULL;
28677c478bd9Sstevel@tonic-gate         goto CLEANUP;
28687c478bd9Sstevel@tonic-gate     }
28697c478bd9Sstevel@tonic-gate 
28707c478bd9Sstevel@tonic-gate     return_value = ValueData;
28717c478bd9Sstevel@tonic-gate 
28727c478bd9Sstevel@tonic-gate     CLEANUP:
28737c478bd9Sstevel@tonic-gate     RegCloseKey(hKey);
28747c478bd9Sstevel@tonic-gate     if (ExpandedValueData != NULL) sasl_FREE(ExpandedValueData);
28757c478bd9Sstevel@tonic-gate     if (return_value == NULL) {
28767c478bd9Sstevel@tonic-gate 	if (ValueData != NULL) sasl_FREE(ValueData);
28777c478bd9Sstevel@tonic-gate     }
28787c478bd9Sstevel@tonic-gate     *path = return_value;
28797c478bd9Sstevel@tonic-gate 
28807c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_
28817c478bd9Sstevel@tonic-gate /* SASL_PATH is not allowed for SUN SDK */
28827c478bd9Sstevel@tonic-gate   if (! *path)
28837c478bd9Sstevel@tonic-gate     *path = PLUGINDIR;
28847c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */
28857c478bd9Sstevel@tonic-gate 	return SASL_OK;
28867c478bd9Sstevel@tonic-gate }
28877c478bd9Sstevel@tonic-gate 
28887c478bd9Sstevel@tonic-gate #endif
2889