windows_private.c 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257
  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, LDAPMod * const *origmods,
  861. Slapi_DN *remote_dn, LDAPMod ***modstosend)
  862. {
  863. winsync_pre_ad_mod_mods_cb thefunc =
  864. (_WinSyncAPI && _WinSyncAPI[WINSYNC_PLUGIN_PRE_AD_MOD_USER_MODS_CB]) ?
  865. (winsync_pre_ad_mod_mods_cb)_WinSyncAPI[WINSYNC_PLUGIN_PRE_AD_MOD_USER_MODS_CB] :
  866. NULL;
  867. if (!thefunc) {
  868. return;
  869. }
  870. (*thefunc)(windows_private_get_api_cookie(ra), rawentry, local_dn,
  871. origmods, remote_dn, modstosend);
  872. return;
  873. }
  874. void
  875. winsync_plugin_call_pre_ad_mod_group_mods_cb(const Repl_Agmt *ra, const Slapi_Entry *rawentry,
  876. const Slapi_DN *local_dn, LDAPMod * const *origmods,
  877. Slapi_DN *remote_dn, LDAPMod ***modstosend)
  878. {
  879. winsync_pre_ad_mod_mods_cb thefunc =
  880. (_WinSyncAPI && _WinSyncAPI[WINSYNC_PLUGIN_PRE_AD_MOD_GROUP_MODS_CB]) ?
  881. (winsync_pre_ad_mod_mods_cb)_WinSyncAPI[WINSYNC_PLUGIN_PRE_AD_MOD_GROUP_MODS_CB] :
  882. NULL;
  883. if (!thefunc) {
  884. return;
  885. }
  886. (*thefunc)(windows_private_get_api_cookie(ra), rawentry, local_dn,
  887. origmods, remote_dn, modstosend);
  888. return;
  889. }
  890. int
  891. winsync_plugin_call_can_add_entry_to_ad_cb(const Repl_Agmt *ra, const Slapi_Entry *local_entry,
  892. const Slapi_DN *remote_dn)
  893. {
  894. winsync_can_add_to_ad_cb thefunc =
  895. (_WinSyncAPI && _WinSyncAPI[WINSYNC_PLUGIN_CAN_ADD_ENTRY_TO_AD_CB]) ?
  896. (winsync_can_add_to_ad_cb)_WinSyncAPI[WINSYNC_PLUGIN_CAN_ADD_ENTRY_TO_AD_CB] :
  897. NULL;
  898. if (!thefunc) {
  899. return 1; /* default is entry can be added to AD */
  900. }
  901. return (*thefunc)(windows_private_get_api_cookie(ra), local_entry, remote_dn);
  902. }
  903. void
  904. winsync_plugin_call_begin_update_cb(const Repl_Agmt *ra, const Slapi_DN *ds_subtree,
  905. const Slapi_DN *ad_subtree, int is_total)
  906. {
  907. winsync_plugin_update_cb thefunc =
  908. (_WinSyncAPI && _WinSyncAPI[WINSYNC_PLUGIN_BEGIN_UPDATE_CB]) ?
  909. (winsync_plugin_update_cb)_WinSyncAPI[WINSYNC_PLUGIN_BEGIN_UPDATE_CB] :
  910. NULL;
  911. if (!thefunc) {
  912. return;
  913. }
  914. (*thefunc)(windows_private_get_api_cookie(ra), ds_subtree, ad_subtree, is_total);
  915. return;
  916. }
  917. void
  918. winsync_plugin_call_end_update_cb(const Repl_Agmt *ra, const Slapi_DN *ds_subtree,
  919. const Slapi_DN *ad_subtree, int is_total)
  920. {
  921. winsync_plugin_update_cb thefunc =
  922. (_WinSyncAPI && _WinSyncAPI[WINSYNC_PLUGIN_END_UPDATE_CB]) ?
  923. (winsync_plugin_update_cb)_WinSyncAPI[WINSYNC_PLUGIN_END_UPDATE_CB] :
  924. NULL;
  925. if (!thefunc) {
  926. return;
  927. }
  928. (*thefunc)(windows_private_get_api_cookie(ra), ds_subtree, ad_subtree, is_total);
  929. return;
  930. }
  931. void
  932. winsync_plugin_call_destroy_agmt_cb(const Repl_Agmt *ra,
  933. const Slapi_DN *ds_subtree,
  934. const Slapi_DN *ad_subtree)
  935. {
  936. winsync_plugin_destroy_agmt_cb thefunc =
  937. (_WinSyncAPI && _WinSyncAPI[WINSYNC_PLUGIN_DESTROY_AGMT_CB]) ?
  938. (winsync_plugin_destroy_agmt_cb)_WinSyncAPI[WINSYNC_PLUGIN_DESTROY_AGMT_CB] :
  939. NULL;
  940. if (thefunc) {
  941. (*thefunc)(windows_private_get_api_cookie(ra), ds_subtree, ad_subtree);
  942. }
  943. return;
  944. }
  945. /* #define WINSYNC_TEST_IPA */
  946. #ifdef WINSYNC_TEST_IPA
  947. #include "ipa-winsync.c"
  948. #include "ipa-winsync-config.c"
  949. #endif