dn.c 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485
  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) 2001 Sun Microsystems, Inc. Used by permission.
  35. * Copyright (C) 2005 Red Hat, Inc.
  36. * All rights reserved.
  37. * END COPYRIGHT BLOCK **/
  38. #ifdef HAVE_CONFIG_H
  39. # include <config.h>
  40. #endif
  41. /* dn.c - routines for dealing with distinguished names */
  42. #include <stdio.h>
  43. #include <ctype.h>
  44. #include <string.h>
  45. #include <sys/types.h>
  46. #ifndef _WIN32
  47. #include <sys/time.h>
  48. #include <sys/socket.h>
  49. #endif
  50. #include "slap.h"
  51. #undef SDN_DEBUG
  52. static void add_rdn_av( char *avstart, char *avend, int *rdn_av_countp,
  53. struct berval **rdn_avsp, struct berval *avstack );
  54. static void reset_rdn_avs( struct berval **rdn_avsp, int *rdn_av_countp );
  55. static void sort_rdn_avs( struct berval *avs, int count );
  56. static int rdn_av_cmp( struct berval *av1, struct berval *av2 );
  57. static void rdn_av_swap( struct berval *av1, struct berval *av2 );
  58. int
  59. hexchar2int( char c )
  60. {
  61. if ( '0' <= c && c <= '9' ) {
  62. return( c - '0' );
  63. }
  64. if ( 'a' <= c && c <= 'f' ) {
  65. return( c - 'a' + 10 );
  66. }
  67. if ( 'A' <= c && c <= 'F' ) {
  68. return( c - 'A' + 10 );
  69. }
  70. return( -1 );
  71. }
  72. #define DNSEPARATOR(c) (c == ',' || c == ';')
  73. #define SEPARATOR(c) (c == ',' || c == ';' || c == '+')
  74. #define SPACE(c) (c == ' ' || c == '\n') /* XXX 518524 */
  75. #define NEEDSESCAPE(c) (c == '\\' || c == '"')
  76. #define B4TYPE 0
  77. #define INTYPE 1
  78. #define B4EQUAL 2
  79. #define B4VALUE 3
  80. #define INVALUE 4
  81. #define INQUOTEDVALUE 5
  82. #define B4SEPARATOR 6
  83. #define SLAPI_DNNORM_INITIAL_RDN_AVS 10
  84. #define SLAPI_DNNORM_SMALL_RDN_AV 512
  85. /*
  86. * substr_dn_normalize - map a DN to a canonical form.
  87. * The DN is read from *dn through *(end-1) and normalized in place.
  88. * The new end is returned; that is, the canonical form is in
  89. * *dn through *(the_return_value-1).
  90. */
  91. /* The goals of this function are:
  92. * 1. be compatible with previous implementations. Especially, enable
  93. * a server running this code to find database index keys that were
  94. * computed by Directory Server 3.0 with a prior version of this code.
  95. * 2. Normalize in place; that is, avoid allocating memory to contain
  96. * the canonical form.
  97. * 3. eliminate insignificant differences; that is, any two DNs are
  98. * not significantly different if and only if their canonical forms
  99. * are identical (ignoring upper/lower case).
  100. * 4. handle a DN in the syntax defined by RFC 2253.
  101. * 5. handle a DN in the syntax defined by RFC 1779.
  102. *
  103. * Goals 3 through 5 are not entirely achieved by this implementation,
  104. * because it can't be done without violating goal 1. Specifically,
  105. * DNs like cn="a,b" and cn=a\,b are not mapped to the same canonical form,
  106. * although they're not significantly different. Likewise for any pair
  107. * of DNs that differ only in their choice of quoting convention.
  108. * A previous version of this code changed all DNs to the most compact
  109. * quoting convention, but that violated goal 1, since Directory Server
  110. * 3.0 did not.
  111. *
  112. * Also, this implementation handles the \xx convention of RFC 2253 and
  113. * consequently violates RFC 1779, according to which this type of quoting
  114. * would be interpreted as a sequence of 2 numerals (not a single byte).
  115. *
  116. * Finally, if the DN contains any RDNs that are multivalued, we sort
  117. * the values in the RDN(s) to help meet goal 3. Ordering is based on a
  118. * case-insensitive comparison of the "attribute=value" pairs.
  119. *
  120. * This function does not support UTF-8 multi-byte encoding for attribute
  121. * values, in particular it does not support UTF-8 whitespace. First the
  122. * SPACE macro above is limited, but also its frequent use of '-1' indexing
  123. * into a char[] may hit the middle of a multi-byte UTF-8 whitespace character
  124. * encoding (518524).
  125. */
  126. char *
  127. substr_dn_normalize( char *dn, char *end )
  128. {
  129. /* \xx is changed to \c.
  130. * \c is changed to c, unless this would change its meaning.
  131. * All values that contain 2 or more separators are "enquoted";
  132. * all other values are not enquoted.
  133. */
  134. char *value = NULL;
  135. char *value_separator = NULL;
  136. char *d = NULL;
  137. char *s = NULL;
  138. char *typestart = NULL;
  139. int gotesc = 0;
  140. int state = B4TYPE;
  141. int rdn_av_count = 0;
  142. struct berval *rdn_avs = NULL;
  143. struct berval initial_rdn_av_stack[ SLAPI_DNNORM_INITIAL_RDN_AVS ];
  144. for ( d = s = dn; s != end; s++ ) {
  145. switch ( state ) {
  146. case B4TYPE:
  147. if ( ! SPACE( *s ) ) {
  148. state = INTYPE;
  149. typestart = d;
  150. *d++ = *s;
  151. }
  152. break;
  153. case INTYPE:
  154. if ( *s == '=' ) {
  155. state = B4VALUE;
  156. *d++ = *s;
  157. } else if ( SPACE( *s ) ) {
  158. state = B4EQUAL;
  159. } else {
  160. *d++ = *s;
  161. }
  162. break;
  163. case B4EQUAL:
  164. if ( *s == '=' ) {
  165. state = B4VALUE;
  166. *d++ = *s;
  167. } else if ( ! SPACE( *s ) ) {
  168. /* not a valid dn - but what can we do here? */
  169. *d++ = *s;
  170. }
  171. break;
  172. case B4VALUE:
  173. if ( *s == '"' || ! SPACE( *s ) ) {
  174. value_separator = NULL;
  175. value = d;
  176. state = ( *s == '"' ) ? INQUOTEDVALUE : INVALUE;
  177. *d++ = *s;
  178. }
  179. break;
  180. case INVALUE:
  181. if ( gotesc ) {
  182. if ( SEPARATOR( *s ) ) {
  183. value_separator = d;
  184. } else if ( ! NEEDSESCAPE( *s ) ) {
  185. --d; /* eliminate the \ */
  186. }
  187. } else if ( SEPARATOR( *s ) ) {
  188. while ( SPACE( *(d - 1) ) )
  189. d--;
  190. if ( value_separator == dn ) { /* 2 or more separators */
  191. /* convert to quoted value: */
  192. char *L = NULL; /* char after last seperator */
  193. char *R; /* value character iterator */
  194. int escape_skips = 0; /* number of escapes we have seen after the first */
  195. for ( R = value; (R = strchr( R, '\\' )) && (R < d); L = ++R ) {
  196. if ( SEPARATOR( R[1] )) {
  197. if ( L == NULL ) {
  198. /* executes once, at first escape, adds opening quote */
  199. const size_t len = R - value;
  200. /* make room for quote by covering escape */
  201. if ( len > 0 ) {
  202. memmove( value+1, value, len );
  203. }
  204. *value = '"'; /* opening quote */
  205. value = R + 1; /* move passed what has been parsed */
  206. } else {
  207. const size_t len = R - L;
  208. if ( len > 0 ) {
  209. /* remove the seperator */
  210. memmove( value, L, len );
  211. value += len; /* move passed what has been parsed */
  212. }
  213. --d;
  214. ++escape_skips;
  215. }
  216. }
  217. }
  218. memmove( value, L, d - L + escape_skips );
  219. *d++ = '"'; /* closing quote */
  220. }
  221. state = B4TYPE;
  222. /*
  223. * Track and sort attribute values within
  224. * multivalued RDNs.
  225. */
  226. if ( *s == '+' || rdn_av_count > 0 ) {
  227. add_rdn_av( typestart, d, &rdn_av_count,
  228. &rdn_avs, initial_rdn_av_stack );
  229. }
  230. if ( *s != '+' ) { /* at end of this RDN */
  231. if ( rdn_av_count > 1 ) {
  232. sort_rdn_avs( rdn_avs, rdn_av_count );
  233. }
  234. if ( rdn_av_count > 0 ) {
  235. reset_rdn_avs( &rdn_avs, &rdn_av_count );
  236. }
  237. }
  238. *d++ = (*s == '+') ? '+' : ',';
  239. break;
  240. }
  241. *d++ = *s;
  242. break;
  243. case INQUOTEDVALUE:
  244. if ( gotesc ) {
  245. if ( ! NEEDSESCAPE( *s ) ) {
  246. --d; /* eliminate the \ */
  247. }
  248. } else if ( *s == '"' ) {
  249. state = B4SEPARATOR;
  250. if ( value_separator == dn /* 2 or more separators */
  251. || SPACE( value[1] ) || SPACE( d[-1] ) ) {
  252. *d++ = *s;
  253. } else {
  254. /* convert to non-quoted value: */
  255. if ( value_separator == NULL ) { /* no separators */
  256. memmove ( value, value+1, (d-value)-1 );
  257. --d;
  258. } else { /* 1 separator */
  259. memmove ( value, value+1, (value_separator-value)-1 );
  260. *(value_separator - 1) = '\\';
  261. }
  262. }
  263. break;
  264. }
  265. if ( SEPARATOR( *s )) {
  266. if ( value_separator ) value_separator = dn;
  267. else value_separator = d;
  268. }
  269. *d++ = *s;
  270. break;
  271. case B4SEPARATOR:
  272. if ( SEPARATOR( *s ) ) {
  273. state = B4TYPE;
  274. /*
  275. * Track and sort attribute values within
  276. * multivalued RDNs.
  277. */
  278. if ( *s == '+' || rdn_av_count > 0 ) {
  279. add_rdn_av( typestart, d, &rdn_av_count,
  280. &rdn_avs, initial_rdn_av_stack );
  281. }
  282. if ( *s != '+' ) { /* at end of this RDN */
  283. if ( rdn_av_count > 1 ) {
  284. sort_rdn_avs( rdn_avs, rdn_av_count );
  285. }
  286. if ( rdn_av_count > 0 ) {
  287. reset_rdn_avs( &rdn_avs, &rdn_av_count );
  288. }
  289. }
  290. *d++ = (*s == '+') ? '+' : ',';
  291. }
  292. break;
  293. default:
  294. LDAPDebug( LDAP_DEBUG_ANY,
  295. "slapi_dn_normalize - unknown state %d\n", state, 0, 0 );
  296. break;
  297. }
  298. if ( *s == '\\' ) {
  299. if ( gotesc ) { /* '\\', again */
  300. /* <type>=XXX\\\\7AYYY; we should keep \\\\. */
  301. gotesc = 0;
  302. } else {
  303. gotesc = 1;
  304. if ( s+2 < end ) {
  305. int n = hexchar2int( s[1] );
  306. /* If 8th bit is on, the char is not ASCII (not UTF-8).
  307. * Thus, not UTF-8 */
  308. if ( n >= 0 && n < 8 ) {
  309. int n2 = hexchar2int( s[2] );
  310. if ( n2 >= 0 ) {
  311. n = (n << 4) + n2;
  312. if (n == 0) { /* don't change \00 */
  313. *d++ = *++s;
  314. *d++ = *++s;
  315. gotesc = 0;
  316. } else { /* change \xx to a single char */
  317. ++s;
  318. *(unsigned char*)(s+1) = n;
  319. }
  320. }
  321. }
  322. }
  323. }
  324. } else {
  325. gotesc = 0;
  326. }
  327. }
  328. /*
  329. * Track and sort attribute values within multivalued RDNs.
  330. */
  331. /* We may still be in an unexpected state, such as B4TYPE if
  332. * we encountered something odd like a '+' at the end of the
  333. * rdn. If this is the case, we don't want to add this bogus
  334. * rdn to our list to sort. We should only be in the INVALUE
  335. * or B4SEPARATOR state if we have a valid rdn component to
  336. * be added. */
  337. if ((rdn_av_count > 0) && ((state == INVALUE) || (state == B4SEPARATOR))) {
  338. add_rdn_av( typestart, d, &rdn_av_count,
  339. &rdn_avs, initial_rdn_av_stack );
  340. }
  341. if ( rdn_av_count > 1 ) {
  342. sort_rdn_avs( rdn_avs, rdn_av_count );
  343. }
  344. if ( rdn_av_count > 0 ) {
  345. reset_rdn_avs( &rdn_avs, &rdn_av_count );
  346. }
  347. /* Trim trailing spaces */
  348. while ( d != dn && *(d - 1) == ' ' ) d--; /* XXX 518524 */
  349. return( d );
  350. }
  351. /*
  352. * Append previous AV to the attribute value array if multivalued RDN.
  353. * We use a stack based array at first and if we overflow that, we
  354. * allocate a larger one from the heap, copy the stack based data in,
  355. * and continue to grow the heap based one as needed.
  356. */
  357. static void
  358. add_rdn_av( char *avstart, char *avend, int *rdn_av_countp,
  359. struct berval **rdn_avsp, struct berval *avstack )
  360. {
  361. if ( *rdn_av_countp == 0 ) {
  362. *rdn_avsp = avstack;
  363. } else if ( *rdn_av_countp == SLAPI_DNNORM_INITIAL_RDN_AVS ) {
  364. struct berval *tmpavs;
  365. tmpavs = (struct berval *)slapi_ch_calloc(
  366. SLAPI_DNNORM_INITIAL_RDN_AVS * 2, sizeof( struct berval ));
  367. memcpy( tmpavs, *rdn_avsp,
  368. SLAPI_DNNORM_INITIAL_RDN_AVS * sizeof( struct berval ));
  369. *rdn_avsp = tmpavs;
  370. } else if (( *rdn_av_countp % SLAPI_DNNORM_INITIAL_RDN_AVS ) == 0 ) {
  371. *rdn_avsp = (struct berval *)slapi_ch_realloc( (char *)*rdn_avsp,
  372. (*rdn_av_countp + SLAPI_DNNORM_INITIAL_RDN_AVS)*sizeof(struct berval) );
  373. }
  374. /*
  375. * Note: The bv_val's are just pointers into the dn itself. Also,
  376. * we DO NOT zero-terminate the bv_val's. The sorting code in
  377. * sort_rdn_avs() takes all of this into account.
  378. */
  379. (*rdn_avsp)[ *rdn_av_countp ].bv_val = avstart;
  380. (*rdn_avsp)[ *rdn_av_countp ].bv_len = avend - avstart;
  381. ++(*rdn_av_countp);
  382. }
  383. /*
  384. * Reset RDN attribute value array, freeing memory if any was allocated.
  385. */
  386. static void
  387. reset_rdn_avs( struct berval **rdn_avsp, int *rdn_av_countp )
  388. {
  389. if ( *rdn_av_countp > SLAPI_DNNORM_INITIAL_RDN_AVS ) {
  390. slapi_ch_free( (void **)rdn_avsp );
  391. }
  392. *rdn_avsp = NULL;
  393. *rdn_av_countp = 0;
  394. }
  395. /*
  396. * Perform an in-place, case-insensitive sort of RDN attribute=value pieces.
  397. * This function is always called with more than one element in "avs".
  398. *
  399. * Note that this is used by the DN normalization code, so if any changes
  400. * are made to the comparison function used for sorting customers will need
  401. * to rebuild their database/index files.
  402. *
  403. * Also note that the bv_val's in the "avas" array are not zero-terminated.
  404. */
  405. static void
  406. sort_rdn_avs( struct berval *avs, int count )
  407. {
  408. int i, j, swaps;
  409. /*
  410. * Since we expect there to be a small number of AVs, we use a
  411. * simple bubble sort. rdn_av_swap() only works correctly on
  412. * adjacent values anyway.
  413. */
  414. for ( i = 0; i < count - 1; ++i ) {
  415. swaps = 0;
  416. for ( j = 0; j < count - 1; ++j ) {
  417. if ( rdn_av_cmp( &avs[j], &avs[j+1] ) > 0 ) {
  418. rdn_av_swap( &avs[j], &avs[j+1] );
  419. ++swaps;
  420. }
  421. }
  422. if ( swaps == 0 ) {
  423. break; /* stop early if no swaps made during the last pass */
  424. }
  425. }
  426. }
  427. /*
  428. * strcasecmp()-like function for RDN attribute values.
  429. */
  430. static int
  431. rdn_av_cmp( struct berval *av1, struct berval *av2 )
  432. {
  433. int rc;
  434. rc = strncasecmp( av1->bv_val, av2->bv_val,
  435. ( av1->bv_len < av2->bv_len ) ? av1->bv_len : av2->bv_len );
  436. if ( rc == 0 ) {
  437. return( av1->bv_len - av2->bv_len ); /* longer is greater */
  438. } else {
  439. return( rc );
  440. }
  441. }
  442. /*
  443. * Swap two adjacent attribute=value pieces within an (R)DN.
  444. * Avoid allocating any heap memory for reasonably small AVs.
  445. */
  446. static void
  447. rdn_av_swap( struct berval *av1, struct berval *av2 )
  448. {
  449. char *buf1, *buf2;
  450. char stackbuf1[ SLAPI_DNNORM_SMALL_RDN_AV ];
  451. char stackbuf2[ SLAPI_DNNORM_SMALL_RDN_AV ];
  452. int len1, len2;
  453. /*
  454. * Copy the two avs into temporary buffers. We use stack-based buffers
  455. * if the avs are small and allocate buffers from the heap to hold
  456. * large values.
  457. */
  458. if (( len1 = av1->bv_len ) <= SLAPI_DNNORM_SMALL_RDN_AV ) {
  459. buf1 = stackbuf1;
  460. } else {
  461. buf1 = slapi_ch_malloc( len1 );
  462. }
  463. memcpy( buf1, av1->bv_val, len1 );
  464. if (( len2 = av2->bv_len ) <= SLAPI_DNNORM_SMALL_RDN_AV ) {
  465. buf2 = stackbuf2;
  466. } else {
  467. buf2 = slapi_ch_malloc( len2 );
  468. }
  469. memcpy( buf2, av2->bv_val, len2 );
  470. /*
  471. * Copy av2 over av1 and reset length of av1.
  472. */
  473. memcpy( av1->bv_val, buf2, av2->bv_len );
  474. av1->bv_len = len2;
  475. /*
  476. * Add separator character (+) and copy av1 into place.
  477. * Also reset av2 pointer and length.
  478. */
  479. av2->bv_val = av1->bv_val + len2;
  480. *(av2->bv_val)++ = '+';
  481. memcpy( av2->bv_val, buf1, len1 );
  482. av2->bv_len = len1;
  483. /*
  484. * Clean up.
  485. */
  486. if ( len1 > SLAPI_DNNORM_SMALL_RDN_AV ) {
  487. slapi_ch_free( (void **)&buf1 );
  488. }
  489. if ( len2 > SLAPI_DNNORM_SMALL_RDN_AV ) {
  490. slapi_ch_free( (void **)&buf2 );
  491. }
  492. }
  493. /*
  494. * slapi_dn_normalize - put dn into a canonical format. the dn is
  495. * normalized in place, as well as returned.
  496. */
  497. char *
  498. slapi_dn_normalize( char *dn )
  499. {
  500. /* LDAPDebug( LDAP_DEBUG_TRACE, "=> slapi_dn_normalize \"%s\"\n", dn, 0, 0 ); */
  501. *(substr_dn_normalize( dn, dn + strlen( dn ))) = '\0';
  502. /* LDAPDebug( LDAP_DEBUG_TRACE, "<= slapi_dn_normalize \"%s\"\n", dn, 0, 0 ); */
  503. return dn;
  504. }
  505. /* Note that this routine normalizes to the end and doesn't null terminate */
  506. char *
  507. slapi_dn_normalize_to_end( char *dn , char *end)
  508. {
  509. return ( substr_dn_normalize( dn, end ? end : dn + strlen( dn )) );
  510. }
  511. /*
  512. * dn could contain UTF-8 multi-byte characters,
  513. * which also need to be converted to the lower case.
  514. */
  515. char *
  516. slapi_dn_ignore_case( char *dn )
  517. {
  518. unsigned char *s, *d;
  519. int ssz, dsz;
  520. /* normalize case (including UTF-8 multi-byte chars) */
  521. for ( s = d = (unsigned char *)dn; *s; s += ssz, d += dsz ) {
  522. slapi_utf8ToLower( s, d, &ssz, &dsz );
  523. }
  524. *d = '\0'; /* utf8ToLower result may be shorter than the original */
  525. return( dn );
  526. }
  527. /*
  528. * slapi_dn_normalize_case - put dn into a canonical form suitable for storing
  529. * in a hash database. this involves normalizing the case as well as
  530. * the format. the dn is normalized in place as well as returned.
  531. */
  532. char *
  533. slapi_dn_normalize_case( char *dn )
  534. {
  535. /* normalize format */
  536. slapi_dn_normalize( dn );
  537. /* normalize case */
  538. return( slapi_dn_ignore_case( dn ));
  539. }
  540. /*
  541. * slapi_dn_beparent - return a copy of the dn of dn's parent,
  542. * NULL if the DN is a suffix of the backend.
  543. */
  544. char *
  545. slapi_dn_beparent(
  546. Slapi_PBlock *pb,
  547. const char *dn
  548. )
  549. {
  550. char *r= NULL;
  551. if ( dn != NULL && *dn != '\0')
  552. {
  553. if(!slapi_dn_isbesuffix( pb, dn ))
  554. {
  555. r= slapi_dn_parent( dn );
  556. }
  557. }
  558. return r;
  559. }
  560. /*
  561. * This function is used for speed. Instead of returning a newly allocated
  562. * dn string that contains the parent, this function just returns a pointer
  563. * to the address _within_ the given string where the parent dn of the
  564. * given dn starts e.g. if you call this with "dc=example,dc=com", the
  565. * function will return "dc=com" - that is, the char* returned will be the
  566. * address of the 'd' after the ',' in "dc=example,dc=com". This function
  567. * also checks for bogus things like consecutive ocurrances of unquoted
  568. * separators e.g. DNs like cn=foo,,,,,,,,,,,cn=bar,,,,,,,
  569. * This function is useful for "interating" over a DN returning the ancestors
  570. * of the given dn e.g.
  571. *
  572. * const char *dn = somedn;
  573. * while (dn = slapi_dn_find_parent(dn)) {
  574. * see if parent exists
  575. * etc.
  576. * }
  577. */
  578. const char*
  579. slapi_dn_find_parent( const char *dn )
  580. {
  581. const char *s;
  582. int inquote;
  583. if ( dn == NULL || *dn == '\0' ) {
  584. return( NULL );
  585. }
  586. /*
  587. * An X.500-style distinguished name looks like this:
  588. * foo=bar,sha=baz,...
  589. */
  590. inquote = 0;
  591. for ( s = dn; *s; s++ ) {
  592. if ( *s == '\\' ) {
  593. if ( *(s + 1) )
  594. s++;
  595. continue;
  596. }
  597. if ( inquote ) {
  598. if ( *s == '"' )
  599. inquote = 0;
  600. } else {
  601. if ( *s == '"' )
  602. inquote = 1;
  603. else {
  604. if ( DNSEPARATOR( *s ) ) {
  605. while ( *s && DNSEPARATOR( *s ) ) {
  606. ++s;
  607. }
  608. if (*s) {
  609. return( s );
  610. }
  611. }
  612. }
  613. }
  614. }
  615. return( NULL );
  616. }
  617. char*
  618. slapi_dn_parent( const char *dn )
  619. {
  620. const char *s = slapi_dn_find_parent(dn);
  621. if ( s == NULL || *s == '\0' ) {
  622. return( NULL );
  623. }
  624. return( slapi_ch_strdup( s ) );
  625. }
  626. /*
  627. * slapi_dn_issuffix - tells whether suffix is a suffix of dn. both dn
  628. * and suffix must be normalized.
  629. */
  630. int
  631. slapi_dn_issuffix(const char *dn, const char *suffix)
  632. {
  633. int dnlen, suffixlen;
  634. if ( dn==NULL || suffix==NULL)
  635. {
  636. return( 0 );
  637. }
  638. suffixlen = strlen( suffix );
  639. dnlen = strlen( dn );
  640. if ( suffixlen > dnlen )
  641. {
  642. return( 0 );
  643. }
  644. if ( suffixlen == 0 )
  645. {
  646. return ( 1 );
  647. }
  648. return( (slapi_utf8casecmp( (unsigned char *)(dn + dnlen - suffixlen),
  649. (unsigned char *)suffix ) == 0)
  650. && ( (dnlen == suffixlen) || DNSEPARATOR(dn[dnlen-suffixlen-1])) );
  651. }
  652. int
  653. slapi_dn_isbesuffix( Slapi_PBlock *pb, const char *dn )
  654. {
  655. int r;
  656. Slapi_DN sdn;
  657. slapi_sdn_init_dn_byref(&sdn,dn);
  658. r= slapi_be_issuffix( pb->pb_backend, &sdn );
  659. slapi_sdn_done(&sdn);
  660. return r;
  661. }
  662. /*
  663. * slapi_dn_isparent - returns non-zero if parentdn is the parent of childdn,
  664. * 0 otherwise
  665. */
  666. int
  667. slapi_dn_isparent( const char *parentdn, const char *childdn )
  668. {
  669. char *realparentdn, *copyparentdn;
  670. int rc;
  671. /* child is root - has no parent */
  672. if ( childdn == NULL || *childdn == '\0' ) {
  673. return( 0 );
  674. }
  675. /* construct the actual parent dn and normalize it */
  676. if ( (realparentdn = slapi_dn_parent( childdn )) == NULL ) {
  677. return( parentdn == NULL || *parentdn == '\0' );
  678. }
  679. slapi_dn_normalize( realparentdn );
  680. /* normalize the purported parent dn */
  681. copyparentdn = slapi_ch_strdup( (char *)parentdn );
  682. slapi_dn_normalize( copyparentdn );
  683. /* compare them */
  684. rc = ! strcasecmp( realparentdn, copyparentdn );
  685. slapi_ch_free( (void**)&copyparentdn );
  686. slapi_ch_free( (void**)&realparentdn );
  687. return( rc );
  688. }
  689. /*
  690. * Function: slapi_dn_isroot
  691. *
  692. * Returns: 1 if "dn" is the root dn
  693. * 0 otherwise.
  694. * dn must be normalized
  695. *
  696. */
  697. int
  698. slapi_dn_isroot( const char *dn )
  699. {
  700. int rc;
  701. char *rootdn;
  702. if ( NULL == dn ) {
  703. return( 0 );
  704. }
  705. if ( NULL == (rootdn = config_get_rootdn())) {
  706. return( 0 );
  707. }
  708. /* note: global root dn is normalized when read from config. file */
  709. rc = (strcasecmp( rootdn, dn ) == 0);
  710. slapi_ch_free ( (void **) &rootdn );
  711. return( rc );
  712. }
  713. int
  714. slapi_is_rootdse( const char *dn )
  715. {
  716. if ( NULL != dn )
  717. {
  718. if ( *dn == '\0' )
  719. {
  720. return 1;
  721. }
  722. }
  723. return 0;
  724. }
  725. int
  726. slapi_rdn2typeval(
  727. char *rdn,
  728. char **type,
  729. struct berval *bv
  730. )
  731. {
  732. char *s;
  733. if ( (s = strchr( rdn, '=' )) == NULL ) {
  734. return( -1 );
  735. }
  736. *s++ = '\0';
  737. *type = rdn;
  738. /* MAB 9 Oct 00 : explicit bug fix of 515715
  739. implicit bug fix of 394800 (can't reproduce anymore)
  740. When adding the rdn attribute in the entry, we need to remove
  741. all special escaped characters included in the value itself,
  742. i.e., strings like "\;" must be converted to ";" and so on... */
  743. strcpy_unescape_value(s,s);
  744. bv->bv_val = s;
  745. bv->bv_len = strlen( s );
  746. return( 0 );
  747. }
  748. /*
  749. * Add an RDN to a DN, getting back the new DN.
  750. */
  751. char *
  752. slapi_dn_plus_rdn(const char *dn, const char *rdn)
  753. {
  754. /* rdn + separator + dn + null */
  755. char *newdn = slapi_ch_smprintf("%s,%s", rdn, dn);
  756. return newdn;
  757. }
  758. /* ====== Slapi_DN functions ====== */
  759. #ifdef SDN_DEBUG
  760. #define SDN_DUMP(sdn,name) sdn_dump(sdn,name)
  761. static void sdn_dump( const Slapi_DN *sdn, const char *text);
  762. #else
  763. #define SDN_DUMP(sdn,name) ((void)0)
  764. #endif
  765. #ifndef SLAPI_DN_COUNTERS
  766. #undef DEBUG /* disable counters */
  767. #endif
  768. #include <prcountr.h>
  769. static int counters_created= 0;
  770. PR_DEFINE_COUNTER(slapi_sdn_counter_created);
  771. PR_DEFINE_COUNTER(slapi_sdn_counter_deleted);
  772. PR_DEFINE_COUNTER(slapi_sdn_counter_exist);
  773. PR_DEFINE_COUNTER(slapi_sdn_counter_dn_created);
  774. PR_DEFINE_COUNTER(slapi_sdn_counter_dn_deleted);
  775. PR_DEFINE_COUNTER(slapi_sdn_counter_dn_exist);
  776. PR_DEFINE_COUNTER(slapi_sdn_counter_ndn_created);
  777. PR_DEFINE_COUNTER(slapi_sdn_counter_ndn_deleted);
  778. PR_DEFINE_COUNTER(slapi_sdn_counter_ndn_exist);
  779. static void
  780. sdn_create_counters()
  781. {
  782. PR_CREATE_COUNTER(slapi_sdn_counter_created,"Slapi_DN","created","");
  783. PR_CREATE_COUNTER(slapi_sdn_counter_deleted,"Slapi_DN","deleted","");
  784. PR_CREATE_COUNTER(slapi_sdn_counter_exist,"Slapi_DN","exist","");
  785. PR_CREATE_COUNTER(slapi_sdn_counter_dn_created,"Slapi_DN","internal_dn_created","");
  786. PR_CREATE_COUNTER(slapi_sdn_counter_dn_deleted,"Slapi_DN","internal_dn_deleted","");
  787. PR_CREATE_COUNTER(slapi_sdn_counter_dn_exist,"Slapi_DN","internal_dn_exist","");
  788. PR_CREATE_COUNTER(slapi_sdn_counter_ndn_created,"Slapi_DN","internal_ndn_created","");
  789. PR_CREATE_COUNTER(slapi_sdn_counter_ndn_deleted,"Slapi_DN","internal_ndn_deleted","");
  790. PR_CREATE_COUNTER(slapi_sdn_counter_ndn_exist,"Slapi_DN","internal_ndn_exist","");
  791. counters_created= 1;
  792. }
  793. #define FLAG_ALLOCATED 0
  794. #define FLAG_DN 1
  795. #define FLAG_NDN 2
  796. Slapi_DN *
  797. slapi_sdn_new()
  798. {
  799. Slapi_DN *sdn= (Slapi_DN *)slapi_ch_malloc(sizeof(Slapi_DN));
  800. slapi_sdn_init(sdn);
  801. sdn->flag= slapi_setbit_uchar(sdn->flag,FLAG_ALLOCATED);
  802. SDN_DUMP( sdn, "slapi_sdn_new");
  803. PR_INCREMENT_COUNTER(slapi_sdn_counter_created);
  804. PR_INCREMENT_COUNTER(slapi_sdn_counter_exist);
  805. return sdn;
  806. }
  807. Slapi_DN *
  808. slapi_sdn_init(Slapi_DN *sdn)
  809. {
  810. sdn->flag= 0;
  811. sdn->dn= NULL;
  812. sdn->ndn= NULL;
  813. sdn->ndn_len=0;
  814. if(!counters_created)
  815. {
  816. sdn_create_counters();
  817. }
  818. return sdn;
  819. }
  820. Slapi_DN *
  821. slapi_sdn_init_dn_byref(Slapi_DN *sdn,const char *dn)
  822. {
  823. slapi_sdn_init(sdn);
  824. slapi_sdn_set_dn_byref(sdn,dn);
  825. return sdn;
  826. }
  827. Slapi_DN *
  828. slapi_sdn_init_dn_byval(Slapi_DN *sdn,const char *dn)
  829. {
  830. slapi_sdn_init(sdn);
  831. slapi_sdn_set_dn_byval(sdn,dn);
  832. return sdn;
  833. }
  834. Slapi_DN *
  835. slapi_sdn_init_dn_passin(Slapi_DN *sdn,const char *dn)
  836. {
  837. slapi_sdn_init(sdn);
  838. slapi_sdn_set_dn_passin(sdn,dn);
  839. return sdn;
  840. }
  841. /* use when dn is normalized previously */
  842. Slapi_DN *
  843. slapi_sdn_init_dn_ndn_byref(Slapi_DN *sdn,const char *dn) {
  844. slapi_sdn_init(sdn);
  845. slapi_sdn_set_dn_byref(sdn,dn);
  846. /* slapi_sdn_set_ndn_byref nulls out dn set in above statement */
  847. sdn->flag= slapi_unsetbit_uchar(sdn->flag,FLAG_NDN);
  848. sdn->ndn= dn;
  849. if(dn == NULL) {
  850. sdn->ndn_len=0;
  851. } else {
  852. sdn->ndn_len=strlen(dn);
  853. }
  854. return sdn;
  855. }
  856. Slapi_DN *
  857. slapi_sdn_init_ndn_byref(Slapi_DN *sdn,const char *dn)
  858. {
  859. slapi_sdn_init(sdn);
  860. slapi_sdn_set_ndn_byref(sdn,dn);
  861. return sdn;
  862. }
  863. Slapi_DN *
  864. slapi_sdn_init_ndn_byval(Slapi_DN *sdn,const char *dn)
  865. {
  866. slapi_sdn_init(sdn);
  867. slapi_sdn_set_ndn_byval(sdn,dn);
  868. return sdn;
  869. }
  870. Slapi_DN *
  871. slapi_sdn_new_dn_byval(const char *dn)
  872. {
  873. Slapi_DN *sdn= slapi_sdn_new();
  874. slapi_sdn_set_dn_byval(sdn,dn);
  875. SDN_DUMP( sdn, "slapi_sdn_new_dn_byval");
  876. return sdn;
  877. }
  878. Slapi_DN *
  879. slapi_sdn_new_ndn_byval(const char *ndn)
  880. {
  881. Slapi_DN *sdn= slapi_sdn_new();
  882. slapi_sdn_set_ndn_byval(sdn,ndn);
  883. SDN_DUMP( sdn, "slapi_sdn_new_ndn_byval");
  884. return sdn;
  885. }
  886. Slapi_DN *
  887. slapi_sdn_new_dn_byref(const char *dn)
  888. {
  889. Slapi_DN *sdn= slapi_sdn_new();
  890. slapi_sdn_set_dn_byref(sdn,dn);
  891. SDN_DUMP( sdn, "slapi_sdn_new_dn_byref");
  892. return sdn;
  893. }
  894. Slapi_DN *
  895. slapi_sdn_new_dn_passin(const char *dn)
  896. {
  897. Slapi_DN *sdn= slapi_sdn_new();
  898. slapi_sdn_set_dn_passin(sdn,dn);
  899. SDN_DUMP( sdn, "slapi_sdn_new_dn_passin");
  900. return sdn;
  901. }
  902. Slapi_DN *
  903. slapi_sdn_new_ndn_byref(const char *ndn)
  904. {
  905. Slapi_DN *sdn= slapi_sdn_new();
  906. slapi_sdn_set_ndn_byref(sdn,ndn);
  907. SDN_DUMP( sdn, "slapi_sdn_new_ndn_byref");
  908. return sdn;
  909. }
  910. Slapi_DN *
  911. slapi_sdn_set_dn_byval(Slapi_DN *sdn, const char *dn)
  912. {
  913. slapi_sdn_done(sdn);
  914. sdn->flag= slapi_setbit_uchar(sdn->flag,FLAG_DN);
  915. if(dn!=NULL)
  916. {
  917. sdn->dn= slapi_ch_strdup(dn);
  918. PR_INCREMENT_COUNTER(slapi_sdn_counter_dn_created);
  919. PR_INCREMENT_COUNTER(slapi_sdn_counter_dn_exist);
  920. }
  921. return sdn;
  922. }
  923. Slapi_DN *
  924. slapi_sdn_set_dn_byref(Slapi_DN *sdn, const char *dn)
  925. {
  926. slapi_sdn_done(sdn);
  927. sdn->flag= slapi_unsetbit_uchar(sdn->flag,FLAG_DN);
  928. sdn->dn= dn;
  929. return sdn;
  930. }
  931. Slapi_DN *
  932. slapi_sdn_set_dn_passin(Slapi_DN *sdn, const char *dn)
  933. {
  934. slapi_sdn_done(sdn);
  935. sdn->flag= slapi_setbit_uchar(sdn->flag,FLAG_DN);
  936. sdn->dn= dn;
  937. if(dn!=NULL)
  938. {
  939. PR_INCREMENT_COUNTER(slapi_sdn_counter_dn_created);
  940. PR_INCREMENT_COUNTER(slapi_sdn_counter_dn_exist);
  941. }
  942. return sdn;
  943. }
  944. Slapi_DN *
  945. slapi_sdn_set_ndn_byval(Slapi_DN *sdn, const char *ndn)
  946. {
  947. slapi_sdn_done(sdn);
  948. sdn->flag= slapi_setbit_uchar(sdn->flag,FLAG_NDN);
  949. if(ndn!=NULL)
  950. {
  951. sdn->ndn= slapi_ch_strdup(ndn);
  952. sdn->ndn_len=strlen(ndn);
  953. PR_INCREMENT_COUNTER(slapi_sdn_counter_ndn_created);
  954. PR_INCREMENT_COUNTER(slapi_sdn_counter_ndn_exist);
  955. }
  956. return sdn;
  957. }
  958. Slapi_DN *
  959. slapi_sdn_set_ndn_byref(Slapi_DN *sdn, const char *ndn)
  960. {
  961. slapi_sdn_done(sdn);
  962. sdn->flag= slapi_unsetbit_uchar(sdn->flag,FLAG_NDN);
  963. sdn->ndn= ndn;
  964. if(ndn == NULL) {
  965. sdn->ndn_len=0;
  966. } else {
  967. sdn->ndn_len=strlen(ndn);
  968. }
  969. return sdn;
  970. }
  971. /*
  972. * Set the RDN of the DN.
  973. */
  974. Slapi_DN *
  975. slapi_sdn_set_rdn(Slapi_DN *sdn, const Slapi_RDN *rdn)
  976. {
  977. const char *rawrdn= slapi_rdn_get_rdn(rdn);
  978. if(slapi_sdn_isempty(sdn))
  979. {
  980. slapi_sdn_set_dn_byval(sdn,rawrdn);
  981. }
  982. else
  983. {
  984. /* NewDN= NewRDN + OldParent */
  985. char *parentdn= slapi_dn_parent(sdn->dn);
  986. char *newdn= slapi_ch_malloc(strlen(rawrdn)+1+strlen(parentdn)+1);
  987. strcpy( newdn, rawrdn );
  988. strcat( newdn, "," );
  989. strcat( newdn, parentdn );
  990. slapi_ch_free((void**)&parentdn);
  991. slapi_sdn_set_dn_passin(sdn,newdn);
  992. }
  993. return sdn;
  994. }
  995. /*
  996. * Add the RDN to the DN.
  997. */
  998. Slapi_DN *
  999. slapi_sdn_add_rdn(Slapi_DN *sdn, const Slapi_RDN *rdn)
  1000. {
  1001. const char *rawrdn= slapi_rdn_get_rdn(rdn);
  1002. if(slapi_sdn_isempty(sdn))
  1003. {
  1004. slapi_sdn_set_dn_byval(sdn,rawrdn);
  1005. }
  1006. else
  1007. {
  1008. /* NewDN= NewRDN + DN */
  1009. const char *dn= slapi_sdn_get_dn(sdn);
  1010. char *newdn= slapi_ch_malloc(strlen(rawrdn)+1+strlen(dn)+1);
  1011. strcpy( newdn, rawrdn );
  1012. strcat( newdn, "," );
  1013. strcat( newdn, dn );
  1014. slapi_sdn_set_dn_passin(sdn,newdn);
  1015. }
  1016. return sdn;
  1017. }
  1018. /*
  1019. * Set the parent of the DN.
  1020. */
  1021. Slapi_DN *
  1022. slapi_sdn_set_parent(Slapi_DN *sdn, const Slapi_DN *parentdn)
  1023. {
  1024. if(slapi_sdn_isempty(sdn))
  1025. {
  1026. slapi_sdn_copy(parentdn, sdn);
  1027. }
  1028. else
  1029. {
  1030. /* NewDN= OldRDN + NewParent */
  1031. Slapi_RDN rdn;
  1032. const char *rawrdn;
  1033. slapi_rdn_init_dn(&rdn,sdn->dn);
  1034. rawrdn= slapi_rdn_get_rdn(&rdn);
  1035. if(slapi_sdn_isempty(parentdn))
  1036. {
  1037. slapi_sdn_set_dn_byval(sdn,rawrdn);
  1038. }
  1039. else
  1040. {
  1041. char *newdn;
  1042. newdn= slapi_ch_malloc(strlen(rawrdn)+1+strlen(parentdn->dn)+1);
  1043. strcpy( newdn, rawrdn );
  1044. strcat( newdn, "," );
  1045. strcat( newdn, parentdn->dn );
  1046. slapi_sdn_set_dn_passin(sdn,newdn);
  1047. }
  1048. slapi_rdn_done(&rdn);
  1049. }
  1050. return sdn;
  1051. }
  1052. void
  1053. slapi_sdn_done(Slapi_DN *sdn)
  1054. {
  1055. /* sdn_dump( sdn, "slapi_sdn_done"); */
  1056. if(sdn->dn!=NULL)
  1057. {
  1058. if(slapi_isbitset_uchar(sdn->flag,FLAG_DN))
  1059. {
  1060. slapi_ch_free((void**)&(sdn->dn));
  1061. sdn->flag= slapi_unsetbit_uchar(sdn->flag,FLAG_DN);
  1062. PR_INCREMENT_COUNTER(slapi_sdn_counter_dn_deleted);
  1063. PR_DECREMENT_COUNTER(slapi_sdn_counter_dn_exist);
  1064. }
  1065. else
  1066. {
  1067. sdn->dn= NULL;
  1068. }
  1069. }
  1070. if(sdn->ndn!=NULL)
  1071. {
  1072. if(slapi_isbitset_uchar(sdn->flag,FLAG_NDN))
  1073. {
  1074. slapi_ch_free((void**)&(sdn->ndn));
  1075. sdn->flag= slapi_unsetbit_uchar(sdn->flag,FLAG_NDN);
  1076. sdn->ndn_len=0;
  1077. PR_INCREMENT_COUNTER(slapi_sdn_counter_ndn_deleted);
  1078. PR_DECREMENT_COUNTER(slapi_sdn_counter_ndn_exist);
  1079. }
  1080. else
  1081. {
  1082. sdn->ndn= NULL;
  1083. sdn->ndn_len=0;
  1084. }
  1085. }
  1086. }
  1087. void
  1088. slapi_sdn_free(Slapi_DN **sdn)
  1089. {
  1090. if(sdn!=NULL && *sdn!=NULL)
  1091. {
  1092. SDN_DUMP( *sdn, "slapi_sdn_free");
  1093. slapi_sdn_done(*sdn);
  1094. if(slapi_isbitset_uchar((*sdn)->flag,FLAG_ALLOCATED))
  1095. {
  1096. slapi_ch_free((void**)sdn);
  1097. PR_INCREMENT_COUNTER(slapi_sdn_counter_deleted);
  1098. PR_DECREMENT_COUNTER(slapi_sdn_counter_exist);
  1099. }
  1100. }
  1101. }
  1102. const char *
  1103. slapi_sdn_get_dn(const Slapi_DN *sdn)
  1104. {
  1105. return (sdn->dn!=NULL ? sdn->dn : sdn->ndn);
  1106. }
  1107. const char *
  1108. slapi_sdn_get_ndn(const Slapi_DN *sdn)
  1109. {
  1110. if(sdn->ndn==NULL)
  1111. {
  1112. if(sdn->dn!=NULL)
  1113. {
  1114. char *p= slapi_ch_strdup(sdn->dn);
  1115. Slapi_DN *ncsdn= (Slapi_DN*)sdn; /* non-const Slapi_DN */
  1116. slapi_dn_normalize_case(p);
  1117. ncsdn->ndn= p;
  1118. ncsdn->ndn_len=strlen(p);
  1119. ncsdn->flag= slapi_setbit_uchar(sdn->flag,FLAG_NDN);
  1120. PR_INCREMENT_COUNTER(slapi_sdn_counter_ndn_created);
  1121. PR_INCREMENT_COUNTER(slapi_sdn_counter_ndn_exist);
  1122. }
  1123. }
  1124. return sdn->ndn;
  1125. }
  1126. void
  1127. slapi_sdn_get_parent(const Slapi_DN *sdn,Slapi_DN *sdn_parent)
  1128. {
  1129. const char *parentdn= slapi_dn_parent(slapi_sdn_get_dn(sdn));
  1130. slapi_sdn_set_dn_passin(sdn_parent,parentdn);
  1131. sdn_parent->flag= slapi_setbit_uchar(sdn_parent->flag,FLAG_DN);
  1132. PR_INCREMENT_COUNTER(slapi_sdn_counter_dn_created);
  1133. PR_INCREMENT_COUNTER(slapi_sdn_counter_dn_exist);
  1134. }
  1135. void
  1136. slapi_sdn_get_backend_parent(const Slapi_DN *sdn,Slapi_DN *sdn_parent,const Slapi_Backend *backend)
  1137. {
  1138. if(slapi_sdn_isempty(sdn) || slapi_be_issuffix( backend, sdn ))
  1139. {
  1140. slapi_sdn_done(sdn_parent);
  1141. }
  1142. else
  1143. {
  1144. slapi_sdn_get_parent(sdn,sdn_parent);
  1145. }
  1146. }
  1147. void
  1148. slapi_sdn_get_rdn(const Slapi_DN *sdn,Slapi_RDN *rdn)
  1149. {
  1150. slapi_rdn_set_dn(rdn,sdn->dn);
  1151. }
  1152. Slapi_DN *
  1153. slapi_sdn_dup(const Slapi_DN *sdn)
  1154. {
  1155. Slapi_DN *tmp;
  1156. SDN_DUMP( sdn, "slapi_sdn_dup");
  1157. tmp=slapi_sdn_new_dn_byval(slapi_sdn_get_dn(sdn));
  1158. /* can't use slapi_set_ndn_byval -- it nulls the dn */
  1159. tmp->flag= slapi_setbit_uchar(tmp->flag,FLAG_NDN);
  1160. if(sdn->ndn!=NULL)
  1161. {
  1162. tmp->ndn= slapi_ch_strdup(sdn->ndn);
  1163. tmp->ndn_len=sdn->ndn_len;
  1164. } else tmp->ndn=NULL;
  1165. return tmp;
  1166. }
  1167. void
  1168. slapi_sdn_copy(const Slapi_DN *from, Slapi_DN *to)
  1169. {
  1170. SDN_DUMP( from, "slapi_sdn_copy from");
  1171. SDN_DUMP( to, "slapi_sdn_copy to");
  1172. slapi_sdn_done(to);
  1173. slapi_sdn_set_dn_byval(to,slapi_sdn_get_dn(from));
  1174. }
  1175. int
  1176. slapi_sdn_compare( const Slapi_DN *sdn1, const Slapi_DN *sdn2 )
  1177. {
  1178. int rc;
  1179. const char *ndn1= slapi_sdn_get_ndn(sdn1);
  1180. const char *ndn2= slapi_sdn_get_ndn(sdn2);
  1181. if(ndn1==ndn2)
  1182. {
  1183. rc= 0;
  1184. }
  1185. else
  1186. {
  1187. if(ndn1==NULL)
  1188. {
  1189. rc= -1;
  1190. }
  1191. else
  1192. {
  1193. if(ndn2==NULL)
  1194. {
  1195. rc= 1;
  1196. }
  1197. else
  1198. {
  1199. rc= strcmp(ndn1,ndn2);
  1200. }
  1201. }
  1202. }
  1203. return rc;
  1204. }
  1205. int
  1206. slapi_sdn_isempty( const Slapi_DN *sdn)
  1207. {
  1208. const char *dn= slapi_sdn_get_dn(sdn);
  1209. return (dn==NULL || dn[0]=='\0');
  1210. }
  1211. int
  1212. slapi_sdn_issuffix(const Slapi_DN *sdn, const Slapi_DN *suffixsdn)
  1213. {
  1214. int rc;
  1215. const char *dn= slapi_sdn_get_ndn(sdn);
  1216. const char *suffixdn= slapi_sdn_get_ndn(suffixsdn);
  1217. if(dn!=NULL && suffixdn!=NULL)
  1218. {
  1219. int dnlen = slapi_sdn_get_ndn_len(sdn);
  1220. int suffixlen= slapi_sdn_get_ndn_len(suffixsdn);
  1221. if (dnlen<suffixlen)
  1222. {
  1223. rc= 0;
  1224. }
  1225. else
  1226. {
  1227. if ( suffixlen == 0 )
  1228. {
  1229. return ( 1 );
  1230. }
  1231. rc= ( (strcasecmp(suffixdn, dn+dnlen-suffixlen)==0)
  1232. && ( (dnlen == suffixlen)
  1233. || DNSEPARATOR(dn[dnlen-suffixlen-1])) );
  1234. }
  1235. }
  1236. else
  1237. {
  1238. rc= 0;
  1239. }
  1240. return rc;
  1241. }
  1242. /* normalizes sdn if it hasn't already been done */
  1243. int
  1244. slapi_sdn_get_ndn_len(const Slapi_DN *sdn)
  1245. {
  1246. int r= 0;
  1247. (void)slapi_sdn_get_ndn(sdn); /* does the normalization if needed */
  1248. if(sdn->ndn!=NULL)
  1249. {
  1250. r= sdn->ndn_len;
  1251. }
  1252. return r;
  1253. }
  1254. int
  1255. slapi_sdn_isparent( const Slapi_DN *parent, const Slapi_DN *child )
  1256. {
  1257. int rc= 0;
  1258. /* child is root - has no parent */
  1259. if ( !slapi_sdn_isempty(child) )
  1260. {
  1261. Slapi_DN childparent;
  1262. slapi_sdn_init(&childparent);
  1263. slapi_sdn_get_parent(child,&childparent);
  1264. rc= (slapi_sdn_compare(parent,&childparent)==0);
  1265. slapi_sdn_done(&childparent);
  1266. }
  1267. return( rc );
  1268. }
  1269. int
  1270. slapi_sdn_isgrandparent( const Slapi_DN *parent, const Slapi_DN *child )
  1271. {
  1272. int rc= 0;
  1273. /* child is root - has no parent */
  1274. if ( !slapi_sdn_isempty(child) )
  1275. {
  1276. Slapi_DN childparent;
  1277. slapi_sdn_init(&childparent);
  1278. slapi_sdn_get_parent(child,&childparent);
  1279. if ( !slapi_sdn_isempty(&childparent) )
  1280. {
  1281. Slapi_DN childchildparent;
  1282. slapi_sdn_init(&childchildparent);
  1283. slapi_sdn_get_parent(&childparent,&childchildparent);
  1284. rc= (slapi_sdn_compare(parent,&childchildparent)==0);
  1285. slapi_sdn_done(&childchildparent);
  1286. }
  1287. slapi_sdn_done(&childparent);
  1288. }
  1289. return( rc );
  1290. }
  1291. /*
  1292. * Return non-zero if "dn" matches the scoping criteria
  1293. * given by "base" and "scope".
  1294. */
  1295. int
  1296. slapi_sdn_scope_test( const Slapi_DN *dn, const Slapi_DN *base, int scope )
  1297. {
  1298. int rc = 0;
  1299. switch ( scope ) {
  1300. case LDAP_SCOPE_BASE:
  1301. rc = ( slapi_sdn_compare( dn, base ) == 0 );
  1302. break;
  1303. case LDAP_SCOPE_ONELEVEL:
  1304. rc = ( slapi_sdn_isparent( base, dn ) != 0 );
  1305. break;
  1306. case LDAP_SCOPE_SUBTREE:
  1307. rc = ( slapi_sdn_issuffix( dn, base ) != 0 );
  1308. break;
  1309. }
  1310. return rc;
  1311. }
  1312. /*
  1313. * build the new dn of an entry for moddn operations
  1314. */
  1315. char *
  1316. slapi_moddn_get_newdn(Slapi_DN *dn_olddn, char *newrdn, char *newsuperiordn)
  1317. {
  1318. char *newdn;
  1319. if( newsuperiordn!=NULL)
  1320. {
  1321. /* construct the new dn */
  1322. newdn= slapi_dn_plus_rdn(newsuperiordn, newrdn); /* JCM - Use Slapi_RDN */
  1323. }
  1324. else
  1325. {
  1326. /* construct the new dn */
  1327. char *pdn;
  1328. const char *dn= slapi_sdn_get_dn(dn_olddn);
  1329. pdn = slapi_dn_parent( dn );
  1330. if ( pdn != NULL )
  1331. {
  1332. newdn= slapi_dn_plus_rdn(pdn, newrdn); /* JCM - Use Slapi_RDN */
  1333. }
  1334. else
  1335. {
  1336. newdn= slapi_ch_strdup(newrdn);
  1337. }
  1338. slapi_ch_free( (void**)&pdn );
  1339. }
  1340. return newdn;
  1341. }
  1342. /* JCM slapi_sdn_get_first ? */
  1343. /* JCM slapi_sdn_get_next ? */
  1344. #ifdef SDN_DEBUG
  1345. static void
  1346. sdn_dump( const Slapi_DN *sdn, const char *text)
  1347. {
  1348. LDAPDebug( LDAP_DEBUG_ANY, "SDN %s ptr=%lx dn=%s\n", text, sdn, (sdn->dn==NULL?"NULL":sdn->dn));
  1349. }
  1350. #endif