xref: /illumos-gate/usr/src/lib/libsasl/lib/common.c (revision 9841a15c)
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");
1165