windows_private.c 18 KB

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