sasl_map.c 18 KB

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