]> git.pld-linux.org Git - packages/cyrus-sasl.git/commitdiff
- removed .orig files from configdir patch (over 100kB less)
authorJakub Bogusz <qboosh@pld-linux.org>
Thu, 9 Jan 2003 20:22:49 +0000 (20:22 +0000)
committercvs2git <feedback@pld-linux.org>
Sun, 24 Jun 2012 12:13:13 +0000 (12:13 +0000)
- disabled gssapi explicitly, added nolibs patch to avoid unnecessary -lresolv
- added lt14d patch to allow build with libtool 1.4d and newer

Changed files:
    cyrus-sasl-configdir.patch -> 1.3
    cyrus-sasl-lt14d.patch -> 1.1
    cyrus-sasl-nolibs.patch -> 1.1
    cyrus-sasl.spec -> 1.79

cyrus-sasl-configdir.patch
cyrus-sasl-lt14d.patch [new file with mode: 0644]
cyrus-sasl-nolibs.patch [new file with mode: 0644]
cyrus-sasl.spec

index aa558c59356410190ca1451d6eaa7306e4cef269..94fac04fa6302d5259fba3d9b9f1222fdde88bf0 100644 (file)
@@ -130,4204 +130,43 @@ diff -durN cyrus-sasl-2.1.10.orig/lib/common.c cyrus-sasl-2.1.10/lib/common.c
  _sasl_find_verifyfile_callback(const sasl_callback_t *callbacks)
  {
    static const sasl_callback_t default_verifyfile_cb = {
-diff -durN cyrus-sasl-2.1.10.orig/lib/common.c.orig cyrus-sasl-2.1.10/lib/common.c.orig
---- cyrus-sasl-2.1.10.orig/lib/common.c.orig   Thu Jan  1 01:00:00 1970
-+++ cyrus-sasl-2.1.10/lib/common.c.orig        Thu Dec  5 15:00:38 2002
-@@ -0,0 +1,1921 @@
-+/* common.c - Functions that are common to server and clinet
-+ * Rob Siemborski
-+ * Tim Martin
-+ * $Id$
-+ */
-+/* 
-+ * Copyright (c) 2001 Carnegie Mellon University.  All rights reserved.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions
-+ * are met:
-+ *
-+ * 1. Redistributions of source code must retain the above copyright
-+ *    notice, this list of conditions and the following disclaimer. 
-+ *
-+ * 2. Redistributions in binary form must reproduce the above copyright
-+ *    notice, this list of conditions and the following disclaimer in
-+ *    the documentation and/or other materials provided with the
-+ *    distribution.
-+ *
-+ * 3. The name "Carnegie Mellon University" must not be used to
-+ *    endorse or promote products derived from this software without
-+ *    prior written permission. For permission or any other legal
-+ *    details, please contact  
-+ *      Office of Technology Transfer
-+ *      Carnegie Mellon University
-+ *      5000 Forbes Avenue
-+ *      Pittsburgh, PA  15213-3890
-+ *      (412) 268-4387, fax: (412) 268-7395
-+ *      tech-transfer@andrew.cmu.edu
-+ *
-+ * 4. Redistributions of any form whatsoever must retain the following
-+ *    acknowledgment:
-+ *    "This product includes software developed by Computing Services
-+ *     at Carnegie Mellon University (http://www.cmu.edu/computing/)."
-+ *
-+ * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
-+ * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
-+ * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
-+ * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
-+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
-+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+ */
-+
-+#include <config.h>
-+#include <stdio.h>
-+#include <string.h>
-+#include <stdlib.h>
-+#include <limits.h>
-+#ifdef HAVE_SYSLOG
-+#include <syslog.h>
-+#endif
-+#include <stdarg.h>
-+#include <ctype.h>
-+
-+#include <sasl.h>
-+#include <saslutil.h>
-+#include <saslplug.h>
-+#include "saslint.h"
-+
-+#ifdef WIN32
-+/* need to handle the fact that errno has been defined as a function
-+   in a dll, not an extern int */
-+# ifdef errno
-+#  undef errno
-+# endif /* errno */
-+#endif /* WIN32 */
-+#ifdef HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+
-+static int _sasl_getpath(void *context __attribute__((unused)), const char **path);
-+
-+static const char build_ident[] = "$Build: libsasl " PACKAGE "-" VERSION " $";
-+
-+/* It turns out to be conveinent to have a shared sasl_utils_t */
-+LIBSASL_VAR const sasl_utils_t *sasl_global_utils = NULL;
-+
-+/* Should be a null-terminated array that lists the available mechanisms */
-+static char **global_mech_list = NULL;
-+
-+void *free_mutex = NULL;
-+
-+void (*_sasl_client_cleanup_hook)(void) = NULL;
-+void (*_sasl_server_cleanup_hook)(void) = NULL;
-+int (*_sasl_client_idle_hook)(sasl_conn_t *conn) = NULL;
-+int (*_sasl_server_idle_hook)(sasl_conn_t *conn) = NULL;
-+
-+sasl_allocation_utils_t _sasl_allocation_utils={
-+  (sasl_malloc_t *)  &malloc,
-+  (sasl_calloc_t *)  &calloc,
-+  (sasl_realloc_t *) &realloc,
-+  (sasl_free_t *) &free
-+};
-+
-+/* Intenal mutex functions do as little as possible (no thread protection) */
-+static void *sasl_mutex_alloc(void)
-+{
-+  return (void *)0x1;
-+}
-+
-+static int sasl_mutex_lock(void *mutex __attribute__((unused)))
-+{
-+    return SASL_OK;
-+}
-+
-+static int sasl_mutex_unlock(void *mutex __attribute__((unused)))
-+{
-+    return SASL_OK;
-+}
-+
-+static void sasl_mutex_free(void *mutex __attribute__((unused)))
-+{
-+    return;
-+}
-+
-+sasl_mutex_utils_t _sasl_mutex_utils={
-+  &sasl_mutex_alloc,
-+  &sasl_mutex_lock,
-+  &sasl_mutex_unlock,
-+  &sasl_mutex_free
-+};
-+
-+void sasl_set_mutex(sasl_mutex_alloc_t *n, sasl_mutex_lock_t *l,
-+                  sasl_mutex_unlock_t *u, sasl_mutex_free_t *d)
-+{
-+  _sasl_mutex_utils.alloc=n;
-+  _sasl_mutex_utils.lock=l;
-+  _sasl_mutex_utils.unlock=u;
-+  _sasl_mutex_utils.free=d;
-+}
-+
-+/* copy a string to malloced memory */
-+int _sasl_strdup(const char *in, char **out, size_t *outlen)
-+{
-+  size_t len = strlen(in);
-+  if (outlen) *outlen = len;
-+  *out=sasl_ALLOC(len + 1);
-+  if (! *out) return SASL_NOMEM;
-+  strcpy((char *) *out, in);
-+  return SASL_OK;
-+}
-+
-+/* adds a string to the buffer; reallocing if need be */
-+int _sasl_add_string(char **out, size_t *alloclen,
-+                   size_t *outlen, const char *add)
-+{
-+  size_t addlen;
-+
-+  if (add==NULL) add = "(null)";
-+
-+  addlen=strlen(add); /* only compute once */
-+  if (_buf_alloc(out, alloclen, (*outlen)+addlen)!=SASL_OK)
-+    return SASL_NOMEM;
-+
-+  strncpy(*out + *outlen, add, addlen);
-+  *outlen += addlen;
-+
-+  return SASL_OK;
-+}
-+
-+/* return the version of the cyrus sasl library as compiled,
-+ * using 32 bits: high byte is major version, second byte is minor version,
-+ * low 16 bits are step # */
-+void sasl_version(const char **implementation, int *version) 
-+{
-+    const char *implementation_string = "Cyrus SASL";
-+    if(implementation) *implementation = implementation_string;
-+    if(version) *version = (SASL_VERSION_MAJOR << 24) | 
-+                         (SASL_VERSION_MINOR << 16) |
-+                         (SASL_VERSION_STEP);
-+}
-+
-+/* security-encode a regular string.  Mostly a wrapper for sasl_encodev */
-+/* output is only valid until next call to sasl_encode or sasl_encodev */
-+int sasl_encode(sasl_conn_t *conn, const char *input,
-+              unsigned inputlen,
-+              const char **output, unsigned *outputlen)
-+{
-+    int result;
-+    struct iovec tmp;
-+
-+    if(!conn) return SASL_BADPARAM;
-+    if(!input || !inputlen || !output || !outputlen)
-+      PARAMERROR(conn);
-+    
-+    /* maxoutbuf checking is done in sasl_encodev */
-+
-+    /* Note: We are casting a const pointer here, but it's okay
-+     * because we believe people downstream of us are well-behaved, and the
-+     * alternative is an absolute mess, performance-wise. */
-+    tmp.iov_base = (void *)input;
-+    tmp.iov_len = inputlen;
-+    
-+    result = sasl_encodev(conn, &tmp, 1, output, outputlen);
-+
-+    RETURN(conn, result);
-+}
-+
-+/* security-encode an iovec */
-+/* output is only valid until next call to sasl_encode or sasl_encodev */
-+int sasl_encodev(sasl_conn_t *conn,
-+               const struct iovec *invec, unsigned numiov,
-+               const char **output, unsigned *outputlen)
-+{
-+    int result;
-+    unsigned i;
-+    size_t total_size = 0;
-+
-+    if (!conn) return SASL_BADPARAM;
-+    if (! invec || ! output || ! outputlen || numiov < 1)
-+      PARAMERROR(conn);
-+
-+    if(!conn->props.maxbufsize) {
-+      sasl_seterror(conn, 0,
-+                    "called sasl_encode[v] with application that does not support security layers");
-+      return SASL_TOOWEAK;
-+    }
-+
-+    /* This might be better to check on a per-plugin basis, but I think
-+     * it's cleaner and more effective here.  It also encourages plugins
-+     * to be honest about what they accept */
-+
-+    for(i=0; i<numiov;i++) {
-+      total_size += invec[i].iov_len;
-+    }    
-+    if(total_size > conn->oparams.maxoutbuf)
-+      PARAMERROR(conn);
-+
-+    if(conn->oparams.encode == NULL)  {
-+      result = _iovec_to_buf(invec, numiov, &conn->encode_buf);
-+      if(result != SASL_OK) INTERROR(conn, result);
-+       
-+      *output = conn->encode_buf->data;
-+      *outputlen = conn->encode_buf->curlen;
-+
-+    } else {
-+      result = conn->oparams.encode(conn->context, invec, numiov,
-+                                    output, outputlen);
-+    }
-+
-+    RETURN(conn, result);
-+}
-+ 
-+/* output is only valid until next call to sasl_decode */
-+int sasl_decode(sasl_conn_t *conn,
-+              const char *input, unsigned inputlen,
-+              const char **output, unsigned *outputlen)
-+{
-+    int result;
-+
-+    if(!conn) return SASL_BADPARAM;
-+    if(!input || !output || !outputlen)
-+      PARAMERROR(conn);
-+
-+    if(!conn->props.maxbufsize) {
-+      sasl_seterror(conn, 0,
-+                    "called sasl_decode with application that does not support security layers");
-+      RETURN(conn, SASL_TOOWEAK);
-+    }
-+
-+    if(conn->oparams.decode == NULL)
-+    {
-+      /* Since we know how long the output is maximally, we can
-+       * just allocate it to begin with, and never need another
-+         * allocation! */
-+
-+      /* However, if they pass us more than they actually can take,
-+       * we cannot help them... */
-+      if(inputlen > conn->props.maxbufsize) {
-+          sasl_seterror(conn, 0,
-+                        "input too large for default sasl_decode");
-+          RETURN(conn,SASL_BUFOVER);
-+      }
-+
-+      if(!conn->decode_buf)
-+          conn->decode_buf = sasl_ALLOC(conn->props.maxbufsize + 1);
-+      if(!conn->decode_buf)   
-+          MEMERROR(conn);
-+      
-+      memcpy(conn->decode_buf, input, inputlen);
-+      conn->decode_buf[inputlen] = '\0';
-+      *output = conn->decode_buf;
-+      *outputlen = inputlen;
-+      
-+        return SASL_OK;
-+    } else {
-+        result = conn->oparams.decode(conn->context, input, inputlen,
-+                                      output, outputlen);
-+
-+      /* NULL an empty buffer (for misbehaved applications) */
-+      if (*outputlen == 0) *output = NULL;
-+
-+        RETURN(conn, result);
-+    }
-+
-+    INTERROR(conn, SASL_FAIL);
-+}
-+
-+
-+void
-+sasl_set_alloc(sasl_malloc_t *m,
-+             sasl_calloc_t *c,
-+             sasl_realloc_t *r,
-+             sasl_free_t *f)
-+{
-+  _sasl_allocation_utils.malloc=m;
-+  _sasl_allocation_utils.calloc=c;
-+  _sasl_allocation_utils.realloc=r;
-+  _sasl_allocation_utils.free=f;
-+}
-+
-+void sasl_done(void)
-+{
-+  if (_sasl_server_cleanup_hook)
-+    _sasl_server_cleanup_hook();
-+
-+  if (_sasl_client_cleanup_hook)
-+    _sasl_client_cleanup_hook();
-+  
-+  _sasl_canonuser_free();
-+  _sasl_done_with_plugins();
-+  
-+  sasl_MUTEX_FREE(free_mutex);
-+  free_mutex = NULL;
-+
-+  _sasl_free_utils(&sasl_global_utils);
-+
-+  sasl_FREE(global_mech_list);
-+  global_mech_list = NULL;
-+
-+  /* in case of another init/done */
-+  _sasl_server_cleanup_hook = NULL;
-+  _sasl_client_cleanup_hook = NULL;
-+
-+  _sasl_client_idle_hook = NULL;
-+  _sasl_server_idle_hook = NULL;
-+}
-+
-+/* fills in the base sasl_conn_t info */
-+int _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) {
-+  int result = SASL_OK;
-+
-+  conn->type = type;
-+
-+  result = _sasl_strdup(service, &conn->service, NULL);
-+  if (result != SASL_OK) 
-+      MEMERROR(conn);
-+
-+  memset(&conn->oparams, 0, sizeof(sasl_out_params_t));
-+  memset(&conn->external, 0, sizeof(_sasl_external_properties_t));
-+
-+  conn->flags = flags;
-+
-+  result = sasl_setprop(conn, SASL_IPLOCALPORT, iplocalport);
-+  if(result != SASL_OK)
-+      RETURN(conn, result);
-+  
-+  result = sasl_setprop(conn, SASL_IPREMOTEPORT, ipremoteport);
-+  if(result != SASL_OK)
-+      RETURN(conn, result);
-+  
-+  conn->encode_buf = NULL;
-+  conn->context = NULL;
-+  conn->secret = NULL;
-+  conn->idle_hook = idle_hook;
-+  conn->callbacks = callbacks;
-+  conn->global_callbacks = global_callbacks;
-+
-+  memset(&conn->props, 0, sizeof(conn->props));
-+
-+  /* Start this buffer out as an empty string */
-+  conn->error_code = SASL_OK;
-+  conn->errdetail_buf = conn->error_buf = NULL;
-+  conn->errdetail_buf_len = conn->error_buf_len = 150;
-+
-+  result = _buf_alloc(&conn->error_buf, &conn->error_buf_len, 150);     
-+  if(result != SASL_OK) MEMERROR(conn);
-+  result = _buf_alloc(&conn->errdetail_buf, &conn->errdetail_buf_len, 150);
-+  if(result != SASL_OK) MEMERROR(conn);
-+  
-+  conn->error_buf[0] = '\0';
-+  conn->errdetail_buf[0] = '\0';
-+  
-+  conn->decode_buf = NULL;
-+
-+  if(serverFQDN) {
-+      result = _sasl_strdup(serverFQDN, &conn->serverFQDN, NULL);
-+  } else if (conn->type == SASL_CONN_SERVER) {
-+      /* We can fake it because we *are* the server */
-+      char name[MAXHOSTNAMELEN];
-+      memset(name, 0, sizeof(name));
-+      gethostname(name, MAXHOSTNAMELEN);
-+      
-+      result = _sasl_strdup(name, &conn->serverFQDN, NULL);
-+  } else {
-+      conn->serverFQDN = NULL;
-+  }
-+  
-+
-+  if(result != SASL_OK) MEMERROR( conn );
-+
-+  RETURN(conn, SASL_OK);
-+}
-+
-+int _sasl_common_init(void)
-+{
-+    int result;
-+    
-+    /* Setup the global utilities */
-+    if(!sasl_global_utils) {
-+      sasl_global_utils = _sasl_alloc_utils(NULL, NULL);
-+      if(sasl_global_utils == NULL) return SASL_NOMEM;
-+    }
-+
-+    /* Init the canon_user plugin */
-+    result = sasl_canonuser_add_plugin("INTERNAL", internal_canonuser_init);
-+    if(result != SASL_OK) return result;    
-+
-+    if (!free_mutex)
-+      free_mutex = sasl_MUTEX_ALLOC();
-+    if (!free_mutex) return SASL_FAIL;
-+
-+    return SASL_OK;
-+}
-+
-+/* dispose connection state, sets it to NULL
-+ *  checks for pointer to NULL
-+ */
-+void sasl_dispose(sasl_conn_t **pconn)
-+{
-+  int result;
-+
-+  if (! pconn) return;
-+  if (! *pconn) return;
-+
-+  /* serialize disposes. this is necessary because we can't
-+     dispose of conn->mutex if someone else is locked on it */
-+  result = sasl_MUTEX_LOCK(free_mutex);
-+  if (result!=SASL_OK) return;
-+  
-+  /* *pconn might have become NULL by now */
-+  if (! (*pconn)) return;
-+
-+  (*pconn)->destroy_conn(*pconn);
-+  sasl_FREE(*pconn);
-+  *pconn=NULL;
-+
-+  sasl_MUTEX_UNLOCK(free_mutex);
-+}
-+
-+void _sasl_conn_dispose(sasl_conn_t *conn) {
-+  if (conn->serverFQDN)
-+      sasl_FREE(conn->serverFQDN);
-+
-+  if (conn->external.auth_id)
-+      sasl_FREE(conn->external.auth_id);
-+
-+  if(conn->encode_buf) {
-+      if(conn->encode_buf->data) sasl_FREE(conn->encode_buf->data);
-+      sasl_FREE(conn->encode_buf);
-+  }
-+
-+  if(conn->error_buf)
-+      sasl_FREE(conn->error_buf);
-+  
-+  if(conn->errdetail_buf)
-+      sasl_FREE(conn->errdetail_buf);
-+
-+  if(conn->decode_buf)
-+      sasl_FREE(conn->decode_buf);
-+
-+  if(conn->mechlist_buf)
-+      sasl_FREE(conn->mechlist_buf);
-+
-+  if(conn->service)
-+      sasl_FREE(conn->service);
-+
-+  /* oparams sub-members should be freed by the plugin, in so much
-+   * as they were allocated by the plugin */
-+}
-+
-+
-+/* get property from SASL connection state
-+ *  propnum       -- property number
-+ *  pvalue        -- pointer to value
-+ * returns:
-+ *  SASL_OK       -- no error
-+ *  SASL_NOTDONE  -- property not available yet
-+ *  SASL_BADPARAM -- bad property number
-+ */
-+int sasl_getprop(sasl_conn_t *conn, int propnum, const void **pvalue)
-+{
-+  int result = SASL_OK;
-+  sasl_getopt_t *getopt;
-+  void *context;
-+  
-+  if (! conn) return SASL_BADPARAM;
-+  if (! pvalue) PARAMERROR(conn);
-+
-+  switch(propnum)
-+  {
-+  case SASL_SSF:
-+      *(sasl_ssf_t **)pvalue= &conn->oparams.mech_ssf;
-+      break;      
-+  case SASL_MAXOUTBUF:
-+      *(unsigned **)pvalue = &conn->oparams.maxoutbuf;
-+      break;
-+  case SASL_GETOPTCTX:
-+      result = _sasl_getcallback(conn, SASL_CB_GETOPT, &getopt, &context);
-+      if(result != SASL_OK) break;
-+      
-+      *(void **)pvalue = context;
-+      break;
-+  case SASL_CALLBACK:
-+      *(const sasl_callback_t **)pvalue = conn->callbacks;
-+      break;
-+  case SASL_IPLOCALPORT:
-+      if(conn->got_ip_local)
-+        *(const char **)pvalue = conn->iplocalport;
-+      else {
-+        *(const char **)pvalue = NULL;
-+        result = SASL_NOTDONE;
-+      }
-+      break;
-+  case SASL_IPREMOTEPORT:
-+      if(conn->got_ip_remote)
-+        *(const char **)pvalue = conn->ipremoteport;
-+      else {
-+        *(const char **)pvalue = NULL;
-+        result = SASL_NOTDONE;
-+      }         
-+      break;
-+  case SASL_USERNAME:
-+      if(! conn->oparams.user)
-+        result = SASL_NOTDONE;
-+      else
-+        *((const char **)pvalue) = conn->oparams.user;
-+      break;
-+  case SASL_AUTHUSER:
-+      if(! conn->oparams.authid)
-+        result = SASL_NOTDONE;
-+      else
-+        *((const char **)pvalue) = conn->oparams.authid;
-+      break;
-+  case SASL_SERVERFQDN:
-+      *((const char **)pvalue) = conn->serverFQDN;
-+      break;
-+  case SASL_DEFUSERREALM:
-+      if(conn->type != SASL_CONN_SERVER) result = SASL_BADPROT;
-+      else
-+        *((const char **)pvalue) = ((sasl_server_conn_t *)conn)->user_realm;
-+      break;
-+  case SASL_SERVICE:
-+      *((const char **)pvalue) = conn->service;
-+      break;
-+  case SASL_AUTHSOURCE: /* name of plugin (not name of mech) */
-+      if(conn->type == SASL_CONN_CLIENT) {
-+        if(!((sasl_client_conn_t *)conn)->mech) {
-+            result = SASL_NOTDONE;
-+            break;
-+        }
-+        *((const char **)pvalue) =
-+            ((sasl_client_conn_t *)conn)->mech->plugname;
-+      } else if (conn->type == SASL_CONN_SERVER) {
-+        if(!((sasl_server_conn_t *)conn)->mech) {
-+            result = SASL_NOTDONE;
-+            break;
-+        }
-+        *((const char **)pvalue) =
-+            ((sasl_server_conn_t *)conn)->mech->plugname;
-+      } else {
-+        result = SASL_BADPARAM;
-+      }
-+      break;
-+  case SASL_MECHNAME: /* name of mech */
-+      if(conn->type == SASL_CONN_CLIENT) {
-+        if(!((sasl_client_conn_t *)conn)->mech) {
-+            result = SASL_NOTDONE;
-+            break;
-+        }
-+        *((const char **)pvalue) =
-+            ((sasl_client_conn_t *)conn)->mech->plug->mech_name;
-+      } else if (conn->type == SASL_CONN_SERVER) {
-+        if(!((sasl_server_conn_t *)conn)->mech) {
-+            result = SASL_NOTDONE;
-+            break;
-+        }
-+        *((const char **)pvalue) =
-+            ((sasl_server_conn_t *)conn)->mech->plug->mech_name;
-+      } else {
-+        result = SASL_BADPARAM;
-+      }
-+      
-+      if(!(*pvalue) && result == SASL_OK) result = SASL_NOTDONE;
-+      break;
-+  case SASL_PLUGERR:
-+      *((const char **)pvalue) = conn->error_buf;
-+      break;
-+  case SASL_SSF_EXTERNAL:
-+      *((const sasl_ssf_t **)pvalue) = &conn->external.ssf;
-+      break;
-+  case SASL_AUTH_EXTERNAL:
-+      *((const char **)pvalue) = conn->external.auth_id;
-+      break;
-+  case SASL_SEC_PROPS:
-+      *((const sasl_security_properties_t **)pvalue) = &conn->props;
-+      break;
-+  default: 
-+      result = SASL_BADPARAM;
-+  }
-+
-+  if(result == SASL_BADPARAM) {
-+      PARAMERROR(conn);
-+  } else if(result == SASL_NOTDONE) {
-+      sasl_seterror(conn, SASL_NOLOG,
-+                  "Information that was requested is not yet available.");
-+      RETURN(conn, result);
-+  } else if(result != SASL_OK) {
-+      INTERROR(conn, result);
-+  } else
-+      RETURN(conn, result); 
-+}
-+
-+/* set property in SASL connection state
-+ * returns:
-+ *  SASL_OK       -- value set
-+ *  SASL_BADPARAM -- invalid property or value
-+ */
-+int sasl_setprop(sasl_conn_t *conn, int propnum, const void *value)
-+{
-+  int result = SASL_OK;
-+  char *str;
-+
-+  /* make sure the sasl context is valid */
-+  if (!conn)
-+    return SASL_BADPARAM;
-+
-+  switch(propnum)
-+  {
-+  case SASL_SSF_EXTERNAL:
-+      conn->external.ssf = *((sasl_ssf_t *)value);
-+      break;
-+
-+  case SASL_AUTH_EXTERNAL:
-+      if(value && strlen(value)) {
-+        result = _sasl_strdup(value, &str, NULL);
-+        if(result != SASL_OK) MEMERROR(conn);
-+      } else {
-+        str = NULL;
-+      }
-+
-+      if(conn->external.auth_id)
-+        sasl_FREE(conn->external.auth_id);
-+
-+      conn->external.auth_id = str;
-+
-+      break;
-+
-+  case SASL_DEFUSERREALM:
-+      if(conn->type != SASL_CONN_SERVER) {
-+      sasl_seterror(conn, 0, "Tried to set realm on non-server connection");
-+      result = SASL_BADPROT;
-+      break;
-+      }
-+
-+      if(value && strlen(value)) {
-+        result = _sasl_strdup(value, &str, NULL);
-+        if(result != SASL_OK) MEMERROR(conn);
-+      } else {
-+        PARAMERROR(conn);
-+      }
-+
-+      if(((sasl_server_conn_t *)conn)->user_realm)
-+                sasl_FREE(((sasl_server_conn_t *)conn)->user_realm);
-+
-+      ((sasl_server_conn_t *)conn)->user_realm = str;
-+      ((sasl_server_conn_t *)conn)->sparams->user_realm = str;
-+
-+      break;
-+
-+  case SASL_SEC_PROPS:
-+  {
-+      sasl_security_properties_t *props = (sasl_security_properties_t *)value;
-+
-+      if(props->maxbufsize == 0 && props->min_ssf != 0) {
-+        sasl_seterror(conn, 0,
-+                      "Attempt to disable security layers (maxoutbuf == 0) with min_ssf > 0");
-+        RETURN(conn, SASL_TOOWEAK);
-+      }
-+
-+      memcpy(&(conn->props), props,
-+           sizeof(sasl_security_properties_t));
-+
-+      break;
-+  }
-+      
-+  case SASL_IPREMOTEPORT:
-+  {
-+      const char *ipremoteport = (const char *)value;
-+      if(!value) {
-+        conn->got_ip_remote = 0; 
-+      } else if (_sasl_ipfromstring(ipremoteport, NULL, 0)
-+               != SASL_OK) {
-+        sasl_seterror(conn, 0, "Bad IPREMOTEPORT value");
-+        RETURN(conn, SASL_BADPARAM);
-+      } else {
-+        strcpy(conn->ipremoteport, ipremoteport);
-+        conn->got_ip_remote = 1;
-+      }
-+      
-+      if(conn->got_ip_remote) {
-+        if(conn->type == SASL_CONN_CLIENT) {
-+            ((sasl_client_conn_t *)conn)->cparams->ipremoteport
-+                = conn->ipremoteport;
-+            ((sasl_client_conn_t *)conn)->cparams->ipremlen =
-+                strlen(conn->ipremoteport);
-+        } else if (conn->type == SASL_CONN_SERVER) {
-+            ((sasl_server_conn_t *)conn)->sparams->ipremoteport
-+                = conn->ipremoteport;
-+            ((sasl_server_conn_t *)conn)->sparams->ipremlen =
-+                strlen(conn->ipremoteport);
-+        }
-+      } else {
-+        if(conn->type == SASL_CONN_CLIENT) {
-+            ((sasl_client_conn_t *)conn)->cparams->ipremoteport
-+                = NULL;
-+            ((sasl_client_conn_t *)conn)->cparams->ipremlen = 0;
-+        } else if (conn->type == SASL_CONN_SERVER) {
-+            ((sasl_server_conn_t *)conn)->sparams->ipremoteport
-+                = NULL;             
-+            ((sasl_server_conn_t *)conn)->sparams->ipremlen = 0;
-+        }
-+      }
-+
-+      break;
-+  }
-+
-+  case SASL_IPLOCALPORT:
-+  {
-+      const char *iplocalport = (const char *)value;
-+      if(!value) {
-+        conn->got_ip_local = 0;         
-+      } else if (_sasl_ipfromstring(iplocalport, NULL, 0)
-+               != SASL_OK) {
-+        sasl_seterror(conn, 0, "Bad IPLOCALPORT value");
-+        RETURN(conn, SASL_BADPARAM);
-+      } else {
-+        strcpy(conn->iplocalport, iplocalport);
-+        conn->got_ip_local = 1;
-+      }
-+
-+      if(conn->got_ip_local) {
-+        if(conn->type == SASL_CONN_CLIENT) {
-+            ((sasl_client_conn_t *)conn)->cparams->iplocalport
-+                = conn->iplocalport;
-+            ((sasl_client_conn_t *)conn)->cparams->iploclen
-+                = strlen(conn->iplocalport);
-+        } else if (conn->type == SASL_CONN_SERVER) {
-+            ((sasl_server_conn_t *)conn)->sparams->iplocalport
-+                = conn->iplocalport;
-+            ((sasl_server_conn_t *)conn)->sparams->iploclen
-+                = strlen(conn->iplocalport);
-+        }
-+      } else {
-+        if(conn->type == SASL_CONN_CLIENT) {
-+            ((sasl_client_conn_t *)conn)->cparams->iplocalport
-+                = NULL;
-+            ((sasl_client_conn_t *)conn)->cparams->iploclen = 0;
-+        } else if (conn->type == SASL_CONN_SERVER) {
-+            ((sasl_server_conn_t *)conn)->sparams->iplocalport
-+                = NULL;
-+            ((sasl_server_conn_t *)conn)->sparams->iploclen = 0;
-+        }
-+      }
-+      break;
-+  }
-+
-+  default:
-+      sasl_seterror(conn, 0, "Unknown parameter type");
-+      result = SASL_BADPARAM;
-+  }
-+  
-+  RETURN(conn, result);
-+}
-+
-+/* this is apparently no longer a user function */
-+static int sasl_usererr(int saslerr)
-+{
-+    /* Hide the difference in a username failure and a password failure */
-+    if (saslerr == SASL_NOUSER)
-+      return SASL_BADAUTH;
-+
-+    /* otherwise return the error given; no transform necessary */
-+    return saslerr;
-+}
-+
-+const char *sasl_errstring(int saslerr,
-+                         const char *langlist __attribute__((unused)),
-+                         const char **outlang)
-+{
-+  if (outlang) *outlang="en-us";
-+
-+  switch(saslerr)
-+    {
-+    case SASL_CONTINUE: return "another step is needed in authentication";
-+    case SASL_OK:       return "successful result";
-+    case SASL_FAIL:     return "generic failure";
-+    case SASL_NOMEM:    return "no memory available";
-+    case SASL_BUFOVER:  return "overflowed buffer";
-+    case SASL_NOMECH:   return "no mechanism available";
-+    case SASL_BADPROT:  return "bad protocol / cancel";
-+    case SASL_NOTDONE:  return "can't request info until later in exchange";
-+    case SASL_BADPARAM: return "invalid parameter supplied";
-+    case SASL_TRYAGAIN: return "transient failure (e.g., weak key)";
-+    case SASL_BADMAC:   return "integrity check failed";
-+    case SASL_NOTINIT:  return "SASL library not initialized";
-+                             /* -- client only codes -- */
-+    case SASL_INTERACT:   return "needs user interaction";
-+    case SASL_BADSERV:    return "server failed mutual authentication step";
-+    case SASL_WRONGMECH:  return "mechanism doesn't support requested feature";
-+                             /* -- server only codes -- */
-+    case SASL_BADAUTH:    return "authentication failure";
-+    case SASL_NOAUTHZ:    return "authorization failure";
-+    case SASL_TOOWEAK:    return "mechanism too weak for this user";
-+    case SASL_ENCRYPT:    return "encryption needed to use mechanism";
-+    case SASL_TRANS:      return "One time use of a plaintext password will enable requested mechanism for user";
-+    case SASL_EXPIRED:    return "passphrase expired, has to be reset";
-+    case SASL_DISABLED:   return "account disabled";
-+    case SASL_NOUSER:     return "user not found";
-+    case SASL_BADVERS:    return "version mismatch with plug-in";
-+    case SASL_UNAVAIL:    return "remote authentication server unavailable";
-+    case SASL_NOVERIFY:   return "user exists, but no verifier for user";
-+    case SASL_PWLOCK:     return "passphrase locked";
-+    case SASL_NOCHANGE:   return "requested change was not needed";
-+    case SASL_WEAKPASS:   return "passphrase is too weak for security policy";
-+    case SASL_NOUSERPASS: return "user supplied passwords are not permitted";
-+
-+    default:   return "undefined error!";
-+    }
-+
-+}
-+
-+/* Return the sanitized error detail about the last error that occured for 
-+ * a connection */
-+const char *sasl_errdetail(sasl_conn_t *conn) 
-+{
-+    unsigned need_len;
-+    const char *errstr;
-+    char leader[128];
-+
-+    if(!conn) return NULL;
-+    
-+    errstr = sasl_errstring(conn->error_code, NULL, NULL);
-+    snprintf(leader,128,"SASL(%d): %s: ",
-+           sasl_usererr(conn->error_code), errstr);
-+    
-+    need_len = strlen(leader) + strlen(conn->error_buf) + 12;
-+    _buf_alloc(&conn->errdetail_buf, &conn->errdetail_buf_len, need_len);
-+
-+    snprintf(conn->errdetail_buf, need_len, "%s%s", leader, conn->error_buf);
-+   
-+    return conn->errdetail_buf;
-+}
-+
-+
-+/* Note that this needs the global callbacks, so if you don't give getcallbacks
-+ * a sasl_conn_t, you're going to need to pass it yourself (or else we couldn't
-+ * have client and server at the same time */
-+static int _sasl_global_getopt(void *context,
-+                             const char *plugin_name,
-+                             const char *option,
-+                             const char ** result,
-+                             unsigned *len)
-+{
-+  const sasl_global_callbacks_t * global_callbacks;
-+  const sasl_callback_t *callback;
-+
-+  global_callbacks = (const sasl_global_callbacks_t *) context;
-+
-+  if (global_callbacks && global_callbacks->callbacks) {
-+      for (callback = global_callbacks->callbacks;
-+         callback->id != SASL_CB_LIST_END;
-+         callback++) {
-+        if (callback->id == SASL_CB_GETOPT
-+            && (((sasl_getopt_t *)(callback->proc))(callback->context,
-+                                                    plugin_name,
-+                                                    option,
-+                                                    result,
-+                                                    len)
-+                == SASL_OK))
-+            return SASL_OK;
-+      }
-+  }
-+
-+  /* look it up in our configuration file */
-+  *result = sasl_config_getstring(option, NULL);
-+  if (*result != NULL) {
-+      if (len) { *len = strlen(*result); }
-+      return SASL_OK;
-+  }
-+
-+  return SASL_FAIL;
-+}
-+
-+static int
-+_sasl_conn_getopt(void *context,
-+                const char *plugin_name,
-+                const char *option,
-+                const char ** result,
-+                unsigned *len)
-+{
-+  sasl_conn_t * conn;
-+  const sasl_callback_t *callback;
-+
-+  if (! context)
-+    return SASL_BADPARAM;
-+
-+  conn = (sasl_conn_t *) context;
-+
-+  if (conn->callbacks)
-+    for (callback = conn->callbacks;
-+       callback->id != SASL_CB_LIST_END;
-+       callback++)
-+      if (callback->id == SASL_CB_GETOPT
-+        && (((sasl_getopt_t *)(callback->proc))(callback->context,
-+                                                plugin_name,
-+                                                option,
-+                                                result,
-+                                                len)
-+            == SASL_OK))
-+      return SASL_OK;
-+
-+  /* If we made it here, we didn't find an appropriate callback
-+   * in the connection's callback list, or the callback we did
-+   * find didn't return SASL_OK.  So we attempt to use the
-+   * global callback for this connection... */
-+  return _sasl_global_getopt((void *)conn->global_callbacks,
-+                           plugin_name,
-+                           option,
-+                           result,
-+                           len);
-+}
-+
-+#ifdef HAVE_SYSLOG
-+/* this is the default logging */
-+static int _sasl_syslog(void *context __attribute__((unused)),
-+                      int priority,
-+                      const char *message)
-+{
-+    int syslog_priority;
-+
-+    /* set syslog priority */
-+    switch(priority) {
-+    case SASL_LOG_NONE:
-+      return SASL_OK;
-+      break;
-+    case SASL_LOG_ERR:
-+      syslog_priority = LOG_ERR;
-+      break;
-+    case SASL_LOG_WARN:
-+      syslog_priority = LOG_WARNING;
-+      break;
-+    case SASL_LOG_NOTE:
-+    case SASL_LOG_FAIL:
-+      syslog_priority = LOG_NOTICE;
-+      break;
-+    case SASL_LOG_PASS:
-+    case SASL_LOG_TRACE:
-+    case SASL_LOG_DEBUG:
-+    default:
-+      syslog_priority = LOG_DEBUG;
-+      break;
-+    }
-+    
-+    /* do the syslog call. do not need to call openlog */
-+    syslog(syslog_priority | LOG_AUTH, "%s", message);
-+    
-+    return SASL_OK;
-+}
-+#endif                                /* HAVE_SYSLOG */
-+
-+static int
-+_sasl_getsimple(void *context,
-+              int id,
-+              const char ** result,
-+              size_t *len)
-+{
-+  const char *userid;
-+  sasl_conn_t *conn;
-+
-+  if (! context || ! result) return SASL_BADPARAM;
-+
-+  conn = (sasl_conn_t *)context;
-+
-+  switch(id) {
-+  case SASL_CB_AUTHNAME:
-+    userid = getenv("USER");
-+    if (userid != NULL) {
-+      *result = userid;
-+      if (len) *len = strlen(userid);
-+      return SASL_OK;
-+    }
-+    userid = getenv("USERNAME");
-+    if (userid != NULL) {
-+      *result = userid;
-+      if (len) *len = strlen(userid);
-+      return SASL_OK;
-+    }
-+#ifdef WIN32
-+    /* for win32, try using the GetUserName standard call */
-+    {
-+      DWORD i;
-+      BOOL rval;
-+      static char sender[128];
-+      
-+      i = sizeof(sender);
-+      rval = GetUserName(sender, &i);
-+      if ( rval) { /* got a userid */
-+              *result = sender;
-+              if (len) *len = strlen(sender);
-+              return SASL_OK;
-+      }
-+    }
-+#endif /* WIN32 */
-+    return SASL_FAIL;
-+  default:
-+    return SASL_BADPARAM;
-+  }
-+}
-+
-+static int
-+_sasl_verifyfile(void *context __attribute__((unused)),
-+               char *file  __attribute__((unused)),
-+               int type  __attribute__((unused)))
-+{
-+  /* always say ok */
-+  return SASL_OK;
-+}
-+
-+
-+static int
-+_sasl_proxy_policy(sasl_conn_t *conn,
-+                 void *context __attribute__((unused)),
-+                 const char *requested_user, unsigned rlen,
-+                 const char *auth_identity, unsigned alen,
-+                 const char *def_realm __attribute__((unused)),
-+                 unsigned urlen __attribute__((unused)),
-+                 struct propctx *propctx __attribute__((unused)))
-+{
-+    if (!conn)
-+      return SASL_BADPARAM;
-+
-+    if (!requested_user || *requested_user == '\0')
-+      return SASL_OK;
-+
-+    if (!auth_identity || !requested_user || rlen != alen ||
-+      (memcmp(auth_identity, requested_user, rlen) != 0)) {
-+      sasl_seterror(conn, 0,
-+                    "Requested identity not authenticated identity");
-+      RETURN(conn, SASL_BADAUTH);
-+    }
-+
-+    return SASL_OK;
-+}
-+
-+int _sasl_getcallback(sasl_conn_t * conn,
-+                    unsigned long callbackid,
-+                    int (**pproc)(),
-+                    void **pcontext)
-+{
-+  const sasl_callback_t *callback;
-+
-+  if (!pproc || !pcontext)
-+      PARAMERROR(conn);
-+
-+  /* Some callbacks are always provided by the library */
-+  switch (callbackid) {
-+  case SASL_CB_LIST_END:
-+    /* Nothing ever gets to provide this */
-+      INTERROR(conn, SASL_FAIL);
-+  case SASL_CB_GETOPT:
-+      if (conn) {
-+        *pproc = &_sasl_conn_getopt;
-+        *pcontext = conn;
-+      } else {
-+        *pproc = &_sasl_global_getopt;
-+        *pcontext = NULL;
-+      }
-+      return SASL_OK;
-+  }
-+
-+  /* If it's not always provided by the library, see if there's
-+   * a version provided by the application for this connection... */
-+  if (conn && conn->callbacks) {
-+    for (callback = conn->callbacks; callback->id != SASL_CB_LIST_END;
-+       callback++) {
-+      if (callback->id == callbackid) {
-+          *pproc = callback->proc;
-+          *pcontext = callback->context;
-+          if (callback->proc) {
-+              return SASL_OK;
-+          } else {
-+              return SASL_INTERACT;
-+          }
-+      }
-+    }
-+  }
-+
-+  /* And, if not for this connection, see if there's one
-+   * for all {server,client} connections... */
-+  if (conn && conn->global_callbacks && conn->global_callbacks->callbacks) {
-+      for (callback = conn->global_callbacks->callbacks;
-+         callback->id != SASL_CB_LIST_END;
-+         callback++) {
-+        if (callback->id == callbackid) {
-+            *pproc = callback->proc;
-+            *pcontext = callback->context;
-+            if (callback->proc) {
-+                return SASL_OK;
-+            } else {
-+                return SASL_INTERACT;
-+            }
-+        }
-+      }
-+  }
-+
-+  /* Otherwise, see if the library provides a default callback. */
-+  switch (callbackid) {
-+#ifdef HAVE_SYSLOG
-+  case SASL_CB_LOG:
-+    *pproc = (int (*)()) &_sasl_syslog;
-+    *pcontext = NULL;
-+    return SASL_OK;
-+#endif /* HAVE_SYSLOG */
-+  case SASL_CB_GETPATH:
-+    *pproc = (int (*)()) &_sasl_getpath;
-+    *pcontext = NULL;
-+    return SASL_OK;
-+  case SASL_CB_AUTHNAME:
-+    *pproc = (int (*)()) &_sasl_getsimple;
-+    *pcontext = conn;
-+    return SASL_OK;
-+  case SASL_CB_VERIFYFILE:
-+    *pproc = & _sasl_verifyfile;
-+    *pcontext = NULL;
-+    return SASL_OK;
-+  case SASL_CB_PROXY_POLICY:
-+    *pproc = (int (*)()) &_sasl_proxy_policy;
-+    *pcontext = NULL;
-+    return SASL_OK;
-+  }
-+
-+  /* Unable to find a callback... */
-+  *pproc = NULL;
-+  *pcontext = NULL;
-+  sasl_seterror(conn, SASL_NOLOG, "Unable to find a callback: %d", callbackid);
-+  RETURN(conn,SASL_FAIL);
-+}
-+
-+
-+/*
-+ * This function is typically called from a plugin.
-+ * It creates a string from the formatting and varargs given
-+ * and calls the logging callback (syslog by default)
-+ *
-+ * %m will parse the value in the next argument as an errno string
-+ * %z will parse the next argument as a SASL error code.
-+ */
-+
-+void
-+_sasl_log (sasl_conn_t *conn,
-+         int level,
-+         const char *fmt,
-+         ...)
-+{
-+  char *out=(char *) sasl_ALLOC(250);
-+  size_t alloclen=100; /* current allocated length */
-+  size_t outlen=0; /* current length of output buffer */
-+  size_t formatlen;
-+  size_t pos=0; /* current position in format string */
-+  int result;
-+  sasl_log_t *log_cb;
-+  void *log_ctx;
-+  
-+  int ival;
-+  char *cval;
-+  va_list ap; /* varargs thing */
-+
-+  if(!fmt) goto done;
-+  if(!out) return;
-+  
-+  formatlen = strlen(fmt);
-+
-+  /* See if we have a logging callback... */
-+  result = _sasl_getcallback(conn, SASL_CB_LOG, &log_cb, &log_ctx);
-+  if (result == SASL_OK && ! log_cb)
-+    result = SASL_FAIL;
-+  if (result != SASL_OK) goto done;
-+  
-+  va_start(ap, fmt); /* start varargs */
-+
-+  while(pos<formatlen)
-+  {
-+    if (fmt[pos]!='%') /* regular character */
-+    {
-+      result = _buf_alloc(&out, &alloclen, outlen+1);
-+      if (result != SASL_OK) goto done;
-+      out[outlen]=fmt[pos];
-+      outlen++;
-+      pos++;
-+
-+    } else { /* formating thing */
-+      int done=0;
-+      char frmt[10];
-+      int frmtpos=1;
-+      char tempbuf[21];
-+      frmt[0]='%';
-+      pos++;
-+
-+      while (done==0)
-+      {
-+      switch(fmt[pos])
-+        {
-+        case 's': /* need to handle this */
-+          cval = va_arg(ap, char *); /* get the next arg */
-+          result = _sasl_add_string(&out, &alloclen,
-+                              &outlen, cval);
-+            
-+          if (result != SASL_OK) /* add the string */
-+              goto done;
-+
-+          done=1;
-+          break;
-+
-+        case '%': /* double % output the '%' character */
-+          result = _buf_alloc(&out,&alloclen,outlen+1);
-+          if (result != SASL_OK)
-+              goto done;
-+          
-+          out[outlen]='%';
-+          outlen++;
-+          done=1;
-+          break;
-+
-+        case 'm': /* insert the errno string */
-+          result = _sasl_add_string(&out, &alloclen, &outlen,
-+                              strerror(va_arg(ap, int)));
-+          if (result != SASL_OK)
-+              goto done;
-+          
-+          done=1;
-+          break;
-+
-+        case 'z': /* insert the sasl error string */
-+          result = _sasl_add_string(&out, &alloclen, &outlen,
-+                              (char *) sasl_errstring(va_arg(ap, int),NULL,NULL));
-+          if (result != SASL_OK)
-+              goto done;
-+          
-+          done=1;
-+          break;
-+
-+        case 'c':
-+          frmt[frmtpos++]=fmt[pos];
-+          frmt[frmtpos]=0;
-+          tempbuf[0] = (char) va_arg(ap, int); /* get the next arg */
-+          tempbuf[1]='\0';
-+          
-+          /* now add the character */
-+          result = _sasl_add_string(&out, &alloclen, &outlen, tempbuf);
-+          if (result != SASL_OK)
-+              goto done;
-+              
-+          done=1;
-+          break;
-+
-+        case 'd':
-+        case 'i':
-+          frmt[frmtpos++]=fmt[pos];
-+          frmt[frmtpos]=0;
-+          ival = va_arg(ap, int); /* get the next arg */
-+
-+          snprintf(tempbuf,20,frmt,ival); /* have snprintf do the work */
-+          /* now add the string */
-+          result = _sasl_add_string(&out, &alloclen, &outlen, tempbuf);
-+          if (result != SASL_OK)
-+              goto done;
-+
-+          done=1;
-+
-+          break;
-+        default: 
-+          frmt[frmtpos++]=fmt[pos]; /* add to the formating */
-+          frmt[frmtpos]=0;        
-+          if (frmtpos>9) 
-+            done=1;
-+        }
-+      pos++;
-+      if (pos>formatlen)
-+        done=1;
-+      }
-+
-+    }
-+  }
-+
-+  /* put 0 at end */
-+  result = _buf_alloc(&out, &alloclen, outlen+1);
-+  if (result != SASL_OK) goto done;
-+  out[outlen]=0;
-+
-+  va_end(ap);    
-+
-+  /* send log message */
-+  result = log_cb(log_ctx, level, out);
-+
-+ done:
-+  if(out) sasl_FREE(out);
-+}
-+
-+
-+
-+/* Allocate and Init a sasl_utils_t structure */
-+sasl_utils_t *
-+_sasl_alloc_utils(sasl_conn_t *conn,
-+                sasl_global_callbacks_t *global_callbacks)
-+{
-+  sasl_utils_t *utils;
-+  /* set util functions - need to do rest*/
-+  utils=sasl_ALLOC(sizeof(sasl_utils_t));
-+  if (utils==NULL)
-+    return NULL;
-+
-+  utils->conn = conn;
-+
-+  sasl_randcreate(&utils->rpool);
-+
-+  if (conn) {
-+    utils->getopt = &_sasl_conn_getopt;
-+    utils->getopt_context = conn;
-+  } else {
-+    utils->getopt = &_sasl_global_getopt;
-+    utils->getopt_context = global_callbacks;
-+  }
-+
-+  utils->malloc=_sasl_allocation_utils.malloc;
-+  utils->calloc=_sasl_allocation_utils.calloc;
-+  utils->realloc=_sasl_allocation_utils.realloc;
-+  utils->free=_sasl_allocation_utils.free;
-+
-+  utils->mutex_alloc = _sasl_mutex_utils.alloc;
-+  utils->mutex_lock = _sasl_mutex_utils.lock;
-+  utils->mutex_unlock = _sasl_mutex_utils.unlock;
-+  utils->mutex_free = _sasl_mutex_utils.free;
-+  
-+  utils->MD5Init  = &_sasl_MD5Init;
-+  utils->MD5Update= &_sasl_MD5Update;
-+  utils->MD5Final = &_sasl_MD5Final;
-+  utils->hmac_md5 = &_sasl_hmac_md5;
-+  utils->hmac_md5_init = &_sasl_hmac_md5_init;
-+  utils->hmac_md5_final = &_sasl_hmac_md5_final;
-+  utils->hmac_md5_precalc = &_sasl_hmac_md5_precalc;
-+  utils->hmac_md5_import = &_sasl_hmac_md5_import;
-+  utils->mkchal = &sasl_mkchal;
-+  utils->utf8verify = &sasl_utf8verify;
-+  utils->rand=&sasl_rand;
-+  utils->churn=&sasl_churn;  
-+  utils->checkpass=NULL;
-+  
-+  utils->encode64=&sasl_encode64;
-+  utils->decode64=&sasl_decode64;
-+  
-+  utils->erasebuffer=&sasl_erasebuffer;
-+
-+  utils->getprop=&sasl_getprop;
-+  utils->setprop=&sasl_setprop;
-+
-+  utils->getcallback=&_sasl_getcallback;
-+
-+  utils->log=&_sasl_log;
-+
-+  utils->seterror=&sasl_seterror;
-+
-+#ifndef macintosh
-+  /* Aux Property Utilities */
-+  utils->prop_new=&prop_new;
-+  utils->prop_dup=&prop_dup;
-+  utils->prop_request=&prop_request;
-+  utils->prop_get=&prop_get;
-+  utils->prop_getnames=&prop_getnames;
-+  utils->prop_clear=&prop_clear;
-+  utils->prop_dispose=&prop_dispose;
-+  utils->prop_format=&prop_format;
-+  utils->prop_set=&prop_set;
-+  utils->prop_setvals=&prop_setvals;
-+  utils->prop_erase=&prop_erase;
-+#endif
-+
-+  /* Spares */
-+  utils->spare_fptr = NULL;
-+  utils->spare_fptr1 = utils->spare_fptr2 = 
-+      utils->spare_fptr3 = NULL;
-+  
-+  return utils;
-+}
-+
-+int
-+_sasl_free_utils(const sasl_utils_t ** utils)
-+{
-+    sasl_utils_t *nonconst;
-+
-+    if(!utils) return SASL_BADPARAM;
-+    if(!*utils) return SASL_OK;
-+
-+    /* I wish we could avoid this cast, it's pretty gratuitous but it
-+     * does make life easier to have it const everywhere else. */
-+    nonconst = (sasl_utils_t *)(*utils);
-+
-+    sasl_randfree(&(nonconst->rpool));
-+    sasl_FREE(nonconst);
-+
-+    *utils = NULL;
-+    return SASL_OK;
-+}
-+
-+int sasl_idle(sasl_conn_t *conn)
-+{
-+  if (! conn) {
-+    if (_sasl_server_idle_hook
-+      && _sasl_server_idle_hook(NULL))
-+      return 1;
-+    if (_sasl_client_idle_hook
-+      && _sasl_client_idle_hook(NULL))
-+      return 1;
-+    return 0;
-+  }
-+
-+  if (conn->idle_hook)
-+    return conn->idle_hook(conn);
-+
-+  return 0;
-+}
-+
-+const sasl_callback_t *
-+_sasl_find_getpath_callback(const sasl_callback_t *callbacks)
-+{
-+  static const sasl_callback_t default_getpath_cb = {
-+    SASL_CB_GETPATH,
-+    &_sasl_getpath,
-+    NULL
-+  };
-+
-+  if (callbacks)
-+    while (callbacks->id != SASL_CB_LIST_END)
-+    {
-+      if (callbacks->id == SASL_CB_GETPATH)
-+      {
-+      return callbacks;
-+      } else {
-+      ++callbacks;
-+      }
-+    }
-+  
-+  return &default_getpath_cb;
-+}
-+
-+const sasl_callback_t *
-+_sasl_find_verifyfile_callback(const sasl_callback_t *callbacks)
-+{
-+  static const sasl_callback_t default_verifyfile_cb = {
-+    SASL_CB_VERIFYFILE,
-+    &_sasl_verifyfile,
-+    NULL
-+  };
-+
-+  if (callbacks)
-+    while (callbacks->id != SASL_CB_LIST_END)
-+    {
-+      if (callbacks->id == SASL_CB_VERIFYFILE)
-+      {
-+      return callbacks;
-+      } else {
-+      ++callbacks;
-+      }
-+    }
-+  
-+  return &default_verifyfile_cb;
-+}
-+
-+/* Basically a conditional call to realloc(), if we need more */
-+int _buf_alloc(char **rwbuf, size_t *curlen, size_t newlen) 
-+{
-+    if(!(*rwbuf)) {
-+      *rwbuf = sasl_ALLOC(newlen);
-+      if (*rwbuf == NULL) {
-+          *curlen = 0;
-+          return SASL_NOMEM;
-+      }
-+      *curlen = newlen;
-+    } else if(*rwbuf && *curlen < newlen) {
-+      size_t needed = 2*(*curlen);
-+
-+      while(needed < newlen)
-+          needed *= 2;
-+
-+      *rwbuf = sasl_REALLOC(*rwbuf, needed);
-+      
-+      if (*rwbuf == NULL) {
-+          *curlen = 0;
-+          return SASL_NOMEM;
-+      }
-+      *curlen = needed;
-+    } 
-+
-+    return SASL_OK;
-+}
-+
-+/* for the mac os x cfm glue: this lets the calling function
-+   get pointers to the error buffer without having to touch the sasl_conn_t struct */
-+void _sasl_get_errorbuf(sasl_conn_t *conn, char ***bufhdl, size_t **lenhdl)
-+{
-+      *bufhdl = &conn->error_buf;
-+      *lenhdl = &conn->error_buf_len;
-+}
-+
-+/* convert an iovec to a single buffer */
-+int _iovec_to_buf(const struct iovec *vec,
-+                unsigned numiov, buffer_info_t **output) 
-+{
-+    unsigned i;
-+    int ret;
-+    buffer_info_t *out;
-+    char *pos;
-+
-+    if(!vec || !output) return SASL_BADPARAM;
-+
-+    if(!(*output)) {
-+      *output = sasl_ALLOC(sizeof(buffer_info_t));
-+      if(!*output) return SASL_NOMEM;
-+      memset(*output,0,sizeof(buffer_info_t));
-+    }
-+
-+    out = *output;
-+    
-+    out->curlen = 0;
-+    for(i=0; i<numiov; i++)
-+      out->curlen += vec[i].iov_len;
-+
-+    ret = _buf_alloc(&out->data, &out->reallen, out->curlen);
-+
-+    if(ret != SASL_OK) return SASL_NOMEM;
-+    
-+    memset(out->data, 0, out->reallen);
-+    pos = out->data;
-+    
-+    for(i=0; i<numiov; i++) {
-+      memcpy(pos, vec[i].iov_base, vec[i].iov_len);
-+      pos += vec[i].iov_len;
-+    }
-+
-+    return SASL_OK;
-+}
-+
-+/* This code might be useful in the future, but it isn't now, so.... */
-+#if 0
-+int _sasl_iptostring(const struct sockaddr *addr, socklen_t addrlen,
-+                   char *out, unsigned outlen) {
-+    char hbuf[NI_MAXHOST], pbuf[NI_MAXSERV];
-+    
-+    if(!addr || !out) return SASL_BADPARAM;
-+
-+    getnameinfo(addr, addrlen, hbuf, sizeof(hbuf), pbuf, sizeof(pbuf),
-+              NI_NUMERICHOST | NI_WITHSCOPEID | NI_NUMERICSERV);
-+
-+    if(outlen < strlen(hbuf) + strlen(pbuf) + 2)
-+      return SASL_BUFOVER;
-+
-+    snprintf(out, outlen, "%s;%s", hbuf, pbuf);
-+
-+    return SASL_OK;
-+}
-+#endif
-+
-+int _sasl_ipfromstring(const char *addr,
-+                     struct sockaddr *out, socklen_t outlen) 
-+{
-+    int i, j;
-+    struct addrinfo hints, *ai = NULL;
-+    char hbuf[NI_MAXHOST];
-+    
-+    /* A NULL out pointer just implies we don't do a copy, just verify it */
-+
-+    if(!addr) return SASL_BADPARAM;
-+
-+    /* Parse the address */
-+    for (i = 0; addr[i] != '\0' && addr[i] != ';'; i++) {
-+      if (i >= NI_MAXHOST)
-+          return SASL_BADPARAM;
-+      hbuf[i] = addr[i];
-+    }
-+    hbuf[i] = '\0';
-+
-+    if (addr[i] == ';')
-+      i++;
-+    /* XXX: Do we need this check? */
-+    for (j = i; addr[j] != '\0'; j++)
-+      if (!isdigit((int)(addr[j])))
-+          return SASL_BADPARAM;
-+
-+    memset(&hints, 0, sizeof(hints));
-+    hints.ai_family = PF_UNSPEC;
-+    hints.ai_socktype = SOCK_STREAM;
-+    hints.ai_flags = AI_PASSIVE | AI_NUMERICHOST;
-+    if (getaddrinfo(hbuf, &addr[i], &hints, &ai) != 0)
-+      return SASL_BADPARAM;
-+
-+    if (out) {
-+      if (outlen < (socklen_t)ai->ai_addrlen) {
-+          freeaddrinfo(ai);
-+          return SASL_BUFOVER;
-+      }
-+      memcpy(out, ai->ai_addr, ai->ai_addrlen);
-+    }
-+
-+    freeaddrinfo(ai);
-+
-+    return SASL_OK;
-+}
-+
-+int _sasl_build_mechlist(void) 
-+{
-+    int count = 0;
-+    sasl_string_list_t *clist = NULL, *slist = NULL, *olist = NULL;
-+    sasl_string_list_t *p, *q, **last, *p_next;
-+
-+    clist = _sasl_client_mechs();
-+    slist = _sasl_server_mechs();
-+
-+    if(!clist) {
-+      olist = slist;
-+    } else {
-+      int flag;
-+      
-+      /* append slist to clist, and set olist to clist */
-+      for(p = slist; p; p = p_next) {
-+          flag = 0;
-+          p_next = p->next;
-+
-+          last = &clist;
-+          for(q = clist; q; q = q->next) {
-+              if(!strcmp(q->d, p->d)) {
-+                  /* They match, set the flag */
-+                  flag = 1;
-+                  break;
-+              }
-+              last = &(q->next);
-+          }
-+
-+          if(!flag) {
-+              (*last)->next = p;
-+              p->next = NULL;
-+          } else {
-+              sasl_FREE(p);
-+          }
-+      }
-+
-+      olist = clist;
-+    }
-+
-+    if(!olist) {
-+      printf ("no olist");
-+      return SASL_FAIL;
-+    }
-+
-+    for (p = olist; p; p = p->next) count++;
-+    
-+    if(global_mech_list) {
-+      sasl_FREE(global_mech_list);
-+      global_mech_list = NULL;
-+    }
-+    
-+    global_mech_list = sasl_ALLOC((count + 1) * sizeof(char *));
-+    if(!global_mech_list) return SASL_NOMEM;
-+    
-+    memset(global_mech_list, 0, (count + 1) * sizeof(char *));
-+    
-+    count = 0;
-+    for (p = olist; p; p = p_next) {
-+      p_next = p->next;
-+
-+      global_mech_list[count++] = (char *) p->d;
-+
-+      sasl_FREE(p);
-+    }
-+
-+    return SASL_OK;
-+}
-+
-+const char ** sasl_global_listmech(void) 
-+{
-+    return global_mech_list;
-+}
-+
-+int 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)
-+{
-+    if(!conn) {
-+      return SASL_BADPARAM;
-+    } else if(conn->type == SASL_CONN_SERVER) {
-+      RETURN(conn, _sasl_server_listmech(conn, user, prefix, sep, suffix,
-+                                         result, plen, pcount));
-+    } else if (conn->type == SASL_CONN_CLIENT) {
-+      RETURN(conn, _sasl_client_listmech(conn, prefix, sep, suffix,
-+                                         result, plen, pcount));
-+    }
-+    
-+    PARAMERROR(conn);
-+}
-+
-+
-+#ifndef WIN32
-+static int
-+_sasl_getpath(void *context __attribute__((unused)),
-+            const char **path)
-+{
-+  if (! path)
-+    return SASL_BADPARAM;
-+
-+  *path = getenv(SASL_PATH_ENV_VAR);
-+  if (! *path)
-+    *path = PLUGINDIR;
-+
-+  return SASL_OK;
-+}
-+
-+#else
-+/* Return NULL on failure */
-+static int
-+_sasl_getpath(void *context __attribute__((unused)), const char **path)
-+{
-+    /* Open registry entry, and find all registered SASL libraries.
-+     *
-+     * Registry location:
-+     *
-+     *     SOFTWARE\\Carnegie Mellon\\Project Cyrus\\SASL Library
-+     *
-+     * Key - value:
-+     *
-+     *     "SearchPath" - value: PATH like (';' delimited) list
-+     *                    of directories where to search for plugins
-+     *                    The list may contain references to environment
-+     *                    variables (e.g. %PATH%).
-+     *
-+     */
-+    HKEY  hKey;
-+    DWORD ret;
-+    DWORD ValueType;              /* value type */
-+    DWORD cbData;                 /* value size */
-+    BYTE * ValueData;             /* value */
-+    DWORD cbExpandedData;         /* "expanded" value size */
-+    BYTE * ExpandedValueData;     /* "expanded" value */
-+    char * return_value;          /* function return value */
-+    char * tmp;
-+
-+    /* Initialization */
-+    ExpandedValueData = NULL;
-+    ValueData = NULL;
-+    return_value = NULL;
-+
-+    /* Open the registry */
-+    ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
-+                     SASL_ROOT_KEY,
-+                     0,
-+                     KEY_READ,
-+                     &hKey);
-+
-+    if (ret != ERROR_SUCCESS) { 
-+              /* no registry entry */
-+              *path = PLUGINDIR;
-+              return SASL_OK; 
-+      }
-+
-+    /* figure out value type and required buffer size */
-+    /* the size will include space for terminating NUL if required */
-+    RegQueryValueEx (hKey,
-+                   SASL_PATH_SUBKEY,
-+                   NULL,          /* reserved */
-+                   &ValueType,
-+                   NULL,
-+                   &cbData);
-+ 
-+    /* Only accept string related types */
-+    if (ValueType != REG_EXPAND_SZ &&
-+      ValueType != REG_MULTI_SZ &&
-+      ValueType != REG_SZ) {
-+      return_value = NULL;
-+      goto CLEANUP;
-+    }
-+
-+    /* Any high water mark? */
-+    ValueData = sasl_ALLOC(cbData);
-+    if (ValueData == NULL) {
-+      return_value = NULL;
-+      goto CLEANUP;
-+    };
-+
-+    RegQueryValueEx (hKey,
-+                   SASL_PATH_SUBKEY,
-+                   NULL,          /* reserved */
-+                   &ValueType,
-+                   ValueData,
-+                   &cbData);
-+
-+    switch (ValueType) {
-+    case REG_EXPAND_SZ:
-+        /* : A random starting guess */
-+        cbExpandedData = cbData + 1024;
-+        ExpandedValueData = sasl_ALLOC(cbExpandedData);
-+        if (ExpandedValueData == NULL) {
-+            return_value = NULL;
-+            goto CLEANUP;
-+        };
-+
-+        cbExpandedData = ExpandEnvironmentStrings(
-+                                                  ValueData,
-+                                                  ExpandedValueData,
-+                                                  cbExpandedData);
-+
-+        if (cbExpandedData == 0) {
-+            /* : GetLastError() contains the reason for failure */
-+            return_value = NULL;
-+            goto CLEANUP;
-+        }
-+
-+        /* : Must retry expansion with the bigger buffer */
-+        if (cbExpandedData > cbData + 1024) {
-+            /* : Memory leak here if can't realloc */
-+            ExpandedValueData = sasl_REALLOC(ExpandedValueData, cbExpandedData);
-+            if (ExpandedValueData == NULL) {
-+                return_value = NULL;
-+                goto CLEANUP;
-+            };
-+
-+            cbExpandedData = ExpandEnvironmentStrings(
-+                                                      ValueData,
-+                                                      ExpandedValueData,
-+                                                      cbExpandedData);
-+
-+            /* : This should not happen */
-+            if (cbExpandedData == 0) {
-+                /* : GetLastError() contains the reason for failure */
-+                return_value = NULL;
-+                goto CLEANUP;
-+            }
-+        }
-+
-+        sasl_FREE(ValueData);
-+        ValueData = ExpandedValueData;
-+        /* : This is to prevent automatical freeing of this block on cleanup */
-+        ExpandedValueData = NULL;
-+
-+        break;
-+
-+    case REG_MULTI_SZ:
-+        tmp = ValueData;
-+
-+        /* : We shouldn't overflow here, as the buffer is guarantied
-+           : to contain at least two consequent NULs */
-+        while (1) {
-+            if (tmp[0] == '\0') {
-+                /* : Stop the process if we found the end of the string (two consequent NULs) */
-+                if (tmp[1] == '\0') {
-+                    break;
-+                }
-+
-+                /* : Replace delimiting NUL with our delimiter characted */
-+                tmp[0] = PATHS_DELIMITER;
-+            }
-+            tmp += strlen(tmp);
-+        }
-+        break;
-+
-+    case REG_SZ:
-+        /* Do nothing, it is good as is */
-+        break;
-+
-+    default:
-+        return_value = NULL;
-+        goto CLEANUP;
-+    }
-+
-+    return_value = ValueData;
-+
-+    CLEANUP:
-+    RegCloseKey(hKey);
-+    if (ExpandedValueData != NULL) sasl_FREE(ExpandedValueData);
-+    if (return_value == NULL) {
-+      if (ValueData != NULL) sasl_FREE(ValueData);
-+    }
-+    *path = return_value;
-+
-+      return SASL_OK;
-+}
-+
-+#endif
-diff -durN cyrus-sasl-2.1.10.orig/lib/saslint.h cyrus-sasl-2.1.10/lib/saslint.h
---- cyrus-sasl-2.1.10.orig/lib/saslint.h       Thu Dec  5 05:16:59 2002
-+++ cyrus-sasl-2.1.10/lib/saslint.h    Thu Jan  9 11:42:29 2003
-@@ -356,6 +356,9 @@
- _sasl_find_getpath_callback(const sasl_callback_t *callbacks);
- extern const sasl_callback_t *
-+_sasl_find_getconfpath_callback(const sasl_callback_t *callbacks);
-+
-+extern const sasl_callback_t *
- _sasl_find_verifyfile_callback(const sasl_callback_t *callbacks);
- extern int _sasl_common_init(void);
-diff -durN cyrus-sasl-2.1.10.orig/lib/saslint.h.orig cyrus-sasl-2.1.10/lib/saslint.h.orig
---- cyrus-sasl-2.1.10.orig/lib/saslint.h.orig  Thu Jan  1 01:00:00 1970
-+++ cyrus-sasl-2.1.10/lib/saslint.h.orig       Thu Dec  5 05:16:59 2002
-@@ -0,0 +1,494 @@
-+/* saslint.h - internal SASL library definitions
-+ * Rob Siemborski
-+ * Tim Martin
-+ * $Id$
-+ */
-+/* 
-+ * Copyright (c) 2001 Carnegie Mellon University.  All rights reserved.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions
-+ * are met:
-+ *
-+ * 1. Redistributions of source code must retain the above copyright
-+ *    notice, this list of conditions and the following disclaimer. 
-+ *
-+ * 2. Redistributions in binary form must reproduce the above copyright
-+ *    notice, this list of conditions and the following disclaimer in
-+ *    the documentation and/or other materials provided with the
-+ *    distribution.
-+ *
-+ * 3. The name "Carnegie Mellon University" must not be used to
-+ *    endorse or promote products derived from this software without
-+ *    prior written permission. For permission or any other legal
-+ *    details, please contact  
-+ *      Office of Technology Transfer
-+ *      Carnegie Mellon University
-+ *      5000 Forbes Avenue
-+ *      Pittsburgh, PA  15213-3890
-+ *      (412) 268-4387, fax: (412) 268-7395
-+ *      tech-transfer@andrew.cmu.edu
-+ *
-+ * 4. Redistributions of any form whatsoever must retain the following
-+ *    acknowledgment:
-+ *    "This product includes software developed by Computing Services
-+ *     at Carnegie Mellon University (http://www.cmu.edu/computing/)."
-+ *
-+ * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
-+ * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
-+ * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
-+ * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
-+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
-+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+ */
-+
-+#ifndef SASLINT_H
-+#define SASLINT_H
-+
-+#include <config.h>
-+#include "sasl.h"
-+#include "saslplug.h"
-+#include "saslutil.h"
-+#include "prop.h"
-+
-+/* #define'd constants */
-+#define CANON_BUF_SIZE 256
-+
-+/* Error Handling Foo */
-+/* Helpful Hints:
-+ *  -Error strings are set as soon as possible (first function in stack trace
-+ *   with a pointer to the sasl_conn_t.
-+ *  -Error codes are set as late as possible (only in the sasl api functions),
-+ *   thoug "as often as possible" also comes to mind to ensure correctness
-+ *  -Errors from calls to _buf_alloc, _sasl_strdup, etc are assumed to be
-+ *   memory errors.
-+ *  -Only errors (error codes < SASL_OK) should be remembered
-+ */
-+#define RETURN(conn, val) { if(conn && (val) < SASL_OK) \
-+                               (conn)->error_code = (val); \
-+                            return (val); }
-+#define MEMERROR(conn) {\
-+    if(conn) sasl_seterror( (conn), 0, \
-+                   "Out of Memory in " __FILE__ " near line %d", __LINE__ ); \
-+    RETURN(conn, SASL_NOMEM) }
-+#define PARAMERROR(conn) {\
-+    if(conn) sasl_seterror( (conn), SASL_NOLOG, \
-+                  "Parameter error in " __FILE__ " near line %d", __LINE__ ); \
-+    RETURN(conn, SASL_BADPARAM) }
-+#define INTERROR(conn, val) {\
-+    if(conn) sasl_seterror( (conn), 0, \
-+                   "Internal Error %d in " __FILE__ " near line %d", (val),\
-+                 __LINE__ ); \
-+    RETURN(conn, (val)) }
-+
-+#ifndef PATH_MAX
-+# ifdef WIN32
-+#  define PATH_MAX MAX_PATH
-+# else
-+#  ifdef _POSIX_PATH_MAX
-+#   define PATH_MAX _POSIX_PATH_MAX
-+#  else
-+#   define PATH_MAX 1024         /* arbitrary; probably big enough will
-+                                  * probably only be 256+64 on
-+                                  * pre-posix machines */
-+#  endif /* _POSIX_PATH_MAX */
-+# endif /* WIN32 */
-+#endif
-+
-+/* : Define directory delimiter in SASL_PATH variable */
-+#ifdef WIN32
-+#define PATHS_DELIMITER       ';'
-+#else
-+#define PATHS_DELIMITER       ':'
-+#endif
-+
-+/* Datatype Definitions */
-+typedef struct {
-+  const sasl_callback_t *callbacks;
-+  const char *appname;
-+} sasl_global_callbacks_t;
-+
-+typedef struct _sasl_external_properties 
-+{
-+    sasl_ssf_t ssf;
-+    char *auth_id;
-+} _sasl_external_properties_t;
-+
-+typedef struct sasl_string_list
-+{
-+    const char *d;
-+    struct sasl_string_list *next;
-+} sasl_string_list_t;
-+
-+typedef struct buffer_info
-+{ 
-+    char *data;
-+    size_t curlen;
-+    size_t reallen;
-+} buffer_info_t;
-+
-+typedef int add_plugin_t(const char *, void *);
-+
-+typedef struct add_plugin_list 
-+{
-+    const char *entryname;
-+    add_plugin_t *add_plugin;
-+} add_plugin_list_t;
-+
-+enum Sasl_conn_type { SASL_CONN_UNKNOWN = 0,
-+                    SASL_CONN_SERVER = 1,
-+                      SASL_CONN_CLIENT = 2 };
-+
-+struct sasl_conn {
-+  enum Sasl_conn_type type;
-+
-+  void (*destroy_conn)(sasl_conn_t *); /* destroy function */
-+
-+  char *service;
-+
-+  unsigned int flags;  /* flags passed to sasl_*_new */
-+
-+  /* IP information.  A buffer of size 52 is adequate for this in its
-+     longest format (see sasl.h) */
-+  int got_ip_local, got_ip_remote;
-+  char iplocalport[NI_MAXHOST + NI_MAXSERV];
-+  char ipremoteport[NI_MAXHOST + NI_MAXSERV];
-+
-+  void *context;
-+  sasl_out_params_t oparams;
-+
-+  sasl_security_properties_t props;
-+  _sasl_external_properties_t external;
-+
-+  sasl_secret_t *secret;
-+
-+  int (*idle_hook)(sasl_conn_t *conn);
-+  const sasl_callback_t *callbacks;
-+  const sasl_global_callbacks_t *global_callbacks; /* global callbacks
-+                                                  * connection */
-+  char *serverFQDN;
-+
-+  /* Pointers to memory that we are responsible for */
-+  buffer_info_t *encode_buf;
-+
-+  int error_code;
-+  char *error_buf, *errdetail_buf;
-+  size_t error_buf_len, errdetail_buf_len;
-+  char *mechlist_buf;
-+  size_t mechlist_buf_len;
-+
-+  char *decode_buf;
-+
-+  char user_buf[CANON_BUF_SIZE+1], authid_buf[CANON_BUF_SIZE+1];
-+};
-+
-+/* Server Conn Type Information */
-+
-+typedef struct mechanism
-+{
-+    int version;
-+    int condition; /* set to SASL_NOUSER if no available users;
-+                    set to SASL_CONTINUE if delayed plugn loading */
-+    char *plugname; /* for AUTHSOURCE tracking */
-+    const sasl_server_plug_t *plug;
-+    struct mechanism *next;
-+    char *f;       /* where should i load the mechanism from? */
-+} mechanism_t;
-+
-+typedef struct mech_list {
-+  const sasl_utils_t *utils;  /* gotten from plug_init */
-+
-+  void *mutex;            /* mutex for this data */ 
-+  mechanism_t *mech_list; /* list of mechanisms */
-+  int mech_length;       /* number of mechanisms */
-+} mech_list_t;
-+
-+typedef struct context_list 
-+{
-+    mechanism_t *mech;
-+    void *context;     /* if NULL, this mech is disabled for this connection
-+                      * otherwise, use this context instead of a call
-+                      * to mech_new */
-+    struct context_list *next;
-+} context_list_t;
-+
-+typedef struct sasl_server_conn {
-+    sasl_conn_t base; /* parts common to server + client */
-+
-+    char *user_realm; /* domain the user authenticating is in */
-+    int sent_last; /* Have we already done the last send? */
-+    int authenticated;
-+    mechanism_t *mech; /* mechanism trying to use */
-+    sasl_server_params_t *sparams;
-+    context_list_t *mech_contexts;
-+} sasl_server_conn_t;
-+
-+/* Client Conn Type Information */
-+
-+typedef struct cmechanism
-+{
-+    int version;
-+
-+    char *plugname;
-+    const sasl_client_plug_t *plug;
-+
-+    struct cmechanism *next;  
-+} cmechanism_t;
-+
-+typedef struct cmech_list {
-+  const sasl_utils_t *utils; 
-+
-+  void *mutex;            /* mutex for this data */ 
-+  cmechanism_t *mech_list; /* list of mechanisms */
-+  int mech_length;       /* number of mechanisms */
-+
-+} cmech_list_t;
-+
-+typedef struct sasl_client_conn {
-+  sasl_conn_t base; /* parts common to server + client */
-+
-+  cmechanism_t *mech;
-+  sasl_client_params_t *cparams;
-+
-+  char *clientFQDN;
-+
-+} sasl_client_conn_t;
-+
-+typedef struct sasl_allocation_utils {
-+  sasl_malloc_t *malloc;
-+  sasl_calloc_t *calloc;
-+  sasl_realloc_t *realloc;
-+  sasl_free_t *free;
-+} sasl_allocation_utils_t;
-+
-+typedef struct sasl_mutex_utils {
-+  sasl_mutex_alloc_t *alloc;
-+  sasl_mutex_lock_t *lock;
-+  sasl_mutex_unlock_t *unlock;
-+  sasl_mutex_free_t *free;
-+} sasl_mutex_utils_t;
-+
-+typedef struct sasl_log_utils_s {
-+  sasl_log_t *log;
-+} sasl_log_utils_t;
-+
-+typedef int sasl_plaintext_verifier(sasl_conn_t *conn,
-+                                  const char *userid,
-+                                  const char *passwd,
-+                                  const char *service,
-+                                  const char *user_realm);
-+
-+struct sasl_verify_password_s {
-+    char *name;
-+    sasl_plaintext_verifier *verify;
-+};
-+
-+/*
-+ * globals & constants
-+ */
-+/*
-+ * common.c
-+ */
-+LIBSASL_API const sasl_utils_t *sasl_global_utils;
-+
-+extern void (*_sasl_client_cleanup_hook)(void);
-+extern void (*_sasl_server_cleanup_hook)(void);
-+extern int (*_sasl_client_idle_hook)(sasl_conn_t *conn);
-+extern int (*_sasl_server_idle_hook)(sasl_conn_t *conn);
-+
-+extern sasl_allocation_utils_t _sasl_allocation_utils;
-+extern sasl_mutex_utils_t _sasl_mutex_utils;
-+
-+/*
-+ * checkpw.c
-+ */
-+extern struct sasl_verify_password_s _sasl_verify_password[];
-+
-+/*
-+ * server.c
-+ */
-+/* (this is a function call to ensure this is read-only to the outside) */
-+extern int _is_sasl_server_active(void);
-+
-+/*
-+ * Allocation and Mutex utility macros
-+ */
-+#define sasl_ALLOC(__size__) (_sasl_allocation_utils.malloc((__size__)))
-+#define sasl_CALLOC(__nelem__, __size__) \
-+      (_sasl_allocation_utils.calloc((__nelem__), (__size__)))
-+#define sasl_REALLOC(__ptr__, __size__) \
-+      (_sasl_allocation_utils.realloc((__ptr__), (__size__)))
-+#define sasl_FREE(__ptr__) (_sasl_allocation_utils.free((__ptr__)))
-+
-+#define sasl_MUTEX_ALLOC() (_sasl_mutex_utils.alloc())
-+#define sasl_MUTEX_LOCK(__mutex__) (_sasl_mutex_utils.lock((__mutex__)))
-+#define sasl_MUTEX_UNLOCK(__mutex__) (_sasl_mutex_utils.unlock((__mutex__)))
-+#define sasl_MUTEX_FREE(__mutex__) \
-+      (_sasl_mutex_utils.free((__mutex__)))
-+
-+/* function prototypes */
-+/*
-+ * dlopen.c and staticopen.c
-+ */
-+/*
-+ * The differences here are:
-+ * _sasl_load_plugins loads all plugins from all files
-+ * _sasl_get_plugin loads the LIBRARY for an individual file
-+ * _sasl_done_with_plugins frees the LIBRARIES loaded by the above 2
-+ * _sasl_locate_entry locates an entrypoint in a given library
-+ */
-+extern int _sasl_load_plugins(const add_plugin_list_t *entrypoints,
-+                             const sasl_callback_t *getpath_callback,
-+                             const sasl_callback_t *verifyfile_callback);
-+extern int _sasl_get_plugin(const char *file,
-+                          const sasl_callback_t *verifyfile_cb,
-+                          void **libraryptr);
-+extern int _sasl_locate_entry(void *library, const char *entryname,
-+                              void **entry_point);
-+extern int _sasl_done_with_plugins();
-+
-+
-+/*
-+ * common.c
-+ */
-+extern const sasl_callback_t *
-+_sasl_find_getpath_callback(const sasl_callback_t *callbacks);
-+
-+extern const sasl_callback_t *
-+_sasl_find_verifyfile_callback(const sasl_callback_t *callbacks);
-+
-+extern int _sasl_common_init(void);
-+
-+extern int _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);
-+extern void _sasl_conn_dispose(sasl_conn_t *conn);
-+
-+extern sasl_utils_t *
-+_sasl_alloc_utils(sasl_conn_t *conn,
-+                sasl_global_callbacks_t *global_callbacks);
-+extern int _sasl_free_utils(const sasl_utils_t ** utils);
-+
-+extern int
-+_sasl_getcallback(sasl_conn_t * conn,
-+                unsigned long callbackid,
-+                int (**pproc)(),
-+                void **pcontext);
-+
-+extern void
-+_sasl_log(sasl_conn_t *conn,
-+        int level,
-+        const char *fmt,
-+        ...);
-+
-+void _sasl_get_errorbuf(sasl_conn_t *conn, char ***bufhdl, size_t **lenhdl);
-+int _sasl_add_string(char **out, size_t *alloclen,
-+                   size_t *outlen, const char *add);
-+
-+/* More Generic Utilities in common.c */
-+extern int _sasl_strdup(const char *in, char **out, size_t *outlen);
-+
-+/* Basically a conditional call to realloc(), if we need more */
-+int _buf_alloc(char **rwbuf, size_t *curlen, size_t newlen);
-+
-+/* convert an iovec to a single buffer */
-+int _iovec_to_buf(const struct iovec *vec,
-+                unsigned numiov, buffer_info_t **output);
-+
-+/* Convert between string formats and sockaddr formats */
-+int _sasl_iptostring(const struct sockaddr *addr, socklen_t addrlen,
-+                   char *out, unsigned outlen);
-+int _sasl_ipfromstring(const char *addr, struct sockaddr *out,
-+                     socklen_t outlen);
-+
-+/*
-+ * external plugin (external.c)
-+ */
-+int external_client_plug_init(const sasl_utils_t *utils,
-+                            int max_version,
-+                            int *out_version,
-+                            sasl_client_plug_t **pluglist,
-+                            int *plugcount);
-+int external_server_plug_init(const sasl_utils_t *utils,
-+                            int max_version,
-+                            int *out_version,
-+                            sasl_server_plug_t **pluglist,
-+                            int *plugcount);
-+
-+/* Mech Listing Functions */
-+int _sasl_build_mechlist(void);
-+int _sasl_server_listmech(sasl_conn_t *conn,
-+                        const char *user,
-+                        const char *prefix,
-+                        const char *sep,
-+                        const char *suffix,
-+                        const char **result,
-+                        unsigned *plen,
-+                        int *pcount);
-+int _sasl_client_listmech(sasl_conn_t *conn,
-+                        const char *prefix,
-+                        const char *sep,
-+                        const char *suffix,
-+                        const char **result,
-+                        unsigned *plen,
-+                        int *pcount);
-+/* Just create a straight list of them */
-+sasl_string_list_t *_sasl_client_mechs(void);
-+sasl_string_list_t *_sasl_server_mechs(void);
-+
-+/*
-+ * config file declarations (config.c)
-+ */
-+extern int sasl_config_init(const char *filename);
-+extern const char *sasl_config_getstring(const char *key,const char *def);
-+extern int sasl_config_getint(const char *key,int def);
-+extern int sasl_config_getswitch(const char *key,int def);
-+
-+/* checkpw.c */
-+#ifdef DO_SASL_CHECKAPOP
-+extern int _sasl_auxprop_verify_apop(sasl_conn_t *conn,
-+                                   const char *userstr,
-+                                   const char *challenge,
-+                                   const char *response,
-+                                   const char *user_realm);
-+#endif /* DO_SASL_CHECKAPOP */
-+
-+/* Auxprop Plugin (checkpw.c) */
-+extern int sasldb_auxprop_plug_init(const sasl_utils_t *utils,
-+                                  int max_version,
-+                                  int *out_version,
-+                                  sasl_auxprop_plug_t **plug,
-+                                  const char *plugname);
-+
-+/*
-+ * auxprop.c
-+ */
-+extern int _sasl_auxprop_add_plugin(void *p, void *library);
-+extern void _sasl_auxprop_free(void);
-+extern void _sasl_auxprop_lookup(sasl_server_params_t *sparams,
-+                               unsigned flags,
-+                               const char *user, unsigned ulen);
-+
-+/*
-+ * canonusr.c
-+ */
-+void _sasl_canonuser_free();
-+extern int internal_canonuser_init(const sasl_utils_t *utils,
-+                                 int max_version,
-+                                 int *out_version,
-+                                 sasl_canonuser_plug_t **plug,
-+                                 const char *plugname);
-+extern int _sasl_canon_user(sasl_conn_t *conn,
-+                          const char *user, unsigned ulen,
-+                          unsigned flags,
-+                          sasl_out_params_t *oparams);
-+
-+#endif /* SASLINT_H */
-diff -durN cyrus-sasl-2.1.10.orig/lib/server.c cyrus-sasl-2.1.10/lib/server.c
---- cyrus-sasl-2.1.10.orig/lib/server.c        Thu Dec  5 05:16:59 2002
-+++ cyrus-sasl-2.1.10/lib/server.c     Thu Jan  9 11:42:29 2003
-@@ -379,15 +379,15 @@
-   char *c;
-   char *config_filename=NULL;
-   int len;
--  const sasl_callback_t *getpath_cb=NULL;
-+  const sasl_callback_t *getconfpath_cb=NULL;
-   /* get the path to the plugins; for now the config file will reside there */
--  getpath_cb=_sasl_find_getpath_callback( global_callbacks.callbacks );
--  if (getpath_cb==NULL) return SASL_BADPARAM;
-+  getconfpath_cb=_sasl_find_getconfpath_callback( global_callbacks.callbacks );
-+  if (getconfpath_cb==NULL) return SASL_BADPARAM;
--  /* getpath_cb->proc MUST be a sasl_getpath_t; if only c had a type
-+  /* getconfpath_cb->proc MUST be a sasl_getconfpath_t; if only c had a type
-      system */
--  result = ((sasl_getpath_t *)(getpath_cb->proc))(getpath_cb->context,
-+  result = ((sasl_getconfpath_t *)(getconfpath_cb->proc))(getconfpath_cb->context,
-                                                 &path_to_config);
-   if (result!=SASL_OK) goto done;
-   if (path_to_config == NULL) path_to_config = "";
-diff -durN cyrus-sasl-2.1.10.orig/lib/server.c.orig cyrus-sasl-2.1.10/lib/server.c.orig
---- cyrus-sasl-2.1.10.orig/lib/server.c.orig   Thu Jan  1 01:00:00 1970
-+++ cyrus-sasl-2.1.10/lib/server.c.orig        Thu Dec  5 05:16:59 2002
-@@ -0,0 +1,1734 @@
-+/* SASL server API implementation
-+ * Rob Siemborski
-+ * Tim Martin
-+ * $Id$
-+ */
-+/* 
-+ * Copyright (c) 2001 Carnegie Mellon University.  All rights reserved.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions
-+ * are met:
-+ *
-+ * 1. Redistributions of source code must retain the above copyright
-+ *    notice, this list of conditions and the following disclaimer. 
-+ *
-+ * 2. Redistributions in binary form must reproduce the above copyright
-+ *    notice, this list of conditions and the following disclaimer in
-+ *    the documentation and/or other materials provided with the
-+ *    distribution.
-+ *
-+ * 3. The name "Carnegie Mellon University" must not be used to
-+ *    endorse or promote products derived from this software without
-+ *    prior written permission. For permission or any other legal
-+ *    details, please contact  
-+ *      Office of Technology Transfer
-+ *      Carnegie Mellon University
-+ *      5000 Forbes Avenue
-+ *      Pittsburgh, PA  15213-3890
-+ *      (412) 268-4387, fax: (412) 268-7395
-+ *      tech-transfer@andrew.cmu.edu
-+ *
-+ * 4. Redistributions of any form whatsoever must retain the following
-+ *    acknowledgment:
-+ *    "This product includes software developed by Computing Services
-+ *     at Carnegie Mellon University (http://www.cmu.edu/computing/)."
-+ *
-+ * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
-+ * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
-+ * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
-+ * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
-+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
-+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+ */
-+
-+/* local functions/structs don't start with sasl
-+ */
-+#include <config.h>
-+#include <errno.h>
-+#include <stdio.h>
-+#include <stdlib.h>
-+#include <limits.h>
-+#ifndef macintosh
-+#include <sys/types.h>
-+#include <sys/stat.h>
-+#endif
-+#include <fcntl.h>
-+#include <string.h>
-+#include <ctype.h>
-+
-+#include "sasl.h"
-+#include "saslint.h"
-+#include "saslplug.h"
-+#include "saslutil.h"
-+
-+#ifdef sun
-+/* gotta define gethostname ourselves on suns */
-+extern int gethostname(char *, int);
-+#endif
-+
-+#define DEFAULT_CHECKPASS_MECH "auxprop"
-+
-+/* Contains functions:
-+ * 
-+ * sasl_server_init
-+ * sasl_server_new
-+ * sasl_listmech
-+ * sasl_server_start
-+ * sasl_server_step
-+ * sasl_checkpass
-+ * sasl_checkapop
-+ * sasl_user_exists
-+ * sasl_setpass
-+ */
-+
-+/* if we've initialized the server sucessfully */
-+static int _sasl_server_active = 0;
-+
-+/* For access by other modules */
-+int _is_sasl_server_active(void) { return _sasl_server_active; }
-+
-+static int _sasl_checkpass(sasl_conn_t *conn, const char *service, 
-+                         const char *user, const char *pass);
-+
-+static mech_list_t *mechlist = NULL; /* global var which holds the list */
-+
-+static sasl_global_callbacks_t global_callbacks;
-+
-+/* set the password for a user
-+ *  conn        -- SASL connection
-+ *  user        -- user name
-+ *  pass        -- plaintext password, may be NULL to remove user
-+ *  passlen     -- length of password, 0 = strlen(pass)
-+ *  oldpass     -- NULL will sometimes work
-+ *  oldpasslen  -- length of password, 0 = strlen(oldpass)
-+ *  flags       -- see flags below
-+ * 
-+ * returns:
-+ *  SASL_NOCHANGE  -- proper entry already exists
-+ *  SASL_NOMECH    -- no authdb supports password setting as configured
-+ *  SASL_NOVERIFY  -- user exists, but no settable password present
-+ *  SASL_DISABLED  -- account disabled
-+ *  SASL_PWLOCK    -- password locked
-+ *  SASL_WEAKPASS  -- password too weak for security policy
-+ *  SASL_NOUSERPASS -- user-supplied passwords not permitted
-+ *  SASL_FAIL      -- OS error
-+ *  SASL_BADPARAM  -- password too long
-+ *  SASL_OK        -- successful
-+ */
-+
-+int sasl_setpass(sasl_conn_t *conn,
-+               const char *user,
-+               const char *pass, unsigned passlen,
-+               const char *oldpass,
-+               unsigned oldpasslen,
-+               unsigned flags)
-+{
-+    int result=SASL_OK, tmpresult;
-+    sasl_server_conn_t *s_conn = (sasl_server_conn_t *) conn;
-+    sasl_server_userdb_setpass_t *setpass_cb = NULL;
-+    void *context = NULL;
-+    mechanism_t *m;
-+     
-+    if (!_sasl_server_active || !mechlist) return SASL_NOTINIT;
-+
-+    /* check params */
-+    if (!conn) return SASL_BADPARAM;
-+    if (conn->type != SASL_CONN_SERVER) PARAMERROR(conn);
-+     
-+    if ((!(flags & SASL_SET_DISABLE) && passlen == 0)
-+        || ((flags & SASL_SET_CREATE) && (flags & SASL_SET_DISABLE)))
-+      PARAMERROR(conn);
-+
-+    /* call userdb callback function */
-+    result = _sasl_getcallback(conn, SASL_CB_SERVER_USERDB_SETPASS,
-+                             &setpass_cb, &context);
-+    if(result == SASL_OK && setpass_cb) {
-+      tmpresult = setpass_cb(conn, context, user, pass, passlen,
-+                          s_conn->sparams->propctx, flags);
-+      if(tmpresult != SASL_OK) {
-+          _sasl_log(conn, SASL_LOG_ERR,
-+                    "setpass callback failed for %s: %z",
-+                    user, tmpresult);
-+      } else {
-+          _sasl_log(conn, SASL_LOG_NOTE,
-+                    "setpass callback succeeded for %s", user);
-+      }
-+    } else {
-+      result = SASL_OK;
-+    }
-+
-+    /* now we let the mechanisms set their secrets */
-+    for (m = mechlist->mech_list; m; m = m->next) {
-+      if (!m->plug->setpass) {
-+          /* can't set pass for this mech */
-+          continue;
-+      }
-+      tmpresult = m->plug->setpass(m->plug->glob_context,
-+                                   ((sasl_server_conn_t *)conn)->sparams,
-+                                   user,
-+                                   pass,
-+                                   passlen,
-+                                   oldpass, oldpasslen,
-+                                   flags);
-+      if (tmpresult == SASL_OK) {
-+          _sasl_log(conn, SASL_LOG_NOTE,
-+                    "%s: set secret for %s", m->plug->mech_name, user);
-+
-+          m->condition = SASL_OK; /* if we previously thought the
-+                                     mechanism didn't have any user secrets 
-+                                     we now think it does */
-+
-+      } else if (tmpresult == SASL_NOCHANGE) {
-+          _sasl_log(conn, SASL_LOG_NOTE,
-+                    "%s: secret not changed for %s", m->plug->mech_name, user);
-+      } else {
-+          result = tmpresult;
-+          _sasl_log(conn, SASL_LOG_ERR,
-+                    "%s: failed to set secret for %s: %z (%m)",
-+                    m->plug->mech_name, user, tmpresult,
-+#ifndef WIN32
-+                    errno
-+#else
-+                    GetLastError()
-+#endif
-+                    );
-+      }
-+    }
-+
-+    RETURN(conn, result);
-+}
-+
-+/* local mechanism which disposes of server */
-+static void server_dispose(sasl_conn_t *pconn)
-+{
-+  sasl_server_conn_t *s_conn=  (sasl_server_conn_t *) pconn;
-+  context_list_t *cur, *cur_next;
-+  
-+  if (s_conn->mech
-+      && s_conn->mech->plug->mech_dispose) {
-+    s_conn->mech->plug->mech_dispose(pconn->context,
-+                                   s_conn->sparams->utils);
-+  }
-+  pconn->context = NULL;
-+
-+  for(cur = s_conn->mech_contexts; cur; cur=cur_next) {
-+      cur_next = cur->next;
-+      if(cur->context)
-+        cur->mech->plug->mech_dispose(cur->context, s_conn->sparams->utils);
-+      sasl_FREE(cur);
-+  }  
-+  s_conn->mech_contexts = NULL;
-+  
-+  _sasl_free_utils(&s_conn->sparams->utils);
-+
-+  if (s_conn->sparams->propctx)
-+      prop_dispose(&s_conn->sparams->propctx);
-+
-+  if (s_conn->user_realm)
-+      sasl_FREE(s_conn->user_realm);
-+
-+  if (s_conn->sparams)
-+      sasl_FREE(s_conn->sparams);
-+
-+  _sasl_conn_dispose(pconn);
-+}
-+
-+static int init_mechlist(void)
-+{
-+    sasl_utils_t *newutils = NULL;
-+
-+    mechlist->mutex = sasl_MUTEX_ALLOC();
-+    if(!mechlist->mutex) return SASL_FAIL;
-+
-+    /* set util functions - need to do rest */
-+    newutils = _sasl_alloc_utils(NULL, &global_callbacks);
-+    if (newutils == NULL)
-+      return SASL_NOMEM;
-+
-+    newutils->checkpass = &sasl_checkpass;
-+
-+    mechlist->utils = newutils;
-+    mechlist->mech_list=NULL;
-+    mechlist->mech_length=0;
-+
-+    return SASL_OK;
-+}
-+
-+/*
-+ * parameters:
-+ *  p - entry point
-+ */
-+int sasl_server_add_plugin(const char *plugname,
-+                         sasl_server_plug_init_t *p)
-+{
-+    int plugcount;
-+    sasl_server_plug_t *pluglist;
-+    mechanism_t *mech;
-+    sasl_server_plug_init_t *entry_point;
-+    int result;
-+    int version;
-+    int lupe;
-+
-+    if(!plugname || !p) return SASL_BADPARAM;
-+
-+    entry_point = (sasl_server_plug_init_t *)p;
-+
-+    /* call into the shared library asking for information about it */
-+    /* version is filled in with the version of the plugin */
-+    result = entry_point(mechlist->utils, SASL_SERVER_PLUG_VERSION, &version,
-+                       &pluglist, &plugcount);
-+
-+    if ((result != SASL_OK) && (result != SASL_NOUSER)) {
-+      _sasl_log(NULL, SASL_LOG_DEBUG,
-+                "server add_plugin entry_point error %z\n", result);
-+      return result;
-+    }
-+
-+    /* Make sure plugin is using the same SASL version as us */
-+    if (version != SASL_SERVER_PLUG_VERSION)
-+    {
-+      _sasl_log(NULL, SASL_LOG_ERR,
-+                "version mismatch on plugin");
-+      return SASL_BADVERS;
-+    }
-+
-+    for (lupe=0;lupe < plugcount ;lupe++)
-+    {
-+      mech = sasl_ALLOC(sizeof(mechanism_t));
-+      if (! mech) return SASL_NOMEM;
-+
-+      mech->plug=pluglist++;
-+      if(_sasl_strdup(plugname, &mech->plugname, NULL) != SASL_OK) {
-+          sasl_FREE(mech);
-+          return SASL_NOMEM;
-+      }
-+      mech->version = version;
-+
-+      /* wheather this mech actually has any users in it's db */
-+      mech->condition = result; /* SASL_OK or SASL_NOUSER */
-+
-+      mech->next = mechlist->mech_list;
-+      mechlist->mech_list = mech;
-+      mechlist->mech_length++;
-+    }
-+
-+    return SASL_OK;
-+}
-+
-+static void server_done(void) {
-+  mechanism_t *m;
-+  mechanism_t *prevm;
-+
-+  if (mechlist != NULL)
-+  {
-+      m=mechlist->mech_list; /* m point to beginning of the list */
-+
-+      while (m!=NULL)
-+      {
-+        prevm=m;
-+        m=m->next;
-+    
-+        if (prevm->plug->mech_free) {
-+            prevm->plug->mech_free(prevm->plug->glob_context,
-+                                   mechlist->utils);
-+        }
-+
-+        sasl_FREE(prevm->plugname);             
-+        sasl_FREE(prevm);    
-+      }
-+      _sasl_free_utils(&mechlist->utils);
-+      sasl_MUTEX_FREE(mechlist->mutex);
-+      sasl_FREE(mechlist);
-+      mechlist = NULL;
-+  }
-+
-+  /* Free the auxprop plugins */
-+  _sasl_auxprop_free();
-+
-+  global_callbacks.callbacks = NULL;
-+  global_callbacks.appname = NULL;
-+
-+  /* no longer active. fail on listmech's etc. */
-+  _sasl_server_active = 0;
-+}
-+
-+static int
-+server_idle(sasl_conn_t *conn)
-+{
-+  mechanism_t *m;
-+  if (! mechlist)
-+    return 0;
-+
-+  for (m = mechlist->mech_list;
-+       m!=NULL;
-+       m = m->next)
-+    if (m->plug->idle
-+      &&  m->plug->idle(m->plug->glob_context,
-+                        conn,
-+                        conn ? ((sasl_server_conn_t *)conn)->sparams : NULL))
-+      return 1;
-+  return 0;
-+}
-+
-+static int load_config(const sasl_callback_t *verifyfile_cb)
-+{
-+  int result;
-+  const char *path_to_config=NULL;
-+  char *c;
-+  char *config_filename=NULL;
-+  int len;
-+  const sasl_callback_t *getpath_cb=NULL;
-+
-+  /* get the path to the plugins; for now the config file will reside there */
-+  getpath_cb=_sasl_find_getpath_callback( global_callbacks.callbacks );
-+  if (getpath_cb==NULL) return SASL_BADPARAM;
-+
-+  /* getpath_cb->proc MUST be a sasl_getpath_t; if only c had a type
-+     system */
-+  result = ((sasl_getpath_t *)(getpath_cb->proc))(getpath_cb->context,
-+                                                &path_to_config);
-+  if (result!=SASL_OK) goto done;
-+  if (path_to_config == NULL) path_to_config = "";
-+
-+  if ((c = strchr(path_to_config, PATHS_DELIMITER))) {
-+      *c = '\0';
-+  }
-+
-+  /* length = length of path + '/' + length of appname + ".conf" + 1
-+     for '\0' */
-+  len = strlen(path_to_config)+2+ strlen(global_callbacks.appname)+5+1;
-+
-+  if (len > PATH_MAX ) {
-+      result = SASL_FAIL;
-+      goto done;
-+  }
-+
-+  /* construct the filename for the config file */
-+  config_filename = sasl_ALLOC(len);
-+  if (! config_filename) {
-+      result = SASL_NOMEM;
-+      goto done;
-+  }
-+
-+  snprintf(config_filename, len, "%s/%s.conf", path_to_config, 
-+         global_callbacks.appname);
-+
-+  /* Ask the application if it's safe to use this file */
-+  result = ((sasl_verifyfile_t *)(verifyfile_cb->proc))(verifyfile_cb->context,
-+                                      config_filename, SASL_VRFY_CONF);
-+
-+  /* returns continue if this file is to be skipped */
-+  
-+  /* returns SASL_CONTINUE if doesn't exist
-+   * if doesn't exist we can continue using default behavior
-+   */
-+  if (result==SASL_OK)
-+    result=sasl_config_init(config_filename);
-+
-+ done:
-+  if (config_filename) sasl_FREE(config_filename);
-+
-+  return result;
-+}
-+
-+/*
-+ * Verify that all the callbacks are valid
-+ */
-+static int verify_server_callbacks(const sasl_callback_t *callbacks)
-+{
-+    if (callbacks == NULL) return SASL_OK;
-+
-+    while (callbacks->id != SASL_CB_LIST_END) {
-+      if (callbacks->proc==NULL) return SASL_FAIL;
-+
-+      callbacks++;
-+    }
-+
-+    return SASL_OK;
-+}
-+
-+static char *grab_field(char *line, char **eofield)
-+{
-+    int d = 0;
-+    char *field;
-+
-+    while (isspace((int) *line)) line++;
-+
-+    /* find end of field */
-+    while (line[d] && !isspace(((int) line[d]))) d++;
-+    field = sasl_ALLOC(d + 1);
-+    if (!field) { return NULL; }
-+    memcpy(field, line, d);
-+    field[d] = '\0';
-+    *eofield = line + d;
-+    
-+    return field;
-+}
-+
-+struct secflag_map_s {
-+    char *name;
-+    int value;
-+};
-+
-+struct secflag_map_s secflag_map[] = {
-+    { "noplaintext", SASL_SEC_NOPLAINTEXT },
-+    { "noactive", SASL_SEC_NOACTIVE },
-+    { "nodictionary", SASL_SEC_NODICTIONARY },
-+    { "forward_secrecy", SASL_SEC_FORWARD_SECRECY },
-+    { "noanonymous", SASL_SEC_NOANONYMOUS },
-+    { "pass_credentials", SASL_SEC_PASS_CREDENTIALS },
-+    { "mutual_auth", SASL_SEC_MUTUAL_AUTH },
-+    { NULL, 0x0 }
-+};
-+
-+static int parse_mechlist_file(const char *mechlistfile)
-+{
-+    FILE *f;
-+    char buf[1024];
-+    char *t, *ptr;
-+    int r = 0;
-+
-+    f = fopen(mechlistfile, "r");
-+    if (!f) return SASL_FAIL;
-+
-+    r = SASL_OK;
-+    while (fgets(buf, sizeof(buf), f) != NULL) {
-+      mechanism_t *n = sasl_ALLOC(sizeof(mechanism_t));
-+      sasl_server_plug_t *nplug;
-+
-+      if (n == NULL) { r = SASL_NOMEM; break; }
-+      n->version = SASL_SERVER_PLUG_VERSION;
-+      n->condition = SASL_CONTINUE;
-+      nplug = sasl_ALLOC(sizeof(sasl_server_plug_t));
-+      if (nplug == NULL) { r = SASL_NOMEM; break; }
-+      memset(nplug, 0, sizeof(sasl_server_plug_t));
-+
-+      /* each line is:
-+         plugin-file WS mech_name WS max_ssf *(WS security_flag) RET
-+      */
-+      
-+      /* grab file */
-+      n->f = grab_field(buf, &ptr);
-+
-+      /* grab mech_name */
-+      nplug->mech_name = grab_field(ptr, &ptr);
-+
-+      /* grab max_ssf */
-+      nplug->max_ssf = strtol(ptr, &ptr, 10);
-+
-+      /* grab security flags */
-+      while (*ptr != '\n') {
-+          struct secflag_map_s *map;
-+
-+          /* read security flag */
-+          t = grab_field(ptr, &ptr);
-+          map = secflag_map;
-+          while (map->name) {
-+              if (!strcasecmp(t, map->name)) {
-+                  nplug->security_flags |= map->value;
-+                  break;
-+              }
-+              map++;
-+          }
-+          if (!map->name) {
-+              _sasl_log(NULL, SASL_LOG_ERR,
-+                        "%s: couldn't identify flag '%s'",
-+                        nplug->mech_name, t);
-+          }
-+          free(t);
-+      }
-+
-+      /* insert mechanism into mechlist */
-+      n->plug = nplug;
-+      n->next = mechlist->mech_list;
-+      mechlist->mech_list = n;
-+      mechlist->mech_length++;
-+    }
-+
-+    fclose(f);
-+    return r;
-+}
-+
-+/* initialize server drivers, done once per process
-+ *  callbacks      -- callbacks for all server connections; must include
-+ *                    getopt callback
-+ *  appname        -- name of calling application (for lower level logging)
-+ * results:
-+ *  state          -- server state
-+ * returns:
-+ *  SASL_OK        -- success
-+ *  SASL_BADPARAM  -- error in config file
-+ *  SASL_NOMEM     -- memory failure
-+ *  SASL_BADVERS   -- Mechanism version mismatch
-+ */
-+
-+int sasl_server_init(const sasl_callback_t *callbacks,
-+                   const char *appname)
-+{
-+    int ret;
-+    const sasl_callback_t *vf;
-+    const char *pluginfile = NULL;
-+#ifdef PIC
-+    sasl_getopt_t *getopt;
-+    void *context;
-+#endif
-+
-+    const add_plugin_list_t ep_list[] = {
-+      { "sasl_server_plug_init", (add_plugin_t *)sasl_server_add_plugin },
-+      { "sasl_auxprop_plug_init", (add_plugin_t *)sasl_auxprop_add_plugin },
-+      { "sasl_canonuser_init", (add_plugin_t *)sasl_canonuser_add_plugin },
-+      { NULL, NULL }
-+    };
-+
-+    /* we require the appname to be non-null */
-+    if (appname==NULL) return SASL_BADPARAM;
-+
-+    ret = _sasl_common_init();
-+    if (ret != SASL_OK)
-+      return ret;
-+ 
-+    _sasl_server_cleanup_hook = &server_done;
-+
-+    /* verify that the callbacks look ok */
-+    ret = verify_server_callbacks(callbacks);
-+    if (ret != SASL_OK) return ret;
-+
-+    global_callbacks.callbacks = callbacks;
-+    global_callbacks.appname = appname;
-+
-+    /* allocate mechlist and set it to empty */
-+    mechlist = sasl_ALLOC(sizeof(mech_list_t));
-+    if (mechlist == NULL) return SASL_NOMEM;
-+
-+    ret = init_mechlist();
-+    if (ret != SASL_OK) return ret;
-+
-+    vf = _sasl_find_verifyfile_callback(callbacks);
-+
-+    /* load config file if applicable */
-+    ret = load_config(vf);
-+    if ((ret != SASL_OK) && (ret != SASL_CONTINUE)) {
-+      return ret;
-+    }
-+
-+    /* load internal plugins */
-+    sasl_server_add_plugin("EXTERNAL", &external_server_plug_init);
-+
-+#ifdef PIC
-+    /* delayed loading of plugins? (DSO only, as it doesn't
-+     * make much [any] sense to delay in the static library case) */
-+    if (_sasl_getcallback(NULL, SASL_CB_GETOPT, &getopt, &context) 
-+         == SASL_OK) {
-+      /* No sasl_conn_t was given to getcallback, so we provide the
-+       * global callbacks structure */
-+      ret = getopt(&global_callbacks, NULL, "plugin_list", &pluginfile, NULL);
-+    }
-+#endif
-+    
-+    if (pluginfile != NULL) {
-+      /* this file should contain a list of plugins available.
-+         we'll load on demand. */
-+
-+      /* Ask the application if it's safe to use this file */
-+      ret = ((sasl_verifyfile_t *)(vf->proc))(vf->context,
-+                                              pluginfile,
-+                                              SASL_VRFY_CONF);
-+      if (ret != SASL_OK) {
-+          _sasl_log(NULL, SASL_LOG_ERR,
-+                    "unable to load plugin list %s: %z", pluginfile, ret);
-+      }
-+      
-+      if (ret == SASL_OK) {
-+          ret = parse_mechlist_file(pluginfile);
-+      }
-+    } else {
-+      /* load all plugins now */
-+      ret = _sasl_load_plugins(ep_list,
-+                               _sasl_find_getpath_callback(callbacks),
-+                               _sasl_find_verifyfile_callback(callbacks));
-+    }
-+
-+    if (ret == SASL_OK) {
-+      /* _sasl_server_active shows if we're active or not. 
-+         server_done() sets it back to 0 */
-+      _sasl_server_active = 1;
-+      _sasl_server_idle_hook = &server_idle;
-+
-+      ret = _sasl_build_mechlist();
-+    }
-+
-+    return ret;
-+}
-+
-+/*
-+ * Once we have the users plaintext password we 
-+ * may want to transition them. That is put entries
-+ * for them in the passwd database for other
-+ * stronger mechanism
-+ *
-+ * for example PLAIN -> CRAM-MD5
-+ */
-+static int
-+_sasl_transition(sasl_conn_t * conn,
-+               const char * pass,
-+               unsigned passlen)
-+{
-+    const char *dotrans = "n";
-+    sasl_getopt_t *getopt;
-+    int result = SASL_OK;
-+    void *context;
-+
-+    if (! conn)
-+      return SASL_BADPARAM;
-+
-+    if (! conn->oparams.authid)
-+      PARAMERROR(conn);
-+
-+    /* check if this is enabled: default to false */
-+    if (_sasl_getcallback(conn, SASL_CB_GETOPT, &getopt, &context) == SASL_OK)
-+    {
-+      getopt(context, NULL, "auto_transition", &dotrans, NULL);
-+      if (dotrans == NULL) dotrans = "n";
-+    }
-+
-+    if (*dotrans == '1' || *dotrans == 'y' ||
-+      (*dotrans == 'o' && dotrans[1] == 'n') || *dotrans == 't') {
-+      /* ok, it's on! */
-+      result = sasl_setpass(conn,
-+                            conn->oparams.authid,
-+                            pass,
-+                            passlen,
-+                            NULL, 0, 0);
-+    }
-+
-+    RETURN(conn,result);
-+}
-+
-+
-+/* create context for a single SASL connection
-+ *  service        -- registered name of the service using SASL (e.g. "imap")
-+ *  serverFQDN     -- Fully qualified domain name of server.  NULL means use
-+ *                    gethostname() or equivalent.
-+ *                    Useful for multi-homed servers.
-+ *  user_realm     -- permits multiple user realms on server, NULL = default
-+ *  iplocalport    -- server IPv4/IPv6 domain literal string with port
-+ *                    (if NULL, then mechanisms requiring IPaddr are disabled)
-+ *  ipremoteport   -- client IPv4/IPv6 domain literal string with port
-+ *                    (if NULL, then mechanisms requiring IPaddr are disabled)
-+ *  callbacks      -- callbacks (e.g., authorization, lang, new getopt context)
-+ *  flags          -- usage flags (see above)
-+ * returns:
-+ *  pconn          -- new connection context
-+ *
-+ * returns:
-+ *  SASL_OK        -- success
-+ *  SASL_NOMEM     -- not enough memory
-+ */
-+
-+int sasl_server_new(const char *service,
-+                  const char *serverFQDN,
-+                  const char *user_realm,
-+                  const char *iplocalport,
-+                  const char *ipremoteport,
-+                  const sasl_callback_t *callbacks,
-+                  unsigned flags,
-+                  sasl_conn_t **pconn)
-+{
-+  int result;
-+  sasl_server_conn_t *serverconn;
-+  sasl_utils_t *utils;
-+
-+  if (_sasl_server_active==0) return SASL_NOTINIT;
-+  if (! pconn) return SASL_FAIL;
-+  if (! service) return SASL_FAIL;
-+
-+  *pconn=sasl_ALLOC(sizeof(sasl_server_conn_t));
-+  if (*pconn==NULL) return SASL_NOMEM;
-+
-+  memset(*pconn, 0, sizeof(sasl_server_conn_t));
-+
-+  serverconn = (sasl_server_conn_t *)*pconn;
-+
-+  /* make sparams */
-+  serverconn->sparams=sasl_ALLOC(sizeof(sasl_server_params_t));
-+  if (serverconn->sparams==NULL)
-+      MEMERROR(*pconn);
-+
-+  memset(serverconn->sparams, 0, sizeof(sasl_server_params_t));
-+
-+  (*pconn)->destroy_conn = &server_dispose;
-+  result = _sasl_conn_init(*pconn, service, flags, SASL_CONN_SERVER,
-+                         &server_idle, serverFQDN,
-+                         iplocalport, ipremoteport,
-+                         callbacks, &global_callbacks);
-+  if (result != SASL_OK)
-+      goto done_error;
-+
-+
-+  /* set util functions - need to do rest */
-+  utils=_sasl_alloc_utils(*pconn, &global_callbacks);
-+  if (!utils) {
-+      result = SASL_NOMEM;
-+      goto done_error;
-+  }
-+  
-+  utils->checkpass = &sasl_checkpass;
-+
-+  /* Setup the propctx -> We'll assume the default size */
-+  serverconn->sparams->propctx=prop_new(0);
-+  if(!serverconn->sparams->propctx) {
-+      result = SASL_NOMEM;
-+      goto done_error;
-+  }
-+
-+  serverconn->sparams->service = (*pconn)->service;
-+  serverconn->sparams->servicelen = strlen((*pconn)->service);
-+
-+  serverconn->sparams->appname = global_callbacks.appname;
-+  serverconn->sparams->applen = strlen(global_callbacks.appname);
-+
-+  serverconn->sparams->serverFQDN = (*pconn)->serverFQDN;
-+  serverconn->sparams->slen = strlen((*pconn)->serverFQDN);
-+
-+  if (user_realm) {
-+      result = _sasl_strdup(user_realm, &serverconn->user_realm, NULL);
-+      serverconn->sparams->urlen = strlen(user_realm);
-+      serverconn->sparams->user_realm = serverconn->user_realm;
-+  } else {
-+      serverconn->user_realm = NULL;
-+      /* the sparams is already zeroed */
-+  }
-+
-+  serverconn->sparams->utils = utils;
-+  serverconn->sparams->transition = &_sasl_transition;
-+  serverconn->sparams->canon_user = &_sasl_canon_user;
-+  serverconn->sparams->props = serverconn->base.props;
-+  serverconn->sparams->flags = flags;
-+
-+  if(result == SASL_OK) return SASL_OK;
-+
-+ done_error:
-+  _sasl_conn_dispose(*pconn);
-+  sasl_FREE(*pconn);
-+  *pconn = NULL;
-+  return result;
-+}
-+
-+/*
-+ * The rule is:
-+ * IF mech strength + external strength < min ssf THEN FAIL
-+ * We also have to look at the security properties and make sure
-+ * that this mechanism has everything we want
-+ */
-+static int mech_permitted(sasl_conn_t *conn,
-+                        mechanism_t *mech)
-+{
-+    sasl_server_conn_t *s_conn = (sasl_server_conn_t *)conn;
-+    const sasl_server_plug_t *plug;
-+    int myflags;
-+    context_list_t *cur;
-+    sasl_getopt_t *getopt;
-+    void *context;
-+    sasl_ssf_t minssf = 0;
-+
-+    if(!conn) return 0;
-+
-+    if(! mech || ! mech->plug) {
-+      PARAMERROR(conn);
-+      return 0;
-+    }
-+    
-+    plug = mech->plug;
-+
-+    /* get the list of allowed mechanisms (default = all) */
-+    if (_sasl_getcallback(conn, SASL_CB_GETOPT, &getopt, &context)
-+            == SASL_OK) {
-+      const char *mlist;
-+
-+      getopt(context, NULL, "mech_list", &mlist, NULL);
-+
-+      /* if we have a list, check the plugin against it */
-+      if (mlist) {
-+          const char *cp;
-+
-+          while (*mlist) {
-+              for (cp = mlist; *cp && !isspace((int) *cp); cp++);
-+              if (((size_t) (cp - mlist) == strlen(plug->mech_name)) &&
-+                  !strncasecmp(mlist, plug->mech_name,
-+                               strlen(plug->mech_name))) {
-+                  break;
-+              }
-+              mlist = cp;
-+              while (*mlist && isspace((int) *mlist)) mlist++;
-+          }
-+
-+          if (!*mlist) return 0;  /* reached EOS -> not in our list */
-+      }
-+    }
-+
-+    /* setup parameters for the call to mech_avail */
-+    s_conn->sparams->serverFQDN=conn->serverFQDN;
-+    s_conn->sparams->service=conn->service;
-+    s_conn->sparams->user_realm=s_conn->user_realm;
-+    s_conn->sparams->props=conn->props;
-+    s_conn->sparams->external_ssf=conn->external.ssf;
-+
-+    /* Check if we have banished this one already */
-+    for(cur = s_conn->mech_contexts; cur; cur=cur->next) {
-+      if(cur->mech == mech) {
-+          /* If it's not mech_avail'd, then stop now */
-+          if(!cur->context) return 0;
-+          break;
-+      }
-+    }
-+    
-+    if (!strcasecmp(plug->mech_name, "EXTERNAL")) {
-+      /* Special case for the external mechanism */
-+      if (conn->props.min_ssf > conn->external.ssf
-+          || ! conn->external.auth_id) {
-+          sasl_seterror(conn, SASL_NOLOG,
-+                        "External SSF not good enough");
-+          return 0;
-+      }
-+    } else {  
-+      if (conn->props.min_ssf < conn->external.ssf) {
-+          minssf = 0;
-+      } else {
-+          minssf = conn->props.min_ssf - conn->external.ssf;
-+      }
-+
-+      /* Generic mechanism */
-+      if (plug->max_ssf < minssf) {
-+          sasl_seterror(conn, SASL_NOLOG,
-+                        "mech %s is too weak", plug->mech_name);
-+          return 0; /* too weak */
-+      }
-+      
-+    }
-+
-+    context = NULL;
-+    if(plug->mech_avail
-+       && plug->mech_avail(plug->glob_context,
-+                         s_conn->sparams, (void **)&context) != SASL_OK ) {
-+      /* Mark this mech as no good for this connection */
-+      cur = sasl_ALLOC(sizeof(context_list_t));
-+      if(!cur) {
-+          MEMERROR(conn);
-+          return 0;
-+      }
-+      cur->context = NULL;
-+      cur->mech = mech;
-+      cur->next = s_conn->mech_contexts;
-+      s_conn->mech_contexts = cur;
-+
-+      /* Error should be set by mech_avail call */
-+      return 0;
-+    } else if(context) {
-+      /* Save this context */
-+      cur = sasl_ALLOC(sizeof(context_list_t));
-+      if(!cur) {
-+          MEMERROR(conn);
-+          return 0;
-+      }
-+      cur->context = context;
-+      cur->mech = mech;
-+      cur->next = s_conn->mech_contexts;
-+      s_conn->mech_contexts = cur;
-+    }
-+    
-+    /* Generic mechanism */
-+    if (plug->max_ssf < minssf) {
-+      sasl_seterror(conn, SASL_NOLOG, "too weak");
-+      return 0; /* too weak */
-+    }
-+
-+    /* if there are no users in the secrets database we can't use this 
-+       mechanism */
-+    if (mech->condition == SASL_NOUSER) {
-+      sasl_seterror(conn, 0, "no users in secrets db");
-+      return 0;
-+    }
-+
-+    /* Can it meet our features? */
-+    if ((conn->flags & SASL_NEED_PROXY) &&
-+      !(plug->features & SASL_FEAT_ALLOWS_PROXY)) {
-+      return 0;
-+    }
-+    
-+    /* security properties---if there are any flags that differ and are
-+       in what the connection are requesting, then fail */
-+    
-+    /* special case plaintext */
-+    myflags = conn->props.security_flags;
-+
-+    /* if there's an external layer this is no longer plaintext */
-+    if ((conn->props.min_ssf <= conn->external.ssf) && 
-+      (conn->external.ssf > 1)) {
-+      myflags &= ~SASL_SEC_NOPLAINTEXT;
-+    }
-+
-+    /* do we want to special case SASL_SEC_PASS_CREDENTIALS? nah.. */
-+    if (((myflags ^ plug->security_flags) & myflags) != 0) {
-+      sasl_seterror(conn, SASL_NOLOG,
-+                    "security flags do not match required");
-+      return 0;
-+    }
-+
-+    /* Check Features */
-+    if(plug->features & SASL_FEAT_GETSECRET) {
-+      /* We no longer support sasl_server_{get,put}secret */
-+      sasl_seterror(conn, 0,
-+                    "mech %s requires unprovided secret facility",
-+                    plug->mech_name);
-+      return 0;
-+    }
-+
-+    return 1;
-+}
-+
-+/*
-+ * make the authorization 
-+ *
-+ */
-+
-+static int do_authorization(sasl_server_conn_t *s_conn)
-+{
-+    int ret;
-+    sasl_authorize_t *authproc;
-+    void *auth_context;
-+    
-+    /* now let's see if authname is allowed to proxy for username! */
-+    
-+    /* check the proxy callback */
-+    if (_sasl_getcallback(&s_conn->base, SASL_CB_PROXY_POLICY,
-+                        &authproc, &auth_context) != SASL_OK) {
-+      INTERROR(&s_conn->base, SASL_NOAUTHZ);
-+    }
-+
-+    ret = authproc(&(s_conn->base), auth_context,
-+                 s_conn->base.oparams.user, s_conn->base.oparams.ulen,
-+                 s_conn->base.oparams.authid, s_conn->base.oparams.alen,
-+                 s_conn->user_realm,
-+                 (s_conn->user_realm ? strlen(s_conn->user_realm) : 0),
-+                 s_conn->sparams->propctx);
-+
-+    RETURN(&s_conn->base, ret);
-+}
-+
-+
-+/* start a mechanism exchange within a connection context
-+ *  mech           -- the mechanism name client requested
-+ *  clientin       -- client initial response (NUL terminated), NULL if empty
-+ *  clientinlen    -- length of initial response
-+ *  serverout      -- initial server challenge, NULL if done 
-+ *                    (library handles freeing this string)
-+ *  serveroutlen   -- length of initial server challenge
-+ * output:
-+ *  pconn          -- the connection negotiation state on success
-+ *
-+ * Same returns as sasl_server_step() or
-+ * SASL_NOMECH if mechanism not available.
-+ */
-+int sasl_server_start(sasl_conn_t *conn,
-+                    const char *mech,
-+                    const char *clientin,
-+                    unsigned clientinlen,
-+                    const char **serverout,
-+                    unsigned *serveroutlen)
-+{
-+    sasl_server_conn_t *s_conn=(sasl_server_conn_t *) conn;
-+    int result;
-+    context_list_t *cur, **prev;
-+    mechanism_t *m;
-+
-+    if (_sasl_server_active==0) return SASL_NOTINIT;
-+
-+    /* make sure mech is valid mechanism
-+       if not return appropriate error */
-+    m=mechlist->mech_list;
-+
-+    /* check parameters */
-+    if(!conn) return SASL_BADPARAM;
-+    
-+    if (!mech || ((clientin==NULL) && (clientinlen>0)))
-+      PARAMERROR(conn);
-+
-+    if(serverout) *serverout = NULL;
-+    if(serveroutlen) *serveroutlen = 0;
-+
-+    while (m!=NULL)
-+    {
-+      if ( strcasecmp(mech,m->plug->mech_name)==0)
-+      {
-+          break;
-+      }
-+      m=m->next;
-+    }
-+  
-+    if (m==NULL) {
-+      sasl_seterror(conn, 0, "Couldn't find mech %s", mech);
-+      result = SASL_NOMECH;
-+      goto done;
-+    }
-+
-+    /* Make sure that we're willing to use this mech */
-+    if (! mech_permitted(conn, m)) {
-+      result = SASL_NOMECH;
-+      goto done;
-+    }
-+
-+    if (m->condition == SASL_CONTINUE) {
-+      sasl_server_plug_init_t *entry_point;
-+      void *library = NULL;
-+      sasl_server_plug_t *pluglist;
-+      int version, plugcount;
-+      int l = 0;
-+
-+      /* need to load this plugin */
-+      result = _sasl_get_plugin(m->f,
-+                  _sasl_find_verifyfile_callback(global_callbacks.callbacks),
-+                                &library);
-+
-+      if (result == SASL_OK) {
-+          result = _sasl_locate_entry(library, "sasl_server_plug_init",
-+                                      (void **)&entry_point);
-+      }
-+
-+      if (result == SASL_OK) {
-+          result = entry_point(mechlist->utils, SASL_SERVER_PLUG_VERSION,
-+                               &version, &pluglist, &plugcount);
-+      }
-+
-+      if (result == SASL_OK) {
-+          /* find the correct mechanism in this plugin */
-+          for (l = 0; l < plugcount; l++) {
-+              if (!strcasecmp(pluglist[l].mech_name, 
-+                              m->plug->mech_name)) break;
-+          }
-+          if (l == plugcount) {
-+              result = SASL_NOMECH;
-+          }
-+      }
-+      if (result == SASL_OK) {
-+          /* check that the parameters are the same */
-+          if ((pluglist[l].max_ssf != m->plug->max_ssf) ||
-+              (pluglist[l].security_flags != m->plug->security_flags)) {
-+              _sasl_log(conn, SASL_LOG_ERR, 
-+                        "%s: security parameters don't match mechlist file",
-+                        pluglist[l].mech_name);
-+              result = SASL_NOMECH;
-+          }
-+      }
-+      if (result == SASL_OK) {
-+          /* copy mechlist over */
-+          sasl_FREE((sasl_server_plug_t *) m->plug);
-+          m->plug = &pluglist[l];
-+          m->condition = SASL_OK;
-+      }
-+
-+      if (result != SASL_OK) {
-+          /* The library will eventually be freed, don't sweat it */
-+          RETURN(conn, result);
-+      }
-+    }
-+
-+    /* We used to setup sparams HERE, but now it's done
-+       inside of mech_permitted (which is called above) */
-+    prev = &s_conn->mech_contexts;
-+    for(cur = *prev; cur; prev=&cur->next,cur=cur->next) {
-+      if(cur->mech == m) {
-+          if(!cur->context) {
-+              sasl_seterror(conn, 0,
-+                            "Got past mech_permitted with a disallowed mech!");
-+              return SASL_NOMECH;
-+          }
-+          /* If we find it, we need to pull cur out of the
-+             list so it won't be freed later! */
-+          (*prev)->next = cur->next;
-+          conn->context = cur->context;
-+          sasl_FREE(cur);
-+      }
-+    }
-+
-+    s_conn->mech = m;
-+    
-+    if(!conn->context) {
-+      /* Note that we don't hand over a new challenge */
-+      result = s_conn->mech->plug->mech_new(s_conn->mech->plug->glob_context,
-+                                            s_conn->sparams,
-+                                            NULL,
-+                                            0,
-+                                            &(conn->context));
-+    } else {
-+      /* the work was already done by mech_avail! */
-+      result = SASL_OK;
-+    }
-+    
-+    if (result == SASL_OK) {
-+         if(clientin) {
-+            if(s_conn->mech->plug->features & SASL_FEAT_SERVER_FIRST) {
-+                /* Remote sent first, but mechanism does not support it.
-+                 * RFC 2222 says we fail at this point. */
-+                sasl_seterror(conn, 0,
-+                              "Remote sent first but mech does not allow it.");
-+                result = SASL_BADPROT;
-+            } else {
-+                /* Mech wants client-first, so let them have it */
-+                result = sasl_server_step(conn,
-+                                          clientin, clientinlen,
-+                                          serverout, serveroutlen);
-+            }
-+        } else {
-+            if(s_conn->mech->plug->features & SASL_FEAT_WANT_CLIENT_FIRST) {
-+                /* Mech wants client first anyway, so we should do that */
-+                *serverout = "";
-+                *serveroutlen = 0;
-+                result = SASL_CONTINUE;
-+            } else {
-+                /* Mech wants server-first, so let them have it */
-+                result = sasl_server_step(conn,
-+                                          clientin, clientinlen,
-+                                          serverout, serveroutlen);
-+            }
-+      }
-+    }
-+
-+ done:
-+    if(   result != SASL_OK
-+       && result != SASL_CONTINUE
-+       && result != SASL_INTERACT) {
-+      if(conn->context) {
-+          s_conn->mech->plug->mech_dispose(conn->context,
-+                                           s_conn->sparams->utils);
-+          conn->context = NULL;
-+      }
-+    }
-+    
-+    RETURN(conn,result);
-+}
-+
-+
-+/* perform one step of the SASL exchange
-+ *  inputlen & input -- client data
-+ *                      NULL on first step if no optional client step
-+ *  outputlen & output -- set to the server data to transmit
-+ *                        to the client in the next step
-+ *                        (library handles freeing this)
-+ *
-+ * returns:
-+ *  SASL_OK        -- exchange is complete.
-+ *  SASL_CONTINUE  -- indicates another step is necessary.
-+ *  SASL_TRANS     -- entry for user exists, but not for mechanism
-+ *                    and transition is possible
-+ *  SASL_BADPARAM  -- service name needed
-+ *  SASL_BADPROT   -- invalid input from client
-+ *  ...
-+ */
-+
-+int sasl_server_step(sasl_conn_t *conn,
-+                   const char *clientin,
-+                   unsigned clientinlen,
-+                   const char **serverout,
-+                   unsigned *serveroutlen)
-+{
-+    int ret;
-+    sasl_server_conn_t *s_conn = (sasl_server_conn_t *) conn;  /* cast */
-+
-+    /* check parameters */
-+    if (_sasl_server_active==0) return SASL_NOTINIT;
-+    if (!conn) return SASL_BADPARAM;
-+    if ((clientin==NULL) && (clientinlen>0))
-+      PARAMERROR(conn);
-+
-+    /* If we've already done the last send, return! */
-+    if(s_conn->sent_last == 1) {
-+      return SASL_OK;
-+    }
-+
-+    /* Don't do another step if the plugin told us that we're done */
-+    if (conn->oparams.doneflag) {
-+      _sasl_log(conn, SASL_LOG_ERR, "attempting server step after doneflag");
-+      return SASL_FAIL;
-+    }
-+
-+    if(serverout) *serverout = NULL;
-+    if(serveroutlen) *serveroutlen = 0;
-+
-+    ret = s_conn->mech->plug->mech_step(conn->context,
-+                                      s_conn->sparams,
-+                                      clientin,
-+                                      clientinlen,
-+                                      serverout,
-+                                      serveroutlen,
-+                                      &conn->oparams);
-+
-+    if (ret == SASL_OK) {
-+      ret = do_authorization(s_conn);
-+    }
-+
-+    if (ret == SASL_OK) {
-+      /* if we're done, we need to watch out for the following:
-+       * 1. the mech does server-send-last
-+       * 2. the protocol does not
-+       *
-+       * in this case, return SASL_CONTINUE and remember we are done.
-+       */
-+      if(*serverout && !(conn->flags & SASL_SUCCESS_DATA)) {
-+          s_conn->sent_last = 1;
-+          ret = SASL_CONTINUE;
-+      }
-+      if(!conn->oparams.maxoutbuf) {
-+          conn->oparams.maxoutbuf = conn->props.maxbufsize;
-+      }
-+
-+      if(conn->oparams.user == NULL || conn->oparams.authid == NULL) {
-+          sasl_seterror(conn, 0,
-+                        "mech did not call canon_user for both authzid " \
-+                        "and authid");
-+          ret = SASL_BADPROT;
-+      }       
-+    }
-+    
-+    if(   ret != SASL_OK
-+       && ret != SASL_CONTINUE
-+       && ret != SASL_INTERACT) {
-+      if(conn->context) {
-+          s_conn->mech->plug->mech_dispose(conn->context,
-+                                           s_conn->sparams->utils);
-+          conn->context = NULL;
-+      }
-+    }
-+
-+    RETURN(conn, ret);
-+}
-+
-+/* returns the length of all the mechanisms
-+ * added up 
-+ */
-+
-+static unsigned mech_names_len()
-+{
-+  mechanism_t *listptr;
-+  unsigned result = 0;
-+
-+  for (listptr = mechlist->mech_list;
-+       listptr;
-+       listptr = listptr->next)
-+    result += strlen(listptr->plug->mech_name);
-+
-+  return result;
-+}
-+
-+/* This returns a list of mechanisms in a NUL-terminated string
-+ *
-+ * The default behavior is to seperate with spaces if sep==NULL
-+ */
-+int _sasl_server_listmech(sasl_conn_t *conn,
-+                        const char *user __attribute__((unused)),
-+                        const char *prefix,
-+                        const char *sep,
-+                        const char *suffix,
-+                        const char **result,
-+                        unsigned *plen,
-+                        int *pcount)
-+{
-+  int lup;
-+  mechanism_t *listptr;
-+  int ret;
-+  int resultlen;
-+  int flag;
-+  const char *mysep;
-+
-+  /* if there hasn't been a sasl_sever_init() fail */
-+  if (_sasl_server_active==0) return SASL_NOTINIT;
-+  if (!conn) return SASL_BADPARAM;
-+  if (conn->type != SASL_CONN_SERVER) PARAMERROR(conn);
-+  
-+  if (! result)
-+      PARAMERROR(conn);
-+
-+  if (plen != NULL)
-+      *plen = 0;
-+  if (pcount != NULL)
-+      *pcount = 0;
-+
-+  if (sep) {
-+      mysep = sep;
-+  } else {
-+      mysep = " ";
-+  }
-+
-+  if (! mechlist || mechlist->mech_length <= 0)
-+      INTERROR(conn, SASL_NOMECH);
-+
-+  resultlen = (prefix ? strlen(prefix) : 0)
-+            + (strlen(mysep) * (mechlist->mech_length - 1))
-+          + mech_names_len()
-+            + (suffix ? strlen(suffix) : 0)
-+          + 1;
-+  ret = _buf_alloc(&conn->mechlist_buf,
-+                 &conn->mechlist_buf_len, resultlen);
-+  if(ret != SASL_OK) MEMERROR(conn);
-+
-+  if (prefix)
-+    strcpy (conn->mechlist_buf,prefix);
-+  else
-+    *(conn->mechlist_buf) = '\0';
-+
-+  listptr = mechlist->mech_list;  
-+   
-+  flag = 0;
-+  /* make list */
-+  for (lup = 0; lup < mechlist->mech_length; lup++) {
-+      /* currently, we don't use the "user" parameter for anything */
-+      if (mech_permitted(conn, listptr)) {
-+        if (pcount != NULL)
-+            (*pcount)++;
-+
-+        /* print seperator */
-+        if (flag) {
-+            strcat(conn->mechlist_buf, mysep);
-+        } else {
-+            flag = 1;
-+        }
-+
-+        /* now print the mechanism name */
-+        strcat(conn->mechlist_buf, listptr->plug->mech_name);
-+      }
-+
-+      listptr = listptr->next;
-+  }
-+
-+  if (suffix)
-+      strcat(conn->mechlist_buf,suffix);
-+
-+  if (plen!=NULL)
-+      *plen=strlen(conn->mechlist_buf);
-+
-+  *result = conn->mechlist_buf;
-+
-+  return SASL_OK;
-+  
-+}
-+
-+sasl_string_list_t *_sasl_server_mechs(void) 
-+{
-+  mechanism_t *listptr;
-+  sasl_string_list_t *retval = NULL, *next=NULL;
-+
-+  if(!_sasl_server_active) return NULL;
-+
-+  /* make list */
-+  for (listptr = mechlist->mech_list; listptr; listptr = listptr->next) {
-+      next = sasl_ALLOC(sizeof(sasl_string_list_t));
-+
-+      if(!next && !retval) return NULL;
-+      else if(!next) {
-+        next = retval->next;
-+        do {
-+            sasl_FREE(retval);
-+            retval = next;
-+            next = retval->next;
-+        } while(next);
-+        return NULL;
-+      }
-+      
-+      next->d = listptr->plug->mech_name;
-+
-+      if(!retval) {
-+        next->next = NULL;
-+        retval = next;
-+      } else {
-+        next->next = retval;
-+        retval = next;
-+      }
-+  }
-+
-+  return retval;
-+}
-+
-+#define EOSTR(s,n) (((s)[n] == '\0') || ((s)[n] == ' ') || ((s)[n] == '\t'))
-+static int is_mech(const char *t, const char *m)
-+{
-+    int sl = strlen(m);
-+    return ((!strncasecmp(m, t, sl)) && EOSTR(t, sl));
-+}
-+
-+/* returns OK if it's valid */
-+static int _sasl_checkpass(sasl_conn_t *conn, const char *service,
-+                         const char *user, const char *pass)
-+{
-+    sasl_server_conn_t *s_conn = (sasl_server_conn_t *) conn;
-+    int result;
-+    sasl_getopt_t *getopt;
-+    sasl_server_userdb_checkpass_t *checkpass_cb;
-+    void *context;
-+    const char *mlist, *mech;
-+    struct sasl_verify_password_s *v;
-+
-+    /* call userdb callback function, if available */
-+    result = _sasl_getcallback(conn, SASL_CB_SERVER_USERDB_CHECKPASS,
-+                             &checkpass_cb, &context);
-+    if(result == SASL_OK && checkpass_cb) {
-+      result = checkpass_cb(conn, context, user, pass, strlen(pass),
-+                            s_conn->sparams->propctx);
-+      if(result == SASL_OK)
-+          return SASL_OK;
-+    }
-+
-+    /* figure out how to check (i.e. auxprop or saslauthd or pwcheck) */
-+    if (_sasl_getcallback(conn, SASL_CB_GETOPT, &getopt, &context)
-+            == SASL_OK) {
-+        getopt(context, NULL, "pwcheck_method", &mlist, NULL);
-+    }
-+
-+    if(!mlist) mlist = DEFAULT_CHECKPASS_MECH;
-+
-+    result = SASL_NOMECH;
-+
-+    mech = mlist;
-+    while (*mech && result != SASL_OK) {
-+      for (v = _sasl_verify_password; v->name; v++) {
-+          if(is_mech(mech, v->name)) {
-+              result = v->verify(conn, user, pass, service,
-+                                 s_conn->user_realm);
-+              break;
-+          }
-+      }
-+      if (result != SASL_OK) {
-+          /* skip to next mech in list */
-+          while (*mech && !isspace((int) *mech)) mech++;
-+          while (*mech && isspace((int) *mech)) mech++;
-+      }
-+    }
-+
-+    if (result == SASL_NOMECH) {
-+      /* no mechanism available ?!? */
-+      _sasl_log(conn, SASL_LOG_ERR, "unknown password verifier %s", mech);
-+    }
-+
-+    if (result != SASL_OK)
-+      sasl_seterror(conn, SASL_NOLOG, "checkpass failed");
-+
-+    RETURN(conn, result);
-+}
-+
-+/* check if a plaintext password is valid
-+ *   if user is NULL, check if plaintext passwords are enabled
-+ * inputs:
-+ *  user          -- user to query in current user_domain
-+ *  userlen       -- length of username, 0 = strlen(user)
-+ *  pass          -- plaintext password to check
-+ *  passlen       -- length of password, 0 = strlen(pass)
-+ * returns 
-+ *  SASL_OK       -- success
-+ *  SASL_NOMECH   -- mechanism not supported
-+ *  SASL_NOVERIFY -- user found, but no verifier
-+ *  SASL_NOUSER   -- user not found
-+ */
-+int sasl_checkpass(sasl_conn_t *conn,
-+                 const char *user,
-+                 unsigned userlen __attribute__((unused)),
-+                 const char *pass,
-+                 unsigned passlen)
-+{
-+    int result;
-+    
-+    if (_sasl_server_active==0) return SASL_NOTINIT;
-+    
-+    /* check if it's just a query if we are enabled */
-+    if (!user)
-+      return SASL_OK;
-+
-+    if (!conn) return SASL_BADPARAM;
-+    
-+    /* check params */
-+    if (pass == NULL)
-+      PARAMERROR(conn);
-+
-+    result = _sasl_checkpass(conn, conn->service, user, pass);
-+
-+    if (result == SASL_OK) {
-+      strncpy(conn->authid_buf, user, CANON_BUF_SIZE);
-+      conn->oparams.authid = conn->authid_buf;
-+      
-+      result = _sasl_transition(conn, pass, passlen);
-+    }
-+
-+    RETURN(conn,result);
-+}
-+
-+/* check if a user exists on server
-+ *  conn          -- connection context (may be NULL, used to hold last error)
-+ *  service       -- registered name of the service using SASL (e.g. "imap")
-+ *  user_realm    -- permits multiple user realms on server, NULL = default
-+ *  user          -- NUL terminated user name
-+ *
-+ * returns:
-+ *  SASL_OK       -- success
-+ *  SASL_DISABLED -- account disabled [FIXME: currently not detected]
-+ *  SASL_NOUSER   -- user not found
-+ *  SASL_NOVERIFY -- user found, but no usable mechanism [FIXME: not supported]
-+ *  SASL_NOMECH   -- no mechanisms enabled
-+ */
-+int sasl_user_exists(sasl_conn_t *conn,
-+                   const char *service,
-+                   const char *user_realm,
-+                   const char *user) 
-+{
-+    int result=SASL_NOMECH;
-+    const char *mlist, *mech;
-+    void *context;
-+    sasl_getopt_t *getopt;
-+    struct sasl_verify_password_s *v;
-+    
-+    /* check params */
-+    if (_sasl_server_active==0) return SASL_NOTINIT;
-+    if (!conn) return SASL_BADPARAM;
-+    if (!user || conn->type != SASL_CONN_SERVER) 
-+      PARAMERROR(conn);
-+
-+    if(!service) service = conn->service;
-+    
-+    /* figure out how to check (i.e. auxprop or saslauthd or pwcheck) */
-+    if (_sasl_getcallback(conn, SASL_CB_GETOPT, &getopt, &context)
-+            == SASL_OK) {
-+        getopt(context, NULL, "pwcheck_method", &mlist, NULL);
-+    }
-+
-+    if(!mlist) mlist = DEFAULT_CHECKPASS_MECH;
-+
-+    result = SASL_NOMECH;
-+
-+    mech = mlist;
-+    while (*mech && result != SASL_OK) {
-+      for (v = _sasl_verify_password; v->name; v++) {
-+          if(is_mech(mech, v->name)) {
-+              result = v->verify(conn, user, NULL, service, user_realm);
-+              break;
-+          }
-+      }
-+      if (result != SASL_OK) {
-+          /* skip to next mech in list */
-+          while (*mech && !isspace((int) *mech)) mech++;
-+          while (*mech && isspace((int) *mech)) mech++;
-+      }
-+    }
-+
-+    /* Screen out the SASL_BADPARAM response
-+     * we'll get from not giving a password */
-+    if(result == SASL_BADPARAM) {
-+      result = SASL_OK;
-+    }
-+
-+    if (result == SASL_NOMECH) {
-+      /* no mechanism available ?!? */
-+      _sasl_log(conn, SASL_LOG_ERR, "no plaintext password verifier?");
-+      sasl_seterror(conn, SASL_NOLOG, "no plaintext password verifier?");
-+    }
-+
-+    RETURN(conn, result);
-+}
-+
-+/* check if an apop exchange is valid
-+ *  (note this is an optional part of the SASL API)
-+ *  if challenge is NULL, just check if APOP is enabled
-+ * inputs:
-+ *  challenge     -- challenge which was sent to client
-+ *  challen       -- length of challenge, 0 = strlen(challenge)
-+ *  response      -- client response, "<user> <digest>" (RFC 1939)
-+ *  resplen       -- length of response, 0 = strlen(response)
-+ * returns 
-+ *  SASL_OK       -- success
-+ *  SASL_BADAUTH  -- authentication failed
-+ *  SASL_BADPARAM -- missing challenge
-+ *  SASL_BADPROT  -- protocol error (e.g., response in wrong format)
-+ *  SASL_NOVERIFY -- user found, but no verifier
-+ *  SASL_NOMECH   -- mechanism not supported
-+ *  SASL_NOUSER   -- user not found
-+ */
-+int sasl_checkapop(sasl_conn_t *conn,
-+#ifdef DO_SASL_CHECKAPOP
-+                 const char *challenge,
-+                 unsigned challen __attribute__((unused)),
-+                 const char *response,
-+                 unsigned resplen __attribute__((unused)))
-+#else
-+                 const char *challenge __attribute__((unused)),
-+                 unsigned challen __attribute__((unused)),
-+                 const char *response __attribute__((unused)),
-+                 unsigned resplen __attribute__((unused)))
-+#endif
-+{
-+#ifdef DO_SASL_CHECKAPOP
-+    sasl_server_conn_t *s_conn = (sasl_server_conn_t *) conn;
-+    char *user, *user_end;
-+    const char *password_request[] = { SASL_AUX_PASSWORD, NULL };
-+    size_t user_len;
-+    int result;
-+
-+    if (_sasl_server_active==0)
-+      return SASL_NOTINIT;
-+
-+    /* check if it's just a query if we are enabled */
-+    if(!challenge)
-+      return SASL_OK;
-+
-+    /* check params */
-+    if (!conn) return SASL_BADPARAM;
-+    if (!response)
-+      PARAMERROR(conn);
-+
-+    /* Parse out username and digest.
-+     *
-+     * Per RFC 1939, response must be "<user> <digest>", where
-+     * <digest> is a 16-octet value which is sent in hexadecimal
-+     * format, using lower-case ASCII characters.
-+     */
-+    user_end = strrchr(response, ' ');
-+    if (!user_end || strspn(user_end + 1, "0123456789abcdef") != 32) 
-+    {
-+        sasl_seterror(conn, 0, "Bad Digest");
-+        RETURN(conn,SASL_BADPROT);
-+    }
-+ 
-+    user_len = (size_t)(user_end - response);
-+    user = sasl_ALLOC(user_len + 1);
-+    memcpy(user, response, user_len);
-+    user[user_len] = '\0';
-+
-+    result = prop_request(s_conn->sparams->propctx, password_request);
-+    if(result != SASL_OK) 
-+    {
-+        sasl_FREE(user);
-+        RETURN(conn, result);
-+    }
-+
-+    /* Cannonify it */
-+    result = _sasl_canon_user(conn, user, user_len,
-+                            SASL_CU_AUTHID | SASL_CU_AUTHZID,
-+                            &(conn->oparams));
-+    sasl_FREE(user);
-+
-+    if(result != SASL_OK) RETURN(conn, result);
-+
-+    /* Do APOP verification */
-+    result = _sasl_auxprop_verify_apop(conn, conn->oparams.authid,
-+      challenge, user_end + 1, s_conn->user_realm);
-+
-+    /* If verification failed, we don't want to encourage getprop to work */
-+    if(result != SASL_OK) {
-+      conn->oparams.user = NULL;
-+      conn->oparams.authid = NULL;
-+    }
+diff -durN cyrus-sasl-2.1.10.orig/lib/saslint.h cyrus-sasl-2.1.10/lib/saslint.h
+--- cyrus-sasl-2.1.10.orig/lib/saslint.h       Thu Dec  5 05:16:59 2002
++++ cyrus-sasl-2.1.10/lib/saslint.h    Thu Jan  9 11:42:29 2003
+@@ -356,6 +356,9 @@
+ _sasl_find_getpath_callback(const sasl_callback_t *callbacks);
+ extern const sasl_callback_t *
++_sasl_find_getconfpath_callback(const sasl_callback_t *callbacks);
 +
-+    RETURN(conn, result);
-+#else /* sasl_checkapop was disabled at compile time */
-+    sasl_seterror(conn, SASL_NOLOG,
-+      "sasl_checkapop called, but was disabled at compile time");
-+    RETURN(conn, SASL_NOMECH);
-+#endif /* DO_SASL_CHECKAPOP */
-+}
-+ 
++extern const sasl_callback_t *
+ _sasl_find_verifyfile_callback(const sasl_callback_t *callbacks);
+ extern int _sasl_common_init(void);
+diff -durN cyrus-sasl-2.1.10.orig/lib/server.c cyrus-sasl-2.1.10/lib/server.c
+--- cyrus-sasl-2.1.10.orig/lib/server.c        Thu Dec  5 05:16:59 2002
++++ cyrus-sasl-2.1.10/lib/server.c     Thu Jan  9 11:42:29 2003
+@@ -379,15 +379,15 @@
+   char *c;
+   char *config_filename=NULL;
+   int len;
+-  const sasl_callback_t *getpath_cb=NULL;
++  const sasl_callback_t *getconfpath_cb=NULL;
+   /* get the path to the plugins; for now the config file will reside there */
+-  getpath_cb=_sasl_find_getpath_callback( global_callbacks.callbacks );
+-  if (getpath_cb==NULL) return SASL_BADPARAM;
++  getconfpath_cb=_sasl_find_getconfpath_callback( global_callbacks.callbacks );
++  if (getconfpath_cb==NULL) return SASL_BADPARAM;
+-  /* getpath_cb->proc MUST be a sasl_getpath_t; if only c had a type
++  /* getconfpath_cb->proc MUST be a sasl_getconfpath_t; if only c had a type
+      system */
+-  result = ((sasl_getpath_t *)(getpath_cb->proc))(getpath_cb->context,
++  result = ((sasl_getconfpath_t *)(getconfpath_cb->proc))(getconfpath_cb->context,
+                                                 &path_to_config);
+   if (result!=SASL_OK) goto done;
+   if (path_to_config == NULL) path_to_config = "";
 diff -durN cyrus-sasl-2.1.10.orig/man/sasl_getconfpath_t.3 cyrus-sasl-2.1.10/man/sasl_getconfpath_t.3
 --- cyrus-sasl-2.1.10.orig/man/sasl_getconfpath_t.3    Thu Jan  1 01:00:00 1970
 +++ cyrus-sasl-2.1.10/man/sasl_getconfpath_t.3 Thu Jan  9 11:42:29 2003
diff --git a/cyrus-sasl-lt14d.patch b/cyrus-sasl-lt14d.patch
new file mode 100644 (file)
index 0000000..5c692ea
--- /dev/null
@@ -0,0 +1,12 @@
+--- cyrus-sasl-2.1.10/lib/Makefile.am.orig     Fri Dec  6 17:24:00 2002
++++ cyrus-sasl-2.1.10/lib/Makefile.am  Thu Jan  9 20:49:51 2003
+@@ -66,6 +66,9 @@
+ plugin_common.lo: plugin_common.o
+       rm -f plugin_common.lo
+       ln -s $(top_builddir)/plugins/plugin_common.lo plugin_common.lo
++      if [ -f $(top_builddir)/plugins/.libs/plugin_common.o ]; then \
++              ln -s ../$(top_builddir)/plugins/.libs/plugin_common.o .libs/plugin_common.o ; \
++      fi
+ plugin_common.o:
+       rm -f plugin_common.o
diff --git a/cyrus-sasl-nolibs.patch b/cyrus-sasl-nolibs.patch
new file mode 100644 (file)
index 0000000..e3cd091
--- /dev/null
@@ -0,0 +1,42 @@
+--- cyrus-sasl-2.1.10/configure.in.orig        Thu Jan  9 20:22:17 2003
++++ cyrus-sasl-2.1.10/configure.in     Thu Jan  9 20:47:17 2003
+@@ -807,7 +807,7 @@
+ AC_SUBST(LTSNPRINTFOBJS)
+ dnl do we need to link in -lresolv?
+-AC_CHECK_LIB(resolv, inet_aton)
++AC_SEARCH_LIBS(inet_aton, resolv)
+ dnl Check for getaddrinfo
+ GETADDRINFOOBJS=""
+--- cyrus-sasl-2.1.10/cmulocal/bsd_sockets.m4.orig     Tue May 28 21:06:56 2002
++++ cyrus-sasl-2.1.10/cmulocal/bsd_sockets.m4  Thu Jan  9 21:07:50 2003
+@@ -16,11 +16,12 @@
+                            LIB_SOCKET="-lsocket $LIB_SOCKET")
+       )
+       LIBS="$LIB_SOCKET $save_LIBS"
+-      AC_CHECK_FUNC(res_search, :,
+-                AC_CHECK_LIB(resolv, res_search,
+-                              LIB_SOCKET="-lresolv $LIB_SOCKET") 
+-        )
+-      LIBS="$LIB_SOCKET $save_LIBS"
++dnl we don't need res_search if no kerberos support
++dnl   AC_CHECK_FUNC(res_search, :,
++dnl             AC_CHECK_LIB(resolv, res_search,
++dnl                           LIB_SOCKET="-lresolv $LIB_SOCKET") 
++dnl     )
++dnl   LIBS="$LIB_SOCKET $save_LIBS"
+       AC_CHECK_FUNCS(dn_expand dns_lookup)
+       LIBS="$save_LIBS"
+       AC_SUBST(LIB_SOCKET)
+--- cyrus-sasl-2.1.10/saslauthd/configure.in.orig      Fri Dec  6 17:24:06 2002
++++ cyrus-sasl-2.1.10/saslauthd/configure.in   Thu Jan  9 21:22:46 2003
+@@ -106,7 +106,7 @@
+ fi
+ AC_SUBST(LIB_PAM)
+-AC_CHECK_LIB(resolv, inet_aton)
++AC_SEARCH_LIBS(inet_aton, resolv)
+ AC_MSG_CHECKING(to include experimental LDAP support)
+ AC_ARG_WITH(ldap, [  --with-ldap=DIR         use LDAP (in DIR) (experimental) [no] ],
index 387d0a9fcf388a594be75920c1c96d2773fc9b62..244dfc0d7334688e5e22e7979e5d05edd82e7ec3 100644 (file)
@@ -19,14 +19,16 @@ Source1:    saslauthd.init
 Source2:       saslauthd.sysconfig
 Source3:       %{name}.pam
 Patch0:                %{name}-configdir.patch
+Patch1:                %{name}-nolibs.patch
+Patch2:                %{name}-lt14d.patch
 BuildRequires: autoconf
 BuildRequires: automake
 BuildRequires: db-devel
-BuildRequires: pam-devel
-BuildRequires: openssl-devel >= 0.9.6a
 BuildRequires: libtool >= 1.4
 %{!?_without_mysql:BuildRequires: mysql-devel}
 %{!?_without_ldap:BuildRequires: openldap-devel}
+BuildRequires: openssl-devel >= 0.9.6a
+BuildRequires: pam-devel
 URL:           http://asg.web.cmu.edu/sasl/
 BuildRoot:     %{tmpdir}/%{name}-%{version}-root-%(id -u -n)
 
@@ -321,21 +323,24 @@ Cyrus SASL mysql plugin.
 %description mysql -l pl
 Wtyczka mysql do Cyrus SASL.
 
-
 %prep
 %setup  -q
 %patch0 -p1
+%patch1 -p1
+%patch2 -p1
 
 %build
-rm -f config/missing
+# acinclude.m4 contains only old libtool.m4
+rm -f acinclude.m4 config/missing
 %{__libtoolize}
 %{__aclocal} -I cmulocal -I config
 %{__autoheader}
-automake -a
+%{__automake}
+#-a
 %{__autoconf}
 
 cd saslauthd
-%{__libtoolize}
+#%{__libtoolize}
 %{__aclocal} -I ../cmulocal -I ../config -I config
 %{__autoheader}
 automake -a
@@ -355,7 +360,8 @@ LDFLAGS="%{rpmldflags} -ldl"; export LDFLAGS
        --with-dblib=berkeley \
        --with-dbpath=/var/lib/sasl2/sasl.db \
        --with-configdir=%{_sysconfdir} \
-       --disable-krb4
+       --disable-krb4 \
+       --disable-gssapi
 %{__make}
 
 %install
This page took 0.200952 seconds and 4 git commands to generate.