xref: /illumos-gate/usr/src/lib/libsasl/include/saslplug.h (revision 7c478bd95313f5f23a4c958a745db2134aa03244)
1 /*
2  * Copyright 2003 Sun Microsystems, Inc.  All rights reserved.
3  * Use is subject to license terms.
4  */
5 
6 /* saslplug.h --  API for SASL plug-ins */
7 
8 #ifndef	_SASL_SASLPLUG_H
9 #define	_SASL_SASLPLUG_H
10 
11 #pragma ident	"%Z%%M%	%I%	%E% SMI"
12 
13 #ifndef	_SASL_SASL_H
14 #include <sasl/sasl.h>
15 #endif
16 
17 #ifndef _MD5_H
18 #include <md5.h>
19 #endif /* _MD5_H */
20 
21 #ifdef	__cplusplus
22 extern "C" {
23 #endif
24 
25 /* intermediate MD5 context */
26 typedef struct HMAC_MD5_CTX_s {
27     MD5_CTX ictx, octx;
28 } HMAC_MD5_CTX;
29 
30 /*
31  * intermediate HMAC state
32  *  values stored in network byte order (Big Endian)
33  */
34 typedef struct HMAC_MD5_STATE_s {
35     uint32_t istate[4];
36     uint32_t ostate[4];
37 } HMAC_MD5_STATE;
38 
39 /*
40  * callback to lookup a sasl_callback_t for a connection
41  * input:
42  *  conn        -- the connection to lookup a callback for
43  *  callbacknum -- the number of the callback
44  * output:
45  *  pproc       -- pointer to the callback function (set to NULL on failure)
46  *  pcontext    -- pointer to the callback context (set to NULL on failure)
47  * returns:
48  *  SASL_OK -- no error
49  *  SASL_FAIL -- unable to find a callback of the requested type
50  *  SASL_INTERACT -- caller must use interaction to get data
51  */
52 typedef int sasl_getcallback_t(sasl_conn_t *conn,
53 				unsigned long callbackid,
54 				int (**pproc)(),
55 				void **pcontext);
56 
57 /*
58  * The sasl_utils structure will remain backwards compatible unless
59  * the SASL_*_PLUG_VERSION is changed incompatibly
60  * higher SASL_UTILS_VERSION numbers indicate more functions are available
61  */
62 #define	SASL_UTILS_VERSION 4
63 
64 /* utility function set for plug-ins */
65 typedef struct sasl_utils {
66     int version;
67 
68 	/* contexts */
69     sasl_conn_t *conn;
70     sasl_rand_t *rpool;
71     void *getopt_context;
72 
73 	/* option function */
74     sasl_getopt_t *getopt;
75 
76 	/* allocation functions: */
77     sasl_malloc_t *malloc;
78     sasl_calloc_t *calloc;
79     sasl_realloc_t *realloc;
80     sasl_free_t *free;
81 
82 	/* mutex functions: */
83     sasl_mutex_alloc_t *mutex_alloc;
84     sasl_mutex_lock_t *mutex_lock;
85     sasl_mutex_unlock_t *mutex_unlock;
86     sasl_mutex_free_t *mutex_free;
87 
88 	/* MD5 hash and HMAC functions */
89     void (*MD5Init)(MD5_CTX *);
90     void (*MD5Update)(MD5_CTX *, const unsigned char *text, unsigned int len);
91     void (*MD5Final)(unsigned char [16], MD5_CTX *);
92     void (*hmac_md5)(const unsigned char *text, int text_len,
93 			const unsigned char *key, int key_len,
94 			unsigned char [16]);
95     void (*hmac_md5_init)(HMAC_MD5_CTX *, const unsigned char *key, int len);
96 	/* hmac_md5_update() is just a call to MD5Update on inner context */
97     void (*hmac_md5_final)(unsigned char [16], HMAC_MD5_CTX *);
98     void (*hmac_md5_precalc)(HMAC_MD5_STATE *,
99 				const unsigned char *key, int len);
100     void (*hmac_md5_import)(HMAC_MD5_CTX *, HMAC_MD5_STATE *);
101 
102 	/* mechanism utility functions (same as above): */
103     int (*mkchal)(sasl_conn_t *conn, char *buf, unsigned maxlen,
104 		unsigned hostflag);
105     int (*utf8verify)(const char *str, unsigned len);
106     void (*rand)(sasl_rand_t *rpool, char *buf, unsigned len);
107     void (*churn)(sasl_rand_t *rpool, const char *data, unsigned len);
108 
109 	/*
110 	 * This allows recursive calls to the sasl_checkpass() routine from
111 	 * within a SASL plug-in.  This MUST NOT be used in the PLAIN mechanism
112 	 * as sasl_checkpass MAY be a front-end for the PLAIN mechanism.
113 	 * This is intended for use by the non-standard LOGIN mechanism and
114 	 * potentially by a future mechanism which uses public-key technology
115 	 * to set up a lightweight encryption layer just for sending a
116 	 * password.
117 	 */
118     int (*checkpass)(sasl_conn_t *conn,
119 		    const char *user, unsigned userlen,
120 		    const char *pass, unsigned passlen);
121 
122 	/* Access to base64 encode/decode routines */
123     int (*decode64)(const char *in, unsigned inlen,
124 		    char *out, unsigned outmax, unsigned *outlen);
125     int (*encode64)(const char *in, unsigned inlen,
126 		    char *out, unsigned outmax, unsigned *outlen);
127 
128 	/* erase a buffer */
129     void (*erasebuffer)(char *buf, unsigned len);
130 
131 	/* callback to sasl_getprop() and sasl_setprop() */
132     int (*getprop)(sasl_conn_t *conn, int propnum, const void **pvalue);
133     int (*setprop)(sasl_conn_t *conn, int propnum, const void *value);
134 
135 	/* callback function */
136     sasl_getcallback_t *getcallback;
137 
138 	/*
139 	 * format a message and then pass it to the SASL_CB_LOG callback
140 	 *
141 	 * use syslog()-style formatting (printf with %m as most recent errno
142 	 * error).  The implementation may use a fixed size buffer not smaller
143 	 * than 512 octets if it securely truncates the message.
144 	 *
145 	 * level is a SASL_LOG_* level (see sasl.h)
146 	 */
147     void (*log)(sasl_conn_t *conn, int level, const char *fmt, ...);
148 
149 	/* callback to sasl_seterror() */
150     void (*seterror)(sasl_conn_t *conn, unsigned flags, const char *fmt, ...);
151 
152 	/* spare function pointer */
153     int *(*spare_fptr)();
154 
155 	/* auxiliary property utilities */
156     struct propctx *(*prop_new)(unsigned estimate);
157     int (*prop_dup)(struct propctx *src_ctx, struct propctx **dst_ctx);
158     int (*prop_request)(struct propctx *ctx, const char **names);
159     const struct propval *(*prop_get)(struct propctx *ctx);
160     int (*prop_getnames)(struct propctx *ctx, const char **names,
161 			struct propval *vals);
162     void (*prop_clear)(struct propctx *ctx, int requests);
163     void (*prop_dispose)(struct propctx **ctx);
164     int (*prop_format)(struct propctx *ctx, const char *sep, int seplen,
165 		    char *outbuf, unsigned outmax, unsigned *outlen);
166     int (*prop_set)(struct propctx *ctx, const char *name,
167 		    const char *value, int vallen);
168     int (*prop_setvals)(struct propctx *ctx, const char *name,
169 			const char **values);
170     void (*prop_erase)(struct propctx *ctx, const char *name);
171 
172 	/* for additions which don't require a version upgrade; set to 0 */
173     int (*spare_fptr1)();
174     int (*spare_fptr2)();
175     int (*spare_fptr3)();
176 } sasl_utils_t;
177 
178 /*
179  * output parameters from SASL API
180  *
181  * created / destroyed by the glue code, though probably filled in
182  * by a combination of the plugin, the glue code, and the canon_user callback.
183  *
184  */
185 typedef struct sasl_out_params {
186     unsigned doneflag;		/* exchange complete */
187 
188     const char *user;		/* canonicalized user name */
189     const char *authid;		/* canonicalized authentication id */
190 
191     unsigned ulen;		/* length of canonicalized user name */
192     unsigned alen;		/* length of canonicalized authid */
193 
194 	/* security layer information */
195     unsigned maxoutbuf;
196     sasl_ssf_t mech_ssf;    /* Should be set non-zero if negotiation of a */
197 			    /* security layer was *attempted*, even if */
198 			    /* the negotiation failed */
199     void *encode_context;
200     int (*encode)(void *context, const struct iovec *invec, unsigned numiov,
201 		const char **output, unsigned *outputlen);
202     void *decode_context;
203     int (*decode)(void *context, const char *input, unsigned inputlen,
204 		const char **output, unsigned *outputlen);
205 
206 	/* for additions which don't require a version upgrade; set to 0 */
207     void *spare_ptr1;
208     void *spare_ptr2;
209     void *spare_ptr3;
210     void *spare_ptr4;
211     int (*spare_fptr1)();
212     int (*spare_fptr2)();
213     int spare_int1;
214     int spare_int2;
215     int spare_int3;
216     int spare_int4;
217 
218 	/*
219 	 * set to 0 initially, this allows a plugin with extended parameters
220 	 * to work with an older framework by updating version as parameters
221 	 * are added.
222 	 */
223     int param_version;
224 } sasl_out_params_t;
225 
226 /*
227  * Client Mechanism Functions
228  */
229 
230 /*
231  * input parameters to client SASL plugin
232  *
233  * created / destroyed by the glue code
234  *
235  */
236 typedef struct sasl_client_params {
237     const char *service;	/* service name */
238     const char *serverFQDN;	/* server fully qualified domain name */
239     const char *clientFQDN;	/* client's fully qualified domain name */
240     const sasl_utils_t *utils;	/* SASL API utility routines -- */
241 				/* for a particular sasl_conn_t, */
242 				/* MUST remain valid until mech_free is */
243 				/* called */
244     const sasl_callback_t *prompt_supp; /* client callback list */
245     const char *iplocalport;	/* server IP domain literal & port */
246     const char *ipremoteport;	/* client IP domain literal & port */
247 
248     unsigned servicelen;	/* length of service */
249     unsigned slen;		/* length of serverFQDN */
250     unsigned clen;		/* length of clientFQDN */
251     unsigned iploclen;		/* length of iplocalport */
252     unsigned ipremlen;		/* length of ipremoteport */
253 
254 	/* application's security requirements & info */
255     sasl_security_properties_t props;
256     sasl_ssf_t external_ssf;	/* external SSF active */
257 
258 	/* for additions which don't require a version upgrade; set to 0 */
259     void *spare_ptr1;
260     void *spare_ptr2;
261     void *spare_ptr3;
262     void *spare_ptr4;
263 
264 	/*
265 	 * Canonicalize a user name from on-wire to internal format
266 	 *  added rjs3 2001-05-23
267 	 *  Must be called once user name aquired if canon_user is non-NULL.
268 	 *  conn    connection context
269 	 *  in	    user name from wire protocol (need not be NUL terminated)
270 	 *  len	    length of user name from wire protocol (0 = strlen(user))
271 	 *  flags   for SASL_CU_* flags
272 	 *  oparams the user, authid, ulen, alen, fields are
273 	 *	    set appropriately after canonicalization/copying and
274 	 *	    authorization of arguments
275 	 *
276 	 *  responsible for setting user, ulen, authid, and alen in the oparams
277 	 *  structure
278 	 *
279 	 *  default behavior is to strip leading and trailing whitespace, as
280 	 *  well as allocating space for and copying the parameters.
281 	 *
282 	 * results:
283 	 *  SASL_OK	  -- success
284 	 *  SASL_NOMEM    -- out of memory
285 	 *  SASL_BADPARAM -- invalid conn
286 	 *  SASL_BADPROT  -- invalid user/authid
287 	 */
288     int (*canon_user)(sasl_conn_t *conn,
289 		    const char *in, unsigned len,
290 		    unsigned flags,
291 		    sasl_out_params_t *oparams);
292 
293     int (*spare_fptr1)();
294 
295     int spare_int1;
296     int spare_int2;
297     int spare_int3;
298 
299 	/* flags field as passed to sasl_client_new */
300     unsigned flags;
301 
302 	/*
303 	 * set to 0 initially, this allows a plugin with extended parameters
304 	 * to work with an older framework by updating version as parameters
305 	 * are added.
306 	 */
307     int param_version;
308 } sasl_client_params_t;
309 
310 /* features shared between client and server */
311 /* These allow the glue code to handle client-first and server-last issues */
312 
313 /*
314  * This indicates that the mechanism prefers to do client-send-first
315  * if the protocol allows it.
316  */
317 #define	SASL_FEAT_WANT_CLIENT_FIRST 0x0002
318 
319 /*
320  * This feature is deprecated, instead, plugins should set *serverout to
321  * non-NULL and return SASL_OK intelligently to allow flexible use of
322  * server-last semantics
323  */
324 /* #define	SASL_FEAT_WANT_SERVER_LAST 0x0004 */
325 
326 /*
327  * This feature is deprecated, instead plugins should correctly set
328  * SASL_FEAT_SERVER_FIRST as needed
329  */
330 /* #define	SASL_FEAT_INTERNAL_CLIENT_FIRST 0x0008 */
331 
332 /*
333  * This indicates that the plugin is server-first only.
334  * Not defining either of SASL_FEAT_SERVER_FIRST or
335  * SASL_FEAT_WANT_CLIENT_FIRST indicates that the mechanism will take care
336  * of the client-first situation internally.
337  */
338 #define	SASL_FEAT_SERVER_FIRST 0x0010
339 
340 /* This plugin allows proxying */
341 #define	SASL_FEAT_ALLOWS_PROXY 0x0020
342 
343 /* client plug-in features */
344 #define	SASL_FEAT_NEEDSERVERFQDN 0x0001
345 
346 /* a C object for a client mechanism */
347 typedef struct sasl_client_plug {
348 	/* mechanism name */
349     const char *mech_name;
350 
351 	/* best mech additional security layer strength factor */
352     sasl_ssf_t max_ssf;
353 
354 	/* best security flags, as defined in sasl_security_properties_t */
355     unsigned security_flags;
356 
357 	/* features of plugin */
358     unsigned features;
359 
360 	/* required prompt ids, NULL = user/pass only */
361     const unsigned long *required_prompts;
362 
363 	/* global state for mechanism */
364     void *glob_context;
365 
366 	/*
367 	 * create context for mechanism, using params supplied
368 	 *  glob_context   -- from above
369 	 *  params	   -- params from sasl_client_new
370 	 *  conn_context   -- context for one connection
371 	 * returns:
372 	 *  SASL_OK	   -- success
373 	 *  SASL_NOMEM	   -- not enough memory
374 	 *  SASL_WRONGMECH -- mech doesn't support security params
375 	 */
376     int (*mech_new)(void *glob_context,
377 		    sasl_client_params_t *cparams,
378 		    void **conn_context);
379 
380 	/*
381 	 * perform one step of exchange.  NULL is passed for serverin on
382 	 * first step.
383 	 * returns:
384 	 *  SASL_OK	   -- success
385 	 *  SASL_INTERACT  -- user interaction needed to fill in prompts
386 	 *  SASL_BADPROT   -- server protocol incorrect/cancelled
387 	 *  SASL_BADSERV   -- server failed mutual auth
388 	 */
389     int (*mech_step)(void *conn_context,
390 		    sasl_client_params_t *cparams,
391 		    const char *serverin,
392 		    unsigned serverinlen,
393 		    sasl_interact_t **prompt_need,
394 		    const char **clientout,
395 		    unsigned *clientoutlen,
396 		    sasl_out_params_t *oparams);
397 
398 	/* dispose of connection context from mech_new */
399     void (*mech_dispose)(void *conn_context, const sasl_utils_t *utils);
400 
401 	/*
402 	 * free all global space used by mechanism
403 	 *  mech_dispose must be called on all mechanisms first
404 	 */
405     void (*mech_free)(void *glob_context, const sasl_utils_t *utils);
406 
407 	/*
408 	 * perform precalculations during a network round-trip
409 	 *  or idle period.  conn_context may be NULL
410 	 *  returns 1 if action taken, 0 if no action taken
411 	 */
412     int (*idle)(void *glob_context,
413 		void *conn_context,
414 		sasl_client_params_t *cparams);
415 
416 	/* for additions which don't require a version upgrade; set to 0 */
417     int (*spare_fptr1)();
418     int (*spare_fptr2)();
419 } sasl_client_plug_t;
420 
421 #define	SASL_CLIENT_PLUG_VERSION	4
422 
423 /*
424  * plug-in entry point:
425  *  utils       -- utility callback functions
426  *  max_version -- highest client plug version supported
427  * returns:
428  *  out_version -- client plug version of result
429  *  pluglist    -- list of mechanism plug-ins
430  *  plugcount   -- number of mechanism plug-ins
431  * results:
432  *  SASL_OK       -- success
433  *  SASL_NOMEM    -- failure
434  *  SASL_BADVERS  -- max_version too small
435  *  SASL_BADPARAM -- bad config string
436  *  ...
437  */
438 typedef int sasl_client_plug_init_t(const sasl_utils_t *utils,
439 				    int max_version,
440 				    int *out_version,
441 				    sasl_client_plug_t **pluglist,
442 				    int *plugcount);
443 
444 /* add a client plug-in */
445 LIBSASL_API int sasl_client_add_plugin(const char *plugname,
446 				sasl_client_plug_init_t *cplugfunc);
447 
448 /*
449  * Server Functions
450  */
451 
452 /*
453  * input parameters to server SASL plugin
454  *
455  * created / destroyed by the glue code
456  *
457  */
458 typedef struct sasl_server_params {
459     const char *service;	/* NULL = default service for user_exists */
460 				/* and setpass */
461     const char *appname;	/* name of calling application */
462     const char *serverFQDN;	/* server default fully qualified domain name */
463 				/* (e.g., gethostname) */
464     const char *user_realm;	/* realm for user (NULL = client supplied) */
465     const char *iplocalport;	/* server IP domain literal & port */
466     const char *ipremoteport;	/* client IP domain literal & port */
467 
468     unsigned servicelen;	/* length of service */
469     unsigned applen;		/* length of appname */
470     unsigned slen;		/* length of serverFQDN */
471     unsigned urlen;		/* length of user_realm */
472     unsigned iploclen;		/* length of iplocalport */
473     unsigned ipremlen;		/* length of ipremoteport */
474 
475 	/*
476 	 * This indicates the level of logging desired.  See SASL_LOG_*
477 	 * in sasl.h
478 	 *
479 	 * Plug-ins can ignore this and just pass their desired level to
480 	 * the log callback.  This is primarily used to eliminate logging which
481 	 * might be a performance problem (e.g., full protocol trace) and
482 	 * to select between SASL_LOG_TRACE and SASL_LOG_PASS alternatives
483 	 */
484     int log_level;
485 
486     const sasl_utils_t *utils;	/* SASL API utility routines -- */
487 				/* for a particular sasl_conn_t, */
488 				/* MUST remain valid until mech_free is */
489 				/* called */
490 
491     const sasl_callback_t *callbacks;	/* Callbacks from application */
492 
493 	/* application's security requirements */
494     sasl_security_properties_t props;
495     sasl_ssf_t external_ssf;	/* external SSF active */
496 
497 	/*
498 	 * server plug-in calls this when it first has access to the plaintext
499 	 *  passphrase.  This is used to transition users via setpass calls.
500 	 *  If passlen is 0, it defaults to strlen(pass).
501 	 *  returns 0 if no entry added, 1 if entry added
502 	 */
503     int (*transition)(sasl_conn_t *conn, const char *pass, unsigned passlen);
504 
505 	/*
506 	 * Canonicalize a user name from on-wire to internal format
507 	 *  added cjn 1999-09-21
508 	 *  Must be called once user name aquired if canon_user is non-NULL.
509 	 *  conn    connection context
510 	 *  user    user name from wire protocol (need not be NUL terminated)
511 	 *  ulen    length of user name from wire protocol (0 = strlen(user))
512 	 *  flags   for SASL_CU_* flags
513 	 *  oparams the user, authid, ulen, alen, fields are
514 	 *	    set appropriately after canonicalization/copying and
515 	 *	    authorization of arguments
516 	 *
517 	 *  responsible for setting user, ulen, authid, and alen in the oparams
518 	 *  structure
519 	 *
520 	 *  default behavior is to strip leading and trailing whitespace, as
521 	 *  well as allocating space for and copying the parameters.
522 	 *
523 	 * results:
524 	 *  SASL_OK	  -- success
525 	 *  SASL_NOMEM    -- out of memory
526 	 *  SASL_BADPARAM -- invalid conn
527 	 *  SASL_BADPROT  -- invalid user/authid
528 	 */
529     int (*canon_user)(sasl_conn_t *conn,
530 		    const char *user, unsigned ulen,
531 		    unsigned flags,
532 		    sasl_out_params_t *oparams);
533 
534 	/*
535 	 * auxiliary property context (see definitions in prop.h)
536 	 *  added cjn 2000-01-30
537 	 *
538 	 * NOTE: these properties are the ones associated with the
539 	 * canonicalized "user" (user to login as / authorization id), not
540 	 * the "authid" (user whose credentials are used / authentication id)
541 	 * Prefix the property name with a "*" if a property associated with
542 	 * the "authid" is interesting.
543 	 */
544     struct propctx *propctx;
545 
546 	/* for additions which don't require a version upgrade; set to 0 */
547     void *spare_ptr1;
548     void *spare_ptr2;
549     void *spare_ptr3;
550     void *spare_ptr4;
551     int (*spare_fptr1)();
552     int (*spare_fptr2)();
553     int spare_int1;
554     int spare_int2;
555     int spare_int3;
556 
557 	/* flags field as passed to sasl_server_new */
558     unsigned flags;
559 
560 	/*
561 	 * set to 0 initially, this allows a plugin with extended parameters
562 	 * to work with an older framework by updating version as parameters
563 	 * are added.
564 	 */
565     int param_version;
566 } sasl_server_params_t;
567 
568 /* features for server plug-in */
569 #define	SASL_FEAT_SERVICE    0x0200 /* service-specific passwords supported */
570 #define	SASL_FEAT_GETSECRET  0x0400 /* sasl_server_{get,put}secret_t */
571 				    /* callbacks required by plug-in */
572 
573 /* a C object for a server mechanism */
574 typedef struct sasl_server_plug {
575 	/* mechanism name */
576     const char *mech_name;
577 
578 	/* best mech additional security layer strength factor */
579     sasl_ssf_t max_ssf;
580 
581 	/* best security flags, as defined in sasl_security_properties_t */
582     unsigned security_flags;
583 
584 	/* features of plugin */
585     unsigned features;
586 
587 	/* global state for mechanism */
588     void *glob_context;
589 
590 	/*
591 	 * create a new mechanism handler
592 	 *  glob_context  -- global context
593 	 *  sparams	  -- server config params
594 	 *  challenge	  -- server challenge from previous instance or NULL
595 	 *  challen	  -- length of challenge from previous instance or 0
596 	 * out:
597 	 *  conn_context  -- connection context
598 	 *  errinfo	  -- error information
599 	 *
600 	 * returns:
601 	 *  SASL_OK	  -- successfully created mech instance
602 	 *  SASL_*	  -- any other server error code
603 	 */
604     int (*mech_new)(void *glob_context,
605 		    sasl_server_params_t *sparams,
606 		    const char *challenge,
607 		    unsigned challen,
608 		    void **conn_context);
609 
610 	/*
611 	 * perform one step in exchange
612 	 *
613 	 * returns:
614 	 *  SASL_OK	  -- success, all done
615 	 *  SASL_CONTINUE -- success, one more round trip
616 	 *  SASL_*	  -- any other server error code
617 	 */
618     int (*mech_step)(void *conn_context,
619 			sasl_server_params_t *sparams,
620 			const char *clientin,
621 			unsigned clientinlen,
622 			const char **serverout,
623 			unsigned *serveroutlen,
624 			sasl_out_params_t *oparams);
625 
626 	/* dispose of a connection state */
627     void (*mech_dispose)(void *conn_context, const sasl_utils_t *utils);
628 
629 	/*
630 	 * free global state for mechanism
631 	 *  mech_dispose must be called on all mechanisms first
632 	 */
633     void (*mech_free)(void *glob_context, const sasl_utils_t *utils);
634 
635 	/*
636 	 * set a password (optional)
637 	 *  glob_context  -- global context
638 	 *  sparams	  -- service, middleware utilities, etc. props ignored
639 	 *  user	  -- user name
640 	 *  pass	  -- password/passphrase (NULL = disable/remove/delete)
641 	 *  passlen	  -- length of password/passphrase
642 	 *  oldpass	  -- old password/passphrase (NULL = transition)
643 	 *  oldpasslen    -- length of password/passphrase
644 	 *  flags	  -- see above
645 	 *
646 	 * returns:
647 	 *  SASL_NOCHANGE -- no change was needed
648 	 *  SASL_NOUSER   -- no entry for user
649 	 *  SASL_NOVERIFY -- no mechanism compatible entry for user
650 	 *  SASL_PWLOCK   -- password locked
651 	 *  SASL_DIABLED  -- account disabled
652 	 *  etc.
653 	 */
654     int (*setpass)(void *glob_context,
655 		    sasl_server_params_t *sparams,
656 		    const char *user,
657 		    const char *pass, unsigned passlen,
658 		    const char *oldpass, unsigned oldpasslen,
659 		    unsigned flags);
660 
661 	/*
662 	 * query which mechanisms are available for user
663 	 *  glob_context  -- context
664 	 *  sparams	  -- service, middleware utilities, etc. props ignored
665 	 *  user	  -- NUL terminated user name
666 	 *  maxmech	  -- max number of strings in mechlist (0 = no output)
667 	 * output:
668 	 *  mechlist	  -- an array of C string pointers, filled in with
669 	 *		  mechanism names available to the user
670 	 *
671 	 * returns:
672 	 *  SASL_OK	  -- success
673 	 *  SASL_NOMEM    -- not enough memory
674 	 *  SASL_FAIL	  -- lower level failure
675 	 *  SASL_DISABLED -- account disabled
676 	 *  SASL_NOUSER   -- user not found
677 	 *  SASL_BUFOVER  -- maxmech is too small
678 	 *  SASL_NOVERIFY -- user found, but no mechanisms available
679 	 */
680     int (*user_query)(void *glob_context,
681 		    sasl_server_params_t *sparams,
682 		    const char *user,
683 		    int maxmech,
684 		    const char **mechlist);
685 
686 	/*
687 	 * perform precalculations during a network round-trip
688 	 *  or idle period.  conn_context may be NULL (optional)
689 	 *  returns 1 if action taken, 0 if no action taken
690 	 */
691     int (*idle)(void *glob_context,
692 		void *conn_context,
693 		sasl_server_params_t *sparams);
694 
695 	/*
696 	 * check if mechanism is available
697 	 * TODO - Is this correct?
698 	 *  optional--if NULL, mechanism is available based on ENABLE=
699 	 * in config
700 	 *
701 	 *  If this routine sets conn_context to a non-NULL value, then the call
702 	 *  to mech_new will be skipped.  This should not be done unless
703 	 *  there's a significant performance benefit, since it can cause
704 	 *  additional memory allocation in SASL core code to keep track of
705 	 *  contexts potentially for multiple mechanisms.
706 	 *
707 	 *  This is called by the first call to sasl_listmech() for a
708 	 *  given connection context, thus for a given protocol it may
709 	 *  never be called.  Note that if mech_avail returns SASL_NOMECH,
710 	 *  then that mechanism is considered disabled for the remainder
711 	 *  of the session.
712 	 *
713 	 *  returns SASL_OK on success,
714 	 *	    SASL_NOMECH if mech disabled
715 	 */
716     int (*mech_avail)(void *glob_context,
717 		    sasl_server_params_t *sparams,
718 		    void **conn_context);
719 
720 	/* for additions which don't require a version upgrade; set to 0 */
721     int (*spare_fptr2)();
722 } sasl_server_plug_t;
723 
724 #define	SASL_SERVER_PLUG_VERSION 4
725 
726 /*
727  * plug-in entry point:
728  *  utils         -- utility callback functions
729  *  plugname      -- name of plug-in (may be NULL)
730  *  max_version   -- highest server plug version supported
731  * returns:
732  *  out_version   -- server plug-in version of result
733  *  pluglist      -- list of mechanism plug-ins
734  *  plugcount     -- number of mechanism plug-ins
735  * results:
736  *  SASL_OK       -- success
737  *  SASL_NOMEM    -- failure
738  *  SASL_BADVERS  -- max_version too small
739  *  SASL_BADPARAM -- bad config string
740  *  ...
741  */
742 typedef int sasl_server_plug_init_t(const sasl_utils_t *utils,
743 				    int max_version,
744 				    int *out_version,
745 				    sasl_server_plug_t **pluglist,
746 				    int *plugcount);
747 
748 /*
749  * add a server plug-in
750  */
751 LIBSASL_API int sasl_server_add_plugin(const char *plugname,
752 				sasl_server_plug_init_t *splugfunc);
753 
754 /*
755  * user canonicalization plug-in -- added cjn 1999-09-29
756  */
757 
758 typedef struct sasl_canonuser {
759 	/* optional features of plugin (set to 0) */
760     int features;
761 
762 	/* spare integer (set to 0) */
763     int spare_int1;
764 
765 	/* global state for plugin */
766     void *glob_context;
767 
768 	/* name of plugin */
769     char *name;
770 
771 	/* free global state for plugin */
772     void (*canon_user_free)(void *glob_context, const sasl_utils_t *utils);
773 
774 	/*
775 	 * canonicalize a username
776 	 *  glob_context    -- global context from this structure
777 	 *  sparams	    -- server params, note user_realm&propctx elements
778 	 *  user	    -- user to login as (may not be NUL terminated)
779 	 *  len		    -- length of user name (0 = strlen(user))
780 	 *  flags	    -- for SASL_CU_* flags
781 	 *  out		    -- buffer to copy user name
782 	 *  out_max	    -- max length of user name
783 	 *  out_len	    -- set to length of user name
784 	 *
785 	 *  note that the output buffers MAY be the same as the input buffers.
786 	 *
787 	 * returns
788 	 *  SASL_OK	    on success
789 	 *  SASL_BADPROT    username contains invalid character
790 	 */
791     int (*canon_user_server)(void *glob_context,
792 			    sasl_server_params_t *sparams,
793 			    const char *user, unsigned len,
794 			    unsigned flags,
795 			    char *out,
796 			    unsigned out_umax, unsigned *out_ulen);
797 
798     int (*canon_user_client)(void *glob_context,
799 			    sasl_client_params_t *cparams,
800 			    const char *user, unsigned len,
801 			    unsigned flags,
802 			    char *out,
803 			    unsigned out_max, unsigned *out_len);
804 
805 	/* for additions which don't require a version upgrade; set to 0 */
806     int (*spare_fptr1)();
807     int (*spare_fptr2)();
808     int (*spare_fptr3)();
809 } sasl_canonuser_plug_t;
810 
811 #define	SASL_CANONUSER_PLUG_VERSION 5
812 
813 /*
814  * default name for canonuser plug-in entry point is "sasl_canonuser_init"
815  *  similar to sasl_server_plug_init model, except only returns one
816  *  sasl_canonuser_plug_t structure;
817  */
818 typedef int sasl_canonuser_init_t(const sasl_utils_t *utils,
819 				int max_version,
820 				int *out_version,
821 				sasl_canonuser_plug_t **plug,
822 				const char *plugname);
823 
824 /* add a canonuser plugin */
825 LIBSASL_API int sasl_canonuser_add_plugin(const char *plugname,
826 				sasl_canonuser_init_t *canonuserfunc);
827 
828 /*
829  * auxiliary property plug-in -- added cjn 1999-09-29
830  */
831 
832 typedef struct sasl_auxprop_plug {
833 	/* optional features of plugin (none defined yet, set to 0) */
834     int features;
835 
836 	/* spare integer, must be set to 0 */
837     int spare_int1;
838 
839 	/* global state for plugin */
840     void *glob_context;
841 
842 	/* free global state for plugin (OPTIONAL) */
843     void (*auxprop_free)(void *glob_context, const sasl_utils_t *utils);
844 
845 	/*
846 	 * fill in fields of an auxiliary property context
847 	 *  last element in array has id of SASL_AUX_END
848 	 *  elements with non-0 len should be ignored.
849 	 */
850     void (*auxprop_lookup)(void *glob_context,
851 			    sasl_server_params_t *sparams,
852 			    unsigned flags,
853 			    const char *user, unsigned ulen);
854 
855 	/* name of the auxprop plugin */
856     char *name;
857 
858 	/* for additions which don't require a version upgrade; set to 0 */
859     void (*spare_fptr1)();
860 } sasl_auxprop_plug_t;
861 
862 /* auxprop lookup flags */
863 #define	SASL_AUXPROP_OVERRIDE 0x01  /* if clear, ignore auxiliary properties */
864 				    /* with non-zero len field.  If set, */
865 				    /* override value of those properties */
866 #define	SASL_AUXPROP_AUTHZID  0x02  /* if clear, we are looking up the */
867 				    /* authid flags (prefixed with *), */
868 				    /* otherwise we are looking up the */
869 				    /* authzid flags (no prefix) */
870 
871 #define	SASL_AUXPROP_PLUG_VERSION 4
872 
873 /*
874  * default name for auxprop plug-in entry point is "sasl_auxprop_init"
875  *  similar to sasl_server_plug_init model, except only returns one
876  *  sasl_auxprop_plug_t structure;
877  */
878 typedef int sasl_auxprop_init_t(const sasl_utils_t *utils,
879 				int max_version,
880 				int *out_version,
881 				sasl_auxprop_plug_t **plug,
882 				const char *plugname);
883 
884 /* add an auxiliary property plug-in */
885 LIBSASL_API int sasl_auxprop_add_plugin(const char *plugname,
886 					sasl_auxprop_init_t *auxpropfunc);
887 
888 #ifdef	__cplusplus
889 }
890 #endif
891 
892 #endif /* _SASL_SASLPLUG_H */
893