pam_ptconfig.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568
  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. /*
  38. * ptconfig.c - configuration-related code for Pass Through Authentication
  39. *
  40. */
  41. #include <plstr.h>
  42. #include "pam_passthru.h"
  43. #define PAM_PT_CONFIG_FILTER "(objectclass=*)"
  44. /*
  45. * The configuration attributes are contained in the plugin entry e.g.
  46. * cn=PAM Pass Through,cn=plugins,cn=config
  47. *
  48. * Configuration is a two step process. The first pass is a validation step which
  49. * occurs pre-op - check inputs and error out if bad. The second pass actually
  50. * applies the changes to the run time config.
  51. */
  52. /*
  53. * function prototypes
  54. */
  55. static int pam_passthru_validate_config (Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Entry* e,
  56. int *returncode, char *returntext, void *arg);
  57. static int pam_passthru_apply_config (Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Entry* e,
  58. int *returncode, char *returntext, void *arg);
  59. static int pam_passthru_search (Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Entry* e,
  60. int *returncode, char *returntext, void *arg)
  61. {
  62. return SLAPI_DSE_CALLBACK_OK;
  63. }
  64. /*
  65. * static variables
  66. */
  67. /* for now, there is only one configuration and it is global to the plugin */
  68. static Pam_PassthruConfig theConfig;
  69. static int inited = 0;
  70. static int dont_allow_that(Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Entry* e,
  71. int *returncode, char *returntext, void *arg)
  72. {
  73. *returncode = LDAP_UNWILLING_TO_PERFORM;
  74. return SLAPI_DSE_CALLBACK_ERROR;
  75. }
  76. /*
  77. * Read configuration and create a configuration data structure.
  78. * This is called after the server has configured itself so we can check
  79. * for things like collisions between our suffixes and backend's suffixes.
  80. * Returns an LDAP error code (LDAP_SUCCESS if all goes well).
  81. */
  82. int
  83. pam_passthru_config(Slapi_Entry *config_e)
  84. {
  85. int returncode = LDAP_SUCCESS;
  86. char returntext[SLAPI_DSE_RETURNTEXT_SIZE];
  87. if ( inited ) {
  88. slapi_log_error( SLAPI_LOG_FATAL, PAM_PASSTHRU_PLUGIN_SUBSYSTEM,
  89. "only one PAM pass through plugin instance can be used\n" );
  90. return( LDAP_PARAM_ERROR );
  91. }
  92. /* initialize fields */
  93. if ((theConfig.lock = slapi_new_mutex()) == NULL) {
  94. return( LDAP_LOCAL_ERROR );
  95. }
  96. /* do not fallback to regular bind */
  97. theConfig.pamptconfig_fallback = PR_FALSE;
  98. /* require TLS/SSL security */
  99. theConfig.pamptconfig_secure = PR_TRUE;
  100. /* use the RDN method to derive the PAM identity */
  101. theConfig.pamptconfig_map_method1 = PAMPT_MAP_METHOD_RDN;
  102. theConfig.pamptconfig_map_method2 = PAMPT_MAP_METHOD_NONE;
  103. theConfig.pamptconfig_map_method3 = PAMPT_MAP_METHOD_NONE;
  104. if (SLAPI_DSE_CALLBACK_OK == pam_passthru_validate_config(NULL, NULL, config_e,
  105. &returncode, returntext, NULL)) {
  106. pam_passthru_apply_config(NULL, NULL, config_e,
  107. &returncode, returntext, NULL);
  108. }
  109. /* config DSE must be initialized before we get here */
  110. if (returncode == LDAP_SUCCESS) {
  111. const char *config_dn = slapi_entry_get_dn_const(config_e);
  112. slapi_config_register_callback(SLAPI_OPERATION_MODIFY, DSE_FLAG_PREOP, config_dn, LDAP_SCOPE_BASE,
  113. PAM_PT_CONFIG_FILTER, pam_passthru_validate_config,NULL);
  114. slapi_config_register_callback(SLAPI_OPERATION_MODIFY, DSE_FLAG_POSTOP, config_dn, LDAP_SCOPE_BASE,
  115. PAM_PT_CONFIG_FILTER, pam_passthru_apply_config,NULL);
  116. slapi_config_register_callback(SLAPI_OPERATION_MODRDN, DSE_FLAG_PREOP, config_dn, LDAP_SCOPE_BASE,
  117. PAM_PT_CONFIG_FILTER, dont_allow_that, NULL);
  118. slapi_config_register_callback(SLAPI_OPERATION_DELETE, DSE_FLAG_PREOP, config_dn, LDAP_SCOPE_BASE,
  119. PAM_PT_CONFIG_FILTER, dont_allow_that, NULL);
  120. slapi_config_register_callback(SLAPI_OPERATION_SEARCH, DSE_FLAG_PREOP, config_dn, LDAP_SCOPE_BASE,
  121. PAM_PT_CONFIG_FILTER, pam_passthru_search,NULL);
  122. }
  123. inited = 1;
  124. if (returncode != LDAP_SUCCESS) {
  125. slapi_log_error(SLAPI_LOG_FATAL, PAM_PASSTHRU_PLUGIN_SUBSYSTEM,
  126. "Error %d: %s\n", returncode, returntext);
  127. }
  128. return returncode;
  129. }
  130. static int
  131. missing_suffix_to_int(char *missing_suffix)
  132. {
  133. int retval = -1; /* -1 is error */
  134. if (!PL_strcasecmp(missing_suffix, PAMPT_MISSING_SUFFIX_ERROR_STRING)) {
  135. retval = PAMPT_MISSING_SUFFIX_ERROR;
  136. } else if (!PL_strcasecmp(missing_suffix, PAMPT_MISSING_SUFFIX_ALLOW_STRING)) {
  137. retval = PAMPT_MISSING_SUFFIX_ALLOW;
  138. } else if (!PL_strcasecmp(missing_suffix, PAMPT_MISSING_SUFFIX_IGNORE_STRING)) {
  139. retval = PAMPT_MISSING_SUFFIX_IGNORE;
  140. }
  141. return retval;
  142. }
  143. static PRBool
  144. check_missing_suffix_flag(int val) {
  145. if (val == PAMPT_MISSING_SUFFIX_ERROR ||
  146. val == PAMPT_MISSING_SUFFIX_ALLOW ||
  147. val == PAMPT_MISSING_SUFFIX_IGNORE) {
  148. return PR_TRUE;
  149. }
  150. return PR_FALSE;
  151. }
  152. #define MAKE_STR(x) #x
  153. static char *get_missing_suffix_values()
  154. {
  155. return MAKE_STR(PAMPT_MISSING_SUFFIX_ERROR) ", " MAKE_STR(PAMPT_MISSING_SUFFIX_ALLOW) ", "
  156. MAKE_STR(PAMPT_MISSING_SUFFIX_IGNORE);
  157. }
  158. static char *get_map_method_values()
  159. {
  160. return PAMPT_MAP_METHOD_DN_STRING " or " PAMPT_MAP_METHOD_RDN_STRING " or " PAMPT_MAP_METHOD_ENTRY_STRING;
  161. }
  162. static int
  163. meth_to_int(char **map_method, int *err)
  164. {
  165. char *end;
  166. int len;
  167. int ret;
  168. *err = 0;
  169. if (!map_method || !*map_method) {
  170. return PAMPT_MAP_METHOD_NONE;
  171. }
  172. end = strchr(*map_method, ' ');
  173. if (!end) {
  174. len = strlen(*map_method);
  175. } else {
  176. len = end - *map_method;
  177. }
  178. if (!PL_strncasecmp(*map_method, PAMPT_MAP_METHOD_DN_STRING, len)) {
  179. ret = PAMPT_MAP_METHOD_DN;
  180. } else if (!PL_strncasecmp(*map_method, PAMPT_MAP_METHOD_RDN_STRING, len)) {
  181. ret = PAMPT_MAP_METHOD_RDN;
  182. } else if (!PL_strncasecmp(*map_method, PAMPT_MAP_METHOD_ENTRY_STRING, len)) {
  183. ret = PAMPT_MAP_METHOD_ENTRY;
  184. } else {
  185. *err = 1;
  186. }
  187. if (!err) {
  188. if (end && *end) {
  189. *map_method = end + 1;
  190. } else {
  191. *map_method = NULL;
  192. }
  193. }
  194. return ret;
  195. }
  196. static int
  197. parse_map_method(char *map_method, int *one, int *two, int *three, char *returntext)
  198. {
  199. int err = 0;
  200. int extra;
  201. *one = *two = *three = PAMPT_MAP_METHOD_NONE;
  202. *one = meth_to_int(&map_method, &err);
  203. if (err) {
  204. PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE,
  205. "The map method in the string [%s] is invalid: must be "
  206. "one of %s", map_method, get_map_method_values());
  207. return LDAP_UNWILLING_TO_PERFORM;
  208. }
  209. *two = meth_to_int(&map_method, &err);
  210. if (err) {
  211. PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE,
  212. "The map method in the string [%s] is invalid: must be "
  213. "one of %s", map_method, get_map_method_values());
  214. return LDAP_UNWILLING_TO_PERFORM;
  215. }
  216. *three = meth_to_int(&map_method, &err);
  217. if (err) {
  218. PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE,
  219. "The map method in the string [%s] is invalid: must be "
  220. "one of %s", map_method, get_map_method_values());
  221. return LDAP_UNWILLING_TO_PERFORM;
  222. }
  223. if (((extra = meth_to_int(&map_method, &err)) != PAMPT_MAP_METHOD_NONE) ||
  224. err) {
  225. PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE,
  226. "Invalid extra text [%s] after last map method",
  227. map_method);
  228. return LDAP_UNWILLING_TO_PERFORM;
  229. }
  230. return err;
  231. }
  232. /*
  233. Validate the pending changes in the e entry.
  234. */
  235. static int
  236. pam_passthru_validate_config (Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Entry* e,
  237. int *returncode, char *returntext, void *arg)
  238. {
  239. char *missing_suffix_str = NULL;
  240. int missing_suffix;
  241. int ii;
  242. char **excludes = NULL;
  243. char **includes = NULL;
  244. char *pam_ident_attr = NULL;
  245. char *map_method = NULL;
  246. *returncode = LDAP_UNWILLING_TO_PERFORM; /* be pessimistic */
  247. /* first, get the missing_suffix flag and validate it */
  248. missing_suffix_str = slapi_entry_attr_get_charptr(e, PAMPT_MISSING_SUFFIX_ATTR);
  249. if ((missing_suffix = missing_suffix_to_int(missing_suffix_str)) < 0 ||
  250. !check_missing_suffix_flag(missing_suffix)) {
  251. PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE,
  252. "Error: valid values for %s are %s",
  253. PAMPT_MISSING_SUFFIX_ATTR, get_missing_suffix_values());
  254. goto done;
  255. }
  256. if (missing_suffix != PAMPT_MISSING_SUFFIX_IGNORE) {
  257. char **missing_list = NULL;
  258. Slapi_DN *comp_dn = slapi_sdn_new();
  259. /* get the list of excluded suffixes */
  260. excludes = slapi_entry_attr_get_charray(e, PAMPT_EXCLUDES_ATTR);
  261. for (ii = 0; excludes && excludes[ii]; ++ii) {
  262. slapi_sdn_init_dn_byref(comp_dn, excludes[ii]);
  263. if (!slapi_be_exist(comp_dn)) {
  264. charray_add(&missing_list, slapi_ch_strdup(excludes[ii]));
  265. }
  266. slapi_sdn_done(comp_dn);
  267. }
  268. /* get the list of included suffixes */
  269. includes = slapi_entry_attr_get_charray(e, PAMPT_INCLUDES_ATTR);
  270. for (ii = 0; includes && includes[ii]; ++ii) {
  271. slapi_sdn_init_dn_byref(comp_dn, includes[ii]);
  272. if (!slapi_be_exist(comp_dn)) {
  273. charray_add(&missing_list, slapi_ch_strdup(includes[ii]));
  274. }
  275. slapi_sdn_done(comp_dn);
  276. }
  277. slapi_sdn_free(&comp_dn);
  278. if (missing_list) {
  279. PRUint32 size =
  280. PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE,
  281. "The following suffixes listed in %s or %s are not present in this "
  282. "server: ", PAMPT_EXCLUDES_ATTR, PAMPT_INCLUDES_ATTR);
  283. for (ii = 0; missing_list[ii]; ++ii) {
  284. if (size < SLAPI_DSE_RETURNTEXT_SIZE) {
  285. size += PR_snprintf(returntext+size, SLAPI_DSE_RETURNTEXT_SIZE-size,
  286. "%s%s", (ii > 0) ? "; " : "",
  287. missing_list[ii]);
  288. }
  289. }
  290. slapi_ch_array_free(missing_list);
  291. missing_list = NULL;
  292. if (missing_suffix != PAMPT_MISSING_SUFFIX_ERROR) {
  293. slapi_log_error(SLAPI_LOG_FATAL, PAM_PASSTHRU_PLUGIN_SUBSYSTEM,
  294. "Warning: %s\n", returntext);
  295. *returntext = 0; /* log error, don't report back to user */
  296. } else {
  297. goto done;
  298. }
  299. }
  300. }
  301. pam_ident_attr = slapi_entry_attr_get_charptr(e, PAMPT_PAM_IDENT_ATTR);
  302. map_method = slapi_entry_attr_get_charptr(e, PAMPT_MAP_METHOD_ATTR);
  303. if (map_method) {
  304. int one, two, three;
  305. *returncode = parse_map_method(map_method, &one, &two, &three, returntext);
  306. if (!pam_ident_attr &&
  307. ((one == PAMPT_MAP_METHOD_ENTRY) || (two == PAMPT_MAP_METHOD_ENTRY) ||
  308. (three == PAMPT_MAP_METHOD_ENTRY))) {
  309. PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE, "Error: the %s method"
  310. " was specified, but no %s was given",
  311. PAMPT_MAP_METHOD_ENTRY_STRING, PAMPT_PAM_IDENT_ATTR);
  312. *returncode = LDAP_UNWILLING_TO_PERFORM;
  313. goto done;
  314. }
  315. if (one == two == three == PAMPT_MAP_METHOD_NONE) {
  316. PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE, "Error: no method(s)"
  317. " specified for %s, should be one or more of %s",
  318. PAMPT_MAP_METHOD_ATTR, get_map_method_values());
  319. *returncode = LDAP_UNWILLING_TO_PERFORM;
  320. goto done;
  321. }
  322. }
  323. /* success */
  324. *returncode = LDAP_SUCCESS;
  325. done:
  326. slapi_ch_free_string(&map_method);
  327. slapi_ch_free_string(&pam_ident_attr);
  328. slapi_ch_array_free(excludes);
  329. excludes = NULL;
  330. slapi_ch_array_free(includes);
  331. includes = NULL;
  332. slapi_ch_free_string(&missing_suffix_str);
  333. if (*returncode != LDAP_SUCCESS)
  334. {
  335. return SLAPI_DSE_CALLBACK_ERROR;
  336. }
  337. else
  338. {
  339. return SLAPI_DSE_CALLBACK_OK;
  340. }
  341. }
  342. static Pam_PassthruSuffix *
  343. New_Pam_PassthruSuffix(char *suffix)
  344. {
  345. Pam_PassthruSuffix *newone = NULL;
  346. if (suffix) {
  347. newone = (Pam_PassthruSuffix *)slapi_ch_malloc(sizeof(Pam_PassthruSuffix));
  348. newone->pamptsuffix_dn = slapi_sdn_new();
  349. slapi_sdn_init_dn_byval(newone->pamptsuffix_dn, suffix);
  350. newone->pamptsuffix_next = NULL;
  351. }
  352. return newone;
  353. }
  354. static Pam_PassthruSuffix *
  355. pam_ptconfig_add_suffixes(char **str_list)
  356. {
  357. Pam_PassthruSuffix *head = NULL;
  358. Pam_PassthruSuffix *suffixent = NULL;
  359. if (str_list && *str_list) {
  360. int ii;
  361. for (ii = 0; str_list[ii]; ++ii) {
  362. Pam_PassthruSuffix *tmp = New_Pam_PassthruSuffix(str_list[ii]);
  363. if (!suffixent) {
  364. head = suffixent = tmp;
  365. } else {
  366. suffixent->pamptsuffix_next = tmp;
  367. suffixent = suffixent->pamptsuffix_next;
  368. }
  369. }
  370. }
  371. return head;
  372. }
  373. static void
  374. Delete_Pam_PassthruSuffix(Pam_PassthruSuffix *one)
  375. {
  376. if (one) {
  377. slapi_sdn_free(&one->pamptsuffix_dn);
  378. slapi_ch_free((void **)&one);
  379. }
  380. }
  381. static void
  382. pam_ptconfig_free_suffixes(Pam_PassthruSuffix *list)
  383. {
  384. while (list) {
  385. Pam_PassthruSuffix *next = list->pamptsuffix_next;
  386. Delete_Pam_PassthruSuffix(list);
  387. list = next;
  388. }
  389. }
  390. /*
  391. Apply the pending changes in the e entry to our config struct.
  392. validate must have already been called
  393. */
  394. static int
  395. pam_passthru_apply_config (Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Entry* e,
  396. int *returncode, char *returntext, void *arg)
  397. {
  398. char **excludes = NULL;
  399. char **includes = NULL;
  400. char *new_service = NULL;
  401. char *pam_ident_attr = NULL;
  402. char *map_method = NULL;
  403. int fallback;
  404. int secure;
  405. *returncode = LDAP_SUCCESS;
  406. pam_ident_attr = slapi_entry_attr_get_charptr(e, PAMPT_PAM_IDENT_ATTR);
  407. map_method = slapi_entry_attr_get_charptr(e, PAMPT_MAP_METHOD_ATTR);
  408. new_service = slapi_entry_attr_get_charptr(e, PAMPT_SERVICE_ATTR);
  409. excludes = slapi_entry_attr_get_charray(e, PAMPT_EXCLUDES_ATTR);
  410. includes = slapi_entry_attr_get_charray(e, PAMPT_INCLUDES_ATTR);
  411. fallback = slapi_entry_attr_get_int(e, PAMPT_FALLBACK_ATTR);
  412. secure = slapi_entry_attr_get_int(e, PAMPT_SECURE_ATTR);
  413. /* lock config here */
  414. slapi_lock_mutex(theConfig.lock);
  415. theConfig.pamptconfig_fallback = fallback;
  416. theConfig.pamptconfig_secure = secure;
  417. if (!theConfig.pamptconfig_service ||
  418. (new_service && PL_strcmp(theConfig.pamptconfig_service, new_service))) {
  419. slapi_ch_free_string(&theConfig.pamptconfig_service);
  420. theConfig.pamptconfig_service = new_service;
  421. new_service = NULL; /* config now owns memory */
  422. }
  423. /* get the list of excluded suffixes */
  424. pam_ptconfig_free_suffixes(theConfig.pamptconfig_excludes);
  425. theConfig.pamptconfig_excludes = pam_ptconfig_add_suffixes(excludes);
  426. /* get the list of included suffixes */
  427. pam_ptconfig_free_suffixes(theConfig.pamptconfig_includes);
  428. theConfig.pamptconfig_includes = pam_ptconfig_add_suffixes(includes);
  429. if (!theConfig.pamptconfig_pam_ident_attr ||
  430. (pam_ident_attr && PL_strcmp(theConfig.pamptconfig_pam_ident_attr, pam_ident_attr))) {
  431. slapi_ch_free_string(&theConfig.pamptconfig_pam_ident_attr);
  432. theConfig.pamptconfig_pam_ident_attr = pam_ident_attr;
  433. pam_ident_attr = NULL; /* config now owns memory */
  434. }
  435. if (map_method) {
  436. parse_map_method(map_method,
  437. &theConfig.pamptconfig_map_method1,
  438. &theConfig.pamptconfig_map_method2,
  439. &theConfig.pamptconfig_map_method3,
  440. NULL);
  441. }
  442. /* unlock config here */
  443. slapi_unlock_mutex(theConfig.lock);
  444. slapi_ch_free_string(&new_service);
  445. slapi_ch_free_string(&map_method);
  446. slapi_ch_free_string(&pam_ident_attr);
  447. slapi_ch_array_free(excludes);
  448. slapi_ch_array_free(includes);
  449. if (*returncode != LDAP_SUCCESS)
  450. {
  451. return SLAPI_DSE_CALLBACK_ERROR;
  452. }
  453. else
  454. {
  455. return SLAPI_DSE_CALLBACK_OK;
  456. }
  457. }
  458. int
  459. pam_passthru_check_suffix(Pam_PassthruConfig *cfg, char *binddn)
  460. {
  461. Slapi_DN *comp_dn;
  462. Pam_PassthruSuffix *try;
  463. int ret = LDAP_SUCCESS;
  464. comp_dn = slapi_sdn_new();
  465. slapi_sdn_init_dn_byref(comp_dn, binddn);
  466. slapi_lock_mutex(cfg->lock);
  467. if (!cfg->pamptconfig_includes && !cfg->pamptconfig_excludes) {
  468. goto done; /* NULL means allow */
  469. }
  470. /* exclude trumps include - if suffix is on exclude list, then
  471. deny */
  472. for (try = cfg->pamptconfig_excludes; try; try = try->pamptsuffix_next) {
  473. if (slapi_sdn_issuffix(comp_dn, try->pamptsuffix_dn)) {
  474. ret = LDAP_UNWILLING_TO_PERFORM; /* suffix is excluded */
  475. goto done;
  476. }
  477. }
  478. /* ok, now flip it - deny access unless dn is on include list */
  479. if (cfg->pamptconfig_includes) {
  480. ret = LDAP_UNWILLING_TO_PERFORM; /* suffix is excluded */
  481. for (try = cfg->pamptconfig_includes; try; try = try->pamptsuffix_next) {
  482. if (slapi_sdn_issuffix(comp_dn, try->pamptsuffix_dn)) {
  483. ret = LDAP_SUCCESS; /* suffix is included */
  484. goto done;
  485. }
  486. }
  487. }
  488. done:
  489. slapi_unlock_mutex(cfg->lock);
  490. slapi_sdn_free(&comp_dn);
  491. return ret;
  492. }
  493. /*
  494. * Get the pass though configuration data. For now, there is only one
  495. * configuration and it is global to the plugin.
  496. */
  497. Pam_PassthruConfig *
  498. pam_passthru_get_config( void )
  499. {
  500. return( &theConfig );
  501. }