sync_util.c 18 KB

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