1
0

windows_private.c 35 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261
  1. /** BEGIN COPYRIGHT BLOCK
  2. * This Program is free software; you can redistribute it and/or modify it under
  3. * the terms of the GNU General Public License as published by the Free Software
  4. * Foundation; version 2 of the License.
  5. *
  6. * This Program is distributed in the hope that it will be useful, but WITHOUT
  7. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  8. * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
  9. *
  10. * You should have received a copy of the GNU General Public License along with
  11. * this Program; if not, write to the Free Software Foundation, Inc., 59 Temple
  12. * Place, Suite 330, Boston, MA 02111-1307 USA.
  13. *
  14. * In addition, as a special exception, Red Hat, Inc. gives You the additional
  15. * right to link the code of this Program with code not covered under the GNU
  16. * General Public License ("Non-GPL Code") and to distribute linked combinations
  17. * including the two, subject to the limitations in this paragraph. Non-GPL Code
  18. * permitted under this exception must only link to the code of this Program
  19. * through those well defined interfaces identified in the file named EXCEPTION
  20. * found in the source code files (the "Approved Interfaces"). The files of
  21. * Non-GPL Code may instantiate templates or use macros or inline functions from
  22. * the Approved Interfaces without causing the resulting work to be covered by
  23. * the GNU General Public License. Only Red Hat, Inc. may make changes or
  24. * additions to the list of Approved Interfaces. You must obey the GNU General
  25. * Public License in all respects for all of the Program code and other code used
  26. * in conjunction with the Program except the Non-GPL Code covered by this
  27. * exception. If you modify this file, you may extend this exception to your
  28. * version of the file, but you are not obligated to do so. If you do not wish to
  29. * provide this exception without modification, you must delete this exception
  30. * statement from your version and license this file solely under the GPL without
  31. * exception.
  32. *
  33. *
  34. * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
  35. * Copyright (C) 2005 Red Hat, Inc.
  36. * All rights reserved.
  37. * END COPYRIGHT BLOCK **/
  38. #ifdef HAVE_CONFIG_H
  39. # include <config.h>
  40. #endif
  41. /* windows_private.c */
  42. #include "repl.h"
  43. #include "repl5.h"
  44. #include "slap.h"
  45. #include "slapi-plugin.h"
  46. #include "winsync-plugin.h"
  47. #include "windowsrepl.h"
  48. struct windowsprivate {
  49. Slapi_DN *windows_subtree; /* DN of synchronized subtree (on the windows side) */
  50. Slapi_DN *directory_subtree; /* DN of synchronized subtree on directory side */
  51. /* this simplifies the mapping as it's simply
  52. from the former to the latter container, or
  53. vice versa */
  54. ber_int_t dirsync_flags;
  55. ber_int_t dirsync_maxattributecount;
  56. char *dirsync_cookie;
  57. int dirsync_cookie_len;
  58. PRBool dirsync_cookie_has_more;
  59. PRBool create_users_from_dirsync;
  60. PRBool create_groups_from_dirsync;
  61. char *windows_domain;
  62. int isnt4;
  63. int iswin2k3;
  64. /* This filter is used to determine if an entry belongs to this agreement. We put it here
  65. * so we only have to allocate each filter once instead of doing it every time we receive a change. */
  66. Slapi_Filter *directory_filter; /* Used for checking if local entries need to be sync'd to AD */
  67. Slapi_Filter *deleted_filter; /* Used for checking if an entry is an AD tombstone */
  68. Slapi_Entry *raw_entry; /* "raw" un-schema processed last entry read from AD */
  69. void *api_cookie; /* private data used by api callbacks */
  70. };
  71. static void windows_private_set_windows_domain(const Repl_Agmt *ra, char *domain);
  72. static int
  73. true_value_from_string(char *val)
  74. {
  75. if (strcasecmp (val, "on") == 0 || strcasecmp (val, "yes") == 0 ||
  76. strcasecmp (val, "true") == 0 || strcasecmp (val, "1") == 0)
  77. {
  78. return 1;
  79. } else
  80. {
  81. return 0;
  82. }
  83. }
  84. static int
  85. windows_parse_config_entry(Repl_Agmt *ra, const char *type, Slapi_Entry *e)
  86. {
  87. char *tmpstr = NULL;
  88. int retval = 0;
  89. if (type == NULL || slapi_attr_types_equivalent(type,type_nsds7WindowsReplicaArea))
  90. {
  91. tmpstr = slapi_entry_attr_get_charptr(e, type_nsds7WindowsReplicaArea);
  92. if (NULL != tmpstr)
  93. {
  94. windows_private_set_windows_subtree(ra, slapi_sdn_new_dn_passin(tmpstr) );
  95. }
  96. retval = 1;
  97. }
  98. if (type == NULL || slapi_attr_types_equivalent(type,type_nsds7DirectoryReplicaArea))
  99. {
  100. tmpstr = slapi_entry_attr_get_charptr(e, type_nsds7DirectoryReplicaArea);
  101. if (NULL != tmpstr)
  102. {
  103. windows_private_set_directory_subtree(ra, slapi_sdn_new_dn_passin(tmpstr) );
  104. }
  105. retval = 1;
  106. }
  107. if (type == NULL || slapi_attr_types_equivalent(type,type_nsds7CreateNewUsers))
  108. {
  109. tmpstr = slapi_entry_attr_get_charptr(e, type_nsds7CreateNewUsers);
  110. if (NULL != tmpstr && true_value_from_string(tmpstr))
  111. {
  112. windows_private_set_create_users(ra, PR_TRUE);
  113. }
  114. else
  115. {
  116. windows_private_set_create_users(ra, PR_FALSE);
  117. }
  118. retval = 1;
  119. slapi_ch_free((void**)&tmpstr);
  120. }
  121. if (type == NULL || slapi_attr_types_equivalent(type,type_nsds7CreateNewGroups))
  122. {
  123. tmpstr = slapi_entry_attr_get_charptr(e, type_nsds7CreateNewGroups);
  124. if (NULL != tmpstr && true_value_from_string(tmpstr))
  125. {
  126. windows_private_set_create_groups(ra, PR_TRUE);
  127. }
  128. else
  129. {
  130. windows_private_set_create_groups(ra, PR_FALSE);
  131. }
  132. retval = 1;
  133. slapi_ch_free((void**)&tmpstr);
  134. }
  135. if (type == NULL || slapi_attr_types_equivalent(type,type_nsds7WindowsDomain))
  136. {
  137. tmpstr = slapi_entry_attr_get_charptr(e, type_nsds7WindowsDomain);
  138. if (NULL != tmpstr)
  139. {
  140. windows_private_set_windows_domain(ra,tmpstr);
  141. }
  142. /* No need to free tmpstr because it was aliased by the call above */
  143. tmpstr = NULL;
  144. retval = 1;
  145. }
  146. return retval;
  147. }
  148. /* Returns non-zero if the modify was ok, zero if not */
  149. int
  150. windows_handle_modify_agreement(Repl_Agmt *ra, const char *type, Slapi_Entry *e)
  151. {
  152. /* Is this a Windows agreement ? */
  153. if (get_agmt_agreement_type(ra) == REPLICA_TYPE_WINDOWS)
  154. {
  155. return windows_parse_config_entry(ra,type,e);
  156. } else
  157. {
  158. return 0;
  159. }
  160. }
  161. void
  162. windows_init_agreement_from_entry(Repl_Agmt *ra, Slapi_Entry *e)
  163. {
  164. agmt_set_priv(ra,windows_private_new());
  165. windows_parse_config_entry(ra,NULL,e);
  166. windows_plugin_init(ra);
  167. }
  168. const char* windows_private_get_purl(const Repl_Agmt *ra)
  169. {
  170. const char* windows_purl;
  171. char *hostname;
  172. hostname = agmt_get_hostname(ra);
  173. windows_purl = slapi_ch_smprintf("ldap://%s:%d", hostname, agmt_get_port(ra));
  174. slapi_ch_free_string(&hostname);
  175. return windows_purl;
  176. }
  177. Dirsync_Private* windows_private_new()
  178. {
  179. Dirsync_Private *dp;
  180. LDAPDebug( LDAP_DEBUG_TRACE, "=> windows_private_new\n", 0, 0, 0 );
  181. dp = (Dirsync_Private *)slapi_ch_calloc(sizeof(Dirsync_Private),1);
  182. dp->dirsync_maxattributecount = -1;
  183. dp->directory_filter = NULL;
  184. dp->deleted_filter = NULL;
  185. LDAPDebug( LDAP_DEBUG_TRACE, "<= windows_private_new\n", 0, 0, 0 );
  186. return dp;
  187. }
  188. void windows_agreement_delete(Repl_Agmt *ra)
  189. {
  190. Dirsync_Private *dp = (Dirsync_Private *) agmt_get_priv(ra);
  191. LDAPDebug( LDAP_DEBUG_TRACE, "=> windows_private_delete\n", 0, 0, 0 );
  192. PR_ASSERT(dp != NULL);
  193. winsync_plugin_call_destroy_agmt_cb(ra, dp->directory_subtree,
  194. dp->windows_subtree);
  195. slapi_sdn_free(&dp->directory_subtree);
  196. slapi_sdn_free(&dp->windows_subtree);
  197. slapi_filter_free(dp->directory_filter, 1);
  198. slapi_filter_free(dp->deleted_filter, 1);
  199. slapi_entry_free(dp->raw_entry);
  200. dp->raw_entry = NULL;
  201. dp->api_cookie = NULL;
  202. slapi_ch_free((void **)dp);
  203. LDAPDebug( LDAP_DEBUG_TRACE, "<= windows_private_delete\n", 0, 0, 0 );
  204. }
  205. int windows_private_get_isnt4(const Repl_Agmt *ra)
  206. {
  207. Dirsync_Private *dp;
  208. LDAPDebug( LDAP_DEBUG_TRACE, "=> windows_private_get_isnt4\n", 0, 0, 0 );
  209. PR_ASSERT(ra);
  210. dp = (Dirsync_Private *) agmt_get_priv(ra);
  211. PR_ASSERT (dp);
  212. LDAPDebug( LDAP_DEBUG_TRACE, "<= windows_private_get_isnt4\n", 0, 0, 0 );
  213. return dp->isnt4;
  214. }
  215. void windows_private_set_isnt4(const Repl_Agmt *ra, int isit)
  216. {
  217. Dirsync_Private *dp;
  218. LDAPDebug( LDAP_DEBUG_TRACE, "=> windows_private_set_isnt4\n", 0, 0, 0 );
  219. PR_ASSERT(ra);
  220. dp = (Dirsync_Private *) agmt_get_priv(ra);
  221. PR_ASSERT (dp);
  222. dp->isnt4 = isit;
  223. LDAPDebug( LDAP_DEBUG_TRACE, "<= windows_private_set_isnt4\n", 0, 0, 0 );
  224. }
  225. int windows_private_get_iswin2k3(const Repl_Agmt *ra)
  226. {
  227. Dirsync_Private *dp;
  228. LDAPDebug( LDAP_DEBUG_TRACE, "=> windows_private_get_iswin2k3\n", 0, 0, 0 );
  229. PR_ASSERT(ra);
  230. dp = (Dirsync_Private *) agmt_get_priv(ra);
  231. PR_ASSERT (dp);
  232. LDAPDebug( LDAP_DEBUG_TRACE, "<= windows_private_get_iswin2k3\n", 0, 0, 0 );
  233. return dp->iswin2k3;
  234. }
  235. void windows_private_set_iswin2k3(const Repl_Agmt *ra, int isit)
  236. {
  237. Dirsync_Private *dp;
  238. LDAPDebug( LDAP_DEBUG_TRACE, "=> windows_private_set_iswin2k3\n", 0, 0, 0 );
  239. PR_ASSERT(ra);
  240. dp = (Dirsync_Private *) agmt_get_priv(ra);
  241. PR_ASSERT (dp);
  242. dp->iswin2k3 = isit;
  243. LDAPDebug( LDAP_DEBUG_TRACE, "<= windows_private_set_iswin2k3\n", 0, 0, 0 );
  244. }
  245. /* Returns a copy of the Slapi_Filter pointer. The caller should not free it */
  246. Slapi_Filter* windows_private_get_directory_filter(const Repl_Agmt *ra)
  247. {
  248. Dirsync_Private *dp;
  249. LDAPDebug( LDAP_DEBUG_TRACE, "=> windows_private_get_directory_filter\n", 0, 0, 0 );
  250. PR_ASSERT(ra);
  251. dp = (Dirsync_Private *) agmt_get_priv(ra);
  252. PR_ASSERT (dp);
  253. if (dp->directory_filter == NULL) {
  254. char *string_filter = slapi_ch_strdup("(&(|(objectclass=ntuser)(objectclass=ntgroup))(ntUserDomainId=*))");
  255. /* The filter gets freed in windows_agreement_delete() */
  256. dp->directory_filter = slapi_str2filter( string_filter );
  257. slapi_ch_free_string(&string_filter);
  258. }
  259. LDAPDebug( LDAP_DEBUG_TRACE, "<= windows_private_get_directory_filter\n", 0, 0, 0 );
  260. return dp->directory_filter;
  261. }
  262. /* Returns a copy of the Slapi_Filter pointer. The caller should not free it */
  263. Slapi_Filter* windows_private_get_deleted_filter(const Repl_Agmt *ra)
  264. {
  265. Dirsync_Private *dp;
  266. LDAPDebug( LDAP_DEBUG_TRACE, "=> windows_private_get_deleted_filter\n", 0, 0, 0 );
  267. PR_ASSERT(ra);
  268. dp = (Dirsync_Private *) agmt_get_priv(ra);
  269. PR_ASSERT (dp);
  270. if (dp->deleted_filter == NULL) {
  271. char *string_filter = slapi_ch_strdup("(isdeleted=*)");
  272. /* The filter gets freed in windows_agreement_delete() */
  273. dp->deleted_filter = slapi_str2filter( string_filter );
  274. slapi_ch_free_string(&string_filter);
  275. }
  276. LDAPDebug( LDAP_DEBUG_TRACE, "<= windows_private_get_deleted_filter\n", 0, 0, 0 );
  277. return dp->deleted_filter;
  278. }
  279. /* Returns a copy of the Slapi_DN pointer, no need to free it */
  280. const Slapi_DN* windows_private_get_windows_subtree (const Repl_Agmt *ra)
  281. {
  282. Dirsync_Private *dp;
  283. LDAPDebug( LDAP_DEBUG_TRACE, "=> windows_private_get_windows_subtree\n", 0, 0, 0 );
  284. PR_ASSERT(ra);
  285. dp = (Dirsync_Private *) agmt_get_priv(ra);
  286. PR_ASSERT (dp);
  287. LDAPDebug( LDAP_DEBUG_TRACE, "<= windows_private_get_windows_subtree\n", 0, 0, 0 );
  288. return dp->windows_subtree;
  289. }
  290. const char *
  291. windows_private_get_windows_domain(const Repl_Agmt *ra)
  292. {
  293. Dirsync_Private *dp;
  294. LDAPDebug( LDAP_DEBUG_TRACE, "=> windows_private_get_windows_domain\n", 0, 0, 0 );
  295. PR_ASSERT(ra);
  296. dp = (Dirsync_Private *) agmt_get_priv(ra);
  297. PR_ASSERT (dp);
  298. LDAPDebug( LDAP_DEBUG_TRACE, "<= windows_private_get_windows_domain\n", 0, 0, 0 );
  299. return dp->windows_domain;
  300. }
  301. static void
  302. windows_private_set_windows_domain(const Repl_Agmt *ra, char *domain)
  303. {
  304. Dirsync_Private *dp;
  305. LDAPDebug( LDAP_DEBUG_TRACE, "=> windows_private_set_windows_domain\n", 0, 0, 0 );
  306. PR_ASSERT(ra);
  307. dp = (Dirsync_Private *) agmt_get_priv(ra);
  308. PR_ASSERT (dp);
  309. dp->windows_domain = domain;
  310. LDAPDebug( LDAP_DEBUG_TRACE, "<= windows_private_set_windows_domain\n", 0, 0, 0 );
  311. }
  312. /* Returns a copy of the Slapi_DN pointer, no need to free it */
  313. const Slapi_DN* windows_private_get_directory_subtree (const Repl_Agmt *ra)
  314. {
  315. Dirsync_Private *dp;
  316. LDAPDebug( LDAP_DEBUG_TRACE, "=> windows_private_get_directory_replarea\n", 0, 0, 0 );
  317. PR_ASSERT(ra);
  318. dp = (Dirsync_Private *) agmt_get_priv(ra);
  319. PR_ASSERT (dp);
  320. LDAPDebug( LDAP_DEBUG_TRACE, "<= windows_private_get_directory_replarea\n", 0, 0, 0 );
  321. return dp->directory_subtree;
  322. }
  323. /* Takes a copy of the sdn passed in */
  324. void windows_private_set_windows_subtree (const Repl_Agmt *ra,Slapi_DN* sdn )
  325. {
  326. Dirsync_Private *dp;
  327. LDAPDebug( LDAP_DEBUG_TRACE, "=> windows_private_set_windows_replarea\n", 0, 0, 0 );
  328. PR_ASSERT(ra);
  329. PR_ASSERT(sdn);
  330. dp = (Dirsync_Private *) agmt_get_priv(ra);
  331. PR_ASSERT (dp);
  332. slapi_sdn_free(&dp->windows_subtree);
  333. dp->windows_subtree = sdn;
  334. LDAPDebug( LDAP_DEBUG_TRACE, "<= windows_private_set_windows_replarea\n", 0, 0, 0 );
  335. }
  336. /* Takes a copy of the sdn passed in */
  337. void windows_private_set_directory_subtree (const Repl_Agmt *ra,Slapi_DN* sdn )
  338. {
  339. Dirsync_Private *dp;
  340. LDAPDebug( LDAP_DEBUG_TRACE, "=> windows_private_set_directory_replarea\n", 0, 0, 0 );
  341. PR_ASSERT(ra);
  342. PR_ASSERT(sdn);
  343. dp = (Dirsync_Private *) agmt_get_priv(ra);
  344. PR_ASSERT (dp);
  345. slapi_sdn_free(&dp->directory_subtree);
  346. dp->directory_subtree = sdn;
  347. LDAPDebug( LDAP_DEBUG_TRACE, "<= windows_private_set_directory_replarea\n", 0, 0, 0 );
  348. }
  349. PRBool windows_private_create_users(const Repl_Agmt *ra)
  350. {
  351. Dirsync_Private *dp;
  352. LDAPDebug( LDAP_DEBUG_TRACE, "=> windows_private_create_users\n", 0, 0, 0 );
  353. PR_ASSERT(ra);
  354. dp = (Dirsync_Private *) agmt_get_priv(ra);
  355. PR_ASSERT (dp);
  356. LDAPDebug( LDAP_DEBUG_TRACE, "<= windows_private_create_users\n", 0, 0, 0 );
  357. return dp->create_users_from_dirsync;
  358. }
  359. void windows_private_set_create_users(const Repl_Agmt *ra, PRBool value)
  360. {
  361. Dirsync_Private *dp;
  362. LDAPDebug( LDAP_DEBUG_TRACE, "=> windows_private_set_create_users\n", 0, 0, 0 );
  363. PR_ASSERT(ra);
  364. dp = (Dirsync_Private *) agmt_get_priv(ra);
  365. PR_ASSERT (dp);
  366. dp->create_users_from_dirsync = value;
  367. LDAPDebug( LDAP_DEBUG_TRACE, "<= windows_private_set_create_users\n", 0, 0, 0 );
  368. }
  369. PRBool windows_private_create_groups(const Repl_Agmt *ra)
  370. {
  371. Dirsync_Private *dp;
  372. LDAPDebug( LDAP_DEBUG_TRACE, "=> windows_private_create_groups\n", 0, 0, 0 );
  373. PR_ASSERT(ra);
  374. dp = (Dirsync_Private *) agmt_get_priv(ra);
  375. PR_ASSERT (dp);
  376. LDAPDebug( LDAP_DEBUG_TRACE, "<= windows_private_create_groups\n", 0, 0, 0 );
  377. return dp->create_groups_from_dirsync;
  378. }
  379. void windows_private_set_create_groups(const Repl_Agmt *ra, PRBool value)
  380. {
  381. Dirsync_Private *dp;
  382. LDAPDebug( LDAP_DEBUG_TRACE, "=> windows_private_set_create_groups\n", 0, 0, 0 );
  383. PR_ASSERT(ra);
  384. dp = (Dirsync_Private *) agmt_get_priv(ra);
  385. PR_ASSERT (dp);
  386. dp->create_groups_from_dirsync = value;
  387. LDAPDebug( LDAP_DEBUG_TRACE, "<= windows_private_set_create_groups\n", 0, 0, 0 );
  388. }
  389. /*
  390. This function returns the current Dirsync_Private that's inside
  391. Repl_Agmt ra as a ldap control.
  392. */
  393. LDAPControl* windows_private_dirsync_control(const Repl_Agmt *ra)
  394. {
  395. LDAPControl *control = NULL;
  396. BerElement *ber;
  397. Dirsync_Private *dp;
  398. char iscritical = PR_TRUE;
  399. LDAPDebug( LDAP_DEBUG_TRACE, "=> windows_private_dirsync_control\n", 0, 0, 0 );
  400. PR_ASSERT(ra);
  401. dp = (Dirsync_Private *) agmt_get_priv(ra);
  402. PR_ASSERT (dp);
  403. ber = ber_alloc();
  404. ber_printf( ber, "{iio}", dp->dirsync_flags, dp->dirsync_maxattributecount, dp->dirsync_cookie, dp->dirsync_cookie_len );
  405. /* Use a regular directory server instead of a real AD - for testing */
  406. if (getenv("WINSYNC_USE_DS")) {
  407. iscritical = PR_FALSE;
  408. }
  409. slapi_build_control( REPL_DIRSYNC_CONTROL_OID, ber, iscritical, &control);
  410. ber_free(ber,1);
  411. LDAPDebug( LDAP_DEBUG_TRACE, "<= windows_private_dirsync_control\n", 0, 0, 0 );
  412. return control;
  413. }
  414. /*
  415. This function scans the array of controls and updates the Repl_Agmt's
  416. Dirsync_Private if the dirsync control is found.
  417. */
  418. void windows_private_update_dirsync_control(const Repl_Agmt *ra,LDAPControl **controls )
  419. {
  420. Dirsync_Private *dp;
  421. int foundDirsyncControl;
  422. int i;
  423. LDAPControl *dirsync = NULL;
  424. BerElement *ber;
  425. ber_int_t hasMoreData;
  426. ber_int_t maxAttributeCount;
  427. BerValue *serverCookie;
  428. #ifdef FOR_DEBUGGING
  429. int return_value = LDAP_SUCCESS;
  430. #endif
  431. LDAPDebug( LDAP_DEBUG_TRACE, "=> windows_private_update_dirsync_control\n", 0, 0, 0 );
  432. PR_ASSERT(ra);
  433. dp = (Dirsync_Private *) agmt_get_priv(ra);
  434. PR_ASSERT (dp);
  435. if (NULL != controls )
  436. {
  437. foundDirsyncControl = 0;
  438. for ( i = 0; (( controls[i] != NULL ) && ( !foundDirsyncControl )); i++ ) {
  439. foundDirsyncControl = !strcmp( controls[i]->ldctl_oid, REPL_DIRSYNC_CONTROL_OID );
  440. }
  441. if ( !foundDirsyncControl )
  442. {
  443. #ifdef FOR_DEBUGGING
  444. return_value = LDAP_CONTROL_NOT_FOUND;
  445. #endif
  446. goto choke;
  447. }
  448. else
  449. {
  450. dirsync = slapi_dup_control( controls[i-1]);
  451. }
  452. ber = ber_init( &dirsync->ldctl_value ) ;
  453. if (ber_scanf( ber, "{iiO}", &hasMoreData, &maxAttributeCount, &serverCookie) == LBER_ERROR)
  454. {
  455. #ifdef FOR_DEBUGGING
  456. return_value = LDAP_CONTROL_NOT_FOUND;
  457. #endif
  458. goto choke;
  459. }
  460. slapi_ch_free_string(&dp->dirsync_cookie);
  461. dp->dirsync_cookie = ( char* ) slapi_ch_malloc(serverCookie->bv_len + 1);
  462. memcpy(dp->dirsync_cookie, serverCookie->bv_val, serverCookie->bv_len);
  463. dp->dirsync_cookie_len = (int) serverCookie->bv_len; /* XXX shouldn't cast? */
  464. /* dp->dirsync_maxattributecount = maxAttributeCount; We don't need to keep this */
  465. dp->dirsync_cookie_has_more = hasMoreData;
  466. choke:
  467. ber_bvfree(serverCookie);
  468. ber_free(ber,1);
  469. ldap_control_free(dirsync);
  470. }
  471. else
  472. {
  473. #ifdef FOR_DEBUGGING
  474. return_value = LDAP_CONTROL_NOT_FOUND;
  475. #endif
  476. }
  477. #ifdef FOR_DEBUGGING
  478. LDAPDebug( LDAP_DEBUG_TRACE, "<= windows_private_update_dirsync_control: rc=%d\n", return_value, 0, 0 );
  479. #else
  480. LDAPDebug( LDAP_DEBUG_TRACE, "<= windows_private_update_dirsync_control\n", 0, 0, 0 );
  481. #endif
  482. }
  483. PRBool windows_private_dirsync_has_more(const Repl_Agmt *ra)
  484. {
  485. Dirsync_Private *dp;
  486. LDAPDebug( LDAP_DEBUG_TRACE, "=> windows_private_dirsync_has_more\n", 0, 0, 0 );
  487. PR_ASSERT(ra);
  488. dp = (Dirsync_Private *) agmt_get_priv(ra);
  489. PR_ASSERT (dp);
  490. LDAPDebug( LDAP_DEBUG_TRACE, "<= windows_private_dirsync_has_more\n", 0, 0, 0 );
  491. return dp->dirsync_cookie_has_more;
  492. }
  493. void windows_private_null_dirsync_cookie(const Repl_Agmt *ra)
  494. {
  495. Dirsync_Private *dp;
  496. LDAPDebug( LDAP_DEBUG_TRACE, "=> windows_private_null_dirsync_control\n", 0, 0, 0 );
  497. dp = (Dirsync_Private *) agmt_get_priv(ra);
  498. PR_ASSERT (dp);
  499. dp->dirsync_cookie_len = 0;
  500. slapi_ch_free_string(&dp->dirsync_cookie);
  501. dp->dirsync_cookie = NULL;
  502. LDAPDebug( LDAP_DEBUG_TRACE, "<= windows_private_null_dirsync_control\n", 0, 0, 0 );
  503. }
  504. static
  505. Slapi_Mods *windows_private_get_cookie_mod(Dirsync_Private *dp, int modtype)
  506. {
  507. Slapi_Mods *smods = NULL;
  508. smods = slapi_mods_new();
  509. slapi_mods_add( smods, modtype,
  510. "nsds7DirsyncCookie", dp->dirsync_cookie_len , dp->dirsync_cookie);
  511. return smods;
  512. }
  513. /* writes the current cookie into dse.ldif under the replication agreement entry
  514. returns: ldap result code of the operation. */
  515. int
  516. windows_private_save_dirsync_cookie(const Repl_Agmt *ra)
  517. {
  518. Dirsync_Private *dp = NULL;
  519. Slapi_PBlock *pb = NULL;
  520. const char* dn = NULL;
  521. Slapi_DN* sdn = NULL;
  522. int rc = 0;
  523. Slapi_Mods *mods = NULL;
  524. LDAPDebug( LDAP_DEBUG_TRACE, "=> windows_private_save_dirsync_cookie\n", 0, 0, 0 );
  525. PR_ASSERT(ra);
  526. dp = (Dirsync_Private *) agmt_get_priv(ra);
  527. PR_ASSERT (dp);
  528. pb = slapi_pblock_new ();
  529. mods = windows_private_get_cookie_mod(dp, LDAP_MOD_REPLACE);
  530. sdn = slapi_sdn_dup( agmt_get_dn_byref(ra) );
  531. dn = slapi_sdn_get_dn(sdn);
  532. slapi_modify_internal_set_pb (pb, dn, slapi_mods_get_ldapmods_byref(mods), NULL, NULL,
  533. repl_get_plugin_identity(PLUGIN_MULTIMASTER_REPLICATION), 0);
  534. slapi_modify_internal_pb (pb);
  535. slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_RESULT, &rc);
  536. if (rc == LDAP_NO_SUCH_ATTRIBUTE)
  537. { /* try again, but as an add instead */
  538. mods = windows_private_get_cookie_mod(dp, LDAP_MOD_ADD);
  539. slapi_modify_internal_set_pb (pb, dn, slapi_mods_get_ldapmods_byref(mods), NULL, NULL,
  540. repl_get_plugin_identity(PLUGIN_MULTIMASTER_REPLICATION), 0);
  541. slapi_modify_internal_pb (pb);
  542. slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_RESULT, &rc);
  543. }
  544. slapi_pblock_destroy (pb);
  545. slapi_mods_free(&mods);
  546. slapi_sdn_free(&sdn);
  547. LDAPDebug( LDAP_DEBUG_TRACE, "<= windows_private_save_dirsync_cookie\n", 0, 0, 0 );
  548. return rc;
  549. }
  550. /* reads the cookie in dse.ldif to the replication agreement entry
  551. returns: ldap result code of ldap operation, or
  552. LDAP_NO_SUCH_ATTRIBUTE. (this is the equilivent of a null cookie) */
  553. int windows_private_load_dirsync_cookie(const Repl_Agmt *ra)
  554. {
  555. Dirsync_Private *dp = NULL;
  556. Slapi_PBlock *pb = NULL;
  557. Slapi_DN* sdn = NULL;
  558. int rc = 0;
  559. Slapi_Entry *entry = NULL;
  560. Slapi_Attr *attr = NULL;
  561. LDAPDebug( LDAP_DEBUG_TRACE, "=> windows_private_load_dirsync_cookie\n", 0, 0, 0 );
  562. PR_ASSERT(ra);
  563. dp = (Dirsync_Private *) agmt_get_priv(ra);
  564. PR_ASSERT (dp);
  565. pb = slapi_pblock_new ();
  566. sdn = slapi_sdn_dup( agmt_get_dn_byref(ra) );
  567. rc = slapi_search_internal_get_entry(sdn, NULL, &entry,
  568. repl_get_plugin_identity (PLUGIN_MULTIMASTER_REPLICATION));
  569. if (rc == 0)
  570. {
  571. rc= slapi_entry_attr_find( entry, type_nsds7DirsyncCookie, &attr );
  572. if (attr)
  573. {
  574. struct berval **vals;
  575. rc = slapi_attr_get_bervals_copy(attr, &vals );
  576. if (vals)
  577. {
  578. dp->dirsync_cookie_len = (int) (vals[0])->bv_len;
  579. slapi_ch_free_string(&dp->dirsync_cookie);
  580. dp->dirsync_cookie = ( char* ) slapi_ch_malloc(dp->dirsync_cookie_len + 1);
  581. memcpy(dp->dirsync_cookie,(vals[0]->bv_val), (vals[0])->bv_len+1);
  582. }
  583. ber_bvecfree(vals);
  584. /* we do not free attr */
  585. }
  586. else
  587. {
  588. rc = LDAP_NO_SUCH_ATTRIBUTE;
  589. }
  590. }
  591. if (entry)
  592. {
  593. slapi_entry_free(entry);
  594. }
  595. slapi_sdn_free( &sdn);
  596. slapi_pblock_destroy (pb);
  597. LDAPDebug( LDAP_DEBUG_TRACE, "<= windows_private_load_dirsync_cookie\n", 0, 0, 0 );
  598. return rc;
  599. }
  600. /* get returns a pointer to the structure - do not free */
  601. Slapi_Entry *windows_private_get_raw_entry(const Repl_Agmt *ra)
  602. {
  603. Dirsync_Private *dp;
  604. LDAPDebug( LDAP_DEBUG_TRACE, "=> windows_private_get_raw_entry\n", 0, 0, 0 );
  605. dp = (Dirsync_Private *) agmt_get_priv(ra);
  606. PR_ASSERT (dp);
  607. LDAPDebug( LDAP_DEBUG_TRACE, "<= windows_private_get_raw_entry\n", 0, 0, 0 );
  608. return dp->raw_entry;
  609. }
  610. /* this is passin - windows_private owns the pointer, not a copy */
  611. void windows_private_set_raw_entry(const Repl_Agmt *ra, Slapi_Entry *e)
  612. {
  613. Dirsync_Private *dp;
  614. LDAPDebug( LDAP_DEBUG_TRACE, "=> windows_private_set_raw_entry\n", 0, 0, 0 );
  615. dp = (Dirsync_Private *) agmt_get_priv(ra);
  616. PR_ASSERT (dp);
  617. slapi_entry_free(dp->raw_entry);
  618. dp->raw_entry = e;
  619. LDAPDebug( LDAP_DEBUG_TRACE, "<= windows_private_set_raw_entry\n", 0, 0, 0 );
  620. }
  621. void *windows_private_get_api_cookie(const Repl_Agmt *ra)
  622. {
  623. Dirsync_Private *dp;
  624. LDAPDebug( LDAP_DEBUG_TRACE, "=> windows_private_get_api_cookie\n", 0, 0, 0 );
  625. dp = (Dirsync_Private *) agmt_get_priv(ra);
  626. PR_ASSERT (dp);
  627. LDAPDebug( LDAP_DEBUG_TRACE, "<= windows_private_get_api_cookie\n", 0, 0, 0 );
  628. return dp->api_cookie;
  629. }
  630. void windows_private_set_api_cookie(Repl_Agmt *ra, void *api_cookie)
  631. {
  632. Dirsync_Private *dp;
  633. LDAPDebug( LDAP_DEBUG_TRACE, "=> windows_private_set_api_cookie\n", 0, 0, 0 );
  634. dp = (Dirsync_Private *) agmt_get_priv(ra);
  635. PR_ASSERT (dp);
  636. dp->api_cookie = api_cookie;
  637. LDAPDebug( LDAP_DEBUG_TRACE, "<= windows_private_set_api_cookie\n", 0, 0, 0 );
  638. }
  639. /* an array of function pointers */
  640. static void **_WinSyncAPI = NULL;
  641. void
  642. windows_plugin_init(Repl_Agmt *ra)
  643. {
  644. void *cookie = NULL;
  645. winsync_plugin_init_cb initfunc = NULL;
  646. LDAPDebug( LDAP_DEBUG_PLUGIN, "--> windows_plugin_init_start -- begin\n",0,0,0);
  647. /* if the function pointer array is null, get the functions - we will
  648. call init once per replication agreement, but will only grab the
  649. api once */
  650. if((NULL == _WinSyncAPI) &&
  651. (slapi_apib_get_interface(WINSYNC_v1_0_GUID, &_WinSyncAPI) ||
  652. (NULL == _WinSyncAPI)))
  653. {
  654. LDAPDebug( LDAP_DEBUG_PLUGIN,
  655. "<-- windows_plugin_init_start -- no windows plugin API registered for GUID [%s] -- end\n",
  656. WINSYNC_v1_0_GUID,0,0);
  657. return;
  658. }
  659. initfunc = (winsync_plugin_init_cb)_WinSyncAPI[WINSYNC_PLUGIN_INIT_CB];
  660. if (initfunc) {
  661. cookie = (*initfunc)(windows_private_get_directory_subtree(ra),
  662. windows_private_get_windows_subtree(ra));
  663. }
  664. windows_private_set_api_cookie(ra, cookie);
  665. LDAPDebug( LDAP_DEBUG_PLUGIN, "<-- windows_plugin_init_start -- end\n",0,0,0);
  666. return;
  667. }
  668. void
  669. winsync_plugin_call_dirsync_search_params_cb(const Repl_Agmt *ra, const char *agmt_dn,
  670. char **base, int *scope, char **filter,
  671. char ***attrs, LDAPControl ***serverctrls)
  672. {
  673. winsync_search_params_cb thefunc =
  674. (_WinSyncAPI && _WinSyncAPI[WINSYNC_PLUGIN_DIRSYNC_SEARCH_CB]) ?
  675. (winsync_search_params_cb)_WinSyncAPI[WINSYNC_PLUGIN_DIRSYNC_SEARCH_CB] :
  676. NULL;
  677. if (!thefunc) {
  678. return;
  679. }
  680. (*thefunc)(windows_private_get_api_cookie(ra), agmt_dn, base, scope, filter,
  681. attrs, serverctrls);
  682. return;
  683. }
  684. void
  685. winsync_plugin_call_pre_ad_search_cb(const Repl_Agmt *ra, const char *agmt_dn,
  686. char **base, int *scope, char **filter,
  687. char ***attrs, LDAPControl ***serverctrls)
  688. {
  689. winsync_search_params_cb thefunc =
  690. (_WinSyncAPI && _WinSyncAPI[WINSYNC_PLUGIN_PRE_AD_SEARCH_CB]) ?
  691. (winsync_search_params_cb)_WinSyncAPI[WINSYNC_PLUGIN_PRE_AD_SEARCH_CB] :
  692. NULL;
  693. if (!thefunc) {
  694. return;
  695. }
  696. (*thefunc)(windows_private_get_api_cookie(ra), agmt_dn, base, scope, filter,
  697. attrs, serverctrls);
  698. return;
  699. }
  700. void
  701. winsync_plugin_call_pre_ds_search_entry_cb(const Repl_Agmt *ra, const char *agmt_dn,
  702. char **base, int *scope, char **filter,
  703. char ***attrs, LDAPControl ***serverctrls)
  704. {
  705. winsync_search_params_cb thefunc =
  706. (_WinSyncAPI && _WinSyncAPI[WINSYNC_PLUGIN_PRE_DS_SEARCH_ENTRY_CB]) ?
  707. (winsync_search_params_cb)_WinSyncAPI[WINSYNC_PLUGIN_PRE_DS_SEARCH_ENTRY_CB] :
  708. NULL;
  709. if (!thefunc) {
  710. return;
  711. }
  712. (*thefunc)(windows_private_get_api_cookie(ra), agmt_dn, base, scope, filter,
  713. attrs, serverctrls);
  714. return;
  715. }
  716. void
  717. winsync_plugin_call_pre_ds_search_all_cb(const Repl_Agmt *ra, const char *agmt_dn,
  718. char **base, int *scope, char **filter,
  719. char ***attrs, LDAPControl ***serverctrls)
  720. {
  721. winsync_search_params_cb thefunc =
  722. (_WinSyncAPI && _WinSyncAPI[WINSYNC_PLUGIN_PRE_DS_SEARCH_ALL_CB]) ?
  723. (winsync_search_params_cb)_WinSyncAPI[WINSYNC_PLUGIN_PRE_DS_SEARCH_ALL_CB] :
  724. NULL;
  725. if (!thefunc) {
  726. return;
  727. }
  728. (*thefunc)(windows_private_get_api_cookie(ra), agmt_dn, base, scope, filter,
  729. attrs, serverctrls);
  730. return;
  731. }
  732. void
  733. winsync_plugin_call_pre_ad_mod_user_cb(const Repl_Agmt *ra, const Slapi_Entry *rawentry,
  734. Slapi_Entry *ad_entry, Slapi_Entry *ds_entry,
  735. Slapi_Mods *smods, int *do_modify)
  736. {
  737. winsync_pre_mod_cb thefunc =
  738. (_WinSyncAPI && _WinSyncAPI[WINSYNC_PLUGIN_PRE_AD_MOD_USER_CB]) ?
  739. (winsync_pre_mod_cb)_WinSyncAPI[WINSYNC_PLUGIN_PRE_AD_MOD_USER_CB] :
  740. NULL;
  741. if (!thefunc) {
  742. return;
  743. }
  744. (*thefunc)(windows_private_get_api_cookie(ra), rawentry, ad_entry,
  745. ds_entry, smods, do_modify);
  746. return;
  747. }
  748. void
  749. winsync_plugin_call_pre_ad_mod_group_cb(const Repl_Agmt *ra, const Slapi_Entry *rawentry,
  750. Slapi_Entry *ad_entry, Slapi_Entry *ds_entry,
  751. Slapi_Mods *smods, int *do_modify)
  752. {
  753. winsync_pre_mod_cb thefunc =
  754. (_WinSyncAPI && _WinSyncAPI[WINSYNC_PLUGIN_PRE_AD_MOD_GROUP_CB]) ?
  755. (winsync_pre_mod_cb)_WinSyncAPI[WINSYNC_PLUGIN_PRE_AD_MOD_GROUP_CB] :
  756. NULL;
  757. if (!thefunc) {
  758. return;
  759. }
  760. (*thefunc)(windows_private_get_api_cookie(ra), rawentry, ad_entry,
  761. ds_entry, smods, do_modify);
  762. return;
  763. }
  764. void
  765. winsync_plugin_call_pre_ds_mod_user_cb(const Repl_Agmt *ra, const Slapi_Entry *rawentry,
  766. Slapi_Entry *ad_entry, Slapi_Entry *ds_entry,
  767. Slapi_Mods *smods, int *do_modify)
  768. {
  769. winsync_pre_mod_cb thefunc =
  770. (_WinSyncAPI && _WinSyncAPI[WINSYNC_PLUGIN_PRE_DS_MOD_USER_CB]) ?
  771. (winsync_pre_mod_cb)_WinSyncAPI[WINSYNC_PLUGIN_PRE_DS_MOD_USER_CB] :
  772. NULL;
  773. if (!thefunc) {
  774. return;
  775. }
  776. (*thefunc)(windows_private_get_api_cookie(ra), rawentry, ad_entry,
  777. ds_entry, smods, do_modify);
  778. return;
  779. }
  780. void
  781. winsync_plugin_call_pre_ds_mod_group_cb(const Repl_Agmt *ra, const Slapi_Entry *rawentry,
  782. Slapi_Entry *ad_entry, Slapi_Entry *ds_entry,
  783. Slapi_Mods *smods, int *do_modify)
  784. {
  785. winsync_pre_mod_cb thefunc =
  786. (_WinSyncAPI && _WinSyncAPI[WINSYNC_PLUGIN_PRE_DS_MOD_GROUP_CB]) ?
  787. (winsync_pre_mod_cb)_WinSyncAPI[WINSYNC_PLUGIN_PRE_DS_MOD_GROUP_CB] :
  788. NULL;
  789. if (!thefunc) {
  790. return;
  791. }
  792. (*thefunc)(windows_private_get_api_cookie(ra), rawentry, ad_entry,
  793. ds_entry, smods, do_modify);
  794. return;
  795. }
  796. void
  797. winsync_plugin_call_pre_ds_add_user_cb(const Repl_Agmt *ra, const Slapi_Entry *rawentry,
  798. Slapi_Entry *ad_entry, Slapi_Entry *ds_entry)
  799. {
  800. winsync_pre_add_cb thefunc =
  801. (_WinSyncAPI && _WinSyncAPI[WINSYNC_PLUGIN_PRE_DS_ADD_USER_CB]) ?
  802. (winsync_pre_add_cb)_WinSyncAPI[WINSYNC_PLUGIN_PRE_DS_ADD_USER_CB] :
  803. NULL;
  804. if (!thefunc) {
  805. return;
  806. }
  807. (*thefunc)(windows_private_get_api_cookie(ra), rawentry, ad_entry,
  808. ds_entry);
  809. return;
  810. }
  811. void
  812. winsync_plugin_call_pre_ds_add_group_cb(const Repl_Agmt *ra, const Slapi_Entry *rawentry,
  813. Slapi_Entry *ad_entry, Slapi_Entry *ds_entry)
  814. {
  815. winsync_pre_add_cb thefunc =
  816. (_WinSyncAPI && _WinSyncAPI[WINSYNC_PLUGIN_PRE_DS_ADD_GROUP_CB]) ?
  817. (winsync_pre_add_cb)_WinSyncAPI[WINSYNC_PLUGIN_PRE_DS_ADD_GROUP_CB] :
  818. NULL;
  819. if (!thefunc) {
  820. return;
  821. }
  822. (*thefunc)(windows_private_get_api_cookie(ra), rawentry, ad_entry,
  823. ds_entry);
  824. return;
  825. }
  826. void
  827. winsync_plugin_call_get_new_ds_user_dn_cb(const Repl_Agmt *ra, const Slapi_Entry *rawentry,
  828. Slapi_Entry *ad_entry, char **new_dn_string,
  829. const Slapi_DN *ds_suffix, const Slapi_DN *ad_suffix)
  830. {
  831. winsync_get_new_dn_cb thefunc =
  832. (_WinSyncAPI && _WinSyncAPI[WINSYNC_PLUGIN_GET_NEW_DS_USER_DN_CB]) ?
  833. (winsync_get_new_dn_cb)_WinSyncAPI[WINSYNC_PLUGIN_GET_NEW_DS_USER_DN_CB] :
  834. NULL;
  835. if (!thefunc) {
  836. return;
  837. }
  838. (*thefunc)(windows_private_get_api_cookie(ra), rawentry, ad_entry,
  839. new_dn_string, ds_suffix, ad_suffix);
  840. return;
  841. }
  842. void
  843. winsync_plugin_call_get_new_ds_group_dn_cb(const Repl_Agmt *ra, const Slapi_Entry *rawentry,
  844. Slapi_Entry *ad_entry, char **new_dn_string,
  845. const Slapi_DN *ds_suffix, const Slapi_DN *ad_suffix)
  846. {
  847. winsync_get_new_dn_cb thefunc =
  848. (_WinSyncAPI && _WinSyncAPI[WINSYNC_PLUGIN_GET_NEW_DS_GROUP_DN_CB]) ?
  849. (winsync_get_new_dn_cb)_WinSyncAPI[WINSYNC_PLUGIN_GET_NEW_DS_GROUP_DN_CB] :
  850. NULL;
  851. if (!thefunc) {
  852. return;
  853. }
  854. (*thefunc)(windows_private_get_api_cookie(ra), rawentry, ad_entry,
  855. new_dn_string, ds_suffix, ad_suffix);
  856. return;
  857. }
  858. void
  859. winsync_plugin_call_pre_ad_mod_user_mods_cb(const Repl_Agmt *ra, const Slapi_Entry *rawentry,
  860. const Slapi_DN *local_dn,
  861. const Slapi_Entry *ds_entry,
  862. LDAPMod * const *origmods,
  863. Slapi_DN *remote_dn, LDAPMod ***modstosend)
  864. {
  865. winsync_pre_ad_mod_mods_cb thefunc =
  866. (_WinSyncAPI && _WinSyncAPI[WINSYNC_PLUGIN_PRE_AD_MOD_USER_MODS_CB]) ?
  867. (winsync_pre_ad_mod_mods_cb)_WinSyncAPI[WINSYNC_PLUGIN_PRE_AD_MOD_USER_MODS_CB] :
  868. NULL;
  869. if (!thefunc) {
  870. return;
  871. }
  872. (*thefunc)(windows_private_get_api_cookie(ra), rawentry, local_dn,
  873. ds_entry, origmods, remote_dn, modstosend);
  874. return;
  875. }
  876. void
  877. winsync_plugin_call_pre_ad_mod_group_mods_cb(const Repl_Agmt *ra, const Slapi_Entry *rawentry,
  878. const Slapi_DN *local_dn,
  879. const Slapi_Entry *ds_entry,
  880. LDAPMod * const *origmods,
  881. Slapi_DN *remote_dn, LDAPMod ***modstosend)
  882. {
  883. winsync_pre_ad_mod_mods_cb thefunc =
  884. (_WinSyncAPI && _WinSyncAPI[WINSYNC_PLUGIN_PRE_AD_MOD_GROUP_MODS_CB]) ?
  885. (winsync_pre_ad_mod_mods_cb)_WinSyncAPI[WINSYNC_PLUGIN_PRE_AD_MOD_GROUP_MODS_CB] :
  886. NULL;
  887. if (!thefunc) {
  888. return;
  889. }
  890. (*thefunc)(windows_private_get_api_cookie(ra), rawentry, local_dn,
  891. ds_entry, origmods, remote_dn, modstosend);
  892. return;
  893. }
  894. int
  895. winsync_plugin_call_can_add_entry_to_ad_cb(const Repl_Agmt *ra, const Slapi_Entry *local_entry,
  896. const Slapi_DN *remote_dn)
  897. {
  898. winsync_can_add_to_ad_cb thefunc =
  899. (_WinSyncAPI && _WinSyncAPI[WINSYNC_PLUGIN_CAN_ADD_ENTRY_TO_AD_CB]) ?
  900. (winsync_can_add_to_ad_cb)_WinSyncAPI[WINSYNC_PLUGIN_CAN_ADD_ENTRY_TO_AD_CB] :
  901. NULL;
  902. if (!thefunc) {
  903. return 1; /* default is entry can be added to AD */
  904. }
  905. return (*thefunc)(windows_private_get_api_cookie(ra), local_entry, remote_dn);
  906. }
  907. void
  908. winsync_plugin_call_begin_update_cb(const Repl_Agmt *ra, const Slapi_DN *ds_subtree,
  909. const Slapi_DN *ad_subtree, int is_total)
  910. {
  911. winsync_plugin_update_cb thefunc =
  912. (_WinSyncAPI && _WinSyncAPI[WINSYNC_PLUGIN_BEGIN_UPDATE_CB]) ?
  913. (winsync_plugin_update_cb)_WinSyncAPI[WINSYNC_PLUGIN_BEGIN_UPDATE_CB] :
  914. NULL;
  915. if (!thefunc) {
  916. return;
  917. }
  918. (*thefunc)(windows_private_get_api_cookie(ra), ds_subtree, ad_subtree, is_total);
  919. return;
  920. }
  921. void
  922. winsync_plugin_call_end_update_cb(const Repl_Agmt *ra, const Slapi_DN *ds_subtree,
  923. const Slapi_DN *ad_subtree, int is_total)
  924. {
  925. winsync_plugin_update_cb thefunc =
  926. (_WinSyncAPI && _WinSyncAPI[WINSYNC_PLUGIN_END_UPDATE_CB]) ?
  927. (winsync_plugin_update_cb)_WinSyncAPI[WINSYNC_PLUGIN_END_UPDATE_CB] :
  928. NULL;
  929. if (!thefunc) {
  930. return;
  931. }
  932. (*thefunc)(windows_private_get_api_cookie(ra), ds_subtree, ad_subtree, is_total);
  933. return;
  934. }
  935. void
  936. winsync_plugin_call_destroy_agmt_cb(const Repl_Agmt *ra,
  937. const Slapi_DN *ds_subtree,
  938. const Slapi_DN *ad_subtree)
  939. {
  940. winsync_plugin_destroy_agmt_cb thefunc =
  941. (_WinSyncAPI && _WinSyncAPI[WINSYNC_PLUGIN_DESTROY_AGMT_CB]) ?
  942. (winsync_plugin_destroy_agmt_cb)_WinSyncAPI[WINSYNC_PLUGIN_DESTROY_AGMT_CB] :
  943. NULL;
  944. if (thefunc) {
  945. (*thefunc)(windows_private_get_api_cookie(ra), ds_subtree, ad_subtree);
  946. }
  947. return;
  948. }
  949. /* #define WINSYNC_TEST_IPA */
  950. #ifdef WINSYNC_TEST_IPA
  951. #include "ipa-winsync.c"
  952. #include "ipa-winsync-config.c"
  953. #endif