windows_private.c 97 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790
  1. /** BEGIN COPYRIGHT BLOCK
  2. * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
  3. * Copyright (C) 2005 Red Hat, Inc.
  4. * All rights reserved.
  5. *
  6. * License: GPL (version 3 or any later version).
  7. * See LICENSE for details.
  8. * END COPYRIGHT BLOCK **/
  9. #ifdef HAVE_CONFIG_H
  10. #include <config.h>
  11. #endif
  12. /* windows_private.c */
  13. #include "repl5.h"
  14. #include "slap.h"
  15. #include "slapi-plugin.h"
  16. #include "winsync-plugin.h"
  17. #include "windowsrepl.h"
  18. struct windowsprivate
  19. {
  20. Slapi_DN *windows_subtree; /* DN of synchronized subtree (on the windows side) */
  21. Slapi_DN *directory_subtree; /* DN of synchronized subtree on directory side */
  22. /* this simplifies the mapping as it's simply
  23. from the former to the latter container, or
  24. vice versa */
  25. ber_int_t dirsync_flags;
  26. ber_int_t dirsync_maxattributecount;
  27. char *dirsync_cookie;
  28. int dirsync_cookie_len;
  29. PRBool dirsync_cookie_has_more;
  30. PRBool create_users_from_dirsync;
  31. PRBool create_groups_from_dirsync;
  32. char *windows_domain;
  33. int isnt4;
  34. int iswin2k3;
  35. /* This filter is used to determine if an entry belongs to this agreement. We put it here
  36. * so we only have to allocate each filter once instead of doing it every time we receive a change. */
  37. Slapi_Filter *directory_filter; /* Used for checking if local entries need to be sync'd to AD */
  38. Slapi_Filter *windows_filter; /* Used for checking if remote entries need to be sync'd to DS */
  39. Slapi_Filter *deleted_filter; /* Used for checking if an entry is an AD tombstone */
  40. Slapi_Entry *raw_entry; /* "raw" un-schema processed last entry read from AD */
  41. int keep_raw_entry; /* flag to control when the raw entry is set */
  42. void *api_cookie; /* private data used by api callbacks */
  43. time_t sync_interval; /* how often to run the dirsync search, in seconds */
  44. int one_way; /* Indicates if this is a one-way agreement and which direction it is */
  45. int move_action; /* Indicates what to do with DS entry if AD entry is moved out of scope */
  46. Slapi_Entry *curr_entry; /* entry being retrieved; used for the range retrieval */
  47. char **range_attrs; /* next attributes for the range retrieval */
  48. char *windows_userfilter;
  49. char *directory_userfilter;
  50. struct subtreepair *subtree_pairs; /* Array of subtree pairs (winSyncSubtreePair) */
  51. Slapi_DN *windows_treetop; /* Common subtree top to sync on AD */
  52. /* If winSyncSubtreePair is not set, identical to windows_subtree.
  53. * If set, ancestor node of all AD subtrees. */
  54. Slapi_DN *directory_treetop; /* Common subtree top to sync on DS */
  55. /* If winSyncSubtreePair is not set, identical to directory_subtree.
  56. * If set, ancestor node of all DS subtrees. */
  57. };
  58. static void windows_private_set_windows_domain(const Repl_Agmt *ra, char *domain);
  59. static subtreePair *create_subtree_pairs(char **pairs);
  60. static void free_subtree_pairs(subtreePair **pairs);
  61. static int
  62. true_value_from_string(char *val)
  63. {
  64. if (strcasecmp(val, "on") == 0 || strcasecmp(val, "yes") == 0 ||
  65. strcasecmp(val, "true") == 0 || strcasecmp(val, "1") == 0) {
  66. return 1;
  67. } else {
  68. return 0;
  69. }
  70. }
  71. /* yech - can't declare a constant string array because type_nsds7XX variables
  72. are not constant strings - so have to build a lookup table */
  73. static int
  74. get_next_disallow_attr_type(int *ii, const char **type)
  75. {
  76. switch (*ii) {
  77. case 0:
  78. *type = type_nsds7WindowsReplicaArea;
  79. break;
  80. case 1:
  81. *type = type_nsds7DirectoryReplicaArea;
  82. break;
  83. case 2:
  84. *type = type_nsds7WindowsDomain;
  85. break;
  86. default:
  87. *type = NULL;
  88. break;
  89. }
  90. if (*type) {
  91. (*ii)++;
  92. return 1;
  93. }
  94. return 0;
  95. }
  96. static int
  97. check_update_allowed(Repl_Agmt *ra, const char *type, Slapi_Entry *e, int *retval)
  98. {
  99. int rc = 1;
  100. /* note - it is not an error to defer setting the value in the ra */
  101. *retval = 1;
  102. if (agmt_get_update_in_progress(ra)) {
  103. const char *distype = NULL;
  104. int ii = 0;
  105. while (get_next_disallow_attr_type(&ii, &distype)) {
  106. if (slapi_attr_types_equivalent(type, distype)) {
  107. char *tmpstr = slapi_entry_attr_get_charptr(e, type);
  108. slapi_log_err(SLAPI_LOG_REPL, windows_repl_plugin_name,
  109. "windows_parse_config_entry: setting %s to %s will be "
  110. "deferred until current update is completed\n",
  111. type, tmpstr);
  112. slapi_ch_free_string(&tmpstr);
  113. rc = 0;
  114. break;
  115. }
  116. }
  117. }
  118. return rc;
  119. }
  120. static int
  121. windows_parse_config_entry(Repl_Agmt *ra, const char *type, Slapi_Entry *e)
  122. {
  123. char *tmpstr = NULL;
  124. int retval = 0;
  125. if (!check_update_allowed(ra, type, e, &retval)) {
  126. return retval;
  127. }
  128. /*
  129. * if winSyncSubtreePair is set, WindowsReplicaArea and DirectoryReplicaArea
  130. * are ignored.
  131. */
  132. if (type == NULL || slapi_attr_types_equivalent(type, type_nsds7WindowsReplicaArea)) {
  133. tmpstr = slapi_entry_attr_get_charptr(e, type_nsds7WindowsReplicaArea);
  134. if (NULL != tmpstr) {
  135. windows_private_set_windows_subtree(ra, slapi_sdn_new_dn_passin(tmpstr));
  136. }
  137. retval = 1;
  138. }
  139. if (type == NULL || slapi_attr_types_equivalent(type, type_nsds7DirectoryReplicaArea)) {
  140. tmpstr = slapi_entry_attr_get_charptr(e, type_nsds7DirectoryReplicaArea);
  141. if (NULL != tmpstr) {
  142. windows_private_set_directory_subtree(ra, slapi_sdn_new_dn_passin(tmpstr));
  143. }
  144. retval = 1;
  145. }
  146. if (type == NULL || slapi_attr_types_equivalent(type, type_nsds7CreateNewUsers)) {
  147. tmpstr = slapi_entry_attr_get_charptr(e, type_nsds7CreateNewUsers);
  148. if (NULL != tmpstr && true_value_from_string(tmpstr)) {
  149. windows_private_set_create_users(ra, PR_TRUE);
  150. } else {
  151. windows_private_set_create_users(ra, PR_FALSE);
  152. }
  153. slapi_ch_free((void **)&tmpstr);
  154. /* If protocol is NULL; the agreement is not started yet.
  155. * So, no need to notify. */
  156. if (agmt_get_protocol(ra)) {
  157. prot_notify_agmt_changed(agmt_get_protocol(ra), (char *)agmt_get_long_name(ra));
  158. }
  159. retval = 1;
  160. }
  161. if (type == NULL || slapi_attr_types_equivalent(type, type_nsds7CreateNewGroups)) {
  162. tmpstr = slapi_entry_attr_get_charptr(e, type_nsds7CreateNewGroups);
  163. if (NULL != tmpstr && true_value_from_string(tmpstr)) {
  164. windows_private_set_create_groups(ra, PR_TRUE);
  165. } else {
  166. windows_private_set_create_groups(ra, PR_FALSE);
  167. }
  168. slapi_ch_free((void **)&tmpstr);
  169. /* If protocol is NULL; the agreement is not started yet.
  170. * So, no need to notify. */
  171. if (agmt_get_protocol(ra)) {
  172. prot_notify_agmt_changed(agmt_get_protocol(ra), (char *)agmt_get_long_name(ra));
  173. }
  174. retval = 1;
  175. }
  176. if (type == NULL || slapi_attr_types_equivalent(type, type_nsds7WindowsDomain)) {
  177. tmpstr = slapi_entry_attr_get_charptr(e, type_nsds7WindowsDomain);
  178. if (NULL != tmpstr) {
  179. windows_private_set_windows_domain(ra, tmpstr);
  180. }
  181. /* No need to free tmpstr because it was aliased by the call above */
  182. tmpstr = NULL;
  183. retval = 1;
  184. }
  185. if (type == NULL || slapi_attr_types_equivalent(type, type_winSyncInterval)) {
  186. tmpstr = slapi_entry_attr_get_charptr(e, type_winSyncInterval);
  187. if (NULL != tmpstr) {
  188. windows_private_set_sync_interval(ra, tmpstr);
  189. /* If protocol is NULL; the agreement is not started yet.
  190. * So, no need to notify. */
  191. if (agmt_get_protocol(ra)) {
  192. prot_notify_agmt_changed(agmt_get_protocol(ra), (char *)agmt_get_long_name(ra));
  193. }
  194. }
  195. slapi_ch_free_string(&tmpstr);
  196. retval = 1;
  197. }
  198. if (type == NULL || slapi_attr_types_equivalent(type, type_oneWaySync)) {
  199. tmpstr = slapi_entry_attr_get_charptr(e, type_oneWaySync);
  200. if (NULL != tmpstr) {
  201. if (strcasecmp(tmpstr, "fromWindows") == 0) {
  202. windows_private_set_one_way(ra, ONE_WAY_SYNC_FROM_AD);
  203. } else if (strcasecmp(tmpstr, "toWindows") == 0) {
  204. windows_private_set_one_way(ra, ONE_WAY_SYNC_TO_AD);
  205. } else {
  206. slapi_log_err(SLAPI_LOG_WARNING, windows_repl_plugin_name,
  207. "windows_parse_config_entry - Ignoring illegal setting for %s attribute in replication "
  208. "agreement \"%s\". Valid values are \"toWindows\" or "
  209. "\"fromWindows\".\n",
  210. type_oneWaySync, slapi_entry_get_dn(e));
  211. windows_private_set_one_way(ra, ONE_WAY_SYNC_DISABLED);
  212. }
  213. } else {
  214. windows_private_set_one_way(ra, ONE_WAY_SYNC_DISABLED);
  215. }
  216. slapi_ch_free((void **)&tmpstr);
  217. /* If protocol is NULL; the agreement is not started yet.
  218. * So, no need to notify. */
  219. if (agmt_get_protocol(ra)) {
  220. prot_notify_agmt_changed(agmt_get_protocol(ra), (char *)agmt_get_long_name(ra));
  221. }
  222. retval = 1;
  223. }
  224. if (type == NULL || slapi_attr_types_equivalent(type, type_winsyncMoveAction)) {
  225. tmpstr = slapi_entry_attr_get_charptr(e, type_winsyncMoveAction);
  226. if (NULL != tmpstr) {
  227. if (strcasecmp(tmpstr, "delete") == 0) {
  228. windows_private_set_move_action(ra, MOVE_DOES_DELETE);
  229. } else if (strcasecmp(tmpstr, "unsync") == 0) {
  230. windows_private_set_move_action(ra, MOVE_DOES_UNSYNC);
  231. } else if (strcasecmp(tmpstr, "none") == 0) {
  232. windows_private_set_move_action(ra, MOVE_DOES_NOTHING);
  233. } else {
  234. slapi_log_err(SLAPI_LOG_WARNING, windows_repl_plugin_name,
  235. "windows_parse_config_entry - Ignoring illegal setting for %s attribute in replication "
  236. "agreement \"%s\". Valid values are \"delete\" or "
  237. "\"unsync\".\n",
  238. type_winsyncMoveAction, slapi_entry_get_dn(e));
  239. windows_private_set_move_action(ra, MOVE_DOES_NOTHING);
  240. }
  241. } else {
  242. windows_private_set_move_action(ra, MOVE_DOES_NOTHING);
  243. }
  244. slapi_ch_free((void **)&tmpstr);
  245. /* If protocol is NULL; the agreement is not started yet.
  246. * So, no need to notify. */
  247. if (agmt_get_protocol(ra)) {
  248. prot_notify_agmt_changed(agmt_get_protocol(ra), (char *)agmt_get_long_name(ra));
  249. }
  250. retval = 1;
  251. }
  252. if (type == NULL || slapi_attr_types_equivalent(type, type_winSyncWindowsFilter)) {
  253. tmpstr = slapi_entry_attr_get_charptr(e, type_winSyncWindowsFilter);
  254. windows_private_set_windows_userfilter(ra, tmpstr); /* if NULL, set it */
  255. retval = 1;
  256. }
  257. if (type == NULL || slapi_attr_types_equivalent(type, type_winSyncDirectoryFilter)) {
  258. tmpstr = slapi_entry_attr_get_charptr(e, type_winSyncDirectoryFilter);
  259. windows_private_set_directory_userfilter(ra, tmpstr); /* if NULL, set it */
  260. retval = 1;
  261. }
  262. if (type == NULL || slapi_attr_types_equivalent(type, type_winSyncSubtreePair)) {
  263. char **parray = slapi_entry_attr_get_charray(e, type_winSyncSubtreePair);
  264. /* If winSyncSubtreePair is not set, subtree_pairs is NULL */
  265. windows_private_set_subtreepairs(ra, parray);
  266. slapi_ch_array_free(parray);
  267. retval = 1;
  268. }
  269. windows_private_set_windows_treetop(ra, NULL);
  270. windows_private_set_directory_treetop(ra, NULL);
  271. return retval;
  272. }
  273. /* Returns non-zero if the modify was ok, zero if not */
  274. int
  275. windows_handle_modify_agreement(Repl_Agmt *ra, const char *type, Slapi_Entry *e)
  276. {
  277. /* Is this a Windows agreement ? */
  278. if (get_agmt_agreement_type(ra) == REPLICA_TYPE_WINDOWS) {
  279. return windows_parse_config_entry(ra, type, e);
  280. } else {
  281. return 0;
  282. }
  283. }
  284. void
  285. windows_update_done(Repl_Agmt *agmt, int is_total __attribute__((unused)))
  286. {
  287. /* "flush" the changes made during the update to the agmt */
  288. /* get the agmt entry */
  289. Slapi_DN *agmtdn = slapi_sdn_dup(agmt_get_dn_byref(agmt));
  290. Slapi_Entry *agmte = NULL;
  291. int rc = slapi_search_internal_get_entry(agmtdn, NULL, &agmte,
  292. repl_get_plugin_identity(PLUGIN_MULTIMASTER_REPLICATION));
  293. if ((rc == 0) && agmte) {
  294. int ii = 0;
  295. const char *distype = NULL;
  296. while (get_next_disallow_attr_type(&ii, &distype)) {
  297. windows_handle_modify_agreement(agmt, distype, agmte);
  298. }
  299. }
  300. slapi_entry_free(agmte);
  301. slapi_sdn_free(&agmtdn);
  302. }
  303. void
  304. windows_init_agreement_from_entry(Repl_Agmt *ra, Slapi_Entry *e)
  305. {
  306. agmt_set_priv(ra, windows_private_new());
  307. windows_parse_config_entry(ra, NULL, e);
  308. windows_plugin_init(ra);
  309. }
  310. const char *
  311. windows_private_get_purl(const Repl_Agmt *ra)
  312. {
  313. const char *windows_purl;
  314. char *hostname;
  315. hostname = agmt_get_hostname(ra);
  316. if (slapi_is_ipv6_addr(hostname)) {
  317. /* need to put brackets around the ipv6 address */
  318. windows_purl = slapi_ch_smprintf("ldap://[%s]:%d", hostname, agmt_get_port(ra));
  319. } else {
  320. windows_purl = slapi_ch_smprintf("ldap://%s:%d", hostname, agmt_get_port(ra));
  321. }
  322. slapi_ch_free_string(&hostname);
  323. return windows_purl;
  324. }
  325. Dirsync_Private *
  326. windows_private_new()
  327. {
  328. Dirsync_Private *dp;
  329. slapi_log_err(SLAPI_LOG_TRACE, windows_repl_plugin_name, "=> windows_private_new\n");
  330. dp = (Dirsync_Private *)slapi_ch_calloc(sizeof(Dirsync_Private), 1);
  331. dp->dirsync_maxattributecount = -1;
  332. dp->directory_filter = NULL;
  333. dp->windows_filter = NULL;
  334. dp->deleted_filter = NULL;
  335. dp->sync_interval = PERIODIC_DIRSYNC_INTERVAL;
  336. dp->windows_userfilter = NULL;
  337. dp->directory_userfilter = NULL;
  338. dp->subtree_pairs = NULL;
  339. dp->windows_treetop = NULL;
  340. dp->directory_treetop = NULL;
  341. slapi_log_err(SLAPI_LOG_TRACE, windows_repl_plugin_name, "<= windows_private_new\n");
  342. return dp;
  343. }
  344. void
  345. windows_agreement_delete(Repl_Agmt *ra)
  346. {
  347. const subtreePair *sp;
  348. Dirsync_Private *dp = (Dirsync_Private *)agmt_get_priv(ra);
  349. slapi_log_err(SLAPI_LOG_TRACE, windows_repl_plugin_name, "=> windows_private_delete\n");
  350. PR_ASSERT(dp != NULL);
  351. winsync_plugin_call_destroy_agmt_cb(ra, dp->directory_subtree,
  352. dp->windows_subtree);
  353. windows_plugin_cleanup_agmt(ra);
  354. slapi_sdn_free(&dp->directory_subtree);
  355. slapi_sdn_free(&dp->windows_subtree);
  356. slapi_filter_free(dp->directory_filter, 1);
  357. slapi_filter_free(dp->windows_filter, 1);
  358. slapi_filter_free(dp->deleted_filter, 1);
  359. slapi_entry_free(dp->raw_entry);
  360. slapi_ch_free_string(&dp->windows_domain);
  361. dp->raw_entry = NULL;
  362. dp->api_cookie = NULL;
  363. slapi_ch_free_string(&dp->dirsync_cookie);
  364. dp->dirsync_cookie_len = 0;
  365. slapi_ch_free_string(&dp->windows_userfilter);
  366. slapi_ch_free_string(&dp->directory_userfilter);
  367. slapi_sdn_free((Slapi_DN **)&dp->windows_treetop);
  368. slapi_sdn_free((Slapi_DN **)&dp->directory_treetop);
  369. for (sp = dp->subtree_pairs; sp && sp->ADsubtree && sp->DSsubtree; sp++) {
  370. slapi_sdn_free((Slapi_DN **)&sp->ADsubtree);
  371. slapi_sdn_free((Slapi_DN **)&sp->DSsubtree);
  372. }
  373. slapi_ch_free((void **)&dp->subtree_pairs);
  374. slapi_ch_free((void **)&dp);
  375. slapi_log_err(SLAPI_LOG_TRACE, windows_repl_plugin_name, "<= windows_private_delete\n");
  376. }
  377. int
  378. windows_private_get_isnt4(const Repl_Agmt *ra)
  379. {
  380. Dirsync_Private *dp;
  381. slapi_log_err(SLAPI_LOG_TRACE, windows_repl_plugin_name, "=> windows_private_get_isnt4\n");
  382. PR_ASSERT(ra);
  383. dp = (Dirsync_Private *)agmt_get_priv(ra);
  384. PR_ASSERT(dp);
  385. slapi_log_err(SLAPI_LOG_TRACE, windows_repl_plugin_name, "<= windows_private_get_isnt4\n");
  386. return dp->isnt4;
  387. }
  388. void
  389. windows_private_set_isnt4(const Repl_Agmt *ra, int isit)
  390. {
  391. Dirsync_Private *dp;
  392. slapi_log_err(SLAPI_LOG_TRACE, windows_repl_plugin_name, "=> windows_private_set_isnt4\n");
  393. PR_ASSERT(ra);
  394. dp = (Dirsync_Private *)agmt_get_priv(ra);
  395. PR_ASSERT(dp);
  396. dp->isnt4 = isit;
  397. slapi_log_err(SLAPI_LOG_TRACE, windows_repl_plugin_name, "<= windows_private_set_isnt4\n");
  398. }
  399. int
  400. windows_private_get_iswin2k3(const Repl_Agmt *ra)
  401. {
  402. Dirsync_Private *dp;
  403. slapi_log_err(SLAPI_LOG_TRACE, windows_repl_plugin_name, "=> windows_private_get_iswin2k3\n");
  404. PR_ASSERT(ra);
  405. dp = (Dirsync_Private *)agmt_get_priv(ra);
  406. PR_ASSERT(dp);
  407. slapi_log_err(SLAPI_LOG_TRACE, windows_repl_plugin_name, "<= windows_private_get_iswin2k3\n");
  408. return dp->iswin2k3;
  409. }
  410. void
  411. windows_private_set_iswin2k3(const Repl_Agmt *ra, int isit)
  412. {
  413. Dirsync_Private *dp;
  414. slapi_log_err(SLAPI_LOG_TRACE, windows_repl_plugin_name, "=> windows_private_set_iswin2k3\n");
  415. PR_ASSERT(ra);
  416. dp = (Dirsync_Private *)agmt_get_priv(ra);
  417. PR_ASSERT(dp);
  418. dp->iswin2k3 = isit;
  419. slapi_log_err(SLAPI_LOG_TRACE, windows_repl_plugin_name, "<= windows_private_set_iswin2k3\n");
  420. }
  421. /* Returns a copy of the Slapi_Filter pointer. The caller should not free it */
  422. Slapi_Filter *
  423. windows_private_get_directory_filter(const Repl_Agmt *ra)
  424. {
  425. Dirsync_Private *dp;
  426. slapi_log_err(SLAPI_LOG_TRACE, windows_repl_plugin_name, "=> windows_private_get_directory_filter\n");
  427. PR_ASSERT(ra);
  428. dp = (Dirsync_Private *)agmt_get_priv(ra);
  429. PR_ASSERT(dp);
  430. if (dp->directory_filter == NULL) {
  431. char *string_filter = NULL;
  432. const char *userfilter = windows_private_get_directory_userfilter(ra);
  433. if (userfilter) {
  434. if ('(' == *userfilter) {
  435. string_filter = slapi_ch_smprintf("(&(|(objectclass=ntuser)(objectclass=ntgroup))(ntUserDomainId=*)%s)",
  436. userfilter);
  437. } else {
  438. string_filter = slapi_ch_smprintf("(&(|(objectclass=ntuser)(objectclass=ntgroup))(ntUserDomainId=*)(%s))",
  439. userfilter);
  440. }
  441. } else {
  442. string_filter = slapi_ch_strdup("(&(|(objectclass=ntuser)(objectclass=ntgroup))(ntUserDomainId=*))");
  443. }
  444. /* The filter gets freed in windows_agreement_delete() */
  445. dp->directory_filter = slapi_str2filter(string_filter);
  446. slapi_ch_free_string(&string_filter);
  447. }
  448. slapi_log_err(SLAPI_LOG_TRACE, windows_repl_plugin_name, "<= windows_private_get_directory_filter\n");
  449. return dp->directory_filter;
  450. }
  451. /* Returns a copy of the Slapi_Filter pointer. The caller should not free it */
  452. Slapi_Filter *
  453. windows_private_get_windows_filter(const Repl_Agmt *ra)
  454. {
  455. Dirsync_Private *dp;
  456. slapi_log_err(SLAPI_LOG_TRACE, windows_repl_plugin_name, "=> windows_private_get_windows_filter\n");
  457. PR_ASSERT(ra);
  458. dp = (Dirsync_Private *)agmt_get_priv(ra);
  459. PR_ASSERT(dp);
  460. if (dp->windows_filter == NULL) {
  461. const char *userfilter = windows_private_get_windows_userfilter(ra);
  462. if (userfilter) {
  463. char *string_filter = NULL;
  464. if ('(' == *userfilter) {
  465. string_filter = slapi_ch_strdup(userfilter);
  466. } else {
  467. string_filter = slapi_ch_smprintf("(%s)", userfilter);
  468. }
  469. /* The filter gets freed in windows_agreement_delete() */
  470. dp->windows_filter = slapi_str2filter(string_filter);
  471. slapi_ch_free_string(&string_filter);
  472. }
  473. }
  474. slapi_log_err(SLAPI_LOG_TRACE, windows_repl_plugin_name, "<= windows_private_get_windows_filter\n");
  475. return dp->windows_filter;
  476. }
  477. /* Returns a copy of the Slapi_Filter pointer. The caller should not free it */
  478. Slapi_Filter *
  479. windows_private_get_deleted_filter(const Repl_Agmt *ra)
  480. {
  481. Dirsync_Private *dp;
  482. slapi_log_err(SLAPI_LOG_TRACE, windows_repl_plugin_name, "=> windows_private_get_deleted_filter\n");
  483. PR_ASSERT(ra);
  484. dp = (Dirsync_Private *)agmt_get_priv(ra);
  485. PR_ASSERT(dp);
  486. if (dp->deleted_filter == NULL) {
  487. char *string_filter = slapi_ch_strdup("(isdeleted=*)");
  488. /* The filter gets freed in windows_agreement_delete() */
  489. dp->deleted_filter = slapi_str2filter(string_filter);
  490. slapi_ch_free_string(&string_filter);
  491. }
  492. slapi_log_err(SLAPI_LOG_TRACE, windows_repl_plugin_name, "<= windows_private_get_deleted_filter\n");
  493. return dp->deleted_filter;
  494. }
  495. /* Returns a copy of the Slapi_DN pointer, no need to free it */
  496. const Slapi_DN *
  497. windows_private_get_windows_subtree(const Repl_Agmt *ra)
  498. {
  499. Dirsync_Private *dp;
  500. slapi_log_err(SLAPI_LOG_TRACE, windows_repl_plugin_name, "=> windows_private_get_windows_subtree\n");
  501. PR_ASSERT(ra);
  502. dp = (Dirsync_Private *)agmt_get_priv(ra);
  503. PR_ASSERT(dp);
  504. slapi_log_err(SLAPI_LOG_TRACE, windows_repl_plugin_name, "<= windows_private_get_windows_subtree\n");
  505. return dp->windows_subtree;
  506. }
  507. const char *
  508. windows_private_get_windows_domain(const Repl_Agmt *ra)
  509. {
  510. Dirsync_Private *dp;
  511. slapi_log_err(SLAPI_LOG_TRACE, windows_repl_plugin_name, "=> windows_private_get_windows_domain\n");
  512. PR_ASSERT(ra);
  513. dp = (Dirsync_Private *)agmt_get_priv(ra);
  514. PR_ASSERT(dp);
  515. slapi_log_err(SLAPI_LOG_TRACE, windows_repl_plugin_name, "<= windows_private_get_windows_domain\n");
  516. return dp->windows_domain;
  517. }
  518. static void
  519. windows_private_set_windows_domain(const Repl_Agmt *ra, char *domain)
  520. {
  521. Dirsync_Private *dp;
  522. slapi_log_err(SLAPI_LOG_TRACE, windows_repl_plugin_name, "=> windows_private_set_windows_domain\n");
  523. PR_ASSERT(ra);
  524. dp = (Dirsync_Private *)agmt_get_priv(ra);
  525. PR_ASSERT(dp);
  526. slapi_ch_free_string(&dp->windows_domain);
  527. dp->windows_domain = domain;
  528. slapi_log_err(SLAPI_LOG_TRACE, windows_repl_plugin_name, "<= windows_private_set_windows_domain\n");
  529. }
  530. /* Returns a copy of the Slapi_DN pointer, no need to free it */
  531. const Slapi_DN *
  532. windows_private_get_directory_subtree(const Repl_Agmt *ra)
  533. {
  534. Dirsync_Private *dp;
  535. slapi_log_err(SLAPI_LOG_TRACE, windows_repl_plugin_name, "=> windows_private_get_directory_replarea\n");
  536. PR_ASSERT(ra);
  537. dp = (Dirsync_Private *)agmt_get_priv(ra);
  538. PR_ASSERT(dp);
  539. slapi_log_err(SLAPI_LOG_TRACE, windows_repl_plugin_name, "<= windows_private_get_directory_replarea\n");
  540. return dp->directory_subtree;
  541. }
  542. /* Takes a copy of the sdn passed in */
  543. void
  544. windows_private_set_windows_subtree(const Repl_Agmt *ra, Slapi_DN *sdn)
  545. {
  546. Dirsync_Private *dp;
  547. slapi_log_err(SLAPI_LOG_TRACE, windows_repl_plugin_name, "=> windows_private_set_windows_replarea\n");
  548. PR_ASSERT(ra);
  549. PR_ASSERT(sdn);
  550. dp = (Dirsync_Private *)agmt_get_priv(ra);
  551. PR_ASSERT(dp);
  552. slapi_sdn_free(&dp->windows_subtree);
  553. dp->windows_subtree = sdn;
  554. slapi_log_err(SLAPI_LOG_TRACE, windows_repl_plugin_name, "<= windows_private_set_windows_replarea\n");
  555. }
  556. /* Takes a copy of the sdn passed in */
  557. void
  558. windows_private_set_directory_subtree(const Repl_Agmt *ra, Slapi_DN *sdn)
  559. {
  560. Dirsync_Private *dp;
  561. slapi_log_err(SLAPI_LOG_TRACE, windows_repl_plugin_name, "=> windows_private_set_directory_replarea\n");
  562. PR_ASSERT(ra);
  563. PR_ASSERT(sdn);
  564. dp = (Dirsync_Private *)agmt_get_priv(ra);
  565. PR_ASSERT(dp);
  566. slapi_sdn_free(&dp->directory_subtree);
  567. dp->directory_subtree = sdn;
  568. slapi_log_err(SLAPI_LOG_TRACE, windows_repl_plugin_name, "<= windows_private_set_directory_replarea\n");
  569. }
  570. PRBool
  571. windows_private_create_users(const Repl_Agmt *ra)
  572. {
  573. Dirsync_Private *dp;
  574. slapi_log_err(SLAPI_LOG_TRACE, windows_repl_plugin_name, "=> windows_private_create_users\n");
  575. PR_ASSERT(ra);
  576. dp = (Dirsync_Private *)agmt_get_priv(ra);
  577. PR_ASSERT(dp);
  578. slapi_log_err(SLAPI_LOG_TRACE, windows_repl_plugin_name, "<= windows_private_create_users\n");
  579. return dp->create_users_from_dirsync;
  580. }
  581. void
  582. windows_private_set_create_users(const Repl_Agmt *ra, PRBool value)
  583. {
  584. Dirsync_Private *dp;
  585. slapi_log_err(SLAPI_LOG_TRACE, windows_repl_plugin_name, "=> windows_private_set_create_users\n");
  586. PR_ASSERT(ra);
  587. dp = (Dirsync_Private *)agmt_get_priv(ra);
  588. PR_ASSERT(dp);
  589. dp->create_users_from_dirsync = value;
  590. slapi_log_err(SLAPI_LOG_TRACE, windows_repl_plugin_name, "<= windows_private_set_create_users\n");
  591. }
  592. PRBool
  593. windows_private_create_groups(const Repl_Agmt *ra)
  594. {
  595. Dirsync_Private *dp;
  596. slapi_log_err(SLAPI_LOG_TRACE, windows_repl_plugin_name, "=> windows_private_create_groups\n");
  597. PR_ASSERT(ra);
  598. dp = (Dirsync_Private *)agmt_get_priv(ra);
  599. PR_ASSERT(dp);
  600. slapi_log_err(SLAPI_LOG_TRACE, windows_repl_plugin_name, "<= windows_private_create_groups\n");
  601. return dp->create_groups_from_dirsync;
  602. }
  603. void
  604. windows_private_set_create_groups(const Repl_Agmt *ra, PRBool value)
  605. {
  606. Dirsync_Private *dp;
  607. slapi_log_err(SLAPI_LOG_TRACE, windows_repl_plugin_name, "=> windows_private_set_create_groups\n");
  608. PR_ASSERT(ra);
  609. dp = (Dirsync_Private *)agmt_get_priv(ra);
  610. PR_ASSERT(dp);
  611. dp->create_groups_from_dirsync = value;
  612. slapi_log_err(SLAPI_LOG_TRACE, windows_repl_plugin_name, "<= windows_private_set_create_groups\n");
  613. }
  614. int
  615. windows_private_get_one_way(const Repl_Agmt *ra)
  616. {
  617. Dirsync_Private *dp;
  618. slapi_log_err(SLAPI_LOG_TRACE, windows_repl_plugin_name, "=> windows_private_get_one_way\n");
  619. PR_ASSERT(ra);
  620. dp = (Dirsync_Private *)agmt_get_priv(ra);
  621. PR_ASSERT(dp);
  622. slapi_log_err(SLAPI_LOG_TRACE, windows_repl_plugin_name, "<= windows_private_get_one_way\n");
  623. return dp->one_way;
  624. }
  625. void
  626. windows_private_set_one_way(const Repl_Agmt *ra, int value)
  627. {
  628. Dirsync_Private *dp;
  629. slapi_log_err(SLAPI_LOG_TRACE, windows_repl_plugin_name, "=> windows_private_set_one_way\n");
  630. PR_ASSERT(ra);
  631. dp = (Dirsync_Private *)agmt_get_priv(ra);
  632. PR_ASSERT(dp);
  633. dp->one_way = value;
  634. slapi_log_err(SLAPI_LOG_TRACE, windows_repl_plugin_name, "<= windows_private_set_one_way\n");
  635. }
  636. const char *
  637. windows_private_get_windows_userfilter(const Repl_Agmt *ra)
  638. {
  639. Dirsync_Private *dp;
  640. slapi_log_err(SLAPI_LOG_TRACE, windows_repl_plugin_name, "=> windows_private_get_windows_userfilter\n");
  641. PR_ASSERT(ra);
  642. dp = (Dirsync_Private *)agmt_get_priv(ra);
  643. PR_ASSERT(dp);
  644. slapi_log_err(SLAPI_LOG_TRACE, windows_repl_plugin_name, "<= windows_private_get_windows_userfilter\n");
  645. return dp->windows_userfilter;
  646. }
  647. /* filter is passed in */
  648. void
  649. windows_private_set_windows_userfilter(const Repl_Agmt *ra, char *filter)
  650. {
  651. Dirsync_Private *dp;
  652. slapi_log_err(SLAPI_LOG_TRACE, windows_repl_plugin_name, "=> windows_private_set_windows_userfilter\n");
  653. PR_ASSERT(ra);
  654. dp = (Dirsync_Private *)agmt_get_priv(ra);
  655. PR_ASSERT(dp);
  656. slapi_ch_free_string(&dp->windows_userfilter);
  657. dp->windows_userfilter = filter;
  658. slapi_log_err(SLAPI_LOG_TRACE, windows_repl_plugin_name, "<= windows_private_set_windows_userfilter\n");
  659. }
  660. const char *
  661. windows_private_get_directory_userfilter(const Repl_Agmt *ra)
  662. {
  663. Dirsync_Private *dp;
  664. slapi_log_err(SLAPI_LOG_TRACE, windows_repl_plugin_name, "=> windows_private_get_directory_userfilter\n");
  665. PR_ASSERT(ra);
  666. dp = (Dirsync_Private *)agmt_get_priv(ra);
  667. PR_ASSERT(dp);
  668. slapi_log_err(SLAPI_LOG_TRACE, windows_repl_plugin_name, "<= windows_private_get_directory_userfilter\n");
  669. return dp->directory_userfilter;
  670. }
  671. /* filter is passed in */
  672. void
  673. windows_private_set_directory_userfilter(const Repl_Agmt *ra, char *filter)
  674. {
  675. Dirsync_Private *dp;
  676. slapi_log_err(SLAPI_LOG_TRACE, windows_repl_plugin_name, "=> windows_private_set_directory_userfilter\n");
  677. PR_ASSERT(ra);
  678. dp = (Dirsync_Private *)agmt_get_priv(ra);
  679. PR_ASSERT(dp);
  680. slapi_ch_free_string(&dp->directory_userfilter);
  681. dp->directory_userfilter = filter;
  682. slapi_log_err(SLAPI_LOG_TRACE, windows_repl_plugin_name, "<= windows_private_set_directory_userfilter\n");
  683. }
  684. const subtreePair *
  685. windows_private_get_subtreepairs(const Repl_Agmt *ra)
  686. {
  687. Dirsync_Private *dp;
  688. slapi_log_err(SLAPI_LOG_TRACE, windows_repl_plugin_name, "=> windows_private_get_subtreepairs\n");
  689. PR_ASSERT(ra);
  690. dp = (Dirsync_Private *)agmt_get_priv(ra);
  691. PR_ASSERT(dp);
  692. slapi_log_err(SLAPI_LOG_TRACE, windows_repl_plugin_name, "<= windows_private_get_subtreepairs\n");
  693. return dp->subtree_pairs;
  694. }
  695. /* parray is NOT passed in; caller frees it. */
  696. void
  697. windows_private_set_subtreepairs(const Repl_Agmt *ra, char **parray)
  698. {
  699. Dirsync_Private *dp;
  700. slapi_log_err(SLAPI_LOG_TRACE, windows_repl_plugin_name, "=> windows_private_set_subtreepairs\n");
  701. PR_ASSERT(ra);
  702. dp = (Dirsync_Private *)agmt_get_priv(ra);
  703. PR_ASSERT(dp);
  704. free_subtree_pairs(&(dp->subtree_pairs));
  705. dp->subtree_pairs = create_subtree_pairs(parray);
  706. slapi_log_err(SLAPI_LOG_TRACE, windows_repl_plugin_name, "<= windows_private_set_subtreepairs\n");
  707. }
  708. /*
  709. * winSyncSubtreePair: <DS_SUBTREE>:<WINDOWS_SUBTREE>
  710. * E.g.,
  711. * winSyncSubtreePair: ou=people,dc=example,dc=com:CN=users,DC=example,DC=com
  712. * winSyncSubtreePair: ou=adminpeople,dc=example,dc=com:CN=adminusers,DC=example,DC=com
  713. */
  714. static subtreePair *
  715. create_subtree_pairs(char **pairs)
  716. {
  717. subtreePair *subtree_pairs = NULL;
  718. subtreePair *spp;
  719. char **ptr;
  720. char *p0, *p1;
  721. char *saveptr = NULL;
  722. int cnt;
  723. for (cnt = 0, ptr = pairs; ptr && *ptr; cnt++, ptr++)
  724. ;
  725. if (0 == cnt) {
  726. return NULL;
  727. }
  728. subtree_pairs = (subtreePair *)slapi_ch_calloc(cnt + 1, sizeof(subtreePair));
  729. spp = subtree_pairs;
  730. for (ptr = pairs; ptr && *ptr; ptr++) {
  731. p0 = ldap_utf8strtok_r(*ptr, ":", &saveptr);
  732. p1 = ldap_utf8strtok_r(NULL, ":", &saveptr);
  733. if ((NULL == p0) || (NULL == p1)) {
  734. slapi_log_err(SLAPI_LOG_ERR, windows_repl_plugin_name,
  735. "create_subtree_pairs - Ignoring invalid subtree pairs \"%s\".\n", *ptr);
  736. continue;
  737. }
  738. spp->DSsubtree = slapi_sdn_new_dn_byval(p0);
  739. if (NULL == spp->DSsubtree) {
  740. slapi_log_err(SLAPI_LOG_ERR, windows_repl_plugin_name,
  741. "create_subtree_pairs - Ignoring invalid DS subtree \"%s\".\n", p0);
  742. continue;
  743. }
  744. spp->ADsubtree = slapi_sdn_new_dn_byval(p1);
  745. if (NULL == spp->ADsubtree) {
  746. slapi_log_err(SLAPI_LOG_ERR, windows_repl_plugin_name,
  747. "create_subtree_pairs - Ignoring invalid AD subtree \"%s\".\n", p1);
  748. slapi_sdn_free(&(spp->DSsubtree));
  749. continue;
  750. }
  751. spp++;
  752. }
  753. return subtree_pairs;
  754. }
  755. static void
  756. free_subtree_pairs(subtreePair **pairs)
  757. {
  758. subtreePair *p;
  759. if (NULL == pairs) {
  760. return;
  761. }
  762. /*
  763. * If exists, the subtree pair is both non-NULL or NULL.
  764. * Both NULL is the condition to stop the loop.
  765. */
  766. for (p = *pairs; p && p->ADsubtree && p->DSsubtree; p++) {
  767. slapi_sdn_free(&(p->ADsubtree));
  768. slapi_sdn_free(&(p->DSsubtree));
  769. }
  770. slapi_ch_free((void **)pairs);
  771. }
  772. const Slapi_DN *
  773. windows_private_get_windows_treetop(const Repl_Agmt *ra)
  774. {
  775. Dirsync_Private *dp;
  776. slapi_log_err(SLAPI_LOG_TRACE, windows_repl_plugin_name, "=> windows_private_get_windows_treetop\n");
  777. PR_ASSERT(ra);
  778. dp = (Dirsync_Private *)agmt_get_priv(ra);
  779. PR_ASSERT(dp);
  780. slapi_log_err(SLAPI_LOG_TRACE, windows_repl_plugin_name, "<= windows_private_get_windows_treetop\n");
  781. return dp->windows_treetop;
  782. }
  783. /* treetop is NOT passed in */
  784. void
  785. windows_private_set_windows_treetop(const Repl_Agmt *ra, char *treetop)
  786. {
  787. Dirsync_Private *dp;
  788. slapi_log_err(SLAPI_LOG_TRACE, windows_repl_plugin_name, "=> windows_private_set_windows_treetop\n");
  789. PR_ASSERT(ra);
  790. dp = (Dirsync_Private *)agmt_get_priv(ra);
  791. PR_ASSERT(dp);
  792. slapi_sdn_free(&(dp->windows_treetop));
  793. if (treetop) {
  794. dp->windows_treetop = slapi_sdn_new_dn_byval(treetop);
  795. } else {
  796. const subtreePair *subtree_pairs = windows_private_get_subtreepairs(ra);
  797. const subtreePair *sp;
  798. if (subtree_pairs) {
  799. Slapi_DN *treetop_sdn = NULL;
  800. for (sp = subtree_pairs; sp && sp->ADsubtree; sp++) {
  801. if (NULL == treetop_sdn) {
  802. treetop_sdn = slapi_sdn_dup(sp->ADsubtree);
  803. } else {
  804. Slapi_DN *prev = treetop_sdn;
  805. treetop_sdn = slapi_sdn_common_ancestor(prev, sp->ADsubtree);
  806. slapi_sdn_free(&prev);
  807. }
  808. }
  809. if (treetop_sdn) {
  810. dp->windows_treetop = treetop_sdn;
  811. } else {
  812. slapi_log_err(SLAPI_LOG_ERR, windows_repl_plugin_name,
  813. "windows_private_set_windows_treetop - "
  814. "winSyncSubtreePair contains inconsistent Windows subtrees.\n");
  815. dp->windows_treetop = NULL;
  816. }
  817. } else {
  818. const Slapi_DN *windows_subtree = windows_private_get_windows_subtree(ra);
  819. dp->windows_treetop = slapi_sdn_dup(windows_subtree);
  820. }
  821. }
  822. slapi_log_err(SLAPI_LOG_TRACE, windows_repl_plugin_name, "<= windows_private_set_windows_treetop\n");
  823. }
  824. const Slapi_DN *
  825. windows_private_get_directory_treetop(const Repl_Agmt *ra)
  826. {
  827. Dirsync_Private *dp;
  828. slapi_log_err(SLAPI_LOG_TRACE, windows_repl_plugin_name, "=> windows_private_get_directory_treetop\n");
  829. PR_ASSERT(ra);
  830. dp = (Dirsync_Private *)agmt_get_priv(ra);
  831. PR_ASSERT(dp);
  832. slapi_log_err(SLAPI_LOG_TRACE, windows_repl_plugin_name, "<= windows_private_get_directory_treetop\n");
  833. return dp->directory_treetop;
  834. }
  835. /* treetop is NOT passed in */
  836. void
  837. windows_private_set_directory_treetop(const Repl_Agmt *ra, char *treetop)
  838. {
  839. Dirsync_Private *dp;
  840. slapi_log_err(SLAPI_LOG_TRACE, windows_repl_plugin_name, "=> windows_private_set_directory_treetop\n");
  841. PR_ASSERT(ra);
  842. dp = (Dirsync_Private *)agmt_get_priv(ra);
  843. PR_ASSERT(dp);
  844. slapi_sdn_free(&(dp->directory_treetop));
  845. if (treetop) {
  846. dp->directory_treetop = slapi_sdn_new_dn_byval(treetop);
  847. } else {
  848. const subtreePair *subtree_pairs = windows_private_get_subtreepairs(ra);
  849. if (subtree_pairs) {
  850. const subtreePair *sp;
  851. Slapi_DN *treetop_sdn = NULL;
  852. for (sp = subtree_pairs; sp && sp->DSsubtree; sp++) {
  853. if (NULL == treetop_sdn) {
  854. treetop_sdn = slapi_sdn_dup(sp->DSsubtree);
  855. } else {
  856. Slapi_DN *prev = treetop_sdn;
  857. treetop_sdn = slapi_sdn_common_ancestor(prev, sp->DSsubtree);
  858. slapi_sdn_free(&prev);
  859. }
  860. }
  861. if (treetop_sdn) {
  862. dp->directory_treetop = treetop_sdn;
  863. } else {
  864. slapi_log_err(SLAPI_LOG_ERR, windows_repl_plugin_name,
  865. "windows_private_set_directory_treetop - "
  866. "winSyncSubtreePair contains inconsistent Windows subtrees.\n");
  867. dp->directory_treetop = NULL;
  868. }
  869. } else {
  870. const Slapi_DN *directory_subtree = windows_private_get_directory_subtree(ra);
  871. dp->directory_treetop = slapi_sdn_dup(directory_subtree);
  872. }
  873. }
  874. slapi_log_err(SLAPI_LOG_TRACE, windows_repl_plugin_name, "<= windows_private_set_directory_treetop\n");
  875. }
  876. /*
  877. This function returns the current Dirsync_Private that's inside
  878. Repl_Agmt ra as a ldap control.
  879. */
  880. LDAPControl *
  881. windows_private_dirsync_control(const Repl_Agmt *ra)
  882. {
  883. LDAPControl *control = NULL;
  884. BerElement *ber;
  885. Dirsync_Private *dp;
  886. char iscritical = PR_TRUE;
  887. slapi_log_err(SLAPI_LOG_TRACE, windows_repl_plugin_name, "=> windows_private_dirsync_control\n");
  888. PR_ASSERT(ra);
  889. dp = (Dirsync_Private *)agmt_get_priv(ra);
  890. PR_ASSERT(dp);
  891. ber = ber_alloc();
  892. ber_printf(ber, "{iio}", dp->dirsync_flags, dp->dirsync_maxattributecount, dp->dirsync_cookie ? dp->dirsync_cookie : "", dp->dirsync_cookie_len);
  893. /* Use a regular directory server instead of a real AD - for testing */
  894. if (getenv("WINSYNC_USE_DS")) {
  895. iscritical = PR_FALSE;
  896. }
  897. slapi_build_control(REPL_DIRSYNC_CONTROL_OID, ber, iscritical, &control);
  898. ber_free(ber, 1);
  899. slapi_log_err(SLAPI_LOG_TRACE, windows_repl_plugin_name, "<= windows_private_dirsync_control\n");
  900. return control;
  901. }
  902. /*
  903. This function scans the array of controls and updates the Repl_Agmt's
  904. Dirsync_Private if the dirsync control is found.
  905. */
  906. void
  907. windows_private_update_dirsync_control(const Repl_Agmt *ra, LDAPControl **controls)
  908. {
  909. Dirsync_Private *dp;
  910. int foundDirsyncControl;
  911. int i;
  912. LDAPControl *dirsync = NULL;
  913. BerElement *ber = NULL;
  914. ber_int_t hasMoreData;
  915. ber_int_t maxAttributeCount;
  916. BerValue *serverCookie = NULL;
  917. #ifdef FOR_DEBUGGING
  918. int return_value = LDAP_SUCCESS;
  919. #endif
  920. slapi_log_err(SLAPI_LOG_TRACE, windows_repl_plugin_name, "=> windows_private_update_dirsync_control\n");
  921. PR_ASSERT(ra);
  922. dp = (Dirsync_Private *)agmt_get_priv(ra);
  923. PR_ASSERT(dp);
  924. if (NULL != controls) {
  925. foundDirsyncControl = 0;
  926. for (i = 0; ((controls[i] != NULL) && (!foundDirsyncControl)); i++) {
  927. foundDirsyncControl = !strcmp(controls[i]->ldctl_oid, REPL_DIRSYNC_CONTROL_OID);
  928. }
  929. if (!foundDirsyncControl) {
  930. #ifdef FOR_DEBUGGING
  931. return_value = LDAP_CONTROL_NOT_FOUND;
  932. #endif
  933. goto choke;
  934. } else if (!controls[i - 1]->ldctl_value.bv_val) {
  935. #ifdef FOR_DEBUGGING
  936. return_value = LDAP_CONTROL_NOT_FOUND;
  937. #endif
  938. goto choke;
  939. } else {
  940. dirsync = slapi_dup_control(controls[i - 1]);
  941. }
  942. if (!dirsync || !BV_HAS_DATA((&(dirsync->ldctl_value)))) {
  943. #ifdef FOR_DEBUGGING
  944. return_value = LDAP_CONTROL_NOT_FOUND;
  945. #endif
  946. goto choke;
  947. }
  948. ber = ber_init(&dirsync->ldctl_value);
  949. if (ber_scanf(ber, "{iiO}", &hasMoreData, &maxAttributeCount, &serverCookie) == LBER_ERROR) {
  950. #ifdef FOR_DEBUGGING
  951. return_value = LDAP_CONTROL_NOT_FOUND;
  952. #endif
  953. goto choke;
  954. }
  955. slapi_ch_free_string(&dp->dirsync_cookie);
  956. dp->dirsync_cookie = (char *)slapi_ch_malloc(serverCookie->bv_len + 1);
  957. memcpy(dp->dirsync_cookie, serverCookie->bv_val, serverCookie->bv_len);
  958. dp->dirsync_cookie_len = (int)serverCookie->bv_len; /* XXX shouldn't cast? */
  959. /* dp->dirsync_maxattributecount = maxAttributeCount; We don't need to keep this */
  960. dp->dirsync_cookie_has_more = hasMoreData;
  961. choke:
  962. ber_bvfree(serverCookie);
  963. ber_free(ber, 1);
  964. ldap_control_free(dirsync);
  965. } else {
  966. #ifdef FOR_DEBUGGING
  967. return_value = LDAP_CONTROL_NOT_FOUND;
  968. #endif
  969. }
  970. #ifdef FOR_DEBUGGING
  971. slapi_log_err(SLAPI_LOG_TRACE, windows_repl_plugin_name,
  972. "<= windows_private_update_dirsync_control - rc=%d\n", return_value);
  973. #else
  974. slapi_log_err(SLAPI_LOG_TRACE, windows_repl_plugin_name,
  975. "<= windows_private_update_dirsync_control\n");
  976. #endif
  977. }
  978. PRBool
  979. windows_private_dirsync_has_more(const Repl_Agmt *ra)
  980. {
  981. Dirsync_Private *dp;
  982. slapi_log_err(SLAPI_LOG_TRACE, windows_repl_plugin_name, "=> windows_private_dirsync_has_more\n");
  983. PR_ASSERT(ra);
  984. dp = (Dirsync_Private *)agmt_get_priv(ra);
  985. PR_ASSERT(dp);
  986. slapi_log_err(SLAPI_LOG_TRACE, windows_repl_plugin_name, "<= windows_private_dirsync_has_more\n");
  987. return dp->dirsync_cookie_has_more;
  988. }
  989. void
  990. windows_private_null_dirsync_cookie(const Repl_Agmt *ra)
  991. {
  992. Dirsync_Private *dp;
  993. slapi_log_err(SLAPI_LOG_TRACE, windows_repl_plugin_name, "=> windows_private_null_dirsync_control\n");
  994. dp = (Dirsync_Private *)agmt_get_priv(ra);
  995. PR_ASSERT(dp);
  996. dp->dirsync_cookie_len = 0;
  997. slapi_ch_free_string(&dp->dirsync_cookie);
  998. dp->dirsync_cookie = NULL;
  999. slapi_log_err(SLAPI_LOG_TRACE, windows_repl_plugin_name, "<= windows_private_null_dirsync_control\n");
  1000. }
  1001. static Slapi_Mods *
  1002. windows_private_get_cookie_mod(Dirsync_Private *dp, int modtype)
  1003. {
  1004. Slapi_Mods *smods = NULL;
  1005. smods = slapi_mods_new();
  1006. slapi_mods_add(smods, modtype,
  1007. "nsds7DirsyncCookie", dp->dirsync_cookie_len, dp->dirsync_cookie);
  1008. return smods;
  1009. }
  1010. /* writes the current cookie into dse.ldif under the replication agreement entry
  1011. returns: ldap result code of the operation. */
  1012. int
  1013. windows_private_save_dirsync_cookie(const Repl_Agmt *ra)
  1014. {
  1015. Dirsync_Private *dp = NULL;
  1016. Slapi_PBlock *pb = NULL;
  1017. Slapi_DN *sdn = NULL;
  1018. int rc = 0;
  1019. Slapi_Mods *mods = NULL;
  1020. slapi_log_err(SLAPI_LOG_TRACE, windows_repl_plugin_name, "=> windows_private_save_dirsync_cookie\n");
  1021. PR_ASSERT(ra);
  1022. dp = (Dirsync_Private *)agmt_get_priv(ra);
  1023. PR_ASSERT(dp);
  1024. pb = slapi_pblock_new();
  1025. mods = windows_private_get_cookie_mod(dp, LDAP_MOD_REPLACE);
  1026. sdn = slapi_sdn_dup(agmt_get_dn_byref(ra));
  1027. slapi_modify_internal_set_pb_ext(pb, sdn,
  1028. slapi_mods_get_ldapmods_byref(mods), NULL, NULL,
  1029. repl_get_plugin_identity(PLUGIN_MULTIMASTER_REPLICATION), 0);
  1030. slapi_modify_internal_pb(pb);
  1031. slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_RESULT, &rc);
  1032. if (rc == LDAP_NO_SUCH_ATTRIBUTE) { /* try again, but as an add instead */
  1033. slapi_mods_free(&mods);
  1034. mods = windows_private_get_cookie_mod(dp, LDAP_MOD_ADD);
  1035. slapi_modify_internal_set_pb_ext(pb, sdn,
  1036. slapi_mods_get_ldapmods_byref(mods), NULL, NULL,
  1037. repl_get_plugin_identity(PLUGIN_MULTIMASTER_REPLICATION), 0);
  1038. slapi_modify_internal_pb(pb);
  1039. slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_RESULT, &rc);
  1040. }
  1041. slapi_pblock_destroy(pb);
  1042. slapi_mods_free(&mods);
  1043. slapi_sdn_free(&sdn);
  1044. slapi_log_err(SLAPI_LOG_TRACE, windows_repl_plugin_name, "<= windows_private_save_dirsync_cookie\n");
  1045. return rc;
  1046. }
  1047. /* reads the cookie in dse.ldif to the replication agreement entry
  1048. returns: ldap result code of ldap operation, or
  1049. LDAP_NO_SUCH_ATTRIBUTE. (this is the equilivent of a null cookie) */
  1050. int
  1051. windows_private_load_dirsync_cookie(const Repl_Agmt *ra)
  1052. {
  1053. Dirsync_Private *dp = NULL;
  1054. Slapi_PBlock *pb = NULL;
  1055. Slapi_DN *sdn = NULL;
  1056. int rc = 0;
  1057. Slapi_Entry *entry = NULL;
  1058. Slapi_Attr *attr = NULL;
  1059. slapi_log_err(SLAPI_LOG_TRACE, windows_repl_plugin_name, "=> windows_private_load_dirsync_cookie\n");
  1060. PR_ASSERT(ra);
  1061. dp = (Dirsync_Private *)agmt_get_priv(ra);
  1062. PR_ASSERT(dp);
  1063. pb = slapi_pblock_new();
  1064. sdn = slapi_sdn_dup(agmt_get_dn_byref(ra));
  1065. rc = slapi_search_internal_get_entry(sdn, NULL, &entry,
  1066. repl_get_plugin_identity(PLUGIN_MULTIMASTER_REPLICATION));
  1067. if (rc == 0) {
  1068. rc = slapi_entry_attr_find(entry, type_nsds7DirsyncCookie, &attr);
  1069. if (attr) {
  1070. struct berval **vals;
  1071. rc = slapi_attr_get_bervals_copy(attr, &vals);
  1072. if (vals) {
  1073. dp->dirsync_cookie_len = (int)(vals[0])->bv_len;
  1074. slapi_ch_free_string(&dp->dirsync_cookie);
  1075. dp->dirsync_cookie = (char *)slapi_ch_malloc(dp->dirsync_cookie_len + 1);
  1076. memcpy(dp->dirsync_cookie, (vals[0]->bv_val), (vals[0])->bv_len + 1);
  1077. }
  1078. ber_bvecfree(vals);
  1079. /* we do not free attr */
  1080. } else {
  1081. rc = LDAP_NO_SUCH_ATTRIBUTE;
  1082. }
  1083. }
  1084. if (entry) {
  1085. slapi_entry_free(entry);
  1086. }
  1087. slapi_sdn_free(&sdn);
  1088. slapi_pblock_destroy(pb);
  1089. slapi_log_err(SLAPI_LOG_TRACE, windows_repl_plugin_name, "<= windows_private_load_dirsync_cookie\n");
  1090. return rc;
  1091. }
  1092. /* get returns a pointer to the structure - do not free */
  1093. Slapi_Entry *
  1094. windows_private_get_raw_entry(const Repl_Agmt *ra)
  1095. {
  1096. Dirsync_Private *dp;
  1097. slapi_log_err(SLAPI_LOG_TRACE, windows_repl_plugin_name, "=> windows_private_get_raw_entry\n");
  1098. dp = (Dirsync_Private *)agmt_get_priv(ra);
  1099. PR_ASSERT(dp);
  1100. slapi_log_err(SLAPI_LOG_TRACE, windows_repl_plugin_name, "<= windows_private_get_raw_entry\n");
  1101. return dp->raw_entry;
  1102. }
  1103. /* this is passin - windows_private owns the pointer, not a copy */
  1104. void
  1105. windows_private_set_raw_entry(const Repl_Agmt *ra, Slapi_Entry *e)
  1106. {
  1107. Dirsync_Private *dp;
  1108. slapi_log_err(SLAPI_LOG_TRACE, windows_repl_plugin_name, "=> windows_private_set_raw_entry\n");
  1109. dp = (Dirsync_Private *)agmt_get_priv(ra);
  1110. PR_ASSERT(dp);
  1111. /* If the keep raw entry flag is set, just free the passed
  1112. * in entry and leave the current raw entry in place. */
  1113. if (windows_private_get_keep_raw_entry(ra)) {
  1114. slapi_entry_free(e);
  1115. } else {
  1116. slapi_entry_free(dp->raw_entry);
  1117. dp->raw_entry = e;
  1118. }
  1119. slapi_log_err(SLAPI_LOG_TRACE, windows_repl_plugin_name, "<= windows_private_set_raw_entry\n");
  1120. }
  1121. /* Setting keep to 1 will cause the current raw entry to remain, even if
  1122. * windows_private_set_raw_entry() is called. This behavior will persist
  1123. * until this flag is set back to 0. */
  1124. void
  1125. windows_private_set_keep_raw_entry(const Repl_Agmt *ra, int keep)
  1126. {
  1127. Dirsync_Private *dp;
  1128. slapi_log_err(SLAPI_LOG_TRACE, windows_repl_plugin_name, "=> windows_private_set_keep_raw_entry\n");
  1129. dp = (Dirsync_Private *)agmt_get_priv(ra);
  1130. PR_ASSERT(dp);
  1131. dp->keep_raw_entry = keep;
  1132. slapi_log_err(SLAPI_LOG_TRACE, windows_repl_plugin_name, "<= windows_private_set_keep_raw_entry\n");
  1133. }
  1134. int
  1135. windows_private_get_keep_raw_entry(const Repl_Agmt *ra)
  1136. {
  1137. Dirsync_Private *dp;
  1138. slapi_log_err(SLAPI_LOG_TRACE, windows_repl_plugin_name, "=> windows_private_get_keep_raw_entry\n");
  1139. dp = (Dirsync_Private *)agmt_get_priv(ra);
  1140. PR_ASSERT(dp);
  1141. slapi_log_err(SLAPI_LOG_TRACE, windows_repl_plugin_name, "<= windows_private_get_keep_raw_entry\n");
  1142. return dp->keep_raw_entry;
  1143. }
  1144. void *
  1145. windows_private_get_api_cookie(const Repl_Agmt *ra)
  1146. {
  1147. Dirsync_Private *dp;
  1148. slapi_log_err(SLAPI_LOG_TRACE, windows_repl_plugin_name, "=> windows_private_get_api_cookie\n");
  1149. dp = (Dirsync_Private *)agmt_get_priv(ra);
  1150. PR_ASSERT(dp);
  1151. slapi_log_err(SLAPI_LOG_TRACE, windows_repl_plugin_name, "<= windows_private_get_api_cookie\n");
  1152. return dp->api_cookie;
  1153. }
  1154. void
  1155. windows_private_set_api_cookie(Repl_Agmt *ra, void *api_cookie)
  1156. {
  1157. Dirsync_Private *dp;
  1158. slapi_log_err(SLAPI_LOG_TRACE, windows_repl_plugin_name, "=> windows_private_set_api_cookie\n");
  1159. dp = (Dirsync_Private *)agmt_get_priv(ra);
  1160. PR_ASSERT(dp);
  1161. dp->api_cookie = api_cookie;
  1162. slapi_log_err(SLAPI_LOG_TRACE, windows_repl_plugin_name, "<= windows_private_set_api_cookie\n");
  1163. }
  1164. time_t
  1165. windows_private_get_sync_interval(const Repl_Agmt *ra)
  1166. {
  1167. Dirsync_Private *dp;
  1168. slapi_log_err(SLAPI_LOG_TRACE, windows_repl_plugin_name, "=> windows_private_get_sync_interval\n");
  1169. PR_ASSERT(ra);
  1170. dp = (Dirsync_Private *)agmt_get_priv(ra);
  1171. PR_ASSERT(dp);
  1172. slapi_log_err(SLAPI_LOG_TRACE, windows_repl_plugin_name, "<= windows_private_get_sync_interval\n");
  1173. return dp->sync_interval;
  1174. }
  1175. void
  1176. windows_private_set_sync_interval(Repl_Agmt *ra, char *str)
  1177. {
  1178. Dirsync_Private *dp;
  1179. time_t tmpval = 0;
  1180. slapi_log_err(SLAPI_LOG_TRACE, windows_repl_plugin_name, "=> windows_private_set_sync_interval\n");
  1181. PR_ASSERT(ra);
  1182. dp = (Dirsync_Private *)agmt_get_priv(ra);
  1183. PR_ASSERT(dp);
  1184. if (str && (tmpval = (time_t)atol(str))) {
  1185. dp->sync_interval = tmpval;
  1186. }
  1187. slapi_log_err(SLAPI_LOG_TRACE, windows_repl_plugin_name, "<= windows_private_set_sync_interval\n");
  1188. }
  1189. int
  1190. windows_private_get_move_action(const Repl_Agmt *ra)
  1191. {
  1192. Dirsync_Private *dp;
  1193. slapi_log_err(SLAPI_LOG_TRACE, windows_repl_plugin_name, "=> windows_private_get_move_action\n");
  1194. PR_ASSERT(ra);
  1195. dp = (Dirsync_Private *)agmt_get_priv(ra);
  1196. PR_ASSERT(dp);
  1197. slapi_log_err(SLAPI_LOG_TRACE, windows_repl_plugin_name, "<= windows_private_get_move_action\n");
  1198. return dp->move_action;
  1199. }
  1200. void
  1201. windows_private_set_move_action(const Repl_Agmt *ra, int value)
  1202. {
  1203. Dirsync_Private *dp;
  1204. slapi_log_err(SLAPI_LOG_TRACE, windows_repl_plugin_name, "=> windows_private_set_move_action\n");
  1205. PR_ASSERT(ra);
  1206. dp = (Dirsync_Private *)agmt_get_priv(ra);
  1207. PR_ASSERT(dp);
  1208. dp->move_action = value;
  1209. slapi_log_err(SLAPI_LOG_TRACE, windows_repl_plugin_name, "<= windows_private_set_move_action\n");
  1210. }
  1211. static PRCallOnceType winsync_callOnce = {0, 0, 0};
  1212. struct winsync_plugin
  1213. {
  1214. struct winsync_plugin *next; /* see PRCList - declare here to avoid lots of casting */
  1215. struct winsync_plugin *prev; /* see PRCList - declare here to avoid lots of casting */
  1216. void **api; /* the api - array of function pointers */
  1217. int maxapi; /* the max index i.e. the api version */
  1218. int precedence; /* lower number == higher precedence */
  1219. };
  1220. static struct winsync_plugin winsync_plugin_list;
  1221. #define DECL_WINSYNC_API_IDX_FUNC(theapi, idx, maxidx, thetype, thefunc) \
  1222. thetype thefunc = (theapi && (idx <= maxidx) && theapi[idx]) ? (thetype)theapi[idx] : NULL;
  1223. #define WINSYNC_PLUGIN_CALL_PLUGINS_BEGIN(idx, thetype, thefunc) \
  1224. struct winsync_plugin *elem; \
  1225. for (elem = PR_LIST_HEAD(&winsync_plugin_list); \
  1226. elem && (elem != &winsync_plugin_list); \
  1227. elem = PR_NEXT_LINK(elem)) { \
  1228. DECL_WINSYNC_API_IDX_FUNC(elem->api, idx, elem->maxapi, thetype, thefunc); \
  1229. if (thefunc) {
  1230. #define WINSYNC_PLUGIN_CALL_PLUGINS_COOKIE_BEGIN(idx, thetype, thefunc) \
  1231. WINSYNC_PLUGIN_CALL_PLUGINS_BEGIN(idx, thetype, thefunc) \
  1232. void *cookie = winsync_plugin_cookie_find(ra, elem->api);
  1233. #define WINSYNC_PLUGIN_CALL_PLUGINS_END \
  1234. } /* this one matches if thefunc */ \
  1235. } /* this one matches the for loop */
  1236. /* this structure is per agreement - to store the cookie per agreement
  1237. for each winsync plugin */
  1238. struct winsync_plugin_cookie
  1239. {
  1240. struct winsync_plugin_cookie *next; /* see PRCList - declare here to avoid lots of casting */
  1241. struct winsync_plugin_cookie *prev; /* see PRCList - declare here to avoid lots of casting */
  1242. void **api; /* the api - array of function pointers */
  1243. void *cookie; /* plugin data */
  1244. };
  1245. static struct winsync_plugin *
  1246. new_winsync_plugin(void **theapi, int maxapi, int precedence)
  1247. {
  1248. struct winsync_plugin *wpi = (struct winsync_plugin *)slapi_ch_calloc(1, sizeof(struct winsync_plugin));
  1249. wpi->api = theapi;
  1250. wpi->maxapi = maxapi;
  1251. wpi->precedence = precedence;
  1252. return wpi;
  1253. }
  1254. static struct winsync_plugin *
  1255. windows_plugin_find(void **theapi)
  1256. {
  1257. struct winsync_plugin *elem = PR_LIST_HEAD(&winsync_plugin_list);
  1258. while (elem && (elem != &winsync_plugin_list)) {
  1259. if (theapi == elem->api) {
  1260. return elem;
  1261. }
  1262. elem = PR_NEXT_LINK(elem);
  1263. }
  1264. return NULL;
  1265. }
  1266. /* returns 0 for success - 1 means already added - -1 means some error */
  1267. static int
  1268. windows_plugin_add(void **theapi, int maxapi)
  1269. {
  1270. int precedence = WINSYNC_PLUGIN_DEFAULT_PRECEDENCE;
  1271. DECL_WINSYNC_API_IDX_FUNC(theapi, WINSYNC_PLUGIN_PRECEDENCE_CB, maxapi, winsync_plugin_precedence_cb, thefunc);
  1272. if (thefunc) {
  1273. /* supports precedence */
  1274. precedence = (*thefunc)();
  1275. }
  1276. if (PR_CLIST_IS_EMPTY(&winsync_plugin_list)) {
  1277. struct winsync_plugin *wpi = new_winsync_plugin(theapi, maxapi, precedence);
  1278. PR_INSERT_LINK(wpi, &winsync_plugin_list);
  1279. return 0;
  1280. } else if (windows_plugin_find(theapi)) {
  1281. return 1; /* already in list */
  1282. } else {
  1283. struct winsync_plugin *wpi = new_winsync_plugin(theapi, maxapi, precedence);
  1284. struct winsync_plugin *elem = PR_LIST_HEAD(&winsync_plugin_list);
  1285. while (elem && (elem != &winsync_plugin_list)) {
  1286. if (precedence < elem->precedence) {
  1287. PR_INSERT_BEFORE(wpi, elem);
  1288. wpi = NULL; /* owned by list now */
  1289. break;
  1290. }
  1291. elem = PR_NEXT_LINK(elem);
  1292. }
  1293. if (elem && wpi) { /* was not added - precedence too high */
  1294. /* just add to end of list */
  1295. PR_INSERT_BEFORE(wpi, elem);
  1296. wpi = NULL; /* owned by list now */
  1297. }
  1298. /* if we got here and wpi is not NULL we need to free wpi */
  1299. slapi_ch_free((void **)&wpi);
  1300. return 0;
  1301. }
  1302. return -1;
  1303. }
  1304. static PRStatus
  1305. windows_plugin_callonce(void)
  1306. {
  1307. char *guids[] = {WINSYNC_v3_0_GUID, WINSYNC_v2_0_GUID, WINSYNC_v1_0_GUID, NULL};
  1308. int maxapis[] = {WINSYNC_PLUGIN_VERSION_3_END, WINSYNC_PLUGIN_VERSION_2_END,
  1309. WINSYNC_PLUGIN_VERSION_1_END, 0};
  1310. int ii;
  1311. PR_INIT_CLIST(&winsync_plugin_list);
  1312. /* loop through all of the registered winsync plugins - look for them in reverse
  1313. version order (e.g. look for v3 first) - if there are no plugins registered
  1314. for the given version, or we have already registered all plugins for a given
  1315. version, just go to the next lowest version */
  1316. for (ii = 0; guids[ii]; ++ii) {
  1317. char *guid = guids[ii];
  1318. int maxapi = maxapis[ii];
  1319. void ***theapis = NULL;
  1320. if (slapi_apib_get_interface_all(guid, &theapis) || (NULL == theapis)) {
  1321. slapi_log_err(SLAPI_LOG_PLUGIN, windows_repl_plugin_name,
  1322. "<-- windows_plugin_callonce - No more windows plugin APIs registered "
  1323. "for GUID [%s] -- end\n",
  1324. guid);
  1325. } else {
  1326. int idx;
  1327. for (idx = 0; theapis && theapis[idx]; ++idx) {
  1328. if (windows_plugin_add(theapis[idx], maxapi)) {
  1329. slapi_log_err(SLAPI_LOG_PLUGIN, windows_repl_plugin_name,
  1330. "<-- windows_plugin_callonce - Already added windows plugin API "
  1331. "[%d][0x%p] for GUID [%s] -- end\n",
  1332. idx, theapis[idx], guid);
  1333. }
  1334. }
  1335. }
  1336. slapi_ch_free((void **)&theapis);
  1337. }
  1338. return PR_SUCCESS;
  1339. }
  1340. static struct winsync_plugin_cookie *
  1341. new_winsync_plugin_cookie(void **theapi, void *cookie)
  1342. {
  1343. struct winsync_plugin_cookie *wpc = (struct winsync_plugin_cookie *)slapi_ch_calloc(1, sizeof(struct winsync_plugin_cookie));
  1344. wpc->api = theapi;
  1345. wpc->cookie = cookie;
  1346. return wpc;
  1347. }
  1348. static void *
  1349. winsync_plugin_cookie_find(const Repl_Agmt *ra, void **theapi)
  1350. {
  1351. if (ra) {
  1352. struct winsync_plugin_cookie *list = (struct winsync_plugin_cookie *)windows_private_get_api_cookie(ra);
  1353. if (list) {
  1354. struct winsync_plugin_cookie *elem = PR_LIST_HEAD(list);
  1355. while (elem && (elem != list)) {
  1356. if (theapi == elem->api) {
  1357. return elem->cookie;
  1358. }
  1359. elem = PR_NEXT_LINK(elem);
  1360. }
  1361. }
  1362. }
  1363. return NULL;
  1364. }
  1365. static void
  1366. winsync_plugin_cookie_add(struct winsync_plugin_cookie **list, void **theapi, void *cookie)
  1367. {
  1368. struct winsync_plugin_cookie *elem = NULL;
  1369. if (!*list) {
  1370. *list = new_winsync_plugin_cookie(NULL, NULL);
  1371. PR_INIT_CLIST(*list);
  1372. }
  1373. elem = new_winsync_plugin_cookie(theapi, cookie);
  1374. PR_INSERT_BEFORE(elem, *list);
  1375. return;
  1376. }
  1377. void
  1378. windows_plugin_init(Repl_Agmt *ra)
  1379. {
  1380. struct winsync_plugin_cookie *list = NULL;
  1381. void *cookie = NULL;
  1382. slapi_log_err(SLAPI_LOG_PLUGIN, windows_repl_plugin_name, "windows_plugin_init - Begin\n");
  1383. if (PR_CallOnce(&winsync_callOnce, windows_plugin_callonce)) {
  1384. PRErrorCode prerr = PR_GetError();
  1385. slapi_log_err(SLAPI_LOG_ERR, windows_repl_plugin_name, "windows_plugin_init - "
  1386. "Cannot initialize plugin: %d:%s\n",
  1387. prerr,
  1388. slapi_pr_strerror(prerr));
  1389. return;
  1390. }
  1391. /* call each plugin init function in turn - store the returned cookie
  1392. indexed by the api */
  1393. {
  1394. WINSYNC_PLUGIN_CALL_PLUGINS_BEGIN(WINSYNC_PLUGIN_INIT_CB, winsync_plugin_init_cb, thefunc)
  1395. cookie = (*thefunc)(windows_private_get_directory_subtree(ra),
  1396. windows_private_get_windows_subtree(ra));
  1397. if (cookie) {
  1398. winsync_plugin_cookie_add(&list, elem->api, cookie);
  1399. }
  1400. WINSYNC_PLUGIN_CALL_PLUGINS_END
  1401. }
  1402. windows_private_set_api_cookie(ra, list);
  1403. slapi_log_err(SLAPI_LOG_PLUGIN, windows_repl_plugin_name, "<-- windows_plugin_init - End\n");
  1404. return;
  1405. }
  1406. void
  1407. windows_plugin_cleanup_agmt(Repl_Agmt *ra)
  1408. {
  1409. struct winsync_plugin_cookie *list = (struct winsync_plugin_cookie *)windows_private_get_api_cookie(ra);
  1410. struct winsync_plugin_cookie *elem = NULL;
  1411. while (list && !PR_CLIST_IS_EMPTY(list)) {
  1412. elem = PR_LIST_HEAD(list);
  1413. PR_REMOVE_LINK(elem);
  1414. slapi_ch_free((void **)&elem);
  1415. }
  1416. slapi_ch_free((void **)&list);
  1417. windows_private_set_api_cookie(ra, NULL);
  1418. return;
  1419. }
  1420. void
  1421. 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)
  1422. {
  1423. WINSYNC_PLUGIN_CALL_PLUGINS_COOKIE_BEGIN(WINSYNC_PLUGIN_DIRSYNC_SEARCH_CB, winsync_search_params_cb, thefunc)
  1424. (*thefunc)(cookie, agmt_dn, base, scope, filter, attrs, serverctrls);
  1425. WINSYNC_PLUGIN_CALL_PLUGINS_END;
  1426. return;
  1427. }
  1428. void
  1429. 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)
  1430. {
  1431. WINSYNC_PLUGIN_CALL_PLUGINS_COOKIE_BEGIN(WINSYNC_PLUGIN_PRE_AD_SEARCH_CB, winsync_search_params_cb, thefunc)
  1432. (*thefunc)(cookie, agmt_dn, base, scope, filter, attrs, serverctrls);
  1433. WINSYNC_PLUGIN_CALL_PLUGINS_END;
  1434. return;
  1435. }
  1436. void
  1437. 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)
  1438. {
  1439. WINSYNC_PLUGIN_CALL_PLUGINS_COOKIE_BEGIN(WINSYNC_PLUGIN_PRE_DS_SEARCH_ENTRY_CB, winsync_search_params_cb, thefunc)
  1440. (*thefunc)(cookie, agmt_dn, base, scope, filter, attrs, serverctrls);
  1441. WINSYNC_PLUGIN_CALL_PLUGINS_END;
  1442. return;
  1443. }
  1444. void
  1445. 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)
  1446. {
  1447. WINSYNC_PLUGIN_CALL_PLUGINS_COOKIE_BEGIN(WINSYNC_PLUGIN_PRE_DS_SEARCH_ALL_CB, winsync_search_params_cb, thefunc)
  1448. (*thefunc)(cookie, agmt_dn, base, scope, filter, attrs, serverctrls);
  1449. WINSYNC_PLUGIN_CALL_PLUGINS_END;
  1450. return;
  1451. }
  1452. void
  1453. 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)
  1454. {
  1455. WINSYNC_PLUGIN_CALL_PLUGINS_COOKIE_BEGIN(WINSYNC_PLUGIN_PRE_AD_MOD_USER_CB, winsync_pre_mod_cb, thefunc)
  1456. (*thefunc)(cookie, rawentry, ad_entry, ds_entry, smods, do_modify);
  1457. WINSYNC_PLUGIN_CALL_PLUGINS_END;
  1458. return;
  1459. }
  1460. void
  1461. 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)
  1462. {
  1463. WINSYNC_PLUGIN_CALL_PLUGINS_COOKIE_BEGIN(WINSYNC_PLUGIN_PRE_AD_MOD_GROUP_CB, winsync_pre_mod_cb, thefunc)
  1464. (*thefunc)(cookie, rawentry, ad_entry, ds_entry, smods, do_modify);
  1465. WINSYNC_PLUGIN_CALL_PLUGINS_END;
  1466. return;
  1467. }
  1468. void
  1469. 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)
  1470. {
  1471. WINSYNC_PLUGIN_CALL_PLUGINS_COOKIE_BEGIN(WINSYNC_PLUGIN_PRE_DS_MOD_USER_CB, winsync_pre_mod_cb, thefunc)
  1472. (*thefunc)(cookie, rawentry, ad_entry, ds_entry, smods, do_modify);
  1473. WINSYNC_PLUGIN_CALL_PLUGINS_END;
  1474. return;
  1475. }
  1476. void
  1477. 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)
  1478. {
  1479. WINSYNC_PLUGIN_CALL_PLUGINS_COOKIE_BEGIN(WINSYNC_PLUGIN_PRE_DS_MOD_GROUP_CB, winsync_pre_mod_cb, thefunc)
  1480. (*thefunc)(cookie, rawentry, ad_entry, ds_entry, smods, do_modify);
  1481. WINSYNC_PLUGIN_CALL_PLUGINS_END;
  1482. return;
  1483. }
  1484. void
  1485. winsync_plugin_call_pre_ds_add_user_cb(const Repl_Agmt *ra, const Slapi_Entry *rawentry, Slapi_Entry *ad_entry, Slapi_Entry *ds_entry)
  1486. {
  1487. WINSYNC_PLUGIN_CALL_PLUGINS_COOKIE_BEGIN(WINSYNC_PLUGIN_PRE_DS_ADD_USER_CB, winsync_pre_add_cb, thefunc)
  1488. (*thefunc)(cookie, rawentry, ad_entry, ds_entry);
  1489. WINSYNC_PLUGIN_CALL_PLUGINS_END;
  1490. return;
  1491. }
  1492. void
  1493. winsync_plugin_call_pre_ds_add_group_cb(const Repl_Agmt *ra, const Slapi_Entry *rawentry, Slapi_Entry *ad_entry, Slapi_Entry *ds_entry)
  1494. {
  1495. WINSYNC_PLUGIN_CALL_PLUGINS_COOKIE_BEGIN(WINSYNC_PLUGIN_PRE_DS_ADD_GROUP_CB, winsync_pre_add_cb, thefunc)
  1496. (*thefunc)(cookie, rawentry, ad_entry, ds_entry);
  1497. WINSYNC_PLUGIN_CALL_PLUGINS_END;
  1498. return;
  1499. }
  1500. void
  1501. 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)
  1502. {
  1503. WINSYNC_PLUGIN_CALL_PLUGINS_COOKIE_BEGIN(WINSYNC_PLUGIN_GET_NEW_DS_USER_DN_CB, winsync_get_new_dn_cb, thefunc)
  1504. (*thefunc)(cookie, rawentry, ad_entry, new_dn_string, ds_suffix, ad_suffix);
  1505. WINSYNC_PLUGIN_CALL_PLUGINS_END;
  1506. return;
  1507. }
  1508. void
  1509. 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)
  1510. {
  1511. WINSYNC_PLUGIN_CALL_PLUGINS_COOKIE_BEGIN(WINSYNC_PLUGIN_GET_NEW_DS_GROUP_DN_CB, winsync_get_new_dn_cb, thefunc)
  1512. (*thefunc)(cookie, rawentry, ad_entry, new_dn_string, ds_suffix, ad_suffix);
  1513. WINSYNC_PLUGIN_CALL_PLUGINS_END;
  1514. return;
  1515. }
  1516. void
  1517. winsync_plugin_call_pre_ad_mod_user_mods_cb(const Repl_Agmt *ra, const Slapi_Entry *rawentry, const Slapi_DN *local_dn, const Slapi_Entry *ds_entry, LDAPMod *const *origmods, Slapi_DN *remote_dn, LDAPMod ***modstosend)
  1518. {
  1519. WINSYNC_PLUGIN_CALL_PLUGINS_COOKIE_BEGIN(WINSYNC_PLUGIN_PRE_AD_MOD_USER_MODS_CB, winsync_pre_ad_mod_mods_cb, thefunc)
  1520. (*thefunc)(cookie, rawentry, local_dn, ds_entry, origmods, remote_dn, modstosend);
  1521. WINSYNC_PLUGIN_CALL_PLUGINS_END;
  1522. return;
  1523. }
  1524. void
  1525. winsync_plugin_call_pre_ad_mod_group_mods_cb(const Repl_Agmt *ra, const Slapi_Entry *rawentry, const Slapi_DN *local_dn, const Slapi_Entry *ds_entry, LDAPMod *const *origmods, Slapi_DN *remote_dn, LDAPMod ***modstosend)
  1526. {
  1527. WINSYNC_PLUGIN_CALL_PLUGINS_COOKIE_BEGIN(WINSYNC_PLUGIN_PRE_AD_MOD_GROUP_MODS_CB, winsync_pre_ad_mod_mods_cb, thefunc)
  1528. (*thefunc)(cookie, rawentry, local_dn, ds_entry, origmods, remote_dn, modstosend);
  1529. WINSYNC_PLUGIN_CALL_PLUGINS_END;
  1530. return;
  1531. }
  1532. int
  1533. winsync_plugin_call_can_add_entry_to_ad_cb(const Repl_Agmt *ra, const Slapi_Entry *local_entry, const Slapi_DN *remote_dn)
  1534. {
  1535. int canadd = 1;
  1536. WINSYNC_PLUGIN_CALL_PLUGINS_COOKIE_BEGIN(WINSYNC_PLUGIN_CAN_ADD_ENTRY_TO_AD_CB, winsync_can_add_to_ad_cb, thefunc)
  1537. if (canadd) {
  1538. canadd = (*thefunc)(cookie, local_entry, remote_dn);
  1539. }
  1540. WINSYNC_PLUGIN_CALL_PLUGINS_END;
  1541. return canadd;
  1542. }
  1543. void
  1544. winsync_plugin_call_begin_update_cb(const Repl_Agmt *ra, const Slapi_DN *ds_subtree, const Slapi_DN *ad_subtree, int is_total)
  1545. {
  1546. WINSYNC_PLUGIN_CALL_PLUGINS_COOKIE_BEGIN(WINSYNC_PLUGIN_BEGIN_UPDATE_CB, winsync_plugin_update_cb, thefunc)
  1547. (*thefunc)(cookie, ds_subtree, ad_subtree, is_total);
  1548. WINSYNC_PLUGIN_CALL_PLUGINS_END;
  1549. return;
  1550. }
  1551. void
  1552. winsync_plugin_call_end_update_cb(const Repl_Agmt *ra, const Slapi_DN *ds_subtree, const Slapi_DN *ad_subtree, int is_total)
  1553. {
  1554. WINSYNC_PLUGIN_CALL_PLUGINS_COOKIE_BEGIN(WINSYNC_PLUGIN_END_UPDATE_CB, winsync_plugin_update_cb, thefunc)
  1555. (*thefunc)(cookie, ds_subtree, ad_subtree, is_total);
  1556. WINSYNC_PLUGIN_CALL_PLUGINS_END;
  1557. return;
  1558. }
  1559. void
  1560. winsync_plugin_call_destroy_agmt_cb(const Repl_Agmt *ra,
  1561. const Slapi_DN *ds_subtree,
  1562. const Slapi_DN *ad_subtree)
  1563. {
  1564. WINSYNC_PLUGIN_CALL_PLUGINS_COOKIE_BEGIN(WINSYNC_PLUGIN_DESTROY_AGMT_CB, winsync_plugin_destroy_agmt_cb, thefunc)
  1565. (*thefunc)(cookie, ds_subtree, ad_subtree);
  1566. WINSYNC_PLUGIN_CALL_PLUGINS_END;
  1567. return;
  1568. }
  1569. void
  1570. winsync_plugin_call_post_ad_mod_user_cb(const Repl_Agmt *ra, const Slapi_Entry *rawentry, Slapi_Entry *ad_entry, Slapi_Entry *ds_entry, Slapi_Mods *smods, int *result)
  1571. {
  1572. WINSYNC_PLUGIN_CALL_PLUGINS_COOKIE_BEGIN(WINSYNC_PLUGIN_POST_AD_MOD_USER_CB, winsync_post_mod_cb, thefunc)
  1573. (*thefunc)(cookie, rawentry, ad_entry, ds_entry, smods, result);
  1574. WINSYNC_PLUGIN_CALL_PLUGINS_END;
  1575. return;
  1576. }
  1577. void
  1578. winsync_plugin_call_post_ad_mod_group_cb(const Repl_Agmt *ra, const Slapi_Entry *rawentry, Slapi_Entry *ad_entry, Slapi_Entry *ds_entry, Slapi_Mods *smods, int *result)
  1579. {
  1580. WINSYNC_PLUGIN_CALL_PLUGINS_COOKIE_BEGIN(WINSYNC_PLUGIN_POST_AD_MOD_GROUP_CB, winsync_post_mod_cb, thefunc)
  1581. (*thefunc)(cookie, rawentry, ad_entry, ds_entry, smods, result);
  1582. WINSYNC_PLUGIN_CALL_PLUGINS_END;
  1583. return;
  1584. }
  1585. void
  1586. winsync_plugin_call_post_ds_mod_user_cb(const Repl_Agmt *ra, const Slapi_Entry *rawentry, Slapi_Entry *ad_entry, Slapi_Entry *ds_entry, Slapi_Mods *smods, int *result)
  1587. {
  1588. WINSYNC_PLUGIN_CALL_PLUGINS_COOKIE_BEGIN(WINSYNC_PLUGIN_POST_DS_MOD_USER_CB, winsync_post_mod_cb, thefunc)
  1589. (*thefunc)(cookie, rawentry, ad_entry, ds_entry, smods, result);
  1590. WINSYNC_PLUGIN_CALL_PLUGINS_END;
  1591. return;
  1592. }
  1593. void
  1594. winsync_plugin_call_post_ds_mod_group_cb(const Repl_Agmt *ra, const Slapi_Entry *rawentry, Slapi_Entry *ad_entry, Slapi_Entry *ds_entry, Slapi_Mods *smods, int *result)
  1595. {
  1596. WINSYNC_PLUGIN_CALL_PLUGINS_COOKIE_BEGIN(WINSYNC_PLUGIN_POST_DS_MOD_GROUP_CB, winsync_post_mod_cb, thefunc)
  1597. (*thefunc)(cookie, rawentry, ad_entry, ds_entry, smods, result);
  1598. WINSYNC_PLUGIN_CALL_PLUGINS_END;
  1599. return;
  1600. }
  1601. void
  1602. winsync_plugin_call_post_ds_add_user_cb(const Repl_Agmt *ra, const Slapi_Entry *rawentry, Slapi_Entry *ad_entry, Slapi_Entry *ds_entry, int *result)
  1603. {
  1604. WINSYNC_PLUGIN_CALL_PLUGINS_COOKIE_BEGIN(WINSYNC_PLUGIN_POST_DS_ADD_USER_CB, winsync_post_add_cb, thefunc)
  1605. (*thefunc)(cookie, rawentry, ad_entry, ds_entry, result);
  1606. WINSYNC_PLUGIN_CALL_PLUGINS_END;
  1607. return;
  1608. }
  1609. void
  1610. winsync_plugin_call_post_ds_add_group_cb(const Repl_Agmt *ra, const Slapi_Entry *rawentry, Slapi_Entry *ad_entry, Slapi_Entry *ds_entry, int *result)
  1611. {
  1612. WINSYNC_PLUGIN_CALL_PLUGINS_COOKIE_BEGIN(WINSYNC_PLUGIN_POST_DS_ADD_GROUP_CB, winsync_post_add_cb, thefunc)
  1613. (*thefunc)(cookie, rawentry, ad_entry, ds_entry, result);
  1614. WINSYNC_PLUGIN_CALL_PLUGINS_END;
  1615. return;
  1616. }
  1617. void
  1618. winsync_plugin_call_pre_ad_add_user_cb(const Repl_Agmt *ra, Slapi_Entry *ad_entry, Slapi_Entry *ds_entry)
  1619. {
  1620. WINSYNC_PLUGIN_CALL_PLUGINS_COOKIE_BEGIN(WINSYNC_PLUGIN_PRE_AD_ADD_USER_CB, winsync_pre_ad_add_cb, thefunc)
  1621. (*thefunc)(cookie, ad_entry, ds_entry);
  1622. WINSYNC_PLUGIN_CALL_PLUGINS_END;
  1623. return;
  1624. }
  1625. void
  1626. winsync_plugin_call_pre_ad_add_group_cb(const Repl_Agmt *ra, Slapi_Entry *ad_entry, Slapi_Entry *ds_entry)
  1627. {
  1628. WINSYNC_PLUGIN_CALL_PLUGINS_COOKIE_BEGIN(WINSYNC_PLUGIN_PRE_AD_ADD_GROUP_CB, winsync_pre_ad_add_cb, thefunc)
  1629. (*thefunc)(cookie, ad_entry, ds_entry);
  1630. WINSYNC_PLUGIN_CALL_PLUGINS_END;
  1631. return;
  1632. }
  1633. void
  1634. winsync_plugin_call_post_ad_add_user_cb(const Repl_Agmt *ra, Slapi_Entry *ad_entry, Slapi_Entry *ds_entry, int *result)
  1635. {
  1636. WINSYNC_PLUGIN_CALL_PLUGINS_COOKIE_BEGIN(WINSYNC_PLUGIN_POST_AD_ADD_USER_CB, winsync_post_ad_add_cb, thefunc)
  1637. (*thefunc)(cookie, ad_entry, ds_entry, result);
  1638. WINSYNC_PLUGIN_CALL_PLUGINS_END;
  1639. return;
  1640. }
  1641. void
  1642. winsync_plugin_call_post_ad_add_group_cb(const Repl_Agmt *ra, Slapi_Entry *ad_entry, Slapi_Entry *ds_entry, int *result)
  1643. {
  1644. WINSYNC_PLUGIN_CALL_PLUGINS_COOKIE_BEGIN(WINSYNC_PLUGIN_POST_AD_ADD_GROUP_CB, winsync_post_ad_add_cb, thefunc)
  1645. (*thefunc)(cookie, ad_entry, ds_entry, result);
  1646. WINSYNC_PLUGIN_CALL_PLUGINS_END;
  1647. return;
  1648. }
  1649. void
  1650. winsync_plugin_call_post_ad_mod_user_mods_cb(const Repl_Agmt *ra, const Slapi_Entry *rawentry, const Slapi_DN *local_dn, const Slapi_Entry *ds_entry, LDAPMod *const *origmods, Slapi_DN *remote_dn, LDAPMod **modstosend, int *result)
  1651. {
  1652. WINSYNC_PLUGIN_CALL_PLUGINS_COOKIE_BEGIN(WINSYNC_PLUGIN_POST_AD_MOD_USER_MODS_CB, winsync_post_ad_mod_mods_cb, thefunc)
  1653. (*thefunc)(cookie, rawentry, local_dn, ds_entry, origmods, remote_dn, modstosend, result);
  1654. WINSYNC_PLUGIN_CALL_PLUGINS_END;
  1655. return;
  1656. }
  1657. void
  1658. winsync_plugin_call_post_ad_mod_group_mods_cb(const Repl_Agmt *ra, const Slapi_Entry *rawentry, const Slapi_DN *local_dn, const Slapi_Entry *ds_entry, LDAPMod *const *origmods, Slapi_DN *remote_dn, LDAPMod **modstosend, int *result)
  1659. {
  1660. WINSYNC_PLUGIN_CALL_PLUGINS_COOKIE_BEGIN(WINSYNC_PLUGIN_POST_AD_MOD_GROUP_MODS_CB, winsync_post_ad_mod_mods_cb, thefunc)
  1661. (*thefunc)(cookie, rawentry, local_dn, ds_entry, origmods, remote_dn, modstosend, result);
  1662. WINSYNC_PLUGIN_CALL_PLUGINS_END;
  1663. return;
  1664. }
  1665. /*
  1666. The following are sample code stubs to show how to implement
  1667. a plugin which uses this api
  1668. */
  1669. #define WINSYNC_SAMPLE_CODE
  1670. #ifdef WINSYNC_SAMPLE_CODE
  1671. #include "slapi-plugin.h"
  1672. #include "winsync-plugin.h"
  1673. static char *test_winsync_plugin_name = "test_winsync_api";
  1674. static void *
  1675. test_winsync_api_init(const Slapi_DN *ds_subtree, const Slapi_DN *ad_subtree)
  1676. {
  1677. slapi_log_err(SLAPI_LOG_PLUGIN, test_winsync_plugin_name,
  1678. "--> test_winsync_init [%s] [%s] -- begin\n",
  1679. slapi_sdn_get_dn(ds_subtree),
  1680. slapi_sdn_get_dn(ad_subtree));
  1681. slapi_log_err(SLAPI_LOG_PLUGIN, test_winsync_plugin_name,
  1682. "<-- test_winsync_init -- end\n");
  1683. return NULL;
  1684. }
  1685. static void
  1686. test_winsync_dirsync_search_params_cb(void *cbdata __attribute__((unused)), const char *agmt_dn __attribute__((unused)), char **base __attribute__((unused)), int *scope __attribute__((unused)), char **filter __attribute__((unused)), char ***attrs __attribute__((unused)), LDAPControl ***serverctrls __attribute__((unused)))
  1687. {
  1688. slapi_log_err(SLAPI_LOG_PLUGIN, test_winsync_plugin_name,
  1689. "--> test_winsync_dirsync_search_params_cb -- begin\n");
  1690. slapi_log_err(SLAPI_LOG_PLUGIN, test_winsync_plugin_name,
  1691. "<-- test_winsync_dirsync_search_params_cb -- end\n");
  1692. return;
  1693. }
  1694. /* called before searching for a single entry from AD - agmt_dn will be NULL */
  1695. static void
  1696. test_winsync_pre_ad_search_cb(void *cbdata __attribute__((unused)), const char *agmt_dn __attribute__((unused)), char **base __attribute__((unused)), int *scope __attribute__((unused)), char **filter __attribute__((unused)), char ***attrs __attribute__((unused)), LDAPControl ***serverctrls __attribute__((unused)))
  1697. {
  1698. slapi_log_err(SLAPI_LOG_PLUGIN, test_winsync_plugin_name,
  1699. "--> test_winsync_pre_ad_search_cb -- begin\n");
  1700. slapi_log_err(SLAPI_LOG_PLUGIN, test_winsync_plugin_name,
  1701. "<-- test_winsync_pre_ad_search_cb -- end\n");
  1702. return;
  1703. }
  1704. /* called before an internal search to get a single DS entry - agmt_dn will be NULL */
  1705. static void
  1706. test_winsync_pre_ds_search_entry_cb(void *cbdata __attribute__((unused)), const char *agmt_dn __attribute__((unused)), char **base __attribute__((unused)), int *scope __attribute__((unused)), char **filter __attribute__((unused)), char ***attrs __attribute__((unused)), LDAPControl ***serverctrls __attribute__((unused)))
  1707. {
  1708. slapi_log_err(SLAPI_LOG_PLUGIN, test_winsync_plugin_name,
  1709. "--> test_winsync_pre_ds_search_cb -- begin\n");
  1710. slapi_log_err(SLAPI_LOG_PLUGIN, test_winsync_plugin_name,
  1711. "<-- test_winsync_pre_ds_search_cb -- end\n");
  1712. return;
  1713. }
  1714. /* called before the total update to get all entries from the DS to sync to AD */
  1715. static void
  1716. test_winsync_pre_ds_search_all_cb(void *cbdata __attribute__((unused)), const char *agmt_dn __attribute__((unused)), char **base __attribute__((unused)), int *scope __attribute__((unused)), char **filter, char ***attrs __attribute__((unused)), LDAPControl ***serverctrls __attribute__((unused)))
  1717. {
  1718. slapi_log_err(SLAPI_LOG_PLUGIN, test_winsync_plugin_name,
  1719. "--> test_winsync_pre_ds_search_all_cb -- orig filter [%s] -- begin\n",
  1720. ((filter && *filter) ? *filter : "NULL"));
  1721. #ifdef THIS_IS_JUST_AN_EXAMPLE
  1722. if (filter) {
  1723. /* We only want to grab users from the ds side - no groups */
  1724. slapi_ch_free_string(filter);
  1725. /* maybe use ntUniqueId=* - only get users that have already been
  1726. synced with AD already - ntUniqueId and ntUserDomainId are
  1727. indexed for equality only - need to add presence? */
  1728. *filter = slapi_ch_strdup("(&(objectclass=ntuser)(ntUserDomainId=*))");
  1729. slapi_log_err(SLAPI_LOG_PLUGIN, test_winsync_plugin_name,
  1730. "--> test_winsync_pre_ds_search_all_cb -- new filter [%s]\n",
  1731. *filter ? *filter : "NULL"));
  1732. }
  1733. #endif
  1734. slapi_log_err(SLAPI_LOG_PLUGIN, test_winsync_plugin_name,
  1735. "<-- test_winsync_pre_ds_search_all_cb -- end\n");
  1736. return;
  1737. }
  1738. static void
  1739. test_winsync_pre_ad_mod_user_cb(void *cbdata __attribute__((unused)), const Slapi_Entry *rawentry __attribute__((unused)), Slapi_Entry *ad_entry __attribute__((unused)), Slapi_Entry *ds_entry __attribute__((unused)), Slapi_Mods *smods __attribute__((unused)), int *do_modify __attribute__((unused)))
  1740. {
  1741. slapi_log_err(SLAPI_LOG_PLUGIN, test_winsync_plugin_name,
  1742. "--> test_winsync_pre_ad_mod_user_cb -- begin\n");
  1743. slapi_log_err(SLAPI_LOG_PLUGIN, test_winsync_plugin_name,
  1744. "<-- test_winsync_pre_ad_mod_user_cb -- end\n");
  1745. return;
  1746. }
  1747. static void
  1748. test_winsync_pre_ad_mod_group_cb(void *cbdata __attribute__((unused)), const Slapi_Entry *rawentry __attribute__((unused)), Slapi_Entry *ad_entry __attribute__((unused)), Slapi_Entry *ds_entry __attribute__((unused)), Slapi_Mods *smods __attribute__((unused)), int *do_modify __attribute__((unused)))
  1749. {
  1750. slapi_log_err(SLAPI_LOG_PLUGIN, test_winsync_plugin_name,
  1751. "--> test_winsync_pre_ad_mod_group_cb -- begin\n");
  1752. slapi_log_err(SLAPI_LOG_PLUGIN, test_winsync_plugin_name,
  1753. "<-- test_winsync_pre_ad_mod_group_cb -- end\n");
  1754. return;
  1755. }
  1756. static void
  1757. test_winsync_pre_ds_mod_user_cb(void *cbdata __attribute__((unused)), const Slapi_Entry *rawentry __attribute__((unused)), Slapi_Entry *ad_entry __attribute__((unused)), Slapi_Entry *ds_entry __attribute__((unused)), Slapi_Mods *smods __attribute__((unused)), int *do_modify __attribute__((unused)))
  1758. {
  1759. slapi_log_err(SLAPI_LOG_PLUGIN, test_winsync_plugin_name,
  1760. "--> test_winsync_pre_ds_mod_user_cb -- begin\n");
  1761. slapi_log_err(SLAPI_LOG_PLUGIN, test_winsync_plugin_name,
  1762. "<-- test_winsync_pre_ds_mod_user_cb -- end\n");
  1763. return;
  1764. }
  1765. static void
  1766. test_winsync_pre_ds_mod_group_cb(void *cbdata __attribute__((unused)), const Slapi_Entry *rawentry __attribute__((unused)), Slapi_Entry *ad_entry __attribute__((unused)), Slapi_Entry *ds_entry __attribute__((unused)), Slapi_Mods *smods __attribute__((unused)), int *do_modify __attribute__((unused)))
  1767. {
  1768. slapi_log_err(SLAPI_LOG_PLUGIN, test_winsync_plugin_name,
  1769. "--> test_winsync_pre_ds_mod_group_cb -- begin\n");
  1770. slapi_log_err(SLAPI_LOG_PLUGIN, test_winsync_plugin_name,
  1771. "<-- test_winsync_pre_ds_mod_group_cb -- end\n");
  1772. return;
  1773. }
  1774. static void
  1775. test_winsync_pre_ds_add_user_cb(void *cbdata __attribute__((unused)), const Slapi_Entry *rawentry __attribute__((unused)), Slapi_Entry *ad_entry __attribute__((unused)), Slapi_Entry *ds_entry __attribute__((unused)))
  1776. {
  1777. slapi_log_err(SLAPI_LOG_PLUGIN, test_winsync_plugin_name,
  1778. "--> test_winsync_pre_ds_add_user_cb -- begin\n");
  1779. slapi_log_err(SLAPI_LOG_PLUGIN, test_winsync_plugin_name,
  1780. "<-- test_winsync_pre_ds_add_user_cb -- end\n");
  1781. return;
  1782. }
  1783. static void
  1784. test_winsync_pre_ds_add_group_cb(void *cbdata __attribute__((unused)), const Slapi_Entry *rawentry __attribute__((unused)), Slapi_Entry *ad_entry __attribute__((unused)), Slapi_Entry *ds_entry __attribute__((unused)))
  1785. {
  1786. slapi_log_err(SLAPI_LOG_PLUGIN, test_winsync_plugin_name,
  1787. "--> test_winsync_pre_ds_add_group_cb -- begin\n");
  1788. slapi_log_err(SLAPI_LOG_PLUGIN, test_winsync_plugin_name,
  1789. "<-- test_winsync_pre_ds_add_group_cb -- end\n");
  1790. return;
  1791. }
  1792. static void
  1793. test_winsync_get_new_ds_user_dn_cb(void *cbdata __attribute__((unused)), const Slapi_Entry *rawentry __attribute__((unused)), Slapi_Entry *ad_entry __attribute__((unused)), char **new_dn_string, const Slapi_DN *ds_suffix __attribute__((unused)), const Slapi_DN *ad_suffix __attribute__((unused)))
  1794. {
  1795. slapi_log_err(SLAPI_LOG_PLUGIN, test_winsync_plugin_name,
  1796. "--> test_winsync_get_new_ds_user_dn_cb -- old dn [%s] -- begin\n",
  1797. *new_dn_string);
  1798. #ifdef THIS_IS_JUST_AN_EXAMPLE
  1799. char **rdns = slapi_ldap_explode_dn(*new_dn_string, 0);
  1800. if (!rdns || !rdns[0]) {
  1801. slapi_ldap_value_free(rdns);
  1802. return;
  1803. }
  1804. slapi_ch_free_string(new_dn_string);
  1805. *new_dn_string = PR_smprintf("%s,%s", rdns[0], slapi_sdn_get_dn(ds_suffix));
  1806. slapi_ldap_value_free(rdns);
  1807. #endif
  1808. slapi_log_err(SLAPI_LOG_PLUGIN, test_winsync_plugin_name,
  1809. "<-- test_winsync_get_new_ds_user_dn_cb -- new dn [%s] -- end\n",
  1810. *new_dn_string);
  1811. return;
  1812. }
  1813. static void
  1814. test_winsync_get_new_ds_group_dn_cb(void *cbdata __attribute__((unused)), const Slapi_Entry *rawentry __attribute__((unused)), Slapi_Entry *ad_entry __attribute__((unused)), char **new_dn_string __attribute__((unused)), const Slapi_DN *ds_suffix __attribute__((unused)), const Slapi_DN *ad_suffix __attribute__((unused)))
  1815. {
  1816. slapi_log_err(SLAPI_LOG_PLUGIN, test_winsync_plugin_name,
  1817. "--> test_winsync_get_new_ds_group_dn_cb -- begin\n");
  1818. slapi_log_err(SLAPI_LOG_PLUGIN, test_winsync_plugin_name,
  1819. "<-- test_winsync_get_new_ds_group_dn_cb -- end\n");
  1820. return;
  1821. }
  1822. static void
  1823. test_winsync_pre_ad_mod_user_mods_cb(void *cbdata __attribute__((unused)), const Slapi_Entry *rawentry __attribute__((unused)), const Slapi_Entry *ds_entry __attribute__((unused)), const Slapi_DN *local_dn __attribute__((unused)), LDAPMod *const *origmods __attribute__((unused)), Slapi_DN *remote_dn __attribute__((unused)), LDAPMod ***modstosend __attribute__((unused)))
  1824. {
  1825. slapi_log_err(SLAPI_LOG_PLUGIN, test_winsync_plugin_name,
  1826. "--> test_winsync_pre_ad_mod_user_mods_cb -- begin\n");
  1827. slapi_log_err(SLAPI_LOG_PLUGIN, test_winsync_plugin_name,
  1828. "<-- test_winsync_pre_ad_mod_user_mods_cb -- end\n");
  1829. return;
  1830. }
  1831. static void
  1832. test_winsync_pre_ad_mod_group_mods_cb(void *cbdata __attribute__((unused)), const Slapi_Entry *rawentry __attribute__((unused)), const Slapi_Entry *ds_entry __attribute__((unused)), const Slapi_DN *local_dn __attribute__((unused)), LDAPMod *const *origmods __attribute__((unused)), Slapi_DN *remote_dn __attribute__((unused)), LDAPMod ***modstosend __attribute__((unused)))
  1833. {
  1834. slapi_log_err(SLAPI_LOG_PLUGIN, test_winsync_plugin_name,
  1835. "--> test_winsync_pre_ad_mod_group_mods_cb -- begin\n");
  1836. slapi_log_err(SLAPI_LOG_PLUGIN, test_winsync_plugin_name,
  1837. "<-- test_winsync_pre_ad_mod_group_mods_cb -- end\n");
  1838. return;
  1839. }
  1840. static int
  1841. test_winsync_can_add_entry_to_ad_cb(void *cbdata __attribute__((unused)), const Slapi_Entry *local_entry __attribute__((unused)), const Slapi_DN *remote_dn __attribute__((unused)))
  1842. {
  1843. slapi_log_err(SLAPI_LOG_PLUGIN, test_winsync_plugin_name,
  1844. "--> test_winsync_can_add_entry_to_ad_cb -- begin\n");
  1845. slapi_log_err(SLAPI_LOG_PLUGIN, test_winsync_plugin_name,
  1846. "<-- test_winsync_can_add_entry_to_ad_cb -- end\n");
  1847. /* return 0;*/ /* false - do not allow entries to be added to ad */
  1848. return 1; /* true - allow entries to be added to ad */
  1849. }
  1850. static void
  1851. test_winsync_begin_update_cb(void *cbdata __attribute__((unused)), const Slapi_DN *ds_subtree __attribute__((unused)), const Slapi_DN *ad_subtree __attribute__((unused)), int is_total __attribute__((unused)))
  1852. {
  1853. slapi_log_err(SLAPI_LOG_PLUGIN, test_winsync_plugin_name,
  1854. "--> test_winsync_begin_update_cb -- begin\n");
  1855. slapi_log_err(SLAPI_LOG_PLUGIN, test_winsync_plugin_name,
  1856. "<-- test_winsync_begin_update_cb -- end\n");
  1857. return;
  1858. }
  1859. static void
  1860. test_winsync_end_update_cb(void *cbdata __attribute__((unused)), const Slapi_DN *ds_subtree __attribute__((unused)), const Slapi_DN *ad_subtree __attribute__((unused)), int is_total __attribute__((unused)))
  1861. {
  1862. slapi_log_err(SLAPI_LOG_PLUGIN, test_winsync_plugin_name,
  1863. "--> test_winsync_end_update_cb -- begin\n");
  1864. slapi_log_err(SLAPI_LOG_PLUGIN, test_winsync_plugin_name,
  1865. "<-- test_winsync_end_update_cb -- end\n");
  1866. return;
  1867. }
  1868. static void
  1869. test_winsync_destroy_agmt_cb(void *cbdata __attribute__((unused)), const Slapi_DN *ds_subtree __attribute__((unused)), const Slapi_DN *ad_subtree __attribute__((unused)))
  1870. {
  1871. slapi_log_err(SLAPI_LOG_PLUGIN, test_winsync_plugin_name,
  1872. "--> test_winsync_destroy_agmt_cb -- begin\n");
  1873. /* free(cbdata); */
  1874. slapi_log_err(SLAPI_LOG_PLUGIN, test_winsync_plugin_name,
  1875. "<-- test_winsync_destroy_agmt_cb -- end\n");
  1876. return;
  1877. }
  1878. static void
  1879. test_winsync_post_ad_mod_user_cb(void *cookie __attribute__((unused)), const Slapi_Entry *rawentry __attribute__((unused)), Slapi_Entry *ad_entry __attribute__((unused)), Slapi_Entry *ds_entry __attribute__((unused)), Slapi_Mods *smods __attribute__((unused)), int *result __attribute__((unused)))
  1880. {
  1881. slapi_log_err(SLAPI_LOG_PLUGIN, test_winsync_plugin_name,
  1882. "--> test_winsync_post_ad_mod_user_cb -- begin\n");
  1883. #ifdef THIS_IS_JUST_AN_EXAMPLE
  1884. slapi_log_err(SLAPI_LOG_PLUGIN, test_winsync_plugin_name,
  1885. "Result of modifying AD entry [%s] was [%d:%s]\n",
  1886. slapi_entry_get_dn(ad_entry), *result, ldap_err2string(*result));
  1887. #endif
  1888. slapi_log_err(SLAPI_LOG_PLUGIN, test_winsync_plugin_name,
  1889. "<-- test_winsync_post_ad_mod_user_cb -- end\n");
  1890. return;
  1891. }
  1892. static void
  1893. test_winsync_post_ad_mod_group_cb(void *cookie __attribute__((unused)), const Slapi_Entry *rawentry __attribute__((unused)), Slapi_Entry *ad_entry __attribute__((unused)), Slapi_Entry *ds_entry __attribute__((unused)), Slapi_Mods *smods __attribute__((unused)), int *result __attribute__((unused)))
  1894. {
  1895. slapi_log_err(SLAPI_LOG_PLUGIN, test_winsync_plugin_name,
  1896. "--> test_winsync_post_ad_mod_group_cb -- begin\n");
  1897. #ifdef THIS_IS_JUST_AN_EXAMPLE
  1898. slapi_log_err(SLAPI_LOG_PLUGIN, test_winsync_plugin_name,
  1899. "Result of modifying AD entry [%s] was [%d:%s]\n",
  1900. slapi_entry_get_dn(ad_entry), *result, ldap_err2string(*result));
  1901. #endif
  1902. slapi_log_err(SLAPI_LOG_PLUGIN, test_winsync_plugin_name,
  1903. "<-- test_winsync_post_ad_mod_group_cb -- end\n");
  1904. return;
  1905. }
  1906. static void
  1907. test_winsync_post_ds_mod_user_cb(void *cookie __attribute__((unused)), const Slapi_Entry *rawentry __attribute__((unused)), Slapi_Entry *ad_entry __attribute__((unused)), Slapi_Entry *ds_entry __attribute__((unused)), Slapi_Mods *smods __attribute__((unused)), int *result __attribute__((unused)))
  1908. {
  1909. slapi_log_err(SLAPI_LOG_PLUGIN, test_winsync_plugin_name,
  1910. "--> test_winsync_post_ds_mod_user_cb -- begin\n");
  1911. #ifdef THIS_IS_JUST_AN_EXAMPLE
  1912. slapi_log_err(SLAPI_LOG_PLUGIN, test_winsync_plugin_name,
  1913. "Result of modifying DS entry [%s] was [%d:%s]\n",
  1914. slapi_entry_get_dn(ds_entry), *result, ldap_err2string(*result));
  1915. #endif
  1916. slapi_log_err(SLAPI_LOG_PLUGIN, test_winsync_plugin_name,
  1917. "<-- test_winsync_post_ds_mod_user_cb -- end\n");
  1918. return;
  1919. }
  1920. static void
  1921. test_winsync_post_ds_mod_group_cb(void *cookie __attribute__((unused)), const Slapi_Entry *rawentry __attribute__((unused)), Slapi_Entry *ad_entry __attribute__((unused)), Slapi_Entry *ds_entry __attribute__((unused)), Slapi_Mods *smods __attribute__((unused)), int *result __attribute__((unused)))
  1922. {
  1923. slapi_log_err(SLAPI_LOG_PLUGIN, test_winsync_plugin_name,
  1924. "--> test_winsync_post_ds_mod_group_cb -- begin\n");
  1925. #ifdef THIS_IS_JUST_AN_EXAMPLE
  1926. slapi_log_err(SLAPI_LOG_PLUGIN, test_winsync_plugin_name,
  1927. "Result of modifying DS entry [%s] was [%d:%s]\n",
  1928. slapi_entry_get_dn(ds_entry), *result, ldap_err2string(*result));
  1929. #endif
  1930. slapi_log_err(SLAPI_LOG_PLUGIN, test_winsync_plugin_name,
  1931. "<-- test_winsync_post_ds_mod_group_cb -- end\n");
  1932. return;
  1933. }
  1934. static void
  1935. test_winsync_post_ds_add_user_cb(void *cookie __attribute__((unused)), const Slapi_Entry *rawentry __attribute__((unused)), Slapi_Entry *ad_entry __attribute__((unused)), Slapi_Entry *ds_entry __attribute__((unused)), int *result __attribute__((unused)))
  1936. {
  1937. slapi_log_err(SLAPI_LOG_PLUGIN, test_winsync_plugin_name,
  1938. "--> test_winsync_post_ds_add_user_cb -- begin\n");
  1939. #ifdef THIS_IS_JUST_AN_EXAMPLE
  1940. slapi_log_err(SLAPI_LOG_PLUGIN, test_winsync_plugin_name,
  1941. "Result of adding DS entry [%s] was [%d:%s]\n",
  1942. slapi_entry_get_dn(ds_entry), *result, ldap_err2string(*result));
  1943. #endif
  1944. slapi_log_err(SLAPI_LOG_PLUGIN, test_winsync_plugin_name,
  1945. "<-- test_winsync_post_ds_add_user_cb -- end\n");
  1946. return;
  1947. }
  1948. static void
  1949. test_winsync_post_ds_add_group_cb(void *cookie __attribute__((unused)), const Slapi_Entry *rawentry __attribute__((unused)), Slapi_Entry *ad_entry __attribute__((unused)), Slapi_Entry *ds_entry __attribute__((unused)), int *result __attribute__((unused)))
  1950. {
  1951. slapi_log_err(SLAPI_LOG_PLUGIN, test_winsync_plugin_name,
  1952. "--> test_winsync_post_ds_add_group_cb -- begin\n");
  1953. #ifdef THIS_IS_JUST_AN_EXAMPLE
  1954. slapi_log_err(SLAPI_LOG_PLUGIN, test_winsync_plugin_name,
  1955. "Result of adding DS entry [%s] was [%d:%s]\n",
  1956. slapi_entry_get_dn(ds_entry), *result, ldap_err2string(*result));
  1957. #endif
  1958. slapi_log_err(SLAPI_LOG_PLUGIN, test_winsync_plugin_name,
  1959. "<-- test_winsync_post_ds_add_group_cb -- end\n");
  1960. return;
  1961. }
  1962. static void
  1963. test_winsync_pre_ad_add_user_cb(void *cookie __attribute__((unused)), Slapi_Entry *ds_entry __attribute__((unused)), Slapi_Entry *ad_entry __attribute__((unused)))
  1964. {
  1965. slapi_log_err(SLAPI_LOG_PLUGIN, test_winsync_plugin_name,
  1966. "--> test_winsync_pre_ad_add_user_cb -- begin\n");
  1967. #ifdef THIS_IS_JUST_AN_EXAMPLE
  1968. slapi_log_err(SLAPI_LOG_PLUGIN, test_winsync_plugin_name,
  1969. "Adding AD entry [%s] from add of DS entry [%s]\n",
  1970. slapi_entry_get_dn(ad_entry), slapi_entry_get_dn(ds_entry));
  1971. /* make modifications to ad_entry here */
  1972. #endif
  1973. slapi_log_err(SLAPI_LOG_PLUGIN, test_winsync_plugin_name,
  1974. "<-- test_winsync_pre_ad_add_user_cb -- end\n");
  1975. return;
  1976. }
  1977. static void
  1978. test_winsync_pre_ad_add_group_cb(void *cookie __attribute__((unused)), Slapi_Entry *ds_entry __attribute__((unused)), Slapi_Entry *ad_entry __attribute__((unused)))
  1979. {
  1980. slapi_log_err(SLAPI_LOG_PLUGIN, test_winsync_plugin_name,
  1981. "--> test_winsync_pre_ad_add_group_cb -- begin\n");
  1982. #ifdef THIS_IS_JUST_AN_EXAMPLE
  1983. slapi_log_err(SLAPI_LOG_PLUGIN, test_winsync_plugin_name,
  1984. "Adding AD entry [%s] from add of DS entry [%s]\n",
  1985. slapi_entry_get_dn(ad_entry), slapi_entry_get_dn(ds_entry));
  1986. /* make modifications to ad_entry here */
  1987. #endif
  1988. slapi_log_err(SLAPI_LOG_PLUGIN, test_winsync_plugin_name,
  1989. "<-- test_winsync_pre_ad_add_group_cb -- end\n");
  1990. return;
  1991. }
  1992. static void
  1993. test_winsync_post_ad_add_user_cb(void *cookie __attribute__((unused)), Slapi_Entry *ds_entry __attribute__((unused)), Slapi_Entry *ad_entry __attribute__((unused)), int *result __attribute__((unused)))
  1994. {
  1995. slapi_log_err(SLAPI_LOG_PLUGIN, test_winsync_plugin_name,
  1996. "--> test_winsync_post_ad_add_user_cb -- begin\n");
  1997. #ifdef THIS_IS_JUST_AN_EXAMPLE
  1998. slapi_log_err(SLAPI_LOG_PLUGIN, test_winsync_plugin_name,
  1999. "Result of adding AD entry [%s] was [%d:%s]\n",
  2000. slapi_entry_get_dn(ad_entry), *result, ldap_err2string(*result));
  2001. #endif
  2002. slapi_log_err(SLAPI_LOG_PLUGIN, test_winsync_plugin_name,
  2003. "<-- test_winsync_post_ad_add_user_cb -- end\n");
  2004. return;
  2005. }
  2006. static void
  2007. test_winsync_post_ad_add_group_cb(void *cookie __attribute__((unused)), Slapi_Entry *ds_entry __attribute__((unused)), Slapi_Entry *ad_entry __attribute__((unused)), int *result __attribute__((unused)))
  2008. {
  2009. slapi_log_err(SLAPI_LOG_PLUGIN, test_winsync_plugin_name,
  2010. "--> test_winsync_post_ad_add_group_cb -- begin\n");
  2011. #ifdef THIS_IS_JUST_AN_EXAMPLE
  2012. slapi_log_err(SLAPI_LOG_PLUGIN, test_winsync_plugin_name,
  2013. "Result of adding AD entry [%s] was [%d:%s]\n",
  2014. slapi_entry_get_dn(ad_entry), *result, ldap_err2string(*result));
  2015. #endif
  2016. slapi_log_err(SLAPI_LOG_PLUGIN, test_winsync_plugin_name,
  2017. "<-- test_winsync_post_ad_add_group_cb -- end\n");
  2018. return;
  2019. }
  2020. static void
  2021. test_winsync_post_ad_mod_user_mods_cb(void *cookie __attribute__((unused)), const Slapi_Entry *rawentry __attribute__((unused)), const Slapi_DN *local_dn __attribute__((unused)), const Slapi_Entry *ds_entry __attribute__((unused)), LDAPMod *const *origmods __attribute__((unused)), Slapi_DN *remote_dn __attribute__((unused)), LDAPMod ***modstosend __attribute__((unused)), int *result __attribute__((unused)))
  2022. {
  2023. slapi_log_err(SLAPI_LOG_PLUGIN, test_winsync_plugin_name,
  2024. "--> test_winsync_post_ad_mod_user_mods_cb -- begin\n");
  2025. #ifdef THIS_IS_JUST_AN_EXAMPLE
  2026. slapi_log_err(SLAPI_LOG_PLUGIN, test_winsync_plugin_name,
  2027. "Result of modifying AD entry [%s] was [%d:%s]\n",
  2028. slapi_sdn_get_dn(remote_dn), *result, ldap_err2string(*result));
  2029. #endif
  2030. slapi_log_err(SLAPI_LOG_PLUGIN, test_winsync_plugin_name,
  2031. "<-- test_winsync_post_ad_mod_user_mods_cb -- end\n");
  2032. return;
  2033. }
  2034. static void
  2035. test_winsync_post_ad_mod_group_mods_cb(void *cookie __attribute__((unused)), const Slapi_Entry *rawentry __attribute__((unused)), const Slapi_DN *local_dn __attribute__((unused)), const Slapi_Entry *ds_entry __attribute__((unused)), LDAPMod *const *origmods __attribute__((unused)), Slapi_DN *remote_dn __attribute__((unused)), LDAPMod ***modstosend __attribute__((unused)), int *result __attribute__((unused)))
  2036. {
  2037. slapi_log_err(SLAPI_LOG_PLUGIN, test_winsync_plugin_name,
  2038. "--> test_winsync_post_ad_mod_group_mods_cb -- begin\n");
  2039. #ifdef THIS_IS_JUST_AN_EXAMPLE
  2040. slapi_log_err(SLAPI_LOG_PLUGIN, test_winsync_plugin_name,
  2041. "Result of modifying AD entry [%s] was [%d:%s]\n",
  2042. slapi_sdn_get_dn(remote_dn), *result, ldap_err2string(*result));
  2043. #endif
  2044. slapi_log_err(SLAPI_LOG_PLUGIN, test_winsync_plugin_name,
  2045. "<-- test_winsync_post_ad_mod_group_mods_cb -- end\n");
  2046. return;
  2047. }
  2048. static int
  2049. test_winsync_precedence(void)
  2050. {
  2051. return 99;
  2052. }
  2053. /**
  2054. * Plugin identifiers
  2055. */
  2056. static Slapi_PluginDesc test_winsync_pdesc = {
  2057. "test-winsync-plugin",
  2058. VENDOR,
  2059. DS_PACKAGE_VERSION,
  2060. "test winsync plugin"};
  2061. static Slapi_ComponentId *test_winsync_plugin_id = NULL;
  2062. #ifdef TEST_V1_WINSYNC_API
  2063. static void *test_winsync_api_v1[] = {
  2064. NULL, /* reserved for api broker use, must be zero */
  2065. test_winsync_api_init,
  2066. test_winsync_dirsync_search_params_cb,
  2067. test_winsync_pre_ad_search_cb,
  2068. test_winsync_pre_ds_search_entry_cb,
  2069. test_winsync_pre_ds_search_all_cb,
  2070. test_winsync_pre_ad_mod_user_cb,
  2071. test_winsync_pre_ad_mod_group_cb,
  2072. test_winsync_pre_ds_mod_user_cb,
  2073. test_winsync_pre_ds_mod_group_cb,
  2074. test_winsync_pre_ds_add_user_cb,
  2075. test_winsync_pre_ds_add_group_cb,
  2076. test_winsync_get_new_ds_user_dn_cb,
  2077. test_winsync_get_new_ds_group_dn_cb,
  2078. test_winsync_pre_ad_mod_user_mods_cb,
  2079. test_winsync_pre_ad_mod_group_mods_cb,
  2080. test_winsync_can_add_entry_to_ad_cb,
  2081. test_winsync_begin_update_cb,
  2082. test_winsync_end_update_cb,
  2083. test_winsync_destroy_agmt_cb};
  2084. #endif /* TEST_V1_WINSYNC_API */
  2085. #ifdef TEST_V2_WINSYNC_API
  2086. static void *test_winsync_api_v2[] = {
  2087. NULL, /* reserved for api broker use, must be zero */
  2088. test_winsync_api_init,
  2089. test_winsync_dirsync_search_params_cb,
  2090. test_winsync_pre_ad_search_cb,
  2091. test_winsync_pre_ds_search_entry_cb,
  2092. test_winsync_pre_ds_search_all_cb,
  2093. test_winsync_pre_ad_mod_user_cb,
  2094. test_winsync_pre_ad_mod_group_cb,
  2095. test_winsync_pre_ds_mod_user_cb,
  2096. test_winsync_pre_ds_mod_group_cb,
  2097. test_winsync_pre_ds_add_user_cb,
  2098. test_winsync_pre_ds_add_group_cb,
  2099. test_winsync_get_new_ds_user_dn_cb,
  2100. test_winsync_get_new_ds_group_dn_cb,
  2101. test_winsync_pre_ad_mod_user_mods_cb,
  2102. test_winsync_pre_ad_mod_group_mods_cb,
  2103. test_winsync_can_add_entry_to_ad_cb,
  2104. test_winsync_begin_update_cb,
  2105. test_winsync_end_update_cb,
  2106. test_winsync_destroy_agmt_cb,
  2107. test_winsync_post_ad_mod_user_cb,
  2108. test_winsync_post_ad_mod_group_cb,
  2109. test_winsync_post_ds_mod_user_cb,
  2110. test_winsync_post_ds_mod_group_cb,
  2111. test_winsync_post_ds_add_user_cb,
  2112. test_winsync_post_ds_add_group_cb,
  2113. test_winsync_pre_ad_add_user_cb,
  2114. test_winsync_pre_ad_add_group_cb,
  2115. test_winsync_post_ad_add_user_cb,
  2116. test_winsync_post_ad_add_group_cb,
  2117. test_winsync_post_ad_mod_user_mods_cb,
  2118. test_winsync_post_ad_mod_group_mods_cb};
  2119. #endif /* TEST_V2_WINSYNC_API */
  2120. static void *test_winsync_api_v3[] = {
  2121. NULL, /* reserved for api broker use, must be zero */
  2122. test_winsync_api_init,
  2123. test_winsync_dirsync_search_params_cb,
  2124. test_winsync_pre_ad_search_cb,
  2125. test_winsync_pre_ds_search_entry_cb,
  2126. test_winsync_pre_ds_search_all_cb,
  2127. test_winsync_pre_ad_mod_user_cb,
  2128. test_winsync_pre_ad_mod_group_cb,
  2129. test_winsync_pre_ds_mod_user_cb,
  2130. test_winsync_pre_ds_mod_group_cb,
  2131. test_winsync_pre_ds_add_user_cb,
  2132. test_winsync_pre_ds_add_group_cb,
  2133. test_winsync_get_new_ds_user_dn_cb,
  2134. test_winsync_get_new_ds_group_dn_cb,
  2135. test_winsync_pre_ad_mod_user_mods_cb,
  2136. test_winsync_pre_ad_mod_group_mods_cb,
  2137. test_winsync_can_add_entry_to_ad_cb,
  2138. test_winsync_begin_update_cb,
  2139. test_winsync_end_update_cb,
  2140. test_winsync_destroy_agmt_cb,
  2141. test_winsync_post_ad_mod_user_cb,
  2142. test_winsync_post_ad_mod_group_cb,
  2143. test_winsync_post_ds_mod_user_cb,
  2144. test_winsync_post_ds_mod_group_cb,
  2145. test_winsync_post_ds_add_user_cb,
  2146. test_winsync_post_ds_add_group_cb,
  2147. test_winsync_pre_ad_add_user_cb,
  2148. test_winsync_pre_ad_add_group_cb,
  2149. test_winsync_post_ad_add_user_cb,
  2150. test_winsync_post_ad_add_group_cb,
  2151. test_winsync_post_ad_mod_user_mods_cb,
  2152. test_winsync_post_ad_mod_group_mods_cb,
  2153. test_winsync_precedence};
  2154. static int
  2155. test_winsync_plugin_start(Slapi_PBlock *pb __attribute__((unused)))
  2156. {
  2157. slapi_log_err(SLAPI_LOG_TRACE, test_winsync_plugin_name,
  2158. "--> test_winsync_plugin_start -- begin\n");
  2159. if (slapi_apib_register(WINSYNC_v3_0_GUID, test_winsync_api_v3)) {
  2160. slapi_log_err(SLAPI_LOG_ERR, test_winsync_plugin_name,
  2161. "test_winsync_plugin_start - Failed to register winsync api -- end\n");
  2162. return -1;
  2163. }
  2164. slapi_log_err(SLAPI_LOG_TRACE, test_winsync_plugin_name,
  2165. "<-- test_winsync_plugin_start -- end\n");
  2166. return 0;
  2167. }
  2168. static int
  2169. test_winsync_plugin_close(Slapi_PBlock *pb __attribute__((unused)))
  2170. {
  2171. slapi_log_err(SLAPI_LOG_TRACE, test_winsync_plugin_name,
  2172. "--> test_winsync_plugin_close -- begin\n");
  2173. slapi_apib_unregister(WINSYNC_v3_0_GUID);
  2174. slapi_log_err(SLAPI_LOG_TRACE, test_winsync_plugin_name,
  2175. "<-- test_winsync_plugin_close -- end\n");
  2176. return 0;
  2177. }
  2178. /* this is the slapi plugin init function,
  2179. not the one used by the winsync api
  2180. */
  2181. int
  2182. test_winsync_plugin_init(Slapi_PBlock *pb)
  2183. {
  2184. slapi_log_err(SLAPI_LOG_TRACE, test_winsync_plugin_name,
  2185. "--> test_winsync_plugin_init -- begin\n");
  2186. if (slapi_pblock_set(pb, SLAPI_PLUGIN_VERSION,
  2187. SLAPI_PLUGIN_VERSION_01) != 0 ||
  2188. slapi_pblock_set(pb, SLAPI_PLUGIN_START_FN,
  2189. (void *)test_winsync_plugin_start) != 0 ||
  2190. slapi_pblock_set(pb, SLAPI_PLUGIN_CLOSE_FN,
  2191. (void *)test_winsync_plugin_close) != 0 ||
  2192. slapi_pblock_set(pb, SLAPI_PLUGIN_DESCRIPTION,
  2193. (void *)&test_winsync_pdesc) != 0) {
  2194. slapi_log_err(SLAPI_LOG_ERR, test_winsync_plugin_name,
  2195. "<-- test_winsync_plugin_init -- failed to register plugin -- end\n");
  2196. return -1;
  2197. }
  2198. /* Retrieve and save the plugin identity to later pass to
  2199. internal operations */
  2200. if (slapi_pblock_get(pb, SLAPI_PLUGIN_IDENTITY, &test_winsync_plugin_id) != 0) {
  2201. slapi_log_err(SLAPI_LOG_ERR, test_winsync_plugin_name,
  2202. "test_winsync_plugin_init - Failed to retrieve plugin identity -- end\n");
  2203. return -1;
  2204. }
  2205. slapi_log_err(SLAPI_LOG_TRACE, test_winsync_plugin_name,
  2206. "<-- test_winsync_plugin_init -- end\n");
  2207. return 0;
  2208. }
  2209. /*
  2210. dn: cn=Test Winsync API,cn=plugins,cn=config
  2211. objectclass: top
  2212. objectclass: nsSlapdPlugin
  2213. objectclass: extensibleObject
  2214. cn: Test Winsync API
  2215. nsslapd-pluginpath: libtestwinsync-plugin
  2216. nsslapd-plugininitfunc: test_winsync_plugin_init
  2217. nsslapd-plugintype: preoperation
  2218. nsslapd-pluginenabled: on
  2219. nsslapd-plugin-depends-on-type: database
  2220. nsslapd-pluginDescription: Test Winsync
  2221. nsslapd-pluginVendor: 389 project
  2222. nsslapd-pluginId: test-winsync
  2223. nsslapd-pluginVersion: 0.9
  2224. */
  2225. #endif /* WINSYNC_SAMPLE_CODE */
  2226. /* #define WINSYNC_TEST_IPA */
  2227. #ifdef WINSYNC_TEST_IPA
  2228. #include "ipa-winsync.c"
  2229. #include "ipa-winsync-config.c"
  2230. #endif