dn.c 91 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194
  1. /** BEGIN COPYRIGHT BLOCK
  2. * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
  3. * Copyright (C) 2005 Red Hat, Inc.
  4. * All rights reserved.
  5. *
  6. * License: GPL (version 3 or any later version).
  7. * See LICENSE for details.
  8. * END COPYRIGHT BLOCK **/
  9. #ifdef HAVE_CONFIG_H
  10. # include <config.h>
  11. #endif
  12. /* dn.c - routines for dealing with distinguished names */
  13. #include <stdio.h>
  14. #include <ctype.h>
  15. #include <string.h>
  16. #include <sys/types.h>
  17. #include <sys/time.h>
  18. #include <sys/socket.h>
  19. #include "slap.h"
  20. #include <plhash.h>
  21. #undef SDN_DEBUG
  22. static void add_rdn_av( char *avstart, char *avend, int *rdn_av_countp,
  23. struct berval **rdn_avsp, struct berval *avstack );
  24. static void reset_rdn_avs( struct berval **rdn_avsp, int *rdn_av_countp );
  25. static void sort_rdn_avs( struct berval *avs, int count, int escape );
  26. static int rdn_av_cmp( struct berval *av1, struct berval *av2 );
  27. static void rdn_av_swap( struct berval *av1, struct berval *av2, int escape );
  28. static int does_cn_uses_dn_syntax_in_dns(char *type, char *dn);
  29. /* normalized dn cache related definitions*/
  30. struct
  31. ndn_cache_lru
  32. {
  33. struct ndn_cache_lru *prev;
  34. struct ndn_cache_lru *next;
  35. char *key;
  36. };
  37. struct
  38. ndn_cache_ctx
  39. {
  40. struct ndn_cache_lru *head;
  41. struct ndn_cache_lru *tail;
  42. Slapi_Counter *cache_hits;
  43. Slapi_Counter *cache_tries;
  44. Slapi_Counter *cache_misses;
  45. size_t cache_size;
  46. size_t cache_max_size;
  47. long cache_count;
  48. };
  49. struct
  50. ndn_hash_val
  51. {
  52. char *ndn;
  53. size_t len;
  54. int size;
  55. struct ndn_cache_lru *lru_node; /* used to speed up lru shuffling */
  56. };
  57. #define NDN_FLUSH_COUNT 10000 /* number of DN's to remove when cache fills up */
  58. #define NDN_MIN_COUNT 1000 /* the minimum number of DN's to keep in the cache */
  59. #define NDN_CACHE_BUCKETS 2053 /* prime number */
  60. static PLHashNumber ndn_hash_string(const void *key);
  61. static int ndn_cache_lookup(char *dn, size_t dn_len, char **result, char **udn, int *rc);
  62. static void ndn_cache_update_lru(struct ndn_cache_lru **node);
  63. static void ndn_cache_add(char *dn, size_t dn_len, char *ndn, size_t ndn_len);
  64. static void ndn_cache_delete(char *dn);
  65. static void ndn_cache_flush();
  66. static void ndn_cache_free();
  67. static int ndn_started = 0;
  68. static PRLock *lru_lock = NULL;
  69. static Slapi_RWLock *ndn_cache_lock = NULL;
  70. static struct ndn_cache_ctx *ndn_cache = NULL;
  71. static PLHashTable *ndn_cache_hashtable = NULL;
  72. #define ISBLANK(c) ((c) == ' ')
  73. #define ISBLANKSTR(s) (((*(s)) == '2') && (*((s)+1) == '0'))
  74. #define ISSPACE(c) (ISBLANK(c) || ((c) == '\n') || ((c) == '\r')) /* XXX 518524 */
  75. #define ISEQUAL(c) ((c) == '=')
  76. #define ISEQUALSTR(s) \
  77. ((*(s) == '3') && ((*((s)+1) == 'd') || (*((s)+1) == 'D')))
  78. #define ISPLUS(c) ((c) == '+')
  79. #define ISPLUSSTR(s) \
  80. ((*(s) == '2') && ((*((s)+1) == 'b') || (*((s)+1) == 'B')))
  81. #define ISESCAPE(c) ((c) == '\\')
  82. #define ISQUOTE(c) ((c) == '"')
  83. #define DNSEPARATOR(c) (((c) == ',') || ((c) == ';'))
  84. #define DNSEPARATORSTR(s) \
  85. (((*(s) == '2') && ((*((s)+1) == 'c') || (*((s)+1) == 'C'))) || \
  86. ((*(s) == '3') && ((*((s)+1) == 'b') || (*((s)+1) == 'B'))))
  87. #define SEPARATOR(c) (DNSEPARATOR(c) || ISPLUS(c))
  88. #define SEPARATORSTR(s) (DNSEPARATORSTR(s) || ISPLUSSTR(s))
  89. #define NEEDSESCAPE(c) (ISESCAPE(c) || ISQUOTE(c) || SEPARATOR(c) || \
  90. ((c) == '<') || ((c) == '>') || ISEQUAL(c))
  91. #define NEEDSESCAPESTR(s) \
  92. (((*(s) == '2') && ((*((s)+1) == '2') || \
  93. (*((s)+1) == 'b') || (*((s)+1) == 'B') || \
  94. (*((s)+1) == 'c') || (*((s)+1) == 'C'))) || \
  95. ((*(s) == '3') && (((*((s)+1) >= 'b') && (*((s)+1) < 'f')) || \
  96. ((*((s)+1) >= 'B') && (*((s)+1) < 'F')))) || \
  97. ((*(s) == '5') && ((*((s)+1) == 'c') || (*((s)+1) == 'C'))))
  98. #define LEADNEEDSESCAPE(c) (ISBLANK(c) || ((c) == '#') || NEEDSESCAPE(c))
  99. #define LEADNEEDSESCAPESTR(s) (NEEDSESCAPESTR(s) || \
  100. ((*(s) == '2') && (*((s)+1) == '3')))
  101. #define ISCLOSEBRACKET(c) (((c) == ')') || ((c) == ']'))
  102. #define MAYBEDN(eq) ( \
  103. (eq) && ((eq) != subtypestart) && \
  104. ((eq) != subtypestart + strlen(subtypestart) - 3) \
  105. )
  106. #define B4TYPE 0
  107. #define INTYPE 1
  108. #define B4EQUAL 2
  109. #define B4VALUE 3
  110. #define INVALUE 4
  111. #define INQUOTEDVALUE 5
  112. #define B4SEPARATOR 6
  113. #define INVALUE1ST 7
  114. #define INQUOTEDVALUE1ST 8
  115. #define SLAPI_DNNORM_INITIAL_RDN_AVS 10
  116. #define SLAPI_DNNORM_SMALL_RDN_AV 512
  117. /*
  118. * substr_dn_normalize - map a DN to a canonical form.
  119. * The DN is read from *dn through *(end-1) and normalized in place.
  120. * The new end is returned; that is, the canonical form is in
  121. * *dn through *(the_return_value-1).
  122. */
  123. /* The goals of this function are:
  124. * 1. be compatible with previous implementations. Especially, enable
  125. * a server running this code to find database index keys that were
  126. * computed by Directory Server 3.0 with a prior version of this code.
  127. * 2. Normalize in place; that is, avoid allocating memory to contain
  128. * the canonical form.
  129. * 3. eliminate insignificant differences; that is, any two DNs are
  130. * not significantly different if and only if their canonical forms
  131. * are identical (ignoring upper/lower case).
  132. * 4. handle a DN in the syntax defined by RFC 2253.
  133. * 5. handle a DN in the syntax defined by RFC 1779.
  134. *
  135. * Goals 3 through 5 are not entirely achieved by this implementation,
  136. * because it can't be done without violating goal 1. Specifically,
  137. * DNs like cn="a,b" and cn=a\,b are not mapped to the same canonical form,
  138. * although they're not significantly different. Likewise for any pair
  139. * of DNs that differ only in their choice of quoting convention.
  140. * A previous version of this code changed all DNs to the most compact
  141. * quoting convention, but that violated goal 1, since Directory Server
  142. * 3.0 did not.
  143. *
  144. * Also, this implementation handles the \xx convention of RFC 2253 and
  145. * consequently violates RFC 1779, according to which this type of quoting
  146. * would be interpreted as a sequence of 2 numerals (not a single byte).
  147. *
  148. * Finally, if the DN contains any RDNs that are multivalued, we sort
  149. * the values in the RDN(s) to help meet goal 3. Ordering is based on a
  150. * case-insensitive comparison of the "attribute=value" pairs.
  151. *
  152. * This function does not support UTF-8 multi-byte encoding for attribute
  153. * values, in particular it does not support UTF-8 whitespace. First the
  154. * ISSPACE macro above is limited, but also its frequent use of '-1' indexing
  155. * into a char[] may hit the middle of a multi-byte UTF-8 whitespace character
  156. * encoding (518524).
  157. */
  158. char *
  159. substr_dn_normalize_orig( char *dn, char *end )
  160. {
  161. /* \xx is changed to \c.
  162. * \c is changed to c, unless this would change its meaning.
  163. * All values that contain 2 or more separators are "enquoted";
  164. * all other values are not enquoted.
  165. */
  166. char *value = NULL;
  167. char *value_separator = NULL;
  168. char *d = NULL;
  169. char *s = NULL;
  170. char *typestart = NULL;
  171. char *lastesc = NULL;
  172. int gotesc = 0;
  173. int state = B4TYPE;
  174. int rdn_av_count = 0;
  175. struct berval *rdn_avs = NULL;
  176. struct berval initial_rdn_av_stack[ SLAPI_DNNORM_INITIAL_RDN_AVS ];
  177. for ( d = s = dn; s != end; s++ ) {
  178. switch ( state ) {
  179. case B4TYPE:
  180. if ( ! ISSPACE( *s ) ) {
  181. state = INTYPE;
  182. typestart = d;
  183. *d++ = *s;
  184. }
  185. break;
  186. case INTYPE:
  187. if ( *s == '=' ) {
  188. state = B4VALUE;
  189. *d++ = *s;
  190. } else if ( ISSPACE( *s ) ) {
  191. state = B4EQUAL;
  192. } else {
  193. *d++ = *s;
  194. }
  195. break;
  196. case B4EQUAL:
  197. if ( *s == '=' ) {
  198. state = B4VALUE;
  199. *d++ = *s;
  200. } else if ( ! ISSPACE( *s ) ) {
  201. /* not a valid dn - but what can we do here? */
  202. *d++ = *s;
  203. }
  204. break;
  205. case B4VALUE:
  206. if ( *s == '"' || ! ISSPACE( *s ) ) {
  207. value_separator = NULL;
  208. value = d;
  209. state = ( *s == '"' ) ? INQUOTEDVALUE : INVALUE1ST;
  210. lastesc = NULL;
  211. *d++ = *s;
  212. }
  213. break;
  214. case INVALUE1ST:
  215. case INVALUE:
  216. if ( gotesc ) {
  217. if ( SEPARATOR( *s ) ) {
  218. value_separator = d;
  219. }
  220. if ( INVALUE1ST == state ) {
  221. if ( !LEADNEEDSESCAPE( *s )) {
  222. /* checking the leading char + special chars */
  223. --d; /* eliminate the \ */
  224. }
  225. } else if ( !NEEDSESCAPE( *s ) ) {
  226. --d; /* eliminate the \ */
  227. lastesc = d;
  228. }
  229. } else if ( SEPARATOR( *s ) ) {
  230. /* handling a trailing escaped space */
  231. /* assuming a space is the only an extra character which
  232. * is not escaped if it appears in the middle, but should
  233. * be if it does at the end of the RDN value */
  234. /* e.g., ou=ABC \ ,o=XYZ --> ou=ABC \ ,o=XYZ */
  235. if ( lastesc ) {
  236. while ( ISSPACE( *(d - 1) ) && d > lastesc ) {
  237. d--;
  238. }
  239. if ( d == lastesc ) {
  240. *d++ = '\\';
  241. *d++ = ' '; /* escaped trailing space */
  242. }
  243. } else {
  244. while ( ISSPACE( *(d - 1) ) ) {
  245. d--;
  246. }
  247. }
  248. if ( value_separator == dn ) { /* 2 or more separators */
  249. /* convert to quoted value: */
  250. char *L = NULL; /* char after last seperator */
  251. char *R; /* value character iterator */
  252. int escape_skips = 0; /* number of escapes we have seen after the first */
  253. for ( R = value; (R = strchr( R, '\\' )) && (R < d); L = ++R ) {
  254. if ( SEPARATOR( R[1] )) {
  255. if ( L == NULL ) {
  256. /* executes once, at first escape, adds opening quote */
  257. const size_t len = R - value;
  258. /* make room for quote by covering escape */
  259. if ( len > 0 ) {
  260. memmove( value+1, value, len );
  261. }
  262. *value = '"'; /* opening quote */
  263. value = R + 1; /* move passed what has been parsed */
  264. } else {
  265. const size_t len = R - L;
  266. if ( len > 0 ) {
  267. /* remove the seperator */
  268. memmove( value, L, len );
  269. value += len; /* move passed what has been parsed */
  270. }
  271. --d;
  272. ++escape_skips;
  273. }
  274. } /* if ( SEPARATOR( R[1] )) */
  275. } /* for */
  276. memmove( value, L, d - L + escape_skips );
  277. *d++ = '"'; /* closing quote */
  278. } /* if (value_separator == dn) */
  279. state = B4TYPE;
  280. /*
  281. * Track and sort attribute values within
  282. * multivalued RDNs.
  283. */
  284. if ( *s == '+' || rdn_av_count > 0 ) {
  285. add_rdn_av( typestart, d, &rdn_av_count,
  286. &rdn_avs, initial_rdn_av_stack );
  287. }
  288. if ( *s != '+' ) { /* at end of this RDN */
  289. if ( rdn_av_count > 1 ) {
  290. sort_rdn_avs( rdn_avs, rdn_av_count, 0 );
  291. }
  292. if ( rdn_av_count > 0 ) {
  293. reset_rdn_avs( &rdn_avs, &rdn_av_count );
  294. }
  295. }
  296. *d++ = (*s == '+') ? '+' : ',';
  297. break;
  298. } /* else if ( SEPARATOR( *s ) ) */
  299. if ( INVALUE1ST == state ) {
  300. state = INVALUE;
  301. }
  302. *d++ = *s;
  303. break;
  304. case INQUOTEDVALUE:
  305. if ( gotesc ) {
  306. if ( ! NEEDSESCAPE( *s ) ) {
  307. --d; /* eliminate the \ */
  308. }
  309. } else if ( *s == '"' ) {
  310. state = B4SEPARATOR;
  311. if (!value) {
  312. LDAPDebug( LDAP_DEBUG_ANY,
  313. "slapi_dn_normalize - missing value\n", 0, 0, 0 );
  314. break;
  315. }
  316. if ( value_separator == dn /* 2 or more separators */
  317. || ISSPACE( value[1] ) || ISSPACE( d[-1] ) ) {
  318. *d++ = *s;
  319. } else {
  320. /* convert to non-quoted value: */
  321. if ( value_separator == NULL ) { /* no separators */
  322. memmove ( value, value+1, (d-value)-1 );
  323. --d;
  324. } else { /* 1 separator */
  325. memmove ( value, value+1, (value_separator-value)-1 );
  326. *(value_separator - 1) = '\\';
  327. }
  328. }
  329. break;
  330. }
  331. if ( SEPARATOR( *s )) {
  332. if ( value_separator ) value_separator = dn;
  333. else value_separator = d;
  334. }
  335. *d++ = *s;
  336. break;
  337. case B4SEPARATOR:
  338. if ( SEPARATOR( *s ) ) {
  339. state = B4TYPE;
  340. /*
  341. * Track and sort attribute values within
  342. * multivalued RDNs.
  343. */
  344. if ( *s == '+' || rdn_av_count > 0 ) {
  345. add_rdn_av( typestart, d, &rdn_av_count,
  346. &rdn_avs, initial_rdn_av_stack );
  347. }
  348. if ( *s != '+' ) { /* at end of this RDN */
  349. if ( rdn_av_count > 1 ) {
  350. sort_rdn_avs( rdn_avs, rdn_av_count, 0 );
  351. }
  352. if ( rdn_av_count > 0 ) {
  353. reset_rdn_avs( &rdn_avs, &rdn_av_count );
  354. }
  355. }
  356. *d++ = (*s == '+') ? '+' : ',';
  357. }
  358. break;
  359. default:
  360. LDAPDebug( LDAP_DEBUG_ANY,
  361. "slapi_dn_normalize - unknown state %d\n", state, 0, 0 );
  362. break;
  363. }
  364. if ( *s == '\\' ) {
  365. if ( gotesc ) { /* '\\', again */
  366. /* <type>=XXX\\\\7AYYY; we should keep \\\\. */
  367. gotesc = 0;
  368. } else {
  369. gotesc = 1;
  370. if ( s+2 < end ) {
  371. int n = slapi_hexchar2int( s[1] );
  372. if ( n >= 0 && n < 16 ) {
  373. int n2 = slapi_hexchar2int( s[2] );
  374. if ( n2 >= 0 ) {
  375. n = (n << 4) + n2;
  376. if (n == 0) { /* don't change \00 */
  377. *d++ = *++s;
  378. *d++ = *++s;
  379. gotesc = 0;
  380. } else { /* change \xx to a single char */
  381. ++s;
  382. *(unsigned char*)(s+1) = n;
  383. }
  384. }
  385. }
  386. }
  387. }
  388. } else {
  389. gotesc = 0;
  390. }
  391. }
  392. /*
  393. * Track and sort attribute values within multivalued RDNs.
  394. */
  395. /* We may still be in an unexpected state, such as B4TYPE if
  396. * we encountered something odd like a '+' at the end of the
  397. * rdn. If this is the case, we don't want to add this bogus
  398. * rdn to our list to sort. We should only be in the INVALUE
  399. * or B4SEPARATOR state if we have a valid rdn component to
  400. * be added. */
  401. if ((rdn_av_count > 0) && ((state == INVALUE1ST) ||
  402. (state == INVALUE) || (state == B4SEPARATOR))) {
  403. add_rdn_av( typestart, d, &rdn_av_count,
  404. &rdn_avs, initial_rdn_av_stack );
  405. }
  406. if ( rdn_av_count > 1 ) {
  407. sort_rdn_avs( rdn_avs, rdn_av_count, 0 );
  408. }
  409. if ( rdn_av_count > 0 ) {
  410. reset_rdn_avs( &rdn_avs, &rdn_av_count );
  411. }
  412. /* Trim trailing spaces */
  413. while ( d != dn && *(d - 1) == ' ' ) d--; /* XXX 518524 */
  414. return( d );
  415. }
  416. char *
  417. substr_dn_normalize( char *dn, char *end )
  418. {
  419. /* no op */
  420. return end;
  421. }
  422. static int
  423. ISEOV(char *s, char *ends)
  424. {
  425. char *p;
  426. for (p = s; p && *p && p < ends; p++) {
  427. if (SEPARATOR(*p)) {
  428. return 1;
  429. } else if (!ISBLANK(*p)) {
  430. return 0; /* not the end of the value */
  431. }
  432. }
  433. return 1;
  434. }
  435. /*
  436. * 1) Escaped NEEDSESCAPE chars (e.g., ',', '<', '=', etc.) are converted to
  437. * ESC HEX HEX (e.g., \2C, \3C, \3D, etc.)
  438. * Input could be a string in double quotes
  439. * (= old DN format: dn: cn="x=x,y=y",... --> dn: cn=x\3Dx\2Cy\3Dy,...) or
  440. * an escaped string
  441. * (= new DN format dn: cn=x\=x\,y\=y,... -> dn: cn=x\3Dx\2Cy\3Dy,...)
  442. *
  443. * 2) All the other ESC HEX HEX are converted to the real characters.
  444. *
  445. * 3) Spaces around separator ',', ';', and '+' are removed.
  446. *
  447. * Input:
  448. * src: src DN
  449. * src_len: length of src; 0 is acceptable if src is NULL terminated.
  450. * Output:
  451. * dest: address of the converted string; NULL terminated
  452. * (could store src address if no need to convert)
  453. * dest_len: length of dest
  454. *
  455. * Return values:
  456. * 0: nothing was done; dest is identical to src (src is passed in).
  457. * 1: successfully escaped; dest is different from src. src needs to be freed.
  458. * -1: failed; dest is NULL; invalid DN
  459. */
  460. int
  461. slapi_dn_normalize_ext(char *src, size_t src_len, char **dest, size_t *dest_len)
  462. {
  463. int rc = -1;
  464. int state = B4TYPE;
  465. char *s = NULL; /* work pointer for src */
  466. char *d = NULL; /* work pointer for dest */
  467. char *ends = NULL;
  468. char *endd = NULL;
  469. char *lastesc = NULL;
  470. char *udn = NULL;
  471. /* rdn avs for the main DN */
  472. char *typestart = NULL;
  473. int rdn_av_count = 0;
  474. struct berval *rdn_avs = NULL;
  475. struct berval initial_rdn_av_stack[ SLAPI_DNNORM_INITIAL_RDN_AVS ];
  476. /* rdn avs for the nested DN */
  477. char *subtypestart = NULL; /* used for nested rdn avs */
  478. int subrdn_av_count = 0;
  479. struct berval *subrdn_avs = NULL;
  480. struct berval subinitial_rdn_av_stack[ SLAPI_DNNORM_INITIAL_RDN_AVS ];
  481. int chkblank = 0;
  482. int is_dn_syntax = 0;
  483. if ((NULL == dest) || (NULL == dest_len)) {
  484. goto bail;
  485. }
  486. if (NULL == src) {
  487. *dest = NULL;
  488. *dest_len = 0;
  489. goto bail;
  490. }
  491. if (0 == src_len) {
  492. src_len = strlen(src);
  493. }
  494. /*
  495. * Check the normalized dn cache
  496. */
  497. if(ndn_cache_lookup(src, src_len, dest, &udn, &rc)){
  498. *dest_len = strlen(*dest);
  499. return rc;
  500. }
  501. s = PL_strnchr(src, '\\', src_len);
  502. if (s) {
  503. *dest_len = src_len * 3;
  504. *dest = slapi_ch_malloc(*dest_len); /* max length */
  505. rc = 1;
  506. } else {
  507. s = PL_strnchr(src, '"', src_len);
  508. if (s) {
  509. *dest_len = src_len * 3;
  510. *dest = slapi_ch_malloc(*dest_len); /* max length */
  511. rc = 1;
  512. } else {
  513. *dest_len = src_len;
  514. *dest = src; /* just removing spaces around separators */
  515. rc = 0;
  516. }
  517. }
  518. if (0 == src_len) { /* src == "" */
  519. goto bail; /* need to bail after setting up *dest and rc */
  520. }
  521. ends = src + src_len;
  522. endd = *dest + *dest_len;
  523. for (s = src, d = *dest; s < ends && d < endd; ) {
  524. switch (state) {
  525. case B4TYPE: /* before type; cn=... */
  526. /* ^ */
  527. if (ISSPACE(*s)) {
  528. s++; /* skip leading spaces */
  529. } else {
  530. state = INTYPE;
  531. typestart = d;
  532. *d++ = *s++;
  533. }
  534. break;
  535. case INTYPE: /* in type; cn=... */
  536. /* ^ */
  537. if (ISEQUAL(*s)) {
  538. /* See if the type is defined to use
  539. * the Distinguished Name syntax. */
  540. char savechar;
  541. /* We need typestart to be a string containing only
  542. * the type. We terminate the type and then reset
  543. * the string after we check the syntax. */
  544. savechar = *d;
  545. *d = '\0';
  546. is_dn_syntax = slapi_attr_is_dn_syntax_type(typestart);
  547. /* Reset the character we modified. */
  548. *d = savechar;
  549. if (!is_dn_syntax) {
  550. is_dn_syntax = does_cn_uses_dn_syntax_in_dns(typestart, src);
  551. }
  552. state = B4VALUE;
  553. *d++ = *s++;
  554. } else if (ISCLOSEBRACKET(*s)) { /* special care for ACL macro */
  555. /* See if the type is defined to use
  556. * the Distinguished Name syntax. */
  557. char savechar;
  558. /* We need typestart to be a string containing only
  559. * the type. We terminate the type and then reset
  560. * the string after we check the syntax. */
  561. savechar = *d;
  562. *d = '\0';
  563. is_dn_syntax = slapi_attr_is_dn_syntax_type(typestart);
  564. /* Reset the character we modified. */
  565. *d = savechar;
  566. if (!is_dn_syntax) {
  567. is_dn_syntax = does_cn_uses_dn_syntax_in_dns(typestart, src);
  568. }
  569. state = INVALUE; /* skip a trailing space */
  570. *d++ = *s++;
  571. } else if (ISSPACE(*s)) {
  572. /* See if the type is defined to use
  573. * the Distinguished Name syntax. */
  574. char savechar;
  575. /* We need typestart to be a string containing only
  576. * the type. We terminate the type and then reset
  577. * the string after we check the syntax. */
  578. savechar = *d;
  579. *d = '\0';
  580. is_dn_syntax = slapi_attr_is_dn_syntax_type(typestart);
  581. /* Reset the character we modified. */
  582. *d = savechar;
  583. if (!is_dn_syntax) {
  584. is_dn_syntax = does_cn_uses_dn_syntax_in_dns(typestart, src);
  585. }
  586. state = B4EQUAL; /* skip a trailing space */
  587. } else if (ISQUOTE(*s) || SEPARATOR(*s)) {
  588. /* type includes quote / separator; not a valid dn */
  589. rc = -1;
  590. goto bail;
  591. } else {
  592. *d++ = *s++;
  593. }
  594. break;
  595. case B4EQUAL: /* before equal; cn =... */
  596. /* ^ */
  597. if (ISEQUAL(*s)) {
  598. state = B4VALUE;
  599. *d++ = *s++;
  600. } else if (ISSPACE(*s)) {
  601. s++; /* skip trailing spaces */
  602. } else {
  603. /* type includes spaces; not a valid dn */
  604. rc = -1;
  605. goto bail;
  606. }
  607. break;
  608. case B4VALUE: /* before value; cn= ABC */
  609. /* ^ */
  610. if (ISSPACE(*s)) {
  611. s++;
  612. } else {
  613. if (ISQUOTE(*s)) {
  614. s++; /* start with the first char in quotes */
  615. state = INQUOTEDVALUE1ST;
  616. } else {
  617. state = INVALUE1ST;
  618. }
  619. lastesc = NULL;
  620. /* process *s in INVALUE or INQUOTEDVALUE */
  621. }
  622. break;
  623. case INVALUE1ST: /* 1st char in value; cn=ABC */
  624. /* ^ */
  625. if (ISSPACE(*s)) { /* skip leading spaces */
  626. s++;
  627. continue;
  628. } else if (SEPARATOR(*s)) {
  629. /* 1st char in value is separator; invalid dn */
  630. rc = -1;
  631. goto bail;
  632. } /* otherwise, go through */
  633. if (!is_dn_syntax || ISESCAPE(*s)) {
  634. subtypestart = NULL; /* if escaped, can't be multivalued dn */
  635. } else {
  636. subtypestart = d; /* prepare for '+' in the nested DN, if any */
  637. }
  638. subrdn_av_count = 0;
  639. case INVALUE: /* in value; cn=ABC */
  640. /* ^ */
  641. if (ISESCAPE(*s)) {
  642. if (s + 1 >= ends) {
  643. /* DN ends with '\'; invalid dn */
  644. rc = -1;
  645. goto bail;
  646. }
  647. if (((state == INVALUE1ST) && LEADNEEDSESCAPE(*(s+1))) ||
  648. ((state == INVALUE) && NEEDSESCAPE(*(s+1)))) {
  649. if (d + 2 >= endd) {
  650. /* Not enough space for dest; this never happens! */
  651. rc = -1;
  652. goto bail;
  653. } else {
  654. if (ISEQUAL(*(s+1)) && is_dn_syntax) {
  655. while (ISSPACE(*(d-1))) {
  656. /* remove trailing spaces */
  657. d--;
  658. }
  659. } else if (SEPARATOR(*(s+1)) && is_dn_syntax) {
  660. /* separator is a subset of needsescape */
  661. while (ISSPACE(*(d-1))) {
  662. /* remove trailing spaces */
  663. d--;
  664. chkblank = 1;
  665. }
  666. if (chkblank && ISESCAPE(*(d-1)) && ISBLANK(*d)) {
  667. /* last space is escaped "cn=A\ ,ou=..." */
  668. /* ^ */
  669. PR_snprintf(d, 3, "%X", *d); /* hexpair */
  670. d += 2;
  671. chkblank = 0;
  672. }
  673. /*
  674. * Track and sort attribute values within
  675. * multivalued RDNs.
  676. */
  677. if (subtypestart &&
  678. (ISPLUS(*(s+1)) || subrdn_av_count > 0)) {
  679. /* if subtypestart is not valid DN,
  680. * we do not do sorting.*/
  681. char *p = PL_strcasestr(subtypestart, "\\3d");
  682. if (MAYBEDN(p)) {
  683. add_rdn_av(subtypestart, d,
  684. &subrdn_av_count,
  685. &subrdn_avs,
  686. subinitial_rdn_av_stack);
  687. } else {
  688. reset_rdn_avs(&subrdn_avs,
  689. &subrdn_av_count);
  690. subtypestart = NULL;
  691. }
  692. }
  693. if (!ISPLUS(*(s+1))) { /* at end of this RDN */
  694. if (subrdn_av_count > 1) {
  695. sort_rdn_avs( subrdn_avs,
  696. subrdn_av_count, 1 );
  697. }
  698. if (subrdn_av_count > 0) {
  699. reset_rdn_avs( &subrdn_avs,
  700. &subrdn_av_count );
  701. subtypestart = NULL;
  702. }
  703. }
  704. }
  705. /* dn: cn=x\=x\,... -> dn: cn=x\3Dx\2C,... */
  706. *d++ = *s++; /* '\\' */
  707. PR_snprintf(d, 3, "%X", *s); /* hexpair */
  708. d += 2;
  709. if (ISPLUS(*s) && is_dn_syntax) {
  710. /* next type start of multi values */
  711. /* should not be a escape char AND should be
  712. * followed by \\= or \\3D */
  713. if ((PL_strnstr(s, "\\=", ends - s) ||
  714. PL_strncaserstr(s, "\\3D", ends - s))) {
  715. subtypestart = d;
  716. } else {
  717. subtypestart = NULL;
  718. }
  719. }
  720. if ((SEPARATOR(*s) || ISEQUAL(*s)) && is_dn_syntax) {
  721. while (ISSPACE(*(s+1)))
  722. s++; /* remove leading spaces */
  723. s++;
  724. } else {
  725. s++;
  726. }
  727. }
  728. } else if (((state == INVALUE1ST) &&
  729. (s+2 < ends) && LEADNEEDSESCAPESTR(s+1)) ||
  730. ((state == INVALUE) &&
  731. (((s+2 < ends) && NEEDSESCAPESTR(s+1)) ||
  732. (ISEOV(s+3, ends) && ISBLANKSTR(s+1))))) {
  733. /* e.g., cn=abc\20 ,... */
  734. /* ^ */
  735. if (ISEQUALSTR(s+1) && is_dn_syntax) {
  736. while (ISSPACE(*(d-1))) {
  737. /* remove trailing spaces */
  738. d--;
  739. }
  740. } else if (SEPARATORSTR(s+1) && is_dn_syntax) {
  741. /* separator is a subset of needsescape */
  742. while (ISSPACE(*(d-1))) {
  743. /* remove trailing spaces */
  744. d--;
  745. chkblank = 1;
  746. }
  747. if (chkblank && ISESCAPE(*(d-1)) && ISBLANK(*d)) {
  748. /* last space is escaped "cn=A\ ,ou=..." */
  749. /* ^ */
  750. PR_snprintf(d, 3, "%X", *d); /* hexpair */
  751. d += 2;
  752. chkblank = 0;
  753. }
  754. /*
  755. * Track and sort attribute values within
  756. * multivalued RDNs.
  757. */
  758. if (subtypestart &&
  759. (ISPLUSSTR(s+1) || subrdn_av_count > 0)) {
  760. /* if subtypestart is not valid DN,
  761. * we do not do sorting.*/
  762. char *p = PL_strcasestr(subtypestart, "\\3d");
  763. if (MAYBEDN(p)) {
  764. add_rdn_av(subtypestart, d, &subrdn_av_count,
  765. &subrdn_avs, subinitial_rdn_av_stack);
  766. } else {
  767. reset_rdn_avs( &subrdn_avs, &subrdn_av_count );
  768. subtypestart = NULL;
  769. }
  770. }
  771. if (!ISPLUSSTR(s+1)) { /* at end of this RDN */
  772. if (subrdn_av_count > 1) {
  773. sort_rdn_avs( subrdn_avs, subrdn_av_count, 1 );
  774. }
  775. if (subrdn_av_count > 0) {
  776. reset_rdn_avs( &subrdn_avs, &subrdn_av_count );
  777. subtypestart = NULL;
  778. }
  779. }
  780. }
  781. *d++ = *s++; /* '\\' */
  782. *d++ = *s++; /* HEX */
  783. *d++ = *s++; /* HEX */
  784. if (ISPLUSSTR(s-2) && is_dn_syntax) {
  785. /* next type start of multi values */
  786. /* should not be a escape char AND should be followed
  787. * by \\= or \\3D */
  788. if (!ISESCAPE(*s) && (PL_strnstr(s, "\\=", ends - s) ||
  789. PL_strncaserstr(s, "\\3D", ends - s))) {
  790. subtypestart = d;
  791. } else {
  792. subtypestart = NULL;
  793. }
  794. }
  795. if ((SEPARATORSTR(s-2) || ISEQUALSTR(s-2)) && is_dn_syntax) {
  796. while (ISSPACE(*s)) {/* remove leading spaces */
  797. s++;
  798. }
  799. }
  800. } else if (s + 2 < ends &&
  801. isxdigit(*(s+1)) && isxdigit(*(s+2))) {
  802. /* esc hexpair ==> real character */
  803. int n = slapi_hexchar2int(*(s+1));
  804. int n2 = slapi_hexchar2int(*(s+2));
  805. n = (n << 4) + n2;
  806. if (n == 0) { /* don't change \00 */
  807. *d++ = *++s;
  808. *d++ = *++s;
  809. } else {
  810. *d++ = n;
  811. s += 3;
  812. }
  813. } else {
  814. /* ignore an escape for now */
  815. lastesc = d; /* position of the previous escape */
  816. s++;
  817. }
  818. } else if (SEPARATOR(*s)) { /* cn=ABC , ... */
  819. /* ^ */
  820. /* handling a trailing escaped space */
  821. /* assuming a space is the only an extra character which
  822. * is not escaped if it appears in the middle, but should
  823. * be if it does at the end of the RDN value */
  824. /* e.g., ou=ABC \ ,o=XYZ --> ou=ABC \ ,o=XYZ */
  825. if (lastesc) {
  826. while (ISSPACE(*(d-1)) && d > lastesc ) {
  827. d--;
  828. }
  829. if (d == lastesc) {
  830. /* esc hexpair of space: \20 */
  831. *d++ = '\\';
  832. *d++ = '2';
  833. *d++ = '0';
  834. }
  835. } else {
  836. while (ISSPACE(*(d-1))) {
  837. d--;
  838. }
  839. }
  840. state = B4SEPARATOR;
  841. break;
  842. } else if (ISSPACE(*s)) {
  843. /* remove extra spaces, e.g., "cn=ABC DEF" --> "cn=ABC DEF" */
  844. *d++ = *s++;
  845. while (ISSPACE(*s))
  846. s++;
  847. } else {
  848. *d++ = *s++;
  849. }
  850. if (state == INVALUE1ST) {
  851. state = INVALUE;
  852. }
  853. break;
  854. case INQUOTEDVALUE1ST:
  855. if (ISSPACE(*s) && (s+1 < ends && ISSPACE(*(s+1)))) {
  856. /* skip leading spaces but need to leave one */
  857. s++;
  858. continue;
  859. }
  860. if (is_dn_syntax) {
  861. subtypestart = d; /* prepare for '+' in the quoted value, if any */
  862. }
  863. subrdn_av_count = 0;
  864. case INQUOTEDVALUE:
  865. if (ISQUOTE(*s)) {
  866. if (ISESCAPE(*(d-1))) { /* the quote is escaped */
  867. PR_snprintf(d, 3, "%X", *(s++)); /* hexpair */
  868. } else { /* end of INQUOTEVALUE */
  869. if (is_dn_syntax) {
  870. while (ISSPACE(*(d-1))) { /* eliminate trailing spaces */
  871. d--;
  872. chkblank = 1;
  873. }
  874. /* We have to keep the last ' ' of a value in quotes.
  875. * The same idea as the escaped last space:
  876. * "cn=A,ou=B " */
  877. /* ^ */
  878. if (chkblank && ISBLANK(*d)) {
  879. PR_snprintf(d, 4, "\\%X", *d); /* hexpair */
  880. d += 3;
  881. chkblank = 0;
  882. }
  883. } else if (ISSPACE(*(d-1))) {
  884. /* Convert last trailing space to hex code */
  885. d--;
  886. PR_snprintf(d, 4, "\\%X", *d); /* hexpair */
  887. d += 3;
  888. }
  889. state = B4SEPARATOR;
  890. s++;
  891. }
  892. } else if (((state == INQUOTEDVALUE1ST) && LEADNEEDSESCAPE(*s)) ||
  893. (state == INQUOTEDVALUE && NEEDSESCAPE(*s))) {
  894. if (d + 2 >= endd) {
  895. /* Not enough space for dest; this never happens! */
  896. rc = -1;
  897. goto bail;
  898. } else {
  899. if (ISEQUAL(*s) && is_dn_syntax) {
  900. while (ISSPACE(*(d-1))) { /* remove trailing spaces */
  901. d--;
  902. }
  903. } else if (SEPARATOR(*s) && is_dn_syntax) {
  904. /* separator is a subset of needsescape */
  905. while (ISSPACE(*(d-1))) { /* remove trailing spaces */
  906. d--;
  907. chkblank = 1;
  908. }
  909. /* We have to keep the last ' ' of a value in quotes.
  910. * The same idea as the escaped last space:
  911. * "cn=A\ ,ou=..." */
  912. /* ^ */
  913. if (chkblank && ISBLANK(*d)) {
  914. PR_snprintf(d, 4, "\\%X", *d); /* hexpair */
  915. d += 3;
  916. chkblank = 0;
  917. }
  918. /*
  919. * Track and sort attribute values within
  920. * multivalued RDNs.
  921. */
  922. if (subtypestart &&
  923. (ISPLUS(*s) || subrdn_av_count > 0)) {
  924. /* if subtypestart is not valid DN,
  925. * we do not do sorting.*/
  926. char *p = PL_strcasestr(subtypestart, "\\3d");
  927. if (MAYBEDN(p)) {
  928. add_rdn_av(subtypestart, d, &subrdn_av_count,
  929. &subrdn_avs, subinitial_rdn_av_stack);
  930. } else {
  931. reset_rdn_avs( &subrdn_avs, &subrdn_av_count );
  932. subtypestart = NULL;
  933. }
  934. }
  935. if (!ISPLUS(*s)) { /* at end of this RDN */
  936. if (subrdn_av_count > 1) {
  937. sort_rdn_avs( subrdn_avs, subrdn_av_count, 1 );
  938. }
  939. if (subrdn_av_count > 0) {
  940. reset_rdn_avs( &subrdn_avs, &subrdn_av_count );
  941. subtypestart = NULL;
  942. }
  943. }
  944. }
  945. /* dn: cn="x=x,..",... -> dn: cn=x\3Dx\2C,... */
  946. *d++ = '\\';
  947. PR_snprintf(d, 3, "%X", *s); /* hexpair */
  948. d += 2;
  949. if (ISPLUS(*s++) && is_dn_syntax) {
  950. subtypestart = d; /* next type start of multi values */
  951. }
  952. if ((SEPARATOR(*(s-1)) || ISEQUAL(*(s-1))) && is_dn_syntax) {
  953. while (ISSPACE(*s)) /* remove leading spaces */
  954. s++;
  955. }
  956. }
  957. } else if (ISSPACE(*s)) {
  958. while (ISSPACE(*s)) {
  959. s++;
  960. }
  961. /*
  962. * dn_syntax_attr=ABC, XYZ --> dn_syntax_attr=ABC,XYZ
  963. * non_dn_syntax_attr=ABC, XYZ --> dn_syntax_attr=ABC, XYZ
  964. */
  965. if (!is_dn_syntax) {
  966. --s;
  967. *d++ = *s++;
  968. }
  969. } else {
  970. *d++ = *s++;
  971. }
  972. if (state == INQUOTEDVALUE1ST) {
  973. state = INQUOTEDVALUE;
  974. }
  975. break;
  976. case B4SEPARATOR:
  977. if (SEPARATOR(*s)) {
  978. state = B4TYPE;
  979. /*
  980. * Track and sort attribute values within
  981. * multivalued RDNs.
  982. */
  983. if (typestart &&
  984. (ISPLUS(*s) || rdn_av_count > 0)) {
  985. add_rdn_av(typestart, d, &rdn_av_count,
  986. &rdn_avs, initial_rdn_av_stack);
  987. }
  988. /* Sub type sorting might be also ongoing */
  989. if (subtypestart && subrdn_av_count > 0) {
  990. add_rdn_av(subtypestart, d, &subrdn_av_count,
  991. &subrdn_avs, subinitial_rdn_av_stack);
  992. }
  993. if (!ISPLUS(*s)) { /* at end of this RDN */
  994. if (rdn_av_count > 1) {
  995. sort_rdn_avs( rdn_avs, rdn_av_count, 0 );
  996. }
  997. if (rdn_av_count > 0) {
  998. reset_rdn_avs( &rdn_avs, &rdn_av_count );
  999. typestart = NULL;
  1000. }
  1001. /* If in the middle of sub type sorting, finish it. */
  1002. if (subrdn_av_count > 1) {
  1003. sort_rdn_avs( subrdn_avs, subrdn_av_count, 1 );
  1004. }
  1005. if (subrdn_av_count > 0) {
  1006. reset_rdn_avs( &subrdn_avs, &subrdn_av_count );
  1007. subtypestart = NULL;
  1008. }
  1009. }
  1010. *d++ = (ISPLUS(*s++)) ? '+' : ',';
  1011. } else {
  1012. s++;
  1013. }
  1014. break;
  1015. default:
  1016. LDAPDebug( LDAP_DEBUG_ANY,
  1017. "slapi_dn_normalize_ext - unknown state %d\n", state, 0, 0 );
  1018. break;
  1019. }
  1020. }
  1021. /*
  1022. * Track and sort attribute values within multivalued RDNs.
  1023. */
  1024. /* We may still be in an unexpected state, such as B4TYPE if
  1025. * we encountered something odd like a '+' at the end of the
  1026. * rdn. If this is the case, we don't want to add this bogus
  1027. * rdn to our list to sort. We should only be in the INVALUE
  1028. * or B4SEPARATOR state if we have a valid rdn component to
  1029. * be added. */
  1030. if (typestart && (rdn_av_count > 0) && ((state == INVALUE1ST) ||
  1031. (state == INVALUE) || (state == B4SEPARATOR))) {
  1032. add_rdn_av(typestart, d, &rdn_av_count, &rdn_avs, initial_rdn_av_stack);
  1033. }
  1034. if ( rdn_av_count > 1 ) {
  1035. sort_rdn_avs( rdn_avs, rdn_av_count, 0 );
  1036. }
  1037. if ( rdn_av_count > 0 ) {
  1038. reset_rdn_avs( &rdn_avs, &rdn_av_count );
  1039. }
  1040. /* Trim trailing spaces */
  1041. while (d > *dest && ISBLANK(*(d-1))) {
  1042. --d; /* XXX 518524 */
  1043. }
  1044. *dest_len = d - *dest;
  1045. bail:
  1046. if (rc < 0) {
  1047. if (dest != NULL) {
  1048. if (*dest != src) {
  1049. slapi_ch_free_string(dest);
  1050. } else {
  1051. *dest = NULL;
  1052. }
  1053. }
  1054. if (dest_len != NULL) {
  1055. *dest_len = 0;
  1056. }
  1057. } else if (d && rc > 0) {
  1058. /* We terminate the str with NULL only when we allocate the str */
  1059. *d = '\0';
  1060. }
  1061. /* add this dn to the normalized dn cache */
  1062. if (udn) {
  1063. if(dest && *dest && dest_len && *dest_len) {
  1064. ndn_cache_add(udn, src_len, *dest, *dest_len);
  1065. } else {
  1066. slapi_ch_free_string(&udn);
  1067. }
  1068. }
  1069. return rc;
  1070. }
  1071. char *
  1072. slapi_create_dn_string(const char *fmt, ...)
  1073. {
  1074. char *src = NULL;
  1075. char *dest = NULL;
  1076. size_t dest_len = 0;
  1077. va_list ap;
  1078. int rc = 0;
  1079. if (NULL == fmt) {
  1080. return NULL;
  1081. }
  1082. va_start(ap, fmt);
  1083. src = PR_vsmprintf(fmt, ap);
  1084. va_end(ap);
  1085. rc = slapi_dn_normalize_ext(src, strlen(src), &dest, &dest_len);
  1086. if (rc < 0) {
  1087. slapi_ch_free_string(&src);
  1088. return NULL;
  1089. } else if (rc == 0) { /* src is passed in. */
  1090. *(dest + dest_len) = '\0';
  1091. } else {
  1092. slapi_ch_free_string(&src);
  1093. }
  1094. return dest;
  1095. }
  1096. char *
  1097. slapi_create_rdn_value(const char *fmt, ...)
  1098. {
  1099. char *src = NULL;
  1100. char *dest = NULL;
  1101. size_t dest_len = 0;
  1102. va_list ap;
  1103. int rc = 0;
  1104. char *dnfmt;
  1105. if (NULL == fmt) {
  1106. return NULL;
  1107. }
  1108. dnfmt = slapi_ch_smprintf("cn=%s", fmt);
  1109. va_start(ap, fmt);
  1110. src = PR_vsmprintf(dnfmt, ap);
  1111. va_end(ap);
  1112. slapi_ch_free_string(&dnfmt);
  1113. rc = slapi_dn_normalize_ext(src, strlen(src), &dest, &dest_len);
  1114. if (rc == 0) { /* src is passed in. */
  1115. *(dest + dest_len) = '\0';
  1116. dest = slapi_ch_strdup(dest + 3);
  1117. } else if (rc > 0) {
  1118. char *odest = dest;
  1119. dest = slapi_ch_strdup(dest + 3);
  1120. slapi_ch_free_string(&odest);
  1121. }
  1122. slapi_ch_free_string(&src);
  1123. return dest;
  1124. }
  1125. /*
  1126. * Append previous AV to the attribute value array if multivalued RDN.
  1127. * We use a stack based array at first and if we overflow that, we
  1128. * allocate a larger one from the heap, copy the stack based data in,
  1129. * and continue to grow the heap based one as needed.
  1130. */
  1131. static void
  1132. add_rdn_av( char *avstart, char *avend, int *rdn_av_countp,
  1133. struct berval **rdn_avsp, struct berval *avstack )
  1134. {
  1135. if ( *rdn_av_countp == 0 ) {
  1136. *rdn_avsp = avstack;
  1137. } else if ( *rdn_av_countp == SLAPI_DNNORM_INITIAL_RDN_AVS ) {
  1138. struct berval *tmpavs;
  1139. tmpavs = (struct berval *)slapi_ch_calloc(
  1140. SLAPI_DNNORM_INITIAL_RDN_AVS * 2, sizeof( struct berval ));
  1141. memcpy( tmpavs, *rdn_avsp,
  1142. SLAPI_DNNORM_INITIAL_RDN_AVS * sizeof( struct berval ));
  1143. *rdn_avsp = tmpavs;
  1144. } else if (( *rdn_av_countp % SLAPI_DNNORM_INITIAL_RDN_AVS ) == 0 ) {
  1145. *rdn_avsp = (struct berval *)slapi_ch_realloc( (char *)*rdn_avsp,
  1146. (*rdn_av_countp +
  1147. SLAPI_DNNORM_INITIAL_RDN_AVS)*sizeof(struct berval) );
  1148. }
  1149. /*
  1150. * Note: The bv_val's are just pointers into the dn itself. Also,
  1151. * we DO NOT zero-terminate the bv_val's. The sorting code in
  1152. * sort_rdn_avs() takes all of this into account.
  1153. */
  1154. (*rdn_avsp)[ *rdn_av_countp ].bv_val = avstart;
  1155. (*rdn_avsp)[ *rdn_av_countp ].bv_len = avend - avstart;
  1156. ++(*rdn_av_countp);
  1157. }
  1158. /*
  1159. * Reset RDN attribute value array, freeing memory if any was allocated.
  1160. */
  1161. static void
  1162. reset_rdn_avs( struct berval **rdn_avsp, int *rdn_av_countp )
  1163. {
  1164. if ( *rdn_av_countp > SLAPI_DNNORM_INITIAL_RDN_AVS ) {
  1165. slapi_ch_free( (void **)rdn_avsp );
  1166. }
  1167. *rdn_avsp = NULL;
  1168. *rdn_av_countp = 0;
  1169. }
  1170. /*
  1171. * Perform an in-place, case-insensitive sort of RDN attribute=value pieces.
  1172. * This function is always called with more than one element in "avs".
  1173. *
  1174. * Note that this is used by the DN normalization code, so if any changes
  1175. * are made to the comparison function used for sorting customers will need
  1176. * to rebuild their database/index files.
  1177. *
  1178. * Also note that the bv_val's in the "avas" array are not zero-terminated.
  1179. */
  1180. static void
  1181. sort_rdn_avs( struct berval *avs, int count, int escape )
  1182. {
  1183. int i, j, swaps;
  1184. /*
  1185. * Since we expect there to be a small number of AVs, we use a
  1186. * simple bubble sort. rdn_av_swap() only works correctly on
  1187. * adjacent values anyway.
  1188. */
  1189. for ( i = 0; i < count - 1; ++i ) {
  1190. swaps = 0;
  1191. for ( j = 0; j < count - 1; ++j ) {
  1192. if ( rdn_av_cmp( &avs[j], &avs[j+1] ) > 0 ) {
  1193. rdn_av_swap( &avs[j], &avs[j+1], escape );
  1194. ++swaps;
  1195. }
  1196. }
  1197. if ( swaps == 0 ) {
  1198. break; /* stop early if no swaps made during the last pass */
  1199. }
  1200. }
  1201. }
  1202. /*
  1203. * strcasecmp()-like function for RDN attribute values.
  1204. */
  1205. static int
  1206. rdn_av_cmp( struct berval *av1, struct berval *av2 )
  1207. {
  1208. int rc;
  1209. rc = strncasecmp( av1->bv_val, av2->bv_val,
  1210. ( av1->bv_len < av2->bv_len ) ? av1->bv_len : av2->bv_len );
  1211. if ( rc == 0 ) {
  1212. return( av1->bv_len - av2->bv_len ); /* longer is greater */
  1213. } else {
  1214. return( rc );
  1215. }
  1216. }
  1217. /*
  1218. * Swap two adjacent attribute=value pieces within an (R)DN.
  1219. * Avoid allocating any heap memory for reasonably small AVs.
  1220. */
  1221. static void
  1222. rdn_av_swap( struct berval *av1, struct berval *av2, int escape )
  1223. {
  1224. char *buf1, *buf2;
  1225. char stackbuf1[ SLAPI_DNNORM_SMALL_RDN_AV ];
  1226. char stackbuf2[ SLAPI_DNNORM_SMALL_RDN_AV ];
  1227. int len1, len2;
  1228. /*
  1229. * Copy the two avs into temporary buffers. We use stack-based buffers
  1230. * if the avs are small and allocate buffers from the heap to hold
  1231. * large values.
  1232. */
  1233. if (( len1 = av1->bv_len ) <= SLAPI_DNNORM_SMALL_RDN_AV ) {
  1234. buf1 = stackbuf1;
  1235. } else {
  1236. buf1 = slapi_ch_malloc( len1 );
  1237. }
  1238. memcpy( buf1, av1->bv_val, len1 );
  1239. if (( len2 = av2->bv_len ) <= SLAPI_DNNORM_SMALL_RDN_AV ) {
  1240. buf2 = stackbuf2;
  1241. } else {
  1242. buf2 = slapi_ch_malloc( len2 );
  1243. }
  1244. memcpy( buf2, av2->bv_val, len2 );
  1245. /*
  1246. * Copy av2 over av1 and reset length of av1.
  1247. */
  1248. memcpy( av1->bv_val, buf2, av2->bv_len );
  1249. av1->bv_len = len2;
  1250. /*
  1251. * Add separator character (+) and copy av1 into place.
  1252. * Also reset av2 pointer and length.
  1253. */
  1254. av2->bv_val = av1->bv_val + len2;
  1255. if (escape) {
  1256. *(av2->bv_val)++ = '\\';
  1257. PR_snprintf(av2->bv_val, 3, "%X", '+'); /* hexpair */
  1258. av2->bv_val += 2;
  1259. } else {
  1260. *(av2->bv_val)++ = '+';
  1261. }
  1262. memcpy( av2->bv_val, buf1, len1 );
  1263. av2->bv_len = len1;
  1264. /*
  1265. * Clean up.
  1266. */
  1267. if ( len1 > SLAPI_DNNORM_SMALL_RDN_AV ) {
  1268. slapi_ch_free( (void **)&buf1 );
  1269. }
  1270. if ( len2 > SLAPI_DNNORM_SMALL_RDN_AV ) {
  1271. slapi_ch_free( (void **)&buf2 );
  1272. }
  1273. }
  1274. /* Introduced for the upgrade tool. DON'T USE THIS API! */
  1275. char *
  1276. slapi_dn_normalize_original( char *dn )
  1277. {
  1278. /* LDAPDebug( LDAP_DEBUG_TRACE, "=> slapi_dn_normalize \"%s\"\n", dn, 0, 0 ); */
  1279. *(substr_dn_normalize_orig( dn, dn + strlen( dn ))) = '\0';
  1280. /* LDAPDebug( LDAP_DEBUG_TRACE, "<= slapi_dn_normalize \"%s\"\n", dn, 0, 0 ); */
  1281. return( dn );
  1282. }
  1283. /* Introduced for the upgrade tool. DON'T USE THIS API! */
  1284. char *
  1285. slapi_dn_normalize_case_original( char *dn )
  1286. {
  1287. /* LDAPDebug( LDAP_DEBUG_TRACE, "=> slapi_dn_normalize \"%s\"\n", dn, 0, 0 ); */
  1288. *(substr_dn_normalize_orig( dn, dn + strlen( dn ))) = '\0';
  1289. /* LDAPDebug( LDAP_DEBUG_TRACE, "<= slapi_dn_normalize \"%s\"\n", dn, 0, 0 ); */
  1290. /* normalize case */
  1291. return( slapi_dn_ignore_case( dn ));
  1292. }
  1293. /*
  1294. * DEPRECATED: this function does nothing.
  1295. * slapi_dn_normalize - put dn into a canonical format. the dn is
  1296. * normalized in place, as well as returned.
  1297. */
  1298. char *
  1299. slapi_dn_normalize( char *dn )
  1300. {
  1301. /* LDAPDebug( LDAP_DEBUG_TRACE, "=> slapi_dn_normalize \"%s\"\n", dn, 0, 0 ); */
  1302. *(substr_dn_normalize( dn, dn + strlen( dn ))) = '\0';
  1303. /* LDAPDebug( LDAP_DEBUG_TRACE, "<= slapi_dn_normalize \"%s\"\n", dn, 0, 0 ); */
  1304. return dn;
  1305. }
  1306. /*
  1307. * DEPRECATED: this function does nothing.
  1308. * Note that this routine normalizes to the end and doesn't null terminate
  1309. */
  1310. char *
  1311. slapi_dn_normalize_to_end( char *dn , char *end)
  1312. {
  1313. return ( substr_dn_normalize( dn, end ? end : dn + strlen( dn )) );
  1314. }
  1315. /*
  1316. * dn could contain UTF-8 multi-byte characters,
  1317. * which also need to be converted to the lower case.
  1318. */
  1319. char *
  1320. slapi_dn_ignore_case( char *dn )
  1321. {
  1322. unsigned char *s = NULL, *d = NULL;
  1323. int ssz, dsz;
  1324. /* normalize case (including UTF-8 multi-byte chars) */
  1325. for ( s = d = (unsigned char *)dn; s && *s; s += ssz, d += dsz ) {
  1326. slapi_utf8ToLower( s, d, &ssz, &dsz );
  1327. }
  1328. if (d) {
  1329. *d = '\0'; /* utf8ToLower result may be shorter than the original */
  1330. }
  1331. return( dn );
  1332. }
  1333. char *
  1334. dn_ignore_case_to_end( char *dn, char *end )
  1335. {
  1336. unsigned char *s = NULL, *d = NULL;
  1337. int ssz, dsz;
  1338. /* normalize case (including UTF-8 multi-byte chars) */
  1339. for (s = d = (unsigned char *)dn; s && s < (unsigned char *)end && *s;
  1340. s += ssz, d += dsz) {
  1341. slapi_utf8ToLower( s, d, &ssz, &dsz );
  1342. }
  1343. if (d) {
  1344. *d = '\0'; /* utf8ToLower result may be shorter than the original */
  1345. }
  1346. return( dn );
  1347. }
  1348. /*
  1349. * slapi_dn_normalize_case - put dn into a canonical form suitable for storing
  1350. * in a hash database. this involves normalizing the case as well as
  1351. * the format. the dn is normalized in place as well as returned.
  1352. * (DEPRECATED)
  1353. */
  1354. char *
  1355. slapi_dn_normalize_case( char *dn )
  1356. {
  1357. /* normalize format (DEPRECATED) noop */
  1358. slapi_dn_normalize( dn );
  1359. /* normalize case */
  1360. return( slapi_dn_ignore_case( dn ));
  1361. }
  1362. int
  1363. slapi_dn_normalize_case_ext(char *src, size_t src_len,
  1364. char **dest, size_t *dest_len)
  1365. {
  1366. int rc = slapi_dn_normalize_ext(src, src_len, dest, dest_len);
  1367. if (rc >= 0) {
  1368. dn_ignore_case_to_end(*dest, *dest + *dest_len);
  1369. }
  1370. return rc;
  1371. }
  1372. char *
  1373. slapi_create_dn_string_case(const char *fmt, ...)
  1374. {
  1375. char *src = NULL;
  1376. char *dest = NULL;
  1377. size_t dest_len = 0;
  1378. va_list ap;
  1379. int rc = 0;
  1380. if (NULL == fmt) {
  1381. return NULL;
  1382. }
  1383. va_start(ap, fmt);
  1384. src = PR_vsmprintf(fmt, ap);
  1385. va_end(ap);
  1386. rc = slapi_dn_normalize_ext(src, strlen(src), &dest, &dest_len);
  1387. if (rc < 0) {
  1388. slapi_ch_free_string(&src);
  1389. } else if (rc == 0) { /* src is passed in. */
  1390. *(dest + dest_len) = '\0';
  1391. } else {
  1392. slapi_ch_free_string(&src);
  1393. }
  1394. return slapi_dn_ignore_case(dest);
  1395. }
  1396. /*
  1397. * slapi_dn_beparent - return a copy of the dn of dn's parent,
  1398. * NULL if the DN is a suffix of the backend.
  1399. */
  1400. char *
  1401. slapi_dn_beparent(
  1402. Slapi_PBlock *pb,
  1403. const char *dn
  1404. )
  1405. {
  1406. char *r= NULL;
  1407. if ( dn != NULL && *dn != '\0')
  1408. {
  1409. if(!slapi_dn_isbesuffix( pb, dn ))
  1410. {
  1411. r= slapi_dn_parent( dn );
  1412. }
  1413. }
  1414. return r;
  1415. }
  1416. /*
  1417. * This function is used for speed. Instead of returning a newly allocated
  1418. * dn string that contains the parent, this function just returns a pointer
  1419. * to the address _within_ the given string where the parent dn of the
  1420. * given dn starts e.g. if you call this with "dc=example,dc=com", the
  1421. * function will return "dc=com" - that is, the char* returned will be the
  1422. * address of the 'd' after the ',' in "dc=example,dc=com". This function
  1423. * also checks for bogus things like consecutive ocurrances of unquoted
  1424. * separators e.g. DNs like cn=foo,,,,,,,,,,,cn=bar,,,,,,,
  1425. * This function is useful for "interating" over a DN returning the ancestors
  1426. * of the given dn e.g.
  1427. *
  1428. * const char *dn = somedn;
  1429. * while (dn = slapi_dn_find_parent(dn)) {
  1430. * see if parent exists
  1431. * etc.
  1432. * }
  1433. */
  1434. const char*
  1435. slapi_dn_find_parent_ext( const char *dn, int is_tombstone )
  1436. {
  1437. const char *s;
  1438. int inquote;
  1439. char *head;
  1440. if ( dn == NULL || *dn == '\0' ) {
  1441. return( NULL );
  1442. }
  1443. /*
  1444. * An X.500-style distinguished name looks like this:
  1445. * foo=bar,sha=baz,...
  1446. */
  1447. head = (char *)dn;
  1448. if (is_tombstone) {
  1449. /* if it's a tombstone entry's DN,
  1450. * skip nsuniqueid=* part and do the job. */
  1451. if (0 == strncasecmp(dn, SLAPI_ATTR_UNIQUEID, 10)) {
  1452. /* exception: RUV_STORAGE_ENTRY_UNIQUEID */
  1453. /* dn is normalized */
  1454. if (0 == strncasecmp(dn + 11, RUV_STORAGE_ENTRY_UNIQUEID,
  1455. sizeof(RUV_STORAGE_ENTRY_UNIQUEID) - 1)) {
  1456. head = (char *)dn;
  1457. } else {
  1458. head = strchr(dn, ',');
  1459. if (head) {
  1460. head++;
  1461. } else {
  1462. head = (char *)dn;
  1463. }
  1464. }
  1465. }
  1466. }
  1467. inquote = 0;
  1468. for ( s = head; *s; s++ ) {
  1469. if ( *s == '\\' ) {
  1470. if ( *(s + 1) )
  1471. s++;
  1472. continue;
  1473. }
  1474. if ( inquote ) {
  1475. if ( *s == '"' )
  1476. inquote = 0;
  1477. } else {
  1478. if ( *s == '"' )
  1479. inquote = 1;
  1480. else {
  1481. if ( DNSEPARATOR( *s ) ) {
  1482. while ( *s && DNSEPARATOR( *s ) ) {
  1483. ++s;
  1484. }
  1485. if (*s) {
  1486. return( s );
  1487. }
  1488. }
  1489. }
  1490. }
  1491. }
  1492. return( NULL );
  1493. }
  1494. const char*
  1495. slapi_dn_find_parent( const char *dn )
  1496. {
  1497. return slapi_dn_find_parent_ext(dn, 0);
  1498. }
  1499. char*
  1500. slapi_dn_parent_ext( const char *dn, int is_tombstone )
  1501. {
  1502. const char *s = slapi_dn_find_parent_ext(dn, is_tombstone);
  1503. if ( s == NULL || *s == '\0' ) {
  1504. return( NULL );
  1505. }
  1506. return( slapi_ch_strdup( s ) );
  1507. }
  1508. char*
  1509. slapi_dn_parent( const char *dn )
  1510. {
  1511. const char *s = slapi_dn_find_parent(dn);
  1512. if ( s == NULL || *s == '\0' ) {
  1513. return( NULL );
  1514. }
  1515. return( slapi_ch_strdup( s ) );
  1516. }
  1517. /*
  1518. * slapi_dn_issuffix - tells whether suffix is a suffix of dn. both dn
  1519. * and suffix must be normalized.
  1520. */
  1521. int
  1522. slapi_dn_issuffix(const char *dn, const char *suffix)
  1523. {
  1524. int dnlen, suffixlen;
  1525. if ( dn==NULL || suffix==NULL)
  1526. {
  1527. return( 0 );
  1528. }
  1529. suffixlen = strlen( suffix );
  1530. dnlen = strlen( dn );
  1531. if ( suffixlen > dnlen )
  1532. {
  1533. return( 0 );
  1534. }
  1535. if ( suffixlen == 0 )
  1536. {
  1537. return ( 1 );
  1538. }
  1539. return( (slapi_utf8casecmp( (unsigned char *)(dn + dnlen - suffixlen),
  1540. (unsigned char *)suffix ) == 0)
  1541. && ( (dnlen == suffixlen) || DNSEPARATOR(dn[dnlen-suffixlen-1])) );
  1542. }
  1543. int
  1544. slapi_dn_isbesuffix( Slapi_PBlock *pb, const char *dn )
  1545. {
  1546. int r;
  1547. Slapi_DN sdn;
  1548. slapi_sdn_init_dn_byref(&sdn,dn);
  1549. r= slapi_be_issuffix( pb->pb_backend, &sdn );
  1550. slapi_sdn_done(&sdn);
  1551. return r;
  1552. }
  1553. /*
  1554. * slapi_dn_isparent - returns non-zero if parentdn is the parent of childdn,
  1555. * 0 otherwise
  1556. */
  1557. int
  1558. slapi_dn_isparent( const char *parentdn, const char *childdn )
  1559. {
  1560. char *realparentdn, *copyparentdn;
  1561. int rc;
  1562. /* child is root - has no parent */
  1563. if ( childdn == NULL || *childdn == '\0' ) {
  1564. return( 0 );
  1565. }
  1566. /* construct the actual parent dn and normalize it */
  1567. if ( (realparentdn = slapi_dn_parent( childdn )) == NULL ) {
  1568. return( parentdn == NULL || *parentdn == '\0' );
  1569. }
  1570. slapi_dn_normalize( realparentdn );
  1571. /* normalize the purported parent dn */
  1572. copyparentdn = slapi_ch_strdup( (char *)parentdn );
  1573. slapi_dn_normalize( copyparentdn );
  1574. /* compare them */
  1575. rc = ! strcasecmp( realparentdn, copyparentdn );
  1576. slapi_ch_free( (void**)&copyparentdn );
  1577. slapi_ch_free( (void**)&realparentdn );
  1578. return( rc );
  1579. }
  1580. /*
  1581. * Function: slapi_dn_isroot
  1582. *
  1583. * Returns: 1 if "dn" is the root dn
  1584. * 0 otherwise.
  1585. * dn must be normalized
  1586. *
  1587. */
  1588. int
  1589. slapi_dn_isroot( const char *dn )
  1590. {
  1591. int rc;
  1592. char *rootdn;
  1593. if ( NULL == dn ) {
  1594. return( 0 );
  1595. }
  1596. if ( NULL == (rootdn = config_get_rootdn())) {
  1597. return( 0 );
  1598. }
  1599. /* note: global root dn is normalized when read from config. file */
  1600. rc = (strcasecmp( rootdn, dn ) == 0);
  1601. slapi_ch_free ( (void **) &rootdn );
  1602. return( rc );
  1603. }
  1604. int
  1605. slapi_is_rootdse( const char *dn )
  1606. {
  1607. if ( NULL != dn )
  1608. {
  1609. if ( *dn == '\0' )
  1610. {
  1611. return 1;
  1612. }
  1613. }
  1614. return 0;
  1615. }
  1616. int
  1617. slapi_rdn2typeval(
  1618. char *rdn,
  1619. char **type,
  1620. struct berval *bv
  1621. )
  1622. {
  1623. char *s;
  1624. if ( (s = strchr( rdn, '=' )) == NULL ) {
  1625. return( -1 );
  1626. }
  1627. *s++ = '\0';
  1628. *type = rdn;
  1629. /* MAB 9 Oct 00 : explicit bug fix of 515715
  1630. implicit bug fix of 394800 (can't reproduce anymore)
  1631. When adding the rdn attribute in the entry, we need to remove
  1632. all special escaped characters included in the value itself,
  1633. i.e., strings like "\;" must be converted to ";" and so on... */
  1634. strcpy_unescape_value(s,s);
  1635. bv->bv_val = s;
  1636. bv->bv_len = strlen( s );
  1637. return( 0 );
  1638. }
  1639. /*
  1640. * Add an RDN to a DN, getting back the new DN.
  1641. */
  1642. char *
  1643. slapi_dn_plus_rdn(const char *dn, const char *rdn)
  1644. {
  1645. /* rdn + separator + dn + null */
  1646. char *newdn = slapi_ch_smprintf("%s,%s", rdn, dn);
  1647. return newdn;
  1648. }
  1649. /* ====== Slapi_DN functions ====== */
  1650. #ifdef SDN_DEBUG
  1651. #define SDN_DUMP(sdn,name) sdn_dump(sdn,name)
  1652. static void sdn_dump( const Slapi_DN *sdn, const char *text);
  1653. #else
  1654. #define SDN_DUMP(sdn,name) ((void)0)
  1655. #endif
  1656. #ifndef SLAPI_DN_COUNTERS
  1657. #undef DEBUG /* disable counters */
  1658. #endif
  1659. #include <prcountr.h>
  1660. static int counters_created= 0;
  1661. PR_DEFINE_COUNTER(slapi_sdn_counter_created);
  1662. PR_DEFINE_COUNTER(slapi_sdn_counter_deleted);
  1663. PR_DEFINE_COUNTER(slapi_sdn_counter_exist);
  1664. PR_DEFINE_COUNTER(slapi_sdn_counter_dn_created);
  1665. PR_DEFINE_COUNTER(slapi_sdn_counter_dn_deleted);
  1666. PR_DEFINE_COUNTER(slapi_sdn_counter_dn_exist);
  1667. PR_DEFINE_COUNTER(slapi_sdn_counter_ndn_created);
  1668. PR_DEFINE_COUNTER(slapi_sdn_counter_ndn_deleted);
  1669. PR_DEFINE_COUNTER(slapi_sdn_counter_ndn_exist);
  1670. PR_DEFINE_COUNTER(slapi_sdn_counter_udn_created);
  1671. PR_DEFINE_COUNTER(slapi_sdn_counter_udn_deleted);
  1672. PR_DEFINE_COUNTER(slapi_sdn_counter_udn_exist);
  1673. static void
  1674. sdn_create_counters()
  1675. {
  1676. PR_CREATE_COUNTER(slapi_sdn_counter_created,"Slapi_DN","created","");
  1677. PR_CREATE_COUNTER(slapi_sdn_counter_deleted,"Slapi_DN","deleted","");
  1678. PR_CREATE_COUNTER(slapi_sdn_counter_exist,"Slapi_DN","exist","");
  1679. PR_CREATE_COUNTER(slapi_sdn_counter_dn_created,"Slapi_DN","internal_dn_created","");
  1680. PR_CREATE_COUNTER(slapi_sdn_counter_dn_deleted,"Slapi_DN","internal_dn_deleted","");
  1681. PR_CREATE_COUNTER(slapi_sdn_counter_dn_exist,"Slapi_DN","internal_dn_exist","");
  1682. PR_CREATE_COUNTER(slapi_sdn_counter_ndn_created,"Slapi_DN","internal_ndn_created","");
  1683. PR_CREATE_COUNTER(slapi_sdn_counter_ndn_deleted,"Slapi_DN","internal_ndn_deleted","");
  1684. PR_CREATE_COUNTER(slapi_sdn_counter_ndn_exist,"Slapi_DN","internal_ndn_exist","");
  1685. PR_CREATE_COUNTER(slapi_sdn_counter_udn_created,"Slapi_DN","internal_udn_created","");
  1686. PR_CREATE_COUNTER(slapi_sdn_counter_udn_deleted,"Slapi_DN","internal_udn_deleted","");
  1687. PR_CREATE_COUNTER(slapi_sdn_counter_udn_exist,"Slapi_DN","internal_udn_exist","");
  1688. counters_created= 1;
  1689. }
  1690. #define FLAG_ALLOCATED 0
  1691. #define FLAG_DN 1
  1692. #define FLAG_NDN 2
  1693. #define FLAG_UDN 3
  1694. Slapi_DN *
  1695. slapi_sdn_new()
  1696. {
  1697. Slapi_DN *sdn= (Slapi_DN *)slapi_ch_malloc(sizeof(Slapi_DN));
  1698. slapi_sdn_init(sdn);
  1699. sdn->flag= slapi_setbit_uchar(sdn->flag,FLAG_ALLOCATED);
  1700. SDN_DUMP( sdn, "slapi_sdn_new");
  1701. PR_INCREMENT_COUNTER(slapi_sdn_counter_created);
  1702. PR_INCREMENT_COUNTER(slapi_sdn_counter_exist);
  1703. return sdn;
  1704. }
  1705. /*
  1706. * WARNING:
  1707. * Do not call slapi_sdn_init and its sibling APIs against Slapi_DN
  1708. * allocated by slapi_sdn_new. slapi_sdn_init clears all bits in the flag.
  1709. * If sdn is allocated by slapi_sdn_new, the FLAG_ALLOCATED bit is cleared
  1710. * and slapi_sdn_free won't free Slapi_DN.
  1711. */
  1712. Slapi_DN *
  1713. slapi_sdn_init(Slapi_DN *sdn)
  1714. {
  1715. sdn->flag= 0;
  1716. sdn->udn= NULL;
  1717. sdn->dn= NULL;
  1718. sdn->ndn= NULL;
  1719. sdn->ndn_len=0;
  1720. if(!counters_created)
  1721. {
  1722. sdn_create_counters();
  1723. }
  1724. return sdn;
  1725. }
  1726. Slapi_DN *
  1727. slapi_sdn_init_dn_byref(Slapi_DN *sdn,const char *dn)
  1728. {
  1729. slapi_sdn_init(sdn);
  1730. slapi_sdn_set_dn_byref(sdn, dn);
  1731. return sdn;
  1732. }
  1733. Slapi_DN *
  1734. slapi_sdn_init_dn_byval(Slapi_DN *sdn,const char *dn)
  1735. {
  1736. slapi_sdn_init(sdn);
  1737. slapi_sdn_set_dn_byval(sdn,dn);
  1738. return sdn;
  1739. }
  1740. Slapi_DN *
  1741. slapi_sdn_init_dn_passin(Slapi_DN *sdn,const char *dn)
  1742. {
  1743. slapi_sdn_init(sdn);
  1744. slapi_sdn_set_dn_passin(sdn,dn);
  1745. return sdn;
  1746. }
  1747. /* use when dn is already normalized (but case is yet touched) */
  1748. Slapi_DN *
  1749. slapi_sdn_init_normdn_byref(Slapi_DN *sdn, const char *dn)
  1750. {
  1751. slapi_sdn_init(sdn);
  1752. if(dn == NULL) {
  1753. sdn->ndn_len = 0;
  1754. } else {
  1755. sdn->ndn_len = strlen(dn);
  1756. sdn->dn = dn;
  1757. sdn->flag = slapi_unsetbit_uchar(sdn->flag, FLAG_DN);
  1758. }
  1759. return sdn;
  1760. }
  1761. /* use when dn is already normalized (but case is yet touched) */
  1762. Slapi_DN *
  1763. slapi_sdn_init_normdn_byval(Slapi_DN *sdn, const char *dn)
  1764. {
  1765. slapi_sdn_init(sdn);
  1766. if(dn == NULL) {
  1767. sdn->ndn_len = 0;
  1768. } else {
  1769. sdn->ndn_len = strlen(dn);
  1770. sdn->dn= slapi_ch_strdup(dn);
  1771. sdn->flag = slapi_setbit_uchar(sdn->flag, FLAG_DN);
  1772. }
  1773. return sdn;
  1774. }
  1775. /* use when dn is already normalized (but case is yet touched) */
  1776. Slapi_DN *
  1777. slapi_sdn_init_normdn_passin(Slapi_DN *sdn, const char *dn)
  1778. {
  1779. slapi_sdn_init(sdn);
  1780. if(dn == NULL) {
  1781. sdn->ndn_len = 0;
  1782. } else {
  1783. sdn->ndn_len = strlen(dn);
  1784. sdn->dn = dn;
  1785. sdn->flag = slapi_setbit_uchar(sdn->flag, FLAG_DN);
  1786. }
  1787. return sdn;
  1788. }
  1789. Slapi_DN *
  1790. slapi_sdn_init_ndn_byref(Slapi_DN *sdn,const char *dn)
  1791. {
  1792. slapi_sdn_init(sdn);
  1793. slapi_sdn_set_ndn_byref(sdn,dn);
  1794. return sdn;
  1795. }
  1796. Slapi_DN *
  1797. slapi_sdn_init_ndn_byval(Slapi_DN *sdn,const char *dn)
  1798. {
  1799. slapi_sdn_init(sdn);
  1800. slapi_sdn_set_ndn_byval(sdn,dn);
  1801. return sdn;
  1802. }
  1803. Slapi_DN *
  1804. slapi_sdn_new_dn_byval(const char *dn)
  1805. {
  1806. Slapi_DN *sdn= slapi_sdn_new();
  1807. slapi_sdn_set_dn_byval(sdn,dn);
  1808. SDN_DUMP( sdn, "slapi_sdn_new_dn_byval");
  1809. return sdn;
  1810. }
  1811. Slapi_DN *
  1812. slapi_sdn_new_ndn_byval(const char *ndn)
  1813. {
  1814. Slapi_DN *sdn= slapi_sdn_new();
  1815. slapi_sdn_set_ndn_byval(sdn,ndn);
  1816. SDN_DUMP( sdn, "slapi_sdn_new_ndn_byval");
  1817. return sdn;
  1818. }
  1819. Slapi_DN *
  1820. slapi_sdn_new_dn_byref(const char *dn)
  1821. {
  1822. Slapi_DN *sdn= slapi_sdn_new();
  1823. slapi_sdn_set_dn_byref(sdn,dn);
  1824. SDN_DUMP( sdn, "slapi_sdn_new_dn_byref");
  1825. return sdn;
  1826. }
  1827. Slapi_DN *
  1828. slapi_sdn_new_dn_passin(const char *dn)
  1829. {
  1830. Slapi_DN *sdn= slapi_sdn_new();
  1831. slapi_sdn_set_dn_passin(sdn,dn);
  1832. SDN_DUMP( sdn, "slapi_sdn_new_dn_passin");
  1833. return sdn;
  1834. }
  1835. Slapi_DN *
  1836. slapi_sdn_new_ndn_byref(const char *ndn)
  1837. {
  1838. Slapi_DN *sdn= slapi_sdn_new();
  1839. slapi_sdn_set_ndn_byref(sdn,ndn);
  1840. SDN_DUMP( sdn, "slapi_sdn_new_ndn_byref");
  1841. return sdn;
  1842. }
  1843. /* use when dn is already fully normalized */
  1844. Slapi_DN *
  1845. slapi_sdn_new_ndn_passin(const char *ndn)
  1846. {
  1847. Slapi_DN *sdn = slapi_sdn_new();
  1848. slapi_sdn_set_ndn_passin(sdn, ndn);
  1849. SDN_DUMP( sdn, "slapi_sdn_new_ndn_passin");
  1850. return sdn;
  1851. }
  1852. /* use when dn is already normalized */
  1853. Slapi_DN *
  1854. slapi_sdn_new_normdn_byref(const char *normdn)
  1855. {
  1856. Slapi_DN *sdn = slapi_sdn_new();
  1857. slapi_sdn_set_normdn_byref(sdn, normdn);
  1858. SDN_DUMP( sdn, "slapi_sdn_new_normdn_byref");
  1859. return sdn;
  1860. }
  1861. /* use when dn is already normalized */
  1862. Slapi_DN *
  1863. slapi_sdn_new_normdn_passin(const char *normdn)
  1864. {
  1865. Slapi_DN *sdn = slapi_sdn_new();
  1866. slapi_sdn_set_normdn_passin(sdn, normdn);
  1867. SDN_DUMP( sdn, "slapi_sdn_new_normdn_passin");
  1868. return sdn;
  1869. }
  1870. /* use when dn is already normalized */
  1871. Slapi_DN *
  1872. slapi_sdn_new_normdn_byval(const char *normdn)
  1873. {
  1874. Slapi_DN *sdn = slapi_sdn_new();
  1875. slapi_sdn_set_normdn_byval(sdn, normdn);
  1876. SDN_DUMP( sdn, "slapi_sdn_new_normdn_byval");
  1877. return sdn;
  1878. }
  1879. Slapi_DN *
  1880. slapi_sdn_set_dn_byval(Slapi_DN *sdn, const char *dn)
  1881. {
  1882. slapi_sdn_done(sdn);
  1883. sdn->flag= slapi_setbit_uchar(sdn->flag,FLAG_UDN);
  1884. if(dn!=NULL)
  1885. {
  1886. sdn->udn= slapi_ch_strdup(dn);
  1887. PR_INCREMENT_COUNTER(slapi_sdn_counter_udn_created);
  1888. PR_INCREMENT_COUNTER(slapi_sdn_counter_udn_exist);
  1889. }
  1890. return sdn;
  1891. }
  1892. Slapi_DN *
  1893. slapi_sdn_set_dn_byref(Slapi_DN *sdn, const char *dn)
  1894. {
  1895. slapi_sdn_done(sdn);
  1896. sdn->flag= slapi_unsetbit_uchar(sdn->flag,FLAG_UDN);
  1897. sdn->udn= dn;
  1898. return sdn;
  1899. }
  1900. Slapi_DN *
  1901. slapi_sdn_set_dn_passin(Slapi_DN *sdn, const char *dn)
  1902. {
  1903. slapi_sdn_done(sdn);
  1904. sdn->flag= slapi_setbit_uchar(sdn->flag,FLAG_UDN);
  1905. sdn->udn= dn;
  1906. if(dn!=NULL)
  1907. {
  1908. PR_INCREMENT_COUNTER(slapi_sdn_counter_udn_created);
  1909. PR_INCREMENT_COUNTER(slapi_sdn_counter_udn_exist);
  1910. }
  1911. return sdn;
  1912. }
  1913. Slapi_DN *
  1914. slapi_sdn_set_normdn_byref(Slapi_DN *sdn, const char *normdn)
  1915. {
  1916. slapi_sdn_done(sdn);
  1917. sdn->flag = slapi_unsetbit_uchar(sdn->flag, FLAG_DN);
  1918. sdn->dn = normdn;
  1919. if(normdn == NULL) {
  1920. sdn->ndn_len = 0;
  1921. } else {
  1922. sdn->ndn_len = strlen(normdn);
  1923. }
  1924. return sdn;
  1925. }
  1926. Slapi_DN *
  1927. slapi_sdn_set_normdn_passin(Slapi_DN *sdn, const char *normdn)
  1928. {
  1929. slapi_sdn_done(sdn);
  1930. sdn->flag = slapi_setbit_uchar(sdn->flag, FLAG_DN);
  1931. sdn->dn = normdn;
  1932. if(normdn == NULL) {
  1933. sdn->ndn_len = 0;
  1934. } else {
  1935. sdn->ndn_len = strlen(normdn);
  1936. PR_INCREMENT_COUNTER(slapi_sdn_counter_dn_created);
  1937. PR_INCREMENT_COUNTER(slapi_sdn_counter_dn_exist);
  1938. }
  1939. return sdn;
  1940. }
  1941. Slapi_DN *
  1942. slapi_sdn_set_normdn_byval(Slapi_DN *sdn, const char *normdn)
  1943. {
  1944. slapi_sdn_done(sdn);
  1945. sdn->flag = slapi_setbit_uchar(sdn->flag, FLAG_DN);
  1946. if(normdn == NULL) {
  1947. sdn->dn = NULL;
  1948. sdn->ndn_len = 0;
  1949. } else {
  1950. sdn->dn = slapi_ch_strdup(normdn);
  1951. sdn->ndn_len = strlen(normdn);
  1952. PR_INCREMENT_COUNTER(slapi_sdn_counter_dn_created);
  1953. PR_INCREMENT_COUNTER(slapi_sdn_counter_dn_exist);
  1954. }
  1955. return sdn;
  1956. }
  1957. Slapi_DN *
  1958. slapi_sdn_set_ndn_byval(Slapi_DN *sdn, const char *ndn)
  1959. {
  1960. slapi_sdn_done(sdn);
  1961. sdn->flag= slapi_setbit_uchar(sdn->flag,FLAG_NDN);
  1962. if(ndn!=NULL)
  1963. {
  1964. sdn->ndn= slapi_ch_strdup(ndn);
  1965. sdn->ndn_len=strlen(ndn);
  1966. PR_INCREMENT_COUNTER(slapi_sdn_counter_ndn_created);
  1967. PR_INCREMENT_COUNTER(slapi_sdn_counter_ndn_exist);
  1968. }
  1969. return sdn;
  1970. }
  1971. Slapi_DN *
  1972. slapi_sdn_set_ndn_byref(Slapi_DN *sdn, const char *ndn)
  1973. {
  1974. slapi_sdn_done(sdn);
  1975. sdn->flag= slapi_unsetbit_uchar(sdn->flag,FLAG_NDN);
  1976. sdn->ndn= ndn;
  1977. if(ndn == NULL) {
  1978. sdn->ndn_len=0;
  1979. } else {
  1980. sdn->ndn_len=strlen(ndn);
  1981. }
  1982. return sdn;
  1983. }
  1984. Slapi_DN *
  1985. slapi_sdn_set_ndn_passin(Slapi_DN *sdn, const char *ndn)
  1986. {
  1987. slapi_sdn_done(sdn);
  1988. sdn->flag = slapi_setbit_uchar(sdn->flag, FLAG_NDN);
  1989. sdn->ndn = ndn;
  1990. if (ndn == NULL) {
  1991. sdn->ndn_len = 0;
  1992. } else {
  1993. sdn->ndn_len = strlen(ndn);
  1994. }
  1995. return sdn;
  1996. }
  1997. /*
  1998. * Set the RDN of the DN.
  1999. */
  2000. Slapi_DN *
  2001. slapi_sdn_set_rdn(Slapi_DN *sdn, const Slapi_RDN *rdn)
  2002. {
  2003. const char *rawrdn= slapi_rdn_get_rdn(rdn);
  2004. if(slapi_sdn_isempty(sdn))
  2005. {
  2006. slapi_sdn_set_dn_byval(sdn,rawrdn);
  2007. }
  2008. else
  2009. {
  2010. /* NewDN= NewRDN + OldParent */
  2011. char *parentdn = slapi_dn_parent(slapi_sdn_get_dn(sdn));
  2012. /*
  2013. * using slapi_ch_smprintf is okay since
  2014. * newdn is set to sdn as a pre-normalized dn.
  2015. */
  2016. char *newdn = slapi_ch_smprintf("%s,%s", rawrdn, parentdn);
  2017. slapi_ch_free((void**)&parentdn);
  2018. slapi_sdn_set_dn_passin(sdn,newdn);
  2019. }
  2020. return sdn;
  2021. }
  2022. /*
  2023. * Add the RDN to the DN.
  2024. */
  2025. Slapi_DN *
  2026. slapi_sdn_add_rdn(Slapi_DN *sdn, const Slapi_RDN *rdn)
  2027. {
  2028. const char *rawrdn = slapi_rdn_get_rdn(rdn);
  2029. if(slapi_sdn_isempty(sdn))
  2030. {
  2031. slapi_sdn_set_dn_byval(sdn,rawrdn);
  2032. }
  2033. else
  2034. {
  2035. /* NewDN= NewRDN + DN */
  2036. const char *dn= slapi_sdn_get_dn(sdn);
  2037. /*
  2038. * using slapi_ch_smprintf is okay since
  2039. * newdn is set to sdn as a pre-normalized dn.
  2040. */
  2041. char *newdn = slapi_ch_smprintf("%s,%s", rawrdn, dn);
  2042. slapi_sdn_set_dn_passin(sdn,newdn);
  2043. }
  2044. return sdn;
  2045. }
  2046. /*
  2047. * Set the parent of the DN.
  2048. */
  2049. Slapi_DN *
  2050. slapi_sdn_set_parent(Slapi_DN *sdn, const Slapi_DN *parentdn)
  2051. {
  2052. if(slapi_sdn_isempty(sdn))
  2053. {
  2054. slapi_sdn_copy(parentdn, sdn);
  2055. }
  2056. else
  2057. {
  2058. /* NewDN= OldRDN + NewParent */
  2059. Slapi_RDN rdn;
  2060. const char *rawrdn;
  2061. slapi_rdn_init_dn(&rdn, slapi_sdn_get_dn(sdn));
  2062. rawrdn= slapi_rdn_get_rdn(&rdn);
  2063. if(slapi_sdn_isempty(parentdn))
  2064. {
  2065. slapi_sdn_set_dn_byval(sdn,rawrdn);
  2066. }
  2067. else
  2068. {
  2069. char *newdn =
  2070. slapi_ch_smprintf("%s,%s", rawrdn, slapi_sdn_get_dn(parentdn));
  2071. slapi_sdn_set_dn_passin(sdn, newdn);
  2072. }
  2073. slapi_rdn_done(&rdn);
  2074. }
  2075. return sdn;
  2076. }
  2077. void
  2078. slapi_sdn_done(Slapi_DN *sdn)
  2079. {
  2080. /* sdn_dump( sdn, "slapi_sdn_done"); */
  2081. if(sdn==NULL)
  2082. {
  2083. return;
  2084. }
  2085. if(sdn->dn!=NULL)
  2086. {
  2087. if(slapi_isbitset_uchar(sdn->flag,FLAG_DN))
  2088. {
  2089. slapi_ch_free((void**)&(sdn->dn));
  2090. PR_INCREMENT_COUNTER(slapi_sdn_counter_dn_deleted);
  2091. PR_DECREMENT_COUNTER(slapi_sdn_counter_dn_exist);
  2092. }
  2093. else
  2094. {
  2095. sdn->dn= NULL;
  2096. }
  2097. }
  2098. sdn->flag= slapi_unsetbit_uchar(sdn->flag,FLAG_DN);
  2099. if(sdn->ndn!=NULL)
  2100. {
  2101. if(slapi_isbitset_uchar(sdn->flag,FLAG_NDN))
  2102. {
  2103. slapi_ch_free((void**)&(sdn->ndn));
  2104. PR_INCREMENT_COUNTER(slapi_sdn_counter_ndn_deleted);
  2105. PR_DECREMENT_COUNTER(slapi_sdn_counter_ndn_exist);
  2106. }
  2107. else
  2108. {
  2109. sdn->ndn= NULL;
  2110. }
  2111. }
  2112. sdn->flag= slapi_unsetbit_uchar(sdn->flag,FLAG_NDN);
  2113. sdn->ndn_len=0;
  2114. if(sdn->udn!=NULL)
  2115. {
  2116. if(slapi_isbitset_uchar(sdn->flag,FLAG_UDN))
  2117. {
  2118. slapi_ch_free((void**)&(sdn->udn));
  2119. PR_INCREMENT_COUNTER(slapi_sdn_counter_udn_deleted);
  2120. PR_DECREMENT_COUNTER(slapi_sdn_counter_udn_exist);
  2121. }
  2122. else
  2123. {
  2124. sdn->udn= NULL;
  2125. }
  2126. }
  2127. sdn->flag= slapi_unsetbit_uchar(sdn->flag,FLAG_UDN);
  2128. }
  2129. void
  2130. slapi_sdn_free(Slapi_DN **sdn)
  2131. {
  2132. if(sdn!=NULL && *sdn!=NULL)
  2133. {
  2134. int is_allocated = 0;
  2135. SDN_DUMP( *sdn, "slapi_sdn_free");
  2136. is_allocated = slapi_isbitset_uchar((*sdn)->flag, FLAG_ALLOCATED);
  2137. slapi_sdn_done(*sdn);
  2138. if(is_allocated)
  2139. {
  2140. slapi_ch_free((void**)sdn);
  2141. PR_INCREMENT_COUNTER(slapi_sdn_counter_deleted);
  2142. PR_DECREMENT_COUNTER(slapi_sdn_counter_exist);
  2143. }
  2144. }
  2145. }
  2146. const char *
  2147. slapi_sdn_get_dn(const Slapi_DN *sdn)
  2148. {
  2149. if (NULL == sdn) {
  2150. return NULL;
  2151. }
  2152. if (sdn->dn) {
  2153. return sdn->dn;
  2154. } else if (sdn->ndn) {
  2155. return sdn->ndn;
  2156. } else if (sdn->udn) {
  2157. char *udn = slapi_ch_strdup(sdn->udn);
  2158. char *normed = NULL;
  2159. size_t dnlen = 0;
  2160. Slapi_DN *ncsdn = (Slapi_DN*)sdn; /* non-const Slapi_DN */
  2161. int rc = slapi_dn_normalize_ext(udn, 0, &normed, &dnlen);
  2162. if (rc == 0) { /* udn is passed in */
  2163. *(normed + dnlen) = '\0';
  2164. ncsdn->dn = normed;
  2165. ncsdn->ndn_len = dnlen;
  2166. ncsdn->flag = slapi_setbit_uchar(sdn->flag, FLAG_DN);
  2167. PR_INCREMENT_COUNTER(slapi_sdn_counter_dn_created);
  2168. PR_INCREMENT_COUNTER(slapi_sdn_counter_dn_exist);
  2169. } else if (rc > 0) { /* rc > 0 */
  2170. slapi_ch_free_string(&udn);
  2171. ncsdn->dn = normed;
  2172. ncsdn->ndn_len = dnlen;
  2173. ncsdn->flag = slapi_setbit_uchar(sdn->flag, FLAG_DN);
  2174. PR_INCREMENT_COUNTER(slapi_sdn_counter_dn_created);
  2175. PR_INCREMENT_COUNTER(slapi_sdn_counter_dn_exist);
  2176. } else { /* else (rc < 0); normalization failed. return NULL */
  2177. slapi_ch_free_string(&udn);
  2178. }
  2179. return sdn->dn;
  2180. } else {
  2181. return NULL;
  2182. }
  2183. }
  2184. const char *
  2185. slapi_sdn_get_ndn(const Slapi_DN *sdn)
  2186. {
  2187. if (NULL == sdn) {
  2188. return NULL;
  2189. }
  2190. if (sdn->ndn) {
  2191. return sdn->ndn;
  2192. } else if (sdn->dn || sdn->udn) {
  2193. Slapi_DN *ncsdn = (Slapi_DN*)sdn; /* non-const Slapi_DN */
  2194. char *ndn = slapi_ch_strdup(slapi_sdn_get_dn(sdn));
  2195. slapi_dn_ignore_case(ndn); /* ignore case */
  2196. ncsdn->ndn = ndn;
  2197. ncsdn->flag = slapi_setbit_uchar(sdn->flag, FLAG_NDN);
  2198. PR_INCREMENT_COUNTER(slapi_sdn_counter_ndn_created);
  2199. PR_INCREMENT_COUNTER(slapi_sdn_counter_ndn_exist);
  2200. return ndn;
  2201. } else {
  2202. return NULL;
  2203. }
  2204. }
  2205. const char *
  2206. slapi_sdn_get_udn(const Slapi_DN *sdn)
  2207. {
  2208. if (sdn->udn) {
  2209. return sdn->udn;
  2210. } else if (sdn->dn) {
  2211. return sdn->dn;
  2212. } else if (sdn->ndn) {
  2213. return sdn->ndn;
  2214. } else {
  2215. return NULL;
  2216. }
  2217. }
  2218. void
  2219. slapi_sdn_get_parent_ext(const Slapi_DN *sdn,
  2220. Slapi_DN *sdn_parent,
  2221. int is_tombstone)
  2222. {
  2223. const char *parentdn =
  2224. slapi_dn_parent_ext(slapi_sdn_get_dn(sdn), is_tombstone);
  2225. slapi_sdn_set_normdn_passin(sdn_parent,parentdn);
  2226. sdn_parent->flag= slapi_setbit_uchar(sdn_parent->flag,FLAG_DN);
  2227. PR_INCREMENT_COUNTER(slapi_sdn_counter_dn_created);
  2228. PR_INCREMENT_COUNTER(slapi_sdn_counter_dn_exist);
  2229. }
  2230. void
  2231. slapi_sdn_get_parent(const Slapi_DN *sdn,Slapi_DN *sdn_parent)
  2232. {
  2233. slapi_sdn_get_parent_ext(sdn, sdn_parent, 0);
  2234. }
  2235. void
  2236. slapi_sdn_get_backend_parent_ext(const Slapi_DN *sdn,
  2237. Slapi_DN *sdn_parent,
  2238. const Slapi_Backend *backend,
  2239. int is_tombstone)
  2240. {
  2241. if(slapi_sdn_isempty(sdn) || slapi_be_issuffix( backend, sdn ))
  2242. {
  2243. slapi_sdn_done(sdn_parent);
  2244. }
  2245. else
  2246. {
  2247. slapi_sdn_get_parent_ext(sdn, sdn_parent, is_tombstone);
  2248. }
  2249. }
  2250. void
  2251. slapi_sdn_get_backend_parent(const Slapi_DN *sdn,Slapi_DN *sdn_parent,const Slapi_Backend *backend)
  2252. {
  2253. slapi_sdn_get_backend_parent_ext(sdn, sdn_parent, backend, 0);
  2254. }
  2255. void
  2256. slapi_sdn_get_rdn(const Slapi_DN *sdn,Slapi_RDN *rdn)
  2257. {
  2258. slapi_rdn_set_dn(rdn, slapi_sdn_get_dn(sdn));
  2259. }
  2260. void
  2261. slapi_sdn_get_rdn_ext(const Slapi_DN *sdn, Slapi_RDN *rdn, int is_tombstone)
  2262. {
  2263. slapi_rdn_set_dn_ext(rdn, slapi_sdn_get_dn(sdn), is_tombstone);
  2264. }
  2265. Slapi_DN *
  2266. slapi_sdn_dup(const Slapi_DN *sdn)
  2267. {
  2268. Slapi_DN *tmp;
  2269. SDN_DUMP( sdn, "slapi_sdn_dup");
  2270. tmp = slapi_sdn_new_normdn_byval(slapi_sdn_get_dn(sdn));
  2271. return tmp;
  2272. }
  2273. void
  2274. slapi_sdn_copy(const Slapi_DN *from, Slapi_DN *to)
  2275. {
  2276. SDN_DUMP( from, "slapi_sdn_copy from");
  2277. SDN_DUMP( to, "slapi_sdn_copy to");
  2278. slapi_sdn_done(to);
  2279. if (from->udn)
  2280. {
  2281. to->flag = slapi_setbit_uchar(to->flag, FLAG_UDN);
  2282. to->udn= slapi_ch_strdup(from->udn);
  2283. PR_INCREMENT_COUNTER(slapi_sdn_counter_udn_created);
  2284. PR_INCREMENT_COUNTER(slapi_sdn_counter_udn_exist);
  2285. }
  2286. if (from->dn)
  2287. {
  2288. to->flag = slapi_setbit_uchar(to->flag, FLAG_DN);
  2289. to->dn = slapi_ch_strdup(from->dn);
  2290. /* dn is normalized; strlen(dn) == strlen(ndn) */
  2291. to->ndn_len = strlen(to->dn);
  2292. PR_INCREMENT_COUNTER(slapi_sdn_counter_dn_created);
  2293. PR_INCREMENT_COUNTER(slapi_sdn_counter_dn_exist);
  2294. }
  2295. if (from->ndn)
  2296. {
  2297. to->flag = slapi_setbit_uchar(to->flag, FLAG_NDN);
  2298. to->ndn = slapi_ch_strdup(from->ndn);
  2299. to->ndn_len = strlen(to->ndn);
  2300. PR_INCREMENT_COUNTER(slapi_sdn_counter_ndn_created);
  2301. PR_INCREMENT_COUNTER(slapi_sdn_counter_ndn_exist);
  2302. }
  2303. }
  2304. int
  2305. slapi_sdn_compare( const Slapi_DN *sdn1, const Slapi_DN *sdn2 )
  2306. {
  2307. int rc;
  2308. const char *ndn1= slapi_sdn_get_ndn(sdn1);
  2309. const char *ndn2= slapi_sdn_get_ndn(sdn2);
  2310. if(ndn1==ndn2)
  2311. {
  2312. rc= 0;
  2313. }
  2314. else
  2315. {
  2316. if(ndn1==NULL)
  2317. {
  2318. rc= -1;
  2319. }
  2320. else
  2321. {
  2322. if(ndn2==NULL)
  2323. {
  2324. rc= 1;
  2325. }
  2326. else
  2327. {
  2328. rc= strcmp(ndn1,ndn2);
  2329. }
  2330. }
  2331. }
  2332. return rc;
  2333. }
  2334. int
  2335. slapi_sdn_isempty(const Slapi_DN *sdn)
  2336. {
  2337. const char *dn = NULL;
  2338. if (sdn) {
  2339. dn = slapi_sdn_get_dn(sdn);
  2340. }
  2341. return (dn==NULL || dn[0]=='\0');
  2342. }
  2343. int
  2344. slapi_sdn_issuffix(const Slapi_DN *sdn, const Slapi_DN *suffixsdn)
  2345. {
  2346. int rc;
  2347. const char *dn= slapi_sdn_get_ndn(sdn);
  2348. const char *suffixdn= slapi_sdn_get_ndn(suffixsdn);
  2349. if(dn!=NULL && suffixdn!=NULL)
  2350. {
  2351. int dnlen = slapi_sdn_get_ndn_len(sdn);
  2352. int suffixlen= slapi_sdn_get_ndn_len(suffixsdn);
  2353. if (dnlen<suffixlen)
  2354. {
  2355. rc= 0;
  2356. }
  2357. else
  2358. {
  2359. if ( suffixlen == 0 )
  2360. {
  2361. return ( 1 );
  2362. }
  2363. rc = (((dnlen == suffixlen) || DNSEPARATOR(dn[dnlen-suffixlen-1]))
  2364. && (strcasecmp(suffixdn, dn+dnlen-suffixlen)==0));
  2365. }
  2366. }
  2367. else
  2368. {
  2369. rc= 0;
  2370. }
  2371. return rc;
  2372. }
  2373. /* normalizes sdn if it hasn't already been done */
  2374. int
  2375. slapi_sdn_get_ndn_len(const Slapi_DN *sdn)
  2376. {
  2377. int r = 0;
  2378. (void)slapi_sdn_get_dn(sdn); /* does the normalization if needed */
  2379. if(sdn->dn || sdn->ndn)
  2380. {
  2381. r = sdn->ndn_len;
  2382. }
  2383. return r;
  2384. }
  2385. int
  2386. slapi_sdn_isparent( const Slapi_DN *parent, const Slapi_DN *child )
  2387. {
  2388. int rc= 0;
  2389. /* child is root - has no parent */
  2390. if ( !slapi_sdn_isempty(child) )
  2391. {
  2392. Slapi_DN childparent;
  2393. slapi_sdn_init(&childparent);
  2394. slapi_sdn_get_parent(child,&childparent);
  2395. rc= (slapi_sdn_compare(parent,&childparent)==0);
  2396. slapi_sdn_done(&childparent);
  2397. }
  2398. return( rc );
  2399. }
  2400. int
  2401. slapi_sdn_isgrandparent( const Slapi_DN *parent, const Slapi_DN *child )
  2402. {
  2403. int rc= 0;
  2404. /* child is root - has no parent */
  2405. if ( !slapi_sdn_isempty(child) )
  2406. {
  2407. Slapi_DN childparent;
  2408. slapi_sdn_init(&childparent);
  2409. slapi_sdn_get_parent(child,&childparent);
  2410. if ( !slapi_sdn_isempty(&childparent) )
  2411. {
  2412. Slapi_DN childchildparent;
  2413. slapi_sdn_init(&childchildparent);
  2414. slapi_sdn_get_parent(&childparent,&childchildparent);
  2415. rc= (slapi_sdn_compare(parent,&childchildparent)==0);
  2416. slapi_sdn_done(&childchildparent);
  2417. }
  2418. slapi_sdn_done(&childparent);
  2419. }
  2420. return( rc );
  2421. }
  2422. /*
  2423. * Return non-zero if "dn" matches the scoping criteria
  2424. * given by "base" and "scope".
  2425. */
  2426. int
  2427. slapi_sdn_scope_test( const Slapi_DN *dn, const Slapi_DN *base, int scope )
  2428. {
  2429. int rc = 0;
  2430. switch ( scope ) {
  2431. case LDAP_SCOPE_BASE:
  2432. rc = ( slapi_sdn_compare( dn, base ) == 0 );
  2433. break;
  2434. case LDAP_SCOPE_ONELEVEL:
  2435. rc = ( slapi_sdn_isparent( base, dn ) != 0 );
  2436. break;
  2437. case LDAP_SCOPE_SUBTREE:
  2438. rc = ( slapi_sdn_issuffix( dn, base ) != 0 );
  2439. break;
  2440. }
  2441. return rc;
  2442. }
  2443. /*
  2444. * Return non-zero if "dn" matches the scoping criteria
  2445. * given by "base" and "scope".
  2446. * If SLAPI_ENTRY_FLAG_TOMBSTONE is set to flags,
  2447. * DN without "nsuniqueid=...," is examined.
  2448. */
  2449. int
  2450. slapi_sdn_scope_test_ext( const Slapi_DN *dn, const Slapi_DN *base, int scope, int flags )
  2451. {
  2452. int rc = 0;
  2453. switch ( scope ) {
  2454. case LDAP_SCOPE_BASE:
  2455. if (flags & SLAPI_ENTRY_FLAG_TOMBSTONE) {
  2456. Slapi_DN parent;
  2457. slapi_sdn_init(&parent);
  2458. slapi_sdn_get_parent(dn, &parent);
  2459. rc = ( slapi_sdn_compare( dn, &parent ) == 0 );
  2460. slapi_sdn_done(&parent);
  2461. } else {
  2462. rc = ( slapi_sdn_compare( dn, base ) == 0 );
  2463. }
  2464. break;
  2465. case LDAP_SCOPE_ONELEVEL:
  2466. #define RUVRDN SLAPI_ATTR_UNIQUEID "=" RUV_STORAGE_ENTRY_UNIQUEID ","
  2467. if ((flags & SLAPI_ENTRY_FLAG_TOMBSTONE) &&
  2468. (strncmp(slapi_sdn_get_ndn(dn), RUVRDN, sizeof(RUVRDN) - 1))) {
  2469. /* tombstones except RUV tombstone */
  2470. Slapi_DN parent;
  2471. slapi_sdn_init(&parent);
  2472. slapi_sdn_get_parent(dn, &parent);
  2473. rc = ( slapi_sdn_isparent( base, &parent ) != 0 );
  2474. slapi_sdn_done(&parent);
  2475. } else {
  2476. rc = ( slapi_sdn_isparent( base, dn ) != 0 );
  2477. }
  2478. break;
  2479. case LDAP_SCOPE_SUBTREE:
  2480. rc = ( slapi_sdn_issuffix( dn, base ) != 0 );
  2481. break;
  2482. }
  2483. return rc;
  2484. }
  2485. /*
  2486. * build the new dn of an entry for moddn operations
  2487. */
  2488. char *
  2489. slapi_moddn_get_newdn(Slapi_DN *dn_olddn, const char *newrdn, const char *newsuperiordn)
  2490. {
  2491. char *newdn;
  2492. if( newsuperiordn!=NULL)
  2493. {
  2494. /* construct the new dn */
  2495. newdn= slapi_dn_plus_rdn(newsuperiordn, newrdn); /* JCM - Use Slapi_RDN */
  2496. }
  2497. else
  2498. {
  2499. /* construct the new dn */
  2500. char *pdn;
  2501. const char *dn= slapi_sdn_get_dn(dn_olddn);
  2502. pdn = slapi_dn_parent( dn );
  2503. if ( pdn != NULL )
  2504. {
  2505. newdn= slapi_dn_plus_rdn(pdn, newrdn); /* JCM - Use Slapi_RDN */
  2506. }
  2507. else
  2508. {
  2509. newdn= slapi_ch_strdup(newrdn);
  2510. }
  2511. slapi_ch_free( (void**)&pdn );
  2512. }
  2513. return newdn;
  2514. }
  2515. /* JCM slapi_sdn_get_first ? */
  2516. /* JCM slapi_sdn_get_next ? */
  2517. #ifdef SDN_DEBUG
  2518. static void
  2519. sdn_dump( const Slapi_DN *sdn, const char *text)
  2520. {
  2521. LDAPDebug( LDAP_DEBUG_ANY, "SDN %s ptr=%lx dn=%s\n", text, sdn, (sdn->dn==NULL?"NULL":sdn->dn));
  2522. }
  2523. #endif
  2524. size_t
  2525. slapi_sdn_get_size(const Slapi_DN *sdn)
  2526. {
  2527. size_t sz = 0;
  2528. /* slapi_sdn_get_ndn_len returns the normalized dn length
  2529. * if dn or ndn exists. If both does not exist, it
  2530. * normalizes udn and set it to dn and returns the length.
  2531. */
  2532. if (NULL == sdn) {
  2533. return sz;
  2534. }
  2535. sz += slapi_sdn_get_ndn_len(sdn) + 1 /* '\0' */;
  2536. if (sdn->dn && sdn->ndn) {
  2537. sz *= 2;
  2538. }
  2539. if (sdn->udn) {
  2540. sz += strlen(sdn->udn) + 1;
  2541. }
  2542. sz += sizeof(Slapi_DN);
  2543. return sz;
  2544. }
  2545. /*
  2546. *
  2547. * Normalized DN Cache
  2548. *
  2549. */
  2550. /*
  2551. * Hashing function using Bernstein's method
  2552. */
  2553. static PLHashNumber
  2554. ndn_hash_string(const void *key)
  2555. {
  2556. PLHashNumber hash = 5381;
  2557. unsigned char *x = (unsigned char *)key;
  2558. int c;
  2559. while ((c = *x++)){
  2560. hash = ((hash << 5) + hash) ^ c;
  2561. }
  2562. return hash;
  2563. }
  2564. void
  2565. ndn_cache_init()
  2566. {
  2567. if(!config_get_ndn_cache_enabled() || ndn_started){
  2568. return;
  2569. }
  2570. ndn_cache_hashtable = PL_NewHashTable( NDN_CACHE_BUCKETS, ndn_hash_string, PL_CompareStrings, PL_CompareValues, 0, 0);
  2571. ndn_cache = (struct ndn_cache_ctx *)slapi_ch_malloc(sizeof(struct ndn_cache_ctx));
  2572. ndn_cache->cache_max_size = config_get_ndn_cache_size();
  2573. ndn_cache->cache_hits = slapi_counter_new();
  2574. ndn_cache->cache_tries = slapi_counter_new();
  2575. ndn_cache->cache_misses = slapi_counter_new();
  2576. ndn_cache->cache_count = 0;
  2577. ndn_cache->cache_size = sizeof(struct ndn_cache_ctx) + sizeof(PLHashTable) + sizeof(PLHashTable);
  2578. ndn_cache->head = NULL;
  2579. ndn_cache->tail = NULL;
  2580. ndn_started = 1;
  2581. if ( NULL == ( lru_lock = PR_NewLock()) || NULL == ( ndn_cache_lock = slapi_new_rwlock())) {
  2582. ndn_cache_destroy();
  2583. slapi_log_error( SLAPI_LOG_FATAL, "ndn_cache_init", "Failed to create locks. Disabling cache.\n" );
  2584. }
  2585. }
  2586. void
  2587. ndn_cache_destroy()
  2588. {
  2589. char *errorbuf = NULL;
  2590. if(!ndn_started){
  2591. return;
  2592. }
  2593. if(lru_lock){
  2594. PR_DestroyLock(lru_lock);
  2595. lru_lock = NULL;
  2596. }
  2597. if(ndn_cache_lock){
  2598. slapi_destroy_rwlock(ndn_cache_lock);
  2599. ndn_cache_lock = NULL;
  2600. }
  2601. if(ndn_cache_hashtable){
  2602. ndn_cache_free();
  2603. PL_HashTableDestroy(ndn_cache_hashtable);
  2604. ndn_cache_hashtable = NULL;
  2605. }
  2606. config_set_ndn_cache_enabled(CONFIG_NDN_CACHE, "off", errorbuf, 1 );
  2607. slapi_counter_destroy(&ndn_cache->cache_hits);
  2608. slapi_counter_destroy(&ndn_cache->cache_tries);
  2609. slapi_counter_destroy(&ndn_cache->cache_misses);
  2610. slapi_ch_free((void **)&ndn_cache);
  2611. ndn_started = 0;
  2612. }
  2613. int
  2614. ndn_cache_started()
  2615. {
  2616. return ndn_started;
  2617. }
  2618. /*
  2619. * Look up this dn in the ndn cache
  2620. */
  2621. static int
  2622. ndn_cache_lookup(char *dn, size_t dn_len, char **result, char **udn, int *rc)
  2623. {
  2624. struct ndn_hash_val *ndn_ht_val = NULL;
  2625. char *ndn, *key;
  2626. int rv = 0;
  2627. if(NULL == udn){
  2628. return rv;
  2629. }
  2630. *udn = NULL;
  2631. if(ndn_started == 0){
  2632. return rv;
  2633. }
  2634. if(dn_len == 0){
  2635. *result = dn;
  2636. *rc = 0;
  2637. return 1;
  2638. }
  2639. slapi_counter_increment(ndn_cache->cache_tries);
  2640. slapi_rwlock_rdlock(ndn_cache_lock);
  2641. ndn_ht_val = (struct ndn_hash_val *)PL_HashTableLookupConst(ndn_cache_hashtable, dn);
  2642. if(ndn_ht_val){
  2643. ndn_cache_update_lru(&ndn_ht_val->lru_node);
  2644. slapi_counter_increment(ndn_cache->cache_hits);
  2645. if ((ndn_ht_val->len != dn_len) ||
  2646. /* even if the lengths match, dn may not be normalized yet.
  2647. * (e.g., 'cn="o=ABC",o=XYZ' vs. 'cn=o\3DABC,o=XYZ') */
  2648. (memcmp(dn, ndn_ht_val->ndn, dn_len))){
  2649. *rc = 1; /* free result */
  2650. ndn = slapi_ch_malloc(ndn_ht_val->len + 1);
  2651. memcpy(ndn, ndn_ht_val->ndn, ndn_ht_val->len);
  2652. ndn[ndn_ht_val->len] = '\0';
  2653. *result = ndn;
  2654. } else {
  2655. /* the dn was already normalized, just return the dn as the result */
  2656. *result = dn;
  2657. *rc = 0;
  2658. }
  2659. rv = 1;
  2660. } else {
  2661. /* copy/preserve the udn, so we can use it as the key when we add dn's to the hashtable */
  2662. key = slapi_ch_malloc(dn_len + 1);
  2663. memcpy(key, dn, dn_len);
  2664. key[dn_len] = '\0';
  2665. *udn = key;
  2666. }
  2667. slapi_rwlock_unlock(ndn_cache_lock);
  2668. return rv;
  2669. }
  2670. /*
  2671. * Move this lru node to the top of the list
  2672. */
  2673. static void
  2674. ndn_cache_update_lru(struct ndn_cache_lru **node)
  2675. {
  2676. struct ndn_cache_lru *prev, *next, *curr_node = *node;
  2677. if(curr_node == NULL){
  2678. return;
  2679. }
  2680. PR_Lock(lru_lock);
  2681. if(curr_node->prev == NULL){
  2682. /* already the top node */
  2683. PR_Unlock(lru_lock);
  2684. return;
  2685. }
  2686. prev = curr_node->prev;
  2687. next = curr_node->next;
  2688. if(next){
  2689. next->prev = prev;
  2690. prev->next = next;
  2691. } else {
  2692. /* this was the tail, so reset the tail */
  2693. ndn_cache->tail = prev;
  2694. prev->next = NULL;
  2695. }
  2696. curr_node->prev = NULL;
  2697. curr_node->next = ndn_cache->head;
  2698. ndn_cache->head->prev = curr_node;
  2699. ndn_cache->head = curr_node;
  2700. PR_Unlock(lru_lock);
  2701. }
  2702. /*
  2703. * Add a ndn to the cache. Try and do as much as possible before taking the write lock.
  2704. */
  2705. static void
  2706. ndn_cache_add(char *dn, size_t dn_len, char *ndn, size_t ndn_len)
  2707. {
  2708. struct ndn_hash_val *ht_entry;
  2709. struct ndn_cache_lru *new_node = NULL;
  2710. PLHashEntry *he;
  2711. int size;
  2712. if(ndn_started == 0 || dn_len == 0){
  2713. return;
  2714. }
  2715. if(strlen(ndn) > ndn_len){
  2716. /* we need to null terminate the ndn */
  2717. *(ndn + ndn_len) = '\0';
  2718. }
  2719. /*
  2720. * Calculate the approximate memory footprint of the hash entry, key, and lru entry.
  2721. */
  2722. size = (dn_len * 2) + ndn_len + sizeof(PLHashEntry) + sizeof(struct ndn_hash_val) + sizeof(struct ndn_cache_lru);
  2723. /*
  2724. * Create our LRU node
  2725. */
  2726. new_node = (struct ndn_cache_lru *)slapi_ch_malloc(sizeof(struct ndn_cache_lru));
  2727. if(new_node == NULL){
  2728. slapi_log_error( SLAPI_LOG_FATAL, "ndn_cache_add", "Failed to allocate new lru node.\n");
  2729. return;
  2730. }
  2731. new_node->prev = NULL;
  2732. new_node->key = dn; /* dn has already been allocated */
  2733. /*
  2734. * Its possible this dn was added to the hash by another thread.
  2735. */
  2736. slapi_rwlock_wrlock(ndn_cache_lock);
  2737. ht_entry = (struct ndn_hash_val *)PL_HashTableLookupConst(ndn_cache_hashtable, dn);
  2738. if(ht_entry){
  2739. /* already exists, free the node and return */
  2740. slapi_rwlock_unlock(ndn_cache_lock);
  2741. slapi_ch_free_string(&new_node->key);
  2742. slapi_ch_free((void **)&new_node);
  2743. return;
  2744. }
  2745. /*
  2746. * Create the hash entry
  2747. */
  2748. ht_entry = (struct ndn_hash_val *)slapi_ch_malloc(sizeof(struct ndn_hash_val));
  2749. if(ht_entry == NULL){
  2750. slapi_rwlock_unlock(ndn_cache_lock);
  2751. slapi_log_error( SLAPI_LOG_FATAL, "ndn_cache_add", "Failed to allocate new hash entry.\n");
  2752. slapi_ch_free_string(&new_node->key);
  2753. slapi_ch_free((void **)&new_node);
  2754. return;
  2755. }
  2756. ht_entry->ndn = slapi_ch_malloc(ndn_len + 1);
  2757. memcpy(ht_entry->ndn, ndn, ndn_len);
  2758. ht_entry->ndn[ndn_len] = '\0';
  2759. ht_entry->len = ndn_len;
  2760. ht_entry->size = size;
  2761. ht_entry->lru_node = new_node;
  2762. /*
  2763. * Check if our cache is full
  2764. */
  2765. PR_Lock(lru_lock); /* grab the lru lock now, as ndn_cache_flush needs it */
  2766. if(ndn_cache->cache_max_size != 0 && ((ndn_cache->cache_size + size) > ndn_cache->cache_max_size)){
  2767. ndn_cache_flush();
  2768. }
  2769. /*
  2770. * Set the ndn cache lru nodes
  2771. */
  2772. if(ndn_cache->head == NULL && ndn_cache->tail == NULL){
  2773. /* this is the first node */
  2774. ndn_cache->head = new_node;
  2775. ndn_cache->tail = new_node;
  2776. new_node->next = NULL;
  2777. } else {
  2778. new_node->next = ndn_cache->head;
  2779. if(ndn_cache->head)
  2780. ndn_cache->head->prev = new_node;
  2781. }
  2782. ndn_cache->head = new_node;
  2783. PR_Unlock(lru_lock);
  2784. /*
  2785. * Add the new object to the hashtable, and update our stats
  2786. */
  2787. he = PL_HashTableAdd(ndn_cache_hashtable, new_node->key, (void *)ht_entry);
  2788. if(he == NULL){
  2789. slapi_log_error( SLAPI_LOG_FATAL, "ndn_cache_add", "Failed to add new entry to hash(%s)\n",dn);
  2790. } else {
  2791. ndn_cache->cache_count++;
  2792. ndn_cache->cache_size += size;
  2793. }
  2794. slapi_rwlock_unlock(ndn_cache_lock);
  2795. }
  2796. /*
  2797. * cache is full, remove the least used dn's. lru_lock/ndn_cache write lock are already taken
  2798. */
  2799. static void
  2800. ndn_cache_flush()
  2801. {
  2802. struct ndn_cache_lru *node, *next, *flush_node;
  2803. int i;
  2804. node = ndn_cache->tail;
  2805. for(i = 0; node && i < NDN_FLUSH_COUNT && ndn_cache->cache_count > NDN_MIN_COUNT; i++){
  2806. flush_node = node;
  2807. /* update the lru */
  2808. next = node->prev;
  2809. next->next = NULL;
  2810. ndn_cache->tail = next;
  2811. node = next;
  2812. /* now update the hash */
  2813. ndn_cache->cache_count--;
  2814. ndn_cache_delete(flush_node->key);
  2815. slapi_ch_free_string(&flush_node->key);
  2816. slapi_ch_free((void **)&flush_node);
  2817. }
  2818. slapi_log_error( SLAPI_LOG_CACHE, "ndn_cache_flush","Flushed cache.\n");
  2819. }
  2820. static void
  2821. ndn_cache_free()
  2822. {
  2823. struct ndn_cache_lru *node, *next, *flush_node;
  2824. if(!ndn_cache){
  2825. return;
  2826. }
  2827. node = ndn_cache->tail;
  2828. while(node && ndn_cache->cache_count){
  2829. flush_node = node;
  2830. /* update the lru */
  2831. next = node->prev;
  2832. if(next){
  2833. next->next = NULL;
  2834. }
  2835. ndn_cache->tail = next;
  2836. node = next;
  2837. /* now update the hash */
  2838. ndn_cache->cache_count--;
  2839. ndn_cache_delete(flush_node->key);
  2840. slapi_ch_free_string(&flush_node->key);
  2841. slapi_ch_free((void **)&flush_node);
  2842. }
  2843. }
  2844. /* this is already "write" locked from ndn_cache_add */
  2845. static void
  2846. ndn_cache_delete(char *dn)
  2847. {
  2848. struct ndn_hash_val *ht_entry;
  2849. ht_entry = (struct ndn_hash_val *)PL_HashTableLookupConst(ndn_cache_hashtable, dn);
  2850. if(ht_entry){
  2851. ndn_cache->cache_size -= ht_entry->size;
  2852. slapi_ch_free_string(&ht_entry->ndn);
  2853. slapi_ch_free((void **)&ht_entry);
  2854. PL_HashTableRemove(ndn_cache_hashtable, dn);
  2855. }
  2856. }
  2857. /* stats for monitor */
  2858. void
  2859. ndn_cache_get_stats(PRUint64 *hits, PRUint64 *tries, size_t *size, size_t *max_size, long *count)
  2860. {
  2861. slapi_rwlock_rdlock(ndn_cache_lock);
  2862. *hits = slapi_counter_get_value(ndn_cache->cache_hits);
  2863. *tries = slapi_counter_get_value(ndn_cache->cache_tries);
  2864. *size = ndn_cache->cache_size;
  2865. *max_size = ndn_cache->cache_max_size;
  2866. *count = ndn_cache->cache_count;
  2867. slapi_rwlock_unlock(ndn_cache_lock);
  2868. }
  2869. /* Common ancestor sdn is allocated.
  2870. * caller is responsible to free it */
  2871. Slapi_DN *
  2872. slapi_sdn_common_ancestor(Slapi_DN *dn1, Slapi_DN *dn2)
  2873. {
  2874. const char *dn1str = NULL;
  2875. const char *dn2str = NULL;
  2876. char **dns1 = NULL;
  2877. char **dns2 = NULL;
  2878. char **dn1p, **dn2p;
  2879. char **dn1end;
  2880. int dn1len = 0;
  2881. int dn2len = 0;
  2882. char *common = NULL;
  2883. char *cp = 0;
  2884. if ((NULL == dn1) || (NULL == dn2)) {
  2885. return NULL;
  2886. }
  2887. dn1str = slapi_sdn_get_ndn(dn1);
  2888. dn2str = slapi_sdn_get_ndn(dn2);
  2889. if (0 == strcmp(dn1str, dn2str)) {
  2890. /* identical */
  2891. return slapi_sdn_dup(dn1);
  2892. }
  2893. dn1len = strlen(dn1str);
  2894. dn2len = strlen(dn2str);
  2895. if (dn1len > dn2len) {
  2896. if (slapi_sdn_isparent(dn2, dn1)) {
  2897. /* dn2 is dn1's parent */
  2898. return slapi_sdn_dup(dn2);
  2899. }
  2900. } else if (dn1len < dn2len) {
  2901. if (slapi_sdn_isparent(dn1, dn2)) {
  2902. /* dn1 is dn2's parent */
  2903. return slapi_sdn_dup(dn1);
  2904. }
  2905. }
  2906. dns1 = slapi_ldap_explode_dn(slapi_sdn_get_ndn(dn1), 0);
  2907. dns2 = slapi_ldap_explode_dn(slapi_sdn_get_ndn(dn2), 0);
  2908. for (dn1p = dns1; dn1p && *dn1p; dn1p++) ;
  2909. for (dn2p = dns2; dn2p && *dn2p; dn2p++) ;
  2910. dn1end = dn1p;
  2911. while (--dn1p && --dn2p && (dn1p >= dns1) && (dn2p >= dns2)) {
  2912. if (strcmp(*dn1p, *dn2p)) {
  2913. break;
  2914. }
  2915. }
  2916. if (dn1end == ++dn1p) {
  2917. /* No common ancestor */
  2918. charray_free(dns1);
  2919. charray_free(dns2);
  2920. return NULL;
  2921. }
  2922. dn1len += 1;
  2923. cp = common = slapi_ch_malloc(dn1len);
  2924. *common = '\0';
  2925. do {
  2926. PR_snprintf(cp, dn1len, "%s,", *dn1p);
  2927. cp += strlen(*dn1p) + 1/*,*/;
  2928. } while (++dn1p < dn1end);
  2929. dn1len = strlen(common);
  2930. if (',' == *(common + dn1len - 1)) {
  2931. *(common + dn1len - 1) = '\0';
  2932. }
  2933. charray_free(dns1);
  2934. charray_free(dns2);
  2935. return slapi_sdn_new_ndn_passin(common);
  2936. }
  2937. /*
  2938. * Return 1 - if nsslapd-cn-uses-dn-syntax-in-dns is true &&
  2939. * the type is "cn" && dn is under "cn=config"
  2940. * Return 0 - otherwise
  2941. */
  2942. static int
  2943. does_cn_uses_dn_syntax_in_dns(char *type, char *dn)
  2944. {
  2945. int rc = 0; /* by default off */
  2946. char *ptr = NULL;
  2947. if (type && dn && config_get_cn_uses_dn_syntax_in_dns() &&
  2948. (PL_strcasecmp(type, "cn") == 0) && (ptr = PL_strrchr(dn, ','))) {
  2949. if (PL_strcasecmp(++ptr, "cn=config") == 0) {
  2950. rc = 1;
  2951. }
  2952. }
  2953. return rc;
  2954. }