sync_util.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702
  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) 2013 Red Hat, Inc.
  35. * All rights reserved.
  36. * END COPYRIGHT BLOCK **/
  37. #include "sync.h"
  38. static struct berval * create_syncinfo_value( int type, const char *cookie, const char **uuids);
  39. static char * sync_cookie_get_server_info(Slapi_PBlock *pb);
  40. static char * sync_cookie_get_client_info(Slapi_PBlock *pb);
  41. /*
  42. * Parse the value from an LDAPv3 sync request control. They look
  43. * like this:
  44. *
  45. * syncRequestValue ::= SEQUENCE {
  46. * mode ENUMERATED {
  47. * -- 0 unused
  48. * refreshOnly (1),
  49. * -- 2 reserved
  50. * refreshAndPersist (3)
  51. * },
  52. * cookie syncCookie OPTIONAL,
  53. * reloadHint BOOLEAN DEFAULT FALSE
  54. * }
  55. *
  56. * Return an LDAP error code (LDAP_SUCCESS if all goes well).
  57. *
  58. */
  59. int
  60. sync_parse_control_value( struct berval *psbvp, ber_int_t *mode, int *reload, char **cookie )
  61. {
  62. int rc= LDAP_SUCCESS;
  63. if ( psbvp->bv_len == 0 || psbvp->bv_val == NULL )
  64. {
  65. rc= LDAP_PROTOCOL_ERROR;
  66. }
  67. else
  68. {
  69. BerElement *ber= ber_init( psbvp );
  70. if ( ber == NULL )
  71. {
  72. rc= LDAP_OPERATIONS_ERROR;
  73. }
  74. else
  75. {
  76. if ( ber_scanf( ber, "{e", mode ) == LBER_ERROR )
  77. {
  78. rc= LDAP_PROTOCOL_ERROR;
  79. } else {
  80. ber_tag_t tag;
  81. ber_len_t len;
  82. tag = ber_peek_tag( ber, &len );
  83. if ( tag == LDAP_TAG_SYNC_COOKIE ) {
  84. rc = ber_scanf( ber, "a", cookie );
  85. tag = ber_peek_tag( ber, &len );
  86. }
  87. if (rc != LBER_ERROR && tag == LDAP_TAG_RELOAD_HINT ) {
  88. rc = ber_scanf( ber, "b", reload );
  89. }
  90. if (rc != LBER_ERROR) {
  91. rc = ber_scanf( ber, "}");
  92. }
  93. if (rc == LBER_ERROR) {
  94. rc= LDAP_PROTOCOL_ERROR;
  95. };
  96. }
  97. /* the ber encoding is no longer needed */
  98. ber_free(ber,1);
  99. }
  100. }
  101. return( rc );
  102. }
  103. char *
  104. sync_nsuniqueid2uuid(const char *nsuniqueid)
  105. {
  106. char *uuid;
  107. char u[17];
  108. u[0] = slapi_str_to_u8(nsuniqueid);
  109. u[1] = slapi_str_to_u8(nsuniqueid+2);
  110. u[2] = slapi_str_to_u8(nsuniqueid+4);
  111. u[3] = slapi_str_to_u8(nsuniqueid+6);
  112. u[4] = slapi_str_to_u8(nsuniqueid+9);
  113. u[5] = slapi_str_to_u8(nsuniqueid+11);
  114. u[6] = slapi_str_to_u8(nsuniqueid+13);
  115. u[7] = slapi_str_to_u8(nsuniqueid+15);
  116. u[8] = slapi_str_to_u8(nsuniqueid+18);
  117. u[9] = slapi_str_to_u8(nsuniqueid+20);
  118. u[10] = slapi_str_to_u8(nsuniqueid+22);
  119. u[11] = slapi_str_to_u8(nsuniqueid+24);
  120. u[12] = slapi_str_to_u8(nsuniqueid+27);
  121. u[13] = slapi_str_to_u8(nsuniqueid+29);
  122. u[14] = slapi_str_to_u8(nsuniqueid+31);
  123. u[15] = slapi_str_to_u8(nsuniqueid+33);
  124. u[16] = '\0';
  125. uuid = slapi_ch_smprintf("%s",(char *)u);
  126. return(uuid);
  127. }
  128. /*
  129. * syncStateValue ::= SEQUENCE {
  130. * state ENUMERATED {
  131. * present (0),
  132. * add (1),
  133. * modify (2),
  134. * delete (3)
  135. * },
  136. * entryUUID syncUUID,
  137. * cookie syncCookie OPTIONAL
  138. * }
  139. *
  140. */
  141. int
  142. sync_create_state_control( Slapi_Entry *e, LDAPControl **ctrlp, int type, Sync_Cookie *cookie)
  143. {
  144. int rc;
  145. BerElement *ber;
  146. struct berval *bvp;
  147. char *uuid;
  148. Slapi_Attr *attr;
  149. Slapi_Value *val;
  150. if ( type == LDAP_SYNC_NONE || ctrlp == NULL || ( ber = der_alloc()) == NULL ) {
  151. return( LDAP_OPERATIONS_ERROR );
  152. }
  153. *ctrlp = NULL;
  154. slapi_entry_attr_find(e, SLAPI_ATTR_UNIQUEID, &attr);
  155. slapi_attr_first_value(attr, &val);
  156. uuid = sync_nsuniqueid2uuid(slapi_value_get_string(val));
  157. if (( rc = ber_printf( ber, "{eo", type , uuid, 16 )) != -1 ) {
  158. if (cookie) {
  159. char *cookiestr = sync_cookie2str(cookie);
  160. rc = ber_printf( ber, "s}", cookiestr);
  161. slapi_ch_free((void **)&cookiestr);
  162. } else {
  163. rc = ber_printf( ber, "}");
  164. }
  165. }
  166. if (rc != -1) {
  167. rc = ber_flatten( ber, &bvp );
  168. }
  169. ber_free( ber, 1 );
  170. slapi_ch_free((void **)&uuid);
  171. if ( rc == -1 ) {
  172. return( LDAP_OPERATIONS_ERROR );
  173. }
  174. *ctrlp = (LDAPControl *)slapi_ch_malloc( sizeof( LDAPControl ));
  175. (*ctrlp)->ldctl_iscritical = 0;
  176. (*ctrlp)->ldctl_oid = slapi_ch_strdup( LDAP_CONTROL_SYNC_STATE );
  177. (*ctrlp)->ldctl_value = *bvp; /* struct copy */
  178. bvp->bv_val = NULL;
  179. ber_bvfree( bvp );
  180. return (LDAP_SUCCESS);
  181. }
  182. /*
  183. * syncDoneValue ::= SEQUENCE {
  184. * cookie syncCookie OPTIONAL
  185. * refreshDeletes BOOLEAN DEFAULT FALSE
  186. * }
  187. *
  188. */
  189. int
  190. sync_create_sync_done_control( LDAPControl **ctrlp, int refresh, char *cookie)
  191. {
  192. int rc;
  193. BerElement *ber;
  194. struct berval *bvp;
  195. if ( ctrlp == NULL || ( ber = der_alloc()) == NULL ) {
  196. return( LDAP_OPERATIONS_ERROR );
  197. }
  198. *ctrlp = NULL;
  199. if (cookie) {
  200. if (( rc = ber_printf( ber, "{s", cookie)) != -1 ) {
  201. if (refresh) {
  202. rc = ber_printf( ber, "e}", refresh);
  203. } else {
  204. rc = ber_printf( ber, "}");
  205. }
  206. }
  207. } else {
  208. if (refresh) {
  209. rc = ber_printf( ber, "{e}", refresh);
  210. } else {
  211. rc = ber_printf( ber, "{}");
  212. }
  213. }
  214. if (rc != -1) {
  215. rc = ber_flatten( ber, &bvp );
  216. }
  217. ber_free( ber, 1 );
  218. if ( rc == -1 ) {
  219. return( LDAP_OPERATIONS_ERROR );
  220. }
  221. *ctrlp = (LDAPControl *)slapi_ch_malloc( sizeof( LDAPControl ));
  222. (*ctrlp)->ldctl_iscritical = 0;
  223. (*ctrlp)->ldctl_oid = slapi_ch_strdup( LDAP_CONTROL_SYNC_DONE );
  224. (*ctrlp)->ldctl_value = *bvp; /* struct copy */
  225. bvp->bv_val = NULL;
  226. ber_bvfree( bvp );
  227. return (LDAP_SUCCESS);
  228. }
  229. char *
  230. sync_cookie2str(Sync_Cookie *cookie)
  231. {
  232. char *cookiestr = NULL;
  233. if (cookie) {
  234. cookiestr = slapi_ch_smprintf("%s#%s#%d",
  235. cookie->cookie_server_signature,
  236. cookie->cookie_client_signature,
  237. cookie->cookie_change_info);
  238. }
  239. return(cookiestr);
  240. }
  241. int
  242. sync_intermediate_msg (Slapi_PBlock *pb, int tag, Sync_Cookie *cookie, char **uuids)
  243. {
  244. int rc;
  245. struct berval *syncInfo;
  246. LDAPControl *ctrlp = NULL;
  247. char *cookiestr = sync_cookie2str(cookie);
  248. syncInfo = create_syncinfo_value(tag, cookiestr, (const char **)uuids);
  249. rc = slapi_send_ldap_intermediate( pb, &ctrlp, LDAP_SYNC_INFO, syncInfo);
  250. slapi_ch_free((void **)&cookiestr);
  251. ber_bvfree(syncInfo);
  252. return (rc);
  253. }
  254. int sync_result_msg (Slapi_PBlock *pb, Sync_Cookie *cookie)
  255. {
  256. int rc = 0;
  257. char *cookiestr = sync_cookie2str(cookie);
  258. LDAPControl **ctrl = (LDAPControl **)slapi_ch_calloc(2, sizeof (LDAPControl *));
  259. sync_create_sync_done_control( &ctrl[0], 0, cookiestr);
  260. slapi_pblock_set(pb, SLAPI_RESCONTROLS, ctrl);
  261. slapi_send_ldap_result(pb, 0, NULL, NULL, 0, NULL );
  262. slapi_ch_free((void **)&cookiestr);
  263. return (rc);
  264. }
  265. int sync_result_err (Slapi_PBlock *pb, int err, char *msg)
  266. {
  267. int rc = 0;
  268. slapi_send_ldap_result(pb, err, NULL, msg, 0, NULL );
  269. return (rc);
  270. }
  271. static struct berval *
  272. create_syncinfo_value( int type, const char *cookie, const char **uuids)
  273. {
  274. BerElement *ber;
  275. struct berval *bvp = NULL;
  276. if ( ( ber = der_alloc() ) == NULL ) {
  277. return( NULL );
  278. }
  279. switch (type) {
  280. case LDAP_TAG_SYNC_NEW_COOKIE:
  281. ber_printf(ber, "to", type, cookie);
  282. break;
  283. case LDAP_TAG_SYNC_REFRESH_DELETE:
  284. case LDAP_TAG_SYNC_REFRESH_PRESENT:
  285. ber_printf(ber, "t{", type);
  286. if (cookie)
  287. ber_printf(ber, "s", cookie);
  288. /* ber_printf(ber, "b",1); */
  289. ber_printf(ber, "}");
  290. break;
  291. case LDAP_TAG_SYNC_ID_SET:
  292. ber_printf(ber, "t{", type);
  293. if (cookie)
  294. ber_printf(ber, "s", cookie);
  295. if (uuids)
  296. ber_printf(ber, "b[v]", 1, uuids);
  297. ber_printf(ber, "}");
  298. break;
  299. default:
  300. break;
  301. }
  302. ber_flatten( ber, &bvp );
  303. ber_free( ber, 1 );
  304. return( bvp );
  305. }
  306. static int
  307. sync_handle_cnum_entry(Slapi_Entry *e, void *cb_data)
  308. {
  309. int rc = 0;
  310. Sync_CallBackData *cb = (Sync_CallBackData *)cb_data;
  311. Slapi_Value *sval=NULL;
  312. const struct berval *value;
  313. cb->changenr = 0;
  314. if ( NULL != e ) {
  315. Slapi_Attr *chattr = NULL;
  316. sval = NULL;
  317. value = NULL;
  318. if ( slapi_entry_attr_find( e, CL_ATTR_CHANGENUMBER, &chattr ) == 0 ) {
  319. slapi_attr_first_value( chattr,&sval );
  320. if ( NULL != sval ) {
  321. value = slapi_value_get_berval ( sval );
  322. if( NULL != value && NULL != value->bv_val &&
  323. '\0' != value->bv_val[0]) {
  324. cb->changenr = sync_number2int(value->bv_val);
  325. }
  326. }
  327. }
  328. }
  329. return (rc);
  330. }
  331. /*
  332. * a cookie is used to synchronize client server sessions,
  333. * it consist of three parts
  334. * -- server id, client should only sync with one server
  335. * -- client id, client should use same bind dn, and srch params
  336. * -- change info, kind of state info like csn, ruv,
  337. * in the first implementation use changenumber from retro cl
  338. *
  339. * syntax: <server-id>#<client-id>#change
  340. *
  341. */
  342. static char *
  343. sync_cookie_get_server_info(Slapi_PBlock *pb)
  344. {
  345. char *info_enc;
  346. int rc = 0;
  347. Slapi_Entry **entries;
  348. Slapi_PBlock *srch_pb = NULL;
  349. char *host = NULL;
  350. char *port = NULL;
  351. char *server_attrs[] = {"nsslapd-localhost", "nsslapd-port", NULL};
  352. srch_pb = slapi_pblock_new ();
  353. slapi_search_internal_set_pb (srch_pb, "cn=config", LDAP_SCOPE_BASE,
  354. "objectclass=*", server_attrs, 0, NULL, NULL,
  355. plugin_get_default_component_id(), 0);
  356. slapi_search_internal_pb (srch_pb);
  357. slapi_pblock_get(srch_pb, SLAPI_PLUGIN_INTOP_RESULT, &rc);
  358. if (rc != 0)
  359. {
  360. slapi_log_error(SLAPI_LOG_FATAL, SYNC_PLUGIN_SUBSYSTEM, "sync_cookie_get_server_info: "
  361. "unable to read server configuration: error %d\n", rc);
  362. }
  363. else
  364. {
  365. slapi_pblock_get(srch_pb, SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES, &entries);
  366. if (NULL == entries || NULL == entries[0])
  367. {
  368. slapi_log_error(SLAPI_LOG_FATAL, SYNC_PLUGIN_SUBSYSTEM, "sync_cookie_get_server_info: "
  369. "server configuration missing\n");
  370. rc = -1;
  371. }
  372. else
  373. {
  374. host = slapi_entry_attr_get_charptr(entries[0], "nsslapd-localhost");
  375. port = slapi_entry_attr_get_charptr(entries[0], "nsslapd-port");
  376. }
  377. }
  378. info_enc = slapi_ch_smprintf("%s:%s",host?host:"nohost",port?port:"noport");
  379. slapi_ch_free ((void**)&host);
  380. slapi_ch_free ((void**)&port);
  381. slapi_free_search_results_internal(srch_pb);
  382. slapi_pblock_destroy (srch_pb);
  383. return(info_enc);
  384. }
  385. static char *
  386. sync_cookie_get_client_info(Slapi_PBlock *pb)
  387. {
  388. char *targetdn;
  389. char *strfilter;
  390. char *clientdn;
  391. char *clientinfo;
  392. slapi_pblock_get(pb, SLAPI_TARGET_DN, &targetdn);
  393. slapi_pblock_get(pb, SLAPI_SEARCH_STRFILTER, &strfilter);
  394. slapi_pblock_get(pb, SLAPI_REQUESTOR_DN, &clientdn);
  395. clientinfo = slapi_ch_smprintf("%s:%s:%s",clientdn,targetdn,strfilter);
  396. return (clientinfo);
  397. }
  398. static int
  399. sync_cookie_get_change_number(int lastnr, const char *uniqueid)
  400. {
  401. Slapi_PBlock *srch_pb;
  402. Slapi_Entry **entries;
  403. Slapi_Entry *cl_entry;
  404. int rv;
  405. int newnr = -1;
  406. char *filter = slapi_ch_smprintf("(&(changenumber>=%d)(targetuniqueid=%s))",lastnr,uniqueid);
  407. srch_pb = slapi_pblock_new();
  408. slapi_search_internal_set_pb(srch_pb, CL_SRCH_BASE,
  409. LDAP_SCOPE_SUBTREE, filter,
  410. NULL, 0, NULL, NULL, plugin_get_default_component_id(), 0);
  411. slapi_search_internal_pb(srch_pb);
  412. slapi_pblock_get(srch_pb, SLAPI_PLUGIN_INTOP_RESULT, &rv);
  413. if ( rv == LDAP_SUCCESS) {
  414. slapi_pblock_get(srch_pb, SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES, &entries);
  415. if (entries && *entries) {
  416. Slapi_Attr *attr;
  417. Slapi_Value *val;
  418. cl_entry = *entries; /* only use teh first one */
  419. slapi_entry_attr_find(cl_entry, CL_ATTR_CHANGENUMBER, &attr);
  420. slapi_attr_first_value(attr, &val);
  421. newnr = sync_number2int((char *)slapi_value_get_string(val));
  422. }
  423. }
  424. slapi_free_search_results_internal(srch_pb);
  425. slapi_pblock_destroy(srch_pb);
  426. slapi_ch_free((void **)&filter);
  427. return (newnr);
  428. }
  429. static int
  430. sync_cookie_get_change_info(Sync_CallBackData *scbd)
  431. {
  432. Slapi_PBlock *seq_pb;
  433. char *base;
  434. char *attrname;
  435. int rc;
  436. base = slapi_ch_strdup("cn=changelog");
  437. attrname = slapi_ch_strdup("changenumber");
  438. seq_pb = slapi_pblock_new();
  439. slapi_pblock_init(seq_pb);
  440. slapi_seq_internal_set_pb(seq_pb, base, SLAPI_SEQ_LAST, attrname, NULL, NULL, 0, 0,
  441. plugin_get_default_component_id(), 0);
  442. rc = slapi_seq_internal_callback_pb (seq_pb, scbd, NULL, sync_handle_cnum_entry, NULL);
  443. slapi_pblock_destroy(seq_pb);
  444. slapi_ch_free((void **)&attrname);
  445. slapi_ch_free((void **)&base);
  446. return (rc);
  447. }
  448. Sync_Cookie *
  449. sync_cookie_create (Slapi_PBlock *pb)
  450. {
  451. Sync_CallBackData scbd;
  452. int rc;
  453. Sync_Cookie *sc = (Sync_Cookie *)slapi_ch_malloc(sizeof(Sync_Cookie));
  454. rc = sync_cookie_get_change_info (&scbd);
  455. if (rc == 0) {
  456. sc->cookie_server_signature = sync_cookie_get_server_info(pb);
  457. sc->cookie_client_signature = sync_cookie_get_client_info(pb);
  458. sc->cookie_change_info = scbd.changenr;
  459. } else {
  460. slapi_ch_free ((void **)&sc);
  461. sc = NULL;
  462. }
  463. return (sc);
  464. }
  465. void sync_cookie_update (Sync_Cookie *sc, Slapi_Entry *ec)
  466. {
  467. const char *uniqueid = NULL;
  468. Slapi_Attr *attr;
  469. Slapi_Value *val;
  470. slapi_entry_attr_find(ec, SLAPI_ATTR_UNIQUEID, &attr);
  471. slapi_attr_first_value(attr, &val);
  472. uniqueid = slapi_value_get_string(val);
  473. sc->cookie_change_info = sync_cookie_get_change_number (sc->cookie_change_info, uniqueid);
  474. }
  475. Sync_Cookie *
  476. sync_cookie_parse (char *cookie)
  477. {
  478. char *p, *q;
  479. Sync_Cookie *sc;
  480. if (cookie == NULL || *cookie == '\0' ) {
  481. return NULL;
  482. }
  483. p = q = cookie;
  484. sc = (Sync_Cookie *)slapi_ch_malloc(sizeof(Sync_Cookie));
  485. sc->cookie_client_signature = NULL;
  486. sc->cookie_server_signature = NULL;
  487. sc->cookie_change_info = -1;
  488. p = strchr(q, '#');
  489. if (p) {
  490. *p = '\0';
  491. sc->cookie_server_signature = slapi_ch_strdup(q);
  492. q = p + 1;
  493. p = strchr(q, '#');
  494. if (p) {
  495. *p = '\0';
  496. sc->cookie_client_signature = slapi_ch_strdup(q);
  497. sc->cookie_change_info = sync_number2int(p+1);
  498. }
  499. }
  500. return (sc);
  501. }
  502. int
  503. sync_cookie_isvalid (Sync_Cookie *testcookie, Sync_Cookie *refcookie)
  504. {
  505. /* client and server info must match */
  506. if (strcmp(testcookie->cookie_client_signature,refcookie->cookie_client_signature) ||
  507. strcmp(testcookie->cookie_server_signature,refcookie->cookie_server_signature) ||
  508. testcookie->cookie_change_info == -1 ||
  509. testcookie->cookie_change_info > refcookie->cookie_change_info )
  510. return (0);
  511. /* could add an additional check if the requested state in client cookie is still
  512. * available. Accept any state request for now.
  513. */
  514. return (1);
  515. }
  516. void
  517. sync_cookie_free (Sync_Cookie **freecookie)
  518. {
  519. if (*freecookie) {
  520. slapi_ch_free((void **)&((*freecookie)->cookie_client_signature));
  521. slapi_ch_free((void **)&((*freecookie)->cookie_server_signature));
  522. slapi_ch_free((void **)freecookie);
  523. }
  524. }
  525. int sync_is_active_scope (const Slapi_DN *dn, Slapi_PBlock *pb)
  526. {
  527. int rc;
  528. char *origbase = NULL;
  529. Slapi_DN *base = NULL;
  530. int scope;
  531. slapi_pblock_get( pb, SLAPI_ORIGINAL_TARGET_DN, &origbase );
  532. slapi_pblock_get( pb, SLAPI_SEARCH_TARGET_SDN, &base );
  533. slapi_pblock_get( pb, SLAPI_SEARCH_SCOPE, &scope );
  534. if (NULL == base) {
  535. base = slapi_sdn_new_dn_byref(origbase);
  536. slapi_pblock_set(pb, SLAPI_SEARCH_TARGET_SDN, base);
  537. }
  538. if ( slapi_sdn_scope_test(dn, base, scope )) {
  539. rc = 1;
  540. } else {
  541. rc = 0;
  542. }
  543. return (rc);
  544. }
  545. int sync_is_active (Slapi_Entry *e, Slapi_PBlock *pb)
  546. {
  547. if ( pb == NULL ) {
  548. /* not yet initialized */
  549. return(0);
  550. } else {
  551. /* check id entry is in scope of sync request */
  552. return(sync_is_active_scope( slapi_entry_get_sdn_const(e),pb));
  553. }
  554. }
  555. Slapi_PBlock *
  556. sync_pblock_copy(Slapi_PBlock *src)
  557. {
  558. Slapi_Operation *operation;
  559. Slapi_Connection *connection;
  560. int *scope;
  561. int *deref;
  562. int *filter_normalized;
  563. char *fstr;
  564. char **attrs, **attrs_dup;
  565. int *attrsonly;
  566. int *isroot;
  567. int *sizelimit;
  568. int *timelimit;
  569. struct slapdplugin *pi;
  570. slapi_pblock_get( src, SLAPI_OPERATION, &operation );
  571. slapi_pblock_get( src, SLAPI_CONNECTION, &connection );
  572. slapi_pblock_get( src, SLAPI_SEARCH_SCOPE, &scope );
  573. slapi_pblock_get( src, SLAPI_SEARCH_DEREF, &deref );
  574. slapi_pblock_get( src, SLAPI_PLUGIN_SYNTAX_FILTER_NORMALIZED, &filter_normalized );
  575. slapi_pblock_get( src, SLAPI_SEARCH_STRFILTER, &fstr );
  576. slapi_pblock_get( src, SLAPI_SEARCH_ATTRS, &attrs );
  577. slapi_pblock_get( src, SLAPI_SEARCH_ATTRSONLY, &attrsonly );
  578. slapi_pblock_get( src, SLAPI_REQUESTOR_ISROOT, &isroot );
  579. slapi_pblock_get( src, SLAPI_SEARCH_SIZELIMIT, &sizelimit );
  580. slapi_pblock_get( src, SLAPI_SEARCH_TIMELIMIT, &timelimit );
  581. slapi_pblock_get( src, SLAPI_PLUGIN, &pi);
  582. Slapi_PBlock *dest = slapi_pblock_new();
  583. slapi_pblock_set( dest, SLAPI_OPERATION, operation );
  584. slapi_pblock_set( dest, SLAPI_CONNECTION, connection );
  585. slapi_pblock_set( dest, SLAPI_SEARCH_SCOPE, &scope );
  586. slapi_pblock_set( dest, SLAPI_SEARCH_DEREF, &deref );
  587. slapi_pblock_set( dest, SLAPI_PLUGIN_SYNTAX_FILTER_NORMALIZED, &filter_normalized );
  588. slapi_pblock_set( dest, SLAPI_SEARCH_STRFILTER, slapi_ch_strdup(fstr) );
  589. attrs_dup = slapi_ch_array_dup(attrs);
  590. slapi_pblock_set( dest, SLAPI_SEARCH_ATTRS, attrs_dup );
  591. slapi_pblock_set( dest, SLAPI_SEARCH_ATTRSONLY, &attrsonly );
  592. slapi_pblock_set( dest, SLAPI_REQUESTOR_ISROOT, &isroot );
  593. slapi_pblock_set( dest, SLAPI_SEARCH_SIZELIMIT, &sizelimit );
  594. slapi_pblock_set( dest, SLAPI_SEARCH_TIMELIMIT, &timelimit );
  595. slapi_pblock_set( dest, SLAPI_PLUGIN, pi);
  596. return dest;
  597. }
  598. int sync_number2int(char *chgnrstr)
  599. {
  600. char *end;
  601. int nr;
  602. nr = strtoul(chgnrstr, &end, 10);
  603. if ( *end == '\0') {
  604. return (nr);
  605. } else {
  606. return (-1);
  607. }
  608. }