summaryrefslogtreecommitdiffstats
path: root/daemons/ipa-slapi-plugins
diff options
context:
space:
mode:
Diffstat (limited to 'daemons/ipa-slapi-plugins')
-rw-r--r--daemons/ipa-slapi-plugins/ipa-memberof/Makefile.am43
-rw-r--r--daemons/ipa-slapi-plugins/ipa-memberof/ipa-memberof.c2244
-rw-r--r--daemons/ipa-slapi-plugins/ipa-memberof/ipa-memberof.h100
-rw-r--r--daemons/ipa-slapi-plugins/ipa-memberof/ipa-memberof_config.c312
-rw-r--r--daemons/ipa-slapi-plugins/ipa-memberof/memberof-conf.ldif14
5 files changed, 0 insertions, 2713 deletions
diff --git a/daemons/ipa-slapi-plugins/ipa-memberof/Makefile.am b/daemons/ipa-slapi-plugins/ipa-memberof/Makefile.am
deleted file mode 100644
index d0ac7f935..000000000
--- a/daemons/ipa-slapi-plugins/ipa-memberof/Makefile.am
+++ /dev/null
@@ -1,43 +0,0 @@
-NULL =
-
-INCLUDES = \
- -I. \
- -I$(srcdir) \
- -DPREFIX=\""$(prefix)"\" \
- -DBINDIR=\""$(bindir)"\" \
- -DLIBDIR=\""$(libdir)"\" \
- -DLIBEXECDIR=\""$(libexecdir)"\" \
- -DDATADIR=\""$(datadir)"\" \
- $(MOZLDAP_CFLAGS) \
- $(KRB5_CFLAGS) \
- $(WARN_CFLAGS) \
- $(NULL)
-
-plugindir = $(libdir)/dirsrv/plugins
-plugin_LTLIBRARIES = \
- libipa-memberof-plugin.la \
- $(NULL)
-
-libipa_memberof_plugin_la_SOURCES = \
- ipa-memberof.c \
- ipa-memberof_config.c \
- $(NULL)
-
-libipa_memberof_plugin_la_LDFLAGS = -avoid-version
-
-libipa_memberof_plugin_la_LIBADD = \
- $(MOZLDAP_LIBS) \
- $(NULL)
-
-appdir = $(IPA_DATA_DIR)
-app_DATA = \
- memberof-conf.ldif \
- $(NULL)
-
-EXTRA_DIST = \
- $(app_DATA) \
- $(NULL)
-
-MAINTAINERCLEANFILES = \
- *~ \
- Makefile.in
diff --git a/daemons/ipa-slapi-plugins/ipa-memberof/ipa-memberof.c b/daemons/ipa-slapi-plugins/ipa-memberof/ipa-memberof.c
deleted file mode 100644
index 3baf2f6cf..000000000
--- a/daemons/ipa-slapi-plugins/ipa-memberof/ipa-memberof.c
+++ /dev/null
@@ -1,2244 +0,0 @@
-/** BEGIN COPYRIGHT BLOCK
- * This Program is free software; you can redistribute it and/or modify it under
- * the terms of the GNU General Public License as published by the Free Software
- * Foundation; version 2 of the License.
- *
- * 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., 59 Temple
- * Place, Suite 330, Boston, MA 02111-1307 USA.
- *
- * In addition, as a special exception, Red Hat, Inc. gives You the additional
- * right to link the code of this Program with code not covered under the GNU
- * General Public License ("Non-GPL Code") and to distribute linked combinations
- * including the two, subject to the limitations in this paragraph. Non-GPL Code
- * permitted under this exception must only link to the code of this Program
- * through those well defined interfaces identified in the file named EXCEPTION
- * found in the source code files (the "Approved Interfaces"). The files of
- * Non-GPL Code may instantiate templates or use macros or inline functions from
- * the Approved Interfaces without causing the resulting work to be covered by
- * the GNU General Public License. Only Red Hat, Inc. may make changes or
- * additions to the list of Approved Interfaces. You must obey the GNU General
- * Public License in all respects for all of the Program code and other code used
- * in conjunction with the Program except the Non-GPL Code covered by this
- * exception. If you modify this file, you may extend this exception to your
- * version of the file, but you are not obligated to do so. If you do not wish to
- * provide this exception without modification, you must delete this exception
- * statement from your version and license this file solely under the GPL without
- * exception.
- *
- * Authors:
- * Pete Rowley <prowley@redhat.com>
- *
- * Copyright (C) 2007 Red Hat, Inc.
- * All rights reserved.
- * END COPYRIGHT BLOCK
- **/
-
-/* The memberof plugin updates the memberof attribute of entries
- * based on modifications performed on groupofuniquenames entries
- *
- * In addition the plugin provides a DS task that may be started
- * administrative clients and that creates the initial memberof
- * list for imported entries and/or fixes the memberof list of
- * existing entries that have inconsistent state (for example,
- * if the memberof attribute was incorrectly edited directly)
- *
- * To start the memberof task add an entry like:
- *
- * dn: cn=mytask, cn=memberof task, cn=tasks, cn=config
- * objectClass: top
- * objectClass: extensibleObject
- * cn: mytask
- * basedn: dc=example, dc=com
- * filter: (uid=test4)
- *
- * where "basedn" is required and refers to the top most node to perform the
- * task on, and where "filter" is an optional attribute that provides a filter
- * describing the entries to be worked on
- */
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#include <dirsrv/slapi-plugin.h>
-
-#include "string.h"
-#include "nspr.h"
-
-#include "ipa-memberof.h"
-
-static Slapi_PluginDesc pdesc = { "ipamo", "FreeIPA project", "FreeIPA/1.0",
- "IPA memberof plugin" };
-
-static void* _PluginID = NULL;
-static Slapi_Mutex *memberof_operation_lock = 0;
-MemberOfConfig *qsortConfig = 0;
-
-typedef struct _memberofstringll
-{
- const char *dn;
- void *next;
-} memberofstringll;
-
-typedef struct _memberof_get_groups_data
-{
- MemberOfConfig *config;
- Slapi_Value *memberdn_val;
- Slapi_ValueSet **groupvals;
-} memberof_get_groups_data;
-
-/****** secrets *********/
-#ifndef SLAPI_TASK_PUBLIC
-/*from FDS slap.h
- * until we get a proper api for access
- */
-#define TASK_RUNNING_AS_TASK 0x0
-
-/******************************************************************************
- * Online tasks interface (to support import, export, etc)
- * After some cleanup, we could consider making these public.
- */
-struct _slapi_task {
- struct _slapi_task *next;
- char *task_dn;
- int task_exitcode; /* for the end user */
- int task_state; /* (see above) */
- int task_progress; /* number between 0 and task_work */
- int task_work; /* "units" of work to be done */
- int task_flags; /* (see above) */
-
- /* it is the task's responsibility to allocate this memory & free it: */
- char *task_status; /* transient status info */
- char *task_log; /* appended warnings, etc */
-
- void *task_private; /* for use by backends */
- TaskCallbackFn cancel; /* task has been cancelled by user */
- TaskCallbackFn destructor; /* task entry is being destroyed */
- int task_refcount;
-};
-
-static void slapi_task_set_data(Slapi_Task *task, void *data)
-{
- if (task) {
- task->task_private = data;
- }
-}
-
-/*
- * Retrieve some opaque task specific data from the task.
- */
-static void * slapi_task_get_data(Slapi_Task *task)
-{
- if (task) {
- return task->task_private;
- }
-}
-
-static void slapi_task_begin(Slapi_Task *task, int total_work)
-{
- if (task) {
- task->task_work = total_work;
- task->task_progress = 0;
- task->task_state = SLAPI_TASK_RUNNING;
- slapi_task_status_changed(task);
- }
-}
-
-static void slapi_task_inc_progress(Slapi_Task *task)
-{
- if (task) {
- task->task_progress++;
- slapi_task_status_changed(task);
- }
-}
-
-static void slapi_task_finish(Slapi_Task *task, int rc)
-{
- if (task) {
- task->task_exitcode = rc;
- task->task_state = SLAPI_TASK_FINISHED;
- slapi_task_status_changed(task);
- }
-}
-
-static void slapi_task_set_destructor_fn(Slapi_Task *task, TaskCallbackFn func)
-{
- if (task) {
- task->destructor = func;
- }
-}
-
-#endif /* !SLAPI_TASK_PUBLIC */
-/****** secrets ********/
-
-/*** function prototypes ***/
-
-/* exported functions */
-int ipamo_postop_init(Slapi_PBlock *pb );
-
-/* plugin callbacks */
-static int memberof_postop_del(Slapi_PBlock *pb );
-static int memberof_postop_modrdn(Slapi_PBlock *pb );
-static int memberof_postop_modify(Slapi_PBlock *pb );
-static int memberof_postop_add(Slapi_PBlock *pb );
-static int memberof_postop_start(Slapi_PBlock *pb);
-static int memberof_postop_close(Slapi_PBlock *pb);
-
-/* supporting cast */
-static int memberof_oktodo(Slapi_PBlock *pb);
-static char *memberof_getdn(Slapi_PBlock *pb);
-static int memberof_modop_one(Slapi_PBlock *pb, MemberOfConfig *config, int mod_op,
- char *op_this, char *op_to);
-static int memberof_modop_one_r(Slapi_PBlock *pb, MemberOfConfig *config, int mod_op,
- char *group_dn, char *op_this, char *op_to, memberofstringll *stack);
-static int memberof_add_one(Slapi_PBlock *pb, MemberOfConfig *config, char *addthis,
- char *addto);
-static int memberof_del_one(Slapi_PBlock *pb, MemberOfConfig *config, char *delthis,
- char *delfrom);
-static int memberof_mod_smod_list(Slapi_PBlock *pb, MemberOfConfig *config, int mod,
- char *groupdn, Slapi_Mod *smod);
-static int memberof_add_smod_list(Slapi_PBlock *pb, MemberOfConfig *config,
- char *groupdn, Slapi_Mod *smod);
-static int memberof_del_smod_list(Slapi_PBlock *pb, MemberOfConfig *config,
- char *groupdn, Slapi_Mod *smod);
-static int memberof_mod_attr_list(Slapi_PBlock *pb, MemberOfConfig *config, int mod,
- char *groupdn, Slapi_Attr *attr);
-static int memberof_mod_attr_list_r(Slapi_PBlock *pb, MemberOfConfig *config,
- int mod, char *group_dn, char *op_this, Slapi_Attr *attr, memberofstringll *stack);
-static int memberof_add_attr_list(Slapi_PBlock *pb, MemberOfConfig *config,
- char *groupdn, Slapi_Attr *attr);
-static int memberof_del_attr_list(Slapi_PBlock *pb, MemberOfConfig *config,
- char *groupdn, Slapi_Attr *attr);
-static int memberof_moddn_attr_list(Slapi_PBlock *pb, MemberOfConfig *config,
- char *pre_dn, char *post_dn, Slapi_Attr *attr);
-static int memberof_replace_list(Slapi_PBlock *pb, MemberOfConfig *config, char *group_dn);
-static void memberof_set_plugin_id(void * plugin_id);
-static void *memberof_get_plugin_id();
-static int memberof_compare(MemberOfConfig *config, const void *a, const void *b);
-static int memberof_qsort_compare(const void *a, const void *b);
-static void memberof_load_array(Slapi_Value **array, Slapi_Attr *attr);
-static int memberof_del_dn_from_groups(Slapi_PBlock *pb, MemberOfConfig *config, char *dn);
-static int memberof_call_foreach_dn(Slapi_PBlock *pb, char *dn,
- char *type, plugin_search_entry_callback callback, void *callback_data);
-static int memberof_is_direct_member(MemberOfConfig *config, Slapi_Value *groupdn,
- Slapi_Value *memberdn);
-static Slapi_ValueSet *memberof_get_groups(MemberOfConfig *config, char *memberdn);
-static int memberof_get_groups_r(MemberOfConfig *config, char *memberdn,
- memberof_get_groups_data *data);
-static int memberof_get_groups_callback(Slapi_Entry *e, void *callback_data);
-static int memberof_test_membership(Slapi_PBlock *pb, MemberOfConfig *config,
- char *group_dn);
-static int memberof_test_membership_callback(Slapi_Entry *e, void *callback_data);
-static int memberof_del_dn_type_callback(Slapi_Entry *e, void *callback_data);
-static int memberof_replace_dn_type_callback(Slapi_Entry *e, void *callback_data);
-static int memberof_replace_dn_from_groups(Slapi_PBlock *pb, MemberOfConfig *config,
- char *pre_dn, char *post_dn);
-static int memberof_modop_one_replace_r(Slapi_PBlock *pb, MemberOfConfig *config,
- int mod_op, char *group_dn, char *op_this, char *replace_with, char *op_to,
- memberofstringll *stack);
-static int memberof_task_add(Slapi_PBlock *pb, Slapi_Entry *e,
- Slapi_Entry *eAfter, int *returncode, char *returntext,
- void *arg);
-static void memberof_task_destructor(Slapi_Task *task);
-static const char *fetch_attr(Slapi_Entry *e, const char *attrname,
- const char *default_val);
-static void memberof_fixup_task_thread(void *arg);
-static int memberof_fix_memberof(MemberOfConfig *config, char *dn, char *filter_str);
-static int memberof_fix_memberof_callback(Slapi_Entry *e, void *callback_data);
-
-
-/*** implementation ***/
-
-
-/*** exported functions ***/
-
-/*
- * ipamo_postop_init()
- *
- * Register plugin call backs
- *
- */
-int
-ipamo_postop_init(Slapi_PBlock *pb)
-{
- int ret = 0;
- char *memberof_plugin_identity = 0;
-
- slapi_log_error( SLAPI_LOG_TRACE, MEMBEROF_PLUGIN_SUBSYSTEM,
- "--> ipamo_postop_init\n" );
- /*
- * Get plugin identity and stored it for later use
- * Used for internal operations
- */
-
- slapi_pblock_get (pb, SLAPI_PLUGIN_IDENTITY, &memberof_plugin_identity);
- PR_ASSERT (memberof_plugin_identity);
- memberof_set_plugin_id(memberof_plugin_identity);
-
- if ( slapi_pblock_set( pb, SLAPI_PLUGIN_VERSION,
- SLAPI_PLUGIN_VERSION_01 ) != 0 ||
- slapi_pblock_set( pb, SLAPI_PLUGIN_DESCRIPTION,
- (void *)&pdesc ) != 0 ||
- slapi_pblock_set( pb, SLAPI_PLUGIN_POST_DELETE_FN,
- (void *) memberof_postop_del ) != 0 ||
- slapi_pblock_set( pb, SLAPI_PLUGIN_POST_MODRDN_FN,
- (void *) memberof_postop_modrdn ) != 0 ||
- slapi_pblock_set( pb, SLAPI_PLUGIN_POST_MODIFY_FN,
- (void *) memberof_postop_modify ) != 0 ||
- slapi_pblock_set( pb, SLAPI_PLUGIN_POST_ADD_FN,
- (void *) memberof_postop_add ) != 0 ||
- slapi_pblock_set(pb, SLAPI_PLUGIN_START_FN,
- (void *) memberof_postop_start ) != 0 ||
- slapi_pblock_set(pb, SLAPI_PLUGIN_CLOSE_FN,
- (void *) memberof_postop_close ) != 0)
- {
- slapi_log_error( SLAPI_LOG_FATAL, MEMBEROF_PLUGIN_SUBSYSTEM,
- "ipamo_postop_init failed\n" );
- ret = -1;
- }
-
- slapi_log_error( SLAPI_LOG_TRACE, MEMBEROF_PLUGIN_SUBSYSTEM,
- "<-- ipamo_postop_init\n" );
- return ret;
-}
-
-/*
- * memberof_postop_start()
- *
- * Do plugin start up stuff
- *
- */
-int memberof_postop_start(Slapi_PBlock *pb)
-{
- int rc = 0;
- Slapi_Entry *config_e = NULL; /* entry containing plugin config */
-
- slapi_log_error( SLAPI_LOG_TRACE, MEMBEROF_PLUGIN_SUBSYSTEM,
- "--> memberof_postop_start\n" );
-
- memberof_operation_lock = slapi_new_mutex();
- if(0 == memberof_operation_lock)
- {
- rc = -1;
- goto bail;
- }
-
- if ( slapi_pblock_get( pb, SLAPI_ADD_ENTRY, &config_e ) != 0 ) {
- slapi_log_error( SLAPI_LOG_FATAL, MEMBEROF_PLUGIN_SUBSYSTEM,
- "missing config entry\n" );
- rc = -1;
- goto bail;
- }
-
- if (( rc = memberof_config( config_e )) != LDAP_SUCCESS ) {
- slapi_log_error( SLAPI_LOG_FATAL, MEMBEROF_PLUGIN_SUBSYSTEM,
- "configuration failed (%s)\n", ldap_err2string( rc ));
- return( -1 );
- }
-
- rc = slapi_task_register_handler("memberof task", memberof_task_add);
- if(rc)
- {
- goto bail;
- }
-
- /*
- * TODO: start up operation actor thread
- * need to get to a point where server failure
- * or shutdown doesn't hose our operations
- * so we should create a task entry that contains
- * all required information to complete the operation
- * then the tasks can be restarted safely if
- * interrupted
- */
-
-bail:
- slapi_log_error( SLAPI_LOG_TRACE, MEMBEROF_PLUGIN_SUBSYSTEM,
- "<-- memberof_postop_start\n" );
-
- return rc;
-}
-
-/*
- * memberof_postop_close()
- *
- * Do plugin shut down stuff
- *
- */
-int memberof_postop_close(Slapi_PBlock *pb)
-{
- slapi_log_error( SLAPI_LOG_TRACE, MEMBEROF_PLUGIN_SUBSYSTEM,
- "--> memberof_postop_close\n" );
-
-
-
- slapi_log_error( SLAPI_LOG_TRACE, MEMBEROF_PLUGIN_SUBSYSTEM,
- "<-- memberof_postop_close\n" );
- return 0;
-}
-
-/*
- * memberof_postop_del()
- *
- * All entries with a memberOf attribute that contains the group DN get retrieved
- * and have the their memberOf attribute regenerated (it is far too complex and
- * error prone to attempt to change only those dn values involved in this case -
- * mainly because the deleted group may itself be a member of other groups which
- * may be members of other groups etc. in a big recursive mess involving dependency
- * chains that must be created and traversed in order to decide if an entry should
- * really have those groups removed too)
- */
-int memberof_postop_del(Slapi_PBlock *pb)
-{
- int ret = 0;
- MemberOfConfig configCopy = {0, 0, 0, 0};
- char *dn;
-
- slapi_log_error( SLAPI_LOG_TRACE, MEMBEROF_PLUGIN_SUBSYSTEM,
- "--> memberof_postop_del\n" );
-
- if(memberof_oktodo(pb) && (dn = memberof_getdn(pb)))
- {
- struct slapi_entry *e = NULL;
-
- slapi_pblock_get( pb, SLAPI_ENTRY_PRE_OP, &e );
-
- /* We need to get the config lock first. Trying to get the
- * config lock after we already hold the op lock can cause
- * a deadlock. */
- memberof_rlock_config();
- /* copy config so it doesn't change out from under us */
- memberof_copy_config(&configCopy, memberof_get_config());
- memberof_unlock_config();
-
- /* get the memberOf operation lock */
- memberof_lock();
-
- /* remove this group DN from the
- * membership lists of groups
- */
- memberof_del_dn_from_groups(pb, &configCopy, dn);
-
- /* is the entry of interest as a group? */
- if(e && !slapi_filter_test_simple(e, configCopy.group_filter))
- {
- Slapi_Attr *attr = 0;
-
- if(0 == slapi_entry_attr_find(e, configCopy.groupattr, &attr))
- {
- memberof_del_attr_list(pb, &configCopy, dn, attr);
- }
- }
-
- memberof_unlock();
-
- memberof_free_config(&configCopy);
- }
-
- slapi_log_error( SLAPI_LOG_TRACE, MEMBEROF_PLUGIN_SUBSYSTEM,
- "<-- memberof_postop_del\n" );
- return ret;
-}
-
-typedef struct _memberof_del_dn_data
-{
- char *dn;
- char *type;
-} memberof_del_dn_data;
-
-int memberof_del_dn_from_groups(Slapi_PBlock *pb, MemberOfConfig *config, char *dn)
-{
- memberof_del_dn_data data = {dn, config->groupattr};
-
- return memberof_call_foreach_dn(pb, dn,
- config->groupattr, memberof_del_dn_type_callback, &data);
-}
-
-int memberof_del_dn_type_callback(Slapi_Entry *e, void *callback_data)
-{
- int rc = 0;
- LDAPMod mod;
- LDAPMod *mods[2];
- char *val[2];
- Slapi_PBlock *mod_pb = 0;
-
- mod_pb = slapi_pblock_new();
-
- mods[0] = &mod;
- mods[1] = 0;
-
- val[0] = ((memberof_del_dn_data *)callback_data)->dn;
- val[1] = 0;
-
- mod.mod_op = LDAP_MOD_DELETE;
- mod.mod_type = ((memberof_del_dn_data *)callback_data)->type;
- mod.mod_values = val;
-
- slapi_modify_internal_set_pb(
- mod_pb, slapi_entry_get_dn(e),
- mods, 0, 0,
- memberof_get_plugin_id(), 0);
-
- slapi_modify_internal_pb(mod_pb);
-
- slapi_pblock_get(mod_pb,
- SLAPI_PLUGIN_INTOP_RESULT,
- &rc);
-
- slapi_pblock_destroy(mod_pb);
-
- return rc;
-}
-
-/*
- * Does a callback search of "type=dn" under the db suffix that "dn" is in.
- * If "dn" is a user, you'd want "type" to be "member". If "dn" is a group,
- * you could want type to be either "member" or "memberOf" depending on the
- * case.
- */
-int memberof_call_foreach_dn(Slapi_PBlock *pb, char *dn,
- char *type, plugin_search_entry_callback callback, void *callback_data)
-{
- int rc = 0;
- Slapi_PBlock *search_pb = slapi_pblock_new();
- Slapi_Backend *be = 0;
- Slapi_DN *sdn = 0;
- Slapi_DN *base_sdn = 0;
- char *filter_str = 0;
-
- /* get the base dn for the backend we are in
- (we don't support having members and groups in
- different backends - issues with offline / read only backends)
- */
- sdn = slapi_sdn_new_dn_byref(dn);
- be = slapi_be_select(sdn);
- if(be)
- {
- base_sdn = (Slapi_DN*)slapi_be_getsuffix(be,0);
- }
-
- if(base_sdn)
- {
- filter_str = slapi_ch_smprintf("(%s=%s)", type, dn);
- }
-
- if(filter_str)
- {
- slapi_search_internal_set_pb(search_pb, slapi_sdn_get_dn(base_sdn),
- LDAP_SCOPE_SUBTREE, filter_str, 0, 0,
- 0, 0,
- memberof_get_plugin_id(),
- 0);
-
- slapi_search_internal_callback_pb(search_pb,
- callback_data,
- 0, callback,
- 0);
- }
-
- slapi_sdn_free(&sdn);
- slapi_pblock_destroy(search_pb);
- slapi_ch_free_string(&filter_str);
- return rc;
-}
-
-/*
- * memberof_postop_modrdn()
- *
- * All entries with a memberOf attribute that contains the old group DN get retrieved
- * and have the old group DN deleted and the new group DN added to their memberOf attribute
- */
-int memberof_postop_modrdn(Slapi_PBlock *pb)
-{
- int ret = 0;
-
- slapi_log_error( SLAPI_LOG_TRACE, MEMBEROF_PLUGIN_SUBSYSTEM,
- "--> memberof_postop_modrdn\n" );
-
- if(memberof_oktodo(pb))
- {
- MemberOfConfig *mainConfig = 0;
- MemberOfConfig configCopy = {0, 0, 0, 0};
- struct slapi_entry *pre_e = NULL;
- struct slapi_entry *post_e = NULL;
- char *pre_dn = 0;
- char *post_dn = 0;
- int interested = 0;
-
- slapi_pblock_get( pb, SLAPI_ENTRY_PRE_OP, &pre_e );
- slapi_pblock_get( pb, SLAPI_ENTRY_POST_OP, &post_e );
-
- if(pre_e && post_e)
- {
- pre_dn = slapi_entry_get_ndn(pre_e);
- post_dn = slapi_entry_get_ndn(post_e);
- }
-
- /* is the entry of interest? */
- memberof_rlock_config();
- mainConfig = memberof_get_config();
- if(pre_dn && post_dn &&
- !slapi_filter_test_simple(post_e, mainConfig->group_filter))
- {
- interested = 1;
- /* copy config so it doesn't change out from under us */
- memberof_copy_config(&configCopy, mainConfig);
- }
- memberof_unlock_config();
-
- if(interested)
- {
- Slapi_Attr *attr = 0;
-
- memberof_lock();
-
- /* get a list of member attributes present in the group
- * entry that is being renamed. */
- if(0 == slapi_entry_attr_find(post_e, configCopy.groupattr, &attr))
- {
- memberof_moddn_attr_list(pb, &configCopy, pre_dn, post_dn, attr);
- }
-
- /* modrdn must change the dns in groups that have
- * this group as a member.
- */
- memberof_replace_dn_from_groups(pb, &configCopy, pre_dn, post_dn);
-
- memberof_unlock();
-
- memberof_free_config(&configCopy);
- }
- }
-
-
- slapi_log_error( SLAPI_LOG_TRACE, MEMBEROF_PLUGIN_SUBSYSTEM,
- "<-- memberof_postop_modrdn\n" );
- return ret;
-}
-
-typedef struct _replace_dn_data
-{
- char *pre_dn;
- char *post_dn;
- char *type;
-} replace_dn_data;
-
-int memberof_replace_dn_from_groups(Slapi_PBlock *pb, MemberOfConfig *config,
- char *pre_dn, char *post_dn)
-{
- replace_dn_data data = {pre_dn, post_dn, config->groupattr};
-
- return memberof_call_foreach_dn(pb, pre_dn, config->groupattr,
- memberof_replace_dn_type_callback, &data);
-}
-
-
-int memberof_replace_dn_type_callback(Slapi_Entry *e, void *callback_data)
-{
- int rc = 0;
- LDAPMod delmod;
- LDAPMod addmod;
- LDAPMod *mods[3];
- char *delval[2];
- char *addval[2];
- Slapi_PBlock *mod_pb = 0;
-
- mod_pb = slapi_pblock_new();
-
- mods[0] = &delmod;
- mods[1] = &addmod;
- mods[2] = 0;
-
- delval[0] = ((replace_dn_data *)callback_data)->pre_dn;
- delval[1] = 0;
-
- delmod.mod_op = LDAP_MOD_DELETE;
- delmod.mod_type = ((replace_dn_data *)callback_data)->type;
- delmod.mod_values = delval;
-
- addval[0] = ((replace_dn_data *)callback_data)->post_dn;
- addval[1] = 0;
-
- addmod.mod_op = LDAP_MOD_ADD;
- addmod.mod_type = ((replace_dn_data *)callback_data)->type;
- addmod.mod_values = addval;
-
- slapi_modify_internal_set_pb(
- mod_pb, slapi_entry_get_dn(e),
- mods, 0, 0,
- memberof_get_plugin_id(), 0);
-
- slapi_modify_internal_pb(mod_pb);
-
- slapi_pblock_get(mod_pb,
- SLAPI_PLUGIN_INTOP_RESULT,
- &rc);
-
- slapi_pblock_destroy(mod_pb);
-
- return rc;
-}
-
-/*
- * memberof_postop_modify()
- *
- * Added members are retrieved and have the group DN added to their memberOf attribute
- * Deleted members are retrieved and have the group DN deleted from their memberOf attribute
- * On replace of the membership attribute values:
- * 1. Sort old and new values
- * 2. Iterate through both lists at same time
- * 3. Any value not in old list but in new list - add group DN to memberOf attribute
- * 4. Any value in old list but not in new list - remove group DN from memberOf attribute
- *
- * Note: this will suck for large groups but nonetheless is optimal (it's linear) given
- * current restrictions i.e. originally adding members in sorted order would allow
- * us to sort one list only (the new one) but that is under server control, not this plugin
- */
-int memberof_postop_modify(Slapi_PBlock *pb)
-{
- int ret = 0;
- char *dn = 0;
- Slapi_Mods *smods = 0;
- Slapi_Mod *smod = 0;
- LDAPMod **mods;
- Slapi_Mod *next_mod = 0;
-
- slapi_log_error( SLAPI_LOG_TRACE, MEMBEROF_PLUGIN_SUBSYSTEM,
- "--> memberof_postop_modify\n" );
-
- if(memberof_oktodo(pb) &&
- (dn = memberof_getdn(pb)))
- {
- int config_copied = 0;
- MemberOfConfig *mainConfig = 0;
- MemberOfConfig configCopy = {0, 0, 0, 0};
-
- /* get the mod set */
- slapi_pblock_get(pb, SLAPI_MODIFY_MODS, &mods);
- smods = slapi_mods_new();
- slapi_mods_init_byref(smods, mods);
-
- next_mod = slapi_mod_new();
- smod = slapi_mods_get_first_smod(smods, next_mod);
- while(smod)
- {
- int interested = 0;
- char *type = (char *)slapi_mod_get_type(smod);
-
- /* We only want to copy the config if we encounter an
- * operation that we need to act on. We also want to
- * only copy the config the first time it's needed so
- * it remains the same for all mods in the operation,
- * despite any config changes that may be made. */
- if (!config_copied)
- {
- memberof_rlock_config();
- mainConfig = memberof_get_config();
-
- if(slapi_attr_types_equivalent(type, mainConfig->groupattr))
- {
- interested = 1;
- /* copy config so it doesn't change out from under us */
- memberof_copy_config(&configCopy, mainConfig);
- config_copied = 1;
- }
-
- memberof_unlock_config();
- } else {
- if(slapi_attr_types_equivalent(type, configCopy.groupattr))
- {
- interested = 1;
- }
- }
-
- if(interested)
- {
- int op = slapi_mod_get_operation(smod);
-
- memberof_lock();
-
- /* the modify op decides the function */
- switch(op & ~LDAP_MOD_BVALUES)
- {
- case LDAP_MOD_ADD:
- {
- /* add group DN to targets */
- memberof_add_smod_list(pb, &configCopy, dn, smod);
- break;
- }
-
- case LDAP_MOD_DELETE:
- {
- /* If there are no values in the smod, we should
- * just do a replace instead. The user is just
- * trying to delete all members from this group
- * entry, which the replace code deals with. */
- if (slapi_mod_get_num_values(smod) == 0)
- {
- memberof_replace_list(pb, &configCopy, dn);
- }
- else
- {
- /* remove group DN from target values in smod*/
- memberof_del_smod_list(pb, &configCopy, dn, smod);
- }
- break;
- }
-
- case LDAP_MOD_REPLACE:
- {
- /* replace current values */
- memberof_replace_list(pb, &configCopy, dn);
- break;
- }
-
- default:
- {
- slapi_log_error(
- SLAPI_LOG_PLUGIN,
- MEMBEROF_PLUGIN_SUBSYSTEM,
- "memberof_postop_modify: unknown mod type\n" );
- break;
- }
- }
-
- memberof_unlock();
- }
-
- slapi_mod_done(next_mod);
- smod = slapi_mods_get_next_smod(smods, next_mod);
- }
-
- if (config_copied)
- {
- memberof_free_config(&configCopy);
- }
-
- slapi_mod_free(&next_mod);
- slapi_mods_free(&smods);
- }
-
- slapi_log_error( SLAPI_LOG_TRACE, MEMBEROF_PLUGIN_SUBSYSTEM,
- "<-- memberof_postop_modify\n" );
- return ret;
-}
-
-
-/*
- * memberof_postop_add()
- *
- * All members in the membership attribute of the new entry get retrieved
- * and have the group DN added to their memberOf attribute
- */
-int memberof_postop_add(Slapi_PBlock *pb)
-{
- int ret = 0;
- int interested = 0;
- char *dn = 0;
-
- slapi_log_error( SLAPI_LOG_TRACE, MEMBEROF_PLUGIN_SUBSYSTEM,
- "--> memberof_postop_add\n" );
-
- if(memberof_oktodo(pb) && (dn = memberof_getdn(pb)))
- {
- MemberOfConfig *mainConfig = 0;
- MemberOfConfig configCopy = {0, 0, 0, 0};
- struct slapi_entry *e = NULL;
-
- slapi_pblock_get( pb, SLAPI_ENTRY_POST_OP, &e );
-
-
- /* is the entry of interest? */
- memberof_rlock_config();
- mainConfig = memberof_get_config();
- if(e && !slapi_filter_test_simple(e, mainConfig->group_filter))
- {
- interested = 1;
- /* copy config so it doesn't change out from under us */
- memberof_copy_config(&configCopy, mainConfig);
- }
- memberof_unlock_config();
-
- if(interested)
- {
- Slapi_Attr *attr = 0;
-
- memberof_lock();
-
- if(0 == slapi_entry_attr_find(e, configCopy.groupattr, &attr))
- {
- memberof_add_attr_list(pb, &configCopy, dn, attr);
- }
-
- memberof_unlock();
-
- memberof_free_config(&configCopy);
- }
- }
-
- slapi_log_error( SLAPI_LOG_TRACE, MEMBEROF_PLUGIN_SUBSYSTEM,
- "<-- memberof_postop_add\n" );
- return ret;
-}
-
-/*** Support functions ***/
-
-/*
- * memberof_oktodo()
- *
- * Check that the op succeeded
- * Note: we also respond to replicated ops so we don't test for that
- * this does require that the memberOf attribute not be replicated
- * and this means that memberof is consistent with local state
- * not the network system state
- *
- */
-int memberof_oktodo(Slapi_PBlock *pb)
-{
- int ret = 1;
- int oprc = 0;
-
- slapi_log_error( SLAPI_LOG_TRACE, MEMBEROF_PLUGIN_SUBSYSTEM,
- "--> memberof_postop_oktodo\n" );
-
- if(slapi_pblock_get(pb, SLAPI_PLUGIN_OPRETURN, &oprc) != 0)
- {
- slapi_log_error( SLAPI_LOG_FATAL, MEMBEROF_PLUGIN_SUBSYSTEM,
- "memberof_postop_oktodo: could not get parameters\n" );
- ret = -1;
- }
-
- /* this plugin should only execute if the operation succeeded
- */
- if(oprc != 0)
- {
- ret = 0;
- }
-
- slapi_log_error( SLAPI_LOG_TRACE, MEMBEROF_PLUGIN_SUBSYSTEM,
- "<-- memberof_postop_oktodo\n" );
-
- return ret;
-}
-
-/*
- * memberof_getdn()
- *
- * Get dn of target entry
- *
- */
-char *memberof_getdn(Slapi_PBlock *pb)
-{
- char *dn = 0;
-
- slapi_pblock_get(pb, SLAPI_TARGET_DN, &dn);
-
- return dn;
-}
-
-/*
- * memberof_modop_one()
- *
- * Perform op on memberof attribute of op_to using op_this as the value
- * However, if op_to happens to be a group, we must arrange for the group
- * members to have the mod performed on them instead, and we must take
- * care to not recurse when we have visted a group before
- *
- * Also, we must not delete entries that are a member of the group
- */
-int memberof_modop_one(Slapi_PBlock *pb, MemberOfConfig *config, int mod_op,
- char *op_this, char *op_to)
-{
- return memberof_modop_one_r(pb, config, mod_op, op_this, op_this, op_to, 0);
-}
-
-/* memberof_modop_one_r()
- *
- * recursive function to perform above (most things don't need the replace arg)
- */
-
-int memberof_modop_one_r(Slapi_PBlock *pb, MemberOfConfig *config, int mod_op,
- char *group_dn, char *op_this, char *op_to, memberofstringll *stack)
-{
- return memberof_modop_one_replace_r(
- pb, config, mod_op, group_dn, op_this, 0, op_to, stack);
-}
-
-/* memberof_modop_one_replace_r()
- *
- * recursive function to perform above (with added replace arg)
- */
-int memberof_modop_one_replace_r(Slapi_PBlock *pb, MemberOfConfig *config,
- int mod_op, char *group_dn, char *op_this, char *replace_with,
- char *op_to, memberofstringll *stack)
-{
- int rc = 0;
- LDAPMod mod;
- LDAPMod replace_mod;
- LDAPMod *mods[3];
- char *val[2];
- char *replace_val[2];
- Slapi_PBlock *mod_pb = 0;
- char *attrlist[2] = {config->groupattr,0};
- Slapi_DN *op_to_sdn = 0;
- Slapi_Entry *e = 0;
- memberofstringll *ll = 0;
- char *op_str = 0;
- Slapi_Value *to_dn_val = slapi_value_new_string(op_to);
- Slapi_Value *this_dn_val = slapi_value_new_string(op_this);
-
- /* determine if this is a group op or single entry */
- op_to_sdn = slapi_sdn_new_dn_byref(op_to);
- slapi_search_internal_get_entry( op_to_sdn, attrlist,
- &e, memberof_get_plugin_id());
- if(!e)
- {
- /* In the case of a delete, we need to worry about the
- * missing entry being a nested group. There's a small
- * window where another thread may have deleted a nested
- * group that our group_dn entry refers to. This has the
- * potential of us missing some indirect member entries
- * that need to be updated. */
- if(LDAP_MOD_DELETE == mod_op)
- {
- Slapi_PBlock *search_pb = slapi_pblock_new();
- Slapi_DN *base_sdn = 0;
- Slapi_Backend *be = 0;
- char *filter_str = 0;
- int n_entries = 0;
-
- /* We can't tell for sure if the op_to entry is a
- * user or a group since the entry doesn't exist
- * anymore. We can safely ignore the missing entry
- * if no other entries have a memberOf attribute that
- * points to the missing entry. */
- be = slapi_be_select(op_to_sdn);
- if(be)
- {
- base_sdn = (Slapi_DN*)slapi_be_getsuffix(be,0);
- }
-
- if(base_sdn)
- {
- filter_str = slapi_ch_smprintf("(%s=%s)",
- config->memberof_attr, op_to);
- }
-
- if(filter_str)
- {
- slapi_search_internal_set_pb(search_pb, slapi_sdn_get_dn(base_sdn),
- LDAP_SCOPE_SUBTREE, filter_str, 0, 0, 0, 0,
- memberof_get_plugin_id(), 0);
-
- if (slapi_search_internal_pb(search_pb))
- {
- /* get result and log an error */
- int res = 0;
- slapi_pblock_get(search_pb, SLAPI_PLUGIN_INTOP_RESULT, &res);
- slapi_log_error( SLAPI_LOG_FATAL, MEMBEROF_PLUGIN_SUBSYSTEM,
- "memberof_modop_one_replace_r: error searching for members: "
- "%d", res);
- } else {
- slapi_pblock_get(search_pb, SLAPI_NENTRIES, &n_entries);
-
- if(n_entries > 0)
- {
- /* We want to fixup the membership for the
- * entries that referred to the missing group
- * entry. This will fix the references to
- * the missing group as well as the group
- * represented by op_this. */
- memberof_test_membership(pb, config, op_to);
- }
- }
-
- slapi_free_search_results_internal(search_pb);
- slapi_ch_free_string(&filter_str);
- }
-
- slapi_pblock_destroy(search_pb);
- }
-
- goto bail;
- }
-
- if(LDAP_MOD_DELETE == mod_op)
- {
- op_str = "DELETE";
- }
- else if(LDAP_MOD_ADD == mod_op)
- {
- op_str = "ADD";
- }
- else if(LDAP_MOD_REPLACE == mod_op)
- {
- op_str = "REPLACE";
- }
- else
- {
- op_str = "UNKNOWN";
- }
-
- slapi_log_error( SLAPI_LOG_PLUGIN, MEMBEROF_PLUGIN_SUBSYSTEM,
- "memberof_modop_one_replace_r: %s %s in %s\n"
- ,op_str, op_this, op_to);
-
- if(!slapi_filter_test_simple(e, config->group_filter))
- {
- /* group */
- Slapi_Value *ll_dn_val = 0;
- Slapi_Attr *members = 0;
-
- ll = stack;
-
- /* have we been here before? */
- while(ll)
- {
- ll_dn_val = slapi_value_new_string(ll->dn);
-
- if(0 == memberof_compare(config, &ll_dn_val, &to_dn_val))
- {
- slapi_value_free(&ll_dn_val);
-
- /* someone set up infinitely
- recursive groups - bail out */
- slapi_log_error( SLAPI_LOG_PLUGIN,
- MEMBEROF_PLUGIN_SUBSYSTEM,
- "memberof_modop_one_replace_r: group recursion"
- " detected in %s\n"
- ,op_to);
- goto bail;
- }
-
- slapi_value_free(&ll_dn_val);
- ll = ll->next;
- }
-
- /* do op on group */
- slapi_log_error( SLAPI_LOG_PLUGIN,
- MEMBEROF_PLUGIN_SUBSYSTEM,
- "memberof_modop_one_replace_r: descending into group %s\n",
- op_to);
- /* Add the nested group's DN to the stack so we can detect loops later. */
- ll = (memberofstringll*)slapi_ch_malloc(sizeof(memberofstringll));
- ll->dn = op_to;
- ll->next = stack;
-
- slapi_entry_attr_find( e, config->groupattr, &members );
- if(members)
- {
- memberof_mod_attr_list_r(pb, config, mod_op, group_dn, op_this, members, ll);
- }
-
- {
- /* crazyness follows:
- * strict-aliasing doesn't like the required cast
- * to void for slapi_ch_free so we are made to
- * juggle to get a normal thing done
- */
- void *pll = ll;
- slapi_ch_free(&pll);
- ll = 0;
- }
- }
- /* continue with operation */
- {
- /* We want to avoid listing a group as a memberOf itself
- * in case someone set up a circular grouping.
- */
- if (0 == memberof_compare(config, &this_dn_val, &to_dn_val))
- {
- slapi_log_error( SLAPI_LOG_PLUGIN,
- MEMBEROF_PLUGIN_SUBSYSTEM,
- "memberof_modop_one_replace_r: not processing memberOf "
- "operations on self entry: %s\n", this_dn_val);
- goto bail;
- }
-
- /* For add and del modify operations, we just regenerate the
- * memberOf attribute. */
- if(LDAP_MOD_DELETE == mod_op || LDAP_MOD_ADD == mod_op)
- {
- /* find parent groups and replace our member attr */
- memberof_fix_memberof_callback(e, config);
- } else {
- /* single entry - do mod */
- mod_pb = slapi_pblock_new();
-
- mods[0] = &mod;
- if(LDAP_MOD_REPLACE == mod_op)
- {
- mods[1] = &replace_mod;
- mods[2] = 0;
- }
- else
- {
- mods[1] = 0;
- }
-
- val[0] = op_this;
- val[1] = 0;
- mod.mod_op = LDAP_MOD_REPLACE == mod_op?LDAP_MOD_DELETE:mod_op;
- mod.mod_type = config->memberof_attr;
- mod.mod_values = val;
-
- if(LDAP_MOD_REPLACE == mod_op)
- {
- replace_val[0] = replace_with;
- replace_val[1] = 0;
-
- replace_mod.mod_op = LDAP_MOD_ADD;
- replace_mod.mod_type = config->memberof_attr;
- replace_mod.mod_values = replace_val;
- }
-
- slapi_modify_internal_set_pb(
- mod_pb, op_to,
- mods, 0, 0,
- memberof_get_plugin_id(), 0);
-
- slapi_modify_internal_pb(mod_pb);
-
- slapi_pblock_get(mod_pb,
- SLAPI_PLUGIN_INTOP_RESULT,
- &rc);
-
- slapi_pblock_destroy(mod_pb);
- }
- }
-
-bail:
- slapi_sdn_free(&op_to_sdn);
- slapi_value_free(&to_dn_val);
- slapi_value_free(&this_dn_val);
- slapi_entry_free(e);
- return rc;
-}
-
-
-/*
- * memberof_add_one()
- *
- * Add addthis DN to the memberof attribute of addto
- *
- */
-int memberof_add_one(Slapi_PBlock *pb, MemberOfConfig *config, char *addthis, char *addto)
-{
- return memberof_modop_one(pb, config, LDAP_MOD_ADD, addthis, addto);
-}
-
-/*
- * memberof_del_one()
- *
- * Delete delthis DN from the memberof attribute of delfrom
- *
- */
-int memberof_del_one(Slapi_PBlock *pb, MemberOfConfig *config, char *delthis, char *delfrom)
-{
- return memberof_modop_one(pb, config, LDAP_MOD_DELETE, delthis, delfrom);
-}
-
-/*
- * memberof_mod_smod_list()
- *
- * Perform mod for group DN to the memberof attribute of the list of targets
- *
- */
-int memberof_mod_smod_list(Slapi_PBlock *pb, MemberOfConfig *config, int mod,
- char *group_dn, Slapi_Mod *smod)
-{
- int rc = 0;
- struct berval *bv = slapi_mod_get_first_value(smod);
- int last_size = 0;
- char *last_str = 0;
-
- while(bv)
- {
- char *dn_str = 0;
-
- if(last_size > bv->bv_len)
- {
- dn_str = last_str;
- }
- else
- {
- int the_size = (bv->bv_len * 2) + 1;
-
- if(last_str)
- slapi_ch_free_string(&last_str);
-
- dn_str = (char*)slapi_ch_malloc(the_size);
-
- last_str = dn_str;
- last_size = the_size;
- }
-
- memset(dn_str, 0, last_size);
-
- strncpy(dn_str, bv->bv_val, (size_t)bv->bv_len);
-
- memberof_modop_one(pb, config, mod, group_dn, dn_str);
-
- bv = slapi_mod_get_next_value(smod);
- }
-
- if(last_str)
- slapi_ch_free_string(&last_str);
-
- return rc;
-}
-
-/*
- * memberof_add_smod_list()
- *
- * Add group DN to the memberof attribute of the list of targets
- *
- */
-int memberof_add_smod_list(Slapi_PBlock *pb, MemberOfConfig *config,
- char *groupdn, Slapi_Mod *smod)
-{
- return memberof_mod_smod_list(pb, config, LDAP_MOD_ADD, groupdn, smod);
-}
-
-
-/*
- * memberof_del_smod_list()
- *
- * Remove group DN from the memberof attribute of the list of targets
- *
- */
-int memberof_del_smod_list(Slapi_PBlock *pb, MemberOfConfig *config,
- char *groupdn, Slapi_Mod *smod)
-{
- return memberof_mod_smod_list(pb, config, LDAP_MOD_DELETE, groupdn, smod);
-}
-
-/**
- * Plugin identity mgmt
- */
-void memberof_set_plugin_id(void * plugin_id)
-{
- _PluginID=plugin_id;
-}
-
-void * memberof_get_plugin_id()
-{
- return _PluginID;
-}
-
-
-/*
- * memberof_mod_attr_list()
- *
- * Perform mod for group DN to the memberof attribute of the list of targets
- *
- */
-int memberof_mod_attr_list(Slapi_PBlock *pb, MemberOfConfig *config, int mod,
- char *group_dn, Slapi_Attr *attr)
-{
- return memberof_mod_attr_list_r(pb, config, mod, group_dn, group_dn, attr, 0);
-}
-
-int memberof_mod_attr_list_r(Slapi_PBlock *pb, MemberOfConfig *config, int mod,
- char *group_dn, char *op_this, Slapi_Attr *attr, memberofstringll *stack)
-{
- int rc = 0;
- Slapi_Value *val = 0;
- Slapi_Value *op_this_val = 0;
- int last_size = 0;
- char *last_str = 0;
- int hint = slapi_attr_first_value(attr, &val);
-
- op_this_val = slapi_value_new_string(op_this);
-
- while(val)
- {
- char *dn_str = 0;
- struct berval *bv = 0;
-
- /* We don't want to process a memberOf operation on ourselves. */
- if(0 != memberof_compare(config, &val, &op_this_val))
- {
- bv = (struct berval *)slapi_value_get_berval(val);
-
- if(last_size > bv->bv_len)
- {
- dn_str = last_str;
- }
- else
- {
- int the_size = (bv->bv_len * 2) + 1;
-
- if(last_str)
- slapi_ch_free_string(&last_str);
-
- dn_str = (char*)slapi_ch_malloc(the_size);
-
- last_str = dn_str;
- last_size = the_size;
- }
-
- memset(dn_str, 0, last_size);
-
- strncpy(dn_str, bv->bv_val, (size_t)bv->bv_len);
-
- /* If we're doing a replace (as we would in the MODRDN case), we need
- * to specify the new group DN value */
- if(mod == LDAP_MOD_REPLACE)
- {
- memberof_modop_one_replace_r(pb, config, mod, group_dn, op_this,
- group_dn, dn_str, stack);
- }
- else
- {
- memberof_modop_one_r(pb, config, mod, group_dn, op_this, dn_str, stack);
- }
- }
-
- hint = slapi_attr_next_value(attr, hint, &val);
- }
-
- slapi_value_free(&op_this_val);
-
- if(last_str)
- slapi_ch_free_string(&last_str);
-
- return rc;
-}
-
-/*
- * memberof_add_attr_list()
- *
- * Add group DN to the memberof attribute of the list of targets
- *
- */
-int memberof_add_attr_list(Slapi_PBlock *pb, MemberOfConfig *config, char *groupdn,
- Slapi_Attr *attr)
-{
- return memberof_mod_attr_list(pb, config, LDAP_MOD_ADD, groupdn, attr);
-}
-
-/*
- * memberof_del_attr_list()
- *
- * Remove group DN from the memberof attribute of the list of targets
- *
- */
-int memberof_del_attr_list(Slapi_PBlock *pb, MemberOfConfig *config, char *groupdn,
- Slapi_Attr *attr)
-{
- return memberof_mod_attr_list(pb, config, LDAP_MOD_DELETE, groupdn, attr);
-}
-
-/*
- * memberof_moddn_attr_list()
- *
- * Perform mod for group DN to the memberof attribute of the list of targets
- *
- */
-int memberof_moddn_attr_list(Slapi_PBlock *pb, MemberOfConfig *config,
- char *pre_dn, char *post_dn, Slapi_Attr *attr)
-{
- int rc = 0;
- Slapi_Value *val = 0;
- int last_size = 0;
- char *last_str = 0;
- int hint = slapi_attr_first_value(attr, &val);
-
- while(val)
- {
- char *dn_str = 0;
- struct berval *bv = (struct berval *)slapi_value_get_berval(val);
-
- if(last_size > bv->bv_len)
- {
- dn_str = last_str;
- }
- else
- {
- int the_size = (bv->bv_len * 2) + 1;
-
- if(last_str)
- slapi_ch_free_string(&last_str);
-
- dn_str = (char*)slapi_ch_malloc(the_size);
-
- last_str = dn_str;
- last_size = the_size;
- }
-
- memset(dn_str, 0, last_size);
-
- strncpy(dn_str, bv->bv_val, (size_t)bv->bv_len);
-
- memberof_modop_one_replace_r(pb, config, LDAP_MOD_REPLACE,
- post_dn, pre_dn, post_dn, dn_str, 0);
-
- hint = slapi_attr_next_value(attr, hint, &val);
- }
-
- if(last_str)
- slapi_ch_free_string(&last_str);
-
- return rc;
-}
-
-/* memberof_get_groups()
- *
- * Gets a list of all groups that an entry is a member of.
- * This is done by looking only at member attribute values.
- * A Slapi_ValueSet* is returned. It is up to the caller to
- * free it.
- */
-Slapi_ValueSet *memberof_get_groups(MemberOfConfig *config, char *memberdn)
-{
- Slapi_Value *memberdn_val = slapi_value_new_string(memberdn);
- Slapi_ValueSet *groupvals = slapi_valueset_new();
- memberof_get_groups_data data = {config, memberdn_val, &groupvals};
-
- memberof_get_groups_r(config, memberdn, &data);
-
- slapi_value_free(&memberdn_val);
-
- return groupvals;
-}
-
-int memberof_get_groups_r(MemberOfConfig *config, char *memberdn, memberof_get_groups_data *data)
-{
- /* Search for member=<memberdn>
- * For each match, add it to the list, recurse and do same search */
- return memberof_call_foreach_dn(NULL, memberdn, config->groupattr,
- memberof_get_groups_callback, data);
-}
-
-/* memberof_get_groups_callback()
- *
- * Callback to perform work of memberof_get_groups()
- */
-int memberof_get_groups_callback(Slapi_Entry *e, void *callback_data)
-{
- char *group_dn = slapi_entry_get_dn(e);
- Slapi_Value *group_dn_val = 0;
- Slapi_ValueSet *groupvals = *((memberof_get_groups_data*)callback_data)->groupvals;
-
- /* get the DN of the group */
- group_dn_val = slapi_value_new_string(group_dn);
-
- /* check if e is the same as our original member entry */
- if (0 == memberof_compare(((memberof_get_groups_data*)callback_data)->config,
- &((memberof_get_groups_data*)callback_data)->memberdn_val, &group_dn_val))
- {
- /* A recursive group caused us to find our original
- * entry we passed to memberof_get_groups(). We just
- * skip processing this entry. */
- slapi_log_error( SLAPI_LOG_PLUGIN, MEMBEROF_PLUGIN_SUBSYSTEM,
- "memberof_get_groups_callback: group recursion"
- " detected in %s\n" ,group_dn);
- slapi_value_free(&group_dn_val);
- goto bail;
-
- }
-
- /* have we been here before? */
- if (groupvals &&
- slapi_valueset_find(((memberof_get_groups_data*)callback_data)->config->group_slapiattr,
- groupvals, group_dn_val))
- {
- /* we either hit a recursive grouping, or an entry is
- * a member of a group through multiple paths. Either
- * way, we can just skip processing this entry since we've
- * already gone through this part of the grouping hierarchy. */
- slapi_log_error( SLAPI_LOG_PLUGIN, MEMBEROF_PLUGIN_SUBSYSTEM,
- "memberof_get_groups_callback: possible group recursion"
- " detected in %s\n" ,group_dn);
- slapi_value_free(&group_dn_val);
- goto bail;
- }
-
- /* Push group_dn_val into the valueset. This memory is now owned
- * by the valueset. */
- slapi_valueset_add_value_ext(groupvals, group_dn_val, SLAPI_VALUE_FLAG_PASSIN);
-
- /* now recurse to find parent groups of e */
- memberof_get_groups_r(((memberof_get_groups_data*)callback_data)->config,
- group_dn, callback_data);
-
- bail:
- return 0;
-}
-
-/* memberof_is_direct_member()
- *
- * tests for direct membership of memberdn in group groupdn
- * returns non-zero when true, zero otherwise
- */
-int memberof_is_direct_member(MemberOfConfig *config, Slapi_Value *groupdn,
- Slapi_Value *memberdn)
-{
- int rc = 0;
- Slapi_DN *sdn = 0;
- char *attrlist[2] = {config->groupattr,0};
- Slapi_Entry *group_e = 0;
- Slapi_Attr *attr = 0;
-
- sdn = slapi_sdn_new_dn_byref(slapi_value_get_string(groupdn));
-
- slapi_search_internal_get_entry(sdn, attrlist,
- &group_e, memberof_get_plugin_id());
-
- if(group_e)
- {
- slapi_entry_attr_find(group_e, config->groupattr, &attr );
- if(attr)
- {
- rc = 0 == slapi_attr_value_find(
- attr, slapi_value_get_berval(memberdn));
- }
- slapi_entry_free(group_e);
- }
-
- slapi_sdn_free(&sdn);
- return rc;
-}
-
-/* memberof_test_membership()
- *
- * Finds all entries who are a "memberOf" the group
- * represented by "group_dn". For each matching entry, we
- * call memberof_test_membership_callback().
- *
- * for each attribute in the memberof attribute
- * determine if the entry is still a member.
- *
- * test each for direct membership
- * move groups entry is memberof to member group
- * test remaining groups for membership in member groups
- * iterate until a pass fails to move a group over to member groups
- * remaining groups should be deleted
- */
-int memberof_test_membership(Slapi_PBlock *pb, MemberOfConfig *config, char *group_dn)
-{
- return memberof_call_foreach_dn(pb, group_dn, config->memberof_attr,
- memberof_test_membership_callback , config);
-}
-
-/*
- * memberof_test_membership_callback()
- *
- * A callback function to do the work of memberof_test_membership().
- * Note that this not only tests membership, but updates the memberOf
- * attributes in the entry to be correct.
- */
-int memberof_test_membership_callback(Slapi_Entry *e, void *callback_data)
-{
- int rc = 0;
- Slapi_Attr *attr = 0;
- int total = 0;
- Slapi_Value **member_array = 0;
- Slapi_Value **candidate_array = 0;
- Slapi_Value *entry_dn = 0;
- MemberOfConfig *config = (MemberOfConfig *)callback_data;
-
- entry_dn = slapi_value_new_string(slapi_entry_get_dn(e));
-
- if(0 == entry_dn)
- {
- goto bail;
- }
-
- /* divide groups into member and non-member lists */
- slapi_entry_attr_find(e, config->memberof_attr, &attr );
- if(attr)
- {
- slapi_attr_get_numvalues( attr, &total);
- if(total)
- {
- Slapi_Value *val = 0;
- int hint = 0;
- int c_index = 0;
- int m_index = 0;
- int member_found = 1;
- int outer_index = 0;
-
- candidate_array =
- (Slapi_Value**)
- slapi_ch_malloc(sizeof(Slapi_Value*)*total);
- memset(candidate_array, 0, sizeof(Slapi_Value*)*total);
- member_array =
- (Slapi_Value**)
- slapi_ch_malloc(sizeof(Slapi_Value*)*total);
- memset(member_array, 0, sizeof(Slapi_Value*)*total);
-
- hint = slapi_attr_first_value(attr, &val);
-
- while(val)
- {
- /* test for direct membership */
- if(memberof_is_direct_member(config, val, entry_dn))
- {
- /* it is a member */
- member_array[m_index] = val;
- m_index++;
- }
- else
- {
- /* not a member, still a candidate */
- candidate_array[c_index] = val;
- c_index++;
- }
-
- hint = slapi_attr_next_value(attr, hint, &val);
- }
-
- /* now iterate over members testing for membership
- in candidate groups and moving candidates to members
- when successful, quit when a full iteration adds no
- new members
- */
- while(member_found)
- {
- member_found = 0;
-
- /* For each group that this entry is a verified member of, see if
- * any of the candidate groups are members. If they are, add them
- * to the list of verified groups that this entry is a member of.
- */
- while(outer_index < m_index)
- {
- int inner_index = 0;
-
- while(inner_index < c_index)
- {
- /* Check for a special value in this position
- * that indicates that the candidate was moved
- * to the member array. */
- if((void*)1 ==
- candidate_array[inner_index])
- {
- /* was moved, skip */
- inner_index++;
- continue;
- }
-
- if(memberof_is_direct_member(
- config,
- candidate_array[inner_index],
- member_array[outer_index]))
- {
- member_array[m_index] =
- candidate_array
- [inner_index];
- m_index++;
-
- candidate_array[inner_index] =
- (void*)1;
-
- member_found = 1;
- }
-
- inner_index++;
- }
-
- outer_index++;
- }
- }
-
- /* here we are left only with values to delete
- from the memberof attribute in the candidate list
- */
- outer_index = 0;
- while(outer_index < c_index)
- {
- /* Check for a special value in this position
- * that indicates that the candidate was moved
- * to the member array. */
- if((void*)1 == candidate_array[outer_index])
- {
- /* item moved, skip */
- outer_index++;
- continue;
- }
-
- memberof_del_one(
- 0, config,
- (char*)slapi_value_get_string(
- candidate_array[outer_index]),
- (char*)slapi_value_get_string(entry_dn));
-
- outer_index++;
- }
- {
- /* crazyness follows:
- * strict-aliasing doesn't like the required cast
- * to void for slapi_ch_free so we are made to
- * juggle to get a normal thing done
- */
- void *pmember_array = member_array;
- void *pcandidate_array = candidate_array;
- slapi_ch_free(&pcandidate_array);
- slapi_ch_free(&pmember_array);
- candidate_array = 0;
- member_array = 0;
- }
- }
- }
-
-bail:
- slapi_value_free(&entry_dn);
-
- return rc;
-}
-
-/*
- * memberof_replace_list()
- *
- * Perform replace the group DN list in the memberof attribute of the list of targets
- *
- */
-int memberof_replace_list(Slapi_PBlock *pb, MemberOfConfig *config, char *group_dn)
-{
- struct slapi_entry *pre_e = NULL;
- struct slapi_entry *post_e = NULL;
- Slapi_Attr *pre_attr = 0;
- Slapi_Attr *post_attr = 0;
-
- slapi_pblock_get( pb, SLAPI_ENTRY_PRE_OP, &pre_e );
- slapi_pblock_get( pb, SLAPI_ENTRY_POST_OP, &post_e );
-
- if(pre_e && post_e)
- {
- slapi_entry_attr_find( pre_e, config->groupattr, &pre_attr );
- slapi_entry_attr_find( post_e, config->groupattr, &post_attr );
- }
-
- if(pre_attr || post_attr)
- {
- int pre_total = 0;
- int post_total = 0;
- Slapi_Value **pre_array = 0;
- Slapi_Value **post_array = 0;
- int pre_index = 0;
- int post_index = 0;
-
- /* create arrays of values */
- if(pre_attr)
- {
- slapi_attr_get_numvalues( pre_attr, &pre_total);
- }
-
- if(post_attr)
- {
- slapi_attr_get_numvalues( post_attr, &post_total);
- }
-
- /* Stash a plugin global pointer here and have memberof_qsort_compare
- * use it. We have to do this because we use memberof_qsort_compare
- * as the comparator function for qsort, which requires the function
- * to only take two void* args. This is thread-safe since we only
- * store and use the pointer while holding the memberOf operation
- * lock. */
- qsortConfig = config;
-
- if(pre_total)
- {
- pre_array =
- (Slapi_Value**)
- slapi_ch_malloc(sizeof(Slapi_Value*)*pre_total);
- memberof_load_array(pre_array, pre_attr);
- qsort(
- pre_array,
- pre_total,
- sizeof(Slapi_Value*),
- memberof_qsort_compare);
- }
-
- if(post_total)
- {
- post_array =
- (Slapi_Value**)
- slapi_ch_malloc(sizeof(Slapi_Value*)*post_total);
- memberof_load_array(post_array, post_attr);
- qsort(
- post_array,
- post_total,
- sizeof(Slapi_Value*),
- memberof_qsort_compare);
- }
-
- qsortConfig = 0;
-
-
- /* work through arrays, following these rules:
- in pre, in post, do nothing
- in pre, not in post, delete from entry
- not in pre, in post, add to entry
- */
- while(pre_index < pre_total || post_index < post_total)
- {
- if(pre_index == pre_total)
- {
- /* add the rest of post */
- memberof_add_one(
- pb, config,
- group_dn,
- (char*)slapi_value_get_string(
- post_array[post_index]));
-
- post_index++;
- }
- else if(post_index == post_total)
- {
- /* delete the rest of pre */
- memberof_del_one(
- pb, config,
- group_dn,
- (char*)slapi_value_get_string(
- pre_array[pre_index]));
-
- pre_index++;
- }
- else
- {
- /* decide what to do */
- int cmp = memberof_compare(
- config,
- &(pre_array[pre_index]),
- &(post_array[post_index]));
-
- if(cmp < 0)
- {
- /* delete pre array */
- memberof_del_one(
- pb, config,
- group_dn,
- (char*)slapi_value_get_string(
- pre_array[pre_index]));
-
- pre_index++;
- }
- else if(cmp > 0)
- {
- /* add post array */
- memberof_add_one(
- pb, config,
- group_dn,
- (char*)slapi_value_get_string(
- post_array[post_index]));
-
- post_index++;
- }
- else
- {
- /* do nothing, advance */
- pre_index++;
- post_index++;
- }
- }
- }
- slapi_ch_free((void **)&pre_array);
- slapi_ch_free((void **)&post_array);
- }
-
- return 0;
-}
-
-/* memberof_load_array()
- *
- * put attribute values in array structure
- */
-void memberof_load_array(Slapi_Value **array, Slapi_Attr *attr)
-{
- Slapi_Value *val = 0;
- int hint = slapi_attr_first_value(attr, &val);
-
- while(val)
- {
- *array = val;
- array++;
- hint = slapi_attr_next_value(attr, hint, &val);
- }
-}
-
-/* memberof_compare()
- *
- * compare two attr values
- */
-int memberof_compare(MemberOfConfig *config, const void *a, const void *b)
-{
- Slapi_Value *val1 = *((Slapi_Value **)a);
- Slapi_Value *val2 = *((Slapi_Value **)b);
-
- return slapi_attr_value_cmp(
- config->group_slapiattr,
- slapi_value_get_berval(val1),
- slapi_value_get_berval(val2));
-}
-
-/* memberof_qsort_compare()
- *
- * This is a version of memberof_compare that uses a plugin
- * global copy of the config. We'd prefer to pass in a copy
- * of config that is local to the running thread, but we can't
- * do this since qsort is using us as a comparator function.
- * We should only use this function when using qsort, and only
- * when the memberOf lock is acquired.
- */
-int memberof_qsort_compare(const void *a, const void *b)
-{
- Slapi_Value *val1 = *((Slapi_Value **)a);
- Slapi_Value *val2 = *((Slapi_Value **)b);
-
- return slapi_attr_value_cmp(
- qsortConfig->group_slapiattr,
- slapi_value_get_berval(val1),
- slapi_value_get_berval(val2));
-}
-
-void memberof_lock()
-{
- slapi_lock_mutex(memberof_operation_lock);
-}
-
-void memberof_unlock()
-{
- slapi_unlock_mutex(memberof_operation_lock);
-}
-
-typedef struct _task_data
-{
- char *dn;
- char *filter_str;
-} task_data;
-
-void memberof_fixup_task_thread(void *arg)
-{
- MemberOfConfig configCopy = {0, 0, 0, 0};
- Slapi_Task *task = (Slapi_Task *)arg;
- task_data *td = NULL;
- int rc = 0;
-
- /* Fetch our task data from the task */
- td = (task_data *)slapi_task_get_data(task);
-
- slapi_task_begin(task, 1);
- slapi_task_log_notice(task, "Memberof task starts (arg: %s) ...\n",
- td->filter_str);
-
- /* We need to get the config lock first. Trying to get the
- * config lock after we already hold the op lock can cause
- * a deadlock. */
- memberof_rlock_config();
- /* copy config so it doesn't change out from under us */
- memberof_copy_config(&configCopy, memberof_get_config());
- memberof_unlock_config();
-
- /* get the memberOf operation lock */
- memberof_lock();
-
- /* do real work */
- rc = memberof_fix_memberof(&configCopy, td->dn, td->filter_str);
-
- /* release the memberOf operation lock */
- memberof_unlock();
-
- memberof_free_config(&configCopy);
-
- slapi_task_log_notice(task, "Memberof task finished.");
- slapi_task_log_status(task, "Memberof task finished.");
- slapi_task_inc_progress(task);
-
- /* this will queue the destruction of the task */
- slapi_task_finish(task, rc);
-}
-
-/* extract a single value from the entry (as a string) -- if it's not in the
- * entry, the default will be returned (which can be NULL).
- * you do not need to free anything returned by this.
- */
-const char *fetch_attr(Slapi_Entry *e, const char *attrname,
- const char *default_val)
-{
- Slapi_Attr *attr;
- Slapi_Value *val = NULL;
-
- if (slapi_entry_attr_find(e, attrname, &attr) != 0)
- return default_val;
- slapi_attr_first_value(attr, &val);
- return slapi_value_get_string(val);
-}
-
-int memberof_task_add(Slapi_PBlock *pb, Slapi_Entry *e,
- Slapi_Entry *eAfter, int *returncode, char *returntext,
- void *arg)
-{
- PRThread *thread = NULL;
- int rv = SLAPI_DSE_CALLBACK_OK;
- task_data *mytaskdata = NULL;
- Slapi_Task *task = NULL;
- const char *filter;
- const char *dn = 0;
-
- *returncode = LDAP_SUCCESS;
- /* get arg(s) */
- if ((dn = fetch_attr(e, "basedn", 0)) == NULL)
- {
- *returncode = LDAP_OBJECT_CLASS_VIOLATION;
- rv = SLAPI_DSE_CALLBACK_ERROR;
- goto out;
- }
-
- if ((filter = fetch_attr(e, "filter", "(objectclass=inetuser)")) == NULL)
- {
- *returncode = LDAP_OBJECT_CLASS_VIOLATION;
- rv = SLAPI_DSE_CALLBACK_ERROR;
- goto out;
- }
-
- /* setup our task data */
- mytaskdata = (task_data*)slapi_ch_malloc(sizeof(task_data));
- if (mytaskdata == NULL)
- {
- *returncode = LDAP_OPERATIONS_ERROR;
- rv = SLAPI_DSE_CALLBACK_ERROR;
- goto out;
- }
- mytaskdata->dn = slapi_ch_strdup(dn);
- mytaskdata->filter_str = slapi_ch_strdup(filter);
-
- /* allocate new task now */
- task = slapi_new_task(slapi_entry_get_ndn(e));
-
- /* register our destructor for cleaning up our private data */
- slapi_task_set_destructor_fn(task, memberof_task_destructor);
-
- /* Stash a pointer to our data in the task */
- slapi_task_set_data(task, mytaskdata);
-
- /* start the sample task as a separate thread */
- thread = PR_CreateThread(PR_USER_THREAD, memberof_fixup_task_thread,
- (void *)task, PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD,
- PR_UNJOINABLE_THREAD, SLAPD_DEFAULT_THREAD_STACKSIZE);
- if (thread == NULL)
- {
- slapi_log_error( SLAPI_LOG_FATAL, MEMBEROF_PLUGIN_SUBSYSTEM,
- "unable to create task thread!\n");
- *returncode = LDAP_OPERATIONS_ERROR;
- rv = SLAPI_DSE_CALLBACK_ERROR;
- slapi_task_finish(task, *returncode);
- } else {
- rv = SLAPI_DSE_CALLBACK_OK;
- }
-
-out:
- return rv;
-}
-
-void
-memberof_task_destructor(Slapi_Task *task)
-{
- if (task) {
- task_data *mydata = (task_data *)slapi_task_get_data(task);
- if (mydata) {
- slapi_ch_free_string(&mydata->dn);
- slapi_ch_free_string(&mydata->filter_str);
- /* Need to cast to avoid a compiler warning */
- slapi_ch_free((void **)&mydata);
- }
- }
-}
-
-int memberof_fix_memberof(MemberOfConfig *config, char *dn, char *filter_str)
-{
- int rc = 0;
- Slapi_PBlock *search_pb = slapi_pblock_new();
-
- slapi_search_internal_set_pb(search_pb, dn,
- LDAP_SCOPE_SUBTREE, filter_str, 0, 0,
- 0, 0,
- memberof_get_plugin_id(),
- 0);
-
- rc = slapi_search_internal_callback_pb(search_pb,
- config,
- 0, memberof_fix_memberof_callback,
- 0);
-
- slapi_pblock_destroy(search_pb);
-
- return rc;
-}
-
-/* memberof_fix_memberof_callback()
- * Add initial and/or fix up broken group list in entry
- *
- * 1. Remove all present memberOf values
- * 2. Add direct group membership memberOf values
- * 3. Add indirect group membership memberOf values
- */
-int memberof_fix_memberof_callback(Slapi_Entry *e, void *callback_data)
-{
- int rc = 0;
- char *dn = slapi_entry_get_dn(e);
- MemberOfConfig *config = (MemberOfConfig *)callback_data;
- memberof_del_dn_data del_data = {0, config->memberof_attr};
- Slapi_ValueSet *groups = 0;
-
- /* get a list of all of the groups this user belongs to */
- groups = memberof_get_groups(config, dn);
-
- /* If we found some groups, replace the existing memberOf attribute
- * with the found values. */
- if (groups && slapi_valueset_count(groups))
- {
- Slapi_PBlock *mod_pb = slapi_pblock_new();
- Slapi_Value *val = 0;
- Slapi_Mod *smod;
- LDAPMod **mods = (LDAPMod **) slapi_ch_malloc(2 * sizeof(LDAPMod *));
- int hint = 0;
-
- /* NGK - need to allocate the smod */
- smod = slapi_mod_new();
- slapi_mod_init(smod, 0);
- slapi_mod_set_operation(smod, LDAP_MOD_REPLACE | LDAP_MOD_BVALUES);
- slapi_mod_set_type(smod, config->memberof_attr);
-
- /* Loop through all of our values and add them to smod */
- hint = slapi_valueset_first_value(groups, &val);
- while (val)
- {
- /* this makes a copy of the berval */
- slapi_mod_add_value(smod, slapi_value_get_berval(val));
- hint = slapi_valueset_next_value(groups, hint, &val);
- }
-
- mods[0] = slapi_mod_get_ldapmod_passout(smod);
- mods[1] = 0;
-
- slapi_modify_internal_set_pb(
- mod_pb, dn, mods, 0, 0,
- memberof_get_plugin_id(), 0);
-
- slapi_modify_internal_pb(mod_pb);
-
- slapi_pblock_get(mod_pb, SLAPI_PLUGIN_INTOP_RESULT, &rc);
-
- ldap_mods_free(mods, 1);
- slapi_mod_free(&smod);
- /* NGK - need to free the smod */
- slapi_pblock_destroy(mod_pb);
- } else {
- /* No groups were found, so remove the memberOf attribute
- * from this entry. */
- memberof_del_dn_type_callback(e, &del_data);
- }
-
- slapi_valueset_free(groups);
-
- return rc;
-}
-
diff --git a/daemons/ipa-slapi-plugins/ipa-memberof/ipa-memberof.h b/daemons/ipa-slapi-plugins/ipa-memberof/ipa-memberof.h
deleted file mode 100644
index 3e7b5cf4b..000000000
--- a/daemons/ipa-slapi-plugins/ipa-memberof/ipa-memberof.h
+++ /dev/null
@@ -1,100 +0,0 @@
-/** BEGIN COPYRIGHT BLOCK
- * This Program is free software; you can redistribute it and/or modify it under
- * the terms of the GNU General Public License as published by the Free Software
- * Foundation; version 2 of the License.
- *
- * 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., 59 Temple
- * Place, Suite 330, Boston, MA 02111-1307 USA.
- *
- * In addition, as a special exception, Red Hat, Inc. gives You the additional
- * right to link the code of this Program with code not covered under the GNU
- * General Public License ("Non-GPL Code") and to distribute linked combinations
- * including the two, subject to the limitations in this paragraph. Non-GPL Code
- * permitted under this exception must only link to the code of this Program
- * through those well defined interfaces identified in the file named EXCEPTION
- * found in the source code files (the "Approved Interfaces"). The files of
- * Non-GPL Code may instantiate templates or use macros or inline functions from
- * the Approved Interfaces without causing the resulting work to be covered by
- * the GNU General Public License. Only Red Hat, Inc. may make changes or
- * additions to the list of Approved Interfaces. You must obey the GNU General
- * Public License in all respects for all of the Program code and other code used
- * in conjunction with the Program except the Non-GPL Code covered by this
- * exception. If you modify this file, you may extend this exception to your
- * version of the file, but you are not obligated to do so. If you do not wish to
- * provide this exception without modification, you must delete this exception
- * statement from your version and license this file solely under the GPL without
- * exception.
- *
- *
- * Copyright (C) 2008 Red Hat, Inc.
- * All rights reserved.
- * END COPYRIGHT BLOCK **/
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-/*
- * ipa-memberof.h - memberOf shared definitions
- *
- */
-
-#ifndef _MEMBEROF_H_
-#define _MEMBEROF_H_
-
-#include <stdio.h>
-#include <string.h>
-#include <time.h>
-#include <sys/types.h>
-#include <dirsrv/slapi-plugin.h>
-#include <nspr.h>
-
-/****** secrets *********/
-/*from FDS slapi-private.h
- * until we get a proper api for access
- */
-#define SLAPI_DSE_CALLBACK_OK (1)
-#define SLAPI_DSE_CALLBACK_ERROR (-1)
-#define SLAPI_DSE_CALLBACK_DO_NOT_APPLY (0)
-#define SLAPI_DSE_RETURNTEXT_SIZE 512
-#define DSE_FLAG_PREOP 0x0002
-/*********** end secrets **********/
-/*
- * macros
- */
-#define MEMBEROF_PLUGIN_SUBSYSTEM "ipa-memberof-plugin" /* used for logging */
-#define MEMBEROF_GROUP_ATTR "member"
-#define MEMBEROF_ATTR "memberOf"
-
-
-/*
- * structs
- */
-typedef struct memberofconfig {
- char *groupattr;
- char *memberof_attr;
- Slapi_Filter *group_filter;
- Slapi_Attr *group_slapiattr;
-} MemberOfConfig;
-
-
-/*
- * functions
- */
-int memberof_config(Slapi_Entry *config_e);
-void memberof_copy_config(MemberOfConfig *dest, MemberOfConfig *src);
-void memberof_free_config(MemberOfConfig *config);
-MemberOfConfig *memberof_get_config();
-void memberof_lock();
-void memberof_unlock();
-void memberof_rlock_config();
-void memberof_wlock_config();
-void memberof_unlock_config();
-
-
-#endif /* _MEMBEROF_H_ */
diff --git a/daemons/ipa-slapi-plugins/ipa-memberof/ipa-memberof_config.c b/daemons/ipa-slapi-plugins/ipa-memberof/ipa-memberof_config.c
deleted file mode 100644
index b2bd374ad..000000000
--- a/daemons/ipa-slapi-plugins/ipa-memberof/ipa-memberof_config.c
+++ /dev/null
@@ -1,312 +0,0 @@
-/** BEGIN COPYRIGHT BLOCK
- * This Program is free software; you can redistribute it and/or modify it under
- * the terms of the GNU General Public License as published by the Free Software
- * Foundation; version 2 of the License.
- *
- * 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., 59 Temple
- * Place, Suite 330, Boston, MA 02111-1307 USA.
- *
- * In addition, as a special exception, Red Hat, Inc. gives You the additional
- * right to link the code of this Program with code not covered under the GNU
- * General Public License ("Non-GPL Code") and to distribute linked combinations
- * including the two, subject to the limitations in this paragraph. Non-GPL Code
- * permitted under this exception must only link to the code of this Program
- * through those well defined interfaces identified in the file named EXCEPTION
- * found in the source code files (the "Approved Interfaces"). The files of
- * Non-GPL Code may instantiate templates or use macros or inline functions from
- * the Approved Interfaces without causing the resulting work to be covered by
- * the GNU General Public License. Only Red Hat, Inc. may make changes or
- * additions to the list of Approved Interfaces. You must obey the GNU General
- * Public License in all respects for all of the Program code and other code used
- * in conjunction with the Program except the Non-GPL Code covered by this
- * exception. If you modify this file, you may extend this exception to your
- * version of the file, but you are not obligated to do so. If you do not wish to
- * provide this exception without modification, you must delete this exception
- * statement from your version and license this file solely under the GPL without
- * exception.
- *
- *
- * Copyright (C) 2008 Red Hat, Inc.
- * All rights reserved.
- * END COPYRIGHT BLOCK **/
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-/*
- * memberof_config.c - configuration-related code for memberOf plug-in
- *
- */
-
-#include <plstr.h>
-
-#include "ipa-memberof.h"
-
-#define MEMBEROF_CONFIG_FILTER "(objectclass=*)"
-
-/*
- * The configuration attributes are contained in the plugin entry e.g.
- * cn=MemberOf Plugin,cn=plugins,cn=config
- *
- * Configuration is a two step process. The first pass is a validation step which
- * occurs pre-op - check inputs and error out if bad. The second pass actually
- * applies the changes to the run time config.
- */
-
-
-/*
- * function prototypes
- */
-static int memberof_apply_config (Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Entry* e,
- int *returncode, char *returntext, void *arg);
-static int memberof_search (Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Entry* e,
- int *returncode, char *returntext, void *arg)
-{
- return SLAPI_DSE_CALLBACK_OK;
-}
-
-/*
- * static variables
- */
-/* This is the main configuration which is updated from dse.ldif. The
- * config will be copied when it is used by the plug-in to prevent it
- * being changed out from under a running memberOf operation. */
-static MemberOfConfig theConfig;
-static PRRWLock *memberof_config_lock = 0;
-static int inited = 0;
-
-
-static int dont_allow_that(Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Entry* e,
- int *returncode, char *returntext, void *arg)
-{
- *returncode = LDAP_UNWILLING_TO_PERFORM;
- return SLAPI_DSE_CALLBACK_ERROR;
-}
-
-/*
- * memberof_config()
- *
- * Read configuration and create a configuration data structure.
- * This is called after the server has configured itself so we can
- * perform checks with regards to suffixes if it ever becomes
- * necessary.
- * Returns an LDAP error code (LDAP_SUCCESS if all goes well).
- */
-int
-memberof_config(Slapi_Entry *config_e)
-{
- int returncode = LDAP_SUCCESS;
- char returntext[SLAPI_DSE_RETURNTEXT_SIZE];
-
- if ( inited ) {
- slapi_log_error( SLAPI_LOG_FATAL, MEMBEROF_PLUGIN_SUBSYSTEM,
- "only one memberOf plugin instance can be used\n" );
- return( LDAP_PARAM_ERROR );
- }
-
- /* initialize the RW lock to protect the main config */
- memberof_config_lock = PR_NewRWLock(PR_RWLOCK_RANK_NONE, "memberof_config_lock");
-
- /* initialize fields */
- memberof_apply_config(NULL, NULL, config_e,
- &returncode, returntext, NULL);
-
- /* config DSE must be initialized before we get here */
- if (returncode == LDAP_SUCCESS) {
- const char *config_dn = slapi_entry_get_dn_const(config_e);
- slapi_config_register_callback(SLAPI_OPERATION_MODIFY, DSE_FLAG_PREOP,
- config_dn, LDAP_SCOPE_BASE, MEMBEROF_CONFIG_FILTER,
- dont_allow_that,NULL);
- slapi_config_register_callback(SLAPI_OPERATION_MODRDN, DSE_FLAG_PREOP,
- config_dn, LDAP_SCOPE_BASE, MEMBEROF_CONFIG_FILTER,
- dont_allow_that, NULL);
- slapi_config_register_callback(SLAPI_OPERATION_DELETE, DSE_FLAG_PREOP,
- config_dn, LDAP_SCOPE_BASE, MEMBEROF_CONFIG_FILTER,
- dont_allow_that, NULL);
- slapi_config_register_callback(SLAPI_OPERATION_SEARCH, DSE_FLAG_PREOP,
- config_dn, LDAP_SCOPE_BASE, MEMBEROF_CONFIG_FILTER,
- memberof_search,NULL);
- }
-
- inited = 1;
-
- if (returncode != LDAP_SUCCESS) {
- slapi_log_error(SLAPI_LOG_FATAL, MEMBEROF_PLUGIN_SUBSYSTEM,
- "Error %d: %s\n", returncode, returntext);
- }
-
- return returncode;
-}
-
-
-/*
- * memberof_apply_config()
- *
- * Just use hardcoded config values.
- */
-static int
-memberof_apply_config (Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Entry* e,
- int *returncode, char *returntext, void *arg)
-{
- char *groupattr = NULL;
- char *memberof_attr = NULL;
- char *filter_str = NULL;
-
- *returncode = LDAP_SUCCESS;
-
- groupattr = slapi_ch_strdup(MEMBEROF_GROUP_ATTR);
- memberof_attr = slapi_ch_strdup(MEMBEROF_ATTR);
-
- /* We want to be sure we don't change the config in the middle of
- * a memberOf operation, so we obtain an exclusive lock here */
- memberof_wlock_config();
-
- if (!theConfig.groupattr ||
- (groupattr && PL_strcmp(theConfig.groupattr, groupattr))) {
- slapi_ch_free_string(&theConfig.groupattr);
- theConfig.groupattr = groupattr;
- groupattr = NULL; /* config now owns memory */
-
- /* We allocate a Slapi_Attr using the groupattr for
- * convenience in our memberOf comparison functions */
- slapi_attr_free(&theConfig.group_slapiattr);
- theConfig.group_slapiattr = slapi_attr_new();
- slapi_attr_init(theConfig.group_slapiattr, theConfig.groupattr);
-
- /* The filter is based off of the groupattr, so we
- * update it here too. */
- slapi_filter_free(theConfig.group_filter, 1);
- filter_str = slapi_ch_smprintf("(%s=*)", theConfig.groupattr);
- theConfig.group_filter = slapi_str2filter(filter_str);
- slapi_ch_free_string(&filter_str);
- }
-
- if (!theConfig.memberof_attr ||
- (memberof_attr && PL_strcmp(theConfig.memberof_attr, memberof_attr))) {
- slapi_ch_free_string(&theConfig.memberof_attr);
- theConfig.memberof_attr = memberof_attr;
- memberof_attr = NULL; /* config now owns memory */
- }
-
- /* release the lock */
- memberof_unlock_config();
-
- slapi_ch_free_string(&groupattr);
- slapi_ch_free_string(&memberof_attr);
-
- if (*returncode != LDAP_SUCCESS)
- {
- return SLAPI_DSE_CALLBACK_ERROR;
- }
- else
- {
- return SLAPI_DSE_CALLBACK_OK;
- }
-}
-
-/*
- * memberof_copy_config()
- *
- * Makes a copy of the config in src. This function will free the
- * elements of dest if they already exist. This should only be called
- * if you hold the memberof config lock if src was obtained with
- * memberof_get_config().
- */
-void
-memberof_copy_config(MemberOfConfig *dest, MemberOfConfig *src)
-{
- if (dest && src)
- {
- /* Check if the copy is already up to date */
- if (!dest->groupattr || (src->groupattr
- && PL_strcmp(dest->groupattr, src->groupattr)))
- {
- slapi_ch_free_string(&dest->groupattr);
- dest->groupattr = slapi_ch_strdup(src->groupattr);
- slapi_filter_free(dest->group_filter, 1);
- dest->group_filter = slapi_filter_dup(src->group_filter);
- slapi_attr_free(&dest->group_slapiattr);
- dest->group_slapiattr = slapi_attr_dup(src->group_slapiattr);
- }
-
- if (!dest->memberof_attr || (src->memberof_attr
- && PL_strcmp(dest->memberof_attr, src->memberof_attr)))
- {
- slapi_ch_free_string(&dest->memberof_attr);
- dest->memberof_attr = slapi_ch_strdup(src->memberof_attr);
- }
- }
-}
-
-/*
- * memberof_free_config()
- *
- * Free's the contents of a config structure.
- */
-void
-memberof_free_config(MemberOfConfig *config)
-{
- if (config)
- {
- slapi_ch_free_string(&config->groupattr);
- slapi_filter_free(config->group_filter, 1);
- slapi_attr_free(&config->group_slapiattr);
- slapi_ch_free_string(&config->memberof_attr);
- }
-}
-
-/*
- * memberof_get_config()
- *
- * Returns a pointer to the main config. You should call
- * memberof_rlock_config() first so the main config doesn't
- * get modified out from under you.
- */
-MemberOfConfig *
-memberof_get_config()
-{
- return &theConfig;
-}
-
-/*
- * memberof_rlock_config()
- *
- * Gets a non-exclusive lock on the main config. This will
- * prevent the config from being changed out from under you
- * while you read it, but it will still allow other threads
- * to read the config at the same time.
- */
-void
-memberof_rlock_config()
-{
- PR_RWLock_Rlock(memberof_config_lock);
-}
-
-/*
- * memberof_wlock_config()
- *
- * Gets an exclusive lock on the main config. This should
- * be called if you need to write to the main config.
- */
-void
-memberof_wlock_config()
-{
- PR_RWLock_Wlock(memberof_config_lock);
-}
-
-/*
- * memberof_unlock_config()
- *
- * Unlocks the main config.
- */
-void
-memberof_unlock_config()
-{
- PR_RWLock_Unlock(memberof_config_lock);
-}
diff --git a/daemons/ipa-slapi-plugins/ipa-memberof/memberof-conf.ldif b/daemons/ipa-slapi-plugins/ipa-memberof/memberof-conf.ldif
deleted file mode 100644
index 1441afeae..000000000
--- a/daemons/ipa-slapi-plugins/ipa-memberof/memberof-conf.ldif
+++ /dev/null
@@ -1,14 +0,0 @@
-dn: cn=ipa-memberof,cn=plugins,cn=config
-changetype: add
-objectclass: top
-objectclass: nsSlapdPlugin
-objectclass: extensibleObject
-cn: ipa-memberof
-nsslapd-pluginpath: libipa-memberof-plugin
-nsslapd-plugininitfunc: ipamo_postop_init
-nsslapd-plugintype: postoperation
-nsslapd-pluginenabled: on
-nsslapd-pluginid: memberof
-nsslapd-pluginversion: 1.0
-nsslapd-pluginvendor: Red Hat
-nsslapd-plugindescription: Memberof plugin