Print this page
3882 remove xmod & friends
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/lib/libsasl/lib/common.c
+++ new/usr/src/lib/libsasl/lib/common.c
1 1 /*
2 2 * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
3 3 * Use is subject to license terms.
4 4 */
5 5
6 6 #pragma ident "%Z%%M% %I% %E% SMI"
7 7
8 8 /* common.c - Functions that are common to server and clinet
9 9 * Rob Siemborski
10 10 * Tim Martin
11 11 * $Id: common.c,v 1.92 2003/04/16 19:36:00 rjs3 Exp $
12 12 */
13 13 /*
14 14 * Copyright (c) 1998-2003 Carnegie Mellon University. All rights reserved.
15 15 *
16 16 * Redistribution and use in source and binary forms, with or without
17 17 * modification, are permitted provided that the following conditions
18 18 * are met:
19 19 *
20 20 * 1. Redistributions of source code must retain the above copyright
21 21 * notice, this list of conditions and the following disclaimer.
22 22 *
23 23 * 2. Redistributions in binary form must reproduce the above copyright
24 24 * notice, this list of conditions and the following disclaimer in
25 25 * the documentation and/or other materials provided with the
26 26 * distribution.
27 27 *
28 28 * 3. The name "Carnegie Mellon University" must not be used to
29 29 * endorse or promote products derived from this software without
30 30 * prior written permission. For permission or any other legal
31 31 * details, please contact
32 32 * Office of Technology Transfer
33 33 * Carnegie Mellon University
34 34 * 5000 Forbes Avenue
35 35 * Pittsburgh, PA 15213-3890
36 36 * (412) 268-4387, fax: (412) 268-7395
37 37 * tech-transfer@andrew.cmu.edu
38 38 *
39 39 * 4. Redistributions of any form whatsoever must retain the following
40 40 * acknowledgment:
41 41 * "This product includes software developed by Computing Services
42 42 * at Carnegie Mellon University (http://www.cmu.edu/computing/)."
43 43 *
44 44 * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
45 45 * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
46 46 * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
47 47 * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
48 48 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
49 49 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
50 50 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
51 51 */
52 52
53 53 #include <config.h>
54 54 #include <stdio.h>
55 55 #include <string.h>
56 56 #include <stdlib.h>
57 57 #include <limits.h>
58 58 #ifdef HAVE_SYSLOG
59 59 #include <syslog.h>
60 60 #endif
61 61 #include <stdarg.h>
62 62 #include <ctype.h>
63 63
64 64 #include <sasl.h>
65 65 #include <saslutil.h>
66 66 #include <saslplug.h>
67 67 #include "saslint.h"
68 68
69 69 #ifdef _SUN_SDK_
70 70 #include "md5_private.h"
71 71 #include "hmac-md5.h"
72 72 #include "plugin_common.h"
73 73 #endif
74 74
75 75
76 76 #ifdef WIN32
77 77 /* need to handle the fact that errno has been defined as a function
78 78 in a dll, not an extern int */
79 79 # ifdef errno
80 80 # undef errno
81 81 # endif /* errno */
82 82 #endif /* WIN32 */
83 83 #ifdef HAVE_UNISTD_H
84 84 #include <unistd.h>
85 85 #endif
86 86
87 87 static int _sasl_getpath(void *context __attribute__((unused)), const char **path);
88 88
89 89 #ifdef _SUN_SDK_
90 90 DEFINE_STATIC_MUTEX(global_mutex);
91 91 DEFINE_STATIC_MUTEX(malloc_global_mutex);
92 92 static void _sasl_dispose_context(_sasl_global_context_t *ctx);
93 93 static int _sasl_getconf(void *context, const char **conf);
94 94
95 95 #ifdef _INTEGRATED_SOLARIS_
96 96 static pthread_key_t errstring_key = PTHREAD_ONCE_KEY_NP;
97 97 #endif /* _INTEGRATED_SOLARIS_ */
98 98 #else
99 99 static const char build_ident[] = "$Build: libsasl " PACKAGE "-" VERSION " $";
100 100
101 101 /* It turns out to be conveinent to have a shared sasl_utils_t */
102 102 LIBSASL_VAR const sasl_utils_t *sasl_global_utils = NULL;
103 103
104 104 /* Should be a null-terminated array that lists the available mechanisms */
105 105 static char **global_mech_list = NULL;
106 106
107 107 void *free_mutex = NULL;
108 108
109 109 int (*_sasl_client_cleanup_hook)(void) = NULL;
110 110 int (*_sasl_server_cleanup_hook)(void) = NULL;
111 111 int (*_sasl_client_idle_hook)(sasl_conn_t *conn) = NULL;
112 112 int (*_sasl_server_idle_hook)(sasl_conn_t *conn) = NULL;
113 113
114 114 sasl_allocation_utils_t _sasl_allocation_utils={
115 115 (sasl_malloc_t *) &malloc,
116 116 (sasl_calloc_t *) &calloc,
117 117 (sasl_realloc_t *) &realloc,
118 118 (sasl_free_t *) &free
119 119 };
120 120 #endif /* _SUN_SDK_ */
121 121
122 122 #ifdef USE_PTHREADS
123 123 static void *sasl_mutex_alloc(void)
124 124 {
125 125 pthread_mutex_t *mutex =
126 126 (pthread_mutex_t *)malloc(sizeof (pthread_mutex_t));
127 127
128 128 if (mutex != NULL) {
129 129 if (pthread_mutex_init(mutex, NULL) != 0) {
130 130 free(mutex);
131 131 mutex = NULL;
132 132 }
133 133 }
134 134 return (mutex);
135 135 }
136 136
137 137 static int sasl_mutex_lock(void *mutex)
138 138 {
139 139 int ret = SASL_BADPARAM;
140 140
141 141 if (mutex != NULL)
142 142 ret = pthread_mutex_lock((pthread_mutex_t *)mutex);
143 143
144 144 return ret;
145 145 }
146 146
147 147 static int sasl_mutex_unlock(void *mutex)
148 148 {
149 149 int ret = SASL_BADPARAM;
150 150
151 151 if (mutex != NULL)
152 152 ret = pthread_mutex_unlock((pthread_mutex_t *)mutex);
153 153
154 154 return ret;
155 155 }
156 156
157 157 static void sasl_mutex_free(void *mutex __attribute__((unused)))
158 158 {
159 159 if (mutex != NULL) {
160 160 pthread_mutex_destroy((pthread_mutex_t *)mutex);
161 161 free(mutex);
162 162 }
163 163 }
164 164 #else
165 165 /* Intenal mutex functions do as little as possible (no thread protection) */
166 166 static void *sasl_mutex_alloc(void)
167 167 {
168 168 return (void *)0x1;
169 169 }
170 170
171 171 static int sasl_mutex_lock(void *mutex __attribute__((unused)))
172 172 {
173 173 return SASL_OK;
174 174 }
175 175
176 176 static int sasl_mutex_unlock(void *mutex __attribute__((unused)))
177 177 {
178 178 return SASL_OK;
179 179 }
180 180
181 181 static void sasl_mutex_free(void *mutex __attribute__((unused)))
182 182 {
183 183 return;
184 184 }
185 185 #endif /* USE_PTHREADS */
186 186
187 187 #ifndef _SUN_SDK_
188 188 sasl_mutex_utils_t _sasl_mutex_utils={
189 189 &sasl_mutex_alloc,
190 190 &sasl_mutex_lock,
191 191 &sasl_mutex_unlock,
192 192 &sasl_mutex_free
193 193 };
194 194 #endif /* !_SUN_SDK_ */
195 195
196 196 void sasl_set_mutex(sasl_mutex_alloc_t *n, sasl_mutex_lock_t *l,
197 197 sasl_mutex_unlock_t *u, sasl_mutex_free_t *d)
198 198 {
199 199 #ifdef _SUN_SDK_
200 200 _sasl_global_context_t *gctx = _sasl_gbl_ctx();
201 201
202 202 gctx->sasl_mutex_utils.alloc=n;
203 203 gctx->sasl_mutex_utils.lock=l;
204 204 gctx->sasl_mutex_utils.unlock=u;
205 205 gctx->sasl_mutex_utils.free=d;
206 206 #else
207 207 _sasl_mutex_utils.alloc=n;
208 208 _sasl_mutex_utils.lock=l;
209 209 _sasl_mutex_utils.unlock=u;
210 210 _sasl_mutex_utils.free=d;
211 211 #endif
212 212 }
213 213
214 214 /* copy a string to malloced memory */
215 215 #ifdef _SUN_SDK_
216 216 int __sasl_strdup(const _sasl_global_context_t *gctx, const char *in,
217 217 char **out, size_t *outlen)
218 218 #else
219 219 int _sasl_strdup(const char *in, char **out, size_t *outlen)
220 220 #endif /* _SUN_SDK_ */
221 221 {
222 222 size_t len = strlen(in);
223 223 if (outlen) *outlen = len;
224 224 *out=sasl_ALLOC(len + 1);
225 225 if (! *out) return SASL_NOMEM;
226 226 strcpy((char *) *out, in);
227 227 return SASL_OK;
228 228 }
229 229
230 230 /* adds a string to the buffer; reallocing if need be */
231 231 #ifdef _SUN_SDK_
232 232 int __sasl_add_string(const _sasl_global_context_t *gctx, char **out,
233 233 size_t *alloclen, size_t *outlen,
234 234 const char *add)
235 235 #else
236 236 int _sasl_add_string(char **out, size_t *alloclen,
237 237 size_t *outlen, const char *add)
238 238 #endif /* _SUN_SDK_ */
239 239 {
240 240 size_t addlen;
241 241
242 242 if (add==NULL) add = "(null)";
243 243
244 244 addlen=strlen(add); /* only compute once */
245 245 if (_buf_alloc(out, alloclen, (*outlen)+addlen)!=SASL_OK)
246 246 return SASL_NOMEM;
247 247
248 248 strncpy(*out + *outlen, add, addlen);
249 249 *outlen += addlen;
250 250
251 251 return SASL_OK;
252 252 }
253 253
254 254 /* return the version of the cyrus sasl library as compiled,
255 255 * using 32 bits: high byte is major version, second byte is minor version,
256 256 * low 16 bits are step # */
257 257 void sasl_version(const char **implementation, int *version)
258 258 {
259 259 #ifdef _SUN_SDK_
260 260 const char *implementation_string = "Sun SASL";
261 261 #else
262 262 const char *implementation_string = "Cyrus SASL";
263 263 #endif /* _SUN_SDK_ */
264 264 if(implementation) *implementation = implementation_string;
265 265 if(version) *version = (SASL_VERSION_MAJOR << 24) |
266 266 (SASL_VERSION_MINOR << 16) |
267 267 (SASL_VERSION_STEP);
268 268 }
269 269
270 270 /* security-encode a regular string. Mostly a wrapper for sasl_encodev */
271 271 /* output is only valid until next call to sasl_encode or sasl_encodev */
272 272 int sasl_encode(sasl_conn_t *conn, const char *input,
273 273 unsigned inputlen,
274 274 const char **output, unsigned *outputlen)
275 275 {
276 276 int result;
277 277 struct iovec tmp;
278 278
279 279 if(!conn) return SASL_BADPARAM;
280 280 if(!input || !inputlen || !output || !outputlen)
281 281 PARAMERROR(conn);
282 282
283 283 /* maxoutbuf checking is done in sasl_encodev */
284 284
285 285 /* Note: We are casting a const pointer here, but it's okay
286 286 * because we believe people downstream of us are well-behaved, and the
287 287 * alternative is an absolute mess, performance-wise. */
288 288 tmp.iov_base = (void *)input;
289 289 tmp.iov_len = inputlen;
290 290
291 291 result = sasl_encodev(conn, &tmp, 1, output, outputlen);
292 292
293 293 RETURN(conn, result);
294 294 }
295 295
296 296 /* security-encode an iovec */
297 297 /* output is only valid until next call to sasl_encode or sasl_encodev */
298 298 int sasl_encodev(sasl_conn_t *conn,
299 299 const struct iovec *invec, unsigned numiov,
↓ open down ↓ |
299 lines elided |
↑ open up ↑ |
300 300 const char **output, unsigned *outputlen)
301 301 {
302 302 #ifdef _SUN_SDK_
303 303 int result = SASL_FAIL;
304 304 #else
305 305 int result;
306 306 #endif /* _SUN_SDK_ */
307 307 unsigned i;
308 308 size_t total_size = 0;
309 309
310 - /* EXPORT DELETE START */
311 310 if (!conn) return SASL_BADPARAM;
312 311 if (! invec || ! output || ! outputlen || numiov < 1)
313 312 PARAMERROR(conn);
314 313
315 314 if(!conn->props.maxbufsize) {
316 315 #ifdef _SUN_SDK_
317 316 _sasl_log(conn, SASL_LOG_ERR,
318 317 "called sasl_encode[v] with application that does not support security layers");
319 318 #else
320 319 sasl_seterror(conn, 0,
321 320 "called sasl_encode[v] with application that does not support security layers");
322 321 #endif /* _SUN_SDK_ */
323 322 return SASL_TOOWEAK;
324 323 }
325 324
326 325 /* This might be better to check on a per-plugin basis, but I think
327 326 * it's cleaner and more effective here. It also encourages plugins
328 327 * to be honest about what they accept */
329 328
330 329 for(i=0; i<numiov;i++) {
331 330 #ifdef _SUN_SDK_
332 331 if (invec[i].iov_base == NULL)
333 332 PARAMERROR(conn);
334 333 #endif /* _SUN_SDK_ */
335 334 total_size += invec[i].iov_len;
336 335 }
337 336 if(total_size > conn->oparams.maxoutbuf)
338 337 PARAMERROR(conn);
339 338
340 339 if(conn->oparams.encode == NULL) {
↓ open down ↓ |
20 lines elided |
↑ open up ↑ |
341 340 #ifdef _SUN_SDK_
342 341 result = _iovec_to_buf(conn->gctx, invec, numiov, &conn->encode_buf);
343 342 #else
344 343 result = _iovec_to_buf(invec, numiov, &conn->encode_buf);
345 344 #endif /* _SUN_SDK_ */
346 345 if(result != SASL_OK) INTERROR(conn, result);
347 346
348 347 *output = conn->encode_buf->data;
349 348 *outputlen = conn->encode_buf->curlen;
350 349
351 - /* CRYPT DELETE START */
352 350 #ifdef _INTEGRATED_SOLARIS_
353 351 } else if (!conn->sun_reg) {
354 352 INTERROR(conn, SASL_FAIL);
355 353 #endif /* _INTEGRATED_SOLARIS_ */
356 - /* CRYPT DELETE END */
357 354 } else {
358 355 result = conn->oparams.encode(conn->context, invec, numiov,
359 356 output, outputlen);
360 357 }
361 - /* EXPORT DELETE END */
362 358
363 359 RETURN(conn, result);
364 360 }
365 361
366 362 /* output is only valid until next call to sasl_decode */
367 363 int sasl_decode(sasl_conn_t *conn,
368 364 const char *input, unsigned inputlen,
369 365 const char **output, unsigned *outputlen)
370 366 {
371 367 int result;
372 - /* EXPORT DELETE START */
373 368 #ifdef _SUN_SDK_
374 369 const _sasl_global_context_t *gctx;
375 370 #endif /* _SUN_SDK_ */
376 371
377 372 if(!conn) return SASL_BADPARAM;
378 373 if(!input || !output || !outputlen)
379 374 PARAMERROR(conn);
380 375
381 376 #ifdef _SUN_SDK_
382 377 gctx = conn->gctx;
383 378 #endif /* _SUN_SDK_ */
384 379
385 380 if(!conn->props.maxbufsize) {
386 381 #ifdef _SUN_SDK_
387 382 _sasl_log(conn, SASL_LOG_ERR,
388 383 "called sasl_decode with application that does not support security layers");
389 384 #else
390 385 sasl_seterror(conn, 0,
391 386 "called sasl_decode with application that does not support security layers");
392 387 #endif /* _SUN_SDK_ */
393 388 RETURN(conn, SASL_TOOWEAK);
394 389 }
395 390
396 391 if(conn->oparams.decode == NULL)
397 392 {
398 393 /* Since we know how long the output is maximally, we can
399 394 * just allocate it to begin with, and never need another
400 395 * allocation! */
401 396
402 397 /* However, if they pass us more than they actually can take,
403 398 * we cannot help them... */
404 399 if(inputlen > conn->props.maxbufsize) {
405 400 #ifdef _SUN_SDK_
406 401 _sasl_log(conn, SASL_LOG_ERR,
407 402 "input too large for default sasl_decode");
408 403 #else
409 404 sasl_seterror(conn, 0,
410 405 "input too large for default sasl_decode");
411 406 #endif /* _SUN_SDK_ */
412 407 RETURN(conn,SASL_BUFOVER);
413 408 }
414 409
415 410 if(!conn->decode_buf)
↓ open down ↓ |
33 lines elided |
↑ open up ↑ |
416 411 conn->decode_buf = sasl_ALLOC(conn->props.maxbufsize + 1);
417 412 if(!conn->decode_buf)
418 413 MEMERROR(conn);
419 414
420 415 memcpy(conn->decode_buf, input, inputlen);
421 416 conn->decode_buf[inputlen] = '\0';
422 417 *output = conn->decode_buf;
423 418 *outputlen = inputlen;
424 419
425 420 return SASL_OK;
426 - /* CRYPT DELETE START */
427 421 #ifdef _INTEGRATED_SOLARIS_
428 422 } else if (!conn->sun_reg) {
429 423 INTERROR(conn, SASL_FAIL);
430 424 #endif /* _INTEGRATED_SOLARIS_ */
431 - /* CRYPT DELETE END */
432 425 } else {
433 426 result = conn->oparams.decode(conn->context, input, inputlen,
434 427 output, outputlen);
435 428
436 429 /* NULL an empty buffer (for misbehaved applications) */
437 430 if (*outputlen == 0) *output = NULL;
438 431
439 432 RETURN(conn, result);
440 433 }
441 434
442 - /* EXPORT DELETE END */
443 435 #ifdef _SUN_SDK_
444 436 return SASL_FAIL;
445 437 #else
446 438 INTERROR(conn, SASL_FAIL);
447 439 #endif /* _SUN_SDK_ */
448 440 }
449 441
450 442
451 443 void
452 444 sasl_set_alloc(sasl_malloc_t *m,
453 445 sasl_calloc_t *c,
454 446 sasl_realloc_t *r,
455 447 sasl_free_t *f)
456 448 {
457 449 #ifdef _SUN_SDK_
458 450 _sasl_global_context_t *gctx = _sasl_gbl_ctx();
459 451
460 452 LOCK_MUTEX(&malloc_global_mutex);
461 453 gctx->sasl_allocation_utils.malloc=m;
462 454 gctx->sasl_allocation_utils.calloc=c;
463 455 gctx->sasl_allocation_utils.realloc=r;
464 456 gctx->sasl_allocation_utils.free=f;
465 457 UNLOCK_MUTEX(&malloc_global_mutex);
466 458 #else
467 459 _sasl_allocation_utils.malloc=m;
468 460 _sasl_allocation_utils.calloc=c;
469 461 _sasl_allocation_utils.realloc=r;
470 462 _sasl_allocation_utils.free=f;
471 463 #endif /* _SUN_SDK_ */
472 464 }
473 465
474 466 void sasl_done(void)
475 467 {
476 468 #ifdef _SUN_SDK_
477 469 _sasl_dispose_context(_sasl_gbl_ctx());
478 470 #else
479 471 if (_sasl_server_cleanup_hook && _sasl_server_cleanup_hook() == SASL_OK) {
480 472 _sasl_server_idle_hook = NULL;
481 473 _sasl_server_cleanup_hook = NULL;
482 474 }
483 475
484 476 if (_sasl_client_cleanup_hook && _sasl_client_cleanup_hook() == SASL_OK) {
485 477 _sasl_client_idle_hook = NULL;
486 478 _sasl_client_cleanup_hook = NULL;
487 479 }
488 480
489 481 if(_sasl_server_cleanup_hook || _sasl_client_cleanup_hook)
490 482 return;
491 483
492 484
493 485 _sasl_canonuser_free();
494 486 _sasl_done_with_plugins();
495 487
496 488 #ifdef _SUN_SDK_
497 489 sasl_config_free();
498 490 #endif /* _SUN_SDK_ */
499 491
500 492 sasl_MUTEX_FREE(free_mutex);
501 493 free_mutex = NULL;
502 494
503 495 _sasl_free_utils(&sasl_global_utils);
504 496
505 497 if(global_mech_list) sasl_FREE(global_mech_list);
506 498 global_mech_list = NULL;
507 499 #endif /* _SUN_SDK_ */
508 500 }
509 501
510 502 /* fills in the base sasl_conn_t info */
511 503 int _sasl_conn_init(sasl_conn_t *conn,
512 504 const char *service,
513 505 unsigned int flags,
514 506 enum Sasl_conn_type type,
515 507 int (*idle_hook)(sasl_conn_t *conn),
516 508 const char *serverFQDN,
517 509 const char *iplocalport,
518 510 const char *ipremoteport,
519 511 const sasl_callback_t *callbacks,
520 512 const sasl_global_callbacks_t *global_callbacks) {
521 513 int result = SASL_OK;
522 514 #ifdef _SUN_SDK_
523 515 const _sasl_global_context_t *gctx = conn->gctx;
524 516 #endif /* _SUN_SDK_ */
525 517
526 518 conn->type = type;
527 519
528 520 result = _sasl_strdup(service, &conn->service, NULL);
529 521 if (result != SASL_OK)
530 522 MEMERROR(conn);
531 523
532 524 memset(&conn->oparams, 0, sizeof(sasl_out_params_t));
533 525 memset(&conn->external, 0, sizeof(_sasl_external_properties_t));
534 526
535 527 conn->flags = flags;
536 528
537 529 result = sasl_setprop(conn, SASL_IPLOCALPORT, iplocalport);
538 530 if(result != SASL_OK)
539 531 RETURN(conn, result);
540 532
541 533 result = sasl_setprop(conn, SASL_IPREMOTEPORT, ipremoteport);
542 534 if(result != SASL_OK)
543 535 RETURN(conn, result);
544 536
545 537 conn->encode_buf = NULL;
546 538 conn->context = NULL;
547 539 #ifndef _SUN_SDK_
548 540 conn->secret = NULL;
549 541 #endif /* !_SUN_SDK_ */
550 542 conn->idle_hook = idle_hook;
551 543 conn->callbacks = callbacks;
552 544 conn->global_callbacks = global_callbacks;
553 545
554 546 memset(&conn->props, 0, sizeof(conn->props));
555 547
556 548 /* Start this buffer out as an empty string */
557 549 conn->error_code = SASL_OK;
558 550 conn->errdetail_buf = conn->error_buf = NULL;
559 551 conn->errdetail_buf_len = conn->error_buf_len = 150;
560 552
561 553 result = _buf_alloc(&conn->error_buf, &conn->error_buf_len, 150);
562 554 if(result != SASL_OK) MEMERROR(conn);
563 555 result = _buf_alloc(&conn->errdetail_buf, &conn->errdetail_buf_len, 150);
564 556 if(result != SASL_OK) MEMERROR(conn);
565 557
566 558 conn->error_buf[0] = '\0';
567 559 conn->errdetail_buf[0] = '\0';
568 560
569 561 conn->decode_buf = NULL;
570 562
571 563 if(serverFQDN) {
572 564 result = _sasl_strdup(serverFQDN, &conn->serverFQDN, NULL);
573 565 } else if (conn->type == SASL_CONN_SERVER) {
574 566 /* We can fake it because we *are* the server */
575 567 char name[MAXHOSTNAMELEN];
576 568 memset(name, 0, sizeof(name));
577 569 gethostname(name, MAXHOSTNAMELEN);
578 570
579 571 result = _sasl_strdup(name, &conn->serverFQDN, NULL);
580 572 } else {
581 573 conn->serverFQDN = NULL;
582 574 }
583 575
584 576
585 577 if(result != SASL_OK) MEMERROR( conn );
586 578
587 579 #ifdef _SUN_SDK_
588 580 return (SASL_OK);
589 581 #else
590 582 RETURN(conn, SASL_OK);
591 583 #endif /* _SUN_SDK_ */
592 584 }
593 585
594 586 #ifdef _SUN_SDK_
595 587 int _sasl_common_init(_sasl_global_context_t *gctx,
596 588 sasl_global_callbacks_t *global_callbacks,
597 589 int server)
598 590 {
599 591 int result;
600 592 sasl_utils_t *sasl_global_utils;
601 593
602 594 sasl_global_utils = (sasl_utils_t *)gctx->sasl_canonusr_global_utils;
603 595
604 596 if(!sasl_global_utils) {
605 597 sasl_global_utils = _sasl_alloc_utils(gctx, NULL, global_callbacks);
606 598 if(sasl_global_utils == NULL) return SASL_NOMEM;
607 599 gctx->sasl_canonusr_global_utils = sasl_global_utils;
608 600 }
609 601
610 602 if (server) {
611 603 sasl_global_utils = (sasl_utils_t *)gctx->sasl_server_global_utils;
612 604
613 605 if(!sasl_global_utils) {
614 606 sasl_global_utils = _sasl_alloc_utils(gctx, NULL, global_callbacks);
615 607 if(sasl_global_utils == NULL) return SASL_NOMEM;
616 608 gctx->sasl_server_global_utils = sasl_global_utils;
617 609 }
618 610 }
619 611
620 612 /* Init the canon_user plugin */
621 613 result = _sasl_canonuser_add_plugin(gctx, "INTERNAL",
622 614 internal_canonuser_init);
623 615 if(result != SASL_OK) return result;
624 616
625 617 if (!gctx->free_mutex)
626 618 gctx->free_mutex = sasl_MUTEX_ALLOC();
627 619 if (!gctx->free_mutex) return SASL_FAIL;
628 620
629 621 return SASL_OK;
630 622 }
631 623 #else
632 624 int _sasl_common_init(sasl_global_callbacks_t *global_callbacks)
633 625 {
634 626 int result;
635 627
636 628 /* Setup the global utilities */
637 629 if(!sasl_global_utils) {
638 630 sasl_global_utils = _sasl_alloc_utils(NULL, global_callbacks);
639 631 if(sasl_global_utils == NULL) return SASL_NOMEM;
640 632 }
641 633
642 634 /* Init the canon_user plugin */
643 635 result = sasl_canonuser_add_plugin("INTERNAL", internal_canonuser_init);
644 636 if(result != SASL_OK) return result;
645 637
646 638 if (!free_mutex)
647 639 free_mutex = sasl_MUTEX_ALLOC();
648 640 if (!free_mutex) return SASL_FAIL;
649 641
650 642 return SASL_OK;
651 643 }
652 644 #endif /* _SUN_SDK_ */
653 645
654 646 /* dispose connection state, sets it to NULL
655 647 * checks for pointer to NULL
656 648 */
657 649 void sasl_dispose(sasl_conn_t **pconn)
658 650 {
659 651 int result;
660 652 #ifdef _SUN_SDK_
661 653 _sasl_global_context_t *gctx;
662 654 void *free_mutex;
663 655 #endif /* _SUN_SDK_ */
664 656
665 657 if (! pconn) return;
666 658 if (! *pconn) return;
667 659
668 660 /* serialize disposes. this is necessary because we can't
669 661 dispose of conn->mutex if someone else is locked on it */
670 662 #ifdef _SUN_SDK_
671 663 gctx = (*pconn)->gctx;
672 664 free_mutex = gctx->free_mutex;
673 665 #endif /* _SUN_SDK_ */
674 666 result = sasl_MUTEX_LOCK(free_mutex);
675 667 if (result!=SASL_OK) return;
676 668
677 669 /* *pconn might have become NULL by now */
678 670 #ifdef _SUN_SDK_
679 671 if (! (*pconn)) {
680 672 sasl_MUTEX_UNLOCK(free_mutex);
681 673 return;
682 674 }
683 675 #else
684 676 if (! (*pconn)) return;
685 677 #endif /* _SUN_SDK_ */
686 678
687 679 (*pconn)->destroy_conn(*pconn);
688 680 sasl_FREE(*pconn);
689 681 *pconn=NULL;
690 682
691 683 sasl_MUTEX_UNLOCK(free_mutex);
692 684 }
693 685
694 686 void _sasl_conn_dispose(sasl_conn_t *conn) {
695 687 #ifdef _SUN_SDK_
696 688 const _sasl_global_context_t *gctx = conn->gctx;
697 689 #endif /* _SUN_SDK_ */
698 690
699 691 if (conn->serverFQDN)
700 692 sasl_FREE(conn->serverFQDN);
701 693
702 694 if (conn->external.auth_id)
703 695 sasl_FREE(conn->external.auth_id);
704 696
705 697 if(conn->encode_buf) {
706 698 if(conn->encode_buf->data) sasl_FREE(conn->encode_buf->data);
707 699 sasl_FREE(conn->encode_buf);
708 700 }
709 701
710 702 if(conn->error_buf)
711 703 sasl_FREE(conn->error_buf);
712 704
713 705 if(conn->errdetail_buf)
714 706 sasl_FREE(conn->errdetail_buf);
715 707
716 708 if(conn->decode_buf)
717 709 sasl_FREE(conn->decode_buf);
718 710
719 711 if(conn->mechlist_buf)
720 712 sasl_FREE(conn->mechlist_buf);
721 713
722 714 if(conn->service)
723 715 sasl_FREE(conn->service);
724 716
725 717 /* oparams sub-members should be freed by the plugin, in so much
726 718 * as they were allocated by the plugin */
727 719 }
728 720
729 721
730 722 /* get property from SASL connection state
731 723 * propnum -- property number
732 724 * pvalue -- pointer to value
733 725 * returns:
734 726 * SASL_OK -- no error
735 727 * SASL_NOTDONE -- property not available yet
736 728 * SASL_BADPARAM -- bad property number
737 729 */
738 730 int sasl_getprop(sasl_conn_t *conn, int propnum, const void **pvalue)
739 731 {
↓ open down ↓ |
287 lines elided |
↑ open up ↑ |
740 732 int result = SASL_OK;
741 733 sasl_getopt_t *getopt;
742 734 void *context;
743 735
744 736 if (! conn) return SASL_BADPARAM;
745 737 if (! pvalue) PARAMERROR(conn);
746 738
747 739 switch(propnum)
748 740 {
749 741 case SASL_SSF:
750 - /* EXPORT DELETE START */
751 - /* CRYPT DELETE START */
752 742 #ifdef _INTEGRATED_SOLARIS_
753 743 if (!conn->sun_reg)
754 744 conn->oparams.mech_ssf = 0;
755 745 #endif /* _INTEGRATED_SOLARIS_ */
756 - /* CRYPT DELETE END */
757 - /* EXPORT DELETE END */
758 746 *(sasl_ssf_t **)pvalue= &conn->oparams.mech_ssf;
759 747 break;
760 748 case SASL_MAXOUTBUF:
761 749 *(unsigned **)pvalue = &conn->oparams.maxoutbuf;
762 750 break;
763 751 case SASL_GETOPTCTX:
764 752 result = _sasl_getcallback(conn, SASL_CB_GETOPT, &getopt, &context);
765 753 if(result != SASL_OK) break;
766 754
767 755 *(void **)pvalue = context;
768 756 break;
769 757 case SASL_CALLBACK:
770 758 *(const sasl_callback_t **)pvalue = conn->callbacks;
771 759 break;
772 760 case SASL_IPLOCALPORT:
773 761 if(conn->got_ip_local)
774 762 *(const char **)pvalue = conn->iplocalport;
775 763 else {
776 764 *(const char **)pvalue = NULL;
777 765 result = SASL_NOTDONE;
778 766 }
779 767 break;
780 768 case SASL_IPREMOTEPORT:
781 769 if(conn->got_ip_remote)
782 770 *(const char **)pvalue = conn->ipremoteport;
783 771 else {
784 772 *(const char **)pvalue = NULL;
785 773 result = SASL_NOTDONE;
786 774 }
787 775 break;
788 776 case SASL_USERNAME:
789 777 if(! conn->oparams.user)
790 778 result = SASL_NOTDONE;
791 779 else
792 780 *((const char **)pvalue) = conn->oparams.user;
793 781 break;
794 782 case SASL_AUTHUSER:
795 783 if(! conn->oparams.authid)
796 784 result = SASL_NOTDONE;
797 785 else
798 786 *((const char **)pvalue) = conn->oparams.authid;
799 787 break;
800 788 case SASL_SERVERFQDN:
801 789 *((const char **)pvalue) = conn->serverFQDN;
802 790 break;
803 791 case SASL_DEFUSERREALM:
804 792 if(conn->type != SASL_CONN_SERVER) result = SASL_BADPROT;
805 793 else
806 794 *((const char **)pvalue) = ((sasl_server_conn_t *)conn)->user_realm;
807 795 break;
808 796 case SASL_SERVICE:
809 797 *((const char **)pvalue) = conn->service;
810 798 break;
811 799 case SASL_AUTHSOURCE: /* name of plugin (not name of mech) */
812 800 if(conn->type == SASL_CONN_CLIENT) {
813 801 if(!((sasl_client_conn_t *)conn)->mech) {
814 802 result = SASL_NOTDONE;
815 803 break;
816 804 }
817 805 *((const char **)pvalue) =
818 806 ((sasl_client_conn_t *)conn)->mech->plugname;
819 807 } else if (conn->type == SASL_CONN_SERVER) {
820 808 if(!((sasl_server_conn_t *)conn)->mech) {
821 809 result = SASL_NOTDONE;
822 810 break;
823 811 }
824 812 *((const char **)pvalue) =
825 813 ((sasl_server_conn_t *)conn)->mech->plugname;
826 814 } else {
827 815 result = SASL_BADPARAM;
828 816 }
829 817 break;
830 818 case SASL_MECHNAME: /* name of mech */
831 819 if(conn->type == SASL_CONN_CLIENT) {
832 820 if(!((sasl_client_conn_t *)conn)->mech) {
833 821 result = SASL_NOTDONE;
834 822 break;
835 823 }
836 824 *((const char **)pvalue) =
837 825 ((sasl_client_conn_t *)conn)->mech->plug->mech_name;
838 826 } else if (conn->type == SASL_CONN_SERVER) {
839 827 if(!((sasl_server_conn_t *)conn)->mech) {
840 828 result = SASL_NOTDONE;
841 829 break;
842 830 }
843 831 *((const char **)pvalue) =
844 832 ((sasl_server_conn_t *)conn)->mech->plug->mech_name;
845 833 } else {
846 834 result = SASL_BADPARAM;
847 835 }
848 836
849 837 if(!(*pvalue) && result == SASL_OK) result = SASL_NOTDONE;
850 838 break;
851 839 case SASL_PLUGERR:
852 840 *((const char **)pvalue) = conn->error_buf;
853 841 break;
854 842 case SASL_SSF_EXTERNAL:
855 843 *((const sasl_ssf_t **)pvalue) = &conn->external.ssf;
856 844 break;
857 845 case SASL_AUTH_EXTERNAL:
858 846 *((const char **)pvalue) = conn->external.auth_id;
859 847 break;
860 848 case SASL_SEC_PROPS:
861 849 *((const sasl_security_properties_t **)pvalue) = &conn->props;
862 850 break;
863 851 default:
864 852 result = SASL_BADPARAM;
865 853 }
866 854
867 855 if(result == SASL_BADPARAM) {
868 856 PARAMERROR(conn);
869 857 } else if(result == SASL_NOTDONE) {
870 858 #ifdef _SUN_SDK_
871 859 _sasl_log(conn, SASL_LOG_NONE,
872 860 "Information that was requested is not yet available.");
873 861 #else
874 862 sasl_seterror(conn, SASL_NOLOG,
875 863 "Information that was requested is not yet available.");
876 864 #endif /* _SUN_SDK_ */
877 865 RETURN(conn, result);
878 866 } else if(result != SASL_OK) {
879 867 INTERROR(conn, result);
880 868 } else
881 869 RETURN(conn, result);
882 870 #ifdef _SUN_SDK_
883 871 return SASL_OK;
884 872 #endif /* _SUN_SDK_ */
885 873 }
886 874
887 875 /* set property in SASL connection state
888 876 * returns:
889 877 * SASL_OK -- value set
890 878 * SASL_BADPARAM -- invalid property or value
891 879 */
892 880 int sasl_setprop(sasl_conn_t *conn, int propnum, const void *value)
893 881 {
894 882 int result = SASL_OK;
895 883 char *str;
896 884 #ifdef _SUN_SDK_
897 885 const _sasl_global_context_t *gctx;
898 886 #endif /* _SUN_SDK_ */
899 887
900 888 /* make sure the sasl context is valid */
901 889 if (!conn)
902 890 return SASL_BADPARAM;
903 891
904 892 #ifdef _SUN_SDK_
905 893 gctx = conn->gctx;
906 894 #endif /* _SUN_SDK_ */
907 895
908 896 switch(propnum)
909 897 {
910 898 case SASL_SSF_EXTERNAL:
911 899 conn->external.ssf = *((sasl_ssf_t *)value);
912 900 if(conn->type == SASL_CONN_SERVER) {
913 901 ((sasl_server_conn_t*)conn)->sparams->external_ssf =
914 902 conn->external.ssf;
915 903 } else {
916 904 ((sasl_client_conn_t*)conn)->cparams->external_ssf =
917 905 conn->external.ssf;
918 906 }
919 907 break;
920 908
921 909 case SASL_AUTH_EXTERNAL:
922 910 if(value && strlen(value)) {
923 911 result = _sasl_strdup(value, &str, NULL);
924 912 if(result != SASL_OK) MEMERROR(conn);
925 913 } else {
926 914 str = NULL;
927 915 }
928 916
929 917 if(conn->external.auth_id)
930 918 sasl_FREE(conn->external.auth_id);
931 919
932 920 conn->external.auth_id = str;
933 921
934 922 break;
935 923
936 924 case SASL_DEFUSERREALM:
937 925 if(conn->type != SASL_CONN_SERVER) {
938 926 #ifdef _SUN_SDK_
939 927 _sasl_log(conn, SASL_LOG_WARN,
940 928 "Tried to set realm on non-server connection");
941 929 #else
942 930 sasl_seterror(conn, 0, "Tried to set realm on non-server connection");
943 931 #endif /* _SUN_SDK_ */
944 932 result = SASL_BADPROT;
945 933 break;
946 934 }
947 935
948 936 if(value && strlen(value)) {
949 937 result = _sasl_strdup(value, &str, NULL);
950 938 if(result != SASL_OK) MEMERROR(conn);
951 939 } else {
952 940 PARAMERROR(conn);
953 941 }
954 942
955 943 if(((sasl_server_conn_t *)conn)->user_realm)
956 944 sasl_FREE(((sasl_server_conn_t *)conn)->user_realm);
957 945
958 946 ((sasl_server_conn_t *)conn)->user_realm = str;
959 947 ((sasl_server_conn_t *)conn)->sparams->user_realm = str;
960 948
961 949 break;
962 950
963 951 case SASL_SEC_PROPS:
964 952 {
965 953 sasl_security_properties_t *props = (sasl_security_properties_t *)value;
966 954
967 955 if(props->maxbufsize == 0 && props->min_ssf != 0) {
968 956 #ifdef _SUN_SDK_
969 957 _sasl_log(conn, SASL_LOG_ERR,
970 958 "Attempt to disable security layers (maxoutbuf == 0) with min_ssf > 0");
971 959 #else
972 960 sasl_seterror(conn, 0,
973 961 "Attempt to disable security layers (maxoutbuf == 0) with min_ssf > 0");
974 962 #endif /* _SUN_SDK_ */
975 963 RETURN(conn, SASL_TOOWEAK);
976 964 }
977 965
978 966 conn->props = *props;
979 967
980 968 if(conn->type == SASL_CONN_SERVER) {
981 969 ((sasl_server_conn_t*)conn)->sparams->props = *props;
982 970 } else {
983 971 ((sasl_client_conn_t*)conn)->cparams->props = *props;
984 972 }
985 973
986 974 break;
987 975 }
988 976
989 977 case SASL_IPREMOTEPORT:
990 978 {
991 979 const char *ipremoteport = (const char *)value;
992 980 if(!value) {
993 981 conn->got_ip_remote = 0;
994 982 #ifdef _SUN_SDK_
995 983 } else if (strlen(ipremoteport) >= sizeof (conn->ipremoteport)) {
996 984 RETURN(conn, SASL_BADPARAM);
997 985 #endif /* _SUN_SDK_ */
998 986 } else if (_sasl_ipfromstring(ipremoteport, NULL, 0)
999 987 != SASL_OK) {
1000 988 #ifdef _SUN_SDK_
1001 989 _sasl_log(conn, SASL_LOG_ERR, "Bad IPREMOTEPORT value");
1002 990 #else
1003 991 sasl_seterror(conn, 0, "Bad IPREMOTEPORT value");
1004 992 #endif /* _SUN_SDK_ */
1005 993 RETURN(conn, SASL_BADPARAM);
1006 994 } else {
1007 995 strcpy(conn->ipremoteport, ipremoteport);
1008 996 conn->got_ip_remote = 1;
1009 997 }
1010 998
1011 999 if(conn->got_ip_remote) {
1012 1000 if(conn->type == SASL_CONN_CLIENT) {
1013 1001 ((sasl_client_conn_t *)conn)->cparams->ipremoteport
1014 1002 = conn->ipremoteport;
1015 1003 ((sasl_client_conn_t *)conn)->cparams->ipremlen =
1016 1004 strlen(conn->ipremoteport);
1017 1005 } else if (conn->type == SASL_CONN_SERVER) {
1018 1006 ((sasl_server_conn_t *)conn)->sparams->ipremoteport
1019 1007 = conn->ipremoteport;
1020 1008 ((sasl_server_conn_t *)conn)->sparams->ipremlen =
1021 1009 strlen(conn->ipremoteport);
1022 1010 }
1023 1011 } else {
1024 1012 if(conn->type == SASL_CONN_CLIENT) {
1025 1013 ((sasl_client_conn_t *)conn)->cparams->ipremoteport
1026 1014 = NULL;
1027 1015 ((sasl_client_conn_t *)conn)->cparams->ipremlen = 0;
1028 1016 } else if (conn->type == SASL_CONN_SERVER) {
1029 1017 ((sasl_server_conn_t *)conn)->sparams->ipremoteport
1030 1018 = NULL;
1031 1019 ((sasl_server_conn_t *)conn)->sparams->ipremlen = 0;
1032 1020 }
1033 1021 }
1034 1022
1035 1023 break;
1036 1024 }
1037 1025
1038 1026 case SASL_IPLOCALPORT:
1039 1027 {
1040 1028 const char *iplocalport = (const char *)value;
1041 1029 if(!value) {
1042 1030 conn->got_ip_local = 0;
1043 1031 #ifdef _SUN_SDK_
1044 1032 } else if (strlen(iplocalport) >= sizeof (conn->iplocalport)) {
1045 1033 RETURN(conn, SASL_BADPARAM);
1046 1034 #endif /* _SUN_SDK_ */
1047 1035 } else if (_sasl_ipfromstring(iplocalport, NULL, 0)
1048 1036 != SASL_OK) {
1049 1037 #ifdef _SUN_SDK_
1050 1038 _sasl_log(conn, SASL_LOG_ERR, "Bad IPLOCALPORT value");
1051 1039 #else
1052 1040 sasl_seterror(conn, 0, "Bad IPLOCALPORT value");
1053 1041 #endif /* _SUN_SDK_ */
1054 1042 RETURN(conn, SASL_BADPARAM);
1055 1043 } else {
1056 1044 strcpy(conn->iplocalport, iplocalport);
1057 1045 conn->got_ip_local = 1;
1058 1046 }
1059 1047
1060 1048 if(conn->got_ip_local) {
1061 1049 if(conn->type == SASL_CONN_CLIENT) {
1062 1050 ((sasl_client_conn_t *)conn)->cparams->iplocalport
1063 1051 = conn->iplocalport;
1064 1052 ((sasl_client_conn_t *)conn)->cparams->iploclen
1065 1053 = strlen(conn->iplocalport);
1066 1054 } else if (conn->type == SASL_CONN_SERVER) {
1067 1055 ((sasl_server_conn_t *)conn)->sparams->iplocalport
1068 1056 = conn->iplocalport;
1069 1057 ((sasl_server_conn_t *)conn)->sparams->iploclen
1070 1058 = strlen(conn->iplocalport);
1071 1059 }
1072 1060 } else {
1073 1061 if(conn->type == SASL_CONN_CLIENT) {
1074 1062 ((sasl_client_conn_t *)conn)->cparams->iplocalport
1075 1063 = NULL;
1076 1064 ((sasl_client_conn_t *)conn)->cparams->iploclen = 0;
1077 1065 } else if (conn->type == SASL_CONN_SERVER) {
1078 1066 ((sasl_server_conn_t *)conn)->sparams->iplocalport
1079 1067 = NULL;
1080 1068 ((sasl_server_conn_t *)conn)->sparams->iploclen = 0;
1081 1069 }
1082 1070 }
1083 1071 break;
1084 1072 }
1085 1073
1086 1074 default:
1087 1075 #ifdef _SUN_SDK_
1088 1076 _sasl_log(conn, SASL_LOG_WARN, "Unknown parameter type");
1089 1077 #else
1090 1078 sasl_seterror(conn, 0, "Unknown parameter type");
1091 1079 #endif /* _SUN_SDK_ */
1092 1080 result = SASL_BADPARAM;
1093 1081 }
1094 1082
1095 1083 RETURN(conn, result);
1096 1084 }
1097 1085
1098 1086 /* this is apparently no longer a user function */
1099 1087 static int sasl_usererr(int saslerr)
1100 1088 {
1101 1089 /* Hide the difference in a username failure and a password failure */
1102 1090 if (saslerr == SASL_NOUSER)
1103 1091 return SASL_BADAUTH;
1104 1092
1105 1093 /* otherwise return the error given; no transform necessary */
1106 1094 return saslerr;
1107 1095 }
1108 1096
1109 1097 #ifdef _INTEGRATED_SOLARIS_
1110 1098 static void free_err_tsd(void *key)
1111 1099 {
1112 1100 free(key);
1113 1101 }
1114 1102 #endif /* _INTEGRATED_SOLARIS_ */
1115 1103
1116 1104 const char *sasl_errstring(int saslerr,
1117 1105 #ifdef _SUN_SDK_
1118 1106 const char *langlist,
1119 1107 #else
1120 1108 const char *langlist __attribute__((unused)),
1121 1109 #endif /* _SUN_SDK_ */
1122 1110 const char **outlang)
1123 1111 {
1124 1112 #ifdef _INTEGRATED_SOLARIS_
1125 1113 const char *s;
1126 1114 const char *s_locale;
1127 1115 char *s_utf8;
1128 1116 void *tsd;
1129 1117
1130 1118 if (outlang) *outlang="i-default";
1131 1119 #else
1132 1120 if (outlang) *outlang="en-us";
1133 1121 #endif /* _INTEGRATED_SOLARIS_ */
1134 1122
1135 1123 #ifdef _INTEGRATED_SOLARIS_
1136 1124 switch(saslerr)
1137 1125 {
1138 1126 case SASL_CONTINUE: s = gettext("another step is needed in authentication");
1139 1127 break;
1140 1128 case SASL_OK: s = gettext("successful result");
1141 1129 break;
1142 1130 case SASL_FAIL: s = gettext("generic failure");
1143 1131 break;
1144 1132 case SASL_NOMEM: s = gettext("no memory available");
1145 1133 break;
1146 1134 case SASL_BUFOVER: s = gettext("overflowed buffer");
1147 1135 break;
1148 1136 case SASL_NOMECH: s = gettext("no mechanism available");
1149 1137 break;
1150 1138 case SASL_BADPROT: s = gettext("bad protocol / cancel");
1151 1139 break;
1152 1140 case SASL_NOTDONE: s = gettext("can't request info until later in exchange");
1153 1141 break;
1154 1142 case SASL_BADPARAM: s = gettext("invalid parameter supplied");
1155 1143 break;
1156 1144 case SASL_TRYAGAIN: s = gettext("transient failure (e.g., weak key)");
1157 1145 break;
1158 1146 case SASL_BADMAC: s = gettext("integrity check failed");
1159 1147 break;
1160 1148 case SASL_NOTINIT: s = gettext("SASL library not initialized");
1161 1149 break;
1162 1150 /* -- client only codes -- */
1163 1151 case SASL_INTERACT: s = gettext("needs user interaction");
1164 1152 break;
1165 1153 case SASL_BADSERV: s = gettext("server failed mutual authentication step");
1166 1154 break;
1167 1155 case SASL_WRONGMECH: s = gettext("mechanism doesn't support requested feature");
1168 1156 break;
1169 1157 /* -- server only codes -- */
1170 1158 case SASL_BADAUTH: s = gettext("authentication failure");
1171 1159 break;
1172 1160 case SASL_NOAUTHZ: s = gettext("authorization failure");
1173 1161 break;
1174 1162 case SASL_TOOWEAK: s = gettext("mechanism too weak for this user");
1175 1163 break;
1176 1164 case SASL_ENCRYPT: s = gettext("encryption needed to use mechanism");
1177 1165 break;
1178 1166 case SASL_TRANS: s = gettext("One time use of a plaintext password will enable requested mechanism for user");
1179 1167 break;
1180 1168 case SASL_EXPIRED: s = gettext("passphrase expired, has to be reset");
1181 1169 break;
1182 1170 case SASL_DISABLED: s = gettext("account disabled");
1183 1171 break;
1184 1172 case SASL_NOUSER: s = gettext("user not found");
1185 1173 break;
1186 1174 case SASL_BADVERS: s = gettext("version mismatch with plug-in");
1187 1175 break;
1188 1176 case SASL_UNAVAIL: s = gettext("remote authentication server unavailable");
1189 1177 break;
1190 1178 case SASL_NOVERIFY: s = gettext("user exists, but no verifier for user");
1191 1179 break;
1192 1180 case SASL_PWLOCK: s = gettext("passphrase locked");
1193 1181 break;
1194 1182 case SASL_NOCHANGE: s = gettext("requested change was not needed");
1195 1183 break;
1196 1184 case SASL_WEAKPASS: s = gettext("passphrase is too weak for security policy");
1197 1185 break;
1198 1186 case SASL_NOUSERPASS: s = gettext("user supplied passwords are not permitted");
1199 1187
1200 1188 break;
1201 1189 default: s = gettext("undefined error!");
1202 1190 break;
1203 1191 }
1204 1192
1205 1193 if (use_locale(langlist, 0))
1206 1194 s_locale = dgettext(TEXT_DOMAIN, s);
1207 1195 else
1208 1196 s_locale = s;
1209 1197
1210 1198 if (s == s_locale)
1211 1199 return s;
1212 1200
1213 1201 s_utf8 = local_to_utf(NULL, s_locale);
1214 1202 if (s_utf8 == NULL)
1215 1203 return s;
1216 1204
1217 1205 if (pthread_key_create_once_np(&errstring_key, free_err_tsd) != 0) {
1218 1206 free(s_utf8);
1219 1207 return s;
1220 1208 }
1221 1209
1222 1210 tsd = pthread_getspecific(errstring_key);
1223 1211 if (tsd != NULL)
1224 1212 free(tsd);
1225 1213 pthread_setspecific(errstring_key, s_utf8);
1226 1214
1227 1215 if (outlang) *outlang="*";
1228 1216 return s_utf8;
1229 1217 #else
1230 1218 switch(saslerr)
1231 1219 {
1232 1220 case SASL_CONTINUE: return "another step is needed in authentication";
1233 1221 case SASL_OK: return "successful result";
1234 1222 case SASL_FAIL: return "generic failure";
1235 1223 case SASL_NOMEM: return "no memory available";
1236 1224 case SASL_BUFOVER: return "overflowed buffer";
1237 1225 case SASL_NOMECH: return "no mechanism available";
1238 1226 case SASL_BADPROT: return "bad protocol / cancel";
1239 1227 case SASL_NOTDONE: return "can't request info until later in exchange";
1240 1228 case SASL_BADPARAM: return "invalid parameter supplied";
1241 1229 case SASL_TRYAGAIN: return "transient failure (e.g., weak key)";
1242 1230 case SASL_BADMAC: return "integrity check failed";
1243 1231 case SASL_NOTINIT: return "SASL library not initialized";
1244 1232 /* -- client only codes -- */
1245 1233 case SASL_INTERACT: return "needs user interaction";
1246 1234 case SASL_BADSERV: return "server failed mutual authentication step";
1247 1235 case SASL_WRONGMECH: return "mechanism doesn't support requested feature";
1248 1236 /* -- server only codes -- */
1249 1237 case SASL_BADAUTH: return "authentication failure";
1250 1238 case SASL_NOAUTHZ: return "authorization failure";
1251 1239 case SASL_TOOWEAK: return "mechanism too weak for this user";
1252 1240 case SASL_ENCRYPT: return "encryption needed to use mechanism";
1253 1241 case SASL_TRANS: return "One time use of a plaintext password will enable requested mechanism for user";
1254 1242 case SASL_EXPIRED: return "passphrase expired, has to be reset";
1255 1243 case SASL_DISABLED: return "account disabled";
1256 1244 case SASL_NOUSER: return "user not found";
1257 1245 case SASL_BADVERS: return "version mismatch with plug-in";
1258 1246 case SASL_UNAVAIL: return "remote authentication server unavailable";
1259 1247 case SASL_NOVERIFY: return "user exists, but no verifier for user";
1260 1248 case SASL_PWLOCK: return "passphrase locked";
1261 1249 case SASL_NOCHANGE: return "requested change was not needed";
1262 1250 case SASL_WEAKPASS: return "passphrase is too weak for security policy";
1263 1251 case SASL_NOUSERPASS: return "user supplied passwords are not permitted";
1264 1252
1265 1253 default: return "undefined error!";
1266 1254 }
1267 1255 #endif /* _INTEGRATED_SOLARIS_ */
1268 1256
1269 1257 }
1270 1258
1271 1259 /* Return the sanitized error detail about the last error that occured for
1272 1260 * a connection */
1273 1261 const char *sasl_errdetail(sasl_conn_t *conn)
1274 1262 {
1275 1263 unsigned need_len;
1276 1264 const char *errstr;
1277 1265 char leader[128];
1278 1266 #ifdef _SUN_SDK_
1279 1267 int ret;
1280 1268 const _sasl_global_context_t *gctx;
1281 1269
1282 1270 if(!conn) return "invalid parameter supplied";
1283 1271
1284 1272 gctx = conn->gctx;
1285 1273 #else
1286 1274 if(!conn) return NULL;
1287 1275 #endif /* _SUN_SDK_ */
1288 1276
1289 1277 errstr = sasl_errstring(conn->error_code, NULL, NULL);
1290 1278 snprintf(leader,128,"SASL(%d): %s: ",
1291 1279 sasl_usererr(conn->error_code), errstr);
1292 1280
1293 1281 need_len = strlen(leader) + strlen(conn->error_buf) + 12;
1294 1282 #ifdef _SUN_SDK_
1295 1283 ret = _buf_alloc(&conn->errdetail_buf, &conn->errdetail_buf_len, need_len);
1296 1284 if (ret != SASL_OK)
↓ open down ↓ |
529 lines elided |
↑ open up ↑ |
1297 1285 return "no memory available";
1298 1286 #else
1299 1287 _buf_alloc(&conn->errdetail_buf, &conn->errdetail_buf_len, need_len);
1300 1288 #endif /* _SUN_SDK_ */
1301 1289
1302 1290 snprintf(conn->errdetail_buf, need_len, "%s%s", leader, conn->error_buf);
1303 1291
1304 1292 return conn->errdetail_buf;
1305 1293 }
1306 1294
1307 -/* EXPORT DELETE START */
1308 -/* CRYPT DELETE START */
1309 1295 #ifdef _INTEGRATED_SOLARIS_
1310 1296 DEFINE_STATIC_MUTEX(reg_mutex);
1311 1297 typedef struct reg_list {
1312 1298 struct reg_list *next;
1313 1299 void *mech;
1314 1300 } reg_list_t;
1315 1301
1316 1302 static reg_list_t *reg_list_base = NULL;
1317 1303
1318 1304 int _is_sun_reg(void *mech)
1319 1305 {
1320 1306 reg_list_t *r, *prev;
1321 1307 int is_reg = 0;
1322 1308
1323 1309 LOCK_MUTEX(®_mutex);
1324 1310 for (r = reg_list_base; r != NULL; r = r->next) {
1325 1311 if (r->mech != mech) {
1326 1312 prev = r;
1327 1313 continue;
1328 1314 }
1329 1315 is_reg = 1;
1330 1316 if (r == reg_list_base) {
1331 1317 reg_list_base = reg_list_base->next;
1332 1318 } else {
1333 1319 prev->next = r->next;
1334 1320 }
1335 1321 free(r);
1336 1322 break;
1337 1323 }
1338 1324 UNLOCK_MUTEX(®_mutex);
1339 1325 return (is_reg);
1340 1326 }
1341 1327
1342 1328 static void
1343 1329 _register_plugin(void *arg)
1344 1330 {
1345 1331 reg_list_t *r = (reg_list_t *)calloc(1, sizeof (reg_list_t));
↓ open down ↓ |
27 lines elided |
↑ open up ↑ |
1346 1332
1347 1333 if (r != NULL) {
1348 1334 r->mech = arg;
1349 1335 LOCK_MUTEX(®_mutex);
1350 1336 r->next = reg_list_base;
1351 1337 reg_list_base = r;
1352 1338 UNLOCK_MUTEX(®_mutex);
1353 1339 }
1354 1340 }
1355 1341 #endif /* _INTEGRATED_SOLARIS_ */
1356 -/* CRYPT DELETE END */
1357 -/* EXPORT DELETE END */
1358 1342
1359 1343 /* Note that this needs the global callbacks, so if you don't give getcallbacks
1360 1344 * a sasl_conn_t, you're going to need to pass it yourself (or else we couldn't
1361 1345 * have client and server at the same time */
1362 1346 static int _sasl_global_getopt(void *context,
1363 1347 const char *plugin_name,
1364 1348 const char *option,
1365 1349 const char ** result,
1366 1350 unsigned *len)
1367 1351 {
1368 1352 const sasl_global_callbacks_t * global_callbacks;
1369 1353 const sasl_callback_t *callback;
1370 1354 #ifdef _SUN_SDK_
1371 1355 _sasl_global_context_t *gctx;
1372 1356 #endif /* _SUN_SDK_ */
1373 1357
1374 1358 global_callbacks = (const sasl_global_callbacks_t *) context;
1375 1359
1376 1360 #ifdef _SUN_SDK_
1377 - /* EXPORT DELETE START */
1378 - /* CRYPT DELETE START */
1379 1361 #ifdef _INTEGRATED_SOLARIS_
1380 1362 if (strcmp("reg_sun_plug", option) == 0) {
1381 1363 *result = (const char *)_register_plugin;
1382 1364 *len = 0;
1383 1365 return (SASL_OK);
1384 1366 }
1385 1367 #endif /* _INTEGRATED_SOLARIS_ */
1386 - /* CRYPT DELETE END */
1387 - /* EXPORT DELETE END */
1388 1368
1389 1369 if (global_callbacks)
1390 1370 gctx = global_callbacks->gctx;
1391 1371 else
1392 1372 gctx = _sasl_gbl_ctx();
1393 1373 #endif /* _SUN_SDK_ */
1394 1374
1395 1375 if (global_callbacks && global_callbacks->callbacks) {
1396 1376 for (callback = global_callbacks->callbacks;
1397 1377 callback->id != SASL_CB_LIST_END;
1398 1378 callback++) {
1399 1379 if (callback->id == SASL_CB_GETOPT) {
1400 1380 if (!callback->proc) return SASL_FAIL;
1401 1381 if (((sasl_getopt_t *)(callback->proc))(callback->context,
1402 1382 plugin_name,
1403 1383 option,
1404 1384 result,
1405 1385 len)
1406 1386 == SASL_OK)
1407 1387 return SASL_OK;
1408 1388 }
1409 1389 }
1410 1390 }
1411 1391
1412 1392 /* look it up in our configuration file */
1413 1393 #ifdef _SUN_SDK_
1414 1394 *result = sasl_config_getstring(gctx, option, NULL);
1415 1395 #else
1416 1396 *result = sasl_config_getstring(option, NULL);
1417 1397 #endif /* _SUN_SDK_ */
1418 1398 if (*result != NULL) {
1419 1399 if (len) { *len = strlen(*result); }
1420 1400 return SASL_OK;
1421 1401 }
1422 1402
1423 1403 return SASL_FAIL;
1424 1404 }
1425 1405
1426 1406 static int
1427 1407 _sasl_conn_getopt(void *context,
1428 1408 const char *plugin_name,
1429 1409 const char *option,
1430 1410 const char ** result,
1431 1411 unsigned *len)
1432 1412 {
1433 1413 sasl_conn_t * conn;
1434 1414 const sasl_callback_t *callback;
1435 1415
1436 1416 if (! context)
1437 1417 return SASL_BADPARAM;
1438 1418
1439 1419 conn = (sasl_conn_t *) context;
1440 1420
1441 1421 if (conn->callbacks)
1442 1422 for (callback = conn->callbacks;
1443 1423 callback->id != SASL_CB_LIST_END;
1444 1424 callback++)
1445 1425 if (callback->id == SASL_CB_GETOPT
1446 1426 && (((sasl_getopt_t *)(callback->proc))(callback->context,
1447 1427 plugin_name,
1448 1428 option,
1449 1429 result,
1450 1430 len)
1451 1431 == SASL_OK))
1452 1432 return SASL_OK;
1453 1433
1454 1434 /* If we made it here, we didn't find an appropriate callback
1455 1435 * in the connection's callback list, or the callback we did
1456 1436 * find didn't return SASL_OK. So we attempt to use the
1457 1437 * global callback for this connection... */
1458 1438 return _sasl_global_getopt((void *)conn->global_callbacks,
1459 1439 plugin_name,
1460 1440 option,
1461 1441 result,
1462 1442 len);
1463 1443 }
1464 1444
1465 1445 #ifdef HAVE_SYSLOG
1466 1446 /* this is the default logging */
1467 1447 static int _sasl_syslog(void *context __attribute__((unused)),
1468 1448 int priority,
1469 1449 const char *message)
1470 1450 {
1471 1451 int syslog_priority;
1472 1452
1473 1453 /* set syslog priority */
1474 1454 switch(priority) {
1475 1455 case SASL_LOG_NONE:
1476 1456 return SASL_OK;
1477 1457 break;
1478 1458 case SASL_LOG_ERR:
1479 1459 syslog_priority = LOG_ERR;
1480 1460 break;
1481 1461 case SASL_LOG_WARN:
1482 1462 syslog_priority = LOG_WARNING;
1483 1463 break;
1484 1464 case SASL_LOG_NOTE:
1485 1465 case SASL_LOG_FAIL:
1486 1466 syslog_priority = LOG_NOTICE;
1487 1467 break;
1488 1468 case SASL_LOG_PASS:
1489 1469 case SASL_LOG_TRACE:
1490 1470 case SASL_LOG_DEBUG:
1491 1471 default:
1492 1472 syslog_priority = LOG_DEBUG;
1493 1473 break;
1494 1474 }
1495 1475
1496 1476 /* do the syslog call. do not need to call openlog */
1497 1477 syslog(syslog_priority | LOG_AUTH, "%s", message);
1498 1478
1499 1479 return SASL_OK;
1500 1480 }
1501 1481 #endif /* HAVE_SYSLOG */
1502 1482
1503 1483 static int
1504 1484 _sasl_getsimple(void *context,
1505 1485 int id,
1506 1486 const char ** result,
1507 1487 size_t *len)
1508 1488 {
1509 1489 const char *userid;
1510 1490 #ifndef _SUN_SDK_
1511 1491 sasl_conn_t *conn;
1512 1492 #endif /* _SUN_SDK_ */
1513 1493
1514 1494 if (! context || ! result) return SASL_BADPARAM;
1515 1495
1516 1496 #ifndef _SUN_SDK_
1517 1497 conn = (sasl_conn_t *)context;
1518 1498 #endif /* _SUN_SDK_ */
1519 1499
1520 1500 switch(id) {
1521 1501 case SASL_CB_AUTHNAME:
1522 1502 #ifdef _INTEGRATED_SOLARIS_
1523 1503 userid = getenv("LOGNAME");
1524 1504 if (userid != NULL) {
1525 1505 *result = userid;
1526 1506 if (len) *len = strlen(userid);
1527 1507 return SASL_OK;
1528 1508 }
1529 1509 #else
1530 1510 userid = getenv("USER");
1531 1511 if (userid != NULL) {
1532 1512 *result = userid;
1533 1513 if (len) *len = strlen(userid);
1534 1514 return SASL_OK;
1535 1515 }
1536 1516 userid = getenv("USERNAME");
1537 1517 if (userid != NULL) {
1538 1518 *result = userid;
1539 1519 if (len) *len = strlen(userid);
1540 1520 return SASL_OK;
1541 1521 }
1542 1522 #endif /* _INTEGRATED_SOLARIS_ */
1543 1523 #ifdef WIN32
1544 1524 /* for win32, try using the GetUserName standard call */
1545 1525 {
1546 1526 DWORD i;
1547 1527 BOOL rval;
1548 1528 static char sender[128];
1549 1529
1550 1530 i = sizeof(sender);
1551 1531 rval = GetUserName(sender, &i);
1552 1532 if ( rval) { /* got a userid */
1553 1533 *result = sender;
1554 1534 if (len) *len = strlen(sender);
1555 1535 return SASL_OK;
1556 1536 }
1557 1537 }
1558 1538 #endif /* WIN32 */
1559 1539 return SASL_FAIL;
1560 1540 default:
1561 1541 return SASL_BADPARAM;
1562 1542 }
1563 1543 }
1564 1544
1565 1545 static int
1566 1546 _sasl_verifyfile(void *context __attribute__((unused)),
1567 1547 char *file __attribute__((unused)),
1568 1548 int type __attribute__((unused)))
1569 1549 {
1570 1550 /* always say ok */
1571 1551 return SASL_OK;
1572 1552 }
1573 1553
1574 1554
1575 1555 static int
1576 1556 _sasl_proxy_policy(sasl_conn_t *conn,
1577 1557 void *context __attribute__((unused)),
1578 1558 const char *requested_user, unsigned rlen,
1579 1559 const char *auth_identity, unsigned alen,
1580 1560 const char *def_realm __attribute__((unused)),
1581 1561 unsigned urlen __attribute__((unused)),
1582 1562 struct propctx *propctx __attribute__((unused)))
1583 1563 {
1584 1564 if (!conn)
1585 1565 return SASL_BADPARAM;
1586 1566
1587 1567 if (!requested_user || *requested_user == '\0')
1588 1568 return SASL_OK;
1589 1569
1590 1570 if (!auth_identity || !requested_user || rlen != alen ||
1591 1571 (memcmp(auth_identity, requested_user, rlen) != 0)) {
1592 1572 #ifdef _INTEGRATED_SOLARIS_
1593 1573 sasl_seterror(conn, 0,
1594 1574 gettext("Requested identity not authenticated identity"));
1595 1575 #else
1596 1576 sasl_seterror(conn, 0,
1597 1577 "Requested identity not authenticated identity");
1598 1578 #endif /* _INTEGRATED_SOLARIS_ */
1599 1579 RETURN(conn, SASL_BADAUTH);
1600 1580 }
1601 1581
1602 1582 return SASL_OK;
1603 1583 }
1604 1584
1605 1585 int _sasl_getcallback(sasl_conn_t * conn,
1606 1586 unsigned long callbackid,
1607 1587 int (**pproc)(),
1608 1588 void **pcontext)
1609 1589 {
1610 1590 const sasl_callback_t *callback;
1611 1591
1612 1592 if (!pproc || !pcontext)
1613 1593 PARAMERROR(conn);
1614 1594
1615 1595 /* Some callbacks are always provided by the library */
1616 1596 switch (callbackid) {
1617 1597 case SASL_CB_LIST_END:
1618 1598 /* Nothing ever gets to provide this */
1619 1599 INTERROR(conn, SASL_FAIL);
1620 1600 #ifdef _SUN_SDK_
1621 1601 break;
1622 1602 #endif /* _SUN_SDK_ */
1623 1603 case SASL_CB_GETOPT:
1624 1604 if (conn) {
1625 1605 *pproc = &_sasl_conn_getopt;
1626 1606 *pcontext = conn;
1627 1607 } else {
1628 1608 *pproc = &_sasl_global_getopt;
1629 1609 *pcontext = NULL;
1630 1610 }
1631 1611 return SASL_OK;
1632 1612 }
1633 1613
1634 1614 /* If it's not always provided by the library, see if there's
1635 1615 * a version provided by the application for this connection... */
1636 1616 if (conn && conn->callbacks) {
1637 1617 for (callback = conn->callbacks; callback->id != SASL_CB_LIST_END;
1638 1618 callback++) {
1639 1619 if (callback->id == callbackid) {
1640 1620 *pproc = callback->proc;
1641 1621 *pcontext = callback->context;
1642 1622 if (callback->proc) {
1643 1623 return SASL_OK;
1644 1624 } else {
1645 1625 return SASL_INTERACT;
1646 1626 }
1647 1627 }
1648 1628 }
1649 1629 }
1650 1630
1651 1631 /* And, if not for this connection, see if there's one
1652 1632 * for all {server,client} connections... */
1653 1633 if (conn && conn->global_callbacks && conn->global_callbacks->callbacks) {
1654 1634 for (callback = conn->global_callbacks->callbacks;
1655 1635 callback->id != SASL_CB_LIST_END;
1656 1636 callback++) {
1657 1637 if (callback->id == callbackid) {
1658 1638 *pproc = callback->proc;
1659 1639 *pcontext = callback->context;
1660 1640 if (callback->proc) {
1661 1641 return SASL_OK;
1662 1642 } else {
1663 1643 return SASL_INTERACT;
1664 1644 }
1665 1645 }
1666 1646 }
1667 1647 }
1668 1648
1669 1649 /* Otherwise, see if the library provides a default callback. */
1670 1650 switch (callbackid) {
1671 1651 #ifdef HAVE_SYSLOG
1672 1652 case SASL_CB_LOG:
1673 1653 *pproc = (int (*)()) &_sasl_syslog;
1674 1654 *pcontext = NULL;
1675 1655 return SASL_OK;
1676 1656 #endif /* HAVE_SYSLOG */
1677 1657 case SASL_CB_GETPATH:
1678 1658 *pproc = (int (*)()) &_sasl_getpath;
1679 1659 *pcontext = NULL;
1680 1660 return SASL_OK;
1681 1661 case SASL_CB_AUTHNAME:
1682 1662 *pproc = (int (*)()) &_sasl_getsimple;
1683 1663 *pcontext = conn;
1684 1664 return SASL_OK;
1685 1665 case SASL_CB_VERIFYFILE:
1686 1666 *pproc = & _sasl_verifyfile;
1687 1667 *pcontext = NULL;
1688 1668 return SASL_OK;
1689 1669 case SASL_CB_PROXY_POLICY:
1690 1670 *pproc = (int (*)()) &_sasl_proxy_policy;
1691 1671 *pcontext = NULL;
1692 1672 return SASL_OK;
1693 1673 }
1694 1674
1695 1675 /* Unable to find a callback... */
1696 1676 *pproc = NULL;
1697 1677 *pcontext = NULL;
1698 1678 #ifdef _SUN_SDK_
1699 1679 if (callbackid != SASL_CB_LANGUAGE)
1700 1680 _sasl_log(conn, SASL_LOG_NONE, "Unable to find a callback: %d", callbackid);
1701 1681 #else
1702 1682 sasl_seterror(conn, SASL_NOLOG, "Unable to find a callback: %d", callbackid);
1703 1683 #endif /* _SUN_SDK_ */
1704 1684 RETURN(conn,SASL_FAIL);
1705 1685 }
1706 1686
1707 1687
1708 1688 #ifdef _SUN_SDK_
1709 1689 static void ___sasl_log (const _sasl_global_context_t *gctx,
1710 1690 sasl_log_t *log_cb, void *log_ctx,
1711 1691 int level, const char *fmt, va_list ap);
1712 1692 #endif /* _SUN_SDK_ */
1713 1693 /*
1714 1694 * This function is typically called from a plugin.
1715 1695 * It creates a string from the formatting and varargs given
1716 1696 * and calls the logging callback (syslog by default)
1717 1697 *
1718 1698 * %m will parse the value in the next argument as an errno string
1719 1699 * %z will parse the next argument as a SASL error code.
1720 1700 */
1721 1701
1722 1702 void
1723 1703 _sasl_log (sasl_conn_t *conn,
1724 1704 int level,
1725 1705 const char *fmt,
1726 1706 ...)
1727 1707 #ifdef _SUN_SDK_
1728 1708 {
1729 1709 _sasl_global_context_t *gctx = conn==NULL ? _sasl_gbl_ctx() : conn->gctx;
1730 1710 sasl_log_t *log_cb;
1731 1711 void *log_ctx;
1732 1712 int result;
1733 1713 va_list ap;
1734 1714
1735 1715 /* See if we have a logging callback... */
1736 1716 result = _sasl_getcallback(conn, SASL_CB_LOG, &log_cb, &log_ctx);
1737 1717 if (result == SASL_OK && ! log_cb)
1738 1718 return;
1739 1719
1740 1720 va_start(ap, fmt); /* start varargs */
1741 1721 ___sasl_log(gctx, log_cb, log_ctx, level, fmt, ap);
1742 1722 va_end(ap);
1743 1723 }
1744 1724
1745 1725 void
1746 1726 __sasl_log(const _sasl_global_context_t *gctx,
1747 1727 const sasl_callback_t *callbacks,
1748 1728 int level,
1749 1729 const char *fmt,
1750 1730 ...)
1751 1731 {
1752 1732 sasl_log_t *log_cb = NULL;
1753 1733 void *log_ctx = NULL;
1754 1734 int result;
1755 1735 va_list ap;
1756 1736
1757 1737 if (callbacks)
1758 1738 while (callbacks->id != SASL_CB_LIST_END) {
1759 1739 if (callbacks->id == SASL_CB_LOG) {
1760 1740 log_cb = callbacks->proc;
1761 1741 log_ctx = callbacks->context;
1762 1742 break;
1763 1743 }
1764 1744 ++callbacks;
1765 1745 }
1766 1746
1767 1747 if (log_cb == NULL) {
1768 1748 result = _sasl_getcallback(NULL, SASL_CB_LOG, &log_cb, &log_ctx);
1769 1749 if (result != SASL_OK || ! log_cb)
1770 1750 return;
1771 1751 }
1772 1752
1773 1753 if (gctx == NULL)
1774 1754 gctx = _sasl_gbl_ctx();
1775 1755
1776 1756 va_start(ap, fmt); /* start varargs */
1777 1757 ___sasl_log(gctx, log_cb, log_ctx, level, fmt, ap);
1778 1758 va_end(ap);
1779 1759 }
1780 1760
1781 1761 static void
1782 1762 ___sasl_log(const _sasl_global_context_t *gctx,
1783 1763 sasl_log_t *log_cb,
1784 1764 void *log_ctx,
1785 1765 int level,
1786 1766 const char *fmt,
1787 1767 va_list ap)
1788 1768 #endif /* _SUN_SDK_ */
1789 1769 {
1790 1770 char *out=(char *) sasl_ALLOC(250);
1791 1771 size_t alloclen=100; /* current allocated length */
1792 1772 size_t outlen=0; /* current length of output buffer */
1793 1773 size_t formatlen;
1794 1774 size_t pos=0; /* current position in format string */
1795 1775 int result;
1796 1776 #ifndef _SUN_SDK_
1797 1777 sasl_log_t *log_cb;
1798 1778 void *log_ctx;
1799 1779 #endif /* !_SUN_SDK_ */
1800 1780
1801 1781 int ival;
1802 1782 char *cval;
1803 1783 #ifndef _SUN_SDK_
1804 1784 va_list ap; /* varargs thing */
1805 1785 #endif /* !_SUN_SDK_ */
1806 1786
1807 1787 if(!fmt) goto done;
1808 1788 if(!out) return;
1809 1789
1810 1790 formatlen = strlen(fmt);
1811 1791
1812 1792 #ifndef _SUN_SDK_
1813 1793 /* See if we have a logging callback... */
1814 1794 result = _sasl_getcallback(conn, SASL_CB_LOG, &log_cb, &log_ctx);
1815 1795 if (result == SASL_OK && ! log_cb)
1816 1796 result = SASL_FAIL;
1817 1797 if (result != SASL_OK) goto done;
1818 1798
1819 1799 va_start(ap, fmt); /* start varargs */
1820 1800 #endif /* !_SUN_SDK_ */
1821 1801
1822 1802 while(pos<formatlen)
1823 1803 {
1824 1804 if (fmt[pos]!='%') /* regular character */
1825 1805 {
1826 1806 result = _buf_alloc(&out, &alloclen, outlen+1);
1827 1807 if (result != SASL_OK) goto done;
1828 1808 out[outlen]=fmt[pos];
1829 1809 outlen++;
1830 1810 pos++;
1831 1811
1832 1812 } else { /* formating thing */
1833 1813 int done=0;
1834 1814 char frmt[10];
1835 1815 int frmtpos=1;
1836 1816 char tempbuf[21];
1837 1817 frmt[0]='%';
1838 1818 pos++;
1839 1819
1840 1820 while (done==0)
1841 1821 {
1842 1822 switch(fmt[pos])
1843 1823 {
1844 1824 case 's': /* need to handle this */
1845 1825 cval = va_arg(ap, char *); /* get the next arg */
1846 1826 result = _sasl_add_string(&out, &alloclen,
1847 1827 &outlen, cval);
1848 1828
1849 1829 if (result != SASL_OK) /* add the string */
1850 1830 goto done;
1851 1831
1852 1832 done=1;
1853 1833 break;
1854 1834
1855 1835 case '%': /* double % output the '%' character */
1856 1836 result = _buf_alloc(&out,&alloclen,outlen+1);
1857 1837 if (result != SASL_OK)
1858 1838 goto done;
1859 1839
1860 1840 out[outlen]='%';
1861 1841 outlen++;
1862 1842 done=1;
1863 1843 break;
1864 1844
1865 1845 case 'm': /* insert the errno string */
1866 1846 result = _sasl_add_string(&out, &alloclen, &outlen,
1867 1847 strerror(va_arg(ap, int)));
1868 1848 if (result != SASL_OK)
1869 1849 goto done;
1870 1850
1871 1851 done=1;
1872 1852 break;
1873 1853
1874 1854 case 'z': /* insert the sasl error string */
1875 1855 result = _sasl_add_string(&out, &alloclen, &outlen,
1876 1856 (char *) sasl_errstring(va_arg(ap, int),NULL,NULL));
1877 1857 if (result != SASL_OK)
1878 1858 goto done;
1879 1859
1880 1860 done=1;
1881 1861 break;
1882 1862
1883 1863 case 'c':
1884 1864 #ifndef _SUN_SDK_
1885 1865 frmt[frmtpos++]=fmt[pos];
1886 1866 frmt[frmtpos]=0;
1887 1867 #endif /* !_SUN_SDK_ */
1888 1868 tempbuf[0] = (char) va_arg(ap, int); /* get the next arg */
1889 1869 tempbuf[1]='\0';
1890 1870
1891 1871 /* now add the character */
1892 1872 result = _sasl_add_string(&out, &alloclen, &outlen, tempbuf);
1893 1873 if (result != SASL_OK)
1894 1874 goto done;
1895 1875
1896 1876 done=1;
1897 1877 break;
1898 1878
1899 1879 case 'd':
1900 1880 case 'i':
1901 1881 frmt[frmtpos++]=fmt[pos];
1902 1882 frmt[frmtpos]=0;
1903 1883 ival = va_arg(ap, int); /* get the next arg */
1904 1884
1905 1885 snprintf(tempbuf,20,frmt,ival); /* have snprintf do the work */
1906 1886 /* now add the string */
1907 1887 result = _sasl_add_string(&out, &alloclen, &outlen, tempbuf);
1908 1888 if (result != SASL_OK)
1909 1889 goto done;
1910 1890
1911 1891 done=1;
1912 1892
1913 1893 break;
1914 1894 default:
1915 1895 frmt[frmtpos++]=fmt[pos]; /* add to the formating */
1916 1896 frmt[frmtpos]=0;
1917 1897 #ifdef _SUN_SDK_
1918 1898 if (frmtpos > sizeof (frmt) - 2)
1919 1899 #else
1920 1900 if (frmtpos>9)
1921 1901 #endif /* _SUN_SDK_ */
1922 1902 done=1;
1923 1903 }
1924 1904 pos++;
1925 1905 if (pos>formatlen)
1926 1906 done=1;
1927 1907 }
1928 1908
1929 1909 }
1930 1910 }
1931 1911
1932 1912 /* put 0 at end */
1933 1913 result = _buf_alloc(&out, &alloclen, outlen+1);
1934 1914 if (result != SASL_OK) goto done;
1935 1915 out[outlen]=0;
1936 1916
1937 1917 va_end(ap);
1938 1918
1939 1919 /* send log message */
1940 1920 result = log_cb(log_ctx, level, out);
1941 1921
1942 1922 done:
1943 1923 if(out) sasl_FREE(out);
1944 1924 }
1945 1925
1946 1926
1947 1927
1948 1928 /* Allocate and Init a sasl_utils_t structure */
1949 1929 #ifdef _SUN_SDK_
1950 1930 sasl_utils_t *
1951 1931 _sasl_alloc_utils(_sasl_global_context_t *gctx, sasl_conn_t *conn,
1952 1932 sasl_global_callbacks_t *global_callbacks)
1953 1933 #else
1954 1934 sasl_utils_t *
1955 1935 _sasl_alloc_utils(sasl_conn_t *conn,
1956 1936 sasl_global_callbacks_t *global_callbacks)
1957 1937 #endif /* _SUN_SDK_ */
1958 1938 {
1959 1939 sasl_utils_t *utils;
1960 1940 #ifdef _SUN_SDK_
1961 1941 sasl_allocation_utils_t alloc;
1962 1942 sasl_mutex_utils_t mutex;
1963 1943
1964 1944 LOCK_MUTEX(&malloc_global_mutex);
1965 1945 alloc = gctx->sasl_allocation_utils;
1966 1946 mutex = gctx->sasl_mutex_utils;
1967 1947 UNLOCK_MUTEX(&malloc_global_mutex);
1968 1948 #endif /* _SUN_SDK_ */
1969 1949
1970 1950 /* set util functions - need to do rest*/
1971 1951 #ifdef _SUN_SDK_
1972 1952 utils=alloc.malloc(sizeof(sasl_utils_t));
1973 1953 #else
1974 1954 utils=sasl_ALLOC(sizeof(sasl_utils_t));
1975 1955 #endif /* _SUN_SDK_ */
1976 1956 if (utils==NULL)
1977 1957 return NULL;
1978 1958
1979 1959 utils->conn = conn;
1980 1960
1981 1961 sasl_randcreate(&utils->rpool);
1982 1962
1983 1963 if (conn) {
1984 1964 utils->getopt = &_sasl_conn_getopt;
1985 1965 utils->getopt_context = conn;
1986 1966 } else {
1987 1967 utils->getopt = &_sasl_global_getopt;
1988 1968 utils->getopt_context = global_callbacks;
1989 1969 }
1990 1970
1991 1971 #ifdef _SUN_SDK_
1992 1972 utils->malloc=alloc.malloc;
1993 1973 utils->calloc=alloc.calloc;
1994 1974 utils->realloc=alloc.realloc;
1995 1975 utils->free=alloc.free;
1996 1976
1997 1977 utils->mutex_alloc = mutex.alloc;
1998 1978 utils->mutex_lock = mutex.lock;
1999 1979 utils->mutex_unlock = mutex.unlock;
2000 1980 utils->mutex_free = mutex.free;
2001 1981 #else
2002 1982 utils->malloc=_sasl_allocation_utils.malloc;
2003 1983 utils->calloc=_sasl_allocation_utils.calloc;
2004 1984 utils->realloc=_sasl_allocation_utils.realloc;
2005 1985 utils->free=_sasl_allocation_utils.free;
2006 1986
2007 1987 utils->mutex_alloc = _sasl_mutex_utils.alloc;
2008 1988 utils->mutex_lock = _sasl_mutex_utils.lock;
2009 1989 utils->mutex_unlock = _sasl_mutex_utils.unlock;
2010 1990 utils->mutex_free = _sasl_mutex_utils.free;
2011 1991 #endif /* _SUN_SDK_ */
2012 1992
2013 1993 #ifdef _SUN_SDK_
2014 1994 utils->MD5Init = (void (*)(MD5_CTX *))&MD5Init;
2015 1995 utils->MD5Update= (void (*)
2016 1996 (MD5_CTX *, const unsigned char *, unsigned int ))&MD5Update;
2017 1997 utils->MD5Final = (void (*)(unsigned char [16], MD5_CTX *))&MD5Final;
2018 1998 #else
2019 1999 utils->MD5Init = &_sasl_MD5Init;
2020 2000 utils->MD5Update= &_sasl_MD5Update;
2021 2001 utils->MD5Final = &_sasl_MD5Final;
2022 2002 #endif /* _SUN_SDK_ */
2023 2003 utils->hmac_md5 = &_sasl_hmac_md5;
2024 2004 utils->hmac_md5_init = &_sasl_hmac_md5_init;
2025 2005 utils->hmac_md5_final = &_sasl_hmac_md5_final;
2026 2006 utils->hmac_md5_precalc = &_sasl_hmac_md5_precalc;
2027 2007 utils->hmac_md5_import = &_sasl_hmac_md5_import;
2028 2008 utils->mkchal = &sasl_mkchal;
2029 2009 utils->utf8verify = &sasl_utf8verify;
2030 2010 utils->rand=&sasl_rand;
2031 2011 utils->churn=&sasl_churn;
2032 2012 utils->checkpass=NULL;
2033 2013
2034 2014 utils->encode64=&sasl_encode64;
2035 2015 utils->decode64=&sasl_decode64;
2036 2016
2037 2017 utils->erasebuffer=&sasl_erasebuffer;
2038 2018
2039 2019 utils->getprop=&sasl_getprop;
2040 2020 utils->setprop=&sasl_setprop;
2041 2021
2042 2022 utils->getcallback=&_sasl_getcallback;
2043 2023
2044 2024 utils->log=&_sasl_log;
2045 2025
2046 2026 utils->seterror=&sasl_seterror;
2047 2027
2048 2028 #ifndef macintosh
2049 2029 /* Aux Property Utilities */
2050 2030 utils->prop_new=&prop_new;
2051 2031 utils->prop_dup=&prop_dup;
2052 2032 utils->prop_request=&prop_request;
2053 2033 utils->prop_get=&prop_get;
2054 2034 utils->prop_getnames=&prop_getnames;
2055 2035 utils->prop_clear=&prop_clear;
2056 2036 utils->prop_dispose=&prop_dispose;
2057 2037 utils->prop_format=&prop_format;
2058 2038 utils->prop_set=&prop_set;
2059 2039 utils->prop_setvals=&prop_setvals;
2060 2040 utils->prop_erase=&prop_erase;
2061 2041 #endif
2062 2042
2063 2043 /* Spares */
2064 2044 utils->spare_fptr = NULL;
2065 2045 utils->spare_fptr1 = utils->spare_fptr2 =
2066 2046 utils->spare_fptr3 = NULL;
2067 2047
2068 2048 return utils;
2069 2049 }
2070 2050
2071 2051 int
2072 2052 _sasl_free_utils(const sasl_utils_t ** utils)
2073 2053 {
2074 2054 sasl_utils_t *nonconst;
2075 2055 #ifdef _SUN_SDK_
2076 2056 sasl_free_t *free_func;
2077 2057 #endif /* _SUN_SDK_ */
2078 2058
2079 2059 if(!utils) return SASL_BADPARAM;
2080 2060 if(!*utils) return SASL_OK;
2081 2061
2082 2062 /* I wish we could avoid this cast, it's pretty gratuitous but it
2083 2063 * does make life easier to have it const everywhere else. */
2084 2064 nonconst = (sasl_utils_t *)(*utils);
2085 2065
2086 2066 sasl_randfree(&(nonconst->rpool));
2087 2067 #ifdef _SUN_SDK_
2088 2068 free_func = (*utils)->free;
2089 2069 free_func(nonconst);
2090 2070 #else
2091 2071 sasl_FREE(nonconst);
2092 2072 #endif /* _SUN_SDK_ */
2093 2073
2094 2074 *utils = NULL;
2095 2075 return SASL_OK;
2096 2076 }
2097 2077
2098 2078 int sasl_idle(sasl_conn_t *conn)
2099 2079 {
2100 2080 if (! conn) {
2101 2081 #ifdef _SUN_SDK_
2102 2082 _sasl_global_context_t *gctx = _sasl_gbl_ctx();
2103 2083
2104 2084 if (gctx->sasl_server_idle_hook
2105 2085 && gctx->sasl_server_idle_hook(NULL))
2106 2086 return 1;
2107 2087 if (gctx->sasl_client_idle_hook
2108 2088 && gctx->sasl_client_idle_hook(NULL))
2109 2089 return 1;
2110 2090 #else
2111 2091 if (_sasl_server_idle_hook
2112 2092 && _sasl_server_idle_hook(NULL))
2113 2093 return 1;
2114 2094 if (_sasl_client_idle_hook
2115 2095 && _sasl_client_idle_hook(NULL))
2116 2096 return 1;
2117 2097 #endif /* _SUN_SDK_ */
2118 2098 return 0;
2119 2099 }
2120 2100
2121 2101 if (conn->idle_hook)
2122 2102 return conn->idle_hook(conn);
2123 2103
2124 2104 return 0;
2125 2105 }
2126 2106
2127 2107 const sasl_callback_t *
2128 2108 _sasl_find_getpath_callback(const sasl_callback_t *callbacks)
2129 2109 {
2130 2110 static const sasl_callback_t default_getpath_cb = {
2131 2111 SASL_CB_GETPATH,
2132 2112 &_sasl_getpath,
2133 2113 NULL
2134 2114 };
2135 2115
2136 2116 if (callbacks)
2137 2117 while (callbacks->id != SASL_CB_LIST_END)
2138 2118 {
2139 2119 if (callbacks->id == SASL_CB_GETPATH)
2140 2120 {
2141 2121 return callbacks;
2142 2122 } else {
2143 2123 ++callbacks;
2144 2124 }
2145 2125 }
2146 2126
2147 2127 return &default_getpath_cb;
2148 2128 }
2149 2129
2150 2130 #ifdef _SUN_SDK_
2151 2131 extern const sasl_callback_t *
2152 2132 _sasl_find_getconf_callback(const sasl_callback_t *callbacks)
2153 2133 {
2154 2134 static const sasl_callback_t default_getconf_cb = {
2155 2135 SASL_CB_GETCONF,
2156 2136 &_sasl_getconf,
2157 2137 NULL
2158 2138 };
2159 2139
2160 2140 if (callbacks)
2161 2141 while (callbacks->id != SASL_CB_LIST_END)
2162 2142 {
2163 2143 if (callbacks->id == SASL_CB_GETCONF)
2164 2144 {
2165 2145 return callbacks;
2166 2146 } else {
2167 2147 ++callbacks;
2168 2148 }
2169 2149 }
2170 2150
2171 2151 return &default_getconf_cb;
2172 2152 }
2173 2153 #endif /* _SUN_SDK_ */
2174 2154
2175 2155 const sasl_callback_t *
2176 2156 _sasl_find_verifyfile_callback(const sasl_callback_t *callbacks)
2177 2157 {
2178 2158 static const sasl_callback_t default_verifyfile_cb = {
2179 2159 SASL_CB_VERIFYFILE,
2180 2160 &_sasl_verifyfile,
2181 2161 NULL
2182 2162 };
2183 2163
2184 2164 if (callbacks)
2185 2165 while (callbacks->id != SASL_CB_LIST_END)
2186 2166 {
2187 2167 if (callbacks->id == SASL_CB_VERIFYFILE)
2188 2168 {
2189 2169 return callbacks;
2190 2170 } else {
2191 2171 ++callbacks;
2192 2172 }
2193 2173 }
2194 2174
2195 2175 return &default_verifyfile_cb;
2196 2176 }
2197 2177
2198 2178 /* Basically a conditional call to realloc(), if we need more */
2199 2179 #ifdef _SUN_SDK_
2200 2180 int __buf_alloc(const _sasl_global_context_t *gctx, char **rwbuf,
2201 2181 size_t *curlen, size_t newlen)
2202 2182 #else
2203 2183 int _buf_alloc(char **rwbuf, size_t *curlen, size_t newlen)
2204 2184 #endif /* _SUN_SDK_ */
2205 2185 {
2206 2186 if(!(*rwbuf)) {
2207 2187 *rwbuf = sasl_ALLOC(newlen);
2208 2188 if (*rwbuf == NULL) {
2209 2189 *curlen = 0;
2210 2190 return SASL_NOMEM;
2211 2191 }
2212 2192 *curlen = newlen;
2213 2193 } else if(*rwbuf && *curlen < newlen) {
2214 2194 size_t needed = 2*(*curlen);
2215 2195
2216 2196 while(needed < newlen)
2217 2197 needed *= 2;
2218 2198
2219 2199 *rwbuf = sasl_REALLOC(*rwbuf, needed);
2220 2200
2221 2201 if (*rwbuf == NULL) {
2222 2202 *curlen = 0;
2223 2203 return SASL_NOMEM;
2224 2204 }
2225 2205 *curlen = needed;
2226 2206 }
2227 2207
2228 2208 return SASL_OK;
2229 2209 }
2230 2210
2231 2211 /* for the mac os x cfm glue: this lets the calling function
2232 2212 get pointers to the error buffer without having to touch the sasl_conn_t struct */
2233 2213 void _sasl_get_errorbuf(sasl_conn_t *conn, char ***bufhdl, size_t **lenhdl)
2234 2214 {
2235 2215 *bufhdl = &conn->error_buf;
2236 2216 *lenhdl = &conn->error_buf_len;
2237 2217 }
2238 2218
2239 2219 /* convert an iovec to a single buffer */
2240 2220 #ifdef _SUN_SDK_
2241 2221 int _iovec_to_buf(const _sasl_global_context_t *gctx, const struct iovec *vec,
2242 2222 unsigned numiov, buffer_info_t **output)
2243 2223 #else
2244 2224 int _iovec_to_buf(const struct iovec *vec,
2245 2225 unsigned numiov, buffer_info_t **output)
2246 2226 #endif /* _SUN_SDK_ */
2247 2227 {
2248 2228 unsigned i;
2249 2229 int ret;
2250 2230 buffer_info_t *out;
2251 2231 char *pos;
2252 2232
2253 2233 if(!vec || !output) return SASL_BADPARAM;
2254 2234
2255 2235 if(!(*output)) {
2256 2236 *output = sasl_ALLOC(sizeof(buffer_info_t));
2257 2237 if(!*output) return SASL_NOMEM;
2258 2238 memset(*output,0,sizeof(buffer_info_t));
2259 2239 }
2260 2240
2261 2241 out = *output;
2262 2242
2263 2243 out->curlen = 0;
2264 2244 for(i=0; i<numiov; i++)
2265 2245 out->curlen += vec[i].iov_len;
2266 2246
2267 2247 ret = _buf_alloc(&out->data, &out->reallen, out->curlen);
2268 2248
2269 2249 if(ret != SASL_OK) return SASL_NOMEM;
2270 2250
2271 2251 memset(out->data, 0, out->reallen);
2272 2252 pos = out->data;
2273 2253
2274 2254 for(i=0; i<numiov; i++) {
2275 2255 memcpy(pos, vec[i].iov_base, vec[i].iov_len);
2276 2256 pos += vec[i].iov_len;
2277 2257 }
2278 2258
2279 2259 return SASL_OK;
2280 2260 }
2281 2261
2282 2262 /* This code might be useful in the future, but it isn't now, so.... */
2283 2263 #if 0
2284 2264 int _sasl_iptostring(const struct sockaddr *addr, socklen_t addrlen,
2285 2265 char *out, unsigned outlen) {
2286 2266 char hbuf[NI_MAXHOST], pbuf[NI_MAXSERV];
2287 2267
2288 2268 if(!addr || !out) return SASL_BADPARAM;
2289 2269
2290 2270 getnameinfo(addr, addrlen, hbuf, sizeof(hbuf), pbuf, sizeof(pbuf),
2291 2271 NI_NUMERICHOST | NI_WITHSCOPEID | NI_NUMERICSERV);
2292 2272
2293 2273 if(outlen < strlen(hbuf) + strlen(pbuf) + 2)
2294 2274 return SASL_BUFOVER;
2295 2275
2296 2276 snprintf(out, outlen, "%s;%s", hbuf, pbuf);
2297 2277
2298 2278 return SASL_OK;
2299 2279 }
2300 2280 #endif
2301 2281
2302 2282 #ifdef _SUN_SDK_
2303 2283 /* An ipv6 address will contain at least two colons */
2304 2284 static int can_be_ipv6(const char *addr)
2305 2285 {
2306 2286 const char *p;
2307 2287
2308 2288 if ((p = strchr(addr, ':')) == NULL)
2309 2289 return (0);
2310 2290
2311 2291 p = strchr(p + 1, ':');
2312 2292
2313 2293 return (p != NULL);
2314 2294 }
2315 2295 #endif /* _SUN_SDK_ */
2316 2296
2317 2297 int _sasl_ipfromstring(const char *addr,
2318 2298 struct sockaddr *out, socklen_t outlen)
2319 2299 {
2320 2300 int i, j;
2321 2301 struct addrinfo hints, *ai = NULL;
2322 2302 char hbuf[NI_MAXHOST];
2323 2303 #ifdef _SUN_SDK_
2324 2304 const char *start, *end, *p;
2325 2305 int addr_only = 1;
2326 2306 #endif /* _SUN_SDK_ */
2327 2307
2328 2308 /* A NULL out pointer just implies we don't do a copy, just verify it */
2329 2309
2330 2310 if(!addr) return SASL_BADPARAM;
2331 2311
2332 2312 #ifdef _SUN_SDK_
2333 2313 end = strchr(addr, ']');
2334 2314 if (end != NULL) {
2335 2315 /* This an rfc 2732 ipv6 address */
2336 2316 start = strchr(addr, '[');
2337 2317 if (start >= end || start == NULL)
2338 2318 return SASL_BADPARAM;
2339 2319 for (i = 0, p = start + 1; p < end; p++) {
2340 2320 hbuf[i++] = *p;
2341 2321 if (i >= NI_MAXHOST)
2342 2322 return SASL_BADPARAM;
2343 2323 }
2344 2324 p = strchr(end, ':');
2345 2325 if (p == NULL)
2346 2326 p = end + 1;
2347 2327 else
2348 2328 p = p + 1;
2349 2329 } else if (can_be_ipv6(addr) != 0) {
2350 2330 /* Parse the address */
2351 2331 for (i = 0; addr[i] != '\0' && addr[i] != ';'; ) {
2352 2332 hbuf[i] = addr[i];
2353 2333 if (++i >= NI_MAXHOST)
2354 2334 return SASL_BADPARAM;
2355 2335 }
2356 2336 if (addr[i] == ';')
2357 2337 p = &addr[i+1];
2358 2338 else
2359 2339 p = &addr[i];
2360 2340 } else {
2361 2341 for (i = 0; addr[i] != '\0' && addr[i] != ';' && addr[i] != ':'; ) {
2362 2342 hbuf[i] = addr[i];
2363 2343 if (isalpha(addr[i]))
2364 2344 addr_only = 0;
2365 2345 if (++i >= NI_MAXHOST)
2366 2346 return SASL_BADPARAM;
2367 2347 }
2368 2348 if (addr[i] == ';' || addr[i] == ':')
2369 2349 p = &addr[i+1];
2370 2350 else
2371 2351 p = &addr[i];
2372 2352 }
2373 2353 hbuf[i] = '\0';
2374 2354 for (j = 0; p[j] != '\0'; j++)
2375 2355 if (!isdigit((int)(p[j])))
2376 2356 return SASL_BADPARAM;
2377 2357 if (atoi(p) == 0)
2378 2358 p = NULL;
2379 2359 #else
2380 2360 /* Parse the address */
2381 2361 for (i = 0; addr[i] != '\0' && addr[i] != ';'; i++) {
2382 2362 if (i >= NI_MAXHOST)
2383 2363 return SASL_BADPARAM;
2384 2364 hbuf[i] = addr[i];
2385 2365 }
2386 2366 hbuf[i] = '\0';
2387 2367
2388 2368 if (addr[i] == ';')
2389 2369 i++;
2390 2370 /* XXX: Do we need this check? */
2391 2371 for (j = i; addr[j] != '\0'; j++)
2392 2372 if (!isdigit((int)(addr[j])))
2393 2373 return SASL_BADPARAM;
2394 2374 #endif /* _SUN_SDK_ */
2395 2375
2396 2376 memset(&hints, 0, sizeof(hints));
2397 2377 hints.ai_family = PF_UNSPEC;
2398 2378 hints.ai_socktype = SOCK_STREAM;
2399 2379 #ifdef _SUN_SDK_
2400 2380 hints.ai_flags = addr_only ? AI_PASSIVE | AI_NUMERICHOST : AI_PASSIVE;
2401 2381 if (getaddrinfo(hbuf, p, &hints, &ai) != 0)
2402 2382 #else
2403 2383 hints.ai_flags = AI_PASSIVE | AI_NUMERICHOST;
2404 2384 if (getaddrinfo(hbuf, &addr[i], &hints, &ai) != 0)
2405 2385 #endif /* _SUN_SDK_ */
2406 2386 return SASL_BADPARAM;
2407 2387
2408 2388 if (out) {
2409 2389 if (outlen < (socklen_t)ai->ai_addrlen) {
2410 2390 freeaddrinfo(ai);
2411 2391 return SASL_BUFOVER;
2412 2392 }
2413 2393 memcpy(out, ai->ai_addr, ai->ai_addrlen);
2414 2394 }
2415 2395
2416 2396 freeaddrinfo(ai);
2417 2397
2418 2398 return SASL_OK;
2419 2399 }
2420 2400
2421 2401 #ifdef _SUN_SDK_
2422 2402 int _sasl_build_mechlist(_sasl_global_context_t *gctx)
2423 2403 #else
2424 2404 int _sasl_build_mechlist(void)
2425 2405 #endif /* _SUN_SDK_ */
2426 2406 {
2427 2407 int count = 0;
2428 2408 sasl_string_list_t *clist = NULL, *slist = NULL, *olist = NULL;
2429 2409 sasl_string_list_t *p, *q, **last, *p_next;
2430 2410
2431 2411 #ifdef _SUN_SDK_
2432 2412 char **global_mech_list;
2433 2413
2434 2414 LOCK_MUTEX(&global_mutex);
2435 2415
2436 2416 clist = _sasl_client_mechs(gctx);
2437 2417 slist = _sasl_server_mechs(gctx);
2438 2418
2439 2419 global_mech_list = gctx->global_mech_list;
2440 2420 #else
2441 2421 clist = _sasl_client_mechs();
2442 2422 slist = _sasl_server_mechs();
2443 2423 #endif /* _SUN_SDK_ */
2444 2424
2445 2425 if(!clist) {
2446 2426 olist = slist;
2447 2427 } else {
2448 2428 int flag;
2449 2429
2450 2430 /* append slist to clist, and set olist to clist */
2451 2431 for(p = slist; p; p = p_next) {
2452 2432 flag = 0;
2453 2433 p_next = p->next;
2454 2434
2455 2435 last = &clist;
2456 2436 for(q = clist; q; q = q->next) {
2457 2437 if(!strcmp(q->d, p->d)) {
2458 2438 /* They match, set the flag */
2459 2439 flag = 1;
2460 2440 break;
2461 2441 }
2462 2442 last = &(q->next);
2463 2443 }
2464 2444
2465 2445 if(!flag) {
2466 2446 *last = p;
2467 2447 p->next = NULL;
2468 2448 } else {
2469 2449 sasl_FREE(p);
2470 2450 }
2471 2451 }
2472 2452
2473 2453 olist = clist;
2474 2454 }
2475 2455
2476 2456 if(!olist) {
2477 2457 #ifdef _SUN_SDK_
2478 2458 UNLOCK_MUTEX(&global_mutex);
2479 2459 #else
2480 2460 printf ("no olist");
2481 2461 #endif /* _SUN_SDK_ */
2482 2462 return SASL_FAIL;
2483 2463 }
2484 2464
2485 2465 for (p = olist; p; p = p->next) count++;
2486 2466
2487 2467 if(global_mech_list) {
2488 2468 sasl_FREE(global_mech_list);
2489 2469 #ifdef _SUN_SDK_
2490 2470 gctx->global_mech_list = NULL;
2491 2471 #else
2492 2472 global_mech_list = NULL;
2493 2473 #endif /* _SUN_SDK_ */
2494 2474 }
2495 2475
2496 2476 global_mech_list = sasl_ALLOC((count + 1) * sizeof(char *));
2497 2477 if(!global_mech_list) return SASL_NOMEM;
2498 2478
2499 2479 memset(global_mech_list, 0, (count + 1) * sizeof(char *));
2500 2480 #ifdef _SUN_SDK_
2501 2481 gctx->global_mech_list = global_mech_list;
2502 2482 #endif /* _SUN_SDK_ */
2503 2483
2504 2484 count = 0;
2505 2485 for (p = olist; p; p = p_next) {
2506 2486 p_next = p->next;
2507 2487
2508 2488 global_mech_list[count++] = (char *) p->d;
2509 2489
2510 2490 sasl_FREE(p);
2511 2491 }
2512 2492
2513 2493 #ifdef _SUN_SDK_
2514 2494 UNLOCK_MUTEX(&global_mutex);
2515 2495 #endif /* _SUN_SDK_ */
2516 2496
2517 2497 return SASL_OK;
2518 2498 }
2519 2499
2520 2500 const char ** sasl_global_listmech(void)
2521 2501 {
2522 2502 #ifdef _SUN_SDK_
2523 2503 _sasl_global_context_t *gctx = _sasl_gbl_ctx();
2524 2504
2525 2505 return (const char **)gctx->global_mech_list;
2526 2506 #else
2527 2507 return (const char **)global_mech_list;
2528 2508 #endif /* _SUN_SDK_ */
2529 2509 }
2530 2510
2531 2511 int sasl_listmech(sasl_conn_t *conn,
2532 2512 const char *user,
2533 2513 const char *prefix,
2534 2514 const char *sep,
2535 2515 const char *suffix,
2536 2516 const char **result,
2537 2517 unsigned *plen,
2538 2518 int *pcount)
2539 2519 {
2540 2520 if(!conn) {
2541 2521 return SASL_BADPARAM;
2542 2522 } else if(conn->type == SASL_CONN_SERVER) {
2543 2523 RETURN(conn, _sasl_server_listmech(conn, user, prefix, sep, suffix,
2544 2524 result, plen, pcount));
2545 2525 } else if (conn->type == SASL_CONN_CLIENT) {
2546 2526 RETURN(conn, _sasl_client_listmech(conn, prefix, sep, suffix,
2547 2527 result, plen, pcount));
2548 2528 }
2549 2529
2550 2530 PARAMERROR(conn);
2551 2531 }
2552 2532
2553 2533 #ifdef _SUN_SDK_
2554 2534 /*
2555 2535 * Creates a context so that libraries may use libsasl independently
2556 2536 * of applications using libsasl.
2557 2537 * Returns NULL on failure.
2558 2538 *
2559 2539 * sasl_free_context frees the context
2560 2540 * To use libsasl independently of the default context, use
2561 2541 * _sasl_server_init() instead of sasl_server_init()
2562 2542 * _sasl_server_new() instead of sasl_server_new()
2563 2543 * _sasl_client_init() instead of sasl_client_init()
2564 2544 * _sasl_client_new() instead of sasl_client_new()
2565 2545 * _sasl_client_add_plugin() instead of sasl_client_add_plugin()
2566 2546 * _sasl_server_add_plugin() instead of sasl_server_add_plugin()
2567 2547 * _sasl_canonuser_add_plugin() instead of sasl_canonuser_add_plugin()
2568 2548 * _sasl_auxprop_add_plugin() instead of sasl_auxprop_add_plugin()
2569 2549 */
2570 2550
2571 2551 void *sasl_create_context(void)
2572 2552 {
2573 2553 _sasl_global_context_t *gctx;
2574 2554
2575 2555 gctx = (_sasl_global_context_t *)
2576 2556 sasl_sun_ALLOC(sizeof(_sasl_global_context_t));
2577 2557
2578 2558 if (gctx != NULL) {
2579 2559 memset(gctx, 0, sizeof(_sasl_global_context_t));
2580 2560
2581 2561 gctx->server_global_callbacks.gctx = gctx;
2582 2562 gctx->client_global_callbacks.gctx = gctx;
2583 2563 LOCK_MUTEX(&malloc_global_mutex);
2584 2564 gctx->sasl_allocation_utils.malloc = (sasl_malloc_t *)&malloc;
2585 2565 gctx->sasl_allocation_utils.calloc = (sasl_calloc_t *)&calloc;
2586 2566 gctx->sasl_allocation_utils.realloc = (sasl_realloc_t *)&realloc;
2587 2567 gctx->sasl_allocation_utils.free = (sasl_free_t *)&free;
2588 2568 gctx->sasl_mutex_utils.alloc = sasl_mutex_alloc;
2589 2569 gctx->sasl_mutex_utils.lock = sasl_mutex_lock;
2590 2570 gctx->sasl_mutex_utils.unlock = sasl_mutex_unlock;
2591 2571 gctx->sasl_mutex_utils.free = sasl_mutex_free;
2592 2572 UNLOCK_MUTEX(&malloc_global_mutex);
2593 2573 }
2594 2574 return gctx;
2595 2575 }
2596 2576
2597 2577 /* Frees the context created by sasl_create_context() */
2598 2578 void sasl_free_context(void *context)
2599 2579 {
2600 2580 _sasl_dispose_context(context);
2601 2581 if (context != NULL) {
2602 2582 sasl_sun_FREE(context);
2603 2583 }
2604 2584 }
2605 2585
2606 2586 /* Used by both sasl_done() and sasl_free_context() to free context */
2607 2587 static void _sasl_dispose_context(_sasl_global_context_t *gctx)
2608 2588 {
2609 2589 if (gctx == NULL)
2610 2590 return;
2611 2591
2612 2592 if (gctx->sasl_server_cleanup_hook &&
2613 2593 gctx->sasl_server_cleanup_hook(gctx) == SASL_OK) {
2614 2594 gctx->sasl_server_idle_hook = NULL;
2615 2595 gctx->sasl_server_cleanup_hook = NULL;
2616 2596 }
2617 2597
2618 2598 if (gctx->sasl_client_cleanup_hook &&
2619 2599 gctx->sasl_client_cleanup_hook(gctx) == SASL_OK) {
2620 2600 gctx->sasl_client_idle_hook = NULL;
2621 2601 gctx->sasl_client_cleanup_hook = NULL;
2622 2602 }
2623 2603
2624 2604 if(gctx->sasl_server_cleanup_hook || gctx->sasl_client_cleanup_hook)
2625 2605 return;
2626 2606
2627 2607 _sasl_canonuser_free(gctx);
2628 2608 _sasl_done_with_plugins(gctx);
2629 2609
2630 2610 sasl_config_free(gctx);
2631 2611
2632 2612 if (gctx->free_mutex != NULL)
2633 2613 sasl_MUTEX_FREE(gctx->free_mutex);
2634 2614 gctx->free_mutex = NULL;
2635 2615
2636 2616 _sasl_free_utils(&(gctx->sasl_server_global_utils));
2637 2617 _sasl_free_utils(&(gctx->sasl_canonusr_global_utils));
2638 2618
2639 2619 LOCK_MUTEX(&global_mutex);
2640 2620 sasl_FREE((void *)gctx->global_mech_list);
2641 2621 gctx->global_mech_list = NULL;
2642 2622 UNLOCK_MUTEX(&global_mutex);
2643 2623
2644 2624 /* in case of another init/done */
2645 2625 gctx->sasl_server_cleanup_hook = NULL;
2646 2626 gctx->sasl_client_cleanup_hook = NULL;
2647 2627
2648 2628 gctx->sasl_client_idle_hook = NULL;
2649 2629 gctx->sasl_server_idle_hook = NULL;
2650 2630 }
2651 2631
2652 2632 _sasl_global_context_t *_sasl_gbl_ctx(void)
2653 2633 {
2654 2634 static _sasl_global_context_t gbl_ctx = {
2655 2635 0, /* sasl_server_active */
2656 2636 NULL, /* mechlist */
2657 2637 NULL, /* splug_path_info */
2658 2638 {NULL, NULL, &gbl_ctx}, /* server_global_callbacks */
2659 2639 NULL, /* sasl_server_cleanup_hook */
2660 2640 NULL, /* sasl_server_idle_hook */
2661 2641 NULL, /* cmechlist */
2662 2642 NULL, /* cplug_path_info */
2663 2643 {NULL, NULL, &gbl_ctx}, /* client_global_callbacks */
2664 2644 0, /* sasl_client_active */
2665 2645 NULL, /* sasl_client_cleanup_hook */
2666 2646 NULL, /* sasl_client_idle_hook */
2667 2647 NULL, /* sasl_server_global_utils */
2668 2648 NULL, /* sasl_client_global_utils */
2669 2649 NULL, /* configlist */
2670 2650 0, /* nconfiglist */
2671 2651 NULL, /* config_path */
2672 2652 0, /* config_last_read */
2673 2653 NULL, /* auxprop_head */
2674 2654 NULL, /* canonuser_head */
2675 2655 NULL, /* global_mech_list */
2676 2656 NULL, /* free_mutex */
2677 2657 {(sasl_malloc_t *)&malloc, (sasl_calloc_t *)&calloc,
2678 2658 (sasl_realloc_t *)&realloc, (sasl_free_t *)&free},
2679 2659 /* sasl_allocation_utils */
2680 2660 {&sasl_mutex_alloc, &sasl_mutex_lock, &sasl_mutex_unlock,
2681 2661 &sasl_mutex_free}, /* sasl_mutex_utils */
2682 2662 NULL /* lib_list_head */
2683 2663 };
2684 2664
2685 2665 return (&gbl_ctx);
2686 2666 }
2687 2667
2688 2668 static int
↓ open down ↓ |
1291 lines elided |
↑ open up ↑ |
2689 2669 _sasl_getconf(void *context __attribute__((unused)), const char **conf)
2690 2670 {
2691 2671 if (! conf)
2692 2672 return SASL_BADPARAM;
2693 2673
2694 2674 *conf = SASL_CONFDIR;
2695 2675
2696 2676 return SASL_OK;
2697 2677 }
2698 2678
2699 -/* EXPORT DELETE START */
2700 -/* CRYPT DELETE START */
2701 2679 #ifdef _INTEGRATED_SOLARIS_
2702 2680 #pragma fini(sasl_fini)
2703 2681 int
2704 2682 sasl_fini(void)
2705 2683 {
2706 2684 reg_list_t *next;
2707 2685
2708 2686 while (reg_list_base != NULL) {
2709 2687 next = reg_list_base->next;
2710 2688 free(reg_list_base);
2711 2689 reg_list_base = next;
2712 2690 }
2713 2691 return (0);
2714 2692 }
2715 2693 #endif /* _INTEGRATED_SOLARIS_ */
2716 -/* CRYPT DELETE END */
2717 -/* EXPORT DELETE END */
2718 2694
2719 2695 #endif /* _SUN_SDK_ */
2720 2696
2721 2697 #ifndef WIN32
2722 2698 static int
2723 2699 _sasl_getpath(void *context __attribute__((unused)),
2724 2700 const char **path)
2725 2701 {
2726 2702 if (! path)
2727 2703 return SASL_BADPARAM;
2728 2704
2729 2705 #ifdef _SUN_SDK_
2730 2706 /* SASL_PATH is not allowed for SUN SDK */
2731 2707 #else
2732 2708 *path = getenv(SASL_PATH_ENV_VAR);
2733 2709 if (! *path)
2734 2710 #endif /* _SUN_SDK_ */
2735 2711 *path = PLUGINDIR;
2736 2712
2737 2713 return SASL_OK;
2738 2714 }
2739 2715
2740 2716 #else
2741 2717 /* Return NULL on failure */
2742 2718 static int
2743 2719 _sasl_getpath(void *context __attribute__((unused)), const char **path)
2744 2720 {
2745 2721 /* Open registry entry, and find all registered SASL libraries.
2746 2722 *
2747 2723 * Registry location:
2748 2724 *
2749 2725 * SOFTWARE\\Carnegie Mellon\\Project Cyrus\\SASL Library
2750 2726 *
2751 2727 * Key - value:
2752 2728 *
2753 2729 * "SearchPath" - value: PATH like (';' delimited) list
2754 2730 * of directories where to search for plugins
2755 2731 * The list may contain references to environment
2756 2732 * variables (e.g. %PATH%).
2757 2733 *
2758 2734 */
2759 2735 HKEY hKey;
2760 2736 DWORD ret;
2761 2737 DWORD ValueType; /* value type */
2762 2738 DWORD cbData; /* value size */
2763 2739 BYTE * ValueData; /* value */
2764 2740 DWORD cbExpandedData; /* "expanded" value size */
2765 2741 BYTE * ExpandedValueData; /* "expanded" value */
2766 2742 char * return_value; /* function return value */
2767 2743 char * tmp;
2768 2744
2769 2745 /* Initialization */
2770 2746 ExpandedValueData = NULL;
2771 2747 ValueData = NULL;
2772 2748 return_value = NULL;
2773 2749
2774 2750 /* Open the registry */
2775 2751 ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
2776 2752 SASL_ROOT_KEY,
2777 2753 0,
2778 2754 KEY_READ,
2779 2755 &hKey);
2780 2756
2781 2757 if (ret != ERROR_SUCCESS) {
2782 2758 /* no registry entry */
2783 2759 *path = PLUGINDIR;
2784 2760 return SASL_OK;
2785 2761 }
2786 2762
2787 2763 /* figure out value type and required buffer size */
2788 2764 /* the size will include space for terminating NUL if required */
2789 2765 RegQueryValueEx (hKey,
2790 2766 SASL_PATH_SUBKEY,
2791 2767 NULL, /* reserved */
2792 2768 &ValueType,
2793 2769 NULL,
2794 2770 &cbData);
2795 2771
2796 2772 /* Only accept string related types */
2797 2773 if (ValueType != REG_EXPAND_SZ &&
2798 2774 ValueType != REG_MULTI_SZ &&
2799 2775 ValueType != REG_SZ) {
2800 2776 return_value = NULL;
2801 2777 goto CLEANUP;
2802 2778 }
2803 2779
2804 2780 /* Any high water mark? */
2805 2781 ValueData = sasl_ALLOC(cbData);
2806 2782 if (ValueData == NULL) {
2807 2783 return_value = NULL;
2808 2784 goto CLEANUP;
2809 2785 };
2810 2786
2811 2787 RegQueryValueEx (hKey,
2812 2788 SASL_PATH_SUBKEY,
2813 2789 NULL, /* reserved */
2814 2790 &ValueType,
2815 2791 ValueData,
2816 2792 &cbData);
2817 2793
2818 2794 switch (ValueType) {
2819 2795 case REG_EXPAND_SZ:
2820 2796 /* : A random starting guess */
2821 2797 cbExpandedData = cbData + 1024;
2822 2798 ExpandedValueData = sasl_ALLOC(cbExpandedData);
2823 2799 if (ExpandedValueData == NULL) {
2824 2800 return_value = NULL;
2825 2801 goto CLEANUP;
2826 2802 };
2827 2803
2828 2804 cbExpandedData = ExpandEnvironmentStrings(
2829 2805 ValueData,
2830 2806 ExpandedValueData,
2831 2807 cbExpandedData);
2832 2808
2833 2809 if (cbExpandedData == 0) {
2834 2810 /* : GetLastError() contains the reason for failure */
2835 2811 return_value = NULL;
2836 2812 goto CLEANUP;
2837 2813 }
2838 2814
2839 2815 /* : Must retry expansion with the bigger buffer */
2840 2816 if (cbExpandedData > cbData + 1024) {
2841 2817 /* : Memory leak here if can't realloc */
2842 2818 ExpandedValueData = sasl_REALLOC(ExpandedValueData, cbExpandedData);
2843 2819 if (ExpandedValueData == NULL) {
2844 2820 return_value = NULL;
2845 2821 goto CLEANUP;
2846 2822 };
2847 2823
2848 2824 cbExpandedData = ExpandEnvironmentStrings(
2849 2825 ValueData,
2850 2826 ExpandedValueData,
2851 2827 cbExpandedData);
2852 2828
2853 2829 /* : This should not happen */
2854 2830 if (cbExpandedData == 0) {
2855 2831 /* : GetLastError() contains the reason for failure */
2856 2832 return_value = NULL;
2857 2833 goto CLEANUP;
2858 2834 }
2859 2835 }
2860 2836
2861 2837 sasl_FREE(ValueData);
2862 2838 ValueData = ExpandedValueData;
2863 2839 /* : This is to prevent automatical freeing of this block on cleanup */
2864 2840 ExpandedValueData = NULL;
2865 2841
2866 2842 break;
2867 2843
2868 2844 case REG_MULTI_SZ:
2869 2845 tmp = ValueData;
2870 2846
2871 2847 /* : We shouldn't overflow here, as the buffer is guarantied
2872 2848 : to contain at least two consequent NULs */
2873 2849 while (1) {
2874 2850 if (tmp[0] == '\0') {
2875 2851 /* : Stop the process if we found the end of the string (two consequent NULs) */
2876 2852 if (tmp[1] == '\0') {
2877 2853 break;
2878 2854 }
2879 2855
2880 2856 /* : Replace delimiting NUL with our delimiter characted */
2881 2857 tmp[0] = PATHS_DELIMITER;
2882 2858 }
2883 2859 tmp += strlen(tmp);
2884 2860 }
2885 2861 break;
2886 2862
2887 2863 case REG_SZ:
2888 2864 /* Do nothing, it is good as is */
2889 2865 break;
2890 2866
2891 2867 default:
2892 2868 return_value = NULL;
2893 2869 goto CLEANUP;
2894 2870 }
2895 2871
2896 2872 return_value = ValueData;
2897 2873
2898 2874 CLEANUP:
2899 2875 RegCloseKey(hKey);
2900 2876 if (ExpandedValueData != NULL) sasl_FREE(ExpandedValueData);
2901 2877 if (return_value == NULL) {
2902 2878 if (ValueData != NULL) sasl_FREE(ValueData);
2903 2879 }
2904 2880 *path = return_value;
2905 2881
2906 2882 #ifdef _SUN_SDK_
2907 2883 /* SASL_PATH is not allowed for SUN SDK */
2908 2884 if (! *path)
2909 2885 *path = PLUGINDIR;
2910 2886 #endif /* _SUN_SDK_ */
2911 2887 return SASL_OK;
2912 2888 }
2913 2889
2914 2890 #endif
↓ open down ↓ |
187 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX