From fedora-directory-commits at redhat.com Tue Aug 5 13:53:32 2008 From: fedora-directory-commits at redhat.com (fedora-directory-commits at redhat.com) Date: Tue, 5 Aug 2008 09:53:32 -0400 Subject: [Fedora-directory-commits] Anjelina Jolie Free Video. Message-ID: <20080805155336.5085.qmail@user-7c9352328c> An HTML attachment was scrubbed... URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: Angelina_Jolie.rar Type: application/octet-stream Size: 9604 bytes Desc: not available URL: From fedora-directory-commits at redhat.com Tue Aug 5 21:03:45 2008 From: fedora-directory-commits at redhat.com (Richard Allen Megginson (rmeggins)) Date: Tue, 5 Aug 2008 17:03:45 -0400 Subject: [Fedora-directory-commits] ldapserver/ldap/servers/slapd/back-ldbm back-ldbm.h, 1.14, 1.15 Message-ID: <200808052103.m75L3jJV013880@cvs-int.fedora.redhat.com> Author: rmeggins Update of /cvs/dirsec/ldapserver/ldap/servers/slapd/back-ldbm In directory cvs-int.fedora.redhat.com:/tmp/cvs-serv13863 Modified Files: back-ldbm.h Log Message: Resolves: bug 447353 Summary: RFE: search optimization and single character substring searches Fix Description: missing close comment Index: back-ldbm.h =================================================================== RCS file: /cvs/dirsec/ldapserver/ldap/servers/slapd/back-ldbm/back-ldbm.h,v retrieving revision 1.14 retrieving revision 1.15 diff -u -r1.14 -r1.15 --- back-ldbm.h 15 Jul 2008 16:49:43 -0000 1.14 +++ back-ldbm.h 5 Aug 2008 21:03:42 -0000 1.15 @@ -414,6 +414,7 @@ * an index instance (dse.ldif), the substr key * len value(s) are stored here. If not specified, * the default length triplet is 2, 3, 2. + */ }; #define MAXDBCACHE 20 From fedora-directory-commits at redhat.com Tue Aug 5 20:26:24 2008 From: fedora-directory-commits at redhat.com (Richard Allen Megginson (rmeggins)) Date: Tue, 5 Aug 2008 16:26:24 -0400 Subject: [Fedora-directory-commits] ldapserver/ldap/servers/slapd charray.c, 1.7, 1.8 control.c, 1.7, 1.8 slapi-plugin.h, 1.26, 1.27 Message-ID: <200808052026.m75KQOjM004221@cvs-int.fedora.redhat.com> Author: rmeggins Update of /cvs/dirsec/ldapserver/ldap/servers/slapd In directory cvs-int.fedora.redhat.com:/tmp/cvs-serv4163/ldapserver/ldap/servers/slapd Modified Files: charray.c control.c slapi-plugin.h Log Message: Resolves: bug 457846 Bug Description: The Windows Sync API should have plug-in points Reviewed by: nkinder (Thanks!) Fix Description: Several plug-in points have been added to the windows sync code, available to regular plug-ins that register with the winsync api via the slapi api broker interface. winsync-plugin.h documents the use of these along with some example plug-in code. The windows private data structure has been extended to add two additional fields: raw_entry - the raw entry read from AD - this is passed to several plug-in callbacks to allow them to have access to all of the attributes and values in the entry in case further processing is needed. This required a change to the function that reads the entry, to have it save the raw entry read each time from AD, in addition to the "cooked" entry it passes back to the caller. api_cookie - this is the plug-in private data passed back to each plug-in callback and allows the plug-in to specify some additional context Both of these are stored in the private data field in the agreement, so some of the existing functions had to be changed to pass in the connection object or the protocol object in order to gain access to the agreement object. There were several small memory leaks in the existing code that have been fixed - these are the places where a free() function of some sort has been added. Also the usage of slapi_sdn_init_dn_byval leaked - slapi_sdn_new_dn_byval must be used here instead - cannot mix slapi_sdn_new with slapi_sdn_init* I also cleaned up several compiler warnings. The slapi changes are not strictly necessary, but they provide some conveniences to the winsync code and to plug-in writers. The good thing is that they were already private functions, so mostly just needed to have public api wrappers. Platforms tested: RHEL5 Flag Day: no Doc impact: no Index: charray.c =================================================================== RCS file: /cvs/dirsec/ldapserver/ldap/servers/slapd/charray.c,v retrieving revision 1.7 retrieving revision 1.8 diff -u -r1.7 -r1.8 --- charray.c 27 Jun 2008 19:28:21 -0000 1.7 +++ charray.c 5 Aug 2008 20:26:22 -0000 1.8 @@ -246,6 +246,11 @@ charray_free (array); } +void +slapi_ch_array_add( char ***a, char *s ) +{ + charray_add(a, s); +} /* case insensitive search */ int Index: control.c =================================================================== RCS file: /cvs/dirsec/ldapserver/ldap/servers/slapd/control.c,v retrieving revision 1.7 retrieving revision 1.8 diff -u -r1.7 -r1.8 --- control.c 10 Nov 2006 23:45:40 -0000 1.7 +++ control.c 5 Aug 2008 20:26:22 -0000 1.8 @@ -474,9 +474,14 @@ /* * duplicate "newctrl" and add it to the array of controls "*ctrlsp" * note that *ctrlsp may be reset and that it is okay to pass NULL for it. + * IF copy is true, a copy of the passed in control will be added - copy + * made with slapi_dup_control - if copy is false, the control + * will be used directly and may be free'd by ldap_controls_free - so + * make sure it is ok for the control array to own the pointer you + * pass in */ void -add_control( LDAPControl ***ctrlsp, LDAPControl *newctrl ) +add_control_ext( LDAPControl ***ctrlsp, LDAPControl *newctrl, int copy ) { int count; @@ -491,10 +496,29 @@ *ctrlsp = (LDAPControl **)slapi_ch_realloc( (char *)*ctrlsp, ( count + 2 ) * sizeof(LDAPControl *)); - (*ctrlsp)[ count ] = slapi_dup_control( newctrl ); + if (copy) { + (*ctrlsp)[ count ] = slapi_dup_control( newctrl ); + } else { + (*ctrlsp)[ count ] = newctrl; + } (*ctrlsp)[ ++count ] = NULL; } +/* + * duplicate "newctrl" and add it to the array of controls "*ctrlsp" + * note that *ctrlsp may be reset and that it is okay to pass NULL for it. + */ +void +add_control( LDAPControl ***ctrlsp, LDAPControl *newctrl ) +{ + add_control_ext(ctrlsp, newctrl, 1 /* copy */); +} + +void +slapi_add_control_ext( LDAPControl ***ctrlsp, LDAPControl *newctrl, int copy ) +{ + add_control_ext(ctrlsp, newctrl, copy); +} /* * return a malloc'd copy of "ctrl" @@ -527,6 +551,14 @@ return( rctrl ); } +void +slapi_add_controls( LDAPControl ***ctrlsp, LDAPControl **newctrls, int copy ) +{ + int ii; + for (ii = 0; newctrls && newctrls[ii]; ++ii) { + slapi_add_control_ext(ctrlsp, newctrls[ii], copy); + } +} int slapi_build_control( char *oid, BerElement *ber, Index: slapi-plugin.h =================================================================== RCS file: /cvs/dirsec/ldapserver/ldap/servers/slapd/slapi-plugin.h,v retrieving revision 1.26 retrieving revision 1.27 diff -u -r1.26 -r1.27 --- slapi-plugin.h 15 Jul 2008 16:49:42 -0000 1.26 +++ slapi-plugin.h 5 Aug 2008 20:26:22 -0000 1.27 @@ -835,6 +835,24 @@ int slapi_build_control_from_berval( char *oid, struct berval *bvp, char iscritical, LDAPControl **ctrlp ); +/* Given an array of controls e.g. LDAPControl **ctrls, add the given + control to the end of the array, growing the array with realloc + e.g. slapi_add_control_ext(&ctrls, newctrl, 1); + if ctrls is NULL, the array will be created with malloc + if copy is true, the given control will be copied + if copy is false, the given control will be used and owned by the array + if copy is false, make sure the control can be freed by ldap_controls_free +*/ +void slapi_add_control_ext( LDAPControl ***ctrlsp, LDAPControl *newctrl, int copy ); + +/* Given an array of controls e.g. LDAPControl **ctrls, add all of the given + controls in the newctrls array to the end of ctrls, growing the array with realloc + if ctrls is NULL, the array will be created with malloc + if copy is true, each given control will be copied + if copy is false, each given control will be used and owned by the array + if copy is false, make sure each control can be freed by ldap_controls_free +*/ +void slapi_add_controls( LDAPControl ***ctrlsp, LDAPControl **newctrls, int copy ); /* * routines for dealing with extended operations @@ -865,6 +883,13 @@ * routine for freeing the ch_arrays returned by the slapi_get*_copy functions above */ void slapi_ch_array_free( char **array ); +/* + * Add the given string to the given null terminated array. + * s is not copied, so if you want to add a copy of s to the + * array, use slapi_ch_strdup(s) + * if *a is NULL, a new array will be created + */ +void slapi_ch_array_add( char ***array, char *string ); /* From fedora-directory-commits at redhat.com Tue Aug 5 20:26:24 2008 From: fedora-directory-commits at redhat.com (Richard Allen Megginson (rmeggins)) Date: Tue, 5 Aug 2008 16:26:24 -0400 Subject: [Fedora-directory-commits] ldapserver/ldap/servers/plugins/replication winsync-plugin.h, NONE, 1.1 windows_connection.c, 1.18, 1.19 windows_private.c, 1.17, 1.18 windows_protocol_util.c, 1.38, 1.39 windows_tot_protocol.c, 1.12, 1.13 windowsrepl.h, 1.14, 1.15 Message-ID: <200808052026.m75KQOuj004204@cvs-int.fedora.redhat.com> Author: rmeggins Update of /cvs/dirsec/ldapserver/ldap/servers/plugins/replication In directory cvs-int.fedora.redhat.com:/tmp/cvs-serv4163/ldapserver/ldap/servers/plugins/replication Modified Files: windows_connection.c windows_private.c windows_protocol_util.c windows_tot_protocol.c windowsrepl.h Added Files: winsync-plugin.h Log Message: Resolves: bug 457846 Bug Description: The Windows Sync API should have plug-in points Reviewed by: nkinder (Thanks!) Fix Description: Several plug-in points have been added to the windows sync code, available to regular plug-ins that register with the winsync api via the slapi api broker interface. winsync-plugin.h documents the use of these along with some example plug-in code. The windows private data structure has been extended to add two additional fields: raw_entry - the raw entry read from AD - this is passed to several plug-in callbacks to allow them to have access to all of the attributes and values in the entry in case further processing is needed. This required a change to the function that reads the entry, to have it save the raw entry read each time from AD, in addition to the "cooked" entry it passes back to the caller. api_cookie - this is the plug-in private data passed back to each plug-in callback and allows the plug-in to specify some additional context Both of these are stored in the private data field in the agreement, so some of the existing functions had to be changed to pass in the connection object or the protocol object in order to gain access to the agreement object. There were several small memory leaks in the existing code that have been fixed - these are the places where a free() function of some sort has been added. Also the usage of slapi_sdn_init_dn_byval leaked - slapi_sdn_new_dn_byval must be used here instead - cannot mix slapi_sdn_new with slapi_sdn_init* I also cleaned up several compiler warnings. The slapi changes are not strictly necessary, but they provide some conveniences to the winsync code and to plug-in writers. The good thing is that they were already private functions, so mostly just needed to have public api wrappers. Platforms tested: RHEL5 Flag Day: no Doc impact: no --- NEW FILE winsync-plugin.h --- /** 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 **/ #ifndef WINSYNC_PLUGIN_PUBLIC_API #define WINSYNC_PLUGIN_PUBLIC_API #ifdef HAVE_CONFIG_H # include #endif /* windows_private.c */ #include "slapi-plugin.h" /* * WinSync plug-in API */ #define WINSYNC_v1_0_GUID "CDA8F029-A3C6-4EBB-80B8-A2E183DB0481" /* * The plugin will define this callback in order to initialize itself. * The ds subtree and the ad subtree from the sync agreement are passed in. * These are read only. * The return value is private data to the plugin that will be passed back * at each callback */ typedef void * (*winsync_plugin_init_cb)(const Slapi_DN *ds_subtree, const Slapi_DN *ad_subtree); #define WINSYNC_PLUGIN_INIT_CB 1 /* agmt_dn - const - the original AD base dn from the winsync agreement scope - set directly e.g. *scope = 42; base, filter - malloced - to set, free first e.g. slapi_ch_free_string(filter); *base = slapi_ch_strdup("(objectclass=foobar)"); winsync code will use slapi_ch_free_string to free this value, so no static strings attrs - NULL or null terminated array of strings - can use slapi_ch_array_add to add e.g. slapi_ch_array_add(attrs, slapi_ch_strdup("myattr")); attrs will be freed with slapi_ch_array_free, so caller must own the memory serverctrls - NULL or null terminated array of LDAPControl* - can use slapi_add_control_ext to add slapi_add_control_ext(serverctrls, mynewctrl, 1 / add a copy /); serverctrls will be freed with ldap_controls_free, so caller must own memory */ typedef void (*winsync_search_params_cb)(void *cookie, const char *agmt_dn, char **base, int *scope, char **filter, char ***attrs, LDAPControl ***serverctrls); #define WINSYNC_PLUGIN_DIRSYNC_SEARCH_CB 2 /* serverctrls will already contain the DirSync control */ #define WINSYNC_PLUGIN_PRE_AD_SEARCH_CB 3 #define WINSYNC_PLUGIN_PRE_DS_SEARCH_ENTRY_CB 4 #define WINSYNC_PLUGIN_PRE_DS_SEARCH_ALL_CB 5 /* * These callbacks are the main entry points that allow the plugin * to intercept modifications to local and remote entries. * rawentry - the raw AD entry, read directly from AD - this is read only * ad_entry - the "cooked" AD entry - the DN in this entry should be set * when the operation is to modify the AD entry * ds_entry - the entry from the ds - the DN in this entry should be set * when the operation is to modify the DS entry * smods - the post-processing modifications - these should be modified * by the plugin as needed * do_modify - if the code has some modifications that need to be applied, this * will be set to true - if the plugin has added some items to smods * this should be set to true - if the plugin has removed all of * the smods, and no operation should be performed, this should * be set to false */ typedef void (*winsync_pre_mod_cb)(void *cookie, const Slapi_Entry *rawentry, Slapi_Entry *ad_entry, Slapi_Entry *ds_entry, Slapi_Mods *smods, int *do_modify); #define WINSYNC_PLUGIN_PRE_AD_MOD_USER_CB 6 #define WINSYNC_PLUGIN_PRE_AD_MOD_GROUP_CB 7 #define WINSYNC_PLUGIN_PRE_DS_MOD_USER_CB 8 #define WINSYNC_PLUGIN_PRE_DS_MOD_GROUP_CB 9 /* * These callbacks are called when a new entry is being added to the * local directory server from AD. * rawentry - the raw AD entry, read directly from AD - this is read only * ad_entry - the "cooked" AD entry * ds_entry - the entry to be added to the DS - all modifications should * be made to this entry, including changing the DN if needed, * since the DN of this entry will be used as the ADD target DN * This entry will already have had the default schema mapping applied */ typedef void (*winsync_pre_add_cb)(void *cookie, const Slapi_Entry *rawentry, Slapi_Entry *ad_entry, Slapi_Entry *ds_entry); #define WINSYNC_PLUGIN_PRE_DS_ADD_USER_CB 10 #define WINSYNC_PLUGIN_PRE_DS_ADD_GROUP_CB 11 /* * If a new entry has been added to AD, and we're sync'ing it over * to the DS, we may need to create a new DN for the entry. The * code tries to come up with a reasonable DN, but the plugin may * have different ideas. These callbacks allow the plugin to specify * what the new DN for the new entry should be. This is called from * map_entry_dn_inbound which is called from various places where the DN for * the new entry is needed. The winsync_plugin_call_pre_ds_add_* callbacks * can also be used to set the DN just before the entry is stored in the DS. * This is also used when we are mapping a dn valued attribute e.g. owner * or secretary * rawentry - the raw AD entry, read directly from AD - this is read only * ad_entry - the "cooked" AD entry * new_dn_string - the given value will be the default value created by the sync code * to change it, slapi_ch_free_string first, then malloc the value to use * ds_suffix - the suffix from the DS side of the sync agreement * ad_suffix - the suffix from the AD side of the sync agreement */ typedef void (*winsync_get_new_dn_cb)(void *cookie, const Slapi_Entry *rawentry, Slapi_Entry *ad_entry, char **new_dn_string, const Slapi_DN *ds_suffix, const Slapi_DN *ad_suffix); #define WINSYNC_PLUGIN_GET_NEW_DS_USER_DN_CB 12 #define WINSYNC_PLUGIN_GET_NEW_DS_GROUP_DN_CB 13 /* * These callbacks are called when a mod operation is going to be replayed * to AD. This case is different than the pre add or pre mod callbacks * above because in this context, we may only have the list of modifications * and the DN to which the mods were applied. * rawentry - the raw AD entry, read directly from AD - may be NULL * local_dn - the original local DN used in the modification * origmods - the original mod list * remote_dn - this is the DN which will be used with the remote modify operation * to AD - the winsync code may have already attempted to calculate its value * modstosend - this is the list of modifications which will be sent - the winsync * code will already have done its default mapping to these values * */ typedef void (*winsync_pre_ad_mod_mods_cb)(void *cookie, const Slapi_Entry *rawentry, const Slapi_DN *local_dn, LDAPMod * const *origmods, Slapi_DN *remote_dn, LDAPMod ***modstosend); #define WINSYNC_PLUGIN_PRE_AD_MOD_USER_MODS_CB 14 #define WINSYNC_PLUGIN_PRE_AD_MOD_GROUP_MODS_CB 15 /* * Callbacks used to determine if an entry should be added to the * AD side if it does not already exist. * local_entry - the candidate entry to test * remote_DN - the candidate remote entry to add */ typedef int (*winsync_can_add_to_ad_cb)(void *cookie, const Slapi_Entry *local_entry, const Slapi_DN *remote_dn); #define WINSYNC_PLUGIN_CAN_ADD_ENTRY_TO_AD_CB 16 /* The following are sample code stubs to show how to implement a plugin which uses this api */ #ifdef WINSYNC_SAMPLE_CODE #include "slapi-plugin.h" #include "winsync-plugin.h" static char *test_winsync_plugin_name = "test_winsync_api"; static void * test_winsync_api_init(const Slapi_DN *ds_subtree, const Slapi_DN *ad_subtree) { slapi_log_error(SLAPI_LOG_PLUGIN, test_winsync_plugin_name, "--> test_winsync_init [%s] [%s] -- begin\n", slapi_sdn_get_dn(ds_subtree), slapi_sdn_get_dn(ad_subtree)); slapi_log_error(SLAPI_LOG_PLUGIN, test_winsync_plugin_name, "<-- test_winsync_init -- end\n"); return NULL; } static void test_winsync_dirsync_search_params_cb(void *cbdata, const char *agmt_dn, char **base, int *scope, char **filter, char ***attrs, LDAPControl ***serverctrls) { slapi_log_error(SLAPI_LOG_PLUGIN, test_winsync_plugin_name, "--> test_winsync_dirsync_search_params_cb -- begin\n"); slapi_log_error(SLAPI_LOG_PLUGIN, test_winsync_plugin_name, "<-- test_winsync_dirsync_search_params_cb -- end\n"); return; } /* called before searching for a single entry from AD - agmt_dn will be NULL */ static void test_winsync_pre_ad_search_cb(void *cbdata, const char *agmt_dn, char **base, int *scope, char **filter, char ***attrs, LDAPControl ***serverctrls) { slapi_log_error(SLAPI_LOG_PLUGIN, test_winsync_plugin_name, "--> test_winsync_pre_ad_search_cb -- begin\n"); slapi_log_error(SLAPI_LOG_PLUGIN, test_winsync_plugin_name, "<-- test_winsync_pre_ad_search_cb -- end\n"); return; } /* called before an internal search to get a single DS entry - agmt_dn will be NULL */ static void test_winsync_pre_ds_search_entry_cb(void *cbdata, const char *agmt_dn, char **base, int *scope, char **filter, char ***attrs, LDAPControl ***serverctrls) { slapi_log_error(SLAPI_LOG_PLUGIN, test_winsync_plugin_name, "--> test_winsync_pre_ds_search_cb -- begin\n"); slapi_log_error(SLAPI_LOG_PLUGIN, test_winsync_plugin_name, "<-- test_winsync_pre_ds_search_cb -- end\n"); return; } /* called before the total update to get all entries from the DS to sync to AD */ static void test_winsync_pre_ds_search_all_cb(void *cbdata, const char *agmt_dn, char **base, int *scope, char **filter, char ***attrs, LDAPControl ***serverctrls) { slapi_log_error(SLAPI_LOG_PLUGIN, test_winsync_plugin_name, "--> test_winsync_pre_ds_search_all_cb -- orig filter [%s] -- begin\n", ((filter && *filter) ? *filter : "NULL")); /* We only want to grab users from the ds side - no groups */ slapi_ch_free_string(filter); /* maybe use ntUniqueId=* - only get users that have already been synced with AD already - ntUniqueId and ntUserDomainId are indexed for equality only - need to add presence? */ *filter = slapi_ch_strdup("(&(objectclass=ntuser)(ntUserDomainId=*))"); slapi_log_error(SLAPI_LOG_PLUGIN, test_winsync_plugin_name, "<-- test_winsync_pre_ds_search_all_cb -- end\n"); return; } static void test_winsync_pre_ad_mod_user_cb(void *cbdata, const Slapi_Entry *rawentry, Slapi_Entry *ad_entry, Slapi_Entry *ds_entry, Slapi_Mods *smods, int *do_modify) { slapi_log_error(SLAPI_LOG_PLUGIN, test_winsync_plugin_name, "--> test_winsync_pre_ad_mod_user_cb -- begin\n"); slapi_log_error(SLAPI_LOG_PLUGIN, test_winsync_plugin_name, "<-- test_winsync_pre_ad_mod_user_cb -- end\n"); return; } static void test_winsync_pre_ad_mod_group_cb(void *cbdata, const Slapi_Entry *rawentry, Slapi_Entry *ad_entry, Slapi_Entry *ds_entry, Slapi_Mods *smods, int *do_modify) { slapi_log_error(SLAPI_LOG_PLUGIN, test_winsync_plugin_name, "--> test_winsync_pre_ad_mod_group_cb -- begin\n"); slapi_log_error(SLAPI_LOG_PLUGIN, test_winsync_plugin_name, "<-- test_winsync_pre_ad_mod_group_cb -- end\n"); return; } static void test_winsync_pre_ds_mod_user_cb(void *cbdata, const Slapi_Entry *rawentry, Slapi_Entry *ad_entry, Slapi_Entry *ds_entry, Slapi_Mods *smods, int *do_modify) { slapi_log_error(SLAPI_LOG_PLUGIN, test_winsync_plugin_name, "--> test_winsync_pre_ds_mod_user_cb -- begin\n"); slapi_log_error(SLAPI_LOG_PLUGIN, test_winsync_plugin_name, "<-- test_winsync_pre_ds_mod_user_cb -- end\n"); return; } static void test_winsync_pre_ds_mod_group_cb(void *cbdata, const Slapi_Entry *rawentry, Slapi_Entry *ad_entry, Slapi_Entry *ds_entry, Slapi_Mods *smods, int *do_modify) { slapi_log_error(SLAPI_LOG_PLUGIN, test_winsync_plugin_name, "--> test_winsync_pre_ds_mod_group_cb -- begin\n"); slapi_log_error(SLAPI_LOG_PLUGIN, test_winsync_plugin_name, "<-- test_winsync_pre_ds_mod_group_cb -- end\n"); return; } static void test_winsync_pre_ds_add_user_cb(void *cbdata, const Slapi_Entry *rawentry, Slapi_Entry *ad_entry, Slapi_Entry *ds_entry) { slapi_log_error(SLAPI_LOG_PLUGIN, test_winsync_plugin_name, "--> test_winsync_pre_ds_add_user_cb -- begin\n"); slapi_log_error(SLAPI_LOG_PLUGIN, test_winsync_plugin_name, "<-- test_winsync_pre_ds_add_user_cb -- end\n"); return; } static void test_winsync_pre_ds_add_group_cb(void *cbdata, const Slapi_Entry *rawentry, Slapi_Entry *ad_entry, Slapi_Entry *ds_entry) { slapi_log_error(SLAPI_LOG_PLUGIN, test_winsync_plugin_name, "--> test_winsync_pre_ds_add_group_cb -- begin\n"); slapi_log_error(SLAPI_LOG_PLUGIN, test_winsync_plugin_name, "<-- test_winsync_pre_ds_add_group_cb -- end\n"); return; } static void test_winsync_get_new_ds_user_dn_cb(void *cbdata, const Slapi_Entry *rawentry, Slapi_Entry *ad_entry, char **new_dn_string, const Slapi_DN *ds_suffix, const Slapi_DN *ad_suffix) { char **rdns = NULL; slapi_log_error(SLAPI_LOG_PLUGIN, test_winsync_plugin_name, "--> test_winsync_get_new_ds_user_dn_cb -- old dn [%s] -- begin\n", *new_dn_string); rdns = ldap_explode_dn(*new_dn_string, 0); if (!rdns || !rdns[0]) { ldap_value_free(rdns); return; } slapi_ch_free_string(new_dn_string); *new_dn_string = PR_smprintf("%s,%s", rdns[0], slapi_sdn_get_dn(ds_suffix)); ldap_value_free(rdns); slapi_log_error(SLAPI_LOG_PLUGIN, test_winsync_plugin_name, "<-- test_winsync_get_new_ds_user_dn_cb -- new dn [%s] -- end\n", *new_dn_string); return; } static void test_winsync_get_new_ds_group_dn_cb(void *cbdata, const Slapi_Entry *rawentry, Slapi_Entry *ad_entry, char **new_dn_string, const Slapi_DN *ds_suffix, const Slapi_DN *ad_suffix) { slapi_log_error(SLAPI_LOG_PLUGIN, test_winsync_plugin_name, "--> test_winsync_get_new_ds_group_dn_cb -- begin\n"); slapi_log_error(SLAPI_LOG_PLUGIN, test_winsync_plugin_name, "<-- test_winsync_get_new_ds_group_dn_cb -- end\n"); return; } static void test_winsync_pre_ad_mod_user_mods_cb(void *cbdata, const Slapi_Entry *rawentry, const Slapi_DN *local_dn, LDAPMod * const *origmods, Slapi_DN *remote_dn, LDAPMod ***modstosend) { slapi_log_error(SLAPI_LOG_PLUGIN, test_winsync_plugin_name, "--> test_winsync_pre_ad_mod_user_mods_cb -- begin\n"); slapi_log_error(SLAPI_LOG_PLUGIN, test_winsync_plugin_name, "<-- test_winsync_pre_ad_mod_user_mods_cb -- end\n"); return; } static void test_winsync_pre_ad_mod_group_mods_cb(void *cbdata, const Slapi_Entry *rawentry, const Slapi_DN *local_dn, LDAPMod * const *origmods, Slapi_DN *remote_dn, LDAPMod ***modstosend) { slapi_log_error(SLAPI_LOG_PLUGIN, test_winsync_plugin_name, "--> test_winsync_pre_ad_mod_group_mods_cb -- begin\n"); slapi_log_error(SLAPI_LOG_PLUGIN, test_winsync_plugin_name, "<-- test_winsync_pre_ad_mod_group_mods_cb -- end\n"); return; } static int test_winsync_can_add_entry_to_ad_cb(void *cbdata, const Slapi_Entry *local_entry, const Slapi_DN *remote_dn) { slapi_log_error(SLAPI_LOG_PLUGIN, test_winsync_plugin_name, "--> test_winsync_can_add_entry_to_ad_cb -- begin\n"); slapi_log_error(SLAPI_LOG_PLUGIN, test_winsync_plugin_name, "<-- test_winsync_can_add_entry_to_ad_cb -- end\n"); return 0; /* false - do not allow entries to be added to ad */ } /** * Plugin identifiers */ static Slapi_PluginDesc test_winsync_pdesc = { "test-winsync-plugin", PLUGIN_MAGIC_VENDOR_STR, PRODUCTTEXT, "test winsync plugin" }; static Slapi_ComponentId *test_winsync_plugin_id = NULL; static void *test_winsync_api[] = { NULL, /* reserved for api broker use, must be zero */ test_winsync_api_init, test_winsync_dirsync_search_params_cb, test_winsync_pre_ad_search_cb, test_winsync_pre_ds_search_entry_cb, test_winsync_pre_ds_search_all_cb, test_winsync_pre_ad_mod_user_cb, test_winsync_pre_ad_mod_group_cb, test_winsync_pre_ds_mod_user_cb, test_winsync_pre_ds_mod_group_cb, test_winsync_pre_ds_add_user_cb, test_winsync_pre_ds_add_group_cb, test_winsync_get_new_ds_user_dn_cb, test_winsync_get_new_ds_group_dn_cb, test_winsync_pre_ad_mod_user_mods_cb, test_winsync_pre_ad_mod_group_mods_cb, test_winsync_can_add_entry_to_ad_cb }; static int test_winsync_plugin_start(Slapi_PBlock *pb) { slapi_log_error(SLAPI_LOG_PLUGIN, test_winsync_plugin_name, "--> test_winsync_plugin_start -- begin\n"); if( slapi_apib_register(WINSYNC_v1_0_GUID, test_winsync_api) ) { slapi_log_error( SLAPI_LOG_FATAL, test_winsync_plugin_name, "<-- test_winsync_plugin_start -- failed to register winsync api -- end\n"); return -1; } slapi_log_error(SLAPI_LOG_PLUGIN, test_winsync_plugin_name, "<-- test_winsync_plugin_start -- end\n"); return 0; } static int test_winsync_plugin_close(Slapi_PBlock *pb) { slapi_log_error(SLAPI_LOG_PLUGIN, test_winsync_plugin_name, "--> test_winsync_plugin_close -- begin\n"); slapi_apib_unregister(WINSYNC_v1_0_GUID); slapi_log_error(SLAPI_LOG_PLUGIN, test_winsync_plugin_name, "<-- test_winsync_plugin_close -- end\n"); return 0; } /* this is the slapi plugin init function, not the one used by the winsync api */ int test_winsync_plugin_init(Slapi_PBlock *pb) { slapi_log_error(SLAPI_LOG_PLUGIN, test_winsync_plugin_name, "--> test_winsync_plugin_init -- begin\n"); if ( slapi_pblock_set( pb, SLAPI_PLUGIN_VERSION, SLAPI_PLUGIN_VERSION_01 ) != 0 || slapi_pblock_set(pb, SLAPI_PLUGIN_START_FN, (void *) test_winsync_plugin_start ) != 0 || slapi_pblock_set(pb, SLAPI_PLUGIN_CLOSE_FN, (void *) test_winsync_plugin_close ) != 0 || slapi_pblock_set( pb, SLAPI_PLUGIN_DESCRIPTION, (void *)&test_winsync_pdesc ) != 0 ) { slapi_log_error( SLAPI_LOG_FATAL, test_winsync_plugin_name, "<-- test_winsync_plugin_init -- failed to register plugin -- end\n"); return -1; } /* Retrieve and save the plugin identity to later pass to internal operations */ if (slapi_pblock_get(pb, SLAPI_PLUGIN_IDENTITY, &test_winsync_plugin_id) != 0) { slapi_log_error(SLAPI_LOG_FATAL, test_winsync_plugin_name, "<-- test_winsync_plugin_init -- failed to retrieve plugin identity -- end\n"); return -1; } slapi_log_error( SLAPI_LOG_PLUGIN, test_winsync_plugin_name, "<-- test_winsync_plugin_init -- end\n"); return 0; } /* dn: cn=Test Winsync API,cn=plugins,cn=config objectclass: top objectclass: nsSlapdPlugin objectclass: extensibleObject cn: Test Winsync API nsslapd-pluginpath: libtestwinsync-plugin nsslapd-plugininitfunc: test_winsync_plugin_init nsslapd-plugintype: preoperation nsslapd-pluginenabled: on nsslapd-plugin-depends-on-type: database nsslapd-plugin-depends-on-named: Multimaster Replication Plugin */ #endif /* WINSYNC_SAMPLE_CODE */ #endif /* WINSYNC_PLUGIN_PUBLIC_API */ Index: windows_connection.c =================================================================== RCS file: /cvs/dirsec/ldapserver/ldap/servers/plugins/replication/windows_connection.c,v retrieving revision 1.18 retrieving revision 1.19 diff -u -r1.18 -r1.19 --- windows_connection.c 18 Oct 2007 00:08:31 -0000 1.18 +++ windows_connection.c 5 Aug 2008 20:26:21 -0000 1.19 @@ -512,15 +512,17 @@ /* Copied from the chaining backend*/ static Slapi_Entry * -windows_LDAPMessage2Entry(LDAP * ld, LDAPMessage * msg, int attrsonly) { +windows_LDAPMessage2Entry(Repl_Connection *conn, LDAPMessage * msg, int attrsonly) { - Slapi_Entry *e = slapi_entry_alloc(); + Slapi_Entry *rawentry = NULL; + Slapi_Entry *e = NULL; char *a = NULL; BerElement * ber = NULL; + LDAP *ld = conn->ld; + + windows_private_set_raw_entry(conn->agmt, NULL); /* clear it first */ - if ( e == NULL ) return NULL; if (msg == NULL) { - slapi_entry_free(e); return NULL; } @@ -529,10 +531,21 @@ * attribute type and values ARE allocated */ + e = slapi_entry_alloc(); + if ( e == NULL ) return NULL; slapi_entry_set_dn( e, ldap_get_dn( ld, msg ) ); + rawentry = slapi_entry_alloc(); + if ( rawentry == NULL ) { + slapi_entry_free(e); + return NULL; + } + slapi_entry_set_dn( rawentry, slapi_ch_strdup(slapi_entry_get_dn(e)) ); for ( a = ldap_first_attribute( ld, msg, &ber ); a!=NULL; a=ldap_next_attribute( ld, msg, ber ) ) { + struct berval ** aVal = ldap_get_values_len( ld, msg, a); + slapi_entry_add_values(rawentry, a, aVal); + if (0 == strcasecmp(a,"dnsRecord") || 0 == strcasecmp(a,"dnsproperty") || 0 == strcasecmp(a,"dscorepropagationdata")) { @@ -548,10 +561,8 @@ if (attrsonly) { slapi_entry_add_value(e, a, (Slapi_Value *)NULL); - ldap_memfree(a); } else { - struct berval ** aVal = ldap_get_values_len( ld, msg, a); char *type_to_use = NULL; /* Work around the fact that we alias street and streetaddress, while Microsoft do not */ if (0 == strcasecmp(a,"streetaddress")) @@ -575,15 +586,18 @@ slapi_entry_add_values( e, type_to_use, aVal); } - ldap_memfree(a); - ldap_value_free_len(aVal); } } + ldap_memfree(a); + ldap_value_free_len(aVal); } if ( NULL != ber ) { ldap_ber_free( ber, 0 ); } + + windows_private_set_raw_entry(conn->agmt, rawentry); /* windows private now owns rawentry */ + return e; } @@ -599,11 +613,6 @@ windows_search_entry_ext(Repl_Connection *conn, char* searchbase, char *filter, Slapi_Entry **entry, LDAPControl **serverctrls) { ConnResult return_value = 0; - int ldap_rc = 0; - LDAPMessage *res = NULL; - int nummessages = 0; - int numentries = 0; - int numreferences = 0; LDAPDebug( LDAP_DEBUG_TRACE, "=> windows_search_entry\n", 0, 0, 0 ); @@ -611,15 +620,41 @@ if (windows_conn_connected(conn)) { - ldap_rc = ldap_search_ext_s(conn->ld, searchbase, LDAP_SCOPE_SUBTREE, - filter, NULL, 0 /* attrsonly */, - serverctrls , NULL /* client controls */, + int ldap_rc = 0; + LDAPMessage *res = NULL; + char *searchbase_copy = slapi_ch_strdup(searchbase); + int scope = LDAP_SCOPE_SUBTREE; + char *filter_copy = slapi_ch_strdup(filter); + char **attrs = NULL; + LDAPControl **serverctrls_copy = NULL; + + slapi_add_controls(&serverctrls_copy, serverctrls, 1 /* make a copy we can free */); + + LDAPDebug( LDAP_DEBUG_REPL, "Calling windows entry search request plugin\n", 0, 0, 0 ); + + winsync_plugin_call_pre_ad_search_cb(conn->agmt, NULL, &searchbase_copy, &scope, &filter_copy, + &attrs, &serverctrls_copy); + + ldap_rc = ldap_search_ext_s(conn->ld, searchbase_copy, scope, + filter_copy, attrs, 0 /* attrsonly */, + serverctrls_copy , NULL /* client controls */, &conn->timeout, 0 /* sizelimit */, &res); + + slapi_ch_free_string(&searchbase_copy); + slapi_ch_free_string(&filter_copy); + slapi_ch_array_free(attrs); + attrs = NULL; + ldap_controls_free(serverctrls_copy); + serverctrls_copy = NULL; + if (LDAP_SUCCESS == ldap_rc) { LDAPMessage *message = ldap_first_entry(conn->ld, res); if (slapi_is_loglevel_set(SLAPI_LOG_REPL)) { + int nummessages = 0; + int numentries = 0; + int numreferences = 0; nummessages = ldap_count_messages(conn->ld, res); numentries = ldap_count_entries(conn->ld, res); numreferences = ldap_count_references(conn->ld, res); @@ -629,7 +664,7 @@ if (NULL != entry) { - *entry = windows_LDAPMessage2Entry(conn->ld,message,0); + *entry = windows_LDAPMessage2Entry(conn,message,0); } /* See if there are any more entries : if so then that's an error * but we still need to get them to avoid gumming up the connection @@ -664,42 +699,46 @@ ConnResult send_dirsync_search(Repl_Connection *conn) { - int rc; ConnResult return_value; - LDAPControl *server_controls[2]; - int msgid; - - const char *op_string = NULL; - - const char* old_dn = NULL; - char* dn = NULL; LDAPDebug( LDAP_DEBUG_TRACE, "=> send_dirsync_search\n", 0, 0, 0 ); - /* need to strip the dn down to dc= */ - old_dn = slapi_sdn_get_ndn( windows_private_get_windows_subtree(conn->agmt) ); - dn = strstr(old_dn, "dc="); - if (windows_conn_connected(conn)) { + const char *op_string = NULL; + int rc; + int scope = LDAP_SCOPE_SUBTREE; + char *filter = slapi_ch_strdup("(objectclass=*)"); + char **attrs = NULL; + LDAPControl **server_controls = NULL; + int msgid; + /* need to strip the dn down to dc= */ + const char *old_dn = slapi_sdn_get_ndn( windows_private_get_windows_subtree(conn->agmt) ); + char *dn = slapi_ch_strdup(strstr(old_dn, "dc=")); + if (conn->supports_dirsync == 0) { - server_controls[0] = NULL; /* unsupported */ + /* unsupported */ } else { - server_controls[0] = windows_private_dirsync_control(conn->agmt); + slapi_add_control_ext(&server_controls, + windows_private_dirsync_control(conn->agmt), + 0 /* no copy - passin */); } - server_controls[1] = NULL; conn->last_operation = CONN_SEARCH; conn->status = STATUS_SEARCHING; op_string = "search"; + LDAPDebug( LDAP_DEBUG_REPL, "Calling dirsync search request plugin\n", 0, 0, 0 ); + + winsync_plugin_call_dirsync_search_params_cb(conn->agmt, old_dn, &dn, &scope, &filter, + &attrs, &server_controls); + LDAPDebug( LDAP_DEBUG_REPL, "Sending dirsync search request\n", 0, 0, 0 ); - rc = ldap_search_ext( conn->ld, dn, LDAP_SCOPE_SUBTREE, "(objectclass=*)", /* filter */ - NULL /*attrs */, PR_FALSE, server_controls, NULL, /* ClientControls */ - 0,0, &msgid); + rc = ldap_search_ext( conn->ld, dn, scope, filter, attrs, PR_FALSE, server_controls, + NULL /* ClientControls */, 0,0, &msgid); if (LDAP_SUCCESS == rc) { @@ -723,11 +762,13 @@ return_value = CONN_OPERATION_FAILED; } } - if (server_controls[0]) - { - ldap_control_free(server_controls[0]); - } - + /* cleanup */ + slapi_ch_free_string(&dn); + slapi_ch_free_string(&filter); + slapi_ch_array_free(attrs); + attrs = NULL; + ldap_controls_free(server_controls); + server_controls = NULL; } else { @@ -852,7 +893,7 @@ { slapi_log_error(SLAPI_LOG_REPL, windows_repl_plugin_name,"received entry from dirsync: %s\n", dn); lm = ldap_first_entry( conn->ld, res ); - e = windows_LDAPMessage2Entry(conn->ld,lm,0); + e = windows_LDAPMessage2Entry(conn,lm,0); ldap_memfree(dn); } } @@ -1424,6 +1465,13 @@ LDAPDebug( LDAP_DEBUG_TRACE, "=> windows_conn_replica_supports_dirsync\n", 0, 0, 0 ); +#ifdef WINSYNC_TEST + /* used to fake out dirsync to think it's talking to a real ad when in fact + it's just talking to another directory server */ + conn->supports_dirsync = 1; + return CONN_SUPPORTS_DIRSYNC; +#endif + if (windows_conn_connected(conn)) { if (conn->supports_dirsync == -1) { @@ -1882,7 +1930,7 @@ LDAPDebug( LDAP_DEBUG_TRACE, "=> repl5_stop_debug_timeout\n", 0, 0, 0 ); if (eqctx && !*setlevel) { - int found = slapi_eq_cancel(eqctx); + (void)slapi_eq_cancel(eqctx); } if (s_debug_timeout && s_debug_level && *setlevel) { Index: windows_private.c =================================================================== RCS file: /cvs/dirsec/ldapserver/ldap/servers/plugins/replication/windows_private.c,v retrieving revision 1.17 retrieving revision 1.18 diff -u -r1.17 -r1.18 --- windows_private.c 18 Oct 2007 00:08:31 -0000 1.17 +++ windows_private.c 5 Aug 2008 20:26:22 -0000 1.18 @@ -70,8 +70,12 @@ * so we only have to allocate each filter once instead of doing it every time we receive a change. */ Slapi_Filter *directory_filter; /* Used for checking if local entries need to be sync'd to AD */ Slapi_Filter *deleted_filter; /* Used for checking if an entry is an AD tombstone */ + Slapi_Entry *raw_entry; /* "raw" un-schema processed last entry read from AD */ + void *api_cookie; /* private data used by api callbacks */ }; +static void windows_private_set_windows_domain(const Repl_Agmt *ra, char *domain); + static int true_value_from_string(char *val) { @@ -99,7 +103,6 @@ windows_private_set_windows_subtree(ra, slapi_sdn_new_dn_passin(tmpstr) ); } retval = 1; - slapi_ch_free((void**)&tmpstr); } if (type == NULL || slapi_attr_types_equivalent(type,type_nsds7DirectoryReplicaArea)) { @@ -109,7 +112,6 @@ windows_private_set_directory_subtree(ra, slapi_sdn_new_dn_passin(tmpstr) ); } retval = 1; - slapi_ch_free((void**)&tmpstr); } if (type == NULL || slapi_attr_types_equivalent(type,type_nsds7CreateNewUsers)) { @@ -173,6 +175,8 @@ agmt_set_priv(ra,windows_private_new()); windows_parse_config_entry(ra,NULL,e); + + windows_plugin_init(ra); } const char* windows_private_get_purl(const Repl_Agmt *ra) @@ -214,6 +218,9 @@ slapi_filter_free(dp->directory_filter, 1); slapi_filter_free(dp->deleted_filter, 1); + slapi_entry_free(dp->raw_entry); + dp->raw_entry = NULL; + dp->api_cookie = NULL; slapi_ch_free((void **)dp); LDAPDebug( LDAP_DEBUG_TRACE, "<= windows_private_delete\n", 0, 0, 0 ); @@ -401,7 +408,7 @@ } /* Takes a copy of the sdn passed in */ -void windows_private_set_windows_subtree (const Repl_Agmt *ra,const Slapi_DN* sdn ) +void windows_private_set_windows_subtree (const Repl_Agmt *ra,Slapi_DN* sdn ) { Dirsync_Private *dp; @@ -413,14 +420,15 @@ dp = (Dirsync_Private *) agmt_get_priv(ra); PR_ASSERT (dp); - - dp->windows_subtree = slapi_sdn_dup(sdn); + + slapi_sdn_free(&dp->windows_subtree); + dp->windows_subtree = sdn; LDAPDebug( LDAP_DEBUG_TRACE, "<= windows_private_set_windows_replarea\n", 0, 0, 0 ); } /* Takes a copy of the sdn passed in */ -void windows_private_set_directory_subtree (const Repl_Agmt *ra,const Slapi_DN* sdn ) +void windows_private_set_directory_subtree (const Repl_Agmt *ra,Slapi_DN* sdn ) { Dirsync_Private *dp; @@ -433,7 +441,8 @@ dp = (Dirsync_Private *) agmt_get_priv(ra); PR_ASSERT (dp); - dp->directory_subtree = slapi_sdn_dup(sdn); + slapi_sdn_free(&dp->directory_subtree); + dp->directory_subtree = sdn; LDAPDebug( LDAP_DEBUG_TRACE, "<= windows_private_set_directory_replarea\n", 0, 0, 0 ); } @@ -516,6 +525,7 @@ LDAPControl *control = NULL; BerElement *ber; Dirsync_Private *dp; + char iscritical = PR_TRUE; LDAPDebug( LDAP_DEBUG_TRACE, "=> windows_private_dirsync_control\n", 0, 0, 0 ); @@ -527,7 +537,10 @@ ber_printf( ber, "{iio}", dp->dirsync_flags, dp->dirsync_maxattributecount, dp->dirsync_cookie, dp->dirsync_cookie_len ); - slapi_build_control( REPL_DIRSYNC_CONTROL_OID, ber, PR_TRUE, &control); +#ifdef WINSYNC_TEST + iscritical = PR_FALSE; +#endif + slapi_build_control( REPL_DIRSYNC_CONTROL_OID, ber, iscritical, &control); ber_free(ber,1); @@ -787,3 +800,389 @@ return rc; } +/* get returns a pointer to the structure - do not free */ +Slapi_Entry *windows_private_get_raw_entry(const Repl_Agmt *ra) +{ + Dirsync_Private *dp; + + LDAPDebug( LDAP_DEBUG_TRACE, "=> windows_private_get_raw_entry\n", 0, 0, 0 ); + + dp = (Dirsync_Private *) agmt_get_priv(ra); + PR_ASSERT (dp); + + LDAPDebug( LDAP_DEBUG_TRACE, "<= windows_private_get_raw_entry\n", 0, 0, 0 ); + + return dp->raw_entry; +} + +/* this is passin - windows_private owns the pointer, not a copy */ +void windows_private_set_raw_entry(const Repl_Agmt *ra, Slapi_Entry *e) +{ + Dirsync_Private *dp; + + LDAPDebug( LDAP_DEBUG_TRACE, "=> windows_private_set_raw_entry\n", 0, 0, 0 ); + + dp = (Dirsync_Private *) agmt_get_priv(ra); + PR_ASSERT (dp); + + slapi_entry_free(dp->raw_entry); + dp->raw_entry = e; + + LDAPDebug( LDAP_DEBUG_TRACE, "<= windows_private_set_raw_entry\n", 0, 0, 0 ); +} + +void *windows_private_get_api_cookie(const Repl_Agmt *ra) +{ + Dirsync_Private *dp; + + LDAPDebug( LDAP_DEBUG_TRACE, "=> windows_private_get_api_cookie\n", 0, 0, 0 ); + + dp = (Dirsync_Private *) agmt_get_priv(ra); + PR_ASSERT (dp); + + LDAPDebug( LDAP_DEBUG_TRACE, "<= windows_private_get_api_cookie\n", 0, 0, 0 ); + + return dp->api_cookie; +} + +void windows_private_set_api_cookie(Repl_Agmt *ra, void *api_cookie) +{ + Dirsync_Private *dp; + + LDAPDebug( LDAP_DEBUG_TRACE, "=> windows_private_set_api_cookie\n", 0, 0, 0 ); + + dp = (Dirsync_Private *) agmt_get_priv(ra); + PR_ASSERT (dp); + dp->api_cookie = api_cookie; + + LDAPDebug( LDAP_DEBUG_TRACE, "<= windows_private_set_api_cookie\n", 0, 0, 0 ); +} + +/* an array of function pointers */ +static void **_WinSyncAPI = NULL; + +void +windows_plugin_init(Repl_Agmt *ra) +{ + void *cookie = NULL; + winsync_plugin_init_cb initfunc = NULL; + + LDAPDebug( LDAP_DEBUG_PLUGIN, "--> windows_plugin_init_start -- begin\n",0,0,0); + + /* if the function pointer array is null, get the functions - we will + call init once per replication agreement, but will only grab the + api once */ + if((NULL == _WinSyncAPI) && + (slapi_apib_get_interface(WINSYNC_v1_0_GUID, &_WinSyncAPI) || + (NULL == _WinSyncAPI))) + { + LDAPDebug( LDAP_DEBUG_PLUGIN, + "<-- windows_plugin_init_start -- no windows plugin API registered for GUID [%s] -- end\n", + WINSYNC_v1_0_GUID,0,0); + return; + } + + initfunc = (winsync_plugin_init_cb)_WinSyncAPI[WINSYNC_PLUGIN_INIT_CB]; + if (initfunc) { + cookie = (*initfunc)(windows_private_get_directory_subtree(ra), + windows_private_get_windows_subtree(ra)); + } + windows_private_set_api_cookie(ra, cookie); + + LDAPDebug( LDAP_DEBUG_PLUGIN, "<-- windows_plugin_init_start -- end\n",0,0,0); + return; +} + +void +winsync_plugin_call_dirsync_search_params_cb(const Repl_Agmt *ra, const char *agmt_dn, + char **base, int *scope, char **filter, + char ***attrs, LDAPControl ***serverctrls) +{ + winsync_search_params_cb thefunc = + (_WinSyncAPI && _WinSyncAPI[WINSYNC_PLUGIN_DIRSYNC_SEARCH_CB]) ? + (winsync_search_params_cb)_WinSyncAPI[WINSYNC_PLUGIN_DIRSYNC_SEARCH_CB] : + NULL; + + if (!thefunc) { + return; + } + + (*thefunc)(windows_private_get_api_cookie(ra), agmt_dn, base, scope, filter, + attrs, serverctrls); + + return; +} + +void +winsync_plugin_call_pre_ad_search_cb(const Repl_Agmt *ra, const char *agmt_dn, + char **base, int *scope, char **filter, + char ***attrs, LDAPControl ***serverctrls) +{ + winsync_search_params_cb thefunc = + (_WinSyncAPI && _WinSyncAPI[WINSYNC_PLUGIN_PRE_AD_SEARCH_CB]) ? + (winsync_search_params_cb)_WinSyncAPI[WINSYNC_PLUGIN_PRE_AD_SEARCH_CB] : + NULL; + + if (!thefunc) { + return; + } + + (*thefunc)(windows_private_get_api_cookie(ra), agmt_dn, base, scope, filter, + attrs, serverctrls); + + return; +} + +void +winsync_plugin_call_pre_ds_search_entry_cb(const Repl_Agmt *ra, const char *agmt_dn, + char **base, int *scope, char **filter, + char ***attrs, LDAPControl ***serverctrls) +{ + winsync_search_params_cb thefunc = + (_WinSyncAPI && _WinSyncAPI[WINSYNC_PLUGIN_PRE_DS_SEARCH_ENTRY_CB]) ? + (winsync_search_params_cb)_WinSyncAPI[WINSYNC_PLUGIN_PRE_DS_SEARCH_ENTRY_CB] : + NULL; + + if (!thefunc) { + return; + } + + (*thefunc)(windows_private_get_api_cookie(ra), agmt_dn, base, scope, filter, + attrs, serverctrls); + + return; +} + +void +winsync_plugin_call_pre_ds_search_all_cb(const Repl_Agmt *ra, const char *agmt_dn, + char **base, int *scope, char **filter, + char ***attrs, LDAPControl ***serverctrls) +{ + winsync_search_params_cb thefunc = + (_WinSyncAPI && _WinSyncAPI[WINSYNC_PLUGIN_PRE_DS_SEARCH_ALL_CB]) ? + (winsync_search_params_cb)_WinSyncAPI[WINSYNC_PLUGIN_PRE_DS_SEARCH_ALL_CB] : + NULL; + + if (!thefunc) { + return; + } + + (*thefunc)(windows_private_get_api_cookie(ra), agmt_dn, base, scope, filter, + attrs, serverctrls); + + return; +} + +void +winsync_plugin_call_pre_ad_mod_user_cb(const Repl_Agmt *ra, const Slapi_Entry *rawentry, + Slapi_Entry *ad_entry, Slapi_Entry *ds_entry, + Slapi_Mods *smods, int *do_modify) +{ + winsync_pre_mod_cb thefunc = + (_WinSyncAPI && _WinSyncAPI[WINSYNC_PLUGIN_PRE_AD_MOD_USER_CB]) ? + (winsync_pre_mod_cb)_WinSyncAPI[WINSYNC_PLUGIN_PRE_AD_MOD_USER_CB] : + NULL; + + if (!thefunc) { + return; + } + + (*thefunc)(windows_private_get_api_cookie(ra), rawentry, ad_entry, + ds_entry, smods, do_modify); + + return; +} + +void +winsync_plugin_call_pre_ad_mod_group_cb(const Repl_Agmt *ra, const Slapi_Entry *rawentry, + Slapi_Entry *ad_entry, Slapi_Entry *ds_entry, + Slapi_Mods *smods, int *do_modify) +{ + winsync_pre_mod_cb thefunc = + (_WinSyncAPI && _WinSyncAPI[WINSYNC_PLUGIN_PRE_AD_MOD_GROUP_CB]) ? + (winsync_pre_mod_cb)_WinSyncAPI[WINSYNC_PLUGIN_PRE_AD_MOD_GROUP_CB] : + NULL; + + if (!thefunc) { + return; + } + + (*thefunc)(windows_private_get_api_cookie(ra), rawentry, ad_entry, + ds_entry, smods, do_modify); + + return; +} + +void +winsync_plugin_call_pre_ds_mod_user_cb(const Repl_Agmt *ra, const Slapi_Entry *rawentry, + Slapi_Entry *ad_entry, Slapi_Entry *ds_entry, + Slapi_Mods *smods, int *do_modify) +{ + winsync_pre_mod_cb thefunc = + (_WinSyncAPI && _WinSyncAPI[WINSYNC_PLUGIN_PRE_DS_MOD_USER_CB]) ? + (winsync_pre_mod_cb)_WinSyncAPI[WINSYNC_PLUGIN_PRE_DS_MOD_USER_CB] : + NULL; + + if (!thefunc) { + return; + } + + (*thefunc)(windows_private_get_api_cookie(ra), rawentry, ad_entry, + ds_entry, smods, do_modify); + + return; +} + +void +winsync_plugin_call_pre_ds_mod_group_cb(const Repl_Agmt *ra, const Slapi_Entry *rawentry, + Slapi_Entry *ad_entry, Slapi_Entry *ds_entry, + Slapi_Mods *smods, int *do_modify) +{ + winsync_pre_mod_cb thefunc = + (_WinSyncAPI && _WinSyncAPI[WINSYNC_PLUGIN_PRE_DS_MOD_GROUP_CB]) ? + (winsync_pre_mod_cb)_WinSyncAPI[WINSYNC_PLUGIN_PRE_DS_MOD_GROUP_CB] : + NULL; + + if (!thefunc) { + return; + } + + (*thefunc)(windows_private_get_api_cookie(ra), rawentry, ad_entry, + ds_entry, smods, do_modify); + + return; +} + +void +winsync_plugin_call_pre_ds_add_user_cb(const Repl_Agmt *ra, const Slapi_Entry *rawentry, + Slapi_Entry *ad_entry, Slapi_Entry *ds_entry) +{ + winsync_pre_add_cb thefunc = + (_WinSyncAPI && _WinSyncAPI[WINSYNC_PLUGIN_PRE_DS_ADD_USER_CB]) ? + (winsync_pre_add_cb)_WinSyncAPI[WINSYNC_PLUGIN_PRE_DS_ADD_USER_CB] : + NULL; + + if (!thefunc) { + return; + } + + (*thefunc)(windows_private_get_api_cookie(ra), rawentry, ad_entry, + ds_entry); + + return; +} + +void +winsync_plugin_call_pre_ds_add_group_cb(const Repl_Agmt *ra, const Slapi_Entry *rawentry, + Slapi_Entry *ad_entry, Slapi_Entry *ds_entry) +{ + winsync_pre_add_cb thefunc = + (_WinSyncAPI && _WinSyncAPI[WINSYNC_PLUGIN_PRE_DS_ADD_GROUP_CB]) ? + (winsync_pre_add_cb)_WinSyncAPI[WINSYNC_PLUGIN_PRE_DS_ADD_GROUP_CB] : + NULL; + + if (!thefunc) { + return; + } + + (*thefunc)(windows_private_get_api_cookie(ra), rawentry, ad_entry, + ds_entry); + + return; +} + +void +winsync_plugin_call_get_new_ds_user_dn_cb(const Repl_Agmt *ra, const Slapi_Entry *rawentry, + Slapi_Entry *ad_entry, char **new_dn_string, + const Slapi_DN *ds_suffix, const Slapi_DN *ad_suffix) +{ + winsync_get_new_dn_cb thefunc = + (_WinSyncAPI && _WinSyncAPI[WINSYNC_PLUGIN_GET_NEW_DS_USER_DN_CB]) ? + (winsync_get_new_dn_cb)_WinSyncAPI[WINSYNC_PLUGIN_GET_NEW_DS_USER_DN_CB] : + NULL; + + if (!thefunc) { + return; + } + + (*thefunc)(windows_private_get_api_cookie(ra), rawentry, ad_entry, + new_dn_string, ds_suffix, ad_suffix); + + return; +} + +void +winsync_plugin_call_get_new_ds_group_dn_cb(const Repl_Agmt *ra, const Slapi_Entry *rawentry, + Slapi_Entry *ad_entry, char **new_dn_string, + const Slapi_DN *ds_suffix, const Slapi_DN *ad_suffix) +{ + winsync_get_new_dn_cb thefunc = + (_WinSyncAPI && _WinSyncAPI[WINSYNC_PLUGIN_GET_NEW_DS_GROUP_DN_CB]) ? + (winsync_get_new_dn_cb)_WinSyncAPI[WINSYNC_PLUGIN_GET_NEW_DS_GROUP_DN_CB] : + NULL; + + if (!thefunc) { + return; + } + + (*thefunc)(windows_private_get_api_cookie(ra), rawentry, ad_entry, + new_dn_string, ds_suffix, ad_suffix); + + return; +} + +void +winsync_plugin_call_pre_ad_mod_user_mods_cb(const Repl_Agmt *ra, const Slapi_Entry *rawentry, + const Slapi_DN *local_dn, LDAPMod * const *origmods, + Slapi_DN *remote_dn, LDAPMod ***modstosend) +{ + winsync_pre_ad_mod_mods_cb thefunc = + (_WinSyncAPI && _WinSyncAPI[WINSYNC_PLUGIN_PRE_AD_MOD_USER_MODS_CB]) ? + (winsync_pre_ad_mod_mods_cb)_WinSyncAPI[WINSYNC_PLUGIN_PRE_AD_MOD_USER_MODS_CB] : + NULL; + + if (!thefunc) { + return; + } + + (*thefunc)(windows_private_get_api_cookie(ra), rawentry, local_dn, + origmods, remote_dn, modstosend); + + return; +} + +void +winsync_plugin_call_pre_ad_mod_group_mods_cb(const Repl_Agmt *ra, const Slapi_Entry *rawentry, + const Slapi_DN *local_dn, LDAPMod * const *origmods, + Slapi_DN *remote_dn, LDAPMod ***modstosend) +{ + winsync_pre_ad_mod_mods_cb thefunc = + (_WinSyncAPI && _WinSyncAPI[WINSYNC_PLUGIN_PRE_AD_MOD_GROUP_MODS_CB]) ? + (winsync_pre_ad_mod_mods_cb)_WinSyncAPI[WINSYNC_PLUGIN_PRE_AD_MOD_GROUP_MODS_CB] : + NULL; + + if (!thefunc) { + return; + } + + (*thefunc)(windows_private_get_api_cookie(ra), rawentry, local_dn, + origmods, remote_dn, modstosend); + + return; +} + +int +winsync_plugin_call_can_add_entry_to_ad_cb(const Repl_Agmt *ra, const Slapi_Entry *local_entry, + const Slapi_DN *remote_dn) +{ + winsync_can_add_to_ad_cb thefunc = + (_WinSyncAPI && _WinSyncAPI[WINSYNC_PLUGIN_CAN_ADD_ENTRY_TO_AD_CB]) ? + (winsync_can_add_to_ad_cb)_WinSyncAPI[WINSYNC_PLUGIN_CAN_ADD_ENTRY_TO_AD_CB] : + NULL; + + if (!thefunc) { + return 1; /* default is entry can be added to AD */ + } + + return (*thefunc)(windows_private_get_api_cookie(ra), local_entry, remote_dn); +} Index: windows_protocol_util.c =================================================================== RCS file: /cvs/dirsec/ldapserver/ldap/servers/plugins/replication/windows_protocol_util.c,v retrieving revision 1.38 retrieving revision 1.39 diff -u -r1.38 -r1.39 --- windows_protocol_util.c 19 Oct 2007 02:09:24 -0000 1.38 +++ windows_protocol_util.c 5 Aug 2008 20:26:22 -0000 1.39 @@ -668,6 +668,7 @@ return_value = ACQUIRE_FATAL_ERROR; } slapi_sdn_free(&replarea_sdn); + csn_free(¤t_csn); } } @@ -1004,7 +1005,6 @@ } if (cn_string) { - char *rdnstr = NULL; char *container_str = NULL; const char *suffix = slapi_sdn_get_dn(windows_private_get_windows_subtree(prp->agmt)); @@ -1184,7 +1184,19 @@ agmt_get_long_name(prp->agmt), op2string(op->operation_type), op->target_address.dn, slapi_sdn_get_dn(remote_dn)); switch (op->operation_type) { - /* For an ADD operation, we map the entry and then send the operation, which may fail if the peer entry already existed */ + /* + we should check the modify case first and check the list of mods - + if the magic objectclass (ntuser) and attributes (ntUserCreateNewAccount + or ntGroupCreateNewAccount) then we should fall through to the ADD case + since the user wants to add the user to AD - could maybe just change + process_replay_add slightly, to add the mods list from the modify + operation - process_replay_add already turns the entry into a mods list + to pass to the ldap add operation, so it should not be too much more + trouble to apply the additional mods from the modify operation - we'll + have to pass in local entry, or perhaps just change the operation from + modify to an add, and set the op->p.p_add.target_entry to the local_entry + which gets retrieved above + */ case SLAPI_OPERATION_ADD: return_value = process_replay_add(prp,op,local_entry,local_dn,remote_dn,is_user,missing_entry,&password); break; @@ -1193,6 +1205,22 @@ LDAPMod **mapped_mods = NULL; windows_map_mods_for_replay(prp,op->p.p_modify.modify_mods, &mapped_mods, is_user, &password); + if (is_user) { + winsync_plugin_call_pre_ad_mod_user_mods_cb(prp->agmt, + windows_private_get_raw_entry(prp->agmt), + local_dn, + op->p.p_modify.modify_mods, + remote_dn, + &mapped_mods); + } else if (is_group) { + winsync_plugin_call_pre_ad_mod_group_mods_cb(prp->agmt, + windows_private_get_raw_entry(prp->agmt), + local_dn, + op->p.p_modify.modify_mods, + remote_dn, + &mapped_mods); + } + /* It's possible that the mapping process results in an empty mod list, in which case we don't bother with the replay */ if ( mapped_mods == NULL || *(mapped_mods)== NULL ) { @@ -1304,7 +1332,7 @@ char *this_attr = NULL; char **list = is_user ? (is_nt4 ? nt4_user_matching_attributes : windows_user_matching_attributes) : (is_nt4 ? nt4_group_matching_attributes : windows_group_matching_attributes); /* Look for the type in the list of straight mapped attrs for the appropriate object type */ - while (this_attr = list[offset]) + while ((this_attr = list[offset])) { if (0 == slapi_attr_type_cmp(this_attr, type, SLAPI_TYPE_CMP_SUBTYPE)) { @@ -1327,7 +1355,7 @@ *mapped_type = NULL; /* Iterate over the map entries looking for the type we have */ - while(this_map = &(our_map[offset])) + while((this_map = &(our_map[offset]))) { char *their_name = to_windows ? this_map->windows_attribute_name : this_map->ldap_attribute_name; char *our_name = to_windows ? this_map->ldap_attribute_name : this_map->windows_attribute_name; @@ -1500,7 +1528,6 @@ if (0 == slapi_attr_type_cmp(new_type, "streetAddress", SLAPI_TYPE_CMP_SUBTYPE)) { if (slapi_valueset_count(vs) > 1) { int i = 0; - const char *street_value = NULL; Slapi_Value *value = NULL; Slapi_Value *new_value = NULL; @@ -2026,6 +2053,10 @@ int rval = 0; const char *subtree_dn = NULL; int not_unique = 0; + char *subtree_dn_copy = NULL; + int scope = LDAP_SCOPE_SUBTREE; + char **attrs = NULL; + LDAPControl **server_controls = NULL; if (pb == NULL) goto done; @@ -2036,12 +2067,21 @@ goto done; subtree_dn = slapi_sdn_get_dn(windows_private_get_directory_subtree(ra)); + subtree_dn_copy = slapi_ch_strdup(subtree_dn); - slapi_search_internal_set_pb(pb, subtree_dn, - LDAP_SCOPE_SUBTREE, query, NULL, 0, NULL, NULL, + winsync_plugin_call_pre_ds_search_entry_cb(ra, NULL, &subtree_dn_copy, &scope, &query, + &attrs, &server_controls); + + slapi_search_internal_set_pb(pb, subtree_dn_copy, + scope, query, attrs, 0, server_controls, NULL, (void *)plugin_get_default_component_id(), 0); slapi_search_internal_pb(pb); + slapi_ch_free_string(&subtree_dn_copy); slapi_ch_free_string(&query); + slapi_ch_array_free(attrs); + attrs = NULL; + ldap_controls_free(server_controls); + server_controls = NULL; slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_RESULT, &rval); if (rval != LDAP_SUCCESS) @@ -2096,7 +2136,7 @@ char *p = str; char c = '\0'; - while (c = *p) + while ((c = *p)) { if ('-' == c) { @@ -2254,7 +2294,7 @@ /* The tombstone suffix discards any containers, so we need * to trim the DN to only dc components. */ - if (suffix = slapi_sdn_get_dn(windows_private_get_windows_subtree(prp->agmt))) { + if ((suffix = slapi_sdn_get_dn(windows_private_get_windows_subtree(prp->agmt)))) { /* If this isn't found, it is treated as an error below. */ suffix = (const char *) PL_strcasestr(suffix,"dc="); } @@ -2358,7 +2398,6 @@ char *dn_string = NULL; if (guid) { - new_dn = slapi_sdn_new(); if (is_nt4) { dn_string = PR_smprintf("GUID=%s,%s",guid,suffix); @@ -2366,7 +2405,7 @@ { dn_string = PR_smprintf("",guid); } - slapi_sdn_init_dn_byval(new_dn,dn_string); + new_dn = slapi_sdn_new_dn_byval(dn_string); PR_smprintf_free(dn_string); } /* dn string is now inside the Slapi_DN, and will be freed by its owner */ @@ -2452,6 +2491,7 @@ * without removing the ntUniqueID attribute. We should verify that the entry really * exists in AD. */ rc = windows_get_remote_entry(prp, new_dn, &remote_entry); + slapi_sdn_free(&new_dn); if (0 == rc && remote_entry) { slapi_entry_free(remote_entry); } else { @@ -2471,7 +2511,6 @@ } if (cn_string) { - char *rdnstr = NULL; char *container_str = NULL; container_str = extract_container(slapi_entry_get_sdn_const(e), @@ -2719,9 +2758,23 @@ if (is_user) { new_dn_string = PR_smprintf("uid=%s,%s%s",username,container_str,suffix); + winsync_plugin_call_get_new_ds_user_dn_cb(ra, + windows_private_get_raw_entry(ra), + e, + &new_dn_string, + windows_private_get_directory_subtree(ra), + windows_private_get_windows_subtree(ra)); } else { new_dn_string = PR_smprintf("cn=%s,%s%s",username,container_str,suffix); + if (is_group) { + winsync_plugin_call_get_new_ds_group_dn_cb(ra, + windows_private_get_raw_entry(ra), + e, + &new_dn_string, + windows_private_get_directory_subtree(ra), + windows_private_get_windows_subtree(ra)); + } } new_dn = slapi_sdn_new_dn_byval(new_dn_string); PR_smprintf_free(new_dn_string); @@ -2939,6 +2992,18 @@ { slapi_entry_add_string(local_entry,"sn",username); } + + if (is_user) { + winsync_plugin_call_pre_ds_add_user_cb(prp->agmt, + windows_private_get_raw_entry(prp->agmt), + remote_entry, + local_entry); + } else if (is_group) { + winsync_plugin_call_pre_ds_add_group_cb(prp->agmt, + windows_private_get_raw_entry(prp->agmt), + remote_entry, + local_entry); + } /* Store it */ windows_dump_entry("Adding new local entry",local_entry); pb = slapi_pblock_new(); @@ -2951,6 +3016,7 @@ "add operation of entry %s returned: %d\n", slapi_sdn_get_dn(local_sdn), retval); } error: + slapi_ch_free_string(&guid_str); if (pb) { slapi_pblock_destroy(pb); @@ -3115,7 +3181,6 @@ * sure we don't try to send more than one value. */ if (slapi_valueset_count(vs) > 1) { int i = 0; - const char *street_value = NULL; Slapi_Value *value = NULL; Slapi_Value *new_value = NULL; @@ -3229,7 +3294,6 @@ * sure we don't try to send more than one value. */ if (slapi_valueset_count(vs) > 1) { int i = 0; - const char *street_value = NULL; Slapi_Value *value = NULL; Slapi_Value *new_value = NULL; @@ -3318,6 +3382,40 @@ slapi_ch_free_string(&local_type); } + if (to_windows) { + if (is_user) { + winsync_plugin_call_pre_ad_mod_user_cb(prp->agmt, + windows_private_get_raw_entry(prp->agmt), + local_entry, /* the cooked ad entry */ + remote_entry, /* the ds entry */ + smods, + do_modify); + } else if (is_group) { + winsync_plugin_call_pre_ad_mod_group_cb(prp->agmt, + windows_private_get_raw_entry(prp->agmt), + local_entry, /* the cooked ad entry */ + remote_entry, /* the ds entry */ + smods, + do_modify); + } + } else { + if (is_user) { + winsync_plugin_call_pre_ds_mod_user_cb(prp->agmt, + windows_private_get_raw_entry(prp->agmt), + remote_entry, /* the cooked ad entry */ + local_entry, /* the ds entry */ + smods, + do_modify); + } else if (is_group) { + winsync_plugin_call_pre_ds_mod_group_cb(prp->agmt, + windows_private_get_raw_entry(prp->agmt), + remote_entry, /* the cooked ad entry */ + local_entry, /* the ds entry */ + smods, + do_modify); + } + } + if (slapi_is_loglevel_set(SLAPI_LOG_REPL) && *do_modify) { slapi_mods_dump(smods,"windows sync"); @@ -3412,10 +3510,16 @@ Slapi_Entry *mapped_entry = NULL; char *password = NULL; const Slapi_DN* local_dn = NULL; + int can_add = winsync_plugin_call_can_add_entry_to_ad_cb(prp->agmt, e, remote_dn); /* First map the entry */ local_dn = slapi_entry_get_sdn_const(e); - if (missing_entry) - retval = windows_create_remote_entry(prp, e, remote_dn, &mapped_entry, &password); + if (missing_entry) { + if (can_add) { + retval = windows_create_remote_entry(prp, e, remote_dn, &mapped_entry, &password); + } else { + return retval; /* cannot add and no entry to modify */ + } + } /* Convert entry to mods */ if (0 == retval && mapped_entry) { Index: windows_tot_protocol.c =================================================================== RCS file: /cvs/dirsec/ldapserver/ldap/servers/plugins/replication/windows_tot_protocol.c,v retrieving revision 1.12 retrieving revision 1.13 diff -u -r1.12 -r1.13 --- windows_tot_protocol.c 18 Oct 2007 00:08:31 -0000 1.12 +++ windows_tot_protocol.c 5 Aug 2008 20:26:22 -0000 1.13 @@ -99,11 +99,15 @@ int rc; callback_data cb_data; Slapi_PBlock *pb; - const char* dn; + char* dn; RUV *ruv = NULL; RUV *starting_ruv = NULL; Replica *replica = NULL; Object *local_ruv_obj = NULL; + int scope = LDAP_SCOPE_SUBTREE; + char *filter = slapi_ch_strdup("(|(objectclass=ntuser)(objectclass=ntgroup))"); + char **attrs = NULL; + LDAPControl **server_controls = NULL; LDAPDebug( LDAP_DEBUG_TRACE, "=> windows_tot_run\n", 0, 0, 0 ); @@ -168,13 +172,15 @@ /* send everything */ - dn = slapi_sdn_get_dn( windows_private_get_directory_subtree(prp->agmt)); + dn = slapi_ch_strdup(slapi_sdn_get_dn( windows_private_get_directory_subtree(prp->agmt))); + + winsync_plugin_call_pre_ds_search_all_cb(prp->agmt, NULL, &dn, &scope, &filter, + &attrs, &server_controls); pb = slapi_pblock_new (); /* Perform a subtree search for any ntuser or ntgroup entries underneath the * suffix defined in the sync agreement. */ - slapi_search_internal_set_pb (pb, dn, - LDAP_SCOPE_SUBTREE, "(|(objectclass=ntuser)(objectclass=ntgroup))", NULL, 0, NULL, NULL, + slapi_search_internal_set_pb (pb, dn, scope, filter, attrs, 0, server_controls, NULL, repl_get_plugin_identity (PLUGIN_MULTIMASTER_REPLICATION), 0); cb_data.prp = prp; cb_data.rc = 0; @@ -186,6 +192,13 @@ get_result /* result callback */, send_entry /* entry callback */, NULL /* referral callback*/); + slapi_ch_free_string(&dn); + slapi_ch_free_string(&filter); + slapi_ch_array_free(attrs); + attrs = NULL; + ldap_controls_free(server_controls); + server_controls = NULL; + slapi_pblock_destroy (pb); agmt_set_last_init_end(prp->agmt, current_time()); rc = cb_data.rc; Index: windowsrepl.h =================================================================== RCS file: /cvs/dirsec/ldapserver/ldap/servers/plugins/replication/windowsrepl.h,v retrieving revision 1.14 retrieving revision 1.15 diff -u -r1.14 -r1.15 --- windowsrepl.h 27 Sep 2007 18:33:30 -0000 1.14 +++ windowsrepl.h 5 Aug 2008 20:26:22 -0000 1.15 @@ -44,9 +44,9 @@ /* windows_private.c */ typedef struct windowsprivate Dirsync_Private; Dirsync_Private* windows_private_new(); -void windows_private_set_windows_subtree (const Repl_Agmt *ra,const Slapi_DN* sdn ); +void windows_private_set_windows_subtree (const Repl_Agmt *ra,Slapi_DN* sdn ); const Slapi_DN* windows_private_get_windows_subtree (const Repl_Agmt *ra); -void windows_private_set_directory_subtree (const Repl_Agmt *ra,const Slapi_DN* sdn ); +void windows_private_set_directory_subtree (const Repl_Agmt *ra,Slapi_DN* sdn ); const Slapi_DN* windows_private_get_directory_subtree (const Repl_Agmt *ra); LDAPControl* windows_private_dirsync_control(const Repl_Agmt *ra); ConnResult send_dirsync_search(Repl_Connection *conn); @@ -63,7 +63,6 @@ void windows_private_set_create_groups(const Repl_Agmt *ra, PRBool value); PRBool windows_private_create_groups(const Repl_Agmt *ra); const char *windows_private_get_windows_domain(const Repl_Agmt *ra); -static void windows_private_set_windows_domain(const Repl_Agmt *ra, char *domain); int windows_private_get_isnt4(const Repl_Agmt *ra); void windows_private_set_isnt4(const Repl_Agmt *ra, int isit); int windows_private_get_iswin2k3(const Repl_Agmt *ra); @@ -71,6 +70,16 @@ Slapi_Filter* windows_private_get_directory_filter(const Repl_Agmt *ra); Slapi_Filter* windows_private_get_deleted_filter(const Repl_Agmt *ra); const char* windows_private_get_purl(const Repl_Agmt *ra); +/* + * The raw entry is the last raw entry read from AD - raw as opposed + * "cooked" - that is, having had schema processing done + */ +/* get returns a pointer to the structure - do not free */ +Slapi_Entry *windows_private_get_raw_entry(const Repl_Agmt *ra); +/* this is passin - windows_private owns the pointer, not a copy */ +void windows_private_set_raw_entry(const Repl_Agmt *ra, Slapi_Entry *e); +void *windows_private_get_api_cookie(const Repl_Agmt *ra); +void windows_private_set_api_cookie(Repl_Agmt *ra, void *cookie); /* in windows_connection.c */ ConnResult windows_conn_connect(Repl_Connection *conn); @@ -112,3 +121,86 @@ /* Used for GUID format conversion */ #define NTUNIQUEID_LENGTH 32 #define AD_GUID_LENGTH 36 + +/* called for each replication agreement - so the winsync + plugin can be agreement specific and store agreement + specific data +*/ +void windows_plugin_init(Repl_Agmt *ra); + +void winsync_plugin_call_dirsync_search_params_cb(const Repl_Agmt *ra, const char *agmt_dn, char **base, int *scope, char **filter, char ***attrs, LDAPControl ***serverctrls); +/* called before searching for a single entry from AD - agmt_dn will be NULL */ +void winsync_plugin_call_pre_ad_search_cb(const Repl_Agmt *ra, const char *agmt_dn, char **base, int *scope, char **filter, char ***attrs, LDAPControl ***serverctrls); +/* called before an internal search to get a single DS entry - agmt_dn will be NULL */ +void winsync_plugin_call_pre_ds_search_entry_cb(const Repl_Agmt *ra, const char *agmt_dn, char **base, int *scope, char **filter, char ***attrs, LDAPControl ***serverctrls); +/* called before the total update to get all entries from the DS to sync to AD */ +void winsync_plugin_call_pre_ds_search_all_cb(const Repl_Agmt *ra, const char *agmt_dn, char **base, int *scope, char **filter, char ***attrs, LDAPControl ***serverctrls); + +void winsync_plugin_call_pre_ad_mod_user_cb(const Repl_Agmt *ra, const Slapi_Entry *rawentry, Slapi_Entry *ad_entry, Slapi_Entry *ds_entry, Slapi_Mods *smods, int *do_modify); +void winsync_plugin_call_pre_ad_mod_group_cb(const Repl_Agmt *ra, const Slapi_Entry *rawentry, Slapi_Entry *ad_entry, Slapi_Entry *ds_entry, Slapi_Mods *smods, int *do_modify); +void winsync_plugin_call_pre_ds_mod_user_cb(const Repl_Agmt *ra, const Slapi_Entry *rawentry, Slapi_Entry *ad_entry, Slapi_Entry *ds_entry, Slapi_Mods *smods, int *do_modify); +void winsync_plugin_call_pre_ds_mod_group_cb(const Repl_Agmt *ra, const Slapi_Entry *rawentry, Slapi_Entry *ad_entry, Slapi_Entry *ds_entry, Slapi_Mods *smods, int *do_modify); + +void winsync_plugin_call_pre_ds_add_user_cb(const Repl_Agmt *ra, const Slapi_Entry *rawentry, Slapi_Entry *ad_entry, Slapi_Entry *ds_entry); +void winsync_plugin_call_pre_ds_add_group_cb(const Repl_Agmt *ra, const Slapi_Entry *rawentry, Slapi_Entry *ad_entry, Slapi_Entry *ds_entry); + +void winsync_plugin_call_get_new_ds_user_dn_cb(const Repl_Agmt *ra, const Slapi_Entry *rawentry, Slapi_Entry *ad_entry, + char **new_dn_string, const Slapi_DN *ds_suffix, const Slapi_DN *ad_suffix); +void winsync_plugin_call_get_new_ds_group_dn_cb(const Repl_Agmt *ra, const Slapi_Entry *rawentry, Slapi_Entry *ad_entry, + char **new_dn_string, const Slapi_DN *ds_suffix, const Slapi_DN *ad_suffix); + +void winsync_plugin_call_pre_ad_mod_user_mods_cb(const Repl_Agmt *ra, const Slapi_Entry *rawentry, const Slapi_DN *local_dn, LDAPMod * const *origmods, Slapi_DN *remote_dn, LDAPMod ***modstosend); +void winsync_plugin_call_pre_ad_mod_group_mods_cb(const Repl_Agmt *ra, const Slapi_Entry *rawentry, const Slapi_DN *local_dn, LDAPMod * const *origmods, Slapi_DN *remote_dn, LDAPMod ***modstosend); + +int winsync_plugin_call_can_add_entry_to_ad_cb(const Repl_Agmt *ra, const Slapi_Entry *local_entry, const Slapi_DN *remote_dn); +/* + Call stack for all places where windows_LDAPMessage2Entry is called: + + windows_LDAPMessage2Entry + ++windows_seach_entry_ext + ++++windows_search_entry + ++++++windows_get_remote_entry + map_dn_values + windows_create_remote_entry + process_replay_add + windows_process_total_add + windows_map_mods_for_replay + windows_replay_update + send_updates + windows_inc_run + windows_create_local_entry + windows_process_dirsync_entry + windows_generate_update_mods + windows_update_remote_entry + process_replay_add + windows_process_total_add + windows_update_local_entry + windows_process_dirsync_entry + process_replay_add + windows_replay_update + map_entry_dn_outbound + map_dn_values + windows_replay_update + windows_process_total_entry + send_entry + windows_tot_run + windows_process_total_add + windows_process_total_entry + send_entry + windows_tot_run + windows_process_dirsync_entry + windows_dirsync_inc_run + find_entry_by_attr_value_remote + map_entry_dn_outbound + ++++windows_get_remote_tombstone + map_windows_tombstone_dn + process_replay_add + ++windows_conn_get_search_result + windows_dirsync_inc_run + + + windows_inc_protocol + ++send_updates + ++++windows_replay_update +*/ +/* #define WINSYNC_TEST 1 */ /* fake ad is really just a regular ds */ From fedora-directory-commits at redhat.com Tue Aug 5 22:18:39 2008 From: fedora-directory-commits at redhat.com (Nathan Kinder (nkinder)) Date: Tue, 5 Aug 2008 18:18:39 -0400 Subject: [Fedora-directory-commits] ldapserver/ldap/servers/plugins/dna dna.c, 1.7, 1.8 Message-ID: <200808052218.m75MIdsv026443@cvs-int.fedora.redhat.com> Author: nkinder Update of /cvs/dirsec/ldapserver/ldap/servers/plugins/dna In directory cvs-int.fedora.redhat.com:/tmp/cvs-serv26374/ldap/servers/plugins/dna Modified Files: dna.c Log Message: Resolves: 457951 Summary: Don't perform a sorted range search in the DNA plug-in if a prefix is configured. Index: dna.c =================================================================== RCS file: /cvs/dirsec/ldapserver/ldap/servers/plugins/dna/dna.c,v retrieving revision 1.7 retrieving revision 1.8 diff -u -r1.7 -r1.8 --- dna.c 31 Jul 2008 16:22:25 -0000 1.7 +++ dna.c 5 Aug 2008 22:18:36 -0000 1.8 @@ -801,22 +801,29 @@ /* we do search all values between nextval and maxval asking the * server to sort them, then we check the first free spot and - * use it as newval */ + * use it as newval. If we go past the end of the range, we + * return LDAP_OPERATIONS_ERROR and set newval to be > the + * maximum configured value for this range. */ static int dna_first_free_value(struct configEntry *config_entry, PRUint64 *newval) { Slapi_Entry **entries = NULL; Slapi_PBlock *pb = NULL; - LDAPControl **ctrls; + LDAPControl **ctrls = NULL; char *attrs[2]; char *filter; char *prefix; char *type; - int preflen; - int result, status; + int result, status, filterlen; PRUint64 tmpval, sval, i; char *strval = NULL; + /* check if the config is already out of range */ + if (config_entry->nextval > config_entry->maxval) { + *newval = config_entry->nextval; + return LDAP_OPERATIONS_ERROR; + } + prefix = config_entry->prefix; type = config_entry->type; tmpval = config_entry->nextval; @@ -824,30 +831,46 @@ attrs[0] = type; attrs[1] = NULL; - ctrls = (LDAPControl **)slapi_ch_calloc(2, sizeof(LDAPControl)); - if (NULL == ctrls) - return LDAP_OPERATIONS_ERROR; + /* We don't sort if we're using a prefix (non integer type). Instead, + * we just search to see if the next value is free, and keep incrementing + * until we find the next free value. */ + if (prefix) { + /* The 7 below is for all of the filter characters "(&(=))" + * plus the trailing \0. The 20 is for the maximum string + * representation of a %llu. */ + filterlen = strlen(config_entry->filter) + + strlen(prefix) + strlen(type) + + 7 + 20; + filter = slapi_ch_malloc(filterlen); + snprintf(filter, filterlen, "(&%s(%s=%s%llu))", + config_entry->filter, type, prefix, tmpval); + } else { + ctrls = (LDAPControl **)slapi_ch_calloc(2, sizeof(LDAPControl)); + if (NULL == ctrls) + return LDAP_OPERATIONS_ERROR; + + ctrls[0] = dna_build_sort_control(config_entry->type); + if (NULL == ctrls[0]) { + slapi_ch_free((void **)&ctrls); + return LDAP_OPERATIONS_ERROR; + } - ctrls[0] = dna_build_sort_control(config_entry->type); - if (NULL == ctrls[0]) { - slapi_ch_free((void **)&ctrls); - return LDAP_OPERATIONS_ERROR; + filter = slapi_ch_smprintf("(&%s(&(%s>=%llu)(%s<=%llu)))", + config_entry->filter, + type, tmpval, + type, config_entry->maxval); } - filter = slapi_ch_smprintf("(&%s(&(%s>=%s%llu)(%s<=%s%llu)))", - config_entry->filter, - type, prefix?prefix:"", tmpval, - type, prefix?prefix:"", config_entry->maxval); if (NULL == filter) { - ldap_control_free(ctrls[0]); - slapi_ch_free((void **)&ctrls); + ldap_controls_free(ctrls); + ctrls = NULL; return LDAP_OPERATIONS_ERROR; } pb = slapi_pblock_new(); if (NULL == pb) { - ldap_control_free(ctrls[0]); - slapi_ch_free((void **)&ctrls); + ldap_controls_free(ctrls); + ctrls = NULL; slapi_ch_free_string(&filter); return LDAP_OPERATIONS_ERROR; } @@ -857,10 +880,6 @@ attrs, 0, ctrls, NULL, getPluginID(), 0); slapi_search_internal_pb(pb); -/* - ldap_control_free(ctrls[0]); -*/ - slapi_ch_free_string(&filter); slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_RESULT, &result); if (LDAP_SUCCESS != result) { @@ -878,46 +897,86 @@ goto cleanup; } - /* entries are sorted and filtered for value >= tval therefore if the - * first one does not match tval it means that the value is free, - * otherwise we need to cycle through values until we find a mismatch, - * the first mismatch is the first free pit */ - - preflen = prefix?strlen(prefix):0; - sval = 0; - for (i = 0; NULL != entries[i]; i++) { - strval = slapi_entry_attr_get_charptr(entries[i], type); - if (preflen) { - if (strlen(strval) <= preflen) { - /* something very wrong here ... */ + if (prefix) { + /* The next value identified in the config entry has already + * been taken. We just iterate through the values until we + * (hopefully) find a free one. */ + for (tmpval += config_entry->interval; tmpval <= config_entry->maxval; + tmpval += config_entry->interval) { + /* filter is guaranteed to be big enough since we allocated + * enough space to fit a string representation of any unsigned + * 64-bit integer */ + snprintf(filter, filterlen, "(&%s(%s=%s%llu))", + config_entry->filter, type, prefix, tmpval); + + /* clear out the pblock so we can re-use it */ + slapi_free_search_results_internal(pb); + slapi_pblock_init(pb); + + slapi_search_internal_set_pb(pb, config_entry->scope, + LDAP_SCOPE_SUBTREE, filter, + attrs, 0, 0, + NULL, getPluginID(), 0); + + slapi_search_internal_pb(pb); + + slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_RESULT, &result); + if (LDAP_SUCCESS != result) { status = LDAP_OPERATIONS_ERROR; goto cleanup; } - strval = &strval[preflen-1]; - } - errno = 0; - sval = strtoul(strval, 0, 0); - if (errno) { - /* something very wrong here ... */ - status = LDAP_OPERATIONS_ERROR; - goto cleanup; + slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES, + &entries); + + if (NULL == entries || NULL == entries[0]) { + /* no values means we already have a good value */ + *newval = tmpval; + status = LDAP_SUCCESS; + goto cleanup; + } } - slapi_ch_free_string(&strval); + } else { + /* entries are sorted and filtered for value >= tval therefore if the + * first one does not match tval it means that the value is free, + * otherwise we need to cycle through values until we find a mismatch, + * the first mismatch is the first free pit */ + sval = 0; + for (i = 0; NULL != entries[i]; i++) { + strval = slapi_entry_attr_get_charptr(entries[i], type); + errno = 0; + sval = strtoul(strval, 0, 0); + if (errno) { + /* something very wrong here ... */ + status = LDAP_OPERATIONS_ERROR; + goto cleanup; + } + slapi_ch_free_string(&strval); - if (tmpval != sval) - break; + if (tmpval != sval) + break; - if (config_entry->maxval < sval) - break; + if (config_entry->maxval < sval) + break; - tmpval += config_entry->interval; + tmpval += config_entry->interval; + } } - *newval = tmpval; - status = LDAP_SUCCESS; + /* check if we went past the end of the range */ + if (tmpval <= config_entry->maxval) { + *newval = tmpval; + status = LDAP_SUCCESS; + } else { + /* we set newval past the end of the range + * so the caller can easily detect that we + * overflowed the configured range. */ + *newval = tmpval; + status = LDAP_OPERATIONS_ERROR; + } cleanup: + slapi_ch_free_string(&filter); slapi_ch_free_string(&strval); slapi_free_search_results_internal(pb); slapi_pblock_destroy(pb); @@ -950,69 +1009,79 @@ /* get the first value */ ret = dna_first_free_value(config_entry, &setval); - if (LDAP_SUCCESS != ret) - goto done; + if (LDAP_SUCCESS != ret) { + /* check if we overflowed the configured range */ + if (setval > config_entry->maxval) { + /* try for a new range or fail */ + ret = dna_fix_maxval(config_entry, &setval); + if (LDAP_SUCCESS != ret) { + slapi_log_error(SLAPI_LOG_FATAL, DNA_PLUGIN_SUBSYSTEM, + "dna_get_next_value: no more IDs available!!\n"); + goto done; + } - /* try for a new range or fail */ - if (setval > config_entry->maxval) { - ret = dna_fix_maxval(config_entry, &setval); - if (LDAP_SUCCESS != ret) { + /* get the first value from our newly extended range */ + ret = dna_first_free_value(config_entry, &setval); + if (LDAP_SUCCESS != ret) + goto done; + } else { + /* dna_first_free_value() failed for some unknown reason */ slapi_log_error(SLAPI_LOG_FATAL, DNA_PLUGIN_SUBSYSTEM, - "dna_get_next_value: no more IDs available!!\n"); + "dna_get_next_value: failed to allocate a new ID!!\n"); goto done; } - - /* get the first value from our newly extended range */ - ret = dna_first_free_value(config_entry, &setval); - if (LDAP_SUCCESS != ret) - goto done; - } - - /* ensure that we haven't gone past the end of our range */ - if (setval > config_entry->maxval) { - ret = LDAP_OPERATIONS_ERROR; - goto done; } nextval = setval + config_entry->interval; - - /* try for a new range or fail */ + /* check if the next value will overflow the range */ if (nextval > config_entry->maxval) { + /* try for a new range now, but let this operation through either way */ ret = dna_fix_maxval(config_entry, &nextval); if (LDAP_SUCCESS != ret) { + /* We were unable to extend the range. The allocation + * for this operation was fine, but the next free value + * is outside of the configured range. + * + * We log an error message, but let the original operation + * go through. We skip updating the config entry with + * the new nextval since it falls outside of the configured + * range. + * + * The next attempt to allocate a new value from this + * range will fail. */ slapi_log_error(SLAPI_LOG_FATAL, DNA_PLUGIN_SUBSYSTEM, "dna_get_next_value: no more IDs available!!\n"); - goto done; + ret = LDAP_SUCCESS; } - } - - /* try to set the new next value in the config entry */ - snprintf(next_value, sizeof(next_value),"%llu", nextval); + } else { + /* try to set the new next value in the config entry */ + snprintf(next_value, sizeof(next_value),"%llu", nextval); - /* set up our replace modify operation */ - replace_val[0] = next_value; - replace_val[1] = 0; - mod_replace.mod_op = LDAP_MOD_REPLACE; - mod_replace.mod_type = DNA_NEXTVAL; - mod_replace.mod_values = replace_val; - mods[0] = &mod_replace; - mods[1] = 0; + /* set up our replace modify operation */ + replace_val[0] = next_value; + replace_val[1] = 0; + mod_replace.mod_op = LDAP_MOD_REPLACE; + mod_replace.mod_type = DNA_NEXTVAL; + mod_replace.mod_values = replace_val; + mods[0] = &mod_replace; + mods[1] = 0; - pb = slapi_pblock_new(); - if (NULL == pb) { - ret = LDAP_OPERATIONS_ERROR; - goto done; - } + pb = slapi_pblock_new(); + if (NULL == pb) { + ret = LDAP_OPERATIONS_ERROR; + goto done; + } - slapi_modify_internal_set_pb(pb, config_entry->dn, - mods, 0, 0, getPluginID(), 0); + slapi_modify_internal_set_pb(pb, config_entry->dn, + mods, 0, 0, getPluginID(), 0); - slapi_modify_internal_pb(pb); + slapi_modify_internal_pb(pb); - slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_RESULT, &ret); + slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_RESULT, &ret); - slapi_pblock_destroy(pb); - pb = NULL; + slapi_pblock_destroy(pb); + pb = NULL; + } if (LDAP_SUCCESS == ret) { *next_value_ret = slapi_ch_smprintf("%llu", setval); From fedora-directory-commits at redhat.com Tue Aug 5 22:18:39 2008 From: fedora-directory-commits at redhat.com (Nathan Kinder (nkinder)) Date: Tue, 5 Aug 2008 18:18:39 -0400 Subject: [Fedora-directory-commits] ldapserver/ldap/servers/slapd pblock.c, 1.15, 1.16 slapi-plugin.h, 1.27, 1.28 Message-ID: <200808052218.m75MIdNT026451@cvs-int.fedora.redhat.com> Author: nkinder Update of /cvs/dirsec/ldapserver/ldap/servers/slapd In directory cvs-int.fedora.redhat.com:/tmp/cvs-serv26374/ldap/servers/slapd Modified Files: pblock.c slapi-plugin.h Log Message: Resolves: 457951 Summary: Don't perform a sorted range search in the DNA plug-in if a prefix is configured. Index: pblock.c =================================================================== RCS file: /cvs/dirsec/ldapserver/ldap/servers/slapd/pblock.c,v retrieving revision 1.15 retrieving revision 1.16 diff -u -r1.15 -r1.16 --- pblock.c 15 Jul 2008 16:49:42 -0000 1.15 +++ pblock.c 5 Aug 2008 22:18:37 -0000 1.16 @@ -96,6 +96,16 @@ } void +slapi_pblock_init( Slapi_PBlock *pb ) +{ + if(pb!=NULL) + { + pblock_done(pb); + pblock_init(pb); + } +} + +void pblock_done( Slapi_PBlock *pb ) { if(pb->pb_op!=NULL) Index: slapi-plugin.h =================================================================== RCS file: /cvs/dirsec/ldapserver/ldap/servers/slapd/slapi-plugin.h,v retrieving revision 1.27 retrieving revision 1.28 diff -u -r1.27 -r1.28 --- slapi-plugin.h 5 Aug 2008 20:26:22 -0000 1.27 +++ slapi-plugin.h 5 Aug 2008 22:18:37 -0000 1.28 @@ -186,6 +186,7 @@ * parameter block routines */ Slapi_PBlock *slapi_pblock_new( void ); /* allocate and initialize */ +void slapi_pblock_init( Slapi_PBlock *pb ); /* clear out for re-use */ int slapi_pblock_get( Slapi_PBlock *pb, int arg, void *value ); int slapi_pblock_set( Slapi_PBlock *pb, int arg, void *value ); void slapi_pblock_destroy( Slapi_PBlock *pb ); From fedora-directory-commits at redhat.com Tue Aug 5 22:43:31 2008 From: fedora-directory-commits at redhat.com (Richard Allen Megginson (rmeggins)) Date: Tue, 5 Aug 2008 18:43:31 -0400 Subject: [Fedora-directory-commits] ldapserver/ldap/servers/plugins/replication windows_private.c, 1.18, 1.19 Message-ID: <200808052243.m75MhVkp027590@cvs-int.fedora.redhat.com> Author: rmeggins Update of /cvs/dirsec/ldapserver/ldap/servers/plugins/replication In directory cvs-int.fedora.redhat.com:/tmp/cvs-serv27573 Modified Files: windows_private.c Log Message: Resolves: bug 457846 Bug Description: The Windows Sync API should have plug-in points Fix Description: forgot to add #include "winsync-plugin.h" Index: windows_private.c =================================================================== RCS file: /cvs/dirsec/ldapserver/ldap/servers/plugins/replication/windows_private.c,v retrieving revision 1.18 retrieving revision 1.19 diff -u -r1.18 -r1.19 --- windows_private.c 5 Aug 2008 20:26:22 -0000 1.18 +++ windows_private.c 5 Aug 2008 22:43:29 -0000 1.19 @@ -48,6 +48,7 @@ #include "slap.h" #include "slapi-plugin.h" #include "windowsrepl.h" +#include "winsync-plugin.h" struct windowsprivate { From fedora-directory-commits at redhat.com Thu Aug 7 18:35:30 2008 From: fedora-directory-commits at redhat.com (Richard Allen Megginson (rmeggins)) Date: Thu, 7 Aug 2008 14:35:30 -0400 Subject: [Fedora-directory-commits] ldapserver/ldap/servers/plugins/syntaxes string.c, 1.9.2.3, 1.9.2.4 Message-ID: <200808071835.m77IZURn014353@cvs-int.fedora.redhat.com> Author: rmeggins Update of /cvs/dirsec/ldapserver/ldap/servers/plugins/syntaxes In directory cvs-int.fedora.redhat.com:/tmp/cvs-serv14316 Modified Files: Tag: Directory_Server_8_0_Branch string.c Log Message: Resolves: bug 458171 Description: string_filter_approx used to simply return the return value from strcmp. The value could be evaluated as LDAP RETURN CODE. string_filter_approx is a static function and it's called only from string_filter_ava. The function returns -1 when it fails. Thus, adjusting the return value of string_filter_approx to the caller function. Branch: Directory_Server_8_0_Branch Index: string.c =================================================================== RCS file: /cvs/dirsec/ldapserver/ldap/servers/plugins/syntaxes/string.c,v retrieving revision 1.9.2.3 retrieving revision 1.9.2.4 diff -u -r1.9.2.3 -r1.9.2.4 --- string.c 18 Jul 2008 23:13:41 -0000 1.9.2.3 +++ string.c 7 Aug 2008 18:35:27 -0000 1.9.2.4 @@ -112,6 +112,10 @@ return( -1 ); } +/* + * return value: 0 -- approximately matched + * -1 -- did not match + */ static int string_filter_approx( struct berval *bvfilter, Slapi_Value **bvals, Slapi_Value **retVal) @@ -179,6 +183,9 @@ break; } } + if (0 != rc) { + rc = -1; + } LDAPDebug( LDAP_DEBUG_TRACE, "<= string_filter_approx %d\n", rc, 0, 0 ); From fedora-directory-commits at redhat.com Thu Aug 7 21:55:34 2008 From: fedora-directory-commits at redhat.com (Richard Allen Megginson (rmeggins)) Date: Thu, 7 Aug 2008 17:55:34 -0400 Subject: [Fedora-directory-commits] ldapserver/ldap/servers/plugins/syntaxes string.c, 1.14, 1.15 Message-ID: <200808072155.m77LtYA1021748@cvs-int.fedora.redhat.com> Author: rmeggins Update of /cvs/dirsec/ldapserver/ldap/servers/plugins/syntaxes In directory cvs-int.fedora.redhat.com:/tmp/cvs-serv21728 Modified Files: string.c Log Message: Resolves: bug 458171 Description: approx search accidentally fails with timelimit although it hasn't hit timelimit. Fix Description: string_filter_approx used to simply return the return value from strcmp. The value could be evaluated as LDAP RETURN CODE. string_filter_approx is a static function and it's called only from string_filter_ava. The function returns -1 when it fails. Thus, adjusting the return value of string_filter_approx to the caller function. Index: string.c =================================================================== RCS file: /cvs/dirsec/ldapserver/ldap/servers/plugins/syntaxes/string.c,v retrieving revision 1.14 retrieving revision 1.15 diff -u -r1.14 -r1.15 --- string.c 23 Jul 2008 14:59:56 -0000 1.14 +++ string.c 7 Aug 2008 21:55:30 -0000 1.15 @@ -114,6 +114,10 @@ return( -1 ); } +/* + * return value: 0 -- approximately matched + * -1 -- did not match + */ static int string_filter_approx( struct berval *bvfilter, Slapi_Value **bvals, Slapi_Value **retVal) @@ -181,6 +185,9 @@ break; } } + if (0 != rc) { + rc = -1; + } LDAPDebug( LDAP_DEBUG_TRACE, "<= string_filter_approx %d\n", rc, 0, 0 ); From fedora-directory-commits at redhat.com Fri Aug 8 15:53:13 2008 From: fedora-directory-commits at redhat.com (Nathan Kinder (nkinder)) Date: Fri, 8 Aug 2008 11:53:13 -0400 Subject: [Fedora-directory-commits] ldapserver/ldap/servers/slapd/back-ldbm ldbm_search.c, 1.13, 1.14 Message-ID: <200808081553.m78FrDBI004447@cvs-int.fedora.redhat.com> Author: nkinder Update of /cvs/dirsec/ldapserver/ldap/servers/slapd/back-ldbm In directory cvs-int.fedora.redhat.com:/tmp/cvs-serv4227/back-ldbm Modified Files: ldbm_search.c Log Message: Resolves: 458135 Summary: Don't log SORT control message for internal operations. Index: ldbm_search.c =================================================================== RCS file: /cvs/dirsec/ldapserver/ldap/servers/slapd/back-ldbm/ldbm_search.c,v retrieving revision 1.13 retrieving revision 1.14 diff -u -r1.13 -r1.14 --- ldbm_search.c 30 Jun 2008 17:28:16 -0000 1.13 +++ ldbm_search.c 8 Aug 2008 15:53:10 -0000 1.14 @@ -478,9 +478,12 @@ char *sort_error_type = NULL; int sort_return_value = 0; - /* Log to the access log the particulars of this sort request */ - /* Log message looks like this: SORT <#candidates> | */ - sort_log_access(pb,sort_control,candidates); + /* Don't log internal operations */ + if (!operation_is_flag_set(operation, OP_FLAG_INTERNAL)) { + /* Log to the access log the particulars of this sort request */ + /* Log message looks like this: SORT <#candidates> | */ + sort_log_access(pb,sort_control,candidates); + } sort_return_value = sort_candidates( be, lookthrough_limit, time_up, pb, candidates, sort_control, &sort_error_type ); /* Fix for bugid # 394184, SD, 20 Jul 00 */ /* replace the hard coded return value by the appropriate LDAP error code */ From fedora-directory-commits at redhat.com Mon Aug 11 17:02:03 2008 From: fedora-directory-commits at redhat.com (Richard Allen Megginson (rmeggins)) Date: Mon, 11 Aug 2008 13:02:03 -0400 Subject: [Fedora-directory-commits] ldapserver/ldap/servers/plugins/acl acleffectiverights.c, 1.12, 1.13 Message-ID: <200808111702.m7BH234c017733@cvs-int.fedora.redhat.com> Author: rmeggins Update of /cvs/dirsec/ldapserver/ldap/servers/plugins/acl In directory cvs-int.fedora.redhat.com:/tmp/cvs-serv17702/ldapserver/ldap/servers/plugins/acl Modified Files: acleffectiverights.c Log Message: Resolves: bug 457156 Bug Description: GER: allow GER for non-existing entries (phase 2) Reviewed by: nhosoi (Thanks!) Fix Description: There are a couple of memory leaks in the code. acleffectiverights.c line 617 calls slapi_attr_get_valueset to get the list of objectclass values in objclassvals - this function allocates memory (returns a dup of the list) but this is not freed. The fix is to call slapi_valueset_free() to free it. The allattrs and opattrs arrays are not freed in all conditions. The fix is to make sure they are freed in all conditions. Platforms tested: RHEL5, Fedora 8 Flag Day: no Doc impact: no Index: acleffectiverights.c =================================================================== RCS file: /cvs/dirsec/ldapserver/ldap/servers/plugins/acl/acleffectiverights.c,v retrieving revision 1.12 retrieving revision 1.13 diff -u -r1.12 -r1.13 --- acleffectiverights.c 31 Jul 2008 21:27:26 -0000 1.12 +++ acleffectiverights.c 11 Aug 2008 17:02:00 -0000 1.13 @@ -649,6 +649,7 @@ } } } + slapi_valueset_free(objclassvals); } /* get operational attrs */ @@ -706,9 +707,9 @@ } } } - charray_free(allattrs); - charray_free(opattrs); } + charray_free(allattrs); + charray_free(opattrs); } else {