| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549 |
- /** BEGIN COPYRIGHT BLOCK
- * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
- * Copyright (C) 2005 Red Hat, Inc.
- * All rights reserved.
- *
- * License: GPL (version 3 or any later version).
- * See LICENSE for details.
- * END COPYRIGHT BLOCK **/
- #ifdef HAVE_CONFIG_H
- # include <config.h>
- #endif
- #include "acl.h"
- static int __aclinit__RegisterLases(void);
- static int __aclinit__RegisterAttributes(void);
- static int __aclinit_handler(Slapi_Entry *e, void *callback_data);
- /***************************************************************************
- *
- * aclinit_main()
- * Main routine which is called at the server boot up time.
- *
- * 1) Reads all the ACI entries from the database and creates
- * the ACL list.
- * 2) Registers all the LASes and the GetAttrs supported by the DS.
- * 3) Generates anonymous profiles.
- * 4) Registers proxy control
- * 5) Creates aclpb pool
- *
- * Input:
- * None.
- *
- * Returns:
- * 0 -- no error
- * 1 -- Error
- *
- * Error Handling:
- * If any error found during the ACL generation, error is logged.
- *
- **************************************************************************/
- static int acl_initialized = 0;
- int
- aclinit_main()
- {
- Slapi_PBlock *pb;
- int rv;
- Slapi_DN *sdn;
- void *node;
- if (acl_initialized) {
- /* There is no need to do anything more */
- return 0;
- }
- /* Initialize the LIBACCESS ACL library */
- if (ACL_Init() != 0) {
- slapi_log_error(SLAPI_LOG_ERR, plugin_name,
- "aclinit_main - ACL Library Initialization failed\n");
- return 1;
- }
-
- /* register all the LASes supported by the DS */
- if (ACL_ERR == __aclinit__RegisterLases()) {
- /* Error is already logged */
- return 1;
- }
- /* Register all the Attrs */
- if (ACL_ERR == __aclinit__RegisterAttributes()) {
- /* Error is already logged */
- return 1;
- }
- /*
- * Register to get backend state changes so we can add/remove
- * acis from backends that come up and go down.
- */
- slapi_register_backend_state_change((void *) NULL, acl_be_state_change_fnc);
-
- /* register the extensions */
- /* ONREPL Moved to the acl_init function because extensions
- need to be registered before any operations are issued
- if ( 0 != acl_init_ext() ) {
- slapi_log_error(SLAPI_LOG_ERR, plugin_name,
- "Unable to initialize the extensions\n");
- return 1;
- } */
- /* create the mutex array */
- if ( 0 != aclext_alloc_lockarray ( ) ) {
- slapi_log_error(SLAPI_LOG_ERR, plugin_name,
- "aclinit_main - Unable to create the mutext array\n");
- return 1;
- }
- /* Allocate the pool */
- if ( 0 != acl_create_aclpb_pool () ) {
- slapi_log_error(SLAPI_LOG_ERR, plugin_name,
- "aclinit_main - Unable to create the acl private pool\n");
- return 1;
- }
- /*
- * Now read all the ACLs from all the backends and put it
- * in a list
- */
- /* initialize the ACLLIST sub-system */
- if ( 0 != (rv = acllist_init ( ))) {
- slapi_log_error(SLAPI_LOG_ERR, plugin_name,
- "aclinit_main - Unable to initialize the plugin:%d\n", rv );
- return 1;
- }
- /* Initialize the anonymous profile i.e., generate it */
- rv = aclanom_init ();
- pb = slapi_pblock_new();
-
- /*
- * search for the aci_attr_type attributes of all entries.
- *
- * slapi_get_fist_suffix() and slapi_get_next_suffix() do not return the
- * rootdse entry so we search for acis in there explicitly here.
- */
- sdn = slapi_sdn_new_ndn_byval("");
- slapi_log_error(SLAPI_LOG_ACL, plugin_name,
- "aclinit_main - Searching for all acis(scope base) at suffix ''\n");
- aclinit_search_and_update_aci ( 0, /* thisbeonly */
- sdn, /* base */
- NULL, /* be name*/
- LDAP_SCOPE_BASE, ACL_ADD_ACIS,
- DO_TAKE_ACLCACHE_WRITELOCK);
- slapi_sdn_free(&sdn);
- sdn = slapi_get_first_suffix( &node, 1 );
- while (sdn)
- {
- slapi_log_error(SLAPI_LOG_ACL, plugin_name,
- "aclinit_main - Searching for all acis(scope subtree) at suffix '%s'\n",
- slapi_sdn_get_dn(sdn) );
- aclinit_search_and_update_aci ( 0, /* thisbeonly */
- sdn, /* base */
- NULL, /* be name*/
- LDAP_SCOPE_SUBTREE, ACL_ADD_ACIS,
- DO_TAKE_ACLCACHE_WRITELOCK);
- sdn = slapi_get_next_suffix( &node, 1 );
- }
- /* Initialize it. */
- acl_initialized = 1;
- /* generate the signatures */
- acl_set_aclsignature ( aclutil_gen_signature ( 100 ) );
- /* Initialize the user-group cache */
- rv = aclgroup_init ( );
- aclanom_gen_anomProfile (DO_TAKE_ACLCACHE_READLOCK);
- /* Register both of the proxied authorization controls (version 1 and 2) */
- slapi_register_supported_control( LDAP_CONTROL_PROXYAUTH,
- SLAPI_OPERATION_SEARCH | SLAPI_OPERATION_COMPARE
- | SLAPI_OPERATION_ADD | SLAPI_OPERATION_DELETE
- | SLAPI_OPERATION_MODIFY | SLAPI_OPERATION_MODDN
- | SLAPI_OPERATION_EXTENDED );
- slapi_register_supported_control( LDAP_CONTROL_PROXIEDAUTH,
- SLAPI_OPERATION_SEARCH | SLAPI_OPERATION_COMPARE
- | SLAPI_OPERATION_ADD | SLAPI_OPERATION_DELETE
- | SLAPI_OPERATION_MODIFY | SLAPI_OPERATION_MODDN
- | SLAPI_OPERATION_EXTENDED );
- slapi_pblock_destroy ( pb );
- return 0;
- }
- /*
- * This routine is the one that scans for acis and either adds them
- * to the internal cache (op==ACL_ADD_ACIS) or deletes them
- * (op==ACL_REMOVE_ACIS).
- *
- * If thisbeonly is 0 the search
- * is conducted on the base with the specifed scope and be_name is ignored.
- * This is used at startup time where we iterate over all suffixes, searching
- * for all the acis in the DIT to load the ACL cache.
- *
- * If thisbeonly is 1 then then a be_name must be specified.
- * In this case we will search in that backend ONLY.
- * This is used in the case where a backend is turned on and off--in this
- * case we only want to add/remove the acis in that particular backend and
- * not for example in any backends below that one.
- */
- int
- aclinit_search_and_update_aci ( int thisbeonly, const Slapi_DN *base,
- char *be_name, int scope, int op,
- acl_lock_flag_t lock_flag )
- {
- char *attrs[2] = { "aci", NULL };
- /* Tell __aclinit_handler whether it's an add or a delete */
- Slapi_PBlock *aPb;
- LDAPControl **ctrls=NULL;
- struct berval *bval;
- aclinit_handler_callback_data_t call_back_data;
- PR_ASSERT( lock_flag == DONT_TAKE_ACLCACHE_WRITELOCK ||
- lock_flag == DO_TAKE_ACLCACHE_WRITELOCK);
- if ( thisbeonly && be_name == NULL) {
- slapi_log_error(SLAPI_LOG_ERR, plugin_name,
- "aclinit_search_and_update_aci - be_name must be specified.\n");
- return -1;
- }
- /*
- * We need to explicitly request (objectclass=ldapsubentry)
- * in order to get all the subentry acis too.
- * Note that subentries can be added under subentries (although its not
- * recommended) so that
- * there may be non-trivial acis under a subentry.
- */
- /* Use new search internal API */
- /* and never retrieve aci from a remote server */
- aPb = slapi_pblock_new ();
-
- /*
- * Set up the control to say "Only get acis from this Backend--
- * there may be more backends under this one.
- */
- if ( thisbeonly ) {
-
- bval = (struct berval *)slapi_ch_malloc(sizeof(struct berval));
- bval->bv_len = strlen(be_name) + 1;
- bval->bv_val = slapi_ch_strdup(be_name);
- ctrls = (LDAPControl **)slapi_ch_calloc( 2, sizeof(LDAPControl *));
- ctrls[0] = NULL;
- ctrls[1] = NULL;
-
- slapi_build_control_from_berval(
- MTN_CONTROL_USE_ONE_BACKEND_OID,
- bval,
- 1 /* is critical */,
- ctrls);
- }
- slapi_search_internal_set_pb ( aPb,
- slapi_sdn_get_dn(base),
- scope,
- "(|(aci=*)(objectclass=ldapsubentry))",
- attrs,
- 0 /* attrsonly */,
- ctrls /* controls: SLAPI_ARGCONTROLS */,
- NULL /* uniqueid */,
- aclplugin_get_identity (ACL_PLUGIN_IDENTITY),
- SLAPI_OP_FLAG_NEVER_CHAIN /* actions : get local aci only */);
-
- if (thisbeonly) {
- slapi_pblock_set(aPb, SLAPI_REQCONTROLS, ctrls);
- }
- call_back_data.op = op;
- call_back_data.retCode = 0;
- call_back_data.lock_flag = lock_flag;
- slapi_search_internal_callback_pb(aPb,
- &call_back_data /* callback_data */,
- NULL/* result_callback */,
- __aclinit_handler,
- NULL /* referral_callback */);
- if (thisbeonly) {
- slapi_ch_free((void **)&bval);
- }
- /*
- * This frees the control oid, the bv_val and the control itself and the
- * ctrls array mem by caling ldap_controls_free()--so we
- * don't need to do it ourselves.
- */
- slapi_pblock_destroy (aPb);
-
- return call_back_data.retCode;
- }
- /***************************************************************************
- *
- * __aclinit_handler
- *
- * For each entry, finds if there is any ACL in that entry. If there is
- * then the ACL is processed and stored in the ACL LIST.
- *
- *
- * Input:
- *
- *
- * Returns:
- * None.
- *
- * Error Handling:
- * If any error found during the ACL generation, the ACL is
- * logged. Also, set in the callback_data so that caller can act upon it.
- *
- **************************************************************************/
- static int
- __aclinit_handler ( Slapi_Entry *e, void *callback_data)
- {
- Slapi_Attr *attr;
- aclinit_handler_callback_data_t *call_back_data =
- (aclinit_handler_callback_data_t*)callback_data;
- Slapi_DN *e_sdn;
- int rv;
- Slapi_Value *sval=NULL;
- call_back_data->retCode = 0; /* assume success--if there's an error we overwrite it */
- if (e != NULL) {
- e_sdn = slapi_entry_get_sdn ( e );
- /*
- * Take the write lock around all the mods--so that
- * other operations will see the acicache either before the whole mod
- * or after but not, as it was before, during the mod.
- * This is in line with the LDAP concept of the operation
- * on the whole entry being the atomic unit.
- *
- */
-
- if ( call_back_data->op == ACL_ADD_ACIS ) {
- slapi_log_error(SLAPI_LOG_ACL, plugin_name,
- "Adding acis for entry '%s'\n", slapi_sdn_get_dn(e_sdn));
- slapi_entry_attr_find ( e, aci_attr_type, &attr );
- if ( attr ) {
-
- const struct berval *attrValue;
-
- int i;
- if ( call_back_data->lock_flag == DO_TAKE_ACLCACHE_WRITELOCK) {
- acllist_acicache_WRITE_LOCK();
- }
- i= slapi_attr_first_value ( attr, &sval );
- while(i != -1) {
- attrValue = slapi_value_get_berval(sval);
-
- if ( 0 != (rv=acllist_insert_aci_needsLock (e_sdn, attrValue))) {
- aclutil_print_err(rv, e_sdn, attrValue, NULL);
- /* We got an error; Log it and then march along */
- slapi_log_error(SLAPI_LOG_ERR, plugin_name,
- "__aclinit_handler - This (%s) ACL will not be considered for evaluation"
- " because of syntax errors.\n",
- attrValue->bv_val ? attrValue->bv_val: "NULL");
- call_back_data->retCode = rv;
- }
- i= slapi_attr_next_value( attr, i, &sval );
- }/* while */
- if ( call_back_data->lock_flag == DO_TAKE_ACLCACHE_WRITELOCK) {
- acllist_acicache_WRITE_UNLOCK();
- }
- }
- } else if (call_back_data->op == ACL_REMOVE_ACIS) {
- /* Here we are deleting the acis. */
- slapi_log_error(SLAPI_LOG_ACL, plugin_name, "__aclinit_handler - Removing acis\n");
- if ( call_back_data->lock_flag == DO_TAKE_ACLCACHE_WRITELOCK) {
- acllist_acicache_WRITE_LOCK();
- }
- if ( 0 != (rv=acllist_remove_aci_needsLock(e_sdn, NULL))) {
- aclutil_print_err(rv, e_sdn, NULL, NULL);
- /* We got an error; Log it and then march along */
- slapi_log_error(SLAPI_LOG_ERR, plugin_name,
- "__aclinit_handler - ACLs not deleted from %s\n",
- slapi_sdn_get_dn(e_sdn));
- call_back_data->retCode = rv;
- }
- if ( call_back_data->lock_flag == DO_TAKE_ACLCACHE_WRITELOCK) {
- acllist_acicache_WRITE_UNLOCK();
- }
- }
-
- }
- /*
- * If we get here it's success.
- * The call_back_data->error is the error code that counts as it's the
- * one that the original caller will see--this routine is called off a callbacl.
- */
-
- return ACL_FALSE; /* "local" error code--it's 0 */
- }
- /***************************************************************************
- *
- * __acl__RegisterAttributes
- *
- * Register all the attributes supported by the DS.
- *
- * Input:
- * None.
- *
- * Returns:
- * ACL_OK - No error
- * ACL_ERR - in case of errror
- *
- * Error Handling:
- * None.
- *
- **************************************************************************/
- static int
- __aclinit__RegisterAttributes(void)
- {
- ACLMethod_t methodinfo;
- NSErr_t errp;
- int rv;
- memset (&errp, 0, sizeof(NSErr_t));
-
- rv = ACL_MethodRegister(&errp, DS_METHOD, &methodinfo);
- if (rv < 0) {
- acl_print_acllib_err(&errp, NULL);
- slapi_log_error(SLAPI_LOG_ERR, plugin_name,
- "__aclinit__RegisterAttributes - Unable to Register the methods\n");
- return ACL_ERR;
- }
- rv = ACL_MethodSetDefault (&errp, methodinfo);
- if (rv < 0) {
- acl_print_acllib_err(&errp, NULL);
- slapi_log_error(SLAPI_LOG_ERR, plugin_name,
- "__aclinit__RegisterAttributes - Unable to Set the default method\n");
- return ACL_ERR;
- }
- rv = ACL_AttrGetterRegister(&errp, ACL_ATTR_IP, DS_LASIpGetter,
- methodinfo, ACL_DBTYPE_ANY, ACL_AT_FRONT, NULL);
- if (rv < 0) {
- acl_print_acllib_err(&errp, NULL);
- slapi_log_error(SLAPI_LOG_ERR, plugin_name,
- "__aclinit__RegisterAttributes - Unable to Register Attr ip\n");
- return ACL_ERR;
- }
- rv = ACL_AttrGetterRegister(&errp, ACL_ATTR_DNS, DS_LASDnsGetter,
- methodinfo, ACL_DBTYPE_ANY, ACL_AT_FRONT, NULL);
- if (rv < 0) {
- acl_print_acllib_err(&errp, NULL);
- slapi_log_error(SLAPI_LOG_ERR, plugin_name,
- "__aclinit__RegisterAttributes - Unable to Register Attr dns\n");
- return ACL_ERR;
- }
- return ACL_OK;
- }
- /***************************************************************************
- *
- * __acl__RegisterLases
- * Register all the LASes supported by the DS.
- *
- * The DS doesnot support user/group. We have defined our own LAS
- * so that we can display/print an error when the LAS is invoked.
- * Input:
- * None.
- *
- * Returns:
- * ACL_OK - No error
- * ACL_ERR - in case of errror
- *
- * Error Handling:
- * None.
- *
- **************************************************************************/
- static int
- __aclinit__RegisterLases(void)
- {
- if (ACL_LasRegister(NULL, DS_LAS_USER, (LASEvalFunc_t) DS_LASUserEval,
- (LASFlushFunc_t) NULL) < 0) {
- slapi_log_error(SLAPI_LOG_ERR, plugin_name,
- "__aclinit__RegisterLases - Unable to register USER Las\n");
- return ACL_ERR;
- }
- if (ACL_LasRegister(NULL, DS_LAS_GROUP, (LASEvalFunc_t) DS_LASGroupEval,
- (LASFlushFunc_t) NULL) < 0) {
- slapi_log_error(SLAPI_LOG_ERR, plugin_name,
- "__aclinit__RegisterLases - Unable to register GROUP Las\n");
- return ACL_ERR;
- }
- if (ACL_LasRegister(NULL, DS_LAS_GROUPDN, (LASEvalFunc_t)DS_LASGroupDnEval,
- (LASFlushFunc_t)NULL) < 0) {
- slapi_log_error(SLAPI_LOG_ERR, plugin_name,
- "__aclinit__RegisterLases - Unable to register GROUPDN Las\n");
- return ACL_ERR;
- }
- if (ACL_LasRegister(NULL, DS_LAS_ROLEDN, (LASEvalFunc_t)DS_LASRoleDnEval,
- (LASFlushFunc_t)NULL) < 0) {
- slapi_log_error(SLAPI_LOG_ERR, plugin_name,
- "__aclinit__RegisterLases - Unable to register ROLEDN Las\n");
- return ACL_ERR;
- }
- if (ACL_LasRegister(NULL, DS_LAS_USERDN, (LASEvalFunc_t)DS_LASUserDnEval,
- (LASFlushFunc_t)NULL) < 0) {
- slapi_log_error(SLAPI_LOG_ERR, plugin_name,
- "__aclinit__RegisterLases - Unable to register USERDN Las\n");
- return ACL_ERR;
- }
- if (ACL_LasRegister(NULL, DS_LAS_USERDNATTR,
- (LASEvalFunc_t)DS_LASUserDnAttrEval,
- (LASFlushFunc_t)NULL) < 0) {
- slapi_log_error(SLAPI_LOG_ERR, plugin_name,
- "__aclinit__RegisterLases - Unable to register USERDNATTR Las\n");
- return ACL_ERR;
- }
- if (ACL_LasRegister(NULL, DS_LAS_AUTHMETHOD,
- (LASEvalFunc_t)DS_LASAuthMethodEval,
- (LASFlushFunc_t)NULL) < 0) {
- slapi_log_error(SLAPI_LOG_ERR, plugin_name,
- "__aclinit__RegisterLases - Unable to register CLIENTAUTHTYPE Las\n");
- return ACL_ERR;
- }
- if (ACL_LasRegister(NULL, DS_LAS_GROUPDNATTR,
- (LASEvalFunc_t)DS_LASGroupDnAttrEval,
- (LASFlushFunc_t)NULL) < 0) {
- slapi_log_error(SLAPI_LOG_ERR, plugin_name,
- "__aclinit__RegisterLases - Unable to register GROUPDNATTR Las\n");
- return ACL_ERR;
- }
- if (ACL_LasRegister(NULL, DS_LAS_USERATTR,
- (LASEvalFunc_t)DS_LASUserAttrEval,
- (LASFlushFunc_t)NULL) < 0) {
- slapi_log_error(SLAPI_LOG_ERR, plugin_name,
- "__aclinit__RegisterLases - Unable to register USERATTR Las\n");
- return ACL_ERR;
- }
- if (ACL_LasRegister(NULL, DS_LAS_SSF,
- (LASEvalFunc_t)DS_LASSSFEval,
- (LASFlushFunc_t)NULL) < 0) {
- slapi_log_error(SLAPI_LOG_ERR, plugin_name,
- "__aclinit__RegisterLases - Unable to register SSF Las\n");
- return ACL_ERR;
- }
- return ACL_OK;
- }
|