Home | History | Annotate | Download | only in include
      1 /*
      2  * Copyright 2003 Sun Microsystems, Inc.  All rights reserved.
      3  * Use is subject to license terms.
      4  */
      5 
      6 /*
      7  * *******************************IMPORTANT******************************
      8  * send email to chris.newman (at) sun.com and cyrus-bugs (at) andrew.cmu.edu     *
      9  * if you need to add new error codes, callback types, property values, *
     10  * etc.   It is important to keep the multiple implementations of this  *
     11  * API from diverging.                                                  *
     12  * *******************************IMPORTANT******************************
     13  *
     14  * Basic Type Summary:
     15  *  sasl_conn_t       Context for a SASL connection negotiation
     16  *  sasl_ssf_t        Security layer Strength Factor
     17  *  sasl_callback_t   A typed client/server callback function and context
     18  *  sasl_interact_t   A client interaction descriptor
     19  *  sasl_secret_t     A client password
     20  *  sasl_rand_t       Random data context structure
     21  *  sasl_security_properties_t  An application's required security level
     22  *
     23  * Callbacks:
     24  *  sasl_getopt_t     client/server: Get an option value
     25  *  sasl_canon_user_t client/server: Canonicalize username
     26  *  sasl_log_t        client/server: Log message handler
     27  *  sasl_verifyfile_t client/server: Verify file for specified usage
     28  *  sasl_getpath_t    client/server: Get sasl search path
     29  *
     30  * Client only Callbacks:
     31  *  sasl_getrealm_t   client: Get available realms
     32  *  sasl_getsimple_t  client: Get user/language list
     33  *  sasl_getsecret_t  client: Get authentication secret
     34  *  sasl_chalprompt_t client: Display challenge and prompt for response
     35  *
     36  * Server only Callbacks:
     37  *  sasl_authorize_t               user authorization policy callback
     38  *  sasl_server_userdb_checkpass_t check password and auxprops in userdb
     39  *  sasl_server_userdb_setpass_t   set password in userdb
     40  *
     41  * Client/Server Function Summary:
     42  *  sasl_done         Release all SASL global state
     43  *  sasl_dispose      Connection done: Dispose of sasl_conn_t
     44  *  sasl_getprop      Get property (e.g., user name, security layer info)
     45  *  sasl_setprop      Set property (e.g., external ssf)
     46  *  sasl_errdetail    Generate string from last error on connection
     47  *  sasl_errstring    Translate sasl error code to a string
     48  *  sasl_encode       Encode data to send using security layer
     49  *  sasl_decode       Decode data received using security layer
     50  *
     51  * Utility functions:
     52  *  sasl_encode64     Encode data to send using MIME base64 encoding
     53  *  sasl_decode64     Decode data received using MIME base64 encoding
     54  *  sasl_erasebuffer  Erase a buffer
     55  *
     56  * Client Function Summary:
     57  *  sasl_client_init  Load and initialize client plug-ins (call once)
     58  *  sasl_client_new   Initialize client connection context: sasl_conn_t
     59  *  sasl_client_start Select mechanism for connection
     60  *  sasl_client_step  Perform one authentication step
     61  *
     62  * Server Function Summary
     63  *  sasl_server_init  Load and initialize server plug-ins (call once)
     64  *  sasl_server_new   Initialize server connection context: sasl_conn_t
     65  *  sasl_listmech     Create list of available mechanisms
     66  *  sasl_server_start Begin an authentication exchange
     67  *  sasl_server_step  Perform one authentication exchange step
     68  *  sasl_checkpass    Check a plaintext passphrase
     69  *  sasl_checkapop    Check an APOP challenge/response (uses pseudo "APOP"
     70  *                    mechanism similar to CRAM-MD5 mechanism; optional)
     71  *  sasl_user_exists  Check if user exists
     72  *  sasl_setpass      Change a password or add a user entry
     73  *  sasl_auxprop_request  Request auxiliary properties
     74  *  sasl_auxprop_getctx   Get auxiliary property context for connection
     75  *
     76  * Basic client model:
     77  *  1. client calls sasl_client_init() at startup to load plug-ins
     78  *  2. when connection formed, call sasl_client_new()
     79  *  3. once list of supported mechanisms received from server, client
     80  *     calls sasl_client_start().  goto 4a
     81  *  4. client calls sasl_client_step()
     82  * [4a. If SASL_INTERACT, fill in prompts and goto 4
     83  *      -- doesn't happen if callbacks provided]
     84  *  4b. If SASL error, goto 7 or 3
     85  *  4c. If SASL_OK, continue or goto 6 if last server response was success
     86  *  5. send message to server, wait for response
     87  *  5a. On data or success with server response, goto 4
     88  *  5b. On failure goto 7 or 3
     89  *  5c. On success with no server response continue
     90  *  6. continue with application protocol until connection closes
     91  *     call sasl_getprop/sasl_encode/sasl_decode() if using security layer
     92  *  7. call sasl_dispose(), may return to step 2
     93  *  8. call sasl_done() when program terminates
     94  *
     95  * Basic Server model:
     96  *  1. call sasl_server_init() at startup to load plug-ins
     97  *  2. On connection, call sasl_server_new()
     98  *  3. call sasl_listmech() and send list to client]
     99  *  4. after client AUTH command, call sasl_server_start(), goto 5a
    100  *  5. call sasl_server_step()
    101  *  5a. If SASL_CONTINUE, output to client, wait response, repeat 5
    102  *  5b. If SASL error, then goto 7
    103  *  5c. If SASL_OK, move on
    104  *  6. continue with application protocol until connection closes
    105  *     call sasl_getprop to get username
    106  *     call sasl_getprop/sasl_encode/sasl_decode() if using security layer
    107  *  7. call sasl_dispose(), may return to step 2
    108  *  8. call sasl_done() when program terminates
    109  *
    110  * ***********************************************
    111  * IMPORTANT NOTE: server realms / username syntax
    112  *
    113  * If a user name contains a "@", then the rightmost "@" in the user name
    114  * separates the account name from the realm in which this account is
    115  * located.  A single server may support multiple realms.  If the
    116  * server knows the realm at connection creation time (e.g., a server
    117  * with multiple IP addresses tightly binds one address to a specific
    118  * realm) then that realm must be passed in the user_realm field of
    119  * the sasl_server_new call.  If user_realm is non-empty and an
    120  * unqualified user name is supplied, then the canon_user facility is
    121  * expected to append "@" and user_realm to the user name.  The canon_user
    122  * facility may treat other characters such as "%" as equivalent to "@".
    123  *
    124  * If the server forbids the use of "@" in user names for other
    125  * purposes, this simplifies security validation.
    126  */
    127 
    128 #ifndef	_SASL_SASL_H
    129 #define	_SASL_SASL_H
    130 
    131 #pragma ident	"%Z%%M%	%I%	%E% SMI"
    132 
    133 #ifndef	_SASL_PROP_H
    134 #include <sasl/prop.h>
    135 #endif
    136 
    137 #ifdef	__cplusplus
    138 extern "C" {
    139 #endif
    140 
    141 #define	SASL_VERSION_MAJOR 2
    142 #define	SASL_VERSION_MINOR 1
    143 #define	SASL_VERSION_STEP 15
    144 
    145 /*
    146  * The following ifdef block is the standard way of creating macros
    147  * which make exporting from a DLL simpler. All files within this DLL
    148  * are compiled with the LIBSASL_EXPORTS symbol defined on the command
    149  * line. this symbol should not be defined on any project that uses
    150  * this DLL. This way any other project whose source files include
    151  * this file see LIBSASL_API functions as being imported from a DLL,
    152  * wheras this DLL sees symbols defined with this macro as being
    153  * exported.
    154  *
    155  * Under Unix, life is simpler: we just need to mark library functions
    156  * as extern.  (Technically, we don't even have to do that.)
    157  */
    158 #ifdef WIN32
    159 #ifdef LIBSASL_EXPORTS
    160 #define	LIBSASL_API  __declspec(dllexport)
    161 #else /* LIBSASL_EXPORTS */
    162 #define	LIBSASL_API  __declspec(dllimport)
    163 #endif /* LIBSASL_EXPORTS */
    164 #else /* WIN32 */
    165 #define	LIBSASL_API extern
    166 #endif /* WIN32 */
    167 
    168 /*
    169  * Same as above, but used during a variable declaration. Only Unix definition
    170  * is different, as we can't assign an initial value to an extern variable
    171  */
    172 #ifdef WIN32
    173 #ifdef LIBSASL_EXPORTS
    174 #define	LIBSASL_VAR  __declspec(dllexport)
    175 #else /* LIBSASL_EXPORTS */
    176 #define	LIBSASL_VAR  __declspec(dllimport)
    177 #endif /* LIBSASL_EXPORTS */
    178 #else /* WIN32 */
    179 #define	LIBSASL_VAR
    180 #endif /* WIN32 */
    181 
    182 /*
    183  * Basic API
    184  */
    185 
    186 /* SASL result codes: */
    187 #define	SASL_CONTINUE	1   /* another step is needed in authentication */
    188 #define	SASL_OK		0   /* successful result */
    189 #define	SASL_FAIL	-1   /* generic failure */
    190 #define	SASL_NOMEM	-2   /* memory shortage failure */
    191 #define	SASL_BUFOVER	-3   /* overflowed buffer */
    192 #define	SASL_NOMECH	-4   /* mechanism not supported */
    193 #define	SASL_BADPROT	-5   /* bad protocol / cancel */
    194 #define	SASL_NOTDONE	-6   /* can't request info until later in exchange */
    195 #define	SASL_BADPARAM	-7   /* invalid parameter supplied */
    196 #define	SASL_TRYAGAIN	-8   /* transient failure (e.g., weak key) */
    197 #define	SASL_BADMAC	-9   /* integrity check failed */
    198 #define	SASL_NOTINIT	-12  /* SASL library not initialized */
    199 
    200 /* -- client only codes -- */
    201 #define	SASL_INTERACT	2   /* needs user interaction */
    202 #define	SASL_BADSERV	-10  /* server failed mutual authentication step */
    203 #define	SASL_WRONGMECH	-11  /* mechanism doesn't support requested feature */
    204 
    205 /* -- server only codes -- */
    206 #define	SASL_BADAUTH	-13  /* authentication failure */
    207 #define	SASL_NOAUTHZ	-14  /* authorization failure */
    208 #define	SASL_TOOWEAK	-15  /* mechanism too weak for this user */
    209 #define	SASL_ENCRYPT	-16  /* encryption needed to use mechanism */
    210 #define	SASL_TRANS	-17  /* One time use of a plaintext password will */
    211 				/* enable requested mechanism for user */
    212 #define	SASL_EXPIRED	-18  /* passphrase expired, has to be reset */
    213 #define	SASL_DISABLED	-19  /* account disabled */
    214 #define	SASL_NOUSER	-20  /* user not found */
    215 #define	SASL_BADVERS	-23  /* version mismatch with plug-in */
    216 #define	SASL_UNAVAIL	-24  /* remote authentication server unavailable */
    217 #define	SASL_NOVERIFY	-26  /* user exists, but no verifier for user */
    218 
    219 /* -- codes for password setting -- */
    220 #define	SASL_PWLOCK	-21  /* passphrase locked */
    221 #define	SASL_NOCHANGE	-22  /* requested change was not needed */
    222 #define	SASL_WEAKPASS	-27  /* passphrase is too weak for security policy */
    223 #define	SASL_NOUSERPASS	-28  /* user supplied passwords not permitted */
    224 
    225 /* max size of a sasl mechanism name */
    226 #define	SASL_MECHNAMEMAX 20
    227 
    228 #ifdef _WIN32
    229 /* Define to have the same layout as a WSABUF */
    230 #ifndef STRUCT_IOVEC_DEFINED
    231 #define	STRUCT_IOVEC_DEFINED 1
    232 struct iovec {
    233     long iov_len;
    234     char *iov_base;
    235 };
    236 #endif
    237 #else
    238 struct iovec;				/* Defined in OS headers */
    239 #endif
    240 
    241 
    242 /* per-connection SASL negotiation state for client or server */
    243 typedef struct sasl_conn sasl_conn_t;
    244 
    245 /*
    246  * Plain text password structure.
    247  *  len is the length of the password, data is the text.
    248  */
    249 typedef struct sasl_secret {
    250     unsigned long len;
    251     unsigned char data[1];		/* variable sized */
    252 } sasl_secret_t;
    253 
    254 /* random data context structure */
    255 typedef struct sasl_rand_s sasl_rand_t;
    256 
    257 
    258 /*
    259  * Configure Basic Services
    260  */
    261 
    262 /*
    263  * the following functions are used to adjust how allocation and mutexes work
    264  * they must be called before all other SASL functions:
    265  */
    266 
    267 /* The following function is obsolete */
    268 /*
    269  * memory allocation functions which may optionally be replaced:
    270  */
    271 typedef void *sasl_malloc_t(unsigned long);
    272 typedef void *sasl_calloc_t(unsigned long, unsigned long);
    273 typedef void *sasl_realloc_t(void *, unsigned long);
    274 typedef void sasl_free_t(void *);
    275 
    276 LIBSASL_API void sasl_set_alloc(sasl_malloc_t *,
    277 				sasl_calloc_t *,
    278 				sasl_realloc_t *,
    279 				sasl_free_t *);
    280 
    281 /* The following function is obsolete */
    282 /*
    283  * mutex functions which may optionally be replaced:
    284  *  sasl_mutex_alloc allocates a mutex structure
    285  *  sasl_mutex_lock blocks until mutex locked
    286  *   returns -1 on deadlock or parameter error
    287  *   returns 0 on success
    288  *  sasl_mutex_unlock unlocks mutex if it's locked
    289  *   returns -1 if not locked or parameter error
    290  *   returns 0 on success
    291  *  sasl_mutex_free frees a mutex structure
    292  */
    293 typedef void *sasl_mutex_alloc_t(void);
    294 typedef int sasl_mutex_lock_t(void *mutex);
    295 typedef int sasl_mutex_unlock_t(void *mutex);
    296 typedef void sasl_mutex_free_t(void *mutex);
    297 LIBSASL_API void sasl_set_mutex(sasl_mutex_alloc_t *, sasl_mutex_lock_t *,
    298 				sasl_mutex_unlock_t *, sasl_mutex_free_t *);
    299 
    300 /*
    301  * Security preference types
    302  */
    303 
    304 /*
    305  * security layer strength factor -- an unsigned integer usable by the caller
    306  *  to specify approximate security layer strength desired.  Roughly
    307  *  correlated to effective key length for encryption.
    308  * 0   = no protection
    309  * 1   = integrity protection only
    310  * 40  = 40-bit DES or 40-bit RC2/RC4
    311  * 56  = DES
    312  * 112 = triple-DES
    313  * 128 = 128-bit RC2/RC4/BLOWFISH
    314  * 256 = baseline AES
    315  */
    316 typedef unsigned sasl_ssf_t;
    317 
    318 /* usage flags provided to sasl_server_new and sasl_client_new: */
    319 #define	SASL_SUCCESS_DATA	0x0004 /* server supports data on success */
    320 #define	SASL_NEED_PROXY		0x0008 /* require a mech that allows proxying */
    321 
    322 /*
    323  * Security Property Types
    324  */
    325 
    326 /*
    327  * Structure specifying the client or server's security policy
    328  * and optional additional properties.
    329  */
    330 
    331 /* These are the various security flags apps can specify. */
    332 /*
    333  * NOPLAINTEXT          -- don't permit mechanisms susceptible to simple
    334  *                         passive attack (e.g., PLAIN, LOGIN)
    335  * NOACTIVE             -- protection from active (non-dictionary) attacks
    336  *                         during authentication exchange.
    337  *                         Authenticates server.
    338  * NODICTIONARY         -- don't permit mechanisms susceptible to passive
    339  *                         dictionary attack
    340  * FORWARD_SECRECY      -- require forward secrecy between sessions
    341  *                         (breaking one won't help break next)
    342  * NOANONYMOUS          -- don't permit mechanisms that allow anonymous login
    343  * PASS_CREDENTIALS     -- require mechanisms which pass client
    344  *			   credentials, and allow mechanisms which can pass
    345  *			   credentials to do so
    346  * MUTUAL_AUTH          -- require mechanisms which provide mutual
    347  *			   authentication
    348  */
    349 #define	SASL_SEC_NOPLAINTEXT		0x0001
    350 #define	SASL_SEC_NOACTIVE		0x0002
    351 #define	SASL_SEC_NODICTIONARY		0x0004
    352 #define	SASL_SEC_FORWARD_SECRECY	0x0008
    353 #define	SASL_SEC_NOANONYMOUS		0x0010
    354 #define	SASL_SEC_PASS_CREDENTIALS	0x0020
    355 #define	SASL_SEC_MUTUAL_AUTH		0x0040
    356 #define	SASL_SEC_MAXIMUM		0x00FF
    357 
    358 typedef struct sasl_security_properties
    359 {
    360 	/*
    361 	 * security strength factor
    362 	 *  min_ssf	= minimum acceptable final level
    363 	 *  max_ssf	= maximum acceptable final level
    364 	 */
    365     sasl_ssf_t min_ssf;
    366     sasl_ssf_t max_ssf;
    367 
    368 	/*
    369 	 * Maximum security layer receive buffer size.
    370 	 *  0=security layer not supported
    371 	 */
    372     unsigned maxbufsize;
    373 
    374 /* bitfield for attacks to protect against */
    375     unsigned security_flags;
    376 
    377 /* NULL terminated array of additional property names, values */
    378     const char **property_names;
    379     const char **property_values;
    380 } sasl_security_properties_t;
    381 
    382 /*
    383  * Callback types
    384  */
    385 
    386 /*
    387  * Extensible type for a client/server callbacks
    388  *  id      -- identifies callback type
    389  *  proc    -- procedure call arguments vary based on id
    390  *  context -- context passed to procedure
    391  */
    392 /*
    393  * Note that any memory that is allocated by the callback needs to be
    394  * freed by the application, be it via function call or interaction.
    395  *
    396  * It may be freed after sasl_*_step returns SASL_OK.  if the mechanism
    397  * requires this information to persist (for a security layer, for example)
    398  * it must maintain a private copy.
    399  */
    400 typedef struct sasl_callback {
    401 	/*
    402 	 * Identifies the type of the callback function.
    403 	 * Mechanisms must ignore callbacks with id's they don't recognize.
    404 	 */
    405     unsigned long id;
    406     int (*proc)();   /* Callback function.  Types of arguments vary by 'id' */
    407     void *context;
    408 } sasl_callback_t;
    409 
    410 /*
    411  * callback ids & functions:
    412  */
    413 #define	SASL_CB_LIST_END   0  /* end of list */
    414 
    415 /*
    416  * option reading callback -- this allows a SASL configuration to be
    417  *  encapsulated in the caller's configuration system.  Some implementations
    418  *  may use default config file(s) if this is omitted.  Configuration items
    419  *  may be plugin-specific and are arbitrary strings.
    420  *
    421  * inputs:
    422  *  context     -- option context from callback record
    423  *  plugin_name -- name of plugin (NULL = general SASL option)
    424  *  option      -- name of option
    425  * output:
    426  *  result      -- set to result which persists until next getopt in
    427  *                 same thread, unchanged if option not found
    428  *  len         -- length of result (may be NULL)
    429  * returns:
    430  *  SASL_OK     -- no error
    431  *  SASL_FAIL   -- error
    432  */
    433 typedef int sasl_getopt_t(void *context, const char *plugin_name,
    434 			const char *option,
    435 			const char **result, unsigned *len);
    436 #define	SASL_CB_GETOPT	1
    437 
    438 /* Logging levels for use with the logging callback function. */
    439 #define	SASL_LOG_NONE  0	/* don't log anything */
    440 #define	SASL_LOG_ERR   1	/* log unusual errors (default) */
    441 #define	SASL_LOG_FAIL  2	/* log all authentication failures */
    442 #define	SASL_LOG_WARN  3	/* log non-fatal warnings */
    443 #define	SASL_LOG_NOTE  4	/* more verbose than LOG_WARN */
    444 #define	SASL_LOG_DEBUG 5	/* more verbose than LOG_NOTE */
    445 #define	SASL_LOG_TRACE 6	/* traces of internal protocols */
    446 #define	SASL_LOG_PASS  7	/* traces of internal protocols, including */
    447 				/* passwords */
    448 
    449 /*
    450  * logging callback -- this allows plugins and the middleware to
    451  *  log operations they perform.
    452  * inputs:
    453  *  context     -- logging context from the callback record
    454  *  level       -- logging level; see above
    455  *  message     -- message to log
    456  * returns:
    457  *  SASL_OK     -- no error
    458  *  SASL_FAIL   -- error
    459  */
    460 typedef int sasl_log_t(void *context,
    461 			int level,
    462 			const char *message);
    463 #define	SASL_CB_LOG	    2
    464 
    465 /*
    466  * getpath callback -- this allows applications to specify the
    467  * colon-separated path to search for plugins (by default,
    468  * taken from an implementation-specific location).
    469  * inputs:
    470  *  context     -- getpath context from the callback record
    471  * outputs:
    472  *  path	-- colon seperated path
    473  * returns:
    474  *  SASL_OK     -- no error
    475  *  SASL_FAIL   -- error
    476  */
    477 typedef int sasl_getpath_t(void *context,
    478 			    const char **path);
    479 
    480 #define	SASL_CB_GETPATH	    3
    481 
    482 /* Callback to get the location of the sasl config  */
    483 #define	SASL_CB_GETCONF	    0x5001
    484 
    485 /*
    486  * verify file callback -- this allows applications to check if they
    487  * want SASL to use files, file by file.  This is intended to allow
    488  * applications to sanity check the environment to make sure plugins
    489  * or the configuration file can't be written to, etc.
    490  * inputs:
    491  *  context     -- verifypath context from the callback record
    492  *  file        -- full path to file to verify
    493  *  type        -- type of file to verify (see below)
    494  *
    495  * returns:
    496  *  SASL_OK        -- no error (file can safely be used)
    497  *  SASL_CONTINUE  -- continue WITHOUT using this file
    498  *  SASL_FAIL      -- error
    499  */
    500 
    501 /* these are the types of files libsasl will ask about */
    502 typedef enum {
    503     SASL_VRFY_PLUGIN = 0,	/* a DLL/shared library plug-in */
    504     SASL_VRFY_CONF = 1,		/* a configuration file */
    505     SASL_VRFY_PASSWD = 2,	/* a password storage file/db */
    506     SASL_VRFY_OTHER = 3		/* some other file */
    507 } sasl_verify_type_t;
    508 
    509 typedef int sasl_verifyfile_t(void *context,
    510 			    const char *file, sasl_verify_type_t type);
    511 #define	SASL_CB_VERIFYFILE  4
    512 
    513 
    514 /* client/user interaction callbacks: */
    515 /*
    516  * Simple prompt -- result must persist until next call to getsimple on
    517  *  same connection or until connection context is disposed
    518  * inputs:
    519  *  context       -- context from callback structure
    520  *  id            -- callback id
    521  * outputs:
    522  *  result        -- set to NUL terminated string
    523  *                   NULL = user cancel
    524  *  len           -- length of result
    525  * returns SASL_OK
    526  */
    527 typedef int sasl_getsimple_t(void *context, int id,
    528 			    const char **result, unsigned *len);
    529 #define	SASL_CB_USER		0x4001	/* client user identity to login as */
    530 #define	SASL_CB_AUTHNAME	0x4002	/* client authentication name */
    531 #define	SASL_CB_LANGUAGE	0x4003
    532 					/*
    533 					 * comma separated list of RFC 1766
    534 					 * language codes in order of preference
    535 					 * to be used to localize client prompts
    536 					 * or server error codes
    537 					 */
    538 #define	SASL_CB_CNONCE		0x4007
    539 	/* caller supplies client-nonce primarily for testing purposes */
    540 
    541 /*
    542  * get a sasl_secret_t (plaintext password with length)
    543  * inputs:
    544  *  conn          -- connection context
    545  *  context       -- context from callback structure
    546  *  id            -- callback id
    547  * outputs:
    548  *  psecret       -- set to NULL to cancel
    549  *                   set to password structure which must persist until
    550  *                   next call to getsecret in same connection, but middleware
    551  *                   will erase password data when it's done with it.
    552  * returns SASL_OK
    553  */
    554 typedef int sasl_getsecret_t(sasl_conn_t *conn, void *context, int id,
    555 			    sasl_secret_t **psecret);
    556 #define	SASL_CB_PASS	0x4004	/* client passphrase-based secret */
    557 
    558 
    559 /*
    560  * prompt for input in response to a challenge.
    561  * input:
    562  *  context   -- context from callback structure
    563  *  id        -- callback id
    564  *  challenge -- server challenge
    565  * output:
    566  *  result    -- NUL terminated result, NULL = user cancel
    567  *  len       -- length of result
    568  * returns SASL_OK
    569  */
    570 typedef int sasl_chalprompt_t(void *context, int id,
    571 			    const char *challenge,
    572 			    const char *prompt, const char *defresult,
    573 			    const char **result, unsigned *len);
    574 #define	SASL_CB_ECHOPROMPT   0x4005 /* challenge and client enterred result */
    575 #define	SASL_CB_NOECHOPROMPT 0x4006 /* challenge and client enterred result */
    576 
    577 /*
    578  * prompt (or autoselect) the realm to do authentication in.
    579  *  may get a list of valid realms.
    580  * input:
    581  *  context     -- context from callback structure
    582  *  id          -- callback id
    583  *  availrealms -- available realms; string list; NULL terminated
    584  *                 list may be empty.
    585  * output:
    586  *  result      -- NUL terminated realm; NULL is equivalent to ""
    587  * returns SASL_OK
    588  * result must persist until the next callback
    589  */
    590 typedef int sasl_getrealm_t(void *context, int id,
    591 			    const char **availrealms,
    592 			    const char **result);
    593 #define	SASL_CB_GETREALM (0x4008) /* realm to attempt authentication in */
    594 
    595 /* server callbacks: */
    596 
    597 /*
    598  * improved callback to verify authorization;
    599  *     canonicalization now handled elsewhere
    600  *  conn           -- connection context
    601  *  requested_user -- the identity/username to authorize (NUL terminated)
    602  *  rlen           -- length of requested_user
    603  *  auth_identity  -- the identity associated with the secret (NUL terminated)
    604  *  alen           -- length of auth_identity
    605  *  default_realm  -- default user realm, as passed to sasl_server_new if
    606  *  urlen          -- length of default realm
    607  *  propctx        -- auxiliary properties
    608  * returns SASL_OK on success,
    609  *         SASL_NOAUTHZ or other SASL response on failure
    610  */
    611 typedef int sasl_authorize_t(sasl_conn_t *conn,
    612 			    void *context,
    613 			    const char *requested_user, unsigned rlen,
    614 			    const char *auth_identity, unsigned alen,
    615 			    const char *def_realm, unsigned urlen,
    616 			    struct propctx *propctx);
    617 #define	SASL_CB_PROXY_POLICY 0x8001
    618 
    619 /*
    620  * functions for "userdb" based plugins to call to get/set passwords.
    621  * the location for the passwords is determined by the caller or middleware.
    622  * plug-ins may get passwords from other locations.
    623  */
    624 
    625 /*
    626  * callback to verify a plaintext password against the caller-supplied
    627  * user database.  This is necessary to allow additional <method>s for
    628  * encoding of the userPassword property.
    629  *  user          -- NUL terminated user name with user@realm syntax
    630  *  pass          -- password to check (may not be NUL terminated)
    631  *  passlen       -- length of password to check
    632  *  propctx       -- auxiliary properties for user
    633  */
    634 typedef int sasl_server_userdb_checkpass_t(sasl_conn_t *conn,
    635 					    void *context,
    636 					    const char *user,
    637 					    const char *pass,
    638 					    unsigned passlen,
    639 					    struct propctx *propctx);
    640 #define	SASL_CB_SERVER_USERDB_CHECKPASS (0x8005)
    641 
    642 /*
    643  * callback to store/change a plaintext password in the user database
    644  *  user          -- NUL terminated user name with user@realm syntax
    645  *  pass          -- password to store (may not be NUL terminated)
    646  *  passlen       -- length of password to store
    647  *  propctx       -- auxiliary properties (not stored)
    648  *  flags         -- see SASL_SET_* flags below (SASL_SET_CREATE optional)
    649  */
    650 typedef int sasl_server_userdb_setpass_t(sasl_conn_t *conn,
    651 					void *context,
    652 					const char *user,
    653 					const char *pass,
    654 					unsigned passlen,
    655 					struct propctx *propctx,
    656 					unsigned flags);
    657 #define	SASL_CB_SERVER_USERDB_SETPASS (0x8006)
    658 
    659 /*
    660  * callback for a server-supplied user canonicalization function.
    661  *
    662  * This function is called directly after the mechanism has the
    663  * authentication and authorization IDs.  It is called before any
    664  * User Canonicalization plugin is called.  It has the responsibility
    665  * of copying its output into the provided output buffers.
    666  *
    667  *  in, inlen     -- user name to canonicalize, may not be NUL terminated
    668  *                   may be same buffer as out
    669  *  flags         -- not currently used, supplied by auth mechanism
    670  *  user_realm    -- the user realm (may be NULL in case of client)
    671  *  out           -- buffer to copy user name
    672  *  out_max       -- max length of user name
    673  *  out_len       -- set to length of user name
    674  *
    675  * returns
    676  *  SASL_OK         on success
    677  *  SASL_BADPROT    username contains invalid character
    678  */
    679 
    680 /* User Canonicalization Function Flags */
    681 
    682 #define	SASL_CU_NONE    0x00 /* Not a valid flag to pass */
    683 /* One of the following two is required */
    684 #define	SASL_CU_AUTHID  0x01
    685 #define	SASL_CU_AUTHZID 0x02
    686 
    687 typedef int sasl_canon_user_t(sasl_conn_t *conn,
    688 			    void *context,
    689 			    const char *in, unsigned inlen,
    690 			    unsigned flags,
    691 			    const char *user_realm,
    692 			    char *out,
    693 			    unsigned out_max, unsigned *out_len);
    694 
    695 #define	SASL_CB_CANON_USER (0x8007)
    696 
    697 /*
    698  * Common Client/server functions
    699  */
    700 
    701 /*
    702  * get sasl library version information
    703  * implementation is a vendor-defined string
    704  * version is a vender-defined representation of the version #
    705  */
    706 LIBSASL_API void sasl_version(const char **implementation,
    707 			    int *version);
    708 
    709 /*
    710  * dispose of all SASL plugins.  Connection
    711  * states have to be disposed of before calling this.
    712  */
    713 LIBSASL_API void sasl_done(void);
    714 
    715 /*
    716  * dispose connection state, sets it to NULL
    717  *  checks for pointer to NULL
    718  */
    719 LIBSASL_API void sasl_dispose(sasl_conn_t **pconn);
    720 
    721 /*
    722  * translate an error number into a string
    723  * input:
    724  *  saslerr  -- the error number
    725  *  langlist -- comma separated list of RFC 1766 languages (may be NULL)
    726  * results:
    727  *  outlang  -- the language actually used (may be NULL if don't care)
    728  * returns:
    729  *  the error message in UTF-8 (only the US-ASCII subset if langlist is NULL)
    730  */
    731 LIBSASL_API const char *sasl_errstring(int saslerr,
    732 					const char *langlist,
    733 					const char **outlang);
    734 
    735 /*
    736  * get detail about the last error that occurred on a connection
    737  * text is sanitized so it's suitable to send over the wire
    738  * (e.g., no distinction between SASL_BADAUTH and SASL_NOUSER)
    739  * input:
    740  *  conn          -- mandatory connection context
    741  * returns:
    742  *  the error message in UTF-8 (only the US-ASCII subset permitted if no
    743  *  SASL_CB_LANGUAGE callback is present)
    744  */
    745 LIBSASL_API const char *sasl_errdetail(sasl_conn_t *conn);
    746 
    747 /*
    748  * set the error string which will be returned by sasl_errdetail() using
    749  *  syslog()-style formatting (e.g. printf-style with %m as most recent
    750  *  errno error)
    751  *
    752  *  primarily for use by server callbacks such as the sasl_authorize_t
    753  *  callback and internally to plug-ins
    754  *
    755  * This will also trigger a call to the SASL logging callback (if any)
    756  * with a level of SASL_LOG_FAIL unless the SASL_NOLOG flag is set.
    757  *
    758  * Messages should be sensitive to the current language setting.  If there
    759  * is no SASL_CB_LANGUAGE callback messages MUST be US-ASCII otherwise UTF-8
    760  * is used and use of RFC 2482 for mixed-language text is encouraged.
    761  *
    762  * if conn is NULL, function does nothing
    763  */
    764 LIBSASL_API void sasl_seterror(sasl_conn_t *conn, unsigned flags,
    765 				const char *fmt, ...);
    766 #define	SASL_NOLOG	0x01
    767 
    768 /*
    769  * get property from SASL connection state
    770  *  propnum       -- property number
    771  *  pvalue        -- pointer to value
    772  * returns:
    773  *  SASL_OK       -- no error
    774  *  SASL_NOTDONE  -- property not available yet
    775  *  SASL_BADPARAM -- bad property number
    776  */
    777 LIBSASL_API int sasl_getprop(sasl_conn_t *conn, int propnum,
    778 			    const void **pvalue);
    779 #define	SASL_USERNAME	0	/* pointer to NUL terminated user name */
    780 #define	SASL_SSF	1	/* security layer security strength factor, */
    781 				/* if 0, call to sasl_encode, sasl_decode */
    782 				/* unnecessary */
    783 #define	SASL_MAXOUTBUF	2	/* security layer max output buf unsigned */
    784 #define	SASL_DEFUSERREALM 3	/* default realm passed to server_new */
    785 				/* or set with setprop */
    786 #define	SASL_GETOPTCTX	4	/* context for getopt callback */
    787 #define	SASL_CALLBACK	7	/* current callback function list */
    788 #define	SASL_IPLOCALPORT 8	/* iplocalport string passed to server_new */
    789 #define	SASL_IPREMOTEPORT 9	/* ipremoteport string passed to server_new */
    790 #define	SASL_SERVICE	12	/* service passed to sasl_*_new */
    791 #define	SASL_SERVERFQDN	13	/* serverFQDN passed to sasl_*_new */
    792 #define	SASL_AUTHSOURCE   14	/* name of auth source last used, useful */
    793 				/* for failed authentication tracking */
    794 #define	SASL_MECHNAME	15	/* active mechanism name, if any */
    795 #define	SASL_AUTHUSER	16	/* authentication/admin user */
    796 
    797 /*
    798  * This returns a string which is either empty or has an error message
    799  * from sasl_seterror (e.g., from a plug-in or callback).  It differs
    800  * from the result of sasl_errdetail() which also takes into account the
    801  * last return status code.
    802  */
    803 #define	SASL_PLUGERR	10
    804 
    805 /*
    806  * set property in SASL connection state
    807  * returns:
    808  *  SASL_OK       -- value set
    809  *  SASL_BADPARAM -- invalid property or value
    810  */
    811 LIBSASL_API int sasl_setprop(sasl_conn_t *conn,
    812 			    int propnum,
    813 			    const void *value);
    814 #define	SASL_SSF_EXTERNAL  100	/* external SSF active (sasl_ssf_t *) */
    815 #define	SASL_SEC_PROPS	   101	/* sasl_security_properties_t */
    816 #define	SASL_AUTH_EXTERNAL 102	/* external authentication ID (const char *) */
    817 
    818 /*
    819  * If the SASL_AUTH_EXTERNAL value is non-NULL, then a special version of the
    820  * EXTERNAL mechanism is enabled (one for server-embedded EXTERNAL mechanisms).
    821  * Otherwise, the EXTERNAL mechanism will be absent unless a plug-in
    822  * including EXTERNAL is present.
    823  */
    824 
    825 /*
    826  * do precalculations during an idle period or network round trip
    827  *  may pass NULL to precompute for some mechanisms prior to connect
    828  *  returns 1 if action taken, 0 if no action taken
    829  */
    830 LIBSASL_API int sasl_idle(sasl_conn_t *conn);
    831 
    832 /*
    833  * Client API
    834  */
    835 
    836 /*
    837  * list of client interactions with user for caller to fill in
    838  */
    839 typedef struct sasl_interact {
    840     unsigned long id;		/* same as client/user callback ID */
    841     const char *challenge;	/* presented to user (e.g. OTP challenge) */
    842     const char *prompt;		/* presented to user (e.g. "Username: ") */
    843     const char *defresult;	/* default result string */
    844     const void *result;		/* set to point to result */
    845     unsigned len;		/* set to length of result */
    846 } sasl_interact_t;
    847 
    848 /*
    849  * initialize the SASL client drivers
    850  *  callbacks      -- base callbacks for all client connections;
    851  *                    must include getopt callback
    852  * returns:
    853  *  SASL_OK        -- Success
    854  *  SASL_NOMEM     -- Not enough memory
    855  *  SASL_BADVERS   -- Mechanism version mismatch
    856  *  SASL_BADPARAM  -- missing getopt callback or error in config file
    857  *  SASL_NOMECH    -- No mechanisms available
    858  *  ...
    859  */
    860 LIBSASL_API int sasl_client_init(const sasl_callback_t *callbacks);
    861 
    862 /*
    863  * initialize a client exchange based on the specified mechanism
    864  *  service       -- registered name of the service using SASL (e.g. "imap")
    865  *  serverFQDN    -- the fully qualified domain name of the server
    866  *  iplocalport   -- client IPv4/IPv6 domain literal string with port
    867  *                    (if NULL, then mechanisms requiring IPaddr are disabled)
    868  *  ipremoteport  -- server IPv4/IPv6 domain literal string with port
    869  *                    (if NULL, then mechanisms requiring IPaddr are disabled)
    870  *  prompt_supp   -- list of client interactions supported
    871  *                   may also include sasl_getopt_t context & call
    872  *                   NULL prompt_supp = user/pass via SASL_INTERACT only
    873  *                   NULL proc = interaction supported via SASL_INTERACT
    874  *  flags         -- server usage flags (see above)
    875  * out:
    876  *  pconn         -- sasl connection
    877  *
    878  * Returns:
    879  *  SASL_OK       -- success
    880  *  SASL_NOMECH   -- no mechanism meets requested properties
    881  *  SASL_NOMEM    -- not enough memory
    882  */
    883 LIBSASL_API int sasl_client_new(const char *service,
    884 				const char *serverFQDN,
    885 				const char *iplocalport,
    886 				const char *ipremoteport,
    887 				const sasl_callback_t *prompt_supp,
    888 				unsigned flags,
    889 				sasl_conn_t **pconn);
    890 
    891 /*
    892  * select a mechanism for a connection
    893  *  mechlist      -- list of mechanisms to use (punctuation ignored)
    894  * output:
    895  *  prompt_need   -- on SASL_INTERACT, list of prompts needed to continue
    896  *                   may be NULL if callbacks provided
    897  *  clientout     -- the initial client response to send to the server
    898  *                   will be valid until next call to client_start/client_step
    899  *                   NULL if mech doesn't include initial client challenge
    900  *  mech          -- set to mechansm name of selected mechanism (may be NULL)
    901  *
    902  * Returns:
    903  *  SASL_OK       -- success
    904  *  SASL_NOMEM    -- not enough memory
    905  *  SASL_NOMECH   -- no mechanism meets requested properties
    906  *  SASL_INTERACT -- user interaction needed to fill in prompt_need list
    907  */
    908 LIBSASL_API int sasl_client_start(sasl_conn_t *conn,
    909 				const char *mechlist,
    910 				sasl_interact_t **prompt_need,
    911 				const char **clientout,
    912 				unsigned *clientoutlen,
    913 				const char **mech);
    914 
    915 /*
    916  * do a single authentication step.
    917  *  serverin    -- the server message received by the client, MUST have a NUL
    918  *                 sentinel, not counted by serverinlen
    919  * output:
    920  *  prompt_need -- on SASL_INTERACT, list of prompts needed to continue
    921  *  clientout   -- the client response to send to the server
    922  *                 will be valid until next call to client_start/client_step
    923  *
    924  * returns:
    925  *  SASL_OK        -- success
    926  *  SASL_INTERACT  -- user interaction needed to fill in prompt_need list
    927  *  SASL_BADPROT   -- server protocol incorrect/cancelled
    928  *  SASL_BADSERV   -- server failed mutual auth
    929  */
    930 LIBSASL_API int sasl_client_step(sasl_conn_t *conn,
    931 				const char *serverin,
    932 				unsigned serverinlen,
    933 				sasl_interact_t **prompt_need,
    934 				const char **clientout,
    935 				unsigned *clientoutlen);
    936 
    937 /*
    938  * Server API
    939  */
    940 
    941 /*
    942  * initialize server drivers, done once per process
    943  *  callbacks      -- callbacks for all server connections; must include
    944  *                    getopt callback
    945  *  appname        -- name of calling application (for lower level logging)
    946  * results:
    947  *  state          -- server state
    948  * returns:
    949  *  SASL_OK        -- success
    950  *  SASL_BADPARAM  -- error in config file
    951  *  SASL_NOMEM     -- memory failure
    952  *  SASL_BADVERS   -- Mechanism version mismatch
    953  */
    954 LIBSASL_API int sasl_server_init(const sasl_callback_t *callbacks,
    955 				const char *appname);
    956 
    957 /*
    958  * IP/port syntax:
    959  *  a.b.c.d:p                where a-d are 0-255 and p is 0-65535 port number.
    960  *  [e:f:g:h:i:j:k:l]:p      where e-l are 0000-ffff lower-case hexidecimal
    961  *  [e:f:g:h:i:j:a.b.c.d]:p  alternate syntax for previous
    962  *
    963  *  Note that one or more "0" fields in f-k can be replaced with "::"
    964  *  Thus:                 [e:f:0000:0000:0000:j:k:l]:p
    965  *  can be abbreviated:   [e:f::j:k:l]:p
    966  *
    967  * A buffer of size 52 is adequate for the longest format with NUL terminator.
    968  */
    969 
    970 /*
    971  * create context for a single SASL connection
    972  *  service        -- registered name of the service using SASL (e.g. "imap")
    973  *  serverFQDN     -- Fully qualified domain name of server.  NULL means use
    974  *                    gethostname() or equivalent.
    975  *                    Useful for multi-homed servers.
    976  *  user_realm     -- permits multiple user realms on server, NULL = default
    977  *  iplocalport    -- server IPv4/IPv6 domain literal string with port
    978  *                    (if NULL, then mechanisms requiring IPaddr are disabled)
    979  *  ipremoteport   -- client IPv4/IPv6 domain literal string with port
    980  *                    (if NULL, then mechanisms requiring IPaddr are disabled)
    981  *  callbacks      -- callbacks (e.g., authorization, lang, new getopt context)
    982  *  flags          -- usage flags (see above)
    983  * returns:
    984  *  pconn          -- new connection context
    985  *
    986  * returns:
    987  *  SASL_OK        -- success
    988  *  SASL_NOMEM     -- not enough memory
    989  */
    990 LIBSASL_API int sasl_server_new(const char *service,
    991 				const char *serverFQDN,
    992 				const char *user_realm,
    993 				const char *iplocalport,
    994 				const char *ipremoteport,
    995 				const sasl_callback_t *callbacks,
    996 				unsigned flags,
    997 				sasl_conn_t **pconn);
    998 
    999 /* The following function is obsolete */
   1000 /*
   1001  * Return an array of NUL-terminated strings, terminated by a NULL pointer,
   1002  * which lists all possible mechanisms that the library can supply
   1003  *
   1004  * Returns NULL on failure.
   1005  */
   1006 LIBSASL_API const char ** sasl_global_listmech(void);
   1007 
   1008 /*
   1009  * This returns a list of mechanisms in a NUL-terminated string
   1010  *  conn          -- the connection to list mechanisms for (either client
   1011  *                   or server)
   1012  *  user          -- restricts mechanisms to those available to that user
   1013  *                   (may be NULL, not used for client case)
   1014  *  prefix        -- appended to beginning of result
   1015  *  sep           -- appended between mechanisms
   1016  *  suffix        -- appended to end of result
   1017  * results:
   1018  *  result        -- NUL terminated result which persists until next
   1019  *                   call to sasl_listmech for this sasl_conn_t
   1020  *  plen          -- gets length of result (excluding NUL), may be NULL
   1021  *  pcount        -- gets number of mechanisms, may be NULL
   1022  *
   1023  * returns:
   1024  *  SASL_OK        -- success
   1025  *  SASL_NOMEM     -- not enough memory
   1026  *  SASL_NOMECH    -- no enabled mechanisms
   1027  */
   1028 LIBSASL_API int sasl_listmech(sasl_conn_t *conn,
   1029 			    const char *user,
   1030 			    const char *prefix,
   1031 			    const char *sep,
   1032 			    const char *suffix,
   1033 			    const char **result,
   1034 			    unsigned *plen,
   1035 			    int *pcount);
   1036 
   1037 /*
   1038  * start a mechanism exchange within a connection context
   1039  *  mech           -- the mechanism name client requested
   1040  *  clientin       -- client initial response (NUL terminated), NULL if empty
   1041  *  clientinlen    -- length of initial response
   1042  *  serverout      -- initial server challenge, NULL if done
   1043  *                    (library handles freeing this string)
   1044  *  serveroutlen   -- length of initial server challenge
   1045  * output:
   1046  *  pconn          -- the connection negotiation state on success
   1047  *
   1048  * Same returns as sasl_server_step() or
   1049  * SASL_NOMECH if mechanism not available.
   1050  */
   1051 LIBSASL_API int sasl_server_start(sasl_conn_t *conn,
   1052 				const char *mech,
   1053 				const char *clientin,
   1054 				unsigned clientinlen,
   1055 				const char **serverout,
   1056 				unsigned *serveroutlen);
   1057 
   1058 /*
   1059  * perform one step of the SASL exchange
   1060  *  inputlen & input -- client data
   1061  *                      NULL on first step if no optional client step
   1062  *  outputlen & output -- set to the server data to transmit
   1063  *                        to the client in the next step
   1064  *                        (library handles freeing this)
   1065  *
   1066  * returns:
   1067  *  SASL_OK        -- exchange is complete.
   1068  *  SASL_CONTINUE  -- indicates another step is necessary.
   1069  *  SASL_TRANS     -- entry for user exists, but not for mechanism
   1070  *                    and transition is possible
   1071  *  SASL_BADPARAM  -- service name needed
   1072  *  SASL_BADPROT   -- invalid input from client
   1073  *  ...
   1074  */
   1075 LIBSASL_API int sasl_server_step(sasl_conn_t *conn,
   1076 				const char *clientin,
   1077 				unsigned clientinlen,
   1078 				const char **serverout,
   1079 				unsigned *serveroutlen);
   1080 
   1081 /* The following function is obsolete */
   1082 /*
   1083  * check if an apop exchange is valid
   1084  *  (note this is an optional part of the SASL API)
   1085  *  if challenge is NULL, just check if APOP is enabled
   1086  * inputs:
   1087  *  challenge     -- challenge which was sent to client
   1088  *  challen       -- length of challenge, 0 = strlen(challenge)
   1089  *  response      -- client response, "<user> <digest>" (RFC 1939)
   1090  *  resplen       -- length of response, 0 = strlen(response)
   1091  * returns
   1092  *  SASL_OK       -- success
   1093  *  SASL_BADAUTH  -- authentication failed
   1094  *  SASL_BADPARAM -- missing challenge
   1095  *  SASL_BADPROT  -- protocol error (e.g., response in wrong format)
   1096  *  SASL_NOVERIFY -- user found, but no verifier
   1097  *  SASL_NOMECH   -- mechanism not supported
   1098  *  SASL_NOUSER   -- user not found
   1099  */
   1100 LIBSASL_API int sasl_checkapop(sasl_conn_t *conn,
   1101 				const char *challenge, unsigned challen,
   1102 				const char *response, unsigned resplen);
   1103 
   1104 /*
   1105  * check if a plaintext password is valid
   1106  *   if user is NULL, check if plaintext passwords are enabled
   1107  * inputs:
   1108  *  user          -- user to query in current user_domain
   1109  *  userlen       -- length of username, 0 = strlen(user)
   1110  *  pass          -- plaintext password to check
   1111  *  passlen       -- length of password, 0 = strlen(pass)
   1112  * returns
   1113  *  SASL_OK       -- success
   1114  *  SASL_NOMECH   -- mechanism not supported
   1115  *  SASL_NOVERIFY -- user found, but no verifier
   1116  *  SASL_NOUSER   -- user not found
   1117  */
   1118 LIBSASL_API int sasl_checkpass(sasl_conn_t *conn,
   1119 				const char *user, unsigned userlen,
   1120 				const char *pass, unsigned passlen);
   1121 
   1122 /*
   1123  * check if a user exists on server
   1124  *  conn          -- connection context
   1125  *  service       -- registered name of the service using SASL (e.g. "imap")
   1126  *  user_realm    -- permits multiple user realms on server, NULL = default
   1127  *  user          -- NUL terminated user name
   1128  *
   1129  * returns:
   1130  *  SASL_OK       -- success
   1131  *  SASL_DISABLED -- account disabled
   1132  *  SASL_NOUSER   -- user not found
   1133  *  SASL_NOVERIFY -- user found, but no usable mechanism
   1134  *  SASL_NOMECH   -- no mechanisms enabled
   1135  */
   1136 LIBSASL_API int sasl_user_exists(sasl_conn_t *conn,
   1137 				const char *service,
   1138 				const char *user_realm,
   1139 				const char *user);
   1140 
   1141 /*
   1142  * set the password for a user
   1143  *  conn        -- SASL connection
   1144  *  user        -- user name
   1145  *  pass        -- plaintext password, may be NULL to remove user
   1146  *  passlen     -- length of password, 0 = strlen(pass)
   1147  *  oldpass     -- NULL will sometimes work
   1148  *  oldpasslen  -- length of password, 0 = strlen(oldpass)
   1149  *  flags       -- see flags below
   1150  *
   1151  * returns:
   1152  *  SASL_NOCHANGE  -- proper entry already exists
   1153  *  SASL_NOMECH    -- no authdb supports password setting as configured
   1154  *  SASL_NOVERIFY  -- user exists, but no settable password present
   1155  *  SASL_DISABLED  -- account disabled
   1156  *  SASL_PWLOCK    -- password locked
   1157  *  SASL_WEAKPASS  -- password too weak for security policy
   1158  *  SASL_NOUSERPASS -- user-supplied passwords not permitted
   1159  *  SASL_FAIL      -- OS error
   1160  *  SASL_BADPARAM  -- password too long
   1161  *  SASL_OK        -- successful
   1162  */
   1163 LIBSASL_API int sasl_setpass(sasl_conn_t *conn,
   1164 			    const char *user,
   1165 			    const char *pass, unsigned passlen,
   1166 			    const char *oldpass, unsigned oldpasslen,
   1167 			    unsigned flags);
   1168 #define	SASL_SET_CREATE  0x01   /* create a new entry for user */
   1169 #define	SASL_SET_REMOVE  SASL_SET_CREATE /* remove user if pass is NULL */
   1170 #define	SASL_SET_DISABLE 0x02	/* disable user account */
   1171 
   1172 /*
   1173  * Auxiliary Property Support -- added by cjn 1999-09-29
   1174  */
   1175 
   1176 #define	SASL_AUX_END	NULL	/* last auxiliary property */
   1177 
   1178 /* traditional Posix items (should be implemented on Posix systems) */
   1179 #define	SASL_AUX_PASSWORD "*userPassword" /* User Password (of authid) */
   1180 #define	SASL_AUX_UIDNUM   "uidNumber"	/* UID number for the user */
   1181 #define	SASL_AUX_GIDNUM   "gidNumber"	/* GID for the user */
   1182 #define	SASL_AUX_FULLNAME "gecos"	/* full name of the user, unix-style */
   1183 #define	SASL_AUX_HOMEDIR  "homeDirectory" /* home directory for user */
   1184 #define	SASL_AUX_SHELL    "loginShell"	/* login shell for the user */
   1185 
   1186 /* optional additional items (not necessarily implemented) */
   1187 /*
   1188  * single preferred mail address for user canonically-quoted
   1189  * RFC821/822 syntax
   1190  */
   1191 #define	SASL_AUX_MAILADDR "mail"
   1192 /* path to unix-style mailbox for user */
   1193 #define	SASL_AUX_UNIXMBX  "mailMessageStore"
   1194 /* SMTP mail channel name to use if user authenticates successfully */
   1195 #define	SASL_AUX_MAILCHAN "mailSMTPSubmitChannel"
   1196 
   1197 /*
   1198  * Request a set of auxiliary properties
   1199  *  conn         connection context
   1200  *  propnames    list of auxiliary property names to request ending with
   1201  *               NULL.
   1202  *
   1203  * Subsequent calls will add items to the request list.  Call with NULL
   1204  * to clear the request list.
   1205  *
   1206  * errors
   1207  *  SASL_OK       -- success
   1208  *  SASL_BADPARAM -- bad count/conn parameter
   1209  *  SASL_NOMEM    -- out of memory
   1210  */
   1211 LIBSASL_API int sasl_auxprop_request(sasl_conn_t *conn,
   1212 				    const char **propnames);
   1213 
   1214 /*
   1215  * Returns current auxiliary property context.
   1216  * Use functions in prop.h to access content
   1217  *
   1218  *  if authentication hasn't completed, property values may be empty/NULL
   1219  *
   1220  *  properties not recognized by active plug-ins will be left empty/NULL
   1221  *
   1222  *  returns NULL if conn is invalid.
   1223  */
   1224 LIBSASL_API struct propctx *sasl_auxprop_getctx(sasl_conn_t *conn);
   1225 
   1226 /*
   1227  * security layer API
   1228  */
   1229 
   1230 /*
   1231  * encode a block of data for transmission using security layer,
   1232  *  returning the input buffer if there is no security layer.
   1233  *  output is only valid until next call to sasl_encode or sasl_encodev
   1234  * returns:
   1235  *  SASL_OK      -- success (returns input if no layer negotiated)
   1236  *  SASL_NOTDONE -- security layer negotiation not finished
   1237  *  SASL_BADPARAM -- inputlen is greater than the SASL_MAXOUTBUF
   1238  */
   1239 LIBSASL_API int sasl_encode(sasl_conn_t *conn,
   1240 			    const char *input, unsigned inputlen,
   1241 			    const char **output, unsigned *outputlen);
   1242 
   1243 /*
   1244  * encode a block of data for transmission using security layer
   1245  *  output is only valid until next call to sasl_encode or sasl_encodev
   1246  * returns:
   1247  *  SASL_OK      -- success (returns input if no layer negotiated)
   1248  *  SASL_NOTDONE -- security layer negotiation not finished
   1249  *  SASL_BADPARAM -- input length is greater than the SASL_MAXOUTBUF
   1250  *		     or no security layer
   1251  */
   1252 LIBSASL_API int sasl_encodev(sasl_conn_t *conn,
   1253 			    const struct iovec *invec, unsigned numiov,
   1254 			    const char **output, unsigned *outputlen);
   1255 
   1256 /*
   1257  * decode a block of data received using security layer
   1258  *  returning the input buffer if there is no security layer.
   1259  *  output is only valid until next call to sasl_decode
   1260  *
   1261  *  if outputlen is 0 on return, than the value of output is undefined.
   1262  *
   1263  * returns:
   1264  *  SASL_OK      -- success (returns input if no layer negotiated)
   1265  *  SASL_NOTDONE -- security layer negotiation not finished
   1266  *  SASL_BADMAC  -- bad message integrity check
   1267  */
   1268 LIBSASL_API int sasl_decode(sasl_conn_t *conn,
   1269 			    const char *input, unsigned inputlen,
   1270 			    const char **output, unsigned *outputlen);
   1271 
   1272 #ifdef	__cplusplus
   1273 }
   1274 #endif
   1275 
   1276 #endif	/* _SASL_SASL_H */
   1277