/****************************************************************************** Copyright (C) 2009 Hewlett-Packard Development Company, L.P. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. Contributors: Hewlett-Packard Development Company, L.P. ******************************************************************************/ /* Example enabling and config entries dn: cn=Account Policy Plugin,cn=plugins,cn=config objectClass: top objectClass: nsSlapdPlugin objectClass: extensibleObject cn: Account Policy Plugin nsslapd-pluginPath: /path/to/libacctpolicy-plugin.sl nsslapd-pluginInitfunc: acct_policy_init nsslapd-pluginType: object nsslapd-pluginEnabled: on nsslapd-plugin-depends-on-type: database nsslapd-pluginId: Account Policy Plugin dn: cn=config,cn=Account Policy Plugin,cn=plugins,cn=config objectClass: top objectClass: extensibleObject cn: config alwaysrecordlogin: yes stateattrname: lastLoginTime altstateattrname: createTimestamp specattrname: acctPolicySubentry limitattrname: accountInactivityLimit */ #include #include #include "slapi-plugin.h" #include "acctpolicy.h" static Slapi_PluginDesc plugin_desc = { PLUGIN_NAME, PLUGIN_VENDOR, PLUGIN_VERSION, PLUGIN_DESC }; static Slapi_PluginDesc pre_plugin_desc = { PRE_PLUGIN_NAME, PLUGIN_VENDOR, PLUGIN_VERSION, PLUGIN_DESC }; static Slapi_PluginDesc post_plugin_desc = { PRE_PLUGIN_NAME, PLUGIN_VENDOR, PLUGIN_VERSION, PLUGIN_DESC }; /* Local function prototypes */ int acct_policy_start( Slapi_PBlock *pb ); int acct_policy_close( Slapi_PBlock *pb ); int acct_policy_init( Slapi_PBlock *pb ); int acct_preop_init( Slapi_PBlock *pb ); int acct_postop_init( Slapi_PBlock *pb ); int acct_bind_preop( Slapi_PBlock *pb ); int acct_bind_postop( Slapi_PBlock *pb ); static void *_PluginID = NULL; static Slapi_DN *_PluginDN = NULL; static Slapi_DN *_ConfigAreaDN = NULL; static Slapi_RWLock *config_rwlock = NULL; void acct_policy_set_plugin_id(void *pluginID) { _PluginID = pluginID; } void * acct_policy_get_plugin_id(void) { return _PluginID; } void acct_policy_set_plugin_sdn(Slapi_DN *pluginDN) { _PluginDN = pluginDN; } Slapi_DN * acct_policy_get_plugin_sdn() { return _PluginDN; } void acct_policy_set_config_area(Slapi_DN *sdn) { _ConfigAreaDN = sdn; } Slapi_DN * acct_policy_get_config_area() { return _ConfigAreaDN; } /* Master init function for the account plugin */ int acct_policy_init( Slapi_PBlock *pb ) { void *plugin_id; int enabled; slapi_pblock_get(pb, SLAPI_PLUGIN_ENABLED, &enabled); if (!enabled) { /* not enabled */ return( CALLBACK_OK ); } if ( slapi_pblock_set( pb, SLAPI_PLUGIN_VERSION, SLAPI_PLUGIN_VERSION_01 ) != 0 || slapi_pblock_set( pb, SLAPI_PLUGIN_DESCRIPTION, (void *)&plugin_desc ) != 0 || slapi_pblock_set( pb, SLAPI_PLUGIN_CLOSE_FN, (void *)&acct_policy_close ) != 0 || slapi_pblock_set( pb, SLAPI_PLUGIN_START_FN, (void *)acct_policy_start ) != 0 ) { slapi_log_error(SLAPI_LOG_ERR, PLUGIN_NAME, "acct_policy_init - Registration failed\n" ); return( CALLBACK_ERR ); } if( slapi_pblock_get( pb, SLAPI_PLUGIN_IDENTITY, &plugin_id ) != 0 ) { slapi_log_error(SLAPI_LOG_ERR, PLUGIN_NAME, "acct_policy_init - Failed to get plugin identity\n" ); return( CALLBACK_ERR ); } set_identity( plugin_id ); /* Register the pre and postop plugins */ if( slapi_register_plugin("preoperation", 1, "acct_preop_init", acct_preop_init, PRE_PLUGIN_DESC, NULL, plugin_id) != 0 || slapi_register_plugin("postoperation", 1, "acct_postop_init", acct_postop_init, POST_PLUGIN_DESC, NULL, plugin_id) != 0 ) { slapi_log_error(SLAPI_LOG_ERR, PLUGIN_NAME, "acct_policy_init - Failed to register callbacks\n" ); return( CALLBACK_ERR ); } return( CALLBACK_OK ); } /* Plugin startup function, when this is called any other plugins should already be initialized, so it's safe to e.g. perform internal searches, which is needed to retrieve the plugin configuration */ int acct_policy_start( Slapi_PBlock *pb ) { acctPluginCfg *cfg; void *plugin_id = get_identity(); Slapi_DN *plugindn = NULL; char *config_area = NULL; if(slapi_plugin_running(pb)){ return 0; } slapi_pblock_get(pb, SLAPI_TARGET_SDN, &plugindn); acct_policy_set_plugin_sdn(slapi_sdn_dup(plugindn)); /* Set the alternate config area if one is defined. */ slapi_pblock_get(pb, SLAPI_PLUGIN_CONFIG_AREA, &config_area); if (config_area) { acct_policy_set_config_area(slapi_sdn_new_normdn_byval(config_area)); } if(config_rwlock == NULL){ if((config_rwlock = slapi_new_rwlock()) == NULL){ return( CALLBACK_ERR ); } } /* Load plugin configuration */ if( acct_policy_load_config_startup( pb, plugin_id ) ) { slapi_log_error(SLAPI_LOG_ERR, PLUGIN_NAME, "acct_policy_start failed to load configuration\n" ); return( CALLBACK_ERR ); } /* Show the configuration */ cfg = get_config(); slapi_log_error(SLAPI_LOG_PLUGIN, PLUGIN_NAME, "acct_policy_start - config: " "stateAttrName=%s altStateAttrName=%s specAttrName=%s limitAttrName=%s " "alwaysRecordLogin=%d\n", cfg->state_attr_name, cfg->alt_state_attr_name?cfg->alt_state_attr_name:"not configured", cfg->spec_attr_name, cfg->limit_attr_name, cfg->always_record_login); return( CALLBACK_OK ); } int acct_policy_close( Slapi_PBlock *pb ) { int rc = 0; slapi_destroy_rwlock(config_rwlock); config_rwlock = NULL; slapi_sdn_free(&_PluginDN); slapi_sdn_free(&_ConfigAreaDN); free_config(); return rc; } int acct_preop_init( Slapi_PBlock *pb ) { /* Which slapi plugin API we're compatible with. */ if ( slapi_pblock_set( pb, SLAPI_PLUGIN_VERSION, SLAPI_PLUGIN_VERSION_01 ) != 0 || slapi_pblock_set( pb, SLAPI_PLUGIN_DESCRIPTION, (void *)&pre_plugin_desc ) != 0 ) { slapi_log_error(SLAPI_LOG_ERR, PRE_PLUGIN_NAME, "Failed to set plugin version or description\n" ); return( CALLBACK_ERR ); } if ( slapi_pblock_set( pb, SLAPI_PLUGIN_PRE_BIND_FN, (void *) acct_bind_preop ) != 0 || slapi_pblock_set(pb, SLAPI_PLUGIN_PRE_ADD_FN, (void *) acct_add_pre_op) != 0 || slapi_pblock_set(pb, SLAPI_PLUGIN_PRE_MODIFY_FN, (void *) acct_mod_pre_op) != 0 || slapi_pblock_set(pb, SLAPI_PLUGIN_PRE_DELETE_FN, (void *) acct_del_pre_op) != 0) { slapi_log_error(SLAPI_LOG_ERR, PRE_PLUGIN_NAME, "acct_preop_init - Failed to set plugin callback function\n" ); return( CALLBACK_ERR ); } return( CALLBACK_OK ); } int acct_postop_init( Slapi_PBlock *pb ) { void *plugin_id = get_identity(); if ( slapi_pblock_set( pb, SLAPI_PLUGIN_VERSION, SLAPI_PLUGIN_VERSION_01 ) != 0 || slapi_pblock_set( pb, SLAPI_PLUGIN_DESCRIPTION, (void *)&post_plugin_desc ) != 0 ) { slapi_log_error(SLAPI_LOG_ERR, POST_PLUGIN_NAME, "acct_postop_init - Failed to set plugin version or name\n" ); return( CALLBACK_ERR ); } if ( slapi_pblock_set( pb, SLAPI_PLUGIN_POST_BIND_FN, (void *)acct_bind_postop ) != 0 || slapi_pblock_set(pb, SLAPI_PLUGIN_POST_ADD_FN, (void *) acct_post_op) != 0 || slapi_pblock_set(pb, SLAPI_PLUGIN_POST_MODIFY_FN, (void *) acct_post_op) != 0) { slapi_log_error(SLAPI_LOG_ERR, POST_PLUGIN_NAME, "acct_postop_init - Failed to set plugin callback function\n" ); return( CALLBACK_ERR ); } if( slapi_pblock_get( pb, SLAPI_PLUGIN_IDENTITY, &plugin_id ) != 0 ) { slapi_log_error(SLAPI_LOG_ERR, POST_PLUGIN_NAME, "acct_postop_init - Failed to get plugin identity\n" ); return( CALLBACK_ERR ); } return( CALLBACK_OK ); } /* * Wrappers for config locking */ void config_rd_lock() { slapi_rwlock_rdlock(config_rwlock); } void config_wr_lock() { slapi_rwlock_wrlock(config_rwlock); } void config_unlock() { slapi_rwlock_unlock(config_rwlock); }