windows_private.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693
  1. /** BEGIN COPYRIGHT BLOCK
  2. * This Program is free software; you can redistribute it and/or modify it under
  3. * the terms of the GNU General Public License as published by the Free Software
  4. * Foundation; version 2 of the License.
  5. *
  6. * This Program is distributed in the hope that it will be useful, but WITHOUT
  7. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  8. * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
  9. *
  10. * You should have received a copy of the GNU General Public License along with
  11. * this Program; if not, write to the Free Software Foundation, Inc., 59 Temple
  12. * Place, Suite 330, Boston, MA 02111-1307 USA.
  13. *
  14. * In addition, as a special exception, Red Hat, Inc. gives You the additional
  15. * right to link the code of this Program with code not covered under the GNU
  16. * General Public License ("Non-GPL Code") and to distribute linked combinations
  17. * including the two, subject to the limitations in this paragraph. Non-GPL Code
  18. * permitted under this exception must only link to the code of this Program
  19. * through those well defined interfaces identified in the file named EXCEPTION
  20. * found in the source code files (the "Approved Interfaces"). The files of
  21. * Non-GPL Code may instantiate templates or use macros or inline functions from
  22. * the Approved Interfaces without causing the resulting work to be covered by
  23. * the GNU General Public License. Only Red Hat, Inc. may make changes or
  24. * additions to the list of Approved Interfaces. You must obey the GNU General
  25. * Public License in all respects for all of the Program code and other code used
  26. * in conjunction with the Program except the Non-GPL Code covered by this
  27. * exception. If you modify this file, you may extend this exception to your
  28. * version of the file, but you are not obligated to do so. If you do not wish to
  29. * provide this exception without modification, you must delete this exception
  30. * statement from your version and license this file solely under the GPL without
  31. * exception.
  32. *
  33. *
  34. * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
  35. * Copyright (C) 2005 Red Hat, Inc.
  36. * All rights reserved.
  37. * END COPYRIGHT BLOCK **/
  38. #ifdef HAVE_CONFIG_H
  39. # include <config.h>
  40. #endif
  41. /* windows_private.c */
  42. #include "repl.h"
  43. #include "repl5.h"
  44. #include "slap.h"
  45. #include "slapi-plugin.h"
  46. #include "windowsrepl.h"
  47. struct windowsprivate {
  48. Slapi_DN *windows_subtree; /* DN of synchronized subtree (on the windows side) */
  49. Slapi_DN *directory_subtree; /* DN of synchronized subtree on directory side */
  50. /* this simplifies the mapping as it's simply
  51. from the former to the latter container, or
  52. vice versa */
  53. ber_int_t dirsync_flags;
  54. ber_int_t dirsync_maxattributecount;
  55. char *dirsync_cookie;
  56. int dirsync_cookie_len;
  57. PRBool dirsync_cookie_has_more;
  58. PRBool create_users_from_dirsync;
  59. PRBool create_groups_from_dirsync;
  60. char *windows_domain;
  61. int isnt4;
  62. };
  63. static int
  64. true_value_from_string(char *val)
  65. {
  66. if (strcasecmp (val, "on") == 0 || strcasecmp (val, "yes") == 0 ||
  67. strcasecmp (val, "true") == 0 || strcasecmp (val, "1") == 0)
  68. {
  69. return 1;
  70. } else
  71. {
  72. return 0;
  73. }
  74. }
  75. static int
  76. windows_parse_config_entry(Repl_Agmt *ra, const char *type, Slapi_Entry *e)
  77. {
  78. char *tmpstr = NULL;
  79. int retval = 0;
  80. if (type == NULL || slapi_attr_types_equivalent(type,type_nsds7WindowsReplicaArea))
  81. {
  82. tmpstr = slapi_entry_attr_get_charptr(e, type_nsds7WindowsReplicaArea);
  83. if (NULL != tmpstr)
  84. {
  85. windows_private_set_windows_subtree(ra, slapi_sdn_new_dn_passin(tmpstr) );
  86. }
  87. retval = 1;
  88. slapi_ch_free((void**)&tmpstr);
  89. }
  90. if (type == NULL || slapi_attr_types_equivalent(type,type_nsds7DirectoryReplicaArea))
  91. {
  92. tmpstr = slapi_entry_attr_get_charptr(e, type_nsds7DirectoryReplicaArea);
  93. if (NULL != tmpstr)
  94. {
  95. windows_private_set_directory_subtree(ra, slapi_sdn_new_dn_passin(tmpstr) );
  96. }
  97. retval = 1;
  98. slapi_ch_free((void**)&tmpstr);
  99. }
  100. if (type == NULL || slapi_attr_types_equivalent(type,type_nsds7CreateNewUsers))
  101. {
  102. tmpstr = slapi_entry_attr_get_charptr(e, type_nsds7CreateNewUsers);
  103. if (NULL != tmpstr && true_value_from_string(tmpstr))
  104. {
  105. windows_private_set_create_users(ra, PR_TRUE);
  106. }
  107. else
  108. {
  109. windows_private_set_create_users(ra, PR_FALSE);
  110. }
  111. retval = 1;
  112. slapi_ch_free((void**)&tmpstr);
  113. }
  114. if (type == NULL || slapi_attr_types_equivalent(type,type_nsds7CreateNewGroups))
  115. {
  116. tmpstr = slapi_entry_attr_get_charptr(e, type_nsds7CreateNewGroups);
  117. if (NULL != tmpstr && true_value_from_string(tmpstr))
  118. {
  119. windows_private_set_create_groups(ra, PR_TRUE);
  120. }
  121. else
  122. {
  123. windows_private_set_create_groups(ra, PR_FALSE);
  124. }
  125. retval = 1;
  126. slapi_ch_free((void**)&tmpstr);
  127. }
  128. if (type == NULL || slapi_attr_types_equivalent(type,type_nsds7WindowsDomain))
  129. {
  130. tmpstr = slapi_entry_attr_get_charptr(e, type_nsds7WindowsDomain);
  131. if (NULL != tmpstr)
  132. {
  133. windows_private_set_windows_domain(ra,tmpstr);
  134. }
  135. /* No need to free tmpstr because it was aliased by the call above */
  136. tmpstr = NULL;
  137. retval = 1;
  138. }
  139. return retval;
  140. }
  141. /* Returns non-zero if the modify was ok, zero if not */
  142. int
  143. windows_handle_modify_agreement(Repl_Agmt *ra, const char *type, Slapi_Entry *e)
  144. {
  145. /* Is this a Windows agreement ? */
  146. if (get_agmt_agreement_type(ra) == REPLICA_TYPE_WINDOWS)
  147. {
  148. return windows_parse_config_entry(ra,type,e);
  149. } else
  150. {
  151. return 0;
  152. }
  153. }
  154. void
  155. windows_init_agreement_from_entry(Repl_Agmt *ra, Slapi_Entry *e)
  156. {
  157. agmt_set_priv(ra,windows_private_new());
  158. windows_parse_config_entry(ra,NULL,e);
  159. }
  160. const char* windows_private_get_purl(const Repl_Agmt *ra)
  161. {
  162. const char* windows_purl;
  163. char *hostname;
  164. hostname = agmt_get_hostname(ra);
  165. windows_purl = slapi_ch_smprintf("ldap://%s:%d", hostname, agmt_get_port(ra));
  166. slapi_ch_free_string(&hostname);
  167. return windows_purl;
  168. }
  169. Dirsync_Private* windows_private_new()
  170. {
  171. Dirsync_Private *dp;
  172. LDAPDebug( LDAP_DEBUG_TRACE, "=> windows_private_new\n", 0, 0, 0 );
  173. dp = (Dirsync_Private *)slapi_ch_calloc(sizeof(Dirsync_Private),1);
  174. dp->dirsync_maxattributecount = -1;
  175. LDAPDebug( LDAP_DEBUG_TRACE, "<= windows_private_new\n", 0, 0, 0 );
  176. return dp;
  177. }
  178. void windows_agreement_delete(Repl_Agmt *ra)
  179. {
  180. Dirsync_Private *dp = (Dirsync_Private *) agmt_get_priv(ra);
  181. LDAPDebug( LDAP_DEBUG_TRACE, "=> windows_private_delete\n", 0, 0, 0 );
  182. PR_ASSERT(dp != NULL);
  183. /* DBDB: need to free payoad here */
  184. slapi_ch_free((void **)dp);
  185. LDAPDebug( LDAP_DEBUG_TRACE, "<= windows_private_delete\n", 0, 0, 0 );
  186. }
  187. int windows_private_get_isnt4(const Repl_Agmt *ra)
  188. {
  189. Dirsync_Private *dp;
  190. LDAPDebug( LDAP_DEBUG_TRACE, "=> windows_private_get_isnt4\n", 0, 0, 0 );
  191. PR_ASSERT(ra);
  192. dp = (Dirsync_Private *) agmt_get_priv(ra);
  193. PR_ASSERT (dp);
  194. LDAPDebug( LDAP_DEBUG_TRACE, "<= windows_private_get_isnt4\n", 0, 0, 0 );
  195. return dp->isnt4;
  196. }
  197. void windows_private_set_isnt4(const Repl_Agmt *ra, int isit)
  198. {
  199. Dirsync_Private *dp;
  200. LDAPDebug( LDAP_DEBUG_TRACE, "=> windows_private_set_isnt4\n", 0, 0, 0 );
  201. PR_ASSERT(ra);
  202. dp = (Dirsync_Private *) agmt_get_priv(ra);
  203. PR_ASSERT (dp);
  204. dp->isnt4 = isit;
  205. LDAPDebug( LDAP_DEBUG_TRACE, "<= windows_private_set_isnt4\n", 0, 0, 0 );
  206. }
  207. /* Returns a copy of the Slapi_DN pointer, no need to free it */
  208. const Slapi_DN* windows_private_get_windows_subtree (const Repl_Agmt *ra)
  209. {
  210. Dirsync_Private *dp;
  211. LDAPDebug( LDAP_DEBUG_TRACE, "=> windows_private_get_windows_subtree\n", 0, 0, 0 );
  212. PR_ASSERT(ra);
  213. dp = (Dirsync_Private *) agmt_get_priv(ra);
  214. PR_ASSERT (dp);
  215. LDAPDebug( LDAP_DEBUG_TRACE, "<= windows_private_get_windows_subtree\n", 0, 0, 0 );
  216. return dp->windows_subtree;
  217. }
  218. const char *
  219. windows_private_get_windows_domain(const Repl_Agmt *ra)
  220. {
  221. Dirsync_Private *dp;
  222. LDAPDebug( LDAP_DEBUG_TRACE, "=> windows_private_get_windows_domain\n", 0, 0, 0 );
  223. PR_ASSERT(ra);
  224. dp = (Dirsync_Private *) agmt_get_priv(ra);
  225. PR_ASSERT (dp);
  226. LDAPDebug( LDAP_DEBUG_TRACE, "<= windows_private_get_windows_domain\n", 0, 0, 0 );
  227. return dp->windows_domain;
  228. }
  229. static void
  230. windows_private_set_windows_domain(const Repl_Agmt *ra, char *domain)
  231. {
  232. Dirsync_Private *dp;
  233. LDAPDebug( LDAP_DEBUG_TRACE, "=> windows_private_set_windows_domain\n", 0, 0, 0 );
  234. PR_ASSERT(ra);
  235. dp = (Dirsync_Private *) agmt_get_priv(ra);
  236. PR_ASSERT (dp);
  237. dp->windows_domain = domain;
  238. LDAPDebug( LDAP_DEBUG_TRACE, "<= windows_private_set_windows_domain\n", 0, 0, 0 );
  239. }
  240. /* Returns a copy of the Slapi_DN pointer, no need to free it */
  241. const Slapi_DN* windows_private_get_directory_subtree (const Repl_Agmt *ra)
  242. {
  243. Dirsync_Private *dp;
  244. LDAPDebug( LDAP_DEBUG_TRACE, "=> windows_private_get_directory_replarea\n", 0, 0, 0 );
  245. PR_ASSERT(ra);
  246. dp = (Dirsync_Private *) agmt_get_priv(ra);
  247. PR_ASSERT (dp);
  248. LDAPDebug( LDAP_DEBUG_TRACE, "<= windows_private_get_directory_replarea\n", 0, 0, 0 );
  249. return dp->directory_subtree;
  250. }
  251. /* Takes a copy of the sdn passed in */
  252. void windows_private_set_windows_subtree (const Repl_Agmt *ra,const Slapi_DN* sdn )
  253. {
  254. Dirsync_Private *dp;
  255. LDAPDebug( LDAP_DEBUG_TRACE, "=> windows_private_set_windows_replarea\n", 0, 0, 0 );
  256. PR_ASSERT(ra);
  257. PR_ASSERT(sdn);
  258. dp = (Dirsync_Private *) agmt_get_priv(ra);
  259. PR_ASSERT (dp);
  260. dp->windows_subtree = slapi_sdn_dup(sdn);
  261. LDAPDebug( LDAP_DEBUG_TRACE, "<= windows_private_set_windows_replarea\n", 0, 0, 0 );
  262. }
  263. /* Takes a copy of the sdn passed in */
  264. void windows_private_set_directory_subtree (const Repl_Agmt *ra,const Slapi_DN* sdn )
  265. {
  266. Dirsync_Private *dp;
  267. LDAPDebug( LDAP_DEBUG_TRACE, "=> windows_private_set_directory_replarea\n", 0, 0, 0 );
  268. PR_ASSERT(ra);
  269. PR_ASSERT(sdn);
  270. dp = (Dirsync_Private *) agmt_get_priv(ra);
  271. PR_ASSERT (dp);
  272. dp->directory_subtree = slapi_sdn_dup(sdn);
  273. LDAPDebug( LDAP_DEBUG_TRACE, "<= windows_private_set_directory_replarea\n", 0, 0, 0 );
  274. }
  275. PRBool windows_private_create_users(const Repl_Agmt *ra)
  276. {
  277. Dirsync_Private *dp;
  278. LDAPDebug( LDAP_DEBUG_TRACE, "=> windows_private_create_users\n", 0, 0, 0 );
  279. PR_ASSERT(ra);
  280. dp = (Dirsync_Private *) agmt_get_priv(ra);
  281. PR_ASSERT (dp);
  282. LDAPDebug( LDAP_DEBUG_TRACE, "<= windows_private_create_users\n", 0, 0, 0 );
  283. return dp->create_users_from_dirsync;
  284. }
  285. void windows_private_set_create_users(const Repl_Agmt *ra, PRBool value)
  286. {
  287. Dirsync_Private *dp;
  288. LDAPDebug( LDAP_DEBUG_TRACE, "=> windows_private_set_create_users\n", 0, 0, 0 );
  289. PR_ASSERT(ra);
  290. dp = (Dirsync_Private *) agmt_get_priv(ra);
  291. PR_ASSERT (dp);
  292. dp->create_users_from_dirsync = value;
  293. LDAPDebug( LDAP_DEBUG_TRACE, "<= windows_private_set_create_users\n", 0, 0, 0 );
  294. }
  295. PRBool windows_private_create_groups(const Repl_Agmt *ra)
  296. {
  297. Dirsync_Private *dp;
  298. LDAPDebug( LDAP_DEBUG_TRACE, "=> windows_private_create_groups\n", 0, 0, 0 );
  299. PR_ASSERT(ra);
  300. dp = (Dirsync_Private *) agmt_get_priv(ra);
  301. PR_ASSERT (dp);
  302. LDAPDebug( LDAP_DEBUG_TRACE, "<= windows_private_create_groups\n", 0, 0, 0 );
  303. return dp->create_groups_from_dirsync;
  304. }
  305. void windows_private_set_create_groups(const Repl_Agmt *ra, PRBool value)
  306. {
  307. Dirsync_Private *dp;
  308. LDAPDebug( LDAP_DEBUG_TRACE, "=> windows_private_set_create_groups\n", 0, 0, 0 );
  309. PR_ASSERT(ra);
  310. dp = (Dirsync_Private *) agmt_get_priv(ra);
  311. PR_ASSERT (dp);
  312. dp->create_groups_from_dirsync = value;
  313. LDAPDebug( LDAP_DEBUG_TRACE, "<= windows_private_set_create_groups\n", 0, 0, 0 );
  314. }
  315. /*
  316. This function returns the current Dirsync_Private that's inside
  317. Repl_Agmt ra as a ldap control.
  318. */
  319. LDAPControl* windows_private_dirsync_control(const Repl_Agmt *ra)
  320. {
  321. LDAPControl *control = NULL;
  322. BerElement *ber;
  323. Dirsync_Private *dp;
  324. LDAPDebug( LDAP_DEBUG_TRACE, "=> windows_private_dirsync_control\n", 0, 0, 0 );
  325. PR_ASSERT(ra);
  326. dp = (Dirsync_Private *) agmt_get_priv(ra);
  327. PR_ASSERT (dp);
  328. ber = ber_alloc();
  329. ber_printf( ber, "{iio}", dp->dirsync_flags, dp->dirsync_maxattributecount, dp->dirsync_cookie, dp->dirsync_cookie_len );
  330. slapi_build_control( REPL_DIRSYNC_CONTROL_OID, ber, PR_TRUE, &control);
  331. ber_free(ber,1);
  332. LDAPDebug( LDAP_DEBUG_TRACE, "<= windows_private_dirsync_control\n", 0, 0, 0 );
  333. return control;
  334. }
  335. /*
  336. This function scans the array of controls and updates the Repl_Agmt's
  337. Dirsync_Private if the dirsync control is found.
  338. */
  339. void windows_private_update_dirsync_control(const Repl_Agmt *ra,LDAPControl **controls )
  340. {
  341. Dirsync_Private *dp;
  342. int foundDirsyncControl;
  343. int i;
  344. LDAPControl *dirsync;
  345. BerElement *ber;
  346. ber_int_t hasMoreData;
  347. ber_int_t maxAttributeCount;
  348. BerValue *serverCookie;
  349. int return_value = LDAP_SUCCESS;
  350. LDAPDebug( LDAP_DEBUG_TRACE, "=> windows_private_update_dirsync_control\n", 0, 0, 0 );
  351. PR_ASSERT(ra);
  352. dp = (Dirsync_Private *) agmt_get_priv(ra);
  353. PR_ASSERT (dp);
  354. if (NULL != controls )
  355. {
  356. foundDirsyncControl = 0;
  357. for ( i = 0; (( controls[i] != NULL ) && ( !foundDirsyncControl )); i++ ) {
  358. foundDirsyncControl = !strcmp( controls[i]->ldctl_oid, REPL_DIRSYNC_CONTROL_OID );
  359. }
  360. if ( !foundDirsyncControl )
  361. {
  362. return_value = LDAP_CONTROL_NOT_FOUND;
  363. goto choke;
  364. }
  365. else
  366. {
  367. dirsync = slapi_dup_control( controls[i-1]);
  368. }
  369. ber = ber_init( &dirsync->ldctl_value ) ;
  370. if (ber_scanf( ber, "{iiO}", &hasMoreData, &maxAttributeCount, &serverCookie) == LBER_ERROR)
  371. {
  372. return_value = LDAP_CONTROL_NOT_FOUND;
  373. goto choke;
  374. }
  375. slapi_ch_free_string(&dp->dirsync_cookie);
  376. dp->dirsync_cookie = ( char* ) slapi_ch_malloc(serverCookie->bv_len + 1);
  377. memcpy(dp->dirsync_cookie, serverCookie->bv_val, serverCookie->bv_len);
  378. dp->dirsync_cookie_len = (int) serverCookie->bv_len; /* XXX shouldn't cast? */
  379. /* dp->dirsync_maxattributecount = maxAttributeCount; We don't need to keep this */
  380. dp->dirsync_cookie_has_more = hasMoreData;
  381. choke:
  382. ber_bvfree(serverCookie);
  383. ber_free(ber,1);
  384. }
  385. else
  386. {
  387. return_value = LDAP_CONTROL_NOT_FOUND;
  388. }
  389. LDAPDebug( LDAP_DEBUG_TRACE, "<= windows_private_update_dirsync_control\n", 0, 0, 0 );
  390. /* return return_value; */
  391. }
  392. PRBool windows_private_dirsync_has_more(const Repl_Agmt *ra)
  393. {
  394. Dirsync_Private *dp;
  395. LDAPDebug( LDAP_DEBUG_TRACE, "=> windows_private_dirsync_has_more\n", 0, 0, 0 );
  396. PR_ASSERT(ra);
  397. dp = (Dirsync_Private *) agmt_get_priv(ra);
  398. PR_ASSERT (dp);
  399. LDAPDebug( LDAP_DEBUG_TRACE, "<= windows_private_dirsync_has_more\n", 0, 0, 0 );
  400. return dp->dirsync_cookie_has_more;
  401. }
  402. void windows_private_null_dirsync_cookie(const Repl_Agmt *ra)
  403. {
  404. Dirsync_Private *dp;
  405. LDAPDebug( LDAP_DEBUG_TRACE, "=> windows_private_null_dirsync_control\n", 0, 0, 0 );
  406. dp = (Dirsync_Private *) agmt_get_priv(ra);
  407. PR_ASSERT (dp);
  408. dp->dirsync_cookie_len = 0;
  409. slapi_ch_free_string(&dp->dirsync_cookie);
  410. dp->dirsync_cookie = NULL;
  411. LDAPDebug( LDAP_DEBUG_TRACE, "<= windows_private_null_dirsync_control\n", 0, 0, 0 );
  412. }
  413. static
  414. Slapi_Mods *windows_private_get_cookie_mod(Dirsync_Private *dp, int modtype)
  415. {
  416. Slapi_Mods *smods = NULL;
  417. smods = slapi_mods_new();
  418. slapi_mods_add( smods, modtype,
  419. "nsds7DirsyncCookie", dp->dirsync_cookie_len , dp->dirsync_cookie);
  420. return smods;
  421. }
  422. /* writes the current cookie into dse.ldif under the replication agreement entry
  423. returns: ldap result code of the operation. */
  424. int
  425. windows_private_save_dirsync_cookie(const Repl_Agmt *ra)
  426. {
  427. Dirsync_Private *dp = NULL;
  428. Slapi_PBlock *pb = NULL;
  429. const char* dn = NULL;
  430. Slapi_DN* sdn = NULL;
  431. int rc = 0;
  432. Slapi_Mods *mods = NULL;
  433. LDAPDebug( LDAP_DEBUG_TRACE, "=> windows_private_save_dirsync_cookie\n", 0, 0, 0 );
  434. PR_ASSERT(ra);
  435. dp = (Dirsync_Private *) agmt_get_priv(ra);
  436. PR_ASSERT (dp);
  437. pb = slapi_pblock_new ();
  438. mods = windows_private_get_cookie_mod(dp, LDAP_MOD_REPLACE);
  439. sdn = slapi_sdn_dup( agmt_get_dn_byref(ra) );
  440. dn = slapi_sdn_get_dn(sdn);
  441. slapi_modify_internal_set_pb (pb, dn, slapi_mods_get_ldapmods_byref(mods), NULL, NULL,
  442. repl_get_plugin_identity(PLUGIN_MULTIMASTER_REPLICATION), 0);
  443. slapi_modify_internal_pb (pb);
  444. slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_RESULT, &rc);
  445. if (rc == LDAP_NO_SUCH_ATTRIBUTE)
  446. { /* try again, but as an add instead */
  447. mods = windows_private_get_cookie_mod(dp, LDAP_MOD_ADD);
  448. slapi_modify_internal_set_pb (pb, dn, slapi_mods_get_ldapmods_byref(mods), NULL, NULL,
  449. repl_get_plugin_identity(PLUGIN_MULTIMASTER_REPLICATION), 0);
  450. slapi_modify_internal_pb (pb);
  451. slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_RESULT, &rc);
  452. }
  453. slapi_pblock_destroy (pb);
  454. slapi_mods_free(&mods);
  455. slapi_sdn_free(&sdn);
  456. LDAPDebug( LDAP_DEBUG_TRACE, "<= windows_private_save_dirsync_cookie\n", 0, 0, 0 );
  457. return rc;
  458. }
  459. /* reads the cookie in dse.ldif to the replication agreement entry
  460. returns: ldap result code of ldap operation, or
  461. LDAP_NO_SUCH_ATTRIBUTE. (this is the equilivent of a null cookie) */
  462. int windows_private_load_dirsync_cookie(const Repl_Agmt *ra)
  463. {
  464. Dirsync_Private *dp = NULL;
  465. Slapi_PBlock *pb = NULL;
  466. Slapi_DN* sdn = NULL;
  467. int rc = 0;
  468. Slapi_Entry *entry = NULL;
  469. Slapi_Attr *attr = NULL;
  470. LDAPDebug( LDAP_DEBUG_TRACE, "=> windows_private_load_dirsync_cookie\n", 0, 0, 0 );
  471. PR_ASSERT(ra);
  472. dp = (Dirsync_Private *) agmt_get_priv(ra);
  473. PR_ASSERT (dp);
  474. pb = slapi_pblock_new ();
  475. sdn = slapi_sdn_dup( agmt_get_dn_byref(ra) );
  476. rc = slapi_search_internal_get_entry(sdn, NULL, &entry,
  477. repl_get_plugin_identity (PLUGIN_MULTIMASTER_REPLICATION));
  478. if (rc == 0)
  479. {
  480. rc= slapi_entry_attr_find( entry, type_nsds7DirsyncCookie, &attr );
  481. if (attr)
  482. {
  483. struct berval **vals;
  484. rc = slapi_attr_get_bervals_copy(attr, &vals );
  485. if (vals)
  486. {
  487. dp->dirsync_cookie_len = (int) (vals[0])->bv_len;
  488. slapi_ch_free_string(&dp->dirsync_cookie);
  489. dp->dirsync_cookie = ( char* ) slapi_ch_malloc(dp->dirsync_cookie_len + 1);
  490. memcpy(dp->dirsync_cookie,(vals[0]->bv_val), (vals[0])->bv_len+1);
  491. }
  492. ber_bvecfree(vals);
  493. /* we do not free attr */
  494. }
  495. else
  496. {
  497. rc = LDAP_NO_SUCH_ATTRIBUTE;
  498. }
  499. }
  500. if (entry)
  501. {
  502. slapi_entry_free(entry);
  503. }
  504. slapi_sdn_free( &sdn);
  505. slapi_pblock_destroy (pb);
  506. LDAPDebug( LDAP_DEBUG_TRACE, "<= windows_private_load_dirsync_cookie\n", 0, 0, 0 );
  507. return rc;
  508. }