windows_private.c 14 KB

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