aclinit.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549
  1. /** BEGIN COPYRIGHT BLOCK
  2. * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
  3. * Copyright (C) 2005 Red Hat, Inc.
  4. * All rights reserved.
  5. *
  6. * License: GPL (version 3 or any later version).
  7. * See LICENSE for details.
  8. * END COPYRIGHT BLOCK **/
  9. #ifdef HAVE_CONFIG_H
  10. # include <config.h>
  11. #endif
  12. #include "acl.h"
  13. static int __aclinit__RegisterLases(void);
  14. static int __aclinit__RegisterAttributes(void);
  15. static int __aclinit_handler(Slapi_Entry *e, void *callback_data);
  16. /***************************************************************************
  17. *
  18. * aclinit_main()
  19. * Main routine which is called at the server boot up time.
  20. *
  21. * 1) Reads all the ACI entries from the database and creates
  22. * the ACL list.
  23. * 2) Registers all the LASes and the GetAttrs supported by the DS.
  24. * 3) Generates anonymous profiles.
  25. * 4) Registers proxy control
  26. * 5) Creates aclpb pool
  27. *
  28. * Input:
  29. * None.
  30. *
  31. * Returns:
  32. * 0 -- no error
  33. * 1 -- Error
  34. *
  35. * Error Handling:
  36. * If any error found during the ACL generation, error is logged.
  37. *
  38. **************************************************************************/
  39. static int acl_initialized = 0;
  40. int
  41. aclinit_main()
  42. {
  43. Slapi_PBlock *pb;
  44. int rv;
  45. Slapi_DN *sdn;
  46. void *node;
  47. if (acl_initialized) {
  48. /* There is no need to do anything more */
  49. return 0;
  50. }
  51. /* Initialize the LIBACCESS ACL library */
  52. if (ACL_Init() != 0) {
  53. slapi_log_error(SLAPI_LOG_ERR, plugin_name,
  54. "aclinit_main - ACL Library Initialization failed\n");
  55. return 1;
  56. }
  57. /* register all the LASes supported by the DS */
  58. if (ACL_ERR == __aclinit__RegisterLases()) {
  59. /* Error is already logged */
  60. return 1;
  61. }
  62. /* Register all the Attrs */
  63. if (ACL_ERR == __aclinit__RegisterAttributes()) {
  64. /* Error is already logged */
  65. return 1;
  66. }
  67. /*
  68. * Register to get backend state changes so we can add/remove
  69. * acis from backends that come up and go down.
  70. */
  71. slapi_register_backend_state_change((void *) NULL, acl_be_state_change_fnc);
  72. /* register the extensions */
  73. /* ONREPL Moved to the acl_init function because extensions
  74. need to be registered before any operations are issued
  75. if ( 0 != acl_init_ext() ) {
  76. slapi_log_error(SLAPI_LOG_ERR, plugin_name,
  77. "Unable to initialize the extensions\n");
  78. return 1;
  79. } */
  80. /* create the mutex array */
  81. if ( 0 != aclext_alloc_lockarray ( ) ) {
  82. slapi_log_error(SLAPI_LOG_ERR, plugin_name,
  83. "aclinit_main - Unable to create the mutext array\n");
  84. return 1;
  85. }
  86. /* Allocate the pool */
  87. if ( 0 != acl_create_aclpb_pool () ) {
  88. slapi_log_error(SLAPI_LOG_ERR, plugin_name,
  89. "aclinit_main - Unable to create the acl private pool\n");
  90. return 1;
  91. }
  92. /*
  93. * Now read all the ACLs from all the backends and put it
  94. * in a list
  95. */
  96. /* initialize the ACLLIST sub-system */
  97. if ( 0 != (rv = acllist_init ( ))) {
  98. slapi_log_error(SLAPI_LOG_ERR, plugin_name,
  99. "aclinit_main - Unable to initialize the plugin:%d\n", rv );
  100. return 1;
  101. }
  102. /* Initialize the anonymous profile i.e., generate it */
  103. rv = aclanom_init ();
  104. pb = slapi_pblock_new();
  105. /*
  106. * search for the aci_attr_type attributes of all entries.
  107. *
  108. * slapi_get_fist_suffix() and slapi_get_next_suffix() do not return the
  109. * rootdse entry so we search for acis in there explicitly here.
  110. */
  111. sdn = slapi_sdn_new_ndn_byval("");
  112. slapi_log_error(SLAPI_LOG_ACL, plugin_name,
  113. "aclinit_main - Searching for all acis(scope base) at suffix ''\n");
  114. aclinit_search_and_update_aci ( 0, /* thisbeonly */
  115. sdn, /* base */
  116. NULL, /* be name*/
  117. LDAP_SCOPE_BASE, ACL_ADD_ACIS,
  118. DO_TAKE_ACLCACHE_WRITELOCK);
  119. slapi_sdn_free(&sdn);
  120. sdn = slapi_get_first_suffix( &node, 1 );
  121. while (sdn)
  122. {
  123. slapi_log_error(SLAPI_LOG_ACL, plugin_name,
  124. "aclinit_main - Searching for all acis(scope subtree) at suffix '%s'\n",
  125. slapi_sdn_get_dn(sdn) );
  126. aclinit_search_and_update_aci ( 0, /* thisbeonly */
  127. sdn, /* base */
  128. NULL, /* be name*/
  129. LDAP_SCOPE_SUBTREE, ACL_ADD_ACIS,
  130. DO_TAKE_ACLCACHE_WRITELOCK);
  131. sdn = slapi_get_next_suffix( &node, 1 );
  132. }
  133. /* Initialize it. */
  134. acl_initialized = 1;
  135. /* generate the signatures */
  136. acl_set_aclsignature ( aclutil_gen_signature ( 100 ) );
  137. /* Initialize the user-group cache */
  138. rv = aclgroup_init ( );
  139. aclanom_gen_anomProfile (DO_TAKE_ACLCACHE_READLOCK);
  140. /* Register both of the proxied authorization controls (version 1 and 2) */
  141. slapi_register_supported_control( LDAP_CONTROL_PROXYAUTH,
  142. SLAPI_OPERATION_SEARCH | SLAPI_OPERATION_COMPARE
  143. | SLAPI_OPERATION_ADD | SLAPI_OPERATION_DELETE
  144. | SLAPI_OPERATION_MODIFY | SLAPI_OPERATION_MODDN
  145. | SLAPI_OPERATION_EXTENDED );
  146. slapi_register_supported_control( LDAP_CONTROL_PROXIEDAUTH,
  147. SLAPI_OPERATION_SEARCH | SLAPI_OPERATION_COMPARE
  148. | SLAPI_OPERATION_ADD | SLAPI_OPERATION_DELETE
  149. | SLAPI_OPERATION_MODIFY | SLAPI_OPERATION_MODDN
  150. | SLAPI_OPERATION_EXTENDED );
  151. slapi_pblock_destroy ( pb );
  152. return 0;
  153. }
  154. /*
  155. * This routine is the one that scans for acis and either adds them
  156. * to the internal cache (op==ACL_ADD_ACIS) or deletes them
  157. * (op==ACL_REMOVE_ACIS).
  158. *
  159. * If thisbeonly is 0 the search
  160. * is conducted on the base with the specifed scope and be_name is ignored.
  161. * This is used at startup time where we iterate over all suffixes, searching
  162. * for all the acis in the DIT to load the ACL cache.
  163. *
  164. * If thisbeonly is 1 then then a be_name must be specified.
  165. * In this case we will search in that backend ONLY.
  166. * This is used in the case where a backend is turned on and off--in this
  167. * case we only want to add/remove the acis in that particular backend and
  168. * not for example in any backends below that one.
  169. */
  170. int
  171. aclinit_search_and_update_aci ( int thisbeonly, const Slapi_DN *base,
  172. char *be_name, int scope, int op,
  173. acl_lock_flag_t lock_flag )
  174. {
  175. char *attrs[2] = { "aci", NULL };
  176. /* Tell __aclinit_handler whether it's an add or a delete */
  177. Slapi_PBlock *aPb;
  178. LDAPControl **ctrls=NULL;
  179. struct berval *bval;
  180. aclinit_handler_callback_data_t call_back_data;
  181. PR_ASSERT( lock_flag == DONT_TAKE_ACLCACHE_WRITELOCK ||
  182. lock_flag == DO_TAKE_ACLCACHE_WRITELOCK);
  183. if ( thisbeonly && be_name == NULL) {
  184. slapi_log_error(SLAPI_LOG_ERR, plugin_name,
  185. "aclinit_search_and_update_aci - be_name must be specified.\n");
  186. return -1;
  187. }
  188. /*
  189. * We need to explicitly request (objectclass=ldapsubentry)
  190. * in order to get all the subentry acis too.
  191. * Note that subentries can be added under subentries (although its not
  192. * recommended) so that
  193. * there may be non-trivial acis under a subentry.
  194. */
  195. /* Use new search internal API */
  196. /* and never retrieve aci from a remote server */
  197. aPb = slapi_pblock_new ();
  198. /*
  199. * Set up the control to say "Only get acis from this Backend--
  200. * there may be more backends under this one.
  201. */
  202. if ( thisbeonly ) {
  203. bval = (struct berval *)slapi_ch_malloc(sizeof(struct berval));
  204. bval->bv_len = strlen(be_name) + 1;
  205. bval->bv_val = slapi_ch_strdup(be_name);
  206. ctrls = (LDAPControl **)slapi_ch_calloc( 2, sizeof(LDAPControl *));
  207. ctrls[0] = NULL;
  208. ctrls[1] = NULL;
  209. slapi_build_control_from_berval(
  210. MTN_CONTROL_USE_ONE_BACKEND_OID,
  211. bval,
  212. 1 /* is critical */,
  213. ctrls);
  214. }
  215. slapi_search_internal_set_pb ( aPb,
  216. slapi_sdn_get_dn(base),
  217. scope,
  218. "(|(aci=*)(objectclass=ldapsubentry))",
  219. attrs,
  220. 0 /* attrsonly */,
  221. ctrls /* controls: SLAPI_ARGCONTROLS */,
  222. NULL /* uniqueid */,
  223. aclplugin_get_identity (ACL_PLUGIN_IDENTITY),
  224. SLAPI_OP_FLAG_NEVER_CHAIN /* actions : get local aci only */);
  225. if (thisbeonly) {
  226. slapi_pblock_set(aPb, SLAPI_REQCONTROLS, ctrls);
  227. }
  228. call_back_data.op = op;
  229. call_back_data.retCode = 0;
  230. call_back_data.lock_flag = lock_flag;
  231. slapi_search_internal_callback_pb(aPb,
  232. &call_back_data /* callback_data */,
  233. NULL/* result_callback */,
  234. __aclinit_handler,
  235. NULL /* referral_callback */);
  236. if (thisbeonly) {
  237. slapi_ch_free((void **)&bval);
  238. }
  239. /*
  240. * This frees the control oid, the bv_val and the control itself and the
  241. * ctrls array mem by caling ldap_controls_free()--so we
  242. * don't need to do it ourselves.
  243. */
  244. slapi_pblock_destroy (aPb);
  245. return call_back_data.retCode;
  246. }
  247. /***************************************************************************
  248. *
  249. * __aclinit_handler
  250. *
  251. * For each entry, finds if there is any ACL in that entry. If there is
  252. * then the ACL is processed and stored in the ACL LIST.
  253. *
  254. *
  255. * Input:
  256. *
  257. *
  258. * Returns:
  259. * None.
  260. *
  261. * Error Handling:
  262. * If any error found during the ACL generation, the ACL is
  263. * logged. Also, set in the callback_data so that caller can act upon it.
  264. *
  265. **************************************************************************/
  266. static int
  267. __aclinit_handler ( Slapi_Entry *e, void *callback_data)
  268. {
  269. Slapi_Attr *attr;
  270. aclinit_handler_callback_data_t *call_back_data =
  271. (aclinit_handler_callback_data_t*)callback_data;
  272. Slapi_DN *e_sdn;
  273. int rv;
  274. Slapi_Value *sval=NULL;
  275. call_back_data->retCode = 0; /* assume success--if there's an error we overwrite it */
  276. if (e != NULL) {
  277. e_sdn = slapi_entry_get_sdn ( e );
  278. /*
  279. * Take the write lock around all the mods--so that
  280. * other operations will see the acicache either before the whole mod
  281. * or after but not, as it was before, during the mod.
  282. * This is in line with the LDAP concept of the operation
  283. * on the whole entry being the atomic unit.
  284. *
  285. */
  286. if ( call_back_data->op == ACL_ADD_ACIS ) {
  287. slapi_log_error(SLAPI_LOG_ACL, plugin_name,
  288. "Adding acis for entry '%s'\n", slapi_sdn_get_dn(e_sdn));
  289. slapi_entry_attr_find ( e, aci_attr_type, &attr );
  290. if ( attr ) {
  291. const struct berval *attrValue;
  292. int i;
  293. if ( call_back_data->lock_flag == DO_TAKE_ACLCACHE_WRITELOCK) {
  294. acllist_acicache_WRITE_LOCK();
  295. }
  296. i= slapi_attr_first_value ( attr, &sval );
  297. while(i != -1) {
  298. attrValue = slapi_value_get_berval(sval);
  299. if ( 0 != (rv=acllist_insert_aci_needsLock (e_sdn, attrValue))) {
  300. aclutil_print_err(rv, e_sdn, attrValue, NULL);
  301. /* We got an error; Log it and then march along */
  302. slapi_log_error(SLAPI_LOG_ERR, plugin_name,
  303. "__aclinit_handler - This (%s) ACL will not be considered for evaluation"
  304. " because of syntax errors.\n",
  305. attrValue->bv_val ? attrValue->bv_val: "NULL");
  306. call_back_data->retCode = rv;
  307. }
  308. i= slapi_attr_next_value( attr, i, &sval );
  309. }/* while */
  310. if ( call_back_data->lock_flag == DO_TAKE_ACLCACHE_WRITELOCK) {
  311. acllist_acicache_WRITE_UNLOCK();
  312. }
  313. }
  314. } else if (call_back_data->op == ACL_REMOVE_ACIS) {
  315. /* Here we are deleting the acis. */
  316. slapi_log_error(SLAPI_LOG_ACL, plugin_name, "__aclinit_handler - Removing acis\n");
  317. if ( call_back_data->lock_flag == DO_TAKE_ACLCACHE_WRITELOCK) {
  318. acllist_acicache_WRITE_LOCK();
  319. }
  320. if ( 0 != (rv=acllist_remove_aci_needsLock(e_sdn, NULL))) {
  321. aclutil_print_err(rv, e_sdn, NULL, NULL);
  322. /* We got an error; Log it and then march along */
  323. slapi_log_error(SLAPI_LOG_ERR, plugin_name,
  324. "__aclinit_handler - ACLs not deleted from %s\n",
  325. slapi_sdn_get_dn(e_sdn));
  326. call_back_data->retCode = rv;
  327. }
  328. if ( call_back_data->lock_flag == DO_TAKE_ACLCACHE_WRITELOCK) {
  329. acllist_acicache_WRITE_UNLOCK();
  330. }
  331. }
  332. }
  333. /*
  334. * If we get here it's success.
  335. * The call_back_data->error is the error code that counts as it's the
  336. * one that the original caller will see--this routine is called off a callbacl.
  337. */
  338. return ACL_FALSE; /* "local" error code--it's 0 */
  339. }
  340. /***************************************************************************
  341. *
  342. * __acl__RegisterAttributes
  343. *
  344. * Register all the attributes supported by the DS.
  345. *
  346. * Input:
  347. * None.
  348. *
  349. * Returns:
  350. * ACL_OK - No error
  351. * ACL_ERR - in case of errror
  352. *
  353. * Error Handling:
  354. * None.
  355. *
  356. **************************************************************************/
  357. static int
  358. __aclinit__RegisterAttributes(void)
  359. {
  360. ACLMethod_t methodinfo;
  361. NSErr_t errp;
  362. int rv;
  363. memset (&errp, 0, sizeof(NSErr_t));
  364. rv = ACL_MethodRegister(&errp, DS_METHOD, &methodinfo);
  365. if (rv < 0) {
  366. acl_print_acllib_err(&errp, NULL);
  367. slapi_log_error(SLAPI_LOG_ERR, plugin_name,
  368. "__aclinit__RegisterAttributes - Unable to Register the methods\n");
  369. return ACL_ERR;
  370. }
  371. rv = ACL_MethodSetDefault (&errp, methodinfo);
  372. if (rv < 0) {
  373. acl_print_acllib_err(&errp, NULL);
  374. slapi_log_error(SLAPI_LOG_ERR, plugin_name,
  375. "__aclinit__RegisterAttributes - Unable to Set the default method\n");
  376. return ACL_ERR;
  377. }
  378. rv = ACL_AttrGetterRegister(&errp, ACL_ATTR_IP, DS_LASIpGetter,
  379. methodinfo, ACL_DBTYPE_ANY, ACL_AT_FRONT, NULL);
  380. if (rv < 0) {
  381. acl_print_acllib_err(&errp, NULL);
  382. slapi_log_error(SLAPI_LOG_ERR, plugin_name,
  383. "__aclinit__RegisterAttributes - Unable to Register Attr ip\n");
  384. return ACL_ERR;
  385. }
  386. rv = ACL_AttrGetterRegister(&errp, ACL_ATTR_DNS, DS_LASDnsGetter,
  387. methodinfo, ACL_DBTYPE_ANY, ACL_AT_FRONT, NULL);
  388. if (rv < 0) {
  389. acl_print_acllib_err(&errp, NULL);
  390. slapi_log_error(SLAPI_LOG_ERR, plugin_name,
  391. "__aclinit__RegisterAttributes - Unable to Register Attr dns\n");
  392. return ACL_ERR;
  393. }
  394. return ACL_OK;
  395. }
  396. /***************************************************************************
  397. *
  398. * __acl__RegisterLases
  399. * Register all the LASes supported by the DS.
  400. *
  401. * The DS doesnot support user/group. We have defined our own LAS
  402. * so that we can display/print an error when the LAS is invoked.
  403. * Input:
  404. * None.
  405. *
  406. * Returns:
  407. * ACL_OK - No error
  408. * ACL_ERR - in case of errror
  409. *
  410. * Error Handling:
  411. * None.
  412. *
  413. **************************************************************************/
  414. static int
  415. __aclinit__RegisterLases(void)
  416. {
  417. if (ACL_LasRegister(NULL, DS_LAS_USER, (LASEvalFunc_t) DS_LASUserEval,
  418. (LASFlushFunc_t) NULL) < 0) {
  419. slapi_log_error(SLAPI_LOG_ERR, plugin_name,
  420. "__aclinit__RegisterLases - Unable to register USER Las\n");
  421. return ACL_ERR;
  422. }
  423. if (ACL_LasRegister(NULL, DS_LAS_GROUP, (LASEvalFunc_t) DS_LASGroupEval,
  424. (LASFlushFunc_t) NULL) < 0) {
  425. slapi_log_error(SLAPI_LOG_ERR, plugin_name,
  426. "__aclinit__RegisterLases - Unable to register GROUP Las\n");
  427. return ACL_ERR;
  428. }
  429. if (ACL_LasRegister(NULL, DS_LAS_GROUPDN, (LASEvalFunc_t)DS_LASGroupDnEval,
  430. (LASFlushFunc_t)NULL) < 0) {
  431. slapi_log_error(SLAPI_LOG_ERR, plugin_name,
  432. "__aclinit__RegisterLases - Unable to register GROUPDN Las\n");
  433. return ACL_ERR;
  434. }
  435. if (ACL_LasRegister(NULL, DS_LAS_ROLEDN, (LASEvalFunc_t)DS_LASRoleDnEval,
  436. (LASFlushFunc_t)NULL) < 0) {
  437. slapi_log_error(SLAPI_LOG_ERR, plugin_name,
  438. "__aclinit__RegisterLases - Unable to register ROLEDN Las\n");
  439. return ACL_ERR;
  440. }
  441. if (ACL_LasRegister(NULL, DS_LAS_USERDN, (LASEvalFunc_t)DS_LASUserDnEval,
  442. (LASFlushFunc_t)NULL) < 0) {
  443. slapi_log_error(SLAPI_LOG_ERR, plugin_name,
  444. "__aclinit__RegisterLases - Unable to register USERDN Las\n");
  445. return ACL_ERR;
  446. }
  447. if (ACL_LasRegister(NULL, DS_LAS_USERDNATTR,
  448. (LASEvalFunc_t)DS_LASUserDnAttrEval,
  449. (LASFlushFunc_t)NULL) < 0) {
  450. slapi_log_error(SLAPI_LOG_ERR, plugin_name,
  451. "__aclinit__RegisterLases - Unable to register USERDNATTR Las\n");
  452. return ACL_ERR;
  453. }
  454. if (ACL_LasRegister(NULL, DS_LAS_AUTHMETHOD,
  455. (LASEvalFunc_t)DS_LASAuthMethodEval,
  456. (LASFlushFunc_t)NULL) < 0) {
  457. slapi_log_error(SLAPI_LOG_ERR, plugin_name,
  458. "__aclinit__RegisterLases - Unable to register CLIENTAUTHTYPE Las\n");
  459. return ACL_ERR;
  460. }
  461. if (ACL_LasRegister(NULL, DS_LAS_GROUPDNATTR,
  462. (LASEvalFunc_t)DS_LASGroupDnAttrEval,
  463. (LASFlushFunc_t)NULL) < 0) {
  464. slapi_log_error(SLAPI_LOG_ERR, plugin_name,
  465. "__aclinit__RegisterLases - Unable to register GROUPDNATTR Las\n");
  466. return ACL_ERR;
  467. }
  468. if (ACL_LasRegister(NULL, DS_LAS_USERATTR,
  469. (LASEvalFunc_t)DS_LASUserAttrEval,
  470. (LASFlushFunc_t)NULL) < 0) {
  471. slapi_log_error(SLAPI_LOG_ERR, plugin_name,
  472. "__aclinit__RegisterLases - Unable to register USERATTR Las\n");
  473. return ACL_ERR;
  474. }
  475. if (ACL_LasRegister(NULL, DS_LAS_SSF,
  476. (LASEvalFunc_t)DS_LASSSFEval,
  477. (LASFlushFunc_t)NULL) < 0) {
  478. slapi_log_error(SLAPI_LOG_ERR, plugin_name,
  479. "__aclinit__RegisterLases - Unable to register SSF Las\n");
  480. return ACL_ERR;
  481. }
  482. return ACL_OK;
  483. }