sync_util.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729
  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. cb->cb_err = 0; /* changenr successfully set */
  326. }
  327. }
  328. }
  329. }
  330. return (rc);
  331. }
  332. /*
  333. * a cookie is used to synchronize client server sessions,
  334. * it consist of three parts
  335. * -- server id, client should only sync with one server
  336. * -- client id, client should use same bind dn, and srch params
  337. * -- change info, kind of state info like csn, ruv,
  338. * in the first implementation use changenumber from retro cl
  339. *
  340. * syntax: <server-id>#<client-id>#change
  341. *
  342. */
  343. static char *
  344. sync_cookie_get_server_info(Slapi_PBlock *pb)
  345. {
  346. char *info_enc;
  347. int rc = 0;
  348. Slapi_Entry **entries;
  349. Slapi_PBlock *srch_pb = NULL;
  350. char *host = NULL;
  351. char *port = NULL;
  352. char *server_attrs[] = {"nsslapd-localhost", "nsslapd-port", NULL};
  353. srch_pb = slapi_pblock_new ();
  354. slapi_search_internal_set_pb (srch_pb, "cn=config", LDAP_SCOPE_BASE,
  355. "objectclass=*", server_attrs, 0, NULL, NULL,
  356. plugin_get_default_component_id(), 0);
  357. slapi_search_internal_pb (srch_pb);
  358. slapi_pblock_get(srch_pb, SLAPI_PLUGIN_INTOP_RESULT, &rc);
  359. if (rc != 0)
  360. {
  361. slapi_log_error(SLAPI_LOG_FATAL, SYNC_PLUGIN_SUBSYSTEM, "sync_cookie_get_server_info: "
  362. "unable to read server configuration: error %d\n", rc);
  363. }
  364. else
  365. {
  366. slapi_pblock_get(srch_pb, SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES, &entries);
  367. if (NULL == entries || NULL == entries[0])
  368. {
  369. slapi_log_error(SLAPI_LOG_FATAL, SYNC_PLUGIN_SUBSYSTEM, "sync_cookie_get_server_info: "
  370. "server configuration missing\n");
  371. rc = -1;
  372. }
  373. else
  374. {
  375. host = slapi_entry_attr_get_charptr(entries[0], "nsslapd-localhost");
  376. port = slapi_entry_attr_get_charptr(entries[0], "nsslapd-port");
  377. }
  378. }
  379. info_enc = slapi_ch_smprintf("%s:%s",host?host:"nohost",port?port:"noport");
  380. slapi_ch_free ((void**)&host);
  381. slapi_ch_free ((void**)&port);
  382. slapi_free_search_results_internal(srch_pb);
  383. slapi_pblock_destroy (srch_pb);
  384. return(info_enc);
  385. }
  386. static char *
  387. sync_cookie_get_client_info(Slapi_PBlock *pb)
  388. {
  389. char *targetdn;
  390. char *strfilter;
  391. char *clientdn;
  392. char *clientinfo;
  393. slapi_pblock_get(pb, SLAPI_TARGET_DN, &targetdn);
  394. slapi_pblock_get(pb, SLAPI_SEARCH_STRFILTER, &strfilter);
  395. slapi_pblock_get(pb, SLAPI_REQUESTOR_DN, &clientdn);
  396. clientinfo = slapi_ch_smprintf("%s:%s:%s",clientdn,targetdn,strfilter);
  397. return (clientinfo);
  398. }
  399. static int
  400. sync_cookie_get_change_number(int lastnr, const char *uniqueid)
  401. {
  402. Slapi_PBlock *srch_pb;
  403. Slapi_Entry **entries;
  404. Slapi_Entry *cl_entry;
  405. int rv;
  406. int newnr = -1;
  407. char *filter = slapi_ch_smprintf("(&(changenumber>=%d)(targetuniqueid=%s))",lastnr,uniqueid);
  408. srch_pb = slapi_pblock_new();
  409. slapi_search_internal_set_pb(srch_pb, CL_SRCH_BASE,
  410. LDAP_SCOPE_SUBTREE, filter,
  411. NULL, 0, NULL, NULL, plugin_get_default_component_id(), 0);
  412. slapi_search_internal_pb(srch_pb);
  413. slapi_pblock_get(srch_pb, SLAPI_PLUGIN_INTOP_RESULT, &rv);
  414. if ( rv == LDAP_SUCCESS) {
  415. slapi_pblock_get(srch_pb, SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES, &entries);
  416. if (entries && *entries) {
  417. Slapi_Attr *attr;
  418. Slapi_Value *val;
  419. cl_entry = *entries; /* only use teh first one */
  420. slapi_entry_attr_find(cl_entry, CL_ATTR_CHANGENUMBER, &attr);
  421. slapi_attr_first_value(attr, &val);
  422. newnr = sync_number2int((char *)slapi_value_get_string(val));
  423. }
  424. }
  425. slapi_free_search_results_internal(srch_pb);
  426. slapi_pblock_destroy(srch_pb);
  427. slapi_ch_free((void **)&filter);
  428. return (newnr);
  429. }
  430. static int
  431. sync_cookie_get_change_info(Sync_CallBackData *scbd)
  432. {
  433. Slapi_PBlock *seq_pb;
  434. char *base;
  435. char *attrname;
  436. int rc;
  437. base = slapi_ch_strdup("cn=changelog");
  438. attrname = slapi_ch_strdup("changenumber");
  439. seq_pb = slapi_pblock_new();
  440. slapi_pblock_init(seq_pb);
  441. slapi_seq_internal_set_pb(seq_pb, base, SLAPI_SEQ_LAST, attrname, NULL, NULL, 0, 0,
  442. plugin_get_default_component_id(), 0);
  443. rc = slapi_seq_internal_callback_pb (seq_pb, scbd, NULL, sync_handle_cnum_entry, NULL);
  444. slapi_pblock_destroy(seq_pb);
  445. slapi_ch_free((void **)&attrname);
  446. slapi_ch_free((void **)&base);
  447. return (rc);
  448. }
  449. Sync_Cookie *
  450. sync_cookie_create (Slapi_PBlock *pb)
  451. {
  452. Sync_CallBackData scbd;
  453. int rc;
  454. Sync_Cookie *sc = (Sync_Cookie *)slapi_ch_calloc(1, sizeof(Sync_Cookie));
  455. scbd.cb_err = SYNC_CALLBACK_PREINIT;
  456. rc = sync_cookie_get_change_info (&scbd);
  457. if (rc == 0) {
  458. sc->cookie_server_signature = sync_cookie_get_server_info(pb);
  459. sc->cookie_client_signature = sync_cookie_get_client_info(pb);
  460. if (scbd.cb_err == SYNC_CALLBACK_PREINIT) {
  461. /* changenr is not initialized. */
  462. sc->cookie_change_info = 0;
  463. } else {
  464. sc->cookie_change_info = scbd.changenr;
  465. }
  466. } else {
  467. slapi_ch_free ((void **)&sc);
  468. sc = NULL;
  469. }
  470. return (sc);
  471. }
  472. void sync_cookie_update (Sync_Cookie *sc, Slapi_Entry *ec)
  473. {
  474. const char *uniqueid = NULL;
  475. Slapi_Attr *attr;
  476. Slapi_Value *val;
  477. slapi_entry_attr_find(ec, SLAPI_ATTR_UNIQUEID, &attr);
  478. slapi_attr_first_value(attr, &val);
  479. uniqueid = slapi_value_get_string(val);
  480. sc->cookie_change_info = sync_cookie_get_change_number (sc->cookie_change_info, uniqueid);
  481. }
  482. Sync_Cookie *
  483. sync_cookie_parse (char *cookie)
  484. {
  485. char *p, *q;
  486. Sync_Cookie *sc = NULL;
  487. if (cookie == NULL || *cookie == '\0' ) {
  488. return NULL;
  489. }
  490. /*
  491. * Format of cookie: server_signature#client_signature#change_info_number
  492. * If the cookie is malformed, NULL is returned.
  493. */
  494. p = q = cookie;
  495. p = strchr(q, '#');
  496. if (p) {
  497. *p = '\0';
  498. sc = (Sync_Cookie *)slapi_ch_calloc(1, sizeof(Sync_Cookie));
  499. sc->cookie_server_signature = slapi_ch_strdup(q);
  500. q = p + 1;
  501. p = strchr(q, '#');
  502. if (p) {
  503. *p = '\0';
  504. sc->cookie_client_signature = slapi_ch_strdup(q);
  505. sc->cookie_change_info = sync_number2int(p+1);
  506. if (sc->cookie_change_info < 0) {
  507. goto error_return;
  508. }
  509. } else {
  510. goto error_return;
  511. }
  512. }
  513. return (sc);
  514. error_return:
  515. slapi_ch_free_string(&(sc->cookie_client_signature));
  516. slapi_ch_free_string(&(sc->cookie_server_signature));
  517. slapi_ch_free((void **)&sc);
  518. return NULL;
  519. }
  520. int
  521. sync_cookie_isvalid (Sync_Cookie *testcookie, Sync_Cookie *refcookie)
  522. {
  523. /* client and server info must match */
  524. if ((testcookie && refcookie) &&
  525. (strcmp(testcookie->cookie_client_signature,refcookie->cookie_client_signature) ||
  526. strcmp(testcookie->cookie_server_signature,refcookie->cookie_server_signature) ||
  527. testcookie->cookie_change_info == -1 ||
  528. testcookie->cookie_change_info > refcookie->cookie_change_info)) {
  529. return (0);
  530. }
  531. /* could add an additional check if the requested state in client cookie is still
  532. * available. Accept any state request for now.
  533. */
  534. return (1);
  535. }
  536. void
  537. sync_cookie_free (Sync_Cookie **freecookie)
  538. {
  539. if (*freecookie) {
  540. slapi_ch_free((void **)&((*freecookie)->cookie_client_signature));
  541. slapi_ch_free((void **)&((*freecookie)->cookie_server_signature));
  542. slapi_ch_free((void **)freecookie);
  543. }
  544. }
  545. int sync_is_active_scope (const Slapi_DN *dn, Slapi_PBlock *pb)
  546. {
  547. int rc;
  548. char *origbase = NULL;
  549. Slapi_DN *base = NULL;
  550. int scope;
  551. slapi_pblock_get( pb, SLAPI_ORIGINAL_TARGET_DN, &origbase );
  552. slapi_pblock_get( pb, SLAPI_SEARCH_TARGET_SDN, &base );
  553. slapi_pblock_get( pb, SLAPI_SEARCH_SCOPE, &scope );
  554. if (NULL == base) {
  555. base = slapi_sdn_new_dn_byref(origbase);
  556. slapi_pblock_set(pb, SLAPI_SEARCH_TARGET_SDN, base);
  557. }
  558. if ( slapi_sdn_scope_test(dn, base, scope )) {
  559. rc = 1;
  560. } else {
  561. rc = 0;
  562. }
  563. return (rc);
  564. }
  565. int sync_is_active (Slapi_Entry *e, Slapi_PBlock *pb)
  566. {
  567. if ( pb == NULL ) {
  568. /* not yet initialized */
  569. return(0);
  570. } else {
  571. /* check id entry is in scope of sync request */
  572. return(sync_is_active_scope( slapi_entry_get_sdn_const(e),pb));
  573. }
  574. }
  575. Slapi_PBlock *
  576. sync_pblock_copy(Slapi_PBlock *src)
  577. {
  578. Slapi_Operation *operation;
  579. Slapi_Operation *operation_new;
  580. Slapi_Connection *connection;
  581. int *scope;
  582. int *deref;
  583. int *filter_normalized;
  584. char *fstr;
  585. char **attrs, **attrs_dup;
  586. char **reqattrs, **reqattrs_dup;
  587. int *attrsonly;
  588. int *isroot;
  589. int *sizelimit;
  590. int *timelimit;
  591. struct slapdplugin *pi;
  592. ber_int_t msgid;
  593. ber_tag_t tag;
  594. slapi_pblock_get( src, SLAPI_OPERATION, &operation );
  595. slapi_pblock_get( src, SLAPI_CONNECTION, &connection );
  596. slapi_pblock_get( src, SLAPI_SEARCH_SCOPE, &scope );
  597. slapi_pblock_get( src, SLAPI_SEARCH_DEREF, &deref );
  598. slapi_pblock_get( src, SLAPI_PLUGIN_SYNTAX_FILTER_NORMALIZED, &filter_normalized );
  599. slapi_pblock_get( src, SLAPI_SEARCH_STRFILTER, &fstr );
  600. slapi_pblock_get( src, SLAPI_SEARCH_ATTRS, &attrs );
  601. slapi_pblock_get( src, SLAPI_SEARCH_REQATTRS, &reqattrs );
  602. slapi_pblock_get( src, SLAPI_SEARCH_ATTRSONLY, &attrsonly );
  603. slapi_pblock_get( src, SLAPI_REQUESTOR_ISROOT, &isroot );
  604. slapi_pblock_get( src, SLAPI_SEARCH_SIZELIMIT, &sizelimit );
  605. slapi_pblock_get( src, SLAPI_SEARCH_TIMELIMIT, &timelimit );
  606. slapi_pblock_get( src, SLAPI_PLUGIN, &pi);
  607. Slapi_PBlock *dest = slapi_pblock_new();
  608. operation_new = slapi_operation_new(0);
  609. msgid = slapi_operation_get_msgid(operation);
  610. slapi_operation_set_msgid(operation_new, msgid);
  611. tag = slapi_operation_get_tag(operation);
  612. slapi_operation_set_tag(operation_new, tag);
  613. slapi_pblock_set( dest, SLAPI_OPERATION, operation_new );
  614. slapi_pblock_set( dest, SLAPI_CONNECTION, connection );
  615. slapi_pblock_set( dest, SLAPI_SEARCH_SCOPE, &scope );
  616. slapi_pblock_set( dest, SLAPI_SEARCH_DEREF, &deref );
  617. slapi_pblock_set( dest, SLAPI_PLUGIN_SYNTAX_FILTER_NORMALIZED, &filter_normalized );
  618. slapi_pblock_set( dest, SLAPI_SEARCH_STRFILTER, slapi_ch_strdup(fstr) );
  619. attrs_dup = slapi_ch_array_dup(attrs);
  620. reqattrs_dup = slapi_ch_array_dup(reqattrs);
  621. slapi_pblock_set( dest, SLAPI_SEARCH_ATTRS, attrs_dup );
  622. slapi_pblock_set( dest, SLAPI_SEARCH_REQATTRS, reqattrs_dup );
  623. slapi_pblock_set( dest, SLAPI_SEARCH_ATTRSONLY, &attrsonly );
  624. slapi_pblock_set( dest, SLAPI_REQUESTOR_ISROOT, &isroot );
  625. slapi_pblock_set( dest, SLAPI_SEARCH_SIZELIMIT, &sizelimit );
  626. slapi_pblock_set( dest, SLAPI_SEARCH_TIMELIMIT, &timelimit );
  627. slapi_pblock_set( dest, SLAPI_PLUGIN, pi);
  628. return dest;
  629. }
  630. int sync_number2int(char *chgnrstr)
  631. {
  632. char *end;
  633. int nr;
  634. nr = strtoul(chgnrstr, &end, 10);
  635. if ( *end == '\0') {
  636. return (nr);
  637. } else {
  638. return (-1);
  639. }
  640. }