windows_private.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513
  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. * END COPYRIGHT BLOCK **/
  6. /* windows_private.c */
  7. #include "repl.h"
  8. #include "repl5.h"
  9. #include "slap.h"
  10. #include "slapi-plugin.h"
  11. #include "windowsrepl.h"
  12. struct windowsprivate {
  13. Slapi_DN *windows_subtree; /* DN of synchronized subtree (on the windows side) */
  14. Slapi_DN *directory_subtree; /* DN of synchronized subtree on directory side */
  15. /* this simplifies the mapping as it's simply
  16. from the former to the latter container, or
  17. vice versa */
  18. int dirsync_flags;
  19. int dirsync_maxattributecount;
  20. char *dirsync_cookie;
  21. int dirsync_cookie_len;
  22. PRBool dirsync_cookie_has_more;
  23. PRBool create_users_from_dirsync;
  24. PRBool create_groups_from_dirsync;
  25. char *windows_domain;
  26. };
  27. void
  28. windows_init_agreement_from_entry(Repl_Agmt *ra, Slapi_Entry *e)
  29. {
  30. char *tmpstr = NULL;
  31. agmt_set_priv(ra,windows_private_new());
  32. /* DN of entry at root of replicated area */
  33. tmpstr = slapi_entry_attr_get_charptr(e, type_nsds7WindowsReplicaArea);
  34. if (NULL != tmpstr)
  35. {
  36. windows_private_set_windows_subtree(ra, slapi_sdn_new_dn_passin(tmpstr) );
  37. }
  38. tmpstr = slapi_entry_attr_get_charptr(e, type_nsds7DirectoryReplicaArea);
  39. if (NULL != tmpstr)
  40. {
  41. windows_private_set_directory_subtree(ra, slapi_sdn_new_dn_passin(tmpstr) );
  42. }
  43. tmpstr = slapi_entry_attr_get_charptr(e, type_nsds7CreateNewUsers);
  44. if (NULL != tmpstr)
  45. {
  46. windows_private_set_create_users(ra, PR_TRUE);
  47. slapi_ch_free((void**)&tmpstr);
  48. }
  49. else
  50. {
  51. windows_private_set_create_users(ra, PR_FALSE);
  52. }
  53. tmpstr = slapi_entry_attr_get_charptr(e, type_nsds7WindowsDomain);
  54. if (NULL != tmpstr)
  55. {
  56. windows_private_set_windows_domain(ra,tmpstr);
  57. }
  58. }
  59. Dirsync_Private* windows_private_new()
  60. {
  61. Dirsync_Private *dp;
  62. LDAPDebug( LDAP_DEBUG_TRACE, "=> windows_private_new\n", 0, 0, 0 );
  63. dp = (Dirsync_Private *)slapi_ch_calloc(sizeof(Dirsync_Private),1);
  64. dp->dirsync_maxattributecount = -1;
  65. dp->create_users_from_dirsync = PR_TRUE;
  66. LDAPDebug( LDAP_DEBUG_TRACE, "<= windows_private_new\n", 0, 0, 0 );
  67. return dp;
  68. }
  69. void windows_agreement_delete(Repl_Agmt *ra)
  70. {
  71. Dirsync_Private *dp = (Dirsync_Private *) agmt_get_priv(ra);
  72. LDAPDebug( LDAP_DEBUG_TRACE, "=> windows_private_delete\n", 0, 0, 0 );
  73. PR_ASSERT(dp != NULL);
  74. /* DBDB: need to free payoad here */
  75. slapi_ch_free((void **)dp);
  76. LDAPDebug( LDAP_DEBUG_TRACE, "<= windows_private_delete\n", 0, 0, 0 );
  77. }
  78. /* Returns a copy of the Slapi_DN pointer, no need to free it */
  79. const Slapi_DN* windows_private_get_windows_subtree (const Repl_Agmt *ra)
  80. {
  81. Dirsync_Private *dp;
  82. LDAPDebug( LDAP_DEBUG_TRACE, "=> windows_private_get_windows_subtree\n", 0, 0, 0 );
  83. PR_ASSERT(ra);
  84. dp = (Dirsync_Private *) agmt_get_priv(ra);
  85. PR_ASSERT (dp);
  86. LDAPDebug( LDAP_DEBUG_TRACE, "<= windows_private_get_windows_subtree\n", 0, 0, 0 );
  87. return dp->windows_subtree;
  88. }
  89. const char *
  90. windows_private_get_windows_domain(const Repl_Agmt *ra)
  91. {
  92. Dirsync_Private *dp;
  93. LDAPDebug( LDAP_DEBUG_TRACE, "=> windows_private_get_windows_domain\n", 0, 0, 0 );
  94. PR_ASSERT(ra);
  95. dp = (Dirsync_Private *) agmt_get_priv(ra);
  96. PR_ASSERT (dp);
  97. LDAPDebug( LDAP_DEBUG_TRACE, "<= windows_private_get_windows_domain\n", 0, 0, 0 );
  98. return dp->windows_domain;
  99. }
  100. static void
  101. windows_private_set_windows_domain(const Repl_Agmt *ra, char *domain)
  102. {
  103. Dirsync_Private *dp;
  104. LDAPDebug( LDAP_DEBUG_TRACE, "=> windows_private_set_windows_domain\n", 0, 0, 0 );
  105. PR_ASSERT(ra);
  106. dp = (Dirsync_Private *) agmt_get_priv(ra);
  107. PR_ASSERT (dp);
  108. dp->windows_domain = domain;
  109. LDAPDebug( LDAP_DEBUG_TRACE, "<= windows_private_set_windows_domain\n", 0, 0, 0 );
  110. }
  111. /* Returns a copy of the Slapi_DN pointer, no need to free it */
  112. const Slapi_DN* windows_private_get_directory_subtree (const Repl_Agmt *ra)
  113. {
  114. Dirsync_Private *dp;
  115. LDAPDebug( LDAP_DEBUG_TRACE, "=> windows_private_get_directory_replarea\n", 0, 0, 0 );
  116. PR_ASSERT(ra);
  117. dp = (Dirsync_Private *) agmt_get_priv(ra);
  118. PR_ASSERT (dp);
  119. LDAPDebug( LDAP_DEBUG_TRACE, "<= windows_private_get_directory_replarea\n", 0, 0, 0 );
  120. return dp->directory_subtree;
  121. }
  122. /* Takes a copy of the sdn passed in */
  123. void windows_private_set_windows_subtree (const Repl_Agmt *ra,const Slapi_DN* sdn )
  124. {
  125. Dirsync_Private *dp;
  126. LDAPDebug( LDAP_DEBUG_TRACE, "=> windows_private_set_windows_replarea\n", 0, 0, 0 );
  127. PR_ASSERT(ra);
  128. PR_ASSERT(sdn);
  129. dp = (Dirsync_Private *) agmt_get_priv(ra);
  130. PR_ASSERT (dp);
  131. dp->windows_subtree = slapi_sdn_dup(sdn);
  132. LDAPDebug( LDAP_DEBUG_TRACE, "<= windows_private_set_windows_replarea\n", 0, 0, 0 );
  133. }
  134. /* Takes a copy of the sdn passed in */
  135. void windows_private_set_directory_subtree (const Repl_Agmt *ra,const Slapi_DN* sdn )
  136. {
  137. Dirsync_Private *dp;
  138. LDAPDebug( LDAP_DEBUG_TRACE, "=> windows_private_set_directory_replarea\n", 0, 0, 0 );
  139. PR_ASSERT(ra);
  140. PR_ASSERT(sdn);
  141. dp = (Dirsync_Private *) agmt_get_priv(ra);
  142. PR_ASSERT (dp);
  143. dp->directory_subtree = slapi_sdn_dup(sdn);
  144. LDAPDebug( LDAP_DEBUG_TRACE, "<= windows_private_set_directory_replarea\n", 0, 0, 0 );
  145. }
  146. PRBool windows_private_create_users(const Repl_Agmt *ra)
  147. {
  148. Dirsync_Private *dp;
  149. LDAPDebug( LDAP_DEBUG_TRACE, "=> windows_private_create_users\n", 0, 0, 0 );
  150. PR_ASSERT(ra);
  151. dp = (Dirsync_Private *) agmt_get_priv(ra);
  152. PR_ASSERT (dp);
  153. LDAPDebug( LDAP_DEBUG_TRACE, "<= windows_private_create_users\n", 0, 0, 0 );
  154. return dp->create_users_from_dirsync;
  155. }
  156. void windows_private_set_create_users(const Repl_Agmt *ra, PRBool value)
  157. {
  158. Dirsync_Private *dp;
  159. LDAPDebug( LDAP_DEBUG_TRACE, "=> windows_private_set_create_users\n", 0, 0, 0 );
  160. PR_ASSERT(ra);
  161. dp = (Dirsync_Private *) agmt_get_priv(ra);
  162. PR_ASSERT (dp);
  163. dp->create_users_from_dirsync = value;
  164. LDAPDebug( LDAP_DEBUG_TRACE, "<= windows_private_set_create_users\n", 0, 0, 0 );
  165. }
  166. /*
  167. This function returns the current Dirsync_Private that's inside
  168. Repl_Agmt ra as a ldap control.
  169. */
  170. LDAPControl* windows_private_dirsync_control(const Repl_Agmt *ra)
  171. {
  172. LDAPControl *control = NULL;
  173. LDAPControl **lc = &control ;
  174. BerElement *ber;
  175. Dirsync_Private *dp;
  176. LDAPDebug( LDAP_DEBUG_TRACE, "=> windows_private_dirsync_control\n", 0, 0, 0 );
  177. PR_ASSERT(ra);
  178. dp = (Dirsync_Private *) agmt_get_priv(ra);
  179. PR_ASSERT (dp);
  180. ber = ber_alloc();
  181. ber_printf( ber, "{iio}", dp->dirsync_flags, dp->dirsync_maxattributecount, dp->dirsync_cookie, dp->dirsync_cookie_len );
  182. slapi_build_control( REPL_DIRSYNC_CONTROL_OID, ber, PR_TRUE, &control);
  183. ber_free(ber,1);
  184. LDAPDebug( LDAP_DEBUG_TRACE, "<= windows_private_dirsync_control\n", 0, 0, 0 );
  185. return control;
  186. }
  187. /*
  188. This function scans the array of controls and updates the Repl_Agmt's
  189. Dirsync_Private if the dirsync control is found.
  190. */
  191. void windows_private_update_dirsync_control(const Repl_Agmt *ra,LDAPControl **controls )
  192. {
  193. Dirsync_Private *dp;
  194. int foundDirsyncControl;
  195. int i;
  196. LDAPControl *dirsync;
  197. BerElement *ber;
  198. int hasMoreData;
  199. int maxAttributeCount;
  200. BerValue *serverCookie;
  201. int return_value = LDAP_SUCCESS;
  202. LDAPDebug( LDAP_DEBUG_TRACE, "=> windows_private_update_dirsync_control\n", 0, 0, 0 );
  203. PR_ASSERT(ra);
  204. dp = (Dirsync_Private *) agmt_get_priv(ra);
  205. PR_ASSERT (dp);
  206. if (NULL != controls )
  207. {
  208. foundDirsyncControl = 0;
  209. for ( i = 0; (( controls[i] != NULL ) && ( !foundDirsyncControl )); i++ ) {
  210. foundDirsyncControl = !strcmp( controls[i]->ldctl_oid, REPL_DIRSYNC_CONTROL_OID );
  211. }
  212. if ( !foundDirsyncControl )
  213. {
  214. return_value = LDAP_CONTROL_NOT_FOUND;
  215. goto choke;
  216. }
  217. else
  218. {
  219. dirsync = slapi_dup_control( controls[i-1]);
  220. }
  221. ber = ber_init( &dirsync->ldctl_value ) ;
  222. if (ber_scanf( ber, "{iiO}", &hasMoreData, &maxAttributeCount, &serverCookie) == LBER_ERROR)
  223. {
  224. return_value = LDAP_CONTROL_NOT_FOUND;
  225. goto choke;
  226. }
  227. slapi_ch_free(&dp->dirsync_cookie);
  228. dp->dirsync_cookie = ( char* ) slapi_ch_malloc(serverCookie->bv_len + 1);
  229. memcpy(dp->dirsync_cookie, serverCookie->bv_val, serverCookie->bv_len);
  230. dp->dirsync_cookie_len = (int) serverCookie->bv_len; /* XXX shouldn't cast? */
  231. /* dp->dirsync_maxattributecount = maxAttributeCount; We don't need to keep this */
  232. dp->dirsync_cookie_has_more = hasMoreData;
  233. choke:
  234. ber_bvfree(serverCookie);
  235. ber_free(ber,1);
  236. }
  237. else
  238. {
  239. return_value = LDAP_CONTROL_NOT_FOUND;
  240. }
  241. LDAPDebug( LDAP_DEBUG_TRACE, "<= windows_private_update_dirsync_control\n", 0, 0, 0 );
  242. /* return return_value; */
  243. }
  244. PRBool windows_private_dirsync_has_more(const Repl_Agmt *ra)
  245. {
  246. Dirsync_Private *dp;
  247. LDAPDebug( LDAP_DEBUG_TRACE, "=> windows_private_dirsync_has_more\n", 0, 0, 0 );
  248. PR_ASSERT(ra);
  249. dp = (Dirsync_Private *) agmt_get_priv(ra);
  250. PR_ASSERT (dp);
  251. LDAPDebug( LDAP_DEBUG_TRACE, "<= windows_private_dirsync_has_more\n", 0, 0, 0 );
  252. return dp->dirsync_cookie_has_more;
  253. }
  254. void windows_private_null_dirsync_cookie(const Repl_Agmt *ra)
  255. {
  256. Dirsync_Private *dp;
  257. LDAPDebug( LDAP_DEBUG_TRACE, "=> windows_private_null_dirsync_control\n", 0, 0, 0 );
  258. dp = (Dirsync_Private *) agmt_get_priv(ra);
  259. PR_ASSERT (dp);
  260. dp->dirsync_cookie_len = 0;
  261. slapi_ch_free(&dp->dirsync_cookie);
  262. dp->dirsync_cookie = NULL;
  263. LDAPDebug( LDAP_DEBUG_TRACE, "<= windows_private_null_dirsync_control\n", 0, 0, 0 );
  264. }
  265. static
  266. Slapi_Mods *windows_private_get_cookie_mod(Dirsync_Private *dp, int modtype)
  267. {
  268. Slapi_Mods *smods = NULL;
  269. smods = slapi_mods_new();
  270. slapi_mods_add( smods, modtype,
  271. "nsds7DirsyncCookie", dp->dirsync_cookie_len , dp->dirsync_cookie);
  272. return smods;
  273. }
  274. /* writes the current cookie into dse.ldif under the replication agreement entry
  275. returns: ldap result code of the operation. */
  276. int
  277. windows_private_save_dirsync_cookie(const Repl_Agmt *ra)
  278. {
  279. Dirsync_Private *dp = NULL;
  280. Slapi_PBlock *pb = NULL;
  281. const char* dn = NULL;
  282. Slapi_DN* sdn = NULL;
  283. int rc = 0;
  284. Slapi_Mods *mods = NULL;
  285. LDAPDebug( LDAP_DEBUG_TRACE, "=> windows_private_save_dirsync_cookie\n", 0, 0, 0 );
  286. PR_ASSERT(ra);
  287. dp = (Dirsync_Private *) agmt_get_priv(ra);
  288. PR_ASSERT (dp);
  289. pb = slapi_pblock_new ();
  290. mods = windows_private_get_cookie_mod(dp, LDAP_MOD_REPLACE);
  291. sdn = slapi_sdn_dup( agmt_get_dn_byref(ra) );
  292. dn = slapi_sdn_get_dn(sdn);
  293. slapi_modify_internal_set_pb (pb, dn, slapi_mods_get_ldapmods_byref(mods), NULL, NULL,
  294. repl_get_plugin_identity(PLUGIN_MULTIMASTER_REPLICATION), 0);
  295. slapi_modify_internal_pb (pb);
  296. slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_RESULT, &rc);
  297. if (rc == LDAP_NO_SUCH_ATTRIBUTE)
  298. { /* try again, but as an add instead */
  299. mods = windows_private_get_cookie_mod(dp, LDAP_MOD_ADD);
  300. slapi_modify_internal_set_pb (pb, dn, slapi_mods_get_ldapmods_byref(mods), NULL, NULL,
  301. repl_get_plugin_identity(PLUGIN_MULTIMASTER_REPLICATION), 0);
  302. slapi_modify_internal_pb (pb);
  303. slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_RESULT, &rc);
  304. }
  305. slapi_pblock_destroy (pb);
  306. slapi_mods_free(&mods);
  307. slapi_sdn_free(&sdn);
  308. LDAPDebug( LDAP_DEBUG_TRACE, "<= windows_private_save_dirsync_cookie\n", 0, 0, 0 );
  309. return rc;
  310. }
  311. /* reads the cookie in dse.ldif to the replication agreement entry
  312. returns: ldap result code of ldap operation, or
  313. LDAP_NO_SUCH_ATTRIBUTE. (this is the equilivent of a null cookie) */
  314. int windows_private_load_dirsync_cookie(const Repl_Agmt *ra)
  315. {
  316. Dirsync_Private *dp = NULL;
  317. Slapi_PBlock *pb = NULL;
  318. Slapi_DN* sdn = NULL;
  319. int rc = 0;
  320. Slapi_Entry *entry = NULL;
  321. char* cookie = NULL;
  322. Slapi_Attr *attr = NULL;
  323. LDAPDebug( LDAP_DEBUG_TRACE, "=> windows_private_load_dirsync_cookie\n", 0, 0, 0 );
  324. PR_ASSERT(ra);
  325. dp = (Dirsync_Private *) agmt_get_priv(ra);
  326. PR_ASSERT (dp);
  327. pb = slapi_pblock_new ();
  328. sdn = slapi_sdn_dup( agmt_get_dn_byref(ra) );
  329. rc = slapi_search_internal_get_entry(sdn, NULL, &entry,
  330. repl_get_plugin_identity (PLUGIN_MULTIMASTER_REPLICATION));
  331. if (rc == 0)
  332. {
  333. rc= slapi_entry_attr_find( entry, type_nsds7DirsyncCookie, &attr );
  334. if (attr)
  335. {
  336. struct berval **vals;
  337. rc = slapi_attr_get_bervals_copy(attr, &vals );
  338. if (vals)
  339. {
  340. dp->dirsync_cookie_len = (int) (vals[0])->bv_len;
  341. slapi_ch_free(&dp->dirsync_cookie);
  342. dp->dirsync_cookie = ( char* ) slapi_ch_malloc(dp->dirsync_cookie_len + 1);
  343. memcpy(dp->dirsync_cookie,(vals[0]->bv_val), (vals[0])->bv_len+1);
  344. }
  345. ber_bvecfree(vals);
  346. /* we do not free attr */
  347. }
  348. else
  349. {
  350. rc = LDAP_NO_SUCH_ATTRIBUTE;
  351. }
  352. }
  353. if (entry)
  354. {
  355. slapi_entry_free(entry);
  356. }
  357. slapi_sdn_free( &sdn);
  358. slapi_pblock_destroy (pb);
  359. LDAPDebug( LDAP_DEBUG_TRACE, "<= windows_private_load_dirsync_cookie\n", 0, 0, 0 );
  360. return rc;
  361. }