sasl_map.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642
  1. /** BEGIN COPYRIGHT BLOCK
  2. * This Program is free software; you can redistribute it and/or modify it under
  3. * the terms of the GNU General Public License as published by the Free Software
  4. * Foundation; version 2 of the License.
  5. *
  6. * This Program is distributed in the hope that it will be useful, but WITHOUT
  7. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  8. * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
  9. *
  10. * You should have received a copy of the GNU General Public License along with
  11. * this Program; if not, write to the Free Software Foundation, Inc., 59 Temple
  12. * Place, Suite 330, Boston, MA 02111-1307 USA.
  13. *
  14. * In addition, as a special exception, Red Hat, Inc. gives You the additional
  15. * right to link the code of this Program with code not covered under the GNU
  16. * General Public License ("Non-GPL Code") and to distribute linked combinations
  17. * including the two, subject to the limitations in this paragraph. Non-GPL Code
  18. * permitted under this exception must only link to the code of this Program
  19. * through those well defined interfaces identified in the file named EXCEPTION
  20. * found in the source code files (the "Approved Interfaces"). The files of
  21. * Non-GPL Code may instantiate templates or use macros or inline functions from
  22. * the Approved Interfaces without causing the resulting work to be covered by
  23. * the GNU General Public License. Only Red Hat, Inc. may make changes or
  24. * additions to the list of Approved Interfaces. You must obey the GNU General
  25. * Public License in all respects for all of the Program code and other code used
  26. * in conjunction with the Program except the Non-GPL Code covered by this
  27. * exception. If you modify this file, you may extend this exception to your
  28. * version of the file, but you are not obligated to do so. If you do not wish to
  29. * provide this exception without modification, you must delete this exception
  30. * statement from your version and license this file solely under the GPL without
  31. * exception.
  32. *
  33. *
  34. * Copyright (C) 2005 Red Hat, Inc.
  35. * All rights reserved.
  36. * END COPYRIGHT BLOCK **/
  37. #ifdef HAVE_CONFIG_H
  38. # include <config.h>
  39. #endif
  40. #include "slap.h"
  41. #include "slapi-plugin.h"
  42. #include "fe.h"
  43. /*
  44. * Map SASL identities to LDAP searches
  45. */
  46. /*
  47. * We maintain a list of mappings to consult
  48. */
  49. typedef struct sasl_map_data_ sasl_map_data;
  50. struct sasl_map_data_ {
  51. char *name;
  52. char *regular_expression;
  53. char *template_base_dn;
  54. char *template_search_filter;
  55. sasl_map_data *next; /* For linked list */
  56. };
  57. typedef struct _sasl_map_private {
  58. PRLock *lock;
  59. sasl_map_data *map_data_list;
  60. } sasl_map_private;
  61. static char * configDN = "cn=mapping,cn=sasl,cn=config";
  62. /*
  63. * DBDB: this is ugly, but right now there is _no_ server-wide
  64. * dynamic structure (like a Slapi_Server * type thing). All the code
  65. * that needs such a thing instead maintains a static or global variable.
  66. * Until we implement the 'right thing', we'll just follow suit here :(
  67. */
  68. static sasl_map_private *sasl_map_static_priv = NULL;
  69. static
  70. sasl_map_private *sasl_map_get_global_priv()
  71. {
  72. /* ASSERT(sasl_map_static_priv) */
  73. return sasl_map_static_priv;
  74. }
  75. static
  76. sasl_map_private *sasl_map_new_private()
  77. {
  78. PRLock *new_lock = PR_NewLock();
  79. sasl_map_private *new_priv = NULL;
  80. if (NULL == new_lock) {
  81. return NULL;
  82. }
  83. new_priv = (sasl_map_private *)slapi_ch_calloc(1,sizeof(sasl_map_private));
  84. new_priv->lock = new_lock;
  85. return new_priv;
  86. }
  87. static void
  88. sasl_map_free_private(sasl_map_private **priv)
  89. {
  90. PR_DestroyLock((*priv)->lock);
  91. slapi_ch_free((void**)priv);
  92. *priv = NULL;
  93. }
  94. /* This function does a shallow copy on the payload data supplied, so the caller should not free it, and it needs to be allocated using slapi_ch_malloc() */
  95. static
  96. sasl_map_data *sasl_map_new_data(char *name, char *regex, char *dntemplate, char *filtertemplate)
  97. {
  98. sasl_map_data *new_dp = (sasl_map_data *) slapi_ch_calloc(1,sizeof(sasl_map_data));
  99. new_dp->name = name;
  100. new_dp->regular_expression = regex;
  101. new_dp->template_base_dn = dntemplate;
  102. new_dp->template_search_filter = filtertemplate;
  103. return new_dp;
  104. }
  105. static
  106. sasl_map_data *sasl_map_next(sasl_map_data *dp)
  107. {
  108. return dp->next;
  109. }
  110. static void
  111. sasl_map_free_data(sasl_map_data **dp)
  112. {
  113. slapi_ch_free_string(&(*dp)->name);
  114. slapi_ch_free_string(&(*dp)->regular_expression);
  115. slapi_ch_free_string(&(*dp)->template_base_dn);
  116. slapi_ch_free_string(&(*dp)->template_search_filter);
  117. slapi_ch_free((void**)dp);
  118. }
  119. static int
  120. sasl_map_remove_list_entry(sasl_map_private *priv, char *removeme)
  121. {
  122. int ret = 0;
  123. int foundit = 0;
  124. sasl_map_data *current = NULL;
  125. sasl_map_data *previous = NULL;
  126. PR_Lock(priv->lock);
  127. current = priv->map_data_list;
  128. while (current) {
  129. if (0 == strcmp(current->name,removeme)) {
  130. foundit = 1;
  131. if (previous) {
  132. /* Unlink it */
  133. previous->next = current->next;
  134. } else {
  135. /* That was the first list entry */
  136. priv->map_data_list = current->next;
  137. }
  138. /* Payload free */
  139. sasl_map_free_data(&current);
  140. /* And no need to look further */
  141. break;
  142. }
  143. previous = current;
  144. current = current->next;
  145. }
  146. if (!foundit) {
  147. ret = -1;
  148. }
  149. PR_Unlock(priv->lock);
  150. return ret;
  151. }
  152. static int
  153. sasl_map_cmp_data(sasl_map_data *dp0, sasl_map_data *dp1)
  154. {
  155. int rc = 0;
  156. if (NULL == dp0) {
  157. if (NULL == dp1) {
  158. return 0;
  159. } else {
  160. return -1;
  161. }
  162. } else {
  163. if (NULL == dp1) {
  164. return 1;
  165. }
  166. }
  167. rc = PL_strcmp(dp0->name, dp1->name);
  168. if (0 != rc) {
  169. /* did not match */
  170. return rc;
  171. }
  172. rc = PL_strcmp(dp0->regular_expression, dp1->regular_expression);
  173. if (0 != rc) {
  174. /* did not match */
  175. return rc;
  176. }
  177. rc = PL_strcmp(dp0->template_base_dn, dp1->template_base_dn);
  178. if (0 != rc) {
  179. /* did not match */
  180. return rc;
  181. }
  182. rc = PL_strcmp(dp0->template_search_filter, dp1->template_search_filter);
  183. return rc;
  184. }
  185. static int
  186. sasl_map_insert_list_entry(sasl_map_private *priv, sasl_map_data *dp)
  187. {
  188. int ret = 0;
  189. int ishere = 0;
  190. sasl_map_data *current = NULL;
  191. if (NULL == dp) {
  192. return ret;
  193. }
  194. PR_Lock(priv->lock);
  195. /* Check to see if it's here already */
  196. current = priv->map_data_list;
  197. while (current) {
  198. if (0 == sasl_map_cmp_data(current, dp)) {
  199. ishere = 1;
  200. }
  201. if (current->next) {
  202. current = current->next;
  203. } else {
  204. break;
  205. }
  206. }
  207. if (ishere) {
  208. return -1;
  209. }
  210. /* current now points to the end of the list or NULL */
  211. if (NULL == priv->map_data_list) {
  212. priv->map_data_list = dp;
  213. } else {
  214. current->next = dp;
  215. }
  216. PR_Unlock(priv->lock);
  217. return ret;
  218. }
  219. /*
  220. * Functions to handle config operations
  221. */
  222. /**
  223. * Get a list of child DNs
  224. * DBDB these functions should be folded into libslapd because it's a copy of a function in ssl.c
  225. */
  226. static char **
  227. getChildren( char *dn ) {
  228. Slapi_PBlock *new_pb = NULL;
  229. Slapi_Entry **e;
  230. int search_result = 1;
  231. int nEntries = 0;
  232. char **list = NULL;
  233. new_pb = slapi_search_internal ( dn, LDAP_SCOPE_ONELEVEL,
  234. "(objectclass=nsSaslMapping)",
  235. NULL, NULL, 0);
  236. slapi_pblock_get( new_pb, SLAPI_NENTRIES, &nEntries);
  237. if ( nEntries > 0 ) {
  238. slapi_pblock_get( new_pb, SLAPI_PLUGIN_INTOP_RESULT, &search_result);
  239. slapi_pblock_get( new_pb, SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES, &e);
  240. if ( e != NULL ) {
  241. int i;
  242. list = (char **)slapi_ch_malloc( sizeof(*list) * (nEntries + 1));
  243. for ( i = 0; e[i] != NULL; i++ ) {
  244. list[i] = slapi_ch_strdup(slapi_entry_get_dn(e[i]));
  245. }
  246. list[nEntries] = NULL;
  247. }
  248. }
  249. slapi_free_search_results_internal(new_pb);
  250. slapi_pblock_destroy(new_pb );
  251. return list;
  252. }
  253. /**
  254. * Free a list of child DNs
  255. */
  256. static void
  257. freeChildren( char **list ) {
  258. if ( list != NULL ) {
  259. int i;
  260. for ( i = 0; list[i] != NULL; i++ ) {
  261. slapi_ch_free( (void **)(&list[i]) );
  262. }
  263. slapi_ch_free( (void **)(&list) );
  264. }
  265. }
  266. /**
  267. * Get a particular entry
  268. */
  269. static Slapi_Entry *
  270. getConfigEntry( const char *dn, Slapi_Entry **e2 ) {
  271. Slapi_DN sdn;
  272. slapi_sdn_init_dn_byref( &sdn, dn );
  273. slapi_search_internal_get_entry( &sdn, NULL, e2,
  274. plugin_get_default_component_id());
  275. slapi_sdn_done( &sdn );
  276. return *e2;
  277. }
  278. /**
  279. * Free an entry
  280. */
  281. static void
  282. freeConfigEntry( Slapi_Entry ** e ) {
  283. if ( (e != NULL) && (*e != NULL) ) {
  284. slapi_entry_free( *e );
  285. *e = NULL;
  286. }
  287. }
  288. /*
  289. * unescape parenthesis in the regular expression.
  290. * E.g., ^u:\(.*\) ==> ^u:(.*)
  291. * This unescape is necessary for the new regex code using PCRE
  292. * to keep the backward compatibility.
  293. */
  294. char *
  295. _sasl_unescape_parenthesis(char *input)
  296. {
  297. char *s = NULL;
  298. char *d = NULL;
  299. for (s = input, d = input; s && *s; s++) {
  300. if (*s == '\\' && *(s+1) && (*(s+1) == '(' || *(s+1) == ')')) {
  301. *d++ = *(++s);
  302. } else {
  303. *d++ = *s;
  304. }
  305. }
  306. *d = '\0';
  307. return input;
  308. }
  309. static int
  310. sasl_map_config_parse_entry(Slapi_Entry *entry, sasl_map_data **new_dp)
  311. {
  312. int ret = 0;
  313. char *regex = NULL;
  314. char *basedntemplate = NULL;
  315. char *filtertemplate = NULL;
  316. char *map_name = NULL;
  317. *new_dp = NULL;
  318. regex = _sasl_unescape_parenthesis(slapi_entry_attr_get_charptr( entry, "nsSaslMapRegexString" ));
  319. basedntemplate = slapi_entry_attr_get_charptr( entry, "nsSaslMapBaseDNTemplate" );
  320. filtertemplate = slapi_entry_attr_get_charptr( entry, "nsSaslMapFilterTemplate" );
  321. map_name = slapi_entry_attr_get_charptr( entry, "cn" );
  322. if ( (NULL == map_name) || (NULL == regex) ||
  323. (NULL == basedntemplate) || (NULL == filtertemplate) ) {
  324. /* Invalid entry */
  325. ret = -1;
  326. } else {
  327. /* Make the new dp */
  328. *new_dp = sasl_map_new_data(map_name, regex, basedntemplate, filtertemplate);
  329. }
  330. if (ret) {
  331. slapi_ch_free((void **) &map_name);
  332. slapi_ch_free((void **) &regex);
  333. slapi_ch_free((void **) &basedntemplate);
  334. slapi_ch_free((void **) &filtertemplate);
  335. }
  336. return ret;
  337. }
  338. static int
  339. sasl_map_read_config_startup(sasl_map_private *priv)
  340. {
  341. char **map_entry_list = NULL;
  342. int ret = 0;
  343. LDAPDebug( LDAP_DEBUG_TRACE, "-> sasl_map_read_config_startup\n", 0, 0, 0 );
  344. if((map_entry_list = getChildren(configDN))) {
  345. char **map_entry = NULL;
  346. Slapi_Entry *entry = NULL;
  347. sasl_map_data *dp = NULL;
  348. for (map_entry = map_entry_list; *map_entry && !ret; map_entry++) {
  349. LDAPDebug( LDAP_DEBUG_CONFIG, "sasl_map_read_config_startup - proceesing [%s]\n", *map_entry, 0, 0 );
  350. getConfigEntry( *map_entry, &entry );
  351. if ( entry == NULL ) {
  352. continue;
  353. }
  354. ret = sasl_map_config_parse_entry(entry,&dp);
  355. if (ret) {
  356. LDAPDebug( LDAP_DEBUG_ANY, "sasl_map_read_config_startup failed to parse entry\n", 0, 0, 0 );
  357. } else {
  358. ret = sasl_map_insert_list_entry(priv,dp);
  359. if (ret) {
  360. LDAPDebug( LDAP_DEBUG_ANY, "sasl_map_read_config_startup failed to insert entry\n", 0, 0, 0 );
  361. } else {
  362. LDAPDebug( LDAP_DEBUG_CONFIG, "sasl_map_read_config_startup - processed [%s]\n", *map_entry, 0, 0 );
  363. }
  364. }
  365. freeConfigEntry( &entry );
  366. }
  367. freeChildren( map_entry_list );
  368. }
  369. LDAPDebug( LDAP_DEBUG_TRACE, "<- sasl_map_read_config_startup\n", 0, 0, 0 );
  370. return ret;
  371. }
  372. int
  373. sasl_map_config_add(Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Entry* e, int *returncode, char *returntext, void *arg)
  374. {
  375. int ret = 0;
  376. sasl_map_data *dp = NULL;
  377. sasl_map_private *priv = sasl_map_get_global_priv();
  378. LDAPDebug( LDAP_DEBUG_TRACE, "-> sasl_map_config_add\n", 0, 0, 0 );
  379. ret = sasl_map_config_parse_entry(entryBefore,&dp);
  380. if (!ret && dp) {
  381. ret = sasl_map_insert_list_entry(priv,dp);
  382. }
  383. if (0 == ret) {
  384. ret = SLAPI_DSE_CALLBACK_OK;
  385. } else {
  386. returntext = "sasl map entry rejected";
  387. *returncode = LDAP_UNWILLING_TO_PERFORM;
  388. ret = SLAPI_DSE_CALLBACK_ERROR;
  389. }
  390. LDAPDebug( LDAP_DEBUG_TRACE, "<- sasl_map_config_add\n", 0, 0, 0 );
  391. return ret;
  392. }
  393. int
  394. sasl_map_config_delete(Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Entry* e, int *returncode, char *returntext, void *arg)
  395. {
  396. int ret = 0;
  397. sasl_map_private *priv = sasl_map_get_global_priv();
  398. char *entry_name = NULL;
  399. LDAPDebug( LDAP_DEBUG_TRACE, "-> sasl_map_config_delete\n", 0, 0, 0 );
  400. entry_name = slapi_entry_attr_get_charptr( entryBefore, "cn" );
  401. if (entry_name) {
  402. /* remove this entry from the list */
  403. ret = sasl_map_remove_list_entry(priv,entry_name);
  404. slapi_ch_free((void **) &entry_name);
  405. }
  406. if (ret) {
  407. ret = SLAPI_DSE_CALLBACK_ERROR;
  408. returntext = "can't delete sasl map entry";
  409. *returncode = LDAP_OPERATIONS_ERROR;
  410. } else {
  411. ret = SLAPI_DSE_CALLBACK_OK;
  412. }
  413. LDAPDebug( LDAP_DEBUG_TRACE, "<- sasl_map_config_delete\n", 0, 0, 0 );
  414. return ret;
  415. }
  416. /* Start and stop the sasl mapping code */
  417. int sasl_map_init()
  418. {
  419. int ret = 0;
  420. sasl_map_private *priv = NULL;
  421. /* Make the private structure */
  422. priv = sasl_map_new_private();
  423. if (priv) {
  424. /* Store in the static var */
  425. sasl_map_static_priv = priv;
  426. /* Read the config on startup */
  427. ret = sasl_map_read_config_startup(priv);
  428. } else {
  429. ret = -1;
  430. }
  431. return ret;
  432. }
  433. int sasl_map_done()
  434. {
  435. int ret = 0;
  436. sasl_map_private *priv = sasl_map_get_global_priv();
  437. sasl_map_data *dp = NULL;
  438. /* there is no sasl map in referral mode */
  439. if (!priv || !priv->lock || !priv->map_data_list) {
  440. return 0;
  441. }
  442. /* Free the map list */
  443. PR_Lock(priv->lock);
  444. dp = priv->map_data_list;
  445. while (dp) {
  446. sasl_map_data *dp_next = dp->next;
  447. sasl_map_free_data(&dp);
  448. dp = dp_next;
  449. }
  450. PR_Unlock(priv->lock);
  451. /* Free the private structure */
  452. sasl_map_free_private(&priv);
  453. return ret;
  454. }
  455. static sasl_map_data*
  456. sasl_map_first(sasl_map_private *priv)
  457. {
  458. sasl_map_data *result = NULL;
  459. PR_Lock(priv->lock);
  460. result = priv->map_data_list;
  461. PR_Unlock(priv->lock);
  462. return result;
  463. }
  464. static int
  465. sasl_map_check(sasl_map_data *dp, char *sasl_user_and_realm, char **ldap_search_base, char **ldap_search_filter)
  466. {
  467. Slapi_Regex *re = NULL;
  468. int ret = 0;
  469. int matched = 0;
  470. const char *recomp_result = NULL;
  471. LDAPDebug( LDAP_DEBUG_TRACE, "-> sasl_map_check\n", 0, 0, 0 );
  472. /* Compiles the regex */
  473. re = slapi_re_comp(dp->regular_expression, &recomp_result);
  474. if (NULL == re) {
  475. LDAPDebug( LDAP_DEBUG_ANY,
  476. "sasl_map_check: slapi_re_comp failed for expression (%s): %s\n",
  477. dp->regular_expression, recomp_result?recomp_result:"unknown", 0 );
  478. } else {
  479. /* Matches the compiled regex against sasl_user_and_realm */
  480. matched = slapi_re_exec(re, sasl_user_and_realm, -1 /* no timelimit */);
  481. LDAPDebug( LDAP_DEBUG_TRACE, "regex: %s, id: %s, %s\n",
  482. dp->regular_expression, sasl_user_and_realm,
  483. matched ? "matched" : "didn't match" );
  484. }
  485. if (matched) {
  486. if (matched == 1) {
  487. char escape_base[BUFSIZ];
  488. char escape_filt[BUFSIZ];
  489. int ldap_search_base_len, ldap_search_filter_len;
  490. int rc = 0;
  491. /* Allocate buffers for the returned strings */
  492. /* We already computed this, so we could pass it in to speed up
  493. * a little */
  494. size_t userrealmlen = strlen(sasl_user_and_realm);
  495. /* These lengths could be precomputed and stored in the dp */
  496. ldap_search_base_len =
  497. userrealmlen + strlen(dp->template_base_dn) + 1;
  498. ldap_search_filter_len =
  499. userrealmlen + strlen(dp->template_search_filter) + 1;
  500. *ldap_search_base = (char *)slapi_ch_malloc(ldap_search_base_len);
  501. *ldap_search_filter =
  502. (char *)slapi_ch_malloc(ldap_search_filter_len);
  503. /* Substitutes '&' and/or "\#" in template_base_dn */
  504. rc = slapi_re_subs(re, sasl_user_and_realm, dp->template_base_dn,
  505. ldap_search_base, ldap_search_base_len);
  506. if (0 != rc) {
  507. LDAPDebug( LDAP_DEBUG_ANY,
  508. "sasl_map_check: slapi_re_subs failed: "
  509. "subject: %s, subst str: %s (%d)\n",
  510. sasl_user_and_realm, dp->template_base_dn, rc);
  511. slapi_ch_free_string(ldap_search_base);
  512. slapi_ch_free_string(ldap_search_filter);
  513. } else {
  514. /* Substitutes '&' and/or "\#" in template_search_filter */
  515. rc = slapi_re_subs_ext(re, sasl_user_and_realm,
  516. dp->template_search_filter, ldap_search_filter,
  517. ldap_search_filter_len, 1);
  518. if (0 != rc) {
  519. LDAPDebug( LDAP_DEBUG_ANY,
  520. "sasl_map_check: slapi_re_subs failed: "
  521. "subject: %s, subst str: %s (%d)\n",
  522. sasl_user_and_realm, dp->template_search_filter, rc);
  523. slapi_ch_free_string(ldap_search_base);
  524. slapi_ch_free_string(ldap_search_filter);
  525. } else {
  526. /* these values are internal regex representations with
  527. * lots of unprintable control chars - escape for logging */
  528. LDAPDebug( LDAP_DEBUG_TRACE,
  529. "mapped base dn: %s, filter: %s\n",
  530. escape_string( *ldap_search_base, escape_base ),
  531. escape_string( *ldap_search_filter, escape_filt ), 0 );
  532. ret = 1;
  533. }
  534. }
  535. } else {
  536. LDAPDebug( LDAP_DEBUG_ANY,
  537. "sasl_map_check: slapi_re_exec failed: "
  538. "regex: %s, subject: %s (%d)\n",
  539. dp->regular_expression, sasl_user_and_realm, matched);
  540. }
  541. }
  542. slapi_re_free(re);
  543. LDAPDebug( LDAP_DEBUG_TRACE, "<- sasl_map_check\n", 0, 0, 0 );
  544. return ret;
  545. }
  546. static char *
  547. sasl_map_str_concat(char *s1, char *s2)
  548. {
  549. if (NULL == s2) {
  550. return (slapi_ch_strdup(s1));
  551. } else {
  552. char *newstr = slapi_ch_smprintf("%s@%s",s1,s2);
  553. return newstr;
  554. }
  555. }
  556. /* Actually perform a mapping
  557. * Takes a sasl identity string, and returns an LDAP search spec to be used to find the entry
  558. * returns 1 if matched, 0 otherwise
  559. */
  560. int
  561. sasl_map_domap(char *sasl_user, char *sasl_realm, char **ldap_search_base, char **ldap_search_filter)
  562. {
  563. int ret = 0;
  564. sasl_map_data *this_map = NULL;
  565. char *sasl_user_and_realm = NULL;
  566. sasl_map_private *priv = sasl_map_get_global_priv();
  567. *ldap_search_base = NULL;
  568. *ldap_search_filter = NULL;
  569. LDAPDebug( LDAP_DEBUG_TRACE, "-> sasl_map_domap\n", 0, 0, 0 );
  570. sasl_user_and_realm = sasl_map_str_concat(sasl_user,sasl_realm);
  571. /* Walk the list of maps */
  572. this_map = sasl_map_first(priv);
  573. while (this_map) {
  574. int matched = 0;
  575. /* If one matches, then make the search params */
  576. LDAPDebug( LDAP_DEBUG_TRACE, "sasl_map_domap - trying map [%s]\n", this_map->name, 0, 0 );
  577. matched = sasl_map_check(this_map, sasl_user_and_realm, ldap_search_base, ldap_search_filter);
  578. if (1 == matched) {
  579. ret = 1;
  580. break;
  581. }
  582. this_map = sasl_map_next(this_map);
  583. }
  584. if (sasl_user_and_realm) {
  585. slapi_ch_free((void**)&sasl_user_and_realm);
  586. }
  587. LDAPDebug( LDAP_DEBUG_TRACE, "<- sasl_map_domap (%s)\n", (1 == ret) ? "mapped" : "not mapped", 0, 0 );
  588. return ret;
  589. }