cyrus.c 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335
  1. /* $OpenLDAP$ */
  2. /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  3. *
  4. * Copyright 1998-2024 The OpenLDAP Foundation.
  5. * All rights reserved.
  6. *
  7. * Redistribution and use in source and binary forms, with or without
  8. * modification, are permitted only as authorized by the OpenLDAP
  9. * Public License.
  10. *
  11. * A copy of this license is available in the file LICENSE in the
  12. * top-level directory of the distribution or, alternatively, at
  13. * <http://www.OpenLDAP.org/license.html>.
  14. */
  15. #include "portable.h"
  16. #include "ldap-int.h"
  17. #ifdef HAVE_CYRUS_SASL
  18. #include <stdio.h>
  19. #include <ac/socket.h>
  20. #include <ac/stdlib.h>
  21. #include <ac/string.h>
  22. #include <ac/time.h>
  23. #include <ac/errno.h>
  24. #include <ac/ctype.h>
  25. #include <ac/unistd.h>
  26. #ifdef HAVE_LIMITS_H
  27. #include <limits.h>
  28. #endif
  29. #ifndef INT_MAX
  30. #define INT_MAX 2147483647 /* 32 bit signed max */
  31. #endif
  32. #if !defined(HOST_NAME_MAX) && defined(_POSIX_HOST_NAME_MAX)
  33. #define HOST_NAME_MAX _POSIX_HOST_NAME_MAX
  34. #endif
  35. #ifdef HAVE_SASL_SASL_H
  36. #include <sasl/sasl.h>
  37. #else
  38. #include <sasl.h>
  39. #endif
  40. #if SASL_VERSION_MAJOR >= 2
  41. #define SASL_CONST const
  42. #else
  43. #define SASL_CONST
  44. #endif
  45. /*
  46. * Various Cyrus SASL related stuff.
  47. */
  48. static const sasl_callback_t client_callbacks[] = {
  49. #ifdef SASL_CB_GETREALM
  50. { SASL_CB_GETREALM, NULL, NULL },
  51. #endif
  52. { SASL_CB_USER, NULL, NULL },
  53. { SASL_CB_AUTHNAME, NULL, NULL },
  54. { SASL_CB_PASS, NULL, NULL },
  55. { SASL_CB_ECHOPROMPT, NULL, NULL },
  56. { SASL_CB_NOECHOPROMPT, NULL, NULL },
  57. { SASL_CB_LIST_END, NULL, NULL }
  58. };
  59. /*
  60. * ldap_int_initialize is responsible for calling this only once.
  61. */
  62. int ldap_int_sasl_init( void )
  63. {
  64. #ifdef HAVE_SASL_VERSION
  65. /* stringify the version number, sasl.h doesn't do it for us */
  66. #define VSTR0(maj, min, pat) #maj "." #min "." #pat
  67. #define VSTR(maj, min, pat) VSTR0(maj, min, pat)
  68. #define SASL_VERSION_STRING VSTR(SASL_VERSION_MAJOR, SASL_VERSION_MINOR, \
  69. SASL_VERSION_STEP)
  70. { int rc;
  71. sasl_version( NULL, &rc );
  72. if ( ((rc >> 16) != ((SASL_VERSION_MAJOR << 8)|SASL_VERSION_MINOR)) ||
  73. (rc & 0xffff) < SASL_VERSION_STEP) {
  74. char version[sizeof("xxx.xxx.xxxxx")];
  75. sprintf( version, "%u.%d.%d", (unsigned)rc >> 24, (rc >> 16) & 0xff,
  76. rc & 0xffff );
  77. Debug1( LDAP_DEBUG_ANY,
  78. "ldap_int_sasl_init: SASL library version mismatch:"
  79. " expected " SASL_VERSION_STRING ","
  80. " got %s\n", version );
  81. return -1;
  82. }
  83. }
  84. #endif
  85. /* SASL 2 takes care of its own memory completely internally */
  86. #if SASL_VERSION_MAJOR < 2 && !defined(CSRIMALLOC)
  87. sasl_set_alloc(
  88. ber_memalloc,
  89. ber_memcalloc,
  90. ber_memrealloc,
  91. ber_memfree );
  92. #endif /* CSRIMALLOC */
  93. #ifdef LDAP_R_COMPILE
  94. sasl_set_mutex(
  95. ldap_pvt_sasl_mutex_new,
  96. ldap_pvt_sasl_mutex_lock,
  97. ldap_pvt_sasl_mutex_unlock,
  98. ldap_pvt_sasl_mutex_dispose );
  99. #endif
  100. if ( sasl_client_init( NULL ) == SASL_OK ) {
  101. return 0;
  102. }
  103. #if SASL_VERSION_MAJOR < 2
  104. /* A no-op to make sure we link with Cyrus 1.5 */
  105. sasl_client_auth( NULL, NULL, NULL, 0, NULL, NULL );
  106. #endif
  107. return -1;
  108. }
  109. static void
  110. sb_sasl_cyrus_init(
  111. struct sb_sasl_generic_data *p,
  112. ber_len_t *min_send,
  113. ber_len_t *max_send,
  114. ber_len_t *max_recv)
  115. {
  116. sasl_conn_t *sasl_context = (sasl_conn_t *)p->ops_private;
  117. ber_len_t maxbuf;
  118. sasl_getprop( sasl_context, SASL_MAXOUTBUF,
  119. (SASL_CONST void **)(char *) &maxbuf );
  120. *min_send = SASL_MIN_BUFF_SIZE;
  121. *max_send = maxbuf;
  122. *max_recv = SASL_MAX_BUFF_SIZE;
  123. }
  124. static ber_int_t
  125. sb_sasl_cyrus_encode(
  126. struct sb_sasl_generic_data *p,
  127. unsigned char *buf,
  128. ber_len_t len,
  129. Sockbuf_Buf *dst)
  130. {
  131. sasl_conn_t *sasl_context = (sasl_conn_t *)p->ops_private;
  132. ber_int_t ret;
  133. unsigned tmpsize = dst->buf_size;
  134. ret = sasl_encode( sasl_context, (char *)buf, len,
  135. (SASL_CONST char **)&dst->buf_base,
  136. &tmpsize );
  137. dst->buf_size = tmpsize;
  138. dst->buf_end = dst->buf_size;
  139. if ( ret != SASL_OK ) {
  140. ber_log_printf( LDAP_DEBUG_ANY, p->sbiod->sbiod_sb->sb_debug,
  141. "sb_sasl_cyrus_encode: failed to encode packet: %s\n",
  142. sasl_errstring( ret, NULL, NULL ) );
  143. return -1;
  144. }
  145. return 0;
  146. }
  147. static ber_int_t
  148. sb_sasl_cyrus_decode(
  149. struct sb_sasl_generic_data *p,
  150. const Sockbuf_Buf *src,
  151. Sockbuf_Buf *dst)
  152. {
  153. sasl_conn_t *sasl_context = (sasl_conn_t *)p->ops_private;
  154. ber_int_t ret;
  155. unsigned tmpsize = dst->buf_size;
  156. ret = sasl_decode( sasl_context,
  157. src->buf_base, src->buf_end,
  158. (SASL_CONST char **)&dst->buf_base,
  159. (unsigned *)&tmpsize );
  160. dst->buf_size = tmpsize;
  161. dst->buf_end = dst->buf_size;
  162. if ( ret != SASL_OK ) {
  163. ber_log_printf( LDAP_DEBUG_ANY, p->sbiod->sbiod_sb->sb_debug,
  164. "sb_sasl_cyrus_decode: failed to decode packet: %s\n",
  165. sasl_errstring( ret, NULL, NULL ) );
  166. return -1;
  167. }
  168. return 0;
  169. }
  170. static void
  171. sb_sasl_cyrus_reset_buf(
  172. struct sb_sasl_generic_data *p,
  173. Sockbuf_Buf *buf)
  174. {
  175. #if SASL_VERSION_MAJOR >= 2
  176. ber_pvt_sb_buf_init( buf );
  177. #else
  178. ber_pvt_sb_buf_destroy( buf );
  179. #endif
  180. }
  181. static void
  182. sb_sasl_cyrus_fini(
  183. struct sb_sasl_generic_data *p)
  184. {
  185. #if SASL_VERSION_MAJOR >= 2
  186. /*
  187. * SASLv2 encode/decode buffers are managed by
  188. * libsasl2. Ensure they are not freed by liblber.
  189. */
  190. p->buf_in.buf_base = NULL;
  191. p->buf_out.buf_base = NULL;
  192. #endif
  193. }
  194. static const struct sb_sasl_generic_ops sb_sasl_cyrus_ops = {
  195. sb_sasl_cyrus_init,
  196. sb_sasl_cyrus_encode,
  197. sb_sasl_cyrus_decode,
  198. sb_sasl_cyrus_reset_buf,
  199. sb_sasl_cyrus_fini
  200. };
  201. int ldap_pvt_sasl_install( Sockbuf *sb, void *ctx_arg )
  202. {
  203. struct sb_sasl_generic_install install_arg;
  204. install_arg.ops = &sb_sasl_cyrus_ops;
  205. install_arg.ops_private = ctx_arg;
  206. return ldap_pvt_sasl_generic_install( sb, &install_arg );
  207. }
  208. void ldap_pvt_sasl_remove( Sockbuf *sb )
  209. {
  210. ldap_pvt_sasl_generic_remove( sb );
  211. }
  212. static int
  213. sasl_err2ldap( int saslerr )
  214. {
  215. int rc;
  216. /* map SASL errors to LDAP API errors returned by:
  217. * sasl_client_new()
  218. * SASL_OK, SASL_NOMECH, SASL_NOMEM
  219. * sasl_client_start()
  220. * SASL_OK, SASL_NOMECH, SASL_NOMEM, SASL_INTERACT
  221. * sasl_client_step()
  222. * SASL_OK, SASL_INTERACT, SASL_BADPROT, SASL_BADSERV
  223. */
  224. switch (saslerr) {
  225. case SASL_CONTINUE:
  226. rc = LDAP_MORE_RESULTS_TO_RETURN;
  227. break;
  228. case SASL_INTERACT:
  229. rc = LDAP_LOCAL_ERROR;
  230. break;
  231. case SASL_OK:
  232. rc = LDAP_SUCCESS;
  233. break;
  234. case SASL_NOMEM:
  235. rc = LDAP_NO_MEMORY;
  236. break;
  237. case SASL_NOMECH:
  238. rc = LDAP_AUTH_UNKNOWN;
  239. break;
  240. case SASL_BADPROT:
  241. rc = LDAP_DECODING_ERROR;
  242. break;
  243. case SASL_BADSERV:
  244. rc = LDAP_AUTH_UNKNOWN;
  245. break;
  246. /* other codes */
  247. case SASL_BADAUTH:
  248. rc = LDAP_AUTH_UNKNOWN;
  249. break;
  250. case SASL_NOAUTHZ:
  251. rc = LDAP_PARAM_ERROR;
  252. break;
  253. case SASL_FAIL:
  254. rc = LDAP_LOCAL_ERROR;
  255. break;
  256. case SASL_TOOWEAK:
  257. case SASL_ENCRYPT:
  258. rc = LDAP_AUTH_UNKNOWN;
  259. break;
  260. default:
  261. rc = LDAP_LOCAL_ERROR;
  262. break;
  263. }
  264. assert( rc == LDAP_SUCCESS || LDAP_API_ERROR( rc ) );
  265. return rc;
  266. }
  267. int
  268. ldap_int_sasl_open(
  269. LDAP *ld,
  270. LDAPConn *lc,
  271. const char * host )
  272. {
  273. int rc;
  274. sasl_conn_t *ctx;
  275. assert( lc->lconn_sasl_authctx == NULL );
  276. if ( host == NULL ) {
  277. ld->ld_errno = LDAP_LOCAL_ERROR;
  278. return ld->ld_errno;
  279. }
  280. #if SASL_VERSION_MAJOR >= 2
  281. rc = sasl_client_new( "ldap", host, NULL, NULL,
  282. client_callbacks, 0, &ctx );
  283. #else
  284. rc = sasl_client_new( "ldap", host, client_callbacks,
  285. SASL_SECURITY_LAYER, &ctx );
  286. #endif
  287. if ( rc != SASL_OK ) {
  288. ld->ld_errno = sasl_err2ldap( rc );
  289. return ld->ld_errno;
  290. }
  291. Debug1( LDAP_DEBUG_TRACE, "ldap_int_sasl_open: host=%s\n",
  292. host );
  293. lc->lconn_sasl_authctx = ctx;
  294. return LDAP_SUCCESS;
  295. }
  296. int ldap_int_sasl_close( LDAP *ld, LDAPConn *lc )
  297. {
  298. sasl_conn_t *ctx = lc->lconn_sasl_authctx;
  299. if( ctx != NULL ) {
  300. sasl_dispose( &ctx );
  301. if ( lc->lconn_sasl_sockctx &&
  302. lc->lconn_sasl_authctx != lc->lconn_sasl_sockctx ) {
  303. ctx = lc->lconn_sasl_sockctx;
  304. sasl_dispose( &ctx );
  305. }
  306. lc->lconn_sasl_sockctx = NULL;
  307. lc->lconn_sasl_authctx = NULL;
  308. }
  309. if( lc->lconn_sasl_cbind ) {
  310. ldap_memfree( lc->lconn_sasl_cbind );
  311. lc->lconn_sasl_cbind = NULL;
  312. }
  313. return LDAP_SUCCESS;
  314. }
  315. int ldap_pvt_sasl_cbinding_parse( const char *arg )
  316. {
  317. int i = -1;
  318. if ( strcasecmp(arg, "none") == 0 )
  319. i = LDAP_OPT_X_SASL_CBINDING_NONE;
  320. else if ( strcasecmp(arg, "tls-unique") == 0 )
  321. i = LDAP_OPT_X_SASL_CBINDING_TLS_UNIQUE;
  322. else if ( strcasecmp(arg, "tls-endpoint") == 0 )
  323. i = LDAP_OPT_X_SASL_CBINDING_TLS_ENDPOINT;
  324. return i;
  325. }
  326. void *ldap_pvt_sasl_cbinding( void *ssl, int type, int is_server )
  327. {
  328. #if defined(SASL_CHANNEL_BINDING) && defined(HAVE_TLS)
  329. char unique_prefix[] = "tls-unique:";
  330. char endpoint_prefix[] = "tls-server-end-point:";
  331. char cbinding[ 64 ];
  332. struct berval cbv = { 64, cbinding };
  333. unsigned char *cb_data; /* used since cb->data is const* */
  334. sasl_channel_binding_t *cb;
  335. char *prefix;
  336. int plen;
  337. switch (type) {
  338. case LDAP_OPT_X_SASL_CBINDING_NONE:
  339. return NULL;
  340. case LDAP_OPT_X_SASL_CBINDING_TLS_UNIQUE:
  341. if ( !ldap_pvt_tls_get_unique( ssl, &cbv, is_server ))
  342. return NULL;
  343. prefix = unique_prefix;
  344. plen = sizeof(unique_prefix) -1;
  345. break;
  346. case LDAP_OPT_X_SASL_CBINDING_TLS_ENDPOINT:
  347. if ( !ldap_pvt_tls_get_endpoint( ssl, &cbv, is_server ))
  348. return NULL;
  349. prefix = endpoint_prefix;
  350. plen = sizeof(endpoint_prefix) -1;
  351. break;
  352. default:
  353. return NULL;
  354. }
  355. cb = ldap_memalloc( sizeof(*cb) + plen + cbv.bv_len );
  356. cb->len = plen + cbv.bv_len;
  357. cb->data = cb_data = (unsigned char *)(cb+1);
  358. memcpy( cb_data, prefix, plen );
  359. memcpy( cb_data + plen, cbv.bv_val, cbv.bv_len );
  360. cb->name = "ldap";
  361. cb->critical = 0;
  362. return cb;
  363. #else
  364. return NULL;
  365. #endif
  366. }
  367. int
  368. ldap_int_sasl_bind(
  369. LDAP *ld,
  370. const char *dn,
  371. const char *mechs,
  372. LDAPControl **sctrls,
  373. LDAPControl **cctrls,
  374. unsigned flags,
  375. LDAP_SASL_INTERACT_PROC *interact,
  376. void *defaults,
  377. LDAPMessage *result,
  378. const char **rmech,
  379. int *msgid )
  380. {
  381. const char *mech;
  382. sasl_ssf_t *ssf;
  383. sasl_conn_t *ctx;
  384. sasl_interact_t *prompts = NULL;
  385. struct berval ccred = BER_BVNULL;
  386. int saslrc, rc;
  387. unsigned credlen;
  388. #if !defined(_WIN32)
  389. char my_hostname[HOST_NAME_MAX + 1];
  390. #endif
  391. int free_saslhost = 0;
  392. Debug1( LDAP_DEBUG_TRACE, "ldap_int_sasl_bind: %s\n",
  393. mechs ? mechs : "<null>" );
  394. /* do a quick !LDAPv3 check... ldap_sasl_bind will do the rest. */
  395. if (ld->ld_version < LDAP_VERSION3) {
  396. ld->ld_errno = LDAP_NOT_SUPPORTED;
  397. return ld->ld_errno;
  398. }
  399. /* Starting a Bind */
  400. if ( !result ) {
  401. const char *pmech = NULL;
  402. sasl_conn_t *oldctx;
  403. ber_socket_t sd;
  404. void *ssl;
  405. rc = 0;
  406. LDAP_MUTEX_LOCK( &ld->ld_conn_mutex );
  407. ber_sockbuf_ctrl( ld->ld_sb, LBER_SB_OPT_GET_FD, &sd );
  408. if ( sd == AC_SOCKET_INVALID || !ld->ld_defconn ) {
  409. /* not connected yet */
  410. rc = ldap_open_defconn( ld );
  411. if ( rc == 0 ) {
  412. ber_sockbuf_ctrl( ld->ld_defconn->lconn_sb,
  413. LBER_SB_OPT_GET_FD, &sd );
  414. if( sd == AC_SOCKET_INVALID ) {
  415. ld->ld_errno = LDAP_LOCAL_ERROR;
  416. rc = ld->ld_errno;
  417. }
  418. }
  419. }
  420. if ( rc == 0 && ld->ld_defconn &&
  421. ld->ld_defconn->lconn_status == LDAP_CONNST_CONNECTING ) {
  422. rc = ldap_int_check_async_open( ld, sd );
  423. }
  424. LDAP_MUTEX_UNLOCK( &ld->ld_conn_mutex );
  425. if( rc != 0 ) return ld->ld_errno;
  426. oldctx = ld->ld_defconn->lconn_sasl_authctx;
  427. /* If we already have an authentication context, clear it out */
  428. if( oldctx ) {
  429. if ( oldctx != ld->ld_defconn->lconn_sasl_sockctx ) {
  430. sasl_dispose( &oldctx );
  431. }
  432. ld->ld_defconn->lconn_sasl_authctx = NULL;
  433. }
  434. {
  435. char *saslhost;
  436. int nocanon = (int)LDAP_BOOL_GET( &ld->ld_options,
  437. LDAP_BOOL_SASL_NOCANON );
  438. /* If we don't need to canonicalize just use the host
  439. * from the LDAP URI.
  440. * Always use the result of gethostname() for LDAPI.
  441. * Skip for Windows which doesn't support LDAPI.
  442. */
  443. #if !defined(_WIN32)
  444. if (ld->ld_defconn->lconn_server->lud_scheme != NULL &&
  445. strcmp("ldapi", ld->ld_defconn->lconn_server->lud_scheme) == 0) {
  446. rc = gethostname(my_hostname, HOST_NAME_MAX + 1);
  447. if (rc == 0) {
  448. saslhost = my_hostname;
  449. } else {
  450. saslhost = "localhost";
  451. }
  452. } else
  453. #endif
  454. if ( nocanon )
  455. saslhost = ld->ld_defconn->lconn_server->lud_host;
  456. else {
  457. saslhost = ldap_host_connected_to( ld->ld_defconn->lconn_sb,
  458. "localhost" );
  459. free_saslhost = 1;
  460. }
  461. rc = ldap_int_sasl_open( ld, ld->ld_defconn, saslhost );
  462. if ( free_saslhost )
  463. LDAP_FREE( saslhost );
  464. }
  465. if ( rc != LDAP_SUCCESS ) return rc;
  466. ctx = ld->ld_defconn->lconn_sasl_authctx;
  467. #ifdef HAVE_TLS
  468. /* Check for TLS */
  469. ssl = ldap_pvt_tls_sb_ctx( ld->ld_defconn->lconn_sb );
  470. if ( ssl ) {
  471. struct berval authid = BER_BVNULL;
  472. ber_len_t fac;
  473. fac = ldap_pvt_tls_get_strength( ssl );
  474. /* failure is OK, we just can't use SASL EXTERNAL */
  475. (void) ldap_pvt_tls_get_my_dn( ssl, &authid, NULL, 0 );
  476. (void) ldap_int_sasl_external( ld, ld->ld_defconn, authid.bv_val, fac );
  477. LDAP_FREE( authid.bv_val );
  478. #ifdef SASL_CHANNEL_BINDING /* 2.1.25+ */
  479. if ( ld->ld_defconn->lconn_sasl_cbind == NULL ) {
  480. void *cb;
  481. cb = ldap_pvt_sasl_cbinding( ssl,
  482. ld->ld_options.ldo_sasl_cbinding,
  483. 0 );
  484. if ( cb != NULL ) {
  485. sasl_setprop( ld->ld_defconn->lconn_sasl_authctx,
  486. SASL_CHANNEL_BINDING, cb );
  487. ld->ld_defconn->lconn_sasl_cbind = cb;
  488. }
  489. }
  490. #endif
  491. }
  492. #endif
  493. #if !defined(_WIN32)
  494. /* Check for local */
  495. if ( ldap_pvt_url_scheme2proto(
  496. ld->ld_defconn->lconn_server->lud_scheme ) == LDAP_PROTO_IPC )
  497. {
  498. char authid[sizeof("gidNumber=4294967295+uidNumber=4294967295,"
  499. "cn=peercred,cn=external,cn=auth")];
  500. sprintf( authid, "gidNumber=%u+uidNumber=%u,"
  501. "cn=peercred,cn=external,cn=auth",
  502. getegid(), geteuid() );
  503. (void) ldap_int_sasl_external( ld, ld->ld_defconn, authid,
  504. LDAP_PVT_SASL_LOCAL_SSF );
  505. }
  506. #endif
  507. /* (re)set security properties */
  508. sasl_setprop( ctx, SASL_SEC_PROPS,
  509. &ld->ld_options.ldo_sasl_secprops );
  510. mech = NULL;
  511. do {
  512. saslrc = sasl_client_start( ctx,
  513. mechs,
  514. #if SASL_VERSION_MAJOR < 2
  515. NULL,
  516. #endif
  517. &prompts,
  518. (SASL_CONST char **)&ccred.bv_val,
  519. &credlen,
  520. &mech );
  521. if( pmech == NULL && mech != NULL ) {
  522. pmech = mech;
  523. *rmech = mech;
  524. if( flags != LDAP_SASL_QUIET ) {
  525. fprintf(stderr,
  526. "SASL/%s authentication started\n",
  527. pmech );
  528. }
  529. }
  530. if( saslrc == SASL_INTERACT ) {
  531. int res;
  532. if( !interact ) break;
  533. res = (interact)( ld, flags, defaults, prompts );
  534. if( res != LDAP_SUCCESS ) break;
  535. }
  536. } while ( saslrc == SASL_INTERACT );
  537. rc = LDAP_SASL_BIND_IN_PROGRESS;
  538. } else {
  539. /* continuing an in-progress Bind */
  540. struct berval *scred = NULL;
  541. ctx = ld->ld_defconn->lconn_sasl_authctx;
  542. rc = ldap_parse_sasl_bind_result( ld, result, &scred, 0 );
  543. if ( rc != LDAP_SUCCESS ) {
  544. if ( scred )
  545. ber_bvfree( scred );
  546. goto done;
  547. }
  548. rc = ldap_result2error( ld, result, 0 );
  549. if ( rc != LDAP_SUCCESS && rc != LDAP_SASL_BIND_IN_PROGRESS ) {
  550. if( scred ) {
  551. /* and server provided us with data? */
  552. Debug2( LDAP_DEBUG_TRACE,
  553. "ldap_int_sasl_bind: rc=%d len=%ld\n",
  554. rc, scred ? (long) scred->bv_len : -1L );
  555. ber_bvfree( scred );
  556. scred = NULL;
  557. }
  558. goto done;
  559. }
  560. mech = *rmech;
  561. if ( rc == LDAP_SUCCESS && mech == NULL ) {
  562. if ( scred )
  563. ber_bvfree( scred );
  564. goto success;
  565. }
  566. do {
  567. if( ! scred ) {
  568. /* no data! */
  569. Debug0( LDAP_DEBUG_TRACE,
  570. "ldap_int_sasl_bind: no data in step!\n" );
  571. }
  572. saslrc = sasl_client_step( ctx,
  573. (scred == NULL) ? NULL : scred->bv_val,
  574. (scred == NULL) ? 0 : scred->bv_len,
  575. &prompts,
  576. (SASL_CONST char **)&ccred.bv_val,
  577. &credlen );
  578. Debug1( LDAP_DEBUG_TRACE, "sasl_client_step: %d\n",
  579. saslrc );
  580. if( saslrc == SASL_INTERACT ) {
  581. int res;
  582. if( !interact ) break;
  583. res = (interact)( ld, flags, defaults, prompts );
  584. if( res != LDAP_SUCCESS ) break;
  585. }
  586. } while ( saslrc == SASL_INTERACT );
  587. ber_bvfree( scred );
  588. }
  589. if ( (saslrc != SASL_OK) && (saslrc != SASL_CONTINUE) ) {
  590. rc = ld->ld_errno = sasl_err2ldap( saslrc );
  591. #if SASL_VERSION_MAJOR >= 2
  592. if ( ld->ld_error ) {
  593. LDAP_FREE( ld->ld_error );
  594. }
  595. ld->ld_error = LDAP_STRDUP( sasl_errdetail( ctx ) );
  596. #endif
  597. goto done;
  598. }
  599. if ( saslrc == SASL_OK )
  600. *rmech = NULL;
  601. ccred.bv_len = credlen;
  602. if ( rc == LDAP_SASL_BIND_IN_PROGRESS ) {
  603. rc = ldap_sasl_bind( ld, dn, mech, &ccred, sctrls, cctrls, msgid );
  604. if ( ccred.bv_val != NULL ) {
  605. #if SASL_VERSION_MAJOR < 2
  606. LDAP_FREE( ccred.bv_val );
  607. #endif
  608. ccred.bv_val = NULL;
  609. }
  610. if ( rc == LDAP_SUCCESS )
  611. rc = LDAP_SASL_BIND_IN_PROGRESS;
  612. goto done;
  613. }
  614. success:
  615. /* Conversation was completed successfully by now */
  616. if( flags != LDAP_SASL_QUIET ) {
  617. char *data;
  618. saslrc = sasl_getprop( ctx, SASL_USERNAME,
  619. (SASL_CONST void **)(char *) &data );
  620. if( saslrc == SASL_OK && data && *data ) {
  621. fprintf( stderr, "SASL username: %s\n", data );
  622. }
  623. #if SASL_VERSION_MAJOR < 2
  624. saslrc = sasl_getprop( ctx, SASL_REALM,
  625. (SASL_CONST void **) &data );
  626. if( saslrc == SASL_OK && data && *data ) {
  627. fprintf( stderr, "SASL realm: %s\n", data );
  628. }
  629. #endif
  630. }
  631. ssf = NULL;
  632. saslrc = sasl_getprop( ctx, SASL_SSF, (SASL_CONST void **)(char *) &ssf );
  633. if( saslrc == SASL_OK ) {
  634. if( flags != LDAP_SASL_QUIET ) {
  635. fprintf( stderr, "SASL SSF: %lu\n",
  636. (unsigned long) *ssf );
  637. }
  638. if( ssf && *ssf ) {
  639. if ( ld->ld_defconn->lconn_sasl_sockctx ) {
  640. sasl_conn_t *oldctx = ld->ld_defconn->lconn_sasl_sockctx;
  641. sasl_dispose( &oldctx );
  642. ldap_pvt_sasl_remove( ld->ld_defconn->lconn_sb );
  643. }
  644. ldap_pvt_sasl_install( ld->ld_defconn->lconn_sb, ctx );
  645. ld->ld_defconn->lconn_sasl_sockctx = ctx;
  646. if( flags != LDAP_SASL_QUIET ) {
  647. fprintf( stderr, "SASL data security layer installed.\n" );
  648. }
  649. }
  650. }
  651. ld->ld_defconn->lconn_sasl_authctx = ctx;
  652. done:
  653. return rc;
  654. }
  655. int
  656. ldap_int_sasl_external(
  657. LDAP *ld,
  658. LDAPConn *conn,
  659. const char * authid,
  660. ber_len_t ssf )
  661. {
  662. int sc;
  663. sasl_conn_t *ctx;
  664. #if SASL_VERSION_MAJOR < 2
  665. sasl_external_properties_t extprops;
  666. #else
  667. sasl_ssf_t sasl_ssf = ssf;
  668. #endif
  669. ctx = conn->lconn_sasl_authctx;
  670. if ( ctx == NULL ) {
  671. return LDAP_LOCAL_ERROR;
  672. }
  673. #if SASL_VERSION_MAJOR >= 2
  674. sc = sasl_setprop( ctx, SASL_SSF_EXTERNAL, &sasl_ssf );
  675. if ( sc == SASL_OK )
  676. sc = sasl_setprop( ctx, SASL_AUTH_EXTERNAL, authid );
  677. #else
  678. memset( &extprops, '\0', sizeof(extprops) );
  679. extprops.ssf = ssf;
  680. extprops.auth_id = (char *) authid;
  681. sc = sasl_setprop( ctx, SASL_SSF_EXTERNAL,
  682. (void *) &extprops );
  683. #endif
  684. if ( sc != SASL_OK ) {
  685. return LDAP_LOCAL_ERROR;
  686. }
  687. return LDAP_SUCCESS;
  688. }
  689. #define GOT_MINSSF 1
  690. #define GOT_MAXSSF 2
  691. #define GOT_MAXBUF 4
  692. static struct {
  693. struct berval key;
  694. int sflag;
  695. int ival;
  696. int idef;
  697. } sprops[] = {
  698. { BER_BVC("none"), 0, 0, 0 },
  699. { BER_BVC("nodict"), SASL_SEC_NODICTIONARY, 0, 0 },
  700. { BER_BVC("noplain"), SASL_SEC_NOPLAINTEXT, 0, 0 },
  701. { BER_BVC("noactive"), SASL_SEC_NOACTIVE, 0, 0 },
  702. { BER_BVC("passcred"), SASL_SEC_PASS_CREDENTIALS, 0, 0 },
  703. { BER_BVC("forwardsec"), SASL_SEC_FORWARD_SECRECY, 0, 0 },
  704. { BER_BVC("noanonymous"), SASL_SEC_NOANONYMOUS, 0, 0 },
  705. { BER_BVC("minssf="), 0, GOT_MINSSF, 0 },
  706. { BER_BVC("maxssf="), 0, GOT_MAXSSF, INT_MAX },
  707. { BER_BVC("maxbufsize="), 0, GOT_MAXBUF, 65536 },
  708. { BER_BVNULL, 0, 0, 0 }
  709. };
  710. void ldap_pvt_sasl_secprops_unparse(
  711. sasl_security_properties_t *secprops,
  712. struct berval *out )
  713. {
  714. int i, l = 0;
  715. int comma;
  716. char *ptr;
  717. if ( secprops == NULL || out == NULL ) {
  718. return;
  719. }
  720. comma = 0;
  721. for ( i=0; !BER_BVISNULL( &sprops[i].key ); i++ ) {
  722. if ( sprops[i].ival ) {
  723. int v = 0;
  724. switch( sprops[i].ival ) {
  725. case GOT_MINSSF: v = secprops->min_ssf; break;
  726. case GOT_MAXSSF: v = secprops->max_ssf; break;
  727. case GOT_MAXBUF: v = secprops->maxbufsize; break;
  728. }
  729. /* It is the default, ignore it */
  730. if ( v == sprops[i].idef ) continue;
  731. l += sprops[i].key.bv_len + 24;
  732. } else if ( sprops[i].sflag ) {
  733. if ( sprops[i].sflag & secprops->security_flags ) {
  734. l += sprops[i].key.bv_len;
  735. }
  736. } else if ( secprops->security_flags == 0 ) {
  737. l += sprops[i].key.bv_len;
  738. }
  739. if ( comma ) l++;
  740. comma = 1;
  741. }
  742. l++;
  743. out->bv_val = LDAP_MALLOC( l );
  744. if ( out->bv_val == NULL ) {
  745. out->bv_len = 0;
  746. return;
  747. }
  748. ptr = out->bv_val;
  749. comma = 0;
  750. for ( i=0; !BER_BVISNULL( &sprops[i].key ); i++ ) {
  751. if ( sprops[i].ival ) {
  752. int v = 0;
  753. switch( sprops[i].ival ) {
  754. case GOT_MINSSF: v = secprops->min_ssf; break;
  755. case GOT_MAXSSF: v = secprops->max_ssf; break;
  756. case GOT_MAXBUF: v = secprops->maxbufsize; break;
  757. }
  758. /* It is the default, ignore it */
  759. if ( v == sprops[i].idef ) continue;
  760. if ( comma ) *ptr++ = ',';
  761. ptr += sprintf(ptr, "%s%d", sprops[i].key.bv_val, v );
  762. comma = 1;
  763. } else if ( sprops[i].sflag ) {
  764. if ( sprops[i].sflag & secprops->security_flags ) {
  765. if ( comma ) *ptr++ = ',';
  766. ptr += sprintf(ptr, "%s", sprops[i].key.bv_val );
  767. comma = 1;
  768. }
  769. } else if ( secprops->security_flags == 0 ) {
  770. if ( comma ) *ptr++ = ',';
  771. ptr += sprintf(ptr, "%s", sprops[i].key.bv_val );
  772. comma = 1;
  773. }
  774. }
  775. out->bv_len = ptr - out->bv_val;
  776. }
  777. int ldap_pvt_sasl_secprops(
  778. const char *in,
  779. sasl_security_properties_t *secprops )
  780. {
  781. unsigned i, j, l;
  782. char **props;
  783. unsigned sflags = 0;
  784. int got_sflags = 0;
  785. sasl_ssf_t max_ssf = 0;
  786. int got_max_ssf = 0;
  787. sasl_ssf_t min_ssf = 0;
  788. int got_min_ssf = 0;
  789. unsigned maxbufsize = 0;
  790. int got_maxbufsize = 0;
  791. if( secprops == NULL ) {
  792. return LDAP_PARAM_ERROR;
  793. }
  794. props = ldap_str2charray( in, "," );
  795. if( props == NULL ) {
  796. return LDAP_PARAM_ERROR;
  797. }
  798. for( i=0; props[i]; i++ ) {
  799. l = strlen( props[i] );
  800. for ( j=0; !BER_BVISNULL( &sprops[j].key ); j++ ) {
  801. if ( l < sprops[j].key.bv_len ) continue;
  802. if ( strncasecmp( props[i], sprops[j].key.bv_val,
  803. sprops[j].key.bv_len )) continue;
  804. if ( sprops[j].ival ) {
  805. unsigned v;
  806. char *next = NULL;
  807. if ( !isdigit( (unsigned char)props[i][sprops[j].key.bv_len] ))
  808. continue;
  809. v = strtoul( &props[i][sprops[j].key.bv_len], &next, 10 );
  810. if ( next == &props[i][sprops[j].key.bv_len] || next[0] != '\0' ) continue;
  811. switch( sprops[j].ival ) {
  812. case GOT_MINSSF:
  813. min_ssf = v; got_min_ssf++; break;
  814. case GOT_MAXSSF:
  815. max_ssf = v; got_max_ssf++; break;
  816. case GOT_MAXBUF:
  817. maxbufsize = v; got_maxbufsize++; break;
  818. }
  819. } else {
  820. if ( props[i][sprops[j].key.bv_len] ) continue;
  821. if ( sprops[j].sflag )
  822. sflags |= sprops[j].sflag;
  823. else
  824. sflags = 0;
  825. got_sflags++;
  826. }
  827. break;
  828. }
  829. if ( BER_BVISNULL( &sprops[j].key )) {
  830. ldap_charray_free( props );
  831. return LDAP_NOT_SUPPORTED;
  832. }
  833. }
  834. if(got_sflags) {
  835. secprops->security_flags = sflags;
  836. }
  837. if(got_min_ssf) {
  838. secprops->min_ssf = min_ssf;
  839. }
  840. if(got_max_ssf) {
  841. secprops->max_ssf = max_ssf;
  842. }
  843. if(got_maxbufsize) {
  844. secprops->maxbufsize = maxbufsize;
  845. }
  846. ldap_charray_free( props );
  847. return LDAP_SUCCESS;
  848. }
  849. int
  850. ldap_int_sasl_config( struct ldapoptions *lo, int option, const char *arg )
  851. {
  852. int rc, i;
  853. switch( option ) {
  854. case LDAP_OPT_X_SASL_SECPROPS:
  855. rc = ldap_pvt_sasl_secprops( arg, &lo->ldo_sasl_secprops );
  856. if( rc == LDAP_SUCCESS ) return 0;
  857. break;
  858. case LDAP_OPT_X_SASL_CBINDING:
  859. i = ldap_pvt_sasl_cbinding_parse( arg );
  860. if ( i >= 0 ) {
  861. lo->ldo_sasl_cbinding = i;
  862. return 0;
  863. }
  864. break;
  865. }
  866. return -1;
  867. }
  868. int
  869. ldap_int_sasl_get_option( LDAP *ld, int option, void *arg )
  870. {
  871. if ( option == LDAP_OPT_X_SASL_MECHLIST ) {
  872. *(char ***)arg = (char **)sasl_global_listmech();
  873. return 0;
  874. }
  875. if ( ld == NULL )
  876. return -1;
  877. switch ( option ) {
  878. case LDAP_OPT_X_SASL_MECH: {
  879. *(char **)arg = ld->ld_options.ldo_def_sasl_mech
  880. ? LDAP_STRDUP( ld->ld_options.ldo_def_sasl_mech ) : NULL;
  881. } break;
  882. case LDAP_OPT_X_SASL_REALM: {
  883. *(char **)arg = ld->ld_options.ldo_def_sasl_realm
  884. ? LDAP_STRDUP( ld->ld_options.ldo_def_sasl_realm ) : NULL;
  885. } break;
  886. case LDAP_OPT_X_SASL_AUTHCID: {
  887. *(char **)arg = ld->ld_options.ldo_def_sasl_authcid
  888. ? LDAP_STRDUP( ld->ld_options.ldo_def_sasl_authcid ) : NULL;
  889. } break;
  890. case LDAP_OPT_X_SASL_AUTHZID: {
  891. *(char **)arg = ld->ld_options.ldo_def_sasl_authzid
  892. ? LDAP_STRDUP( ld->ld_options.ldo_def_sasl_authzid ) : NULL;
  893. } break;
  894. case LDAP_OPT_X_SASL_SSF: {
  895. int sc;
  896. sasl_ssf_t *ssf;
  897. sasl_conn_t *ctx;
  898. if( ld->ld_defconn == NULL ) {
  899. return -1;
  900. }
  901. ctx = ld->ld_defconn->lconn_sasl_sockctx;
  902. if ( ctx == NULL ) {
  903. return -1;
  904. }
  905. sc = sasl_getprop( ctx, SASL_SSF,
  906. (SASL_CONST void **)(char *) &ssf );
  907. if ( sc != SASL_OK ) {
  908. return -1;
  909. }
  910. *(ber_len_t *)arg = *ssf;
  911. } break;
  912. case LDAP_OPT_X_SASL_SSF_EXTERNAL:
  913. /* this option is write only */
  914. return -1;
  915. case LDAP_OPT_X_SASL_SSF_MIN:
  916. *(ber_len_t *)arg = ld->ld_options.ldo_sasl_secprops.min_ssf;
  917. break;
  918. case LDAP_OPT_X_SASL_SSF_MAX:
  919. *(ber_len_t *)arg = ld->ld_options.ldo_sasl_secprops.max_ssf;
  920. break;
  921. case LDAP_OPT_X_SASL_MAXBUFSIZE:
  922. *(ber_len_t *)arg = ld->ld_options.ldo_sasl_secprops.maxbufsize;
  923. break;
  924. case LDAP_OPT_X_SASL_NOCANON:
  925. *(int *)arg = (int) LDAP_BOOL_GET(&ld->ld_options, LDAP_BOOL_SASL_NOCANON );
  926. break;
  927. case LDAP_OPT_X_SASL_USERNAME: {
  928. int sc;
  929. char *username;
  930. sasl_conn_t *ctx;
  931. if( ld->ld_defconn == NULL ) {
  932. return -1;
  933. }
  934. ctx = ld->ld_defconn->lconn_sasl_authctx;
  935. if ( ctx == NULL ) {
  936. return -1;
  937. }
  938. sc = sasl_getprop( ctx, SASL_USERNAME,
  939. (SASL_CONST void **)(char **) &username );
  940. if ( sc != SASL_OK ) {
  941. return -1;
  942. }
  943. *(char **)arg = username ? LDAP_STRDUP( username ) : NULL;
  944. } break;
  945. case LDAP_OPT_X_SASL_SECPROPS:
  946. /* this option is write only */
  947. return -1;
  948. case LDAP_OPT_X_SASL_CBINDING:
  949. *(int *)arg = ld->ld_options.ldo_sasl_cbinding;
  950. break;
  951. #ifdef SASL_GSS_CREDS
  952. case LDAP_OPT_X_SASL_GSS_CREDS: {
  953. sasl_conn_t *ctx;
  954. int sc;
  955. if ( ld->ld_defconn == NULL )
  956. return -1;
  957. ctx = ld->ld_defconn->lconn_sasl_authctx;
  958. if ( ctx == NULL )
  959. return -1;
  960. sc = sasl_getprop( ctx, SASL_GSS_CREDS, arg );
  961. if ( sc != SASL_OK )
  962. return -1;
  963. }
  964. break;
  965. #endif
  966. default:
  967. return -1;
  968. }
  969. return 0;
  970. }
  971. int
  972. ldap_int_sasl_set_option( LDAP *ld, int option, void *arg )
  973. {
  974. if ( ld == NULL )
  975. return -1;
  976. if ( arg == NULL && option != LDAP_OPT_X_SASL_NOCANON )
  977. return -1;
  978. switch ( option ) {
  979. case LDAP_OPT_X_SASL_SSF:
  980. case LDAP_OPT_X_SASL_USERNAME:
  981. /* This option is read-only */
  982. return -1;
  983. case LDAP_OPT_X_SASL_SSF_EXTERNAL: {
  984. int sc;
  985. #if SASL_VERSION_MAJOR < 2
  986. sasl_external_properties_t extprops;
  987. #else
  988. sasl_ssf_t sasl_ssf;
  989. #endif
  990. sasl_conn_t *ctx;
  991. if( ld->ld_defconn == NULL ) {
  992. return -1;
  993. }
  994. ctx = ld->ld_defconn->lconn_sasl_authctx;
  995. if ( ctx == NULL ) {
  996. return -1;
  997. }
  998. #if SASL_VERSION_MAJOR >= 2
  999. sasl_ssf = * (ber_len_t *)arg;
  1000. sc = sasl_setprop( ctx, SASL_SSF_EXTERNAL, &sasl_ssf);
  1001. #else
  1002. memset(&extprops, 0L, sizeof(extprops));
  1003. extprops.ssf = * (ber_len_t *) arg;
  1004. sc = sasl_setprop( ctx, SASL_SSF_EXTERNAL,
  1005. (void *) &extprops );
  1006. #endif
  1007. if ( sc != SASL_OK ) {
  1008. return -1;
  1009. }
  1010. } break;
  1011. case LDAP_OPT_X_SASL_SSF_MIN:
  1012. ld->ld_options.ldo_sasl_secprops.min_ssf = *(ber_len_t *)arg;
  1013. break;
  1014. case LDAP_OPT_X_SASL_SSF_MAX:
  1015. ld->ld_options.ldo_sasl_secprops.max_ssf = *(ber_len_t *)arg;
  1016. break;
  1017. case LDAP_OPT_X_SASL_MAXBUFSIZE:
  1018. ld->ld_options.ldo_sasl_secprops.maxbufsize = *(ber_len_t *)arg;
  1019. break;
  1020. case LDAP_OPT_X_SASL_NOCANON:
  1021. if ( arg == LDAP_OPT_OFF ) {
  1022. LDAP_BOOL_CLR(&ld->ld_options, LDAP_BOOL_SASL_NOCANON );
  1023. } else {
  1024. LDAP_BOOL_SET(&ld->ld_options, LDAP_BOOL_SASL_NOCANON );
  1025. }
  1026. break;
  1027. case LDAP_OPT_X_SASL_SECPROPS: {
  1028. int sc;
  1029. sc = ldap_pvt_sasl_secprops( (char *) arg,
  1030. &ld->ld_options.ldo_sasl_secprops );
  1031. return sc == LDAP_SUCCESS ? 0 : -1;
  1032. }
  1033. case LDAP_OPT_X_SASL_CBINDING:
  1034. if ( !arg ) return -1;
  1035. switch( *(int *) arg ) {
  1036. case LDAP_OPT_X_SASL_CBINDING_NONE:
  1037. case LDAP_OPT_X_SASL_CBINDING_TLS_UNIQUE:
  1038. case LDAP_OPT_X_SASL_CBINDING_TLS_ENDPOINT:
  1039. ld->ld_options.ldo_sasl_cbinding = *(int *) arg;
  1040. return 0;
  1041. }
  1042. return -1;
  1043. #ifdef SASL_GSS_CREDS
  1044. case LDAP_OPT_X_SASL_GSS_CREDS: {
  1045. sasl_conn_t *ctx;
  1046. int sc;
  1047. if ( ld->ld_defconn == NULL )
  1048. return -1;
  1049. ctx = ld->ld_defconn->lconn_sasl_authctx;
  1050. if ( ctx == NULL )
  1051. return -1;
  1052. sc = sasl_setprop( ctx, SASL_GSS_CREDS, arg );
  1053. if ( sc != SASL_OK )
  1054. return -1;
  1055. }
  1056. break;
  1057. #endif
  1058. default:
  1059. return -1;
  1060. }
  1061. return 0;
  1062. }
  1063. #ifdef LDAP_R_COMPILE
  1064. #define LDAP_DEBUG_R_SASL
  1065. void *ldap_pvt_sasl_mutex_new(void)
  1066. {
  1067. ldap_pvt_thread_mutex_t *mutex;
  1068. mutex = (ldap_pvt_thread_mutex_t *) LDAP_CALLOC( 1,
  1069. sizeof(ldap_pvt_thread_mutex_t) );
  1070. if ( ldap_pvt_thread_mutex_init( mutex ) == 0 ) {
  1071. return mutex;
  1072. }
  1073. LDAP_FREE( mutex );
  1074. #ifndef LDAP_DEBUG_R_SASL
  1075. assert( 0 );
  1076. #endif /* !LDAP_DEBUG_R_SASL */
  1077. return NULL;
  1078. }
  1079. int ldap_pvt_sasl_mutex_lock(void *mutex)
  1080. {
  1081. #ifdef LDAP_DEBUG_R_SASL
  1082. if ( mutex == NULL ) {
  1083. return SASL_OK;
  1084. }
  1085. #else /* !LDAP_DEBUG_R_SASL */
  1086. assert( mutex != NULL );
  1087. #endif /* !LDAP_DEBUG_R_SASL */
  1088. return ldap_pvt_thread_mutex_lock( (ldap_pvt_thread_mutex_t *)mutex )
  1089. ? SASL_FAIL : SASL_OK;
  1090. }
  1091. int ldap_pvt_sasl_mutex_unlock(void *mutex)
  1092. {
  1093. #ifdef LDAP_DEBUG_R_SASL
  1094. if ( mutex == NULL ) {
  1095. return SASL_OK;
  1096. }
  1097. #else /* !LDAP_DEBUG_R_SASL */
  1098. assert( mutex != NULL );
  1099. #endif /* !LDAP_DEBUG_R_SASL */
  1100. return ldap_pvt_thread_mutex_unlock( (ldap_pvt_thread_mutex_t *)mutex )
  1101. ? SASL_FAIL : SASL_OK;
  1102. }
  1103. void ldap_pvt_sasl_mutex_dispose(void *mutex)
  1104. {
  1105. #ifdef LDAP_DEBUG_R_SASL
  1106. if ( mutex == NULL ) {
  1107. return;
  1108. }
  1109. #else /* !LDAP_DEBUG_R_SASL */
  1110. assert( mutex != NULL );
  1111. #endif /* !LDAP_DEBUG_R_SASL */
  1112. (void) ldap_pvt_thread_mutex_destroy( (ldap_pvt_thread_mutex_t *)mutex );
  1113. LDAP_FREE( mutex );
  1114. }
  1115. #endif
  1116. #else
  1117. int ldap_int_sasl_init( void )
  1118. { return LDAP_SUCCESS; }
  1119. int ldap_int_sasl_close( LDAP *ld, LDAPConn *lc )
  1120. { return LDAP_SUCCESS; }
  1121. int
  1122. ldap_int_sasl_bind(
  1123. LDAP *ld,
  1124. const char *dn,
  1125. const char *mechs,
  1126. LDAPControl **sctrls,
  1127. LDAPControl **cctrls,
  1128. unsigned flags,
  1129. LDAP_SASL_INTERACT_PROC *interact,
  1130. void *defaults,
  1131. LDAPMessage *result,
  1132. const char **rmech,
  1133. int *msgid )
  1134. { return LDAP_NOT_SUPPORTED; }
  1135. int
  1136. ldap_int_sasl_external(
  1137. LDAP *ld,
  1138. LDAPConn *conn,
  1139. const char * authid,
  1140. ber_len_t ssf )
  1141. { return LDAP_SUCCESS; }
  1142. #endif /* HAVE_CYRUS_SASL */