entry.c 119 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199
  1. /** BEGIN COPYRIGHT BLOCK
  2. * This Program is free software; you can redistribute it and/or modify it under
  3. * the terms of the GNU General Public License as published by the Free Software
  4. * Foundation; version 2 of the License.
  5. *
  6. * This Program is distributed in the hope that it will be useful, but WITHOUT
  7. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  8. * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
  9. *
  10. * You should have received a copy of the GNU General Public License along with
  11. * this Program; if not, write to the Free Software Foundation, Inc., 59 Temple
  12. * Place, Suite 330, Boston, MA 02111-1307 USA.
  13. *
  14. * In addition, as a special exception, Red Hat, Inc. gives You the additional
  15. * right to link the code of this Program with code not covered under the GNU
  16. * General Public License ("Non-GPL Code") and to distribute linked combinations
  17. * including the two, subject to the limitations in this paragraph. Non-GPL Code
  18. * permitted under this exception must only link to the code of this Program
  19. * through those well defined interfaces identified in the file named EXCEPTION
  20. * found in the source code files (the "Approved Interfaces"). The files of
  21. * Non-GPL Code may instantiate templates or use macros or inline functions from
  22. * the Approved Interfaces without causing the resulting work to be covered by
  23. * the GNU General Public License. Only Red Hat, Inc. may make changes or
  24. * additions to the list of Approved Interfaces. You must obey the GNU General
  25. * Public License in all respects for all of the Program code and other code used
  26. * in conjunction with the Program except the Non-GPL Code covered by this
  27. * exception. If you modify this file, you may extend this exception to your
  28. * version of the file, but you are not obligated to do so. If you do not wish to
  29. * provide this exception without modification, you must delete this exception
  30. * statement from your version and license this file solely under the GPL without
  31. * exception.
  32. *
  33. *
  34. * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
  35. * Copyright (C) 2005 Red Hat, Inc.
  36. * All rights reserved.
  37. * END COPYRIGHT BLOCK **/
  38. #ifdef HAVE_CONFIG_H
  39. # include <config.h>
  40. #endif
  41. /* entry.c - routines for dealing with entries */
  42. #include <stdio.h>
  43. #include <string.h>
  44. #include <ctype.h>
  45. #include <sys/types.h>
  46. #ifndef _WIN32
  47. #include <sys/socket.h>
  48. #endif
  49. #undef DEBUG /* disable counters */
  50. #include <prcountr.h>
  51. #include "slap.h"
  52. #undef ENTRY_DEBUG
  53. #define DELETED_ATTR_STRING ";deletedattribute"
  54. #define DELETED_ATTR_STRSIZE 17 /* sizeof(";deletedattribute") */
  55. #define DELETED_VALUE_STRING ";deleted"
  56. #define DELETED_VALUE_STRSIZE 8 /* sizeof(";deleted") */
  57. /* a helper function to set special rdn to a tombstone entry */
  58. static int _entry_set_tombstone_rdn(Slapi_Entry *e, const char *normdn);
  59. /* protected attributes which are not included in the flattened entry,
  60. * which will be stored in the db. */
  61. static char *protected_attrs_all [] = {PSEUDO_ATTR_UNHASHEDUSERPASSWORD,
  62. SLAPI_ATTR_ENTRYDN,
  63. NULL};
  64. #if defined(USE_OLD_UNHASHED)
  65. static char *forbidden_attrs [] = {PSEUDO_ATTR_UNHASHEDUSERPASSWORD,
  66. NULL};
  67. #endif
  68. /* Attributes which are put into the entry extension */
  69. struct attrs_in_extension attrs_in_extension[] =
  70. {
  71. {PSEUDO_ATTR_UNHASHEDUSERPASSWORD,
  72. slapi_pw_get_entry_ext,
  73. slapi_pw_set_entry_ext,
  74. pw_copy_entry_ext},
  75. {NULL, NULL, NULL}
  76. };
  77. /*
  78. * An attribute name is of the form 'basename[;option]'.
  79. * The state informaion is encoded in options. For example:
  80. *
  81. * telephonenumber;vucsn-011111111222233334444: 1 650 937 5739
  82. *
  83. * This function strips out the csn options, leaving behind a
  84. * type with any non-csn options left intact.
  85. */
  86. /*
  87. * WARNING: s gets butchered... the base type remains.
  88. */
  89. void
  90. str2entry_state_information_from_type(char *s,CSNSet **csnset,CSN **attributedeletioncsn,CSN **maxcsn,int *value_state,int *attr_state)
  91. {
  92. char *p= strchr(s, ';');
  93. *value_state= VALUE_PRESENT;
  94. *attr_state= ATTRIBUTE_PRESENT;
  95. while(p!=NULL)
  96. {
  97. if(p[3]=='c' && p[4]=='s' && p[5]=='n' && p[6]=='-')
  98. {
  99. CSNType t= CSN_TYPE_UNKNOWN;
  100. if(p[1]=='x' && p[2]=='1')
  101. {
  102. t= CSN_TYPE_UNKNOWN;
  103. }
  104. if(p[1]=='x' && p[2]=='2')
  105. {
  106. t= CSN_TYPE_NONE;
  107. }
  108. if(p[1]=='a' && p[2]=='d')
  109. {
  110. t= CSN_TYPE_ATTRIBUTE_DELETED;
  111. }
  112. if(p[1]=='v' && p[2]=='u')
  113. {
  114. t= CSN_TYPE_VALUE_UPDATED;
  115. }
  116. if(p[1]=='v' && p[2]=='d')
  117. {
  118. t= CSN_TYPE_VALUE_DELETED;
  119. }
  120. if(p[1]=='m' && p[2]=='d')
  121. {
  122. t= CSN_TYPE_VALUE_DISTINGUISHED;
  123. }
  124. p[0]='\0';
  125. if(t!=CSN_TYPE_ATTRIBUTE_DELETED)
  126. {
  127. CSN csn;
  128. csn_init_by_string(&csn,p+7);
  129. csnset_add_csn(csnset,t,&csn);
  130. if ( *maxcsn == NULL )
  131. {
  132. *maxcsn = csn_dup ( &csn );
  133. }
  134. else if ( csn_compare (*maxcsn, &csn) < 0 )
  135. {
  136. csn_init_by_csn ( *maxcsn, &csn );
  137. }
  138. }
  139. else
  140. {
  141. *attributedeletioncsn= csn_new_by_string(p+7);
  142. if ( *maxcsn == NULL )
  143. {
  144. *maxcsn = csn_dup ( *attributedeletioncsn );
  145. }
  146. else if ( csn_compare (*maxcsn, *attributedeletioncsn) < 0 )
  147. {
  148. csn_init_by_csn ( *maxcsn, *attributedeletioncsn );
  149. }
  150. }
  151. }
  152. else if(strncmp(p+1,"deletedattribute", 16)==0)
  153. {
  154. p[0]='\0';
  155. *attr_state= ATTRIBUTE_DELETED;
  156. }
  157. else if(strncmp(p+1,"deleted", 7)==0)
  158. {
  159. p[0]='\0';
  160. *value_state= VALUE_DELETED;
  161. }
  162. p= strchr(p+1, ';');
  163. }
  164. }
  165. /* rawdn is not consumed. Caller needs to free it. */
  166. static Slapi_Entry *
  167. str2entry_fast( const char *rawdn, const Slapi_RDN *srdn, char *s, int flags, int read_stateinfo )
  168. {
  169. Slapi_Entry *e;
  170. char *next, *ptype=NULL;
  171. int nvals= 0;
  172. int del_nvals= 0;
  173. unsigned long attr_val_cnt = 0;
  174. CSN *attributedeletioncsn= NULL; /* Moved to this level so that the JCM csn_free call below gets useful */
  175. CSNSet *valuecsnset= NULL; /* Moved to this level so that the JCM csn_free call below gets useful */
  176. CSN *maxcsn = NULL;
  177. char *normdn = NULL;
  178. Slapi_Attr **a = NULL;
  179. #ifdef OBSOLETE_DN_SYNTAX_CHECK
  180. int strict = 0;
  181. /* Check if we should be performing strict validation. */
  182. strict = config_get_dn_validate_strict();
  183. #endif
  184. /*
  185. * In string format, an entry looks like either of these:
  186. *
  187. * dn: <dn>\n
  188. * [<attr>:[:] <value>\n]
  189. * [<tab><continuedvalue>\n]*
  190. * ...
  191. *
  192. * rdn: <rdn>\n
  193. * [<attr>:[:] <value>\n]
  194. * [<tab><continuedvalue>\n]*
  195. * ...
  196. *
  197. * If a double colon is used after a type, it means the
  198. * following value is encoded as a base 64 string. This
  199. * happens if the value contains a non-printing character
  200. * or newline.
  201. *
  202. * In case an entry starts with rdn:, dn must be provided.
  203. */
  204. LDAPDebug( LDAP_DEBUG_TRACE, "=> str2entry_fast\n", 0, 0, 0 );
  205. e = slapi_entry_alloc();
  206. slapi_entry_init(e,NULL,NULL);
  207. /* dn|rdn + attributes */
  208. next = s;
  209. /* get the read lock of name2asi for performance purpose.
  210. It reduces read locking by per-entry lock, instead of per-attribute.
  211. */
  212. /* attr_syntax_read_lock();
  213. * no longer needed since attr syntax is not initialized
  214. */
  215. while ( (s = ldif_getline( &next )) != NULL &&
  216. attr_val_cnt < ENTRY_MAX_ATTRIBUTE_VALUE_COUNT )
  217. {
  218. struct berval type = {0, NULL};
  219. struct berval value = {0, NULL};
  220. int freeval = 0;
  221. int value_state= VALUE_NOTFOUND;
  222. int attr_state= ATTRIBUTE_NOTFOUND;
  223. int maxvals;
  224. int del_maxvals;
  225. if ( *s == '\n' || *s == '\0' ) {
  226. break;
  227. }
  228. if ( slapi_ldif_parse_line( s, &type, &value, &freeval ) < 0 ) {
  229. LDAPDebug( LDAP_DEBUG_TRACE,
  230. "<= str2entry_fast NULL (parse_line)\n", 0, 0, 0 );
  231. continue;
  232. }
  233. /*
  234. * Extract the attribute and value CSNs from the attribute type.
  235. */
  236. csn_free(&attributedeletioncsn); /* JCM - Do this more efficiently */
  237. csnset_free(&valuecsnset);
  238. value_state= VALUE_NOTFOUND;
  239. attr_state= ATTRIBUTE_NOTFOUND;
  240. str2entry_state_information_from_type(type.bv_val,&valuecsnset,&attributedeletioncsn,&maxcsn,&value_state,&attr_state);
  241. if(!read_stateinfo)
  242. {
  243. /* We are not maintaining state information */
  244. if(value_state==VALUE_DELETED || attr_state==ATTRIBUTE_DELETED)
  245. {
  246. /* ignore deleted values and attributes */
  247. /* the memory below was not allocated by the slapi_ch_ functions */
  248. if (freeval) slapi_ch_free_string(&value.bv_val);
  249. continue;
  250. }
  251. /* Ignore CSNs */
  252. csn_free(&attributedeletioncsn);
  253. csnset_free(&valuecsnset);
  254. }
  255. /*
  256. * We cache some stuff as we go around the loop.
  257. */
  258. if((ptype==NULL)||(PL_strcasecmp(type.bv_val,ptype) != 0))
  259. {
  260. slapi_ch_free_string(&ptype);
  261. ptype=PL_strndup(type.bv_val, type.bv_len);
  262. nvals = 0;
  263. maxvals = 0;
  264. del_nvals = 0;
  265. del_maxvals = 0;
  266. a = NULL;
  267. }
  268. if ( rawdn ) {
  269. if ( NULL == slapi_entry_get_dn_const( e )) {
  270. if (flags & SLAPI_STR2ENTRY_USE_OBSOLETE_DNFORMAT) {
  271. normdn =
  272. slapi_dn_normalize_original(slapi_ch_strdup(rawdn));
  273. } else {
  274. if (flags & SLAPI_STR2ENTRY_DN_NORMALIZED) {
  275. normdn = slapi_ch_strdup(rawdn);
  276. } else {
  277. normdn = slapi_create_dn_string("%s", rawdn);
  278. if (NULL == normdn) {
  279. LDAPDebug1Arg(LDAP_DEBUG_TRACE,
  280. "str2entry_fast: Invalid DN: %s\n", rawdn);
  281. slapi_entry_free( e );
  282. if (freeval) slapi_ch_free_string(&value.bv_val);
  283. e = NULL;
  284. goto done;
  285. }
  286. }
  287. }
  288. /* normdn is consumed in e */
  289. slapi_entry_set_normdn(e, normdn);
  290. }
  291. if ( NULL == slapi_entry_get_rdn_const( e )) {
  292. if (srdn) {
  293. /* we can use the rdn generated in entryrdn_lookup_dn */
  294. slapi_entry_set_srdn ( e, srdn );
  295. }else if (normdn) {
  296. /* normdn is just referred in slapi_entry_set_rdn. */
  297. slapi_entry_set_rdn(e, normdn);
  298. } else {
  299. if (flags & SLAPI_STR2ENTRY_USE_OBSOLETE_DNFORMAT) {
  300. normdn =
  301. slapi_dn_normalize_original(slapi_ch_strdup(rawdn));
  302. } else {
  303. if (flags & SLAPI_STR2ENTRY_DN_NORMALIZED) {
  304. normdn = slapi_ch_strdup(rawdn);
  305. } else {
  306. normdn = slapi_create_dn_string("%s", rawdn);
  307. if (NULL == normdn) {
  308. LDAPDebug1Arg(LDAP_DEBUG_TRACE,
  309. "str2entry_fast: Invalid DN: %s\n", rawdn);
  310. slapi_entry_free( e );
  311. if (freeval)
  312. slapi_ch_free_string(&value.bv_val);
  313. e = NULL;
  314. goto done;
  315. }
  316. }
  317. }
  318. /* normdn is just referred in slapi_entry_set_rdn. */
  319. slapi_entry_set_rdn(e, normdn);
  320. slapi_ch_free_string(&normdn);
  321. }
  322. }
  323. rawdn = NULL; /* Set once in the loop.
  324. This won't affect the caller's passed address. */
  325. }
  326. if ( PL_strncasecmp( type.bv_val, "dn", type.bv_len ) == 0 ) {
  327. if ( slapi_entry_get_dn_const(e)!=NULL ) {
  328. char ebuf[ BUFSIZ ];
  329. LDAPDebug( LDAP_DEBUG_TRACE,
  330. "str2entry_fast: entry has multiple dns \"%s\" and "
  331. "\"%s\" (second ignored)\n",
  332. slapi_entry_get_dn_const(e),
  333. escape_string( value.bv_val, ebuf ), 0 );
  334. /* the memory below was not allocated by the slapi_ch_ functions */
  335. if (freeval) slapi_ch_free_string(&value.bv_val);
  336. continue;
  337. }
  338. if (flags & SLAPI_STR2ENTRY_USE_OBSOLETE_DNFORMAT) {
  339. normdn =
  340. slapi_ch_strdup(slapi_dn_normalize_original(value.bv_val));
  341. } else {
  342. normdn = slapi_create_dn_string("%s", value.bv_val);
  343. }
  344. if (NULL == normdn) {
  345. char ebuf[ BUFSIZ ];
  346. LDAPDebug1Arg(LDAP_DEBUG_TRACE,
  347. "str2entry_fast: Invalid DN: %s\n",
  348. escape_string( value.bv_val, ebuf ));
  349. slapi_entry_free( e );
  350. if (freeval) slapi_ch_free_string(&value.bv_val);
  351. e = NULL;
  352. goto done;
  353. }
  354. /* normdn is consumed in e */
  355. slapi_entry_set_normdn(e, normdn);
  356. /* the memory below was not allocated by the slapi_ch_ functions */
  357. if (freeval) slapi_ch_free_string(&value.bv_val);
  358. continue;
  359. }
  360. if ( PL_strncasecmp( type.bv_val, "rdn", type.bv_len ) == 0 ) {
  361. if ( NULL == slapi_entry_get_rdn_const( e )) {
  362. slapi_entry_set_rdn( e, value.bv_val );
  363. }
  364. /* the memory below was not allocated by the slapi_ch_ functions */
  365. if (freeval) slapi_ch_free_string(&value.bv_val);
  366. continue;
  367. }
  368. /* If SLAPI_STR2ENTRY_NO_ENTRYDN is set, skip entrydn */
  369. if ( (flags & SLAPI_STR2ENTRY_NO_ENTRYDN) &&
  370. PL_strncasecmp( type.bv_val, "entrydn", type.bv_len ) == 0 ) {
  371. if (freeval) slapi_ch_free_string(&value.bv_val);
  372. continue;
  373. }
  374. /* retrieve uniqueid */
  375. if ( PL_strncasecmp (type.bv_val, SLAPI_ATTR_UNIQUEID, type.bv_len) == 0 ){
  376. if (e->e_uniqueid != NULL){
  377. LDAPDebug (LDAP_DEBUG_TRACE,
  378. "str2entry_fast: entry has multiple uniqueids %s "
  379. "and %s (second ignored)\n",
  380. e->e_uniqueid, value.bv_val, 0);
  381. }else{
  382. /* name2asi will be locked in slapi_entry_set_uniqueid */
  383. /* attr_syntax_unlock_read(); */
  384. slapi_entry_set_uniqueid (e, PL_strndup(value.bv_val, value.bv_len));
  385. /* attr_syntax_read_lock();*/
  386. }
  387. /* the memory below was not allocated by the slapi_ch_ functions */
  388. if (freeval) slapi_ch_free_string(&value.bv_val);
  389. continue;
  390. }
  391. if (PL_strncasecmp(type.bv_val,"objectclass",type.bv_len) == 0) {
  392. if (PL_strncasecmp(value.bv_val,"ldapsubentry",value.bv_len) == 0)
  393. e->e_flags |= SLAPI_ENTRY_LDAPSUBENTRY;
  394. if (PL_strncasecmp(value.bv_val, SLAPI_ATTR_VALUE_TOMBSTONE,value.bv_len) == 0)
  395. e->e_flags |= SLAPI_ENTRY_FLAG_TOMBSTONE;
  396. }
  397. {
  398. Slapi_Value *svalue = NULL;
  399. if(a==NULL)
  400. {
  401. switch(attr_state)
  402. {
  403. case ATTRIBUTE_PRESENT:
  404. if(attrlist_append_nosyntax_init(&e->e_attrs, type.bv_val, &a)==0 /* Found */)
  405. {
  406. LDAPDebug (LDAP_DEBUG_ANY, "str2entry_fast: Error. Non-contiguous attribute values for %s\n", type.bv_val, 0, 0);
  407. PR_ASSERT(0);
  408. continue;
  409. }
  410. break;
  411. case ATTRIBUTE_DELETED:
  412. if(attrlist_append_nosyntax_init(&e->e_deleted_attrs, type.bv_val, &a)==0 /* Found */)
  413. {
  414. LDAPDebug (LDAP_DEBUG_ANY, "str2entry_fast: Error. Non-contiguous deleted attribute values for %s\n", type.bv_val, 0, 0);
  415. PR_ASSERT(0);
  416. continue;
  417. }
  418. break;
  419. case ATTRIBUTE_NOTFOUND:
  420. LDAPDebug (LDAP_DEBUG_ANY, "str2entry_fast: Error. Non-contiguous deleted attribute values for %s\n", type.bv_val, 0, 0);
  421. PR_ASSERT(0);
  422. continue;
  423. /* break; ??? */
  424. }
  425. }
  426. /* moved the value setting code here to check Slapi_Attr 'a'
  427. * to retrieve the attribute syntax info */
  428. svalue = value_new(NULL, CSN_TYPE_NONE, NULL);
  429. #ifdef OBSOLETE_DN_SYNTAX_CHECK
  430. if (slapi_attr_is_dn_syntax_attr(*a)) {
  431. int rc = 0;
  432. char *dn_aval = NULL;
  433. if (strict) {
  434. /* check that the dn is formatted correctly */
  435. rc = slapi_dn_syntax_check(NULL, value.bv_val, 1);
  436. if (rc) { /* syntax check failed */
  437. LDAPDebug2Args(LDAP_DEBUG_TRACE,
  438. "str2entry_fast: strict: Invalid DN value: %s: %s\n",
  439. type.bv_val, value.bv_val);
  440. slapi_entry_free( e );
  441. if (freeval) slapi_ch_free_string(&value.bv_val);
  442. e = NULL;
  443. goto done;
  444. }
  445. }
  446. if (flags & SLAPI_STR2ENTRY_USE_OBSOLETE_DNFORMAT) {
  447. dn_aval = slapi_dn_normalize_original(value.bv_val);
  448. slapi_value_set(svalue, dn_aval, strlen(dn_aval));
  449. } else {
  450. Slapi_DN *sdn = slapi_sdn_new_dn_byref(value.bv_val);
  451. /* Note: slapi_sdn_get_dn returns normalized DN with
  452. * case-intact. Thus, the length of dn_aval is
  453. * slapi_sdn_get_ndn_len(sdn). */
  454. dn_aval = (char *)slapi_sdn_get_dn(sdn);
  455. slapi_value_set(svalue, (void *)dn_aval,
  456. slapi_sdn_get_ndn_len(sdn));
  457. slapi_sdn_free(&sdn);
  458. }
  459. } else {
  460. slapi_value_set_berval(svalue, &value);
  461. }
  462. #endif
  463. slapi_value_set_berval(svalue, &value);
  464. /* the memory below was not allocated by the slapi_ch_ functions */
  465. if (freeval) slapi_ch_free_string(&value.bv_val);
  466. svalue->v_csnset = valuecsnset;
  467. valuecsnset = NULL;
  468. {
  469. const CSN *distinguishedcsn= csnset_get_csn_of_type(svalue->v_csnset,CSN_TYPE_VALUE_DISTINGUISHED);
  470. if(distinguishedcsn!=NULL)
  471. {
  472. entry_add_dncsn_ext(e,distinguishedcsn, ENTRY_DNCSN_INCREASING);
  473. }
  474. }
  475. if(value_state==VALUE_DELETED)
  476. {
  477. /* consumes the value */
  478. valuearray_add_value_fast(
  479. &(*a)->a_deleted_values.va, /* JCM .va is private */
  480. svalue,
  481. del_nvals,
  482. &del_maxvals,
  483. 0/*!Exact*/,
  484. 1/*Passin*/ );
  485. del_nvals++;
  486. }
  487. else
  488. {
  489. /* consumes the value */
  490. valuearray_add_value_fast(
  491. &(*a)->a_present_values.va, /* JCM .va is private */
  492. svalue,
  493. nvals,
  494. &maxvals,
  495. 0 /*!Exact*/,
  496. 1 /*Passin*/ );
  497. nvals++;
  498. }
  499. if(attributedeletioncsn!=NULL)
  500. {
  501. attr_set_deletion_csn(*a,attributedeletioncsn);
  502. }
  503. }
  504. csn_free(&attributedeletioncsn);
  505. csnset_free(&valuecsnset);
  506. attr_val_cnt++;
  507. }
  508. slapi_ch_free_string(&ptype);
  509. if ( attr_val_cnt >= ENTRY_MAX_ATTRIBUTE_VALUE_COUNT )
  510. {
  511. LDAPDebug( LDAP_DEBUG_ANY,
  512. "str2entry_fast: entry %s exceeded max attribute value cound %ld\n",
  513. slapi_entry_get_dn_const(e)?slapi_entry_get_dn_const(e):"unknown",
  514. attr_val_cnt, 0 );
  515. }
  516. if (read_stateinfo && maxcsn)
  517. {
  518. e->e_maxcsn = maxcsn;
  519. maxcsn = NULL;
  520. }
  521. /* release read lock of name2asi, per-entry lock */
  522. /* attr_syntax_unlock_read();
  523. * no longer locked since attr syntax is not initialized
  524. */
  525. /* If this is a tombstone, it requires a special treatment for rdn. */
  526. if (e->e_flags & SLAPI_ENTRY_FLAG_TOMBSTONE) {
  527. /* tombstone */
  528. if (_entry_set_tombstone_rdn(e, slapi_entry_get_dn_const(e))) {
  529. LDAPDebug1Arg( LDAP_DEBUG_TRACE, "str2entry_fast: "
  530. "tombstone entry has badly formatted dn: %s\n",
  531. slapi_entry_get_dn_const(e) );
  532. slapi_entry_free( e ); e = NULL;
  533. goto done;
  534. }
  535. }
  536. /* check to make sure there was a dn: line */
  537. if ( slapi_entry_get_dn_const(e)==NULL ) {
  538. if (!(SLAPI_STR2ENTRY_INCLUDE_VERSION_STR & flags))
  539. LDAPDebug( LDAP_DEBUG_ANY, "str2entry_fast: entry has no dn\n",
  540. 0, 0, 0 );
  541. slapi_entry_free( e );
  542. e = NULL;
  543. }
  544. done:
  545. csn_free(&attributedeletioncsn);
  546. csn_free(&maxcsn);
  547. LDAPDebug( LDAP_DEBUG_TRACE, "<= str2entry_fast 0x%x\n",
  548. e, 0, 0 );
  549. return( e );
  550. }
  551. #define STR2ENTRY_SMALL_BUFFER_SIZE 64
  552. #define STR2ENTRY_INITIAL_BERVAL_ARRAY_SIZE 8
  553. #define STR2ENTRY_VALUE_DUPCHECK_THRESHOLD 5
  554. typedef struct _entry_attr_data {
  555. int ead_attrarrayindex;
  556. const char *ead_attrtypename;
  557. char ead_allocated; /* non-zero if this struct needs to be freed */
  558. } entry_attr_data;
  559. /* Structure which stores a tree for the attributes on the entry rather than the linked list on a regular entry struture */
  560. typedef struct _entry_attrs {
  561. Avlnode *ea_attrlist;
  562. int ea_attrdatacount;
  563. entry_attr_data ea_attrdata[ STR2ENTRY_SMALL_BUFFER_SIZE ];
  564. } entry_attrs;
  565. typedef struct _str2entry_attr {
  566. char *sa_type;
  567. int sa_state;
  568. struct valuearrayfast sa_present_values;
  569. struct valuearrayfast sa_deleted_values;
  570. int sa_numdups;
  571. value_compare_fn_type sa_comparefn;
  572. Avlnode *sa_vtree;
  573. CSN *sa_attributedeletioncsn;
  574. Slapi_Attr sa_attr;
  575. } str2entry_attr;
  576. static void
  577. entry_attr_init(str2entry_attr *sa, const char *type, int state)
  578. {
  579. sa->sa_type= slapi_ch_strdup(type);
  580. sa->sa_state= state;
  581. valuearrayfast_init(&sa->sa_present_values,NULL);
  582. valuearrayfast_init(&sa->sa_deleted_values,NULL);
  583. sa->sa_numdups= 0;
  584. sa->sa_comparefn = NULL;
  585. sa->sa_vtree= NULL;
  586. sa->sa_attributedeletioncsn= NULL;
  587. slapi_attr_init(&sa->sa_attr, type);
  588. }
  589. /*
  590. * Create a tree of attributes.
  591. */
  592. static int
  593. entry_attrs_new(entry_attrs **pea)
  594. {
  595. entry_attrs *tmp = (entry_attrs *)slapi_ch_calloc(1, sizeof(entry_attrs));
  596. if (NULL == tmp) {
  597. return -1;
  598. } else {
  599. *pea = tmp;
  600. return 0;
  601. }
  602. }
  603. /*
  604. * Delete an attribute type tree node.
  605. */
  606. static void
  607. attr_type_node_free( caddr_t data )
  608. {
  609. entry_attr_data *ea = (entry_attr_data *)data;
  610. if ( NULL != ea && ea->ead_allocated ) {
  611. slapi_ch_free( (void **)&ea );
  612. }
  613. }
  614. /*
  615. * Delete a tree of attributes.
  616. */
  617. static void
  618. entry_attrs_delete(entry_attrs **pea)
  619. {
  620. if (NULL != *pea) {
  621. /* Delete the AVL tree */
  622. avl_free((*pea)->ea_attrlist, attr_type_node_free);
  623. slapi_ch_free((void**)pea);
  624. }
  625. }
  626. static int
  627. attr_type_node_cmp( caddr_t d1, caddr_t d2 )
  628. {
  629. /*
  630. * A simple strcasecmp() will do here because we do not care
  631. * about subtypes, etc. The slapi_str2entry() function treats
  632. * subtypes as distinct attribute types, because that is how
  633. * they are stored within the Slapi_Entry structure.
  634. */
  635. entry_attr_data *ea1= (entry_attr_data *)d1;
  636. entry_attr_data *ea2= (entry_attr_data *)d2;
  637. PR_ASSERT( ea1 != NULL );
  638. PR_ASSERT( ea1->ead_attrtypename != NULL );
  639. PR_ASSERT( ea2 != NULL );
  640. PR_ASSERT( ea2->ead_attrtypename != NULL );
  641. return strcasecmp(ea1->ead_attrtypename,ea2->ead_attrtypename);
  642. }
  643. /*
  644. * Adds a new attribute to the attribute tree.
  645. */
  646. static void
  647. entry_attrs_add(entry_attrs *ea, const char *atname, int atarrayindex)
  648. {
  649. entry_attr_data *ead;
  650. if ( ea->ea_attrdatacount < STR2ENTRY_SMALL_BUFFER_SIZE ) {
  651. ead = &(ea->ea_attrdata[ ea->ea_attrdatacount ]);
  652. ead->ead_allocated = 0;
  653. } else {
  654. ead = (entry_attr_data *)slapi_ch_malloc( sizeof( entry_attr_data ));
  655. ead->ead_allocated = 1;
  656. }
  657. ++ea->ea_attrdatacount;
  658. ead->ead_attrarrayindex = atarrayindex;
  659. ead->ead_attrtypename = atname; /* a reference, not a strdup! */
  660. avl_insert( &(ea->ea_attrlist), ead, attr_type_node_cmp, avl_dup_error );
  661. }
  662. /*
  663. * Checks for an attribute in the tree. Returns the attr array index or -1
  664. * if not found;
  665. */
  666. static int
  667. entry_attrs_find(entry_attrs *ea,char *type)
  668. {
  669. entry_attr_data tmpead = {0};
  670. entry_attr_data *foundead;
  671. tmpead.ead_attrtypename = type;
  672. foundead = (entry_attr_data *)avl_find( ea->ea_attrlist, &tmpead,
  673. attr_type_node_cmp );
  674. return ( NULL != foundead ) ? foundead->ead_attrarrayindex : -1;
  675. }
  676. /* What's going on here then ?
  677. Well, originally duplicate value checking was done by taking each
  678. new value and comparing in turn against all the previous values.
  679. Needless to say this was costly when there were many values.
  680. So, new code was written which built a binary tree of index keys
  681. for the values, and the test was done against the tree.
  682. Nothing wrong with this, it speeded up the case where there were
  683. many values nicely.
  684. Unfortunately, when there are few values, it proved to be a significent
  685. performance sink.
  686. So, now we check the old way up 'till there's 5 attribute values, then
  687. switch to the tree-based scheme.
  688. Note that duplicate values are only checked for and ignored
  689. if flags contains SLAPI_STR2ENTRY_REMOVEDUPVALS.
  690. */
  691. /* dn is not consumed. Caller needs to free it. */
  692. static Slapi_Entry *
  693. str2entry_dupcheck( const char *rawdn, char *s, int flags, int read_stateinfo )
  694. {
  695. Slapi_Entry *e;
  696. str2entry_attr stack_attrs[STR2ENTRY_SMALL_BUFFER_SIZE];
  697. str2entry_attr *dyn_attrs = NULL;
  698. str2entry_attr *attrs = stack_attrs;
  699. str2entry_attr *prev_attr= NULL;
  700. int nattrs;
  701. int maxattrs = STR2ENTRY_SMALL_BUFFER_SIZE;
  702. char *type;
  703. struct berval bvtype;
  704. str2entry_attr *sa;
  705. int i, j;
  706. char *next=NULL;
  707. char *valuecharptr=NULL;
  708. struct berval bvvalue;
  709. int rc;
  710. int fast_dup_check = 0;
  711. entry_attrs *ea = NULL;
  712. int tree_attr_checking = 0;
  713. int big_entry_attr_presence_check = 0;
  714. int check_for_duplicate_values =
  715. ( 0 != ( flags & SLAPI_STR2ENTRY_REMOVEDUPVALS ));
  716. Slapi_Value *value = 0;
  717. CSN *attributedeletioncsn= NULL;
  718. CSN *maxcsn= NULL;
  719. char *normdn = NULL;
  720. int strict = 0;
  721. /* Check if we should be performing strict validation. */
  722. strict = config_get_dn_validate_strict();
  723. LDAPDebug( LDAP_DEBUG_TRACE, "=> str2entry_dupcheck\n", 0, 0, 0 );
  724. e = slapi_entry_alloc();
  725. slapi_entry_init(e,NULL,NULL);
  726. next = s;
  727. nattrs = 0;
  728. if (flags & SLAPI_STR2ENTRY_BIGENTRY)
  729. {
  730. big_entry_attr_presence_check = 1;
  731. }
  732. while ( (s = ldif_getline( &next )) != NULL )
  733. {
  734. CSNSet *valuecsnset= NULL;
  735. int value_state= VALUE_NOTFOUND;
  736. int attr_state= VALUE_NOTFOUND;
  737. int freeval = 0;
  738. struct berval bv_null = {0, NULL};
  739. csn_free(&attributedeletioncsn);
  740. if ( *s == '\n' || *s == '\0' ) {
  741. break;
  742. }
  743. bvtype = bv_null;
  744. bvvalue = bv_null;
  745. if ( slapi_ldif_parse_line( s, &bvtype, &bvvalue, &freeval ) < 0 ) {
  746. LDAPDebug(LDAP_DEBUG_ANY,
  747. "Warning: Entry (%s), ignoring invalid line \"%s\"...\n",
  748. rawdn ? rawdn : "", s, 0);
  749. continue;
  750. }
  751. type = bvtype.bv_val;
  752. valuecharptr = bvvalue.bv_val;
  753. /*
  754. * Extract the attribute and value CSNs from the attribute type.
  755. */
  756. csnset_free(&valuecsnset);
  757. value_state= VALUE_NOTFOUND;
  758. attr_state= VALUE_NOTFOUND;
  759. str2entry_state_information_from_type(type,&valuecsnset,&attributedeletioncsn,&maxcsn,&value_state,&attr_state);
  760. if(!read_stateinfo)
  761. {
  762. /* We are not maintaining state information */
  763. if(value_state==VALUE_DELETED || attr_state==ATTRIBUTE_DELETED)
  764. {
  765. /* ignore deleted values and attributes */
  766. /* the memory below was not allocated by the slapi_ch_ functions */
  767. if (freeval) slapi_ch_free_string(&bvvalue.bv_val);
  768. continue;
  769. }
  770. /* Ignore CSNs */
  771. csn_free(&attributedeletioncsn);
  772. csnset_free(&valuecsnset);
  773. }
  774. if ( rawdn ) {
  775. if ( NULL == slapi_entry_get_dn_const(e) ) {
  776. if (flags & SLAPI_STR2ENTRY_DN_NORMALIZED) {
  777. normdn = slapi_ch_strdup(rawdn);
  778. } else {
  779. normdn = slapi_create_dn_string("%s", rawdn);
  780. if (NULL == normdn) {
  781. LDAPDebug1Arg(LDAP_DEBUG_TRACE,
  782. "str2entry_dupcheck: Invalid DN: %s\n", rawdn);
  783. slapi_entry_free( e );
  784. if (freeval) slapi_ch_free_string(&bvvalue.bv_val);
  785. csn_free(&attributedeletioncsn);
  786. csn_free(&maxcsn);
  787. return NULL;
  788. }
  789. }
  790. /* normdn is consumed in e */
  791. slapi_entry_set_normdn(e, normdn);
  792. }
  793. if ( NULL == slapi_entry_get_rdn_const(e) ) {
  794. if (normdn) {
  795. /* normdn is just referred in slapi_entry_set_rdn. */
  796. slapi_entry_set_rdn(e, normdn);
  797. } else {
  798. if (flags & SLAPI_STR2ENTRY_DN_NORMALIZED) {
  799. normdn = slapi_ch_strdup(rawdn);
  800. } else {
  801. normdn = slapi_create_dn_string("%s", rawdn);
  802. if (NULL == normdn) {
  803. LDAPDebug1Arg(LDAP_DEBUG_TRACE,
  804. "str2entry_dupcheck: Invalid DN: %s\n", rawdn);
  805. slapi_entry_free( e );
  806. if (freeval) slapi_ch_free_string(&bvvalue.bv_val);
  807. csn_free(&attributedeletioncsn);
  808. csn_free(&maxcsn);
  809. return NULL;
  810. }
  811. }
  812. /* normdn is just referred in slapi_entry_set_rdn. */
  813. slapi_entry_set_rdn(e, normdn);
  814. slapi_ch_free_string(&normdn);
  815. }
  816. }
  817. rawdn = NULL; /* Set once in the loop.
  818. This won't affect the caller's passed address. */
  819. }
  820. if ( strcasecmp( type, "dn" ) == 0 ) {
  821. if ( slapi_entry_get_dn_const(e)!=NULL ) {
  822. char ebuf[ BUFSIZ ];
  823. LDAPDebug( LDAP_DEBUG_TRACE,
  824. "str2entry_dupcheck: entry has multiple dns \"%s\" "
  825. "and \"%s\" (second ignored)\n",
  826. slapi_entry_get_dn_const(e),
  827. escape_string( valuecharptr, ebuf ), 0 );
  828. /* the memory below was not allocated by the slapi_ch_ functions */
  829. if (freeval) slapi_ch_free_string(&bvvalue.bv_val);
  830. continue;
  831. }
  832. normdn = slapi_create_dn_string("%s", valuecharptr);
  833. if (NULL == normdn) {
  834. LDAPDebug1Arg(LDAP_DEBUG_TRACE,
  835. "str2entry_dupcheck: Invalid DN: %s\n", valuecharptr);
  836. slapi_entry_free( e ); e = NULL;
  837. if (freeval) slapi_ch_free_string(&bvvalue.bv_val);
  838. goto free_and_return;
  839. }
  840. /* normdn is consumed in e */
  841. slapi_entry_set_normdn(e, normdn);
  842. /* the memory below was not allocated by the slapi_ch_ functions */
  843. if (freeval) slapi_ch_free_string(&bvvalue.bv_val);
  844. continue;
  845. }
  846. if ( strcasecmp( type, "rdn" ) == 0 ) {
  847. if ( NULL == slapi_entry_get_rdn_const( e )) {
  848. slapi_entry_set_rdn( e, valuecharptr );
  849. }
  850. /* the memory below was not allocated by the slapi_ch_ functions */
  851. if (freeval) slapi_ch_free_string(&bvvalue.bv_val);
  852. continue;
  853. }
  854. /* If SLAPI_STR2ENTRY_NO_ENTRYDN is set, skip entrydn */
  855. if ( (flags & SLAPI_STR2ENTRY_NO_ENTRYDN) &&
  856. strcasecmp( type, "entrydn" ) == 0 ) {
  857. if (freeval) slapi_ch_free_string(&bvvalue.bv_val);
  858. continue;
  859. }
  860. /* retrieve uniqueid */
  861. if ( strcasecmp (type, SLAPI_ATTR_UNIQUEID) == 0 ){
  862. if (e->e_uniqueid != NULL){
  863. LDAPDebug (LDAP_DEBUG_TRACE,
  864. "str2entry_dupcheck: entry has multiple uniqueids %s "
  865. "and %s (second ignored)\n",
  866. e->e_uniqueid, valuecharptr, 0);
  867. }else{
  868. slapi_entry_set_uniqueid (e, slapi_ch_strdup(valuecharptr));
  869. }
  870. /* the memory below was not allocated by the slapi_ch_ functions */
  871. if (freeval) slapi_ch_free_string(&bvvalue.bv_val);
  872. continue;
  873. }
  874. if (strcasecmp(type,"objectclass") == 0) {
  875. if (strcasecmp(valuecharptr,"ldapsubentry") == 0)
  876. e->e_flags |= SLAPI_ENTRY_LDAPSUBENTRY;
  877. if (strcasecmp(valuecharptr, SLAPI_ATTR_VALUE_TOMBSTONE) == 0)
  878. e->e_flags |= SLAPI_ENTRY_FLAG_TOMBSTONE;
  879. }
  880. /* Here we have a quick look to see if this attribute is a new
  881. value for the type we last processed or a new type.
  882. If not, we look to see if we've seen this attribute type before.
  883. */
  884. if ( prev_attr!=NULL && strcasecmp( type, prev_attr->sa_type ) != 0 )
  885. {
  886. /* Different attribute type - find it, or alloc new */
  887. prev_attr = NULL;
  888. /* The linear check below can take a while, so we change to use a tree if there are many attrs */
  889. if (!big_entry_attr_presence_check)
  890. {
  891. for ( i = 0; i < nattrs; i++ )
  892. {
  893. if (strcasecmp( type, attrs[i].sa_type ) == 0 )
  894. {
  895. prev_attr = &attrs[i];
  896. break;
  897. }
  898. }
  899. }
  900. else
  901. {
  902. int prev_index;
  903. /* Did we just switch checking mechanism ? */
  904. if (!tree_attr_checking)
  905. {
  906. /* If so then put the exising attrs into the tree */
  907. if (0 != entry_attrs_new(&ea))
  908. {
  909. /* Something very bad happened */
  910. if (freeval) slapi_ch_free_string(&bvvalue.bv_val);
  911. csn_free(&attributedeletioncsn);
  912. csn_free(&maxcsn);
  913. return NULL;
  914. }
  915. for ( i = 0; i < nattrs; i++ )
  916. {
  917. entry_attrs_add(ea,attrs[i].sa_type, i);
  918. }
  919. tree_attr_checking = 1;
  920. }
  921. prev_index = entry_attrs_find(ea,type);
  922. if ( prev_index >= 0 ) {
  923. prev_attr = &attrs[prev_index];
  924. /* (prev_attr!=NULL) Means that we already had that one in the set */
  925. }
  926. }
  927. }
  928. if ( prev_attr==NULL )
  929. {
  930. /* Haven't seen this type yet */
  931. fast_dup_check = 1;
  932. if ( nattrs == maxattrs )
  933. {
  934. /* Out of space - reallocate */
  935. maxattrs *= 2;
  936. if ( nattrs == STR2ENTRY_SMALL_BUFFER_SIZE ) {
  937. /* out of fixed space - switch to dynamic */
  938. PR_ASSERT( dyn_attrs == NULL );
  939. dyn_attrs = (str2entry_attr *)
  940. slapi_ch_malloc( sizeof( str2entry_attr ) *
  941. maxattrs );
  942. memcpy( dyn_attrs, stack_attrs,
  943. STR2ENTRY_SMALL_BUFFER_SIZE *
  944. sizeof( str2entry_attr ));
  945. attrs = dyn_attrs;
  946. } else {
  947. /* Need more dynamic space */
  948. dyn_attrs = (str2entry_attr *)
  949. slapi_ch_realloc( (char *) dyn_attrs,
  950. sizeof( str2entry_attr ) * maxattrs );
  951. attrs = dyn_attrs; /* realloc may change base pointer */
  952. }
  953. }
  954. /* Record the new type in the array */
  955. entry_attr_init(&attrs[nattrs], type, attr_state);
  956. if ( check_for_duplicate_values )
  957. {
  958. /* Get the comparison function for later use */
  959. attr_get_value_cmp_fn( &attrs[nattrs].sa_attr, &(attrs[nattrs].sa_comparefn));
  960. /*
  961. * If the compare function wasn't available,
  962. * we have to revert to AVL-tree-based dup checking,
  963. * which uses index keys for comparisons
  964. */
  965. if (NULL == attrs[nattrs].sa_comparefn)
  966. {
  967. fast_dup_check = 0;
  968. }
  969. /*
  970. * If we are maintaining the attribute tree,
  971. * then add the new attribute to the tree.
  972. */
  973. if (big_entry_attr_presence_check && tree_attr_checking)
  974. {
  975. entry_attrs_add(ea,attrs[nattrs].sa_type, nattrs);
  976. }
  977. }
  978. prev_attr = &attrs[nattrs];
  979. nattrs++;
  980. } else { /* prev_attr != NULL */
  981. if ( check_for_duplicate_values ) {
  982. /*
  983. * If the compare function wasn't available,
  984. * we have to revert to AVL-tree-based dup checking,
  985. * which uses index keys for comparisons
  986. */
  987. if (NULL == prev_attr->sa_comparefn) {
  988. fast_dup_check = 0;
  989. }
  990. }
  991. }
  992. sa = prev_attr; /* For readability */
  993. value= value_new(NULL, CSN_TYPE_NONE, NULL);
  994. if (slapi_attr_is_dn_syntax_attr(&(sa->sa_attr))) {
  995. Slapi_DN *sdn = NULL;
  996. const char *dn_aval = NULL;
  997. if (strict) {
  998. /* check that the dn is formatted correctly */
  999. rc = slapi_dn_syntax_check(NULL, valuecharptr, 1);
  1000. if (rc) { /* syntax check failed */
  1001. LDAPDebug2Args(LDAP_DEBUG_ANY,
  1002. "str2entry_dupcheck: strict: Invalid DN value: %s: %s\n",
  1003. type, valuecharptr);
  1004. slapi_entry_free( e ); e = NULL;
  1005. if (freeval) slapi_ch_free_string(&bvvalue.bv_val);
  1006. goto free_and_return;
  1007. }
  1008. }
  1009. sdn = slapi_sdn_new_dn_byref(bvvalue.bv_val);
  1010. /* Note: slapi_sdn_get_dn returns the normalized DN
  1011. * with case-intact. Thus, the length of dn_aval is
  1012. * slapi_sdn_get_ndn_len(sdn). */
  1013. dn_aval = slapi_sdn_get_dn(sdn);
  1014. slapi_value_set(value, (void *)dn_aval, slapi_sdn_get_ndn_len(sdn));
  1015. slapi_sdn_free(&sdn);
  1016. } else {
  1017. slapi_value_set_berval(value, &bvvalue);
  1018. }
  1019. /* the memory below was not allocated by the slapi_ch_ functions */
  1020. if (freeval) slapi_ch_free_string(&bvvalue.bv_val);
  1021. value->v_csnset= valuecsnset;
  1022. valuecsnset= NULL;
  1023. {
  1024. const CSN *distinguishedcsn= csnset_get_csn_of_type(value->v_csnset,CSN_TYPE_VALUE_DISTINGUISHED);
  1025. if(distinguishedcsn!=NULL)
  1026. {
  1027. entry_add_dncsn(e,distinguishedcsn);
  1028. }
  1029. }
  1030. if(value_state==VALUE_DELETED)
  1031. {
  1032. /*
  1033. * for deleted values, we do not want to perform a dupcheck against
  1034. * existing values. Also, we do not want to add it to the
  1035. * avl tree (if one is being maintained)
  1036. *
  1037. */
  1038. rc = 0; /* Presume no duplicate */
  1039. }
  1040. else if ( !check_for_duplicate_values )
  1041. {
  1042. rc = LDAP_SUCCESS; /* presume no duplicate */
  1043. } else {
  1044. /* For value dup checking, we either use brute-force, if there's a small number */
  1045. /* Or a tree-based approach if there's a large number. */
  1046. /* The tree code is expensive, which is why we don't use it unless there's many attributes */
  1047. rc = 0; /* Presume no duplicate */
  1048. if (fast_dup_check)
  1049. {
  1050. /* Fast dup-checking */
  1051. /* Do we now have so many values that we should switch to tree-based checking ? */
  1052. if (sa->sa_present_values.num > STR2ENTRY_VALUE_DUPCHECK_THRESHOLD)
  1053. {
  1054. /* Make the tree from the existing attr values */
  1055. rc= valuetree_add_valuearray( &sa->sa_attr, sa->sa_present_values.va, &sa->sa_vtree, NULL);
  1056. /* Check if the value already exists, in the tree. */
  1057. rc= valuetree_add_value( &sa->sa_attr, value, &sa->sa_vtree);
  1058. fast_dup_check = 0;
  1059. }
  1060. else
  1061. {
  1062. /* JCM - need an efficient valuearray function to do this */
  1063. /* Brute-force check */
  1064. for ( j = 0; j < sa->sa_present_values.num; j++ )/* JCM innards */
  1065. {
  1066. if (0 == sa->sa_comparefn(slapi_value_get_berval(value),slapi_value_get_berval(sa->sa_present_values.va[j])))/* JCM innards */
  1067. {
  1068. /* Oops---this value matches one already present */
  1069. rc = LDAP_TYPE_OR_VALUE_EXISTS;
  1070. break;
  1071. }
  1072. }
  1073. }
  1074. }
  1075. else
  1076. {
  1077. /* Check if the value already exists, in the tree. */
  1078. rc = valuetree_add_value( &sa->sa_attr, value, &sa->sa_vtree);
  1079. }
  1080. }
  1081. if ( rc==LDAP_SUCCESS )
  1082. {
  1083. if(value_state==VALUE_DELETED)
  1084. {
  1085. valuearrayfast_add_value_passin(&sa->sa_deleted_values,value);
  1086. value= NULL; /* value was consumed */
  1087. }
  1088. else
  1089. {
  1090. valuearrayfast_add_value_passin(&sa->sa_present_values,value);
  1091. value= NULL; /* value was consumed */
  1092. }
  1093. if(attributedeletioncsn!=NULL)
  1094. {
  1095. sa->sa_attributedeletioncsn= attributedeletioncsn;
  1096. attributedeletioncsn= NULL; /* csn was consumed */
  1097. }
  1098. }
  1099. else if (rc==LDAP_TYPE_OR_VALUE_EXISTS)
  1100. {
  1101. sa->sa_numdups++;
  1102. csn_free(&attributedeletioncsn);
  1103. }
  1104. else
  1105. {
  1106. /* Failure adding to value tree */
  1107. LDAPDebug( LDAP_DEBUG_ANY, "str2entry_dupcheck: unexpected failure %d constructing value tree\n", rc, 0, 0 );
  1108. slapi_entry_free( e ); e = NULL;
  1109. goto free_and_return;
  1110. }
  1111. slapi_value_free(&value);
  1112. }
  1113. /* All done with parsing. Now create the entry. */
  1114. /* check to make sure there was a dn: line */
  1115. if ( slapi_entry_get_dn_const(e)==NULL )
  1116. {
  1117. if (!(SLAPI_STR2ENTRY_INCLUDE_VERSION_STR & flags))
  1118. LDAPDebug( LDAP_DEBUG_ANY, "str2entry_dupcheck: entry has no dn\n",
  1119. 0, 0, 0 );
  1120. slapi_entry_free( e ); e = NULL;
  1121. goto free_and_return;
  1122. }
  1123. /* get the read lock of name2asi for performance purpose.
  1124. It reduces read locking by per-entry lock, instead of per-attribute.
  1125. */
  1126. attr_syntax_read_lock();
  1127. /*
  1128. * For each unique attribute in the array,
  1129. * Create a Slapi_Attr and set it's present and deleted values.
  1130. */
  1131. for ( i = 0; i < nattrs; i++ )
  1132. {
  1133. sa = &attrs[i];
  1134. if ( sa->sa_numdups > 0 )
  1135. {
  1136. if ( sa->sa_numdups > 1 ) {
  1137. LDAPDebug( LDAP_DEBUG_ANY, "str2entry_dupcheck: %d duplicate values for attribute "
  1138. "type %s detected in entry %s. Extra values ignored.\n",
  1139. sa->sa_numdups, sa->sa_type, slapi_entry_get_dn_const(e) );
  1140. } else {
  1141. LDAPDebug( LDAP_DEBUG_ANY, "str2entry_dupcheck: Duplicate value for attribute "
  1142. "type %s detected in entry %s. Extra value ignored.\n",
  1143. sa->sa_type, slapi_entry_get_dn_const(e), 0 );
  1144. }
  1145. }
  1146. {
  1147. Slapi_Attr **alist= NULL;
  1148. if(sa->sa_state==ATTRIBUTE_DELETED)
  1149. {
  1150. if(read_stateinfo)
  1151. {
  1152. alist= &e->e_deleted_attrs;
  1153. }
  1154. else
  1155. {
  1156. /*
  1157. * if we are not maintaining state info,
  1158. * ignore the deleted attributes
  1159. */
  1160. }
  1161. }
  1162. else
  1163. {
  1164. alist= &e->e_attrs;
  1165. }
  1166. if(alist!=NULL)
  1167. {
  1168. int maxvals = 0;
  1169. Slapi_Attr **a= NULL;
  1170. attrlist_find_or_create_locking_optional(alist, sa->sa_type, &a, PR_FALSE);
  1171. valuearray_add_valuearray_fast( /* JCM should be calling a valueset function */
  1172. &(*a)->a_present_values.va, /* JCM .va is private */
  1173. sa->sa_present_values.va,
  1174. 0, /* Currently there are no present values on the attribute */
  1175. sa->sa_present_values.num,
  1176. &maxvals,
  1177. 1/*Exact*/,
  1178. 1/*Passin*/);
  1179. sa->sa_present_values.num= 0; /* The values have been consumed */
  1180. maxvals = 0;
  1181. valuearray_add_valuearray_fast( /* JCM should be calling a valueset function */
  1182. &(*a)->a_deleted_values.va, /* JCM .va is private */
  1183. sa->sa_deleted_values.va,
  1184. 0, /* Currently there are no deleted values on the attribute */
  1185. sa->sa_deleted_values.num,
  1186. &maxvals,
  1187. 1/*Exact*/,
  1188. 1/*Passin*/);
  1189. sa->sa_deleted_values.num= 0; /* The values have been consumed */
  1190. if(sa->sa_attributedeletioncsn!=NULL)
  1191. {
  1192. attr_set_deletion_csn(*a,sa->sa_attributedeletioncsn);
  1193. csn_free(&sa->sa_attributedeletioncsn);
  1194. }
  1195. }
  1196. }
  1197. }
  1198. /* release read lock of name2asi, per-entry lock */
  1199. attr_syntax_unlock_read();
  1200. /* If this is a tombstone, it requires a special treatment for rdn. */
  1201. if (e->e_flags & SLAPI_ENTRY_FLAG_TOMBSTONE) {
  1202. /* tombstone */
  1203. if (_entry_set_tombstone_rdn(e, slapi_entry_get_dn_const(e))) {
  1204. LDAPDebug1Arg( LDAP_DEBUG_TRACE, "str2entry_dupcheck: "
  1205. "tombstone entry has badly formatted dn: %s\n",
  1206. slapi_entry_get_dn_const(e) );
  1207. slapi_entry_free( e ); e = NULL;
  1208. goto free_and_return;
  1209. }
  1210. }
  1211. /* Add the RDN values, if asked, and if not already present */
  1212. if ( flags & SLAPI_STR2ENTRY_ADDRDNVALS ) {
  1213. if ( slapi_entry_add_rdn_values( e ) != LDAP_SUCCESS ) {
  1214. LDAPDebug( LDAP_DEBUG_TRACE,
  1215. "str2entry_dupcheck: entry has badly formatted dn\n",
  1216. 0, 0, 0 );
  1217. slapi_entry_free( e ); e = NULL;
  1218. goto free_and_return;
  1219. }
  1220. }
  1221. if (read_stateinfo)
  1222. {
  1223. e->e_maxcsn = maxcsn;
  1224. maxcsn = NULL;
  1225. }
  1226. free_and_return:
  1227. for ( i = 0; i < nattrs; i++ )
  1228. {
  1229. slapi_ch_free((void **) &(attrs[ i ].sa_type));
  1230. valuearrayfast_done(&attrs[ i ].sa_present_values);
  1231. valuearrayfast_done(&attrs[ i ].sa_deleted_values);
  1232. valuetree_free( &attrs[ i ].sa_vtree );
  1233. attr_done( &attrs[ i ].sa_attr );
  1234. }
  1235. if (tree_attr_checking)
  1236. {
  1237. entry_attrs_delete(&ea);
  1238. }
  1239. slapi_ch_free((void **) &dyn_attrs );
  1240. if (value) slapi_value_free(&value);
  1241. csn_free(&attributedeletioncsn);
  1242. csn_free(&maxcsn);
  1243. LDAPDebug( LDAP_DEBUG_TRACE, "<= str2entry_dupcheck 0x%x \"%s\"\n",
  1244. e, slapi_sdn_get_dn (slapi_entry_get_sdn_const(e)), 0 );
  1245. return e;
  1246. }
  1247. /*
  1248. *
  1249. * Convert an entry in LDIF format into a
  1250. * Slapi_Entry structure. If we can assume that the
  1251. * LDIF is well-formed we call str2entry_fast(),
  1252. * which does no error checking.
  1253. * Otherwise we do not assume well-formed LDIF, and
  1254. * call str2entry_dupcheck(), which checks for
  1255. * duplicate attribute values and does not assume
  1256. * that values are all contiguous.
  1257. *
  1258. * Well-formed LDIF has the following characteristics:
  1259. * 1) There are no duplicate attribute values
  1260. * 2) The RDN is an attribute of the entry
  1261. * 3) All values for a given attribute type are
  1262. * contiguous.
  1263. */
  1264. #define SLAPI_STRENTRY_FLAGS_HANDLED_IN_SLAPI_STR2ENTRY \
  1265. ( SLAPI_STR2ENTRY_IGNORE_STATE \
  1266. | SLAPI_STR2ENTRY_EXPAND_OBJECTCLASSES \
  1267. | SLAPI_STR2ENTRY_TOMBSTONE_CHECK \
  1268. | SLAPI_STR2ENTRY_USE_OBSOLETE_DNFORMAT \
  1269. | SLAPI_STR2ENTRY_NO_ENTRYDN \
  1270. | SLAPI_STR2ENTRY_DN_NORMALIZED \
  1271. )
  1272. #define SLAPI_STRENTRY_FLAGS_HANDLED_BY_STR2ENTRY_FAST \
  1273. ( SLAPI_STR2ENTRY_INCLUDE_VERSION_STR \
  1274. | SLAPI_STRENTRY_FLAGS_HANDLED_IN_SLAPI_STR2ENTRY \
  1275. )
  1276. /*
  1277. * If well-formed LDIF has not been provided OR if a flag that is
  1278. * not handled by str2entry_fast() has been passed in, call the
  1279. * slower but more forgiving str2entry_dupcheck() function.
  1280. */
  1281. #define STR2ENTRY_CANNOT_USE_FAST(flags) \
  1282. (((flags) & SLAPI_STR2ENTRY_NOT_WELL_FORMED_LDIF) || \
  1283. ((flags) & ~SLAPI_STRENTRY_FLAGS_HANDLED_BY_STR2ENTRY_FAST))
  1284. Slapi_Entry *
  1285. slapi_str2entry( char *s, int flags )
  1286. {
  1287. Slapi_Entry *e;
  1288. int read_stateinfo= ~( flags & SLAPI_STR2ENTRY_IGNORE_STATE );
  1289. LDAPDebug( LDAP_DEBUG_ARGS,
  1290. "slapi_str2entry: flags=0x%x, entry=\"%.50s...\"\n",
  1291. flags, s, 0 );
  1292. /*
  1293. * If well-formed LDIF has not been provided OR if a flag that is
  1294. * not handled by str2entry_fast() has been passed in, call the
  1295. * slower but more forgiving str2entry_dupcheck() function.
  1296. */
  1297. if (STR2ENTRY_CANNOT_USE_FAST(flags))
  1298. {
  1299. e= str2entry_dupcheck( NULL/*dn*/, s, flags, read_stateinfo );
  1300. }
  1301. else
  1302. {
  1303. e= str2entry_fast( NULL/*dn*/, NULL/*rdn*/, s, flags, read_stateinfo );
  1304. }
  1305. if (!e)
  1306. return e; /* e == NULL */
  1307. if ( flags & SLAPI_STR2ENTRY_EXPAND_OBJECTCLASSES )
  1308. {
  1309. if ( flags & SLAPI_STR2ENTRY_NO_SCHEMA_LOCK )
  1310. {
  1311. schema_expand_objectclasses_nolock( e );
  1312. }
  1313. else
  1314. {
  1315. slapi_schema_expand_objectclasses( e );
  1316. }
  1317. }
  1318. if ( flags & SLAPI_STR2ENTRY_TOMBSTONE_CHECK )
  1319. {
  1320. /*
  1321. * Check if the entry is a tombstone.
  1322. */
  1323. if(slapi_entry_attr_hasvalue(e, SLAPI_ATTR_OBJECTCLASS, SLAPI_ATTR_VALUE_TOMBSTONE))
  1324. {
  1325. e->e_flags |= SLAPI_ENTRY_FLAG_TOMBSTONE;
  1326. }
  1327. }
  1328. return e;
  1329. }
  1330. /*
  1331. * string s does not include dn.
  1332. * NOTE: the first arg "dn" should have been normalized before passing.
  1333. */
  1334. Slapi_Entry *
  1335. slapi_str2entry_ext( const char *normdn, const Slapi_RDN *srdn, char *s, int flags )
  1336. {
  1337. Slapi_Entry *e;
  1338. int read_stateinfo= ~( flags & SLAPI_STR2ENTRY_IGNORE_STATE );
  1339. if (NULL == normdn)
  1340. {
  1341. return slapi_str2entry( s, flags );
  1342. }
  1343. LDAPDebug( LDAP_DEBUG_ARGS,
  1344. "slapi_str2entry_ext: flags=0x%x, dn=\"%s\", entry=\"%.50s...\"\n",
  1345. flags, normdn, s );
  1346. /*
  1347. * If well-formed LDIF has not been provided OR if a flag that is
  1348. * not handled by str2entry_fast() has been passed in, call the
  1349. * slower but more forgiving str2entry_dupcheck() function.
  1350. */
  1351. if (STR2ENTRY_CANNOT_USE_FAST(flags))
  1352. {
  1353. e = str2entry_dupcheck( normdn, s,
  1354. flags|SLAPI_STR2ENTRY_DN_NORMALIZED, read_stateinfo );
  1355. }
  1356. else
  1357. {
  1358. e = str2entry_fast( normdn, srdn, s,
  1359. flags|SLAPI_STR2ENTRY_DN_NORMALIZED, read_stateinfo );
  1360. }
  1361. if (!e)
  1362. return e; /* e == NULL */
  1363. if ( flags & SLAPI_STR2ENTRY_EXPAND_OBJECTCLASSES )
  1364. {
  1365. if ( flags & SLAPI_STR2ENTRY_NO_SCHEMA_LOCK )
  1366. {
  1367. schema_expand_objectclasses_nolock( e );
  1368. }
  1369. else
  1370. {
  1371. slapi_schema_expand_objectclasses( e );
  1372. }
  1373. }
  1374. if ( flags & SLAPI_STR2ENTRY_TOMBSTONE_CHECK )
  1375. {
  1376. /*
  1377. * Check if the entry is a tombstone.
  1378. */
  1379. if(slapi_entry_attr_hasvalue(e, SLAPI_ATTR_OBJECTCLASS, SLAPI_ATTR_VALUE_TOMBSTONE))
  1380. {
  1381. e->e_flags |= SLAPI_ENTRY_FLAG_TOMBSTONE;
  1382. }
  1383. }
  1384. return e;
  1385. }
  1386. /*
  1387. * If the attribute type is in the protected list, it returns size 0.
  1388. */
  1389. static size_t
  1390. entry2str_internal_size_value( const char *attrtype, const Slapi_Value *v,
  1391. int entry2str_ctrl, int attribute_state,
  1392. int value_state )
  1393. {
  1394. size_t elen = 0;
  1395. size_t attrtypelen;
  1396. if((NULL == attrtype) || is_type_protected(attrtype)) {
  1397. goto bail;
  1398. }
  1399. attrtypelen = strlen(attrtype);
  1400. if(entry2str_ctrl & SLAPI_DUMP_STATEINFO)
  1401. {
  1402. attrtypelen+= csnset_string_size(v->v_csnset);
  1403. if (attribute_state==ATTRIBUTE_DELETED)
  1404. {
  1405. attrtypelen += DELETED_ATTR_STRSIZE;
  1406. }
  1407. if(value_state==VALUE_DELETED)
  1408. {
  1409. attrtypelen += DELETED_VALUE_STRSIZE;
  1410. }
  1411. }
  1412. elen = LDIF_SIZE_NEEDED(attrtypelen, slapi_value_get_berval(v)->bv_len);
  1413. bail:
  1414. return elen;
  1415. }
  1416. static size_t
  1417. entry2str_internal_size_valueset( const char *attrtype, const Slapi_ValueSet *vs, int entry2str_ctrl, int attribute_state, int value_state )
  1418. {
  1419. size_t elen= 0;
  1420. if(!valueset_isempty(vs))
  1421. {
  1422. int i;
  1423. Slapi_Value **va= valueset_get_valuearray(vs);
  1424. for (i = 0; va[i]; i++)
  1425. {
  1426. elen+= entry2str_internal_size_value(attrtype, va[i], entry2str_ctrl,
  1427. attribute_state, value_state );
  1428. }
  1429. }
  1430. return elen;
  1431. }
  1432. static size_t
  1433. entry2str_internal_size_attrlist( const Slapi_Attr *attrlist, int entry2str_ctrl, int attribute_state )
  1434. {
  1435. size_t elen= 0;
  1436. const Slapi_Attr *a;
  1437. for (a= attrlist; a; a = a->a_next)
  1438. {
  1439. /* skip operational attributes if not requested */
  1440. if ((entry2str_ctrl & SLAPI_DUMP_NOOPATTRS) &&
  1441. slapi_attr_flag_is_set(a, SLAPI_ATTR_FLAG_OPATTR))
  1442. continue;
  1443. /* Count the space required for the present and deleted values */
  1444. elen+= entry2str_internal_size_valueset(a->a_type, &a->a_present_values,
  1445. entry2str_ctrl, attribute_state,
  1446. VALUE_PRESENT);
  1447. if(entry2str_ctrl & SLAPI_DUMP_STATEINFO)
  1448. {
  1449. elen+= entry2str_internal_size_valueset(a->a_type, &a->a_deleted_values,
  1450. entry2str_ctrl, attribute_state,
  1451. VALUE_DELETED);
  1452. /* ";adcsn-" + a->a_deletioncsn */
  1453. if ( a->a_deletioncsn )
  1454. {
  1455. elen+= 1 + LDIF_CSNPREFIX_MAXLENGTH + CSN_STRSIZE;
  1456. }
  1457. }
  1458. }
  1459. return elen;
  1460. }
  1461. static void
  1462. entry2str_internal_put_value( const char *attrtype, const CSN *attrcsn, CSNType attrcsntype, int attr_state, const Slapi_Value *v, int value_state, char **ecur, char **typebuf, size_t *typebuf_len, int entry2str_ctrl )
  1463. {
  1464. const char *type;
  1465. unsigned long options = 0;
  1466. const struct berval *bvp;
  1467. if(entry2str_ctrl & SLAPI_DUMP_STATEINFO)
  1468. {
  1469. char *p;
  1470. size_t attrtypelen= strlen(attrtype);
  1471. size_t attrcsnlen= 0;
  1472. size_t valuecsnlen= 0;
  1473. size_t need= attrtypelen+1;
  1474. if(attrcsn!=NULL)
  1475. {
  1476. /* ; csntype csn */
  1477. attrcsnlen= 1 + csn_string_size();
  1478. need+= attrcsnlen;
  1479. }
  1480. if(v->v_csnset!=NULL)
  1481. {
  1482. /* +(; csntype csn) */
  1483. valuecsnlen= csnset_string_size(v->v_csnset);
  1484. need+= valuecsnlen;
  1485. }
  1486. if(attr_state==ATTRIBUTE_DELETED)
  1487. {
  1488. need+= DELETED_ATTR_STRSIZE;
  1489. }
  1490. if(value_state==VALUE_DELETED)
  1491. {
  1492. need+= DELETED_VALUE_STRSIZE; /* ;deleted */
  1493. }
  1494. if(*typebuf_len<need)
  1495. {
  1496. *typebuf= (char*)slapi_ch_realloc(*typebuf,need);
  1497. *typebuf_len= need;
  1498. }
  1499. p= *typebuf;
  1500. type= p;
  1501. strcpy(p,attrtype);
  1502. p+= attrtypelen;
  1503. if(attrcsn!=NULL)
  1504. {
  1505. csn_as_attr_option_string(attrcsntype,attrcsn,p);
  1506. p+= attrcsnlen;
  1507. }
  1508. if(v->v_csnset!=NULL)
  1509. {
  1510. csnset_as_string(v->v_csnset,p);
  1511. p+= valuecsnlen;
  1512. }
  1513. if(attr_state==ATTRIBUTE_DELETED)
  1514. {
  1515. strcpy(p,DELETED_ATTR_STRING);
  1516. p+= DELETED_ATTR_STRSIZE;
  1517. }
  1518. if(value_state==VALUE_DELETED)
  1519. {
  1520. strcpy(p,DELETED_VALUE_STRING);
  1521. }
  1522. }
  1523. else
  1524. {
  1525. type= attrtype;
  1526. }
  1527. bvp = slapi_value_get_berval(v);
  1528. if (entry2str_ctrl & SLAPI_DUMP_NOWRAP)
  1529. options |= LDIF_OPT_NOWRAP;
  1530. if (entry2str_ctrl & SLAPI_DUMP_MINIMAL_ENCODING)
  1531. options |= LDIF_OPT_MINIMAL_ENCODING;
  1532. slapi_ldif_put_type_and_value_with_options( ecur, type, bvp->bv_val, bvp->bv_len, options );
  1533. }
  1534. static void
  1535. entry2str_internal_put_valueset( const char *attrtype, const CSN *attrcsn, CSNType attrcsntype, int attr_state, const Slapi_ValueSet *vs, int value_state, char **ecur, char **typebuf, size_t *typebuf_len, int entry2str_ctrl )
  1536. {
  1537. if(!valueset_isempty(vs))
  1538. {
  1539. int i;
  1540. Slapi_Value **va= valueset_get_valuearray(vs);
  1541. for ( i = 0; va[i] != NULL; i++ )
  1542. {
  1543. /* Attach the attribute deletion csn on the first value */
  1544. if((entry2str_ctrl & SLAPI_DUMP_STATEINFO) && i==0)
  1545. {
  1546. entry2str_internal_put_value( attrtype, attrcsn, attrcsntype, attr_state, va[i], value_state, ecur, typebuf, typebuf_len, entry2str_ctrl );
  1547. }
  1548. else
  1549. {
  1550. entry2str_internal_put_value( attrtype, NULL, CSN_TYPE_UNKNOWN, attr_state, va[i], value_state, ecur, typebuf, typebuf_len, entry2str_ctrl );
  1551. }
  1552. }
  1553. }
  1554. }
  1555. int
  1556. is_type_protected(const char *type)
  1557. {
  1558. char **paap = NULL;
  1559. for (paap = protected_attrs_all; paap && *paap; paap++) {
  1560. if (0 == strcasecmp(type, *paap)) {
  1561. return 1;
  1562. }
  1563. }
  1564. return 0;
  1565. }
  1566. #if defined(USE_OLD_UNHASHED)
  1567. int
  1568. is_type_forbidden(const char *type)
  1569. {
  1570. char **paap = NULL;
  1571. for (paap = forbidden_attrs; paap && *paap; paap++) {
  1572. if (0 == strcasecmp(type, *paap)) {
  1573. return 1;
  1574. }
  1575. }
  1576. return 0;
  1577. }
  1578. #endif
  1579. static void
  1580. entry2str_internal_put_attrlist( const Slapi_Attr *attrlist, int attr_state, int entry2str_ctrl, char **ecur, char **typebuf, size_t *typebuf_len)
  1581. {
  1582. const Slapi_Attr *a;
  1583. /* Put the present attributes */
  1584. for (a= attrlist; a; a = a->a_next)
  1585. {
  1586. /* skip operational attributes if not requested */
  1587. if ((entry2str_ctrl & SLAPI_DUMP_NOOPATTRS) &&
  1588. slapi_attr_flag_is_set(a, SLAPI_ATTR_FLAG_OPATTR))
  1589. continue;
  1590. /* don't dump uniqueid if not asked */
  1591. if (!(strcasecmp(a->a_type, SLAPI_ATTR_UNIQUEID) == 0 &&
  1592. !(SLAPI_DUMP_UNIQUEID & entry2str_ctrl)) &&
  1593. !is_type_protected(a->a_type))
  1594. {
  1595. /* Putting present attribute values */
  1596. /* put "<type>:[:] <value>" line for each value */
  1597. int present_values= !valueset_isempty(&a->a_present_values);
  1598. if(present_values)
  1599. {
  1600. entry2str_internal_put_valueset(a->a_type, a->a_deletioncsn, CSN_TYPE_ATTRIBUTE_DELETED, attr_state, &a->a_present_values, VALUE_PRESENT, ecur, typebuf, typebuf_len, entry2str_ctrl);
  1601. }
  1602. if(entry2str_ctrl & SLAPI_DUMP_STATEINFO)
  1603. {
  1604. /* Putting deleted attribute values */
  1605. if(present_values)
  1606. {
  1607. entry2str_internal_put_valueset(a->a_type, NULL, CSN_TYPE_NONE, attr_state, &a->a_deleted_values, VALUE_DELETED, ecur, typebuf, typebuf_len, entry2str_ctrl);
  1608. }
  1609. else
  1610. {
  1611. /* There were no present values on which to place the ADCSN, so we put it on the first deleted value. */
  1612. entry2str_internal_put_valueset(a->a_type, a->a_deletioncsn, CSN_TYPE_ATTRIBUTE_DELETED, attr_state, &a->a_deleted_values, VALUE_DELETED, ecur, typebuf, typebuf_len, entry2str_ctrl);
  1613. }
  1614. }
  1615. }
  1616. }
  1617. }
  1618. static char *
  1619. entry2str_internal( Slapi_Entry *e, int *len, int entry2str_ctrl )
  1620. {
  1621. char *ebuf;
  1622. char *ecur;
  1623. size_t elen = 0;
  1624. size_t typebuf_len= 64;
  1625. char *typebuf= (char *)slapi_ch_malloc(typebuf_len);
  1626. Slapi_Value dnvalue;
  1627. /*
  1628. * In string format, an entry looks like this:
  1629. * dn: <dn>\n
  1630. * [<attr>: <value>\n]*
  1631. */
  1632. ecur = ebuf = NULL;
  1633. value_init(&dnvalue,NULL,CSN_TYPE_NONE,NULL);
  1634. /* find length of buffer needed to hold this entry */
  1635. if (slapi_entry_get_dn_const(e)!=NULL)
  1636. {
  1637. slapi_value_set_string(&dnvalue,slapi_entry_get_dn_const(e));
  1638. elen+= entry2str_internal_size_value( "dn", &dnvalue, entry2str_ctrl,
  1639. ATTRIBUTE_PRESENT, VALUE_PRESENT );
  1640. }
  1641. /* Count the space required for the present attributes */
  1642. elen+= entry2str_internal_size_attrlist( e->e_attrs, entry2str_ctrl, ATTRIBUTE_PRESENT );
  1643. /* Count the space required for the deleted attributes */
  1644. if(entry2str_ctrl & SLAPI_DUMP_STATEINFO)
  1645. {
  1646. elen+= entry2str_internal_size_attrlist( e->e_deleted_attrs, entry2str_ctrl,
  1647. ATTRIBUTE_DELETED );
  1648. }
  1649. elen += 1;
  1650. ecur = ebuf = (char *)slapi_ch_malloc(elen);
  1651. /* put the dn */
  1652. if ( slapi_entry_get_dn_const(e)!=NULL)
  1653. {
  1654. /* put "dn: <dn>" */
  1655. entry2str_internal_put_value("dn", NULL, CSN_TYPE_NONE, ATTRIBUTE_PRESENT, &dnvalue, VALUE_PRESENT, &ecur, &typebuf, &typebuf_len, entry2str_ctrl);
  1656. }
  1657. /* Put the present attributes */
  1658. entry2str_internal_put_attrlist( e->e_attrs, ATTRIBUTE_PRESENT, entry2str_ctrl, &ecur, &typebuf, &typebuf_len );
  1659. /* Put the deleted attributes */
  1660. if(entry2str_ctrl & SLAPI_DUMP_STATEINFO)
  1661. {
  1662. entry2str_internal_put_attrlist( e->e_deleted_attrs, ATTRIBUTE_DELETED, entry2str_ctrl, &ecur, &typebuf, &typebuf_len );
  1663. }
  1664. *ecur = '\0';
  1665. if ( (size_t)(ecur - ebuf + 1) > elen )
  1666. {
  1667. slapi_log_error (SLAPI_LOG_FATAL, NULL,
  1668. "entry2str_internal: array boundary wrote: bufsize=%ld wrote=%ld\n",
  1669. elen, (ecur - ebuf + 1));
  1670. }
  1671. if ( NULL != len ) {
  1672. *len = ecur - ebuf;
  1673. }
  1674. slapi_ch_free((void**)&typebuf);
  1675. value_done(&dnvalue);
  1676. return ebuf;
  1677. }
  1678. static char *
  1679. entry2str_internal_ext( Slapi_Entry *e, int *len, int entry2str_ctrl)
  1680. {
  1681. if (entry2str_ctrl & SLAPI_DUMP_RDN_ENTRY) /* dump rdn: ... */
  1682. {
  1683. char *ebuf;
  1684. char *ecur;
  1685. size_t elen = 0;
  1686. size_t typebuf_len = 64;
  1687. char *typebuf = (char *)slapi_ch_malloc(typebuf_len);
  1688. Slapi_Value rdnvalue;
  1689. /*
  1690. * In string format, an entry looks like this:
  1691. * rdn: <normalized rdn>\n
  1692. * [<attr>: <value>\n]*
  1693. */
  1694. ecur = ebuf = NULL;
  1695. value_init(&rdnvalue, NULL, CSN_TYPE_NONE, NULL);
  1696. /* find length of buffer needed to hold this entry */
  1697. if (NULL == slapi_entry_get_rdn_const(e) &&
  1698. NULL != slapi_entry_get_dn_const(e))
  1699. {
  1700. /* e_srdn is not filled in, use e_sdn */
  1701. slapi_rdn_init_all_sdn(&e->e_srdn, slapi_entry_get_sdn_const(e));
  1702. }
  1703. if (NULL != slapi_entry_get_rdn_const(e))
  1704. {
  1705. slapi_value_set_string(&rdnvalue, slapi_entry_get_rdn_const(e));
  1706. elen += entry2str_internal_size_value("rdn", &rdnvalue,
  1707. entry2str_ctrl,
  1708. ATTRIBUTE_PRESENT,
  1709. VALUE_PRESENT);
  1710. }
  1711. /* Count the space required for the present attributes */
  1712. elen += entry2str_internal_size_attrlist(e->e_attrs, entry2str_ctrl,
  1713. ATTRIBUTE_PRESENT);
  1714. /* Count the space required for the deleted attributes */
  1715. if(entry2str_ctrl & SLAPI_DUMP_STATEINFO)
  1716. {
  1717. elen += entry2str_internal_size_attrlist(e->e_deleted_attrs,
  1718. entry2str_ctrl,
  1719. ATTRIBUTE_DELETED);
  1720. }
  1721. elen += 1;
  1722. ecur = ebuf = (char *)slapi_ch_malloc(elen);
  1723. /* put the rdn */
  1724. if (slapi_entry_get_rdn_const(e) != NULL)
  1725. {
  1726. /* put "rdn: <normalized rdn>" */
  1727. entry2str_internal_put_value("rdn", NULL, CSN_TYPE_NONE,
  1728. ATTRIBUTE_PRESENT, &rdnvalue,
  1729. VALUE_PRESENT, &ecur, &typebuf,
  1730. &typebuf_len, entry2str_ctrl);
  1731. }
  1732. /* Put the present attributes */
  1733. entry2str_internal_put_attrlist(e->e_attrs, ATTRIBUTE_PRESENT,
  1734. entry2str_ctrl, &ecur,
  1735. &typebuf, &typebuf_len );
  1736. /* Put the deleted attributes */
  1737. if(entry2str_ctrl & SLAPI_DUMP_STATEINFO)
  1738. {
  1739. entry2str_internal_put_attrlist(e->e_deleted_attrs,
  1740. ATTRIBUTE_DELETED, entry2str_ctrl,
  1741. &ecur, &typebuf, &typebuf_len );
  1742. }
  1743. *ecur = '\0';
  1744. if ((size_t)(ecur - ebuf + 1) > elen)
  1745. {
  1746. /* this should not happen */
  1747. slapi_log_error (SLAPI_LOG_FATAL, NULL,
  1748. "entry2str_internal_ext: array boundary wrote: "
  1749. "bufsize=%ld wrote=%ld\n",
  1750. elen, (ecur - ebuf + 1));
  1751. }
  1752. if ( NULL != len ) {
  1753. *len = ecur - ebuf;
  1754. }
  1755. slapi_ch_free((void**)&typebuf);
  1756. value_done(&rdnvalue);
  1757. return ebuf;
  1758. }
  1759. else /* dump "dn: ..." */
  1760. {
  1761. return entry2str_internal( e, len, entry2str_ctrl );
  1762. }
  1763. }
  1764. /*
  1765. * This function converts an entry to the entry string starting with "dn: ..."
  1766. */
  1767. char *
  1768. slapi_entry2str( Slapi_Entry *e, int *len )
  1769. {
  1770. return entry2str_internal(e, len, 0);
  1771. }
  1772. /*
  1773. * This function converts an entry to the entry string starting with "dn: ..."
  1774. */
  1775. char *
  1776. slapi_entry2str_dump_uniqueid( Slapi_Entry *e, int *len )
  1777. {
  1778. return entry2str_internal(e, len, SLAPI_DUMP_UNIQUEID);
  1779. }
  1780. /*
  1781. * This function converts an entry to the entry string starting with "dn: ..."
  1782. */
  1783. char *
  1784. slapi_entry2str_no_opattrs( Slapi_Entry *e, int *len )
  1785. {
  1786. return entry2str_internal(e, len, SLAPI_DUMP_NOOPATTRS);
  1787. }
  1788. /*
  1789. * This function converts an entry to the entry string starting with "dn: ..."
  1790. * by default. If option includes SLAPI_DUMP_RDN_ENTRY bit, it does the entry
  1791. * to "rdn: ..."
  1792. */
  1793. char *
  1794. slapi_entry2str_with_options( Slapi_Entry *e, int *len, int options )
  1795. {
  1796. return entry2str_internal_ext(e, len, options);
  1797. }
  1798. static int entry_type = -1; /* The type number assigned by the Factory for 'Entry' */
  1799. int
  1800. get_entry_object_type()
  1801. {
  1802. if(entry_type==-1)
  1803. {
  1804. /* The factory is given the name of the object type, in
  1805. * return for a type handle. Whenever the object is created
  1806. * or destroyed the factory is called with the handle so
  1807. * that it may call the constructors or destructors registered
  1808. * with it.
  1809. */
  1810. entry_type= factory_register_type(SLAPI_EXT_ENTRY,offsetof(Slapi_Entry,e_extension));
  1811. }
  1812. return entry_type;
  1813. }
  1814. /* ====== Slapi_Entry functions ====== */
  1815. #ifdef ENTRY_DEBUG
  1816. static void entry_dump( const Slapi_Entry *e, const char *text);
  1817. #define ENTRY_DUMP(e,name) entry_dump(e,name)
  1818. #else
  1819. #define ENTRY_DUMP(e,name) ((void)0)
  1820. #endif
  1821. static int counters_created= 0;
  1822. PR_DEFINE_COUNTER(slapi_entry_counter_created);
  1823. PR_DEFINE_COUNTER(slapi_entry_counter_deleted);
  1824. PR_DEFINE_COUNTER(slapi_entry_counter_exist);
  1825. Slapi_Entry *
  1826. slapi_entry_alloc()
  1827. {
  1828. Slapi_Entry *e= (Slapi_Entry *) slapi_ch_calloc( 1, sizeof(struct slapi_entry) );
  1829. slapi_sdn_init(&e->e_sdn);
  1830. slapi_rdn_init(&e->e_srdn);
  1831. e->e_extension = factory_create_extension(get_entry_object_type(),e,NULL);
  1832. if(!counters_created)
  1833. {
  1834. PR_CREATE_COUNTER(slapi_entry_counter_created,"Slapi_Entry","created","");
  1835. PR_CREATE_COUNTER(slapi_entry_counter_deleted,"Slapi_Entry","deleted","");
  1836. PR_CREATE_COUNTER(slapi_entry_counter_exist,"Slapi_Entry","exist","");
  1837. counters_created= 1;
  1838. }
  1839. PR_INCREMENT_COUNTER(slapi_entry_counter_created);
  1840. PR_INCREMENT_COUNTER(slapi_entry_counter_exist);
  1841. ENTRY_DUMP(e,"slapi_entry_alloc");
  1842. return e;
  1843. }
  1844. /*
  1845. * WARNING - The DN is passed in *not* copied.
  1846. */
  1847. void
  1848. slapi_entry_init(Slapi_Entry *e, char *dn, Slapi_Attr *a)
  1849. {
  1850. slapi_sdn_set_dn_passin(slapi_entry_get_sdn(e), dn);
  1851. e->e_uniqueid= NULL;
  1852. e->e_attrs= a;
  1853. e->e_dncsnset= NULL;
  1854. e->e_maxcsn= NULL;
  1855. e->e_deleted_attrs= NULL;
  1856. e->e_virtual_attrs= NULL;
  1857. e->e_virtual_watermark= 0;
  1858. e->e_virtual_lock= slapi_new_rwlock();
  1859. e->e_flags= 0;
  1860. }
  1861. void
  1862. slapi_entry_init_ext(Slapi_Entry *e, Slapi_DN *sdn, Slapi_Attr *a)
  1863. {
  1864. slapi_sdn_copy(sdn, slapi_entry_get_sdn(e));
  1865. e->e_uniqueid= NULL;
  1866. e->e_attrs= a;
  1867. e->e_dncsnset= NULL;
  1868. e->e_maxcsn= NULL;
  1869. e->e_deleted_attrs= NULL;
  1870. e->e_virtual_attrs= NULL;
  1871. e->e_virtual_watermark= 0;
  1872. e->e_virtual_lock= slapi_new_rwlock();
  1873. e->e_flags= 0;
  1874. }
  1875. void
  1876. slapi_entry_free( Slapi_Entry *e ) /* JCM - Should be ** so that we can NULL the ptr */
  1877. {
  1878. if(e!=NULL)
  1879. {
  1880. ENTRY_DUMP(e,"slapi_entry_free");
  1881. factory_destroy_extension(get_entry_object_type(),e,NULL/*Parent*/,&(e->e_extension));
  1882. slapi_sdn_done(&e->e_sdn);
  1883. slapi_rdn_done(&e->e_srdn);
  1884. csnset_free(&e->e_dncsnset);
  1885. csn_free(&e->e_maxcsn);
  1886. slapi_ch_free((void **)&e->e_uniqueid);
  1887. attrlist_free(e->e_attrs);
  1888. attrlist_free(e->e_deleted_attrs);
  1889. attrlist_free(e->e_virtual_attrs);
  1890. if(e->e_virtual_lock)
  1891. slapi_destroy_rwlock(e->e_virtual_lock);
  1892. slapi_ch_free((void**)&e);
  1893. PR_INCREMENT_COUNTER(slapi_entry_counter_deleted);
  1894. PR_DECREMENT_COUNTER(slapi_entry_counter_exist);
  1895. }
  1896. }
  1897. static size_t slapi_attrlist_size(Slapi_Attr *attrs)
  1898. {
  1899. size_t size = 0;
  1900. Slapi_Attr *a;
  1901. for (a= attrs; a; a = a->a_next) {
  1902. if (a->a_type) size += strlen(a->a_type) + 1;
  1903. size += valueset_size(&a->a_present_values);
  1904. size += valueset_size(&a->a_deleted_values);
  1905. /* Don't bother with a_listtofree. This is only set
  1906. * by a call to slapi_attr_get_values, which should
  1907. * never be used on a cache entry since it can cause
  1908. * the entry to grow without bound.
  1909. */
  1910. if (a->a_deletioncsn) size += sizeof(CSN);
  1911. size += sizeof(Slapi_Attr);
  1912. }
  1913. return size;
  1914. }
  1915. static size_t slapi_dn_size(Slapi_DN *sdn)
  1916. {
  1917. size_t size = 0;
  1918. if (sdn == NULL) return 0;
  1919. if (slapi_sdn_get_dn(sdn)) {
  1920. size += slapi_sdn_get_ndn_len(sdn) + 1;
  1921. }
  1922. if (slapi_sdn_get_ndn(sdn)) {
  1923. size += slapi_sdn_get_ndn_len(sdn) + 1;
  1924. }
  1925. return size;
  1926. }
  1927. /* return the approximate size of an entry --
  1928. * useful for checking cache sizes, etc
  1929. */
  1930. size_t
  1931. slapi_entry_size(Slapi_Entry *e)
  1932. {
  1933. u_long size = 0;
  1934. /* doesn't include memory used by e_extension */
  1935. if (e->e_uniqueid) size += strlen(e->e_uniqueid) + 1;
  1936. if (e->e_dncsnset) size += csnset_size(e->e_dncsnset);
  1937. if (e->e_maxcsn) size += sizeof( CSN );
  1938. size += slapi_dn_size(&e->e_sdn);
  1939. size += slapi_rdn_get_size(&e->e_srdn);
  1940. size += slapi_attrlist_size(e->e_attrs);
  1941. if (e->e_deleted_attrs) size += slapi_attrlist_size(e->e_deleted_attrs);
  1942. if (e->e_virtual_attrs) size += slapi_attrlist_size(e->e_virtual_attrs);
  1943. size += sizeof(Slapi_Entry);
  1944. return size;
  1945. }
  1946. /*
  1947. * return a complete copy of entry pointed to by "e"
  1948. * entry extensions are duplicated, as well.
  1949. */
  1950. Slapi_Entry *
  1951. slapi_entry_dup( const Slapi_Entry *e )
  1952. {
  1953. Slapi_Entry *ec;
  1954. Slapi_Attr *a;
  1955. Slapi_Attr *lastattr= NULL;
  1956. struct attrs_in_extension *aiep;
  1957. PR_ASSERT( NULL != e );
  1958. ec = slapi_entry_alloc();
  1959. /*
  1960. * init the new entry--some things (eg. locks in the entry) are not dup'ed
  1961. */
  1962. slapi_entry_init(ec,NULL,NULL);
  1963. slapi_sdn_copy(slapi_entry_get_sdn_const(e),&ec->e_sdn);
  1964. slapi_srdn_copy(slapi_entry_get_srdn_const(e),&ec->e_srdn);
  1965. /* duplicate the dncsn also */
  1966. ec->e_dncsnset= csnset_dup(e->e_dncsnset);
  1967. ec->e_maxcsn= csn_dup(e->e_maxcsn);
  1968. /* don't use slapi_entry_set_uniqueid here because
  1969. it will cause uniqueid to be added twice to the
  1970. attribute list
  1971. */
  1972. if ( e->e_uniqueid != NULL )
  1973. {
  1974. ec->e_uniqueid = slapi_ch_strdup( e->e_uniqueid ); /* JCM - UniqueID Dup function? */
  1975. }
  1976. for ( a = e->e_attrs; a != NULL; a = a->a_next )
  1977. {
  1978. Slapi_Attr *newattr= slapi_attr_dup(a);
  1979. if(lastattr==NULL)
  1980. {
  1981. ec->e_attrs= newattr;
  1982. }
  1983. else
  1984. {
  1985. lastattr->a_next= newattr;
  1986. }
  1987. lastattr= newattr;
  1988. }
  1989. lastattr= NULL;
  1990. for ( a = e->e_deleted_attrs; a != NULL; a = a->a_next )
  1991. {
  1992. Slapi_Attr *newattr= slapi_attr_dup(a);
  1993. if(lastattr==NULL)
  1994. {
  1995. ec->e_deleted_attrs= newattr;
  1996. }
  1997. else
  1998. {
  1999. lastattr->a_next= newattr;
  2000. }
  2001. lastattr= newattr;
  2002. }
  2003. /* Copy flags as well */
  2004. ec->e_flags = e->e_flags;
  2005. /* Copy extension */
  2006. for (aiep = attrs_in_extension; aiep && aiep->ext_type; aiep++) {
  2007. aiep->ext_copy(e, ec);
  2008. }
  2009. ENTRY_DUMP(ec,"slapi_entry_dup");
  2010. return( ec );
  2011. }
  2012. #ifdef ENTRY_DEBUG
  2013. static void
  2014. entry_dump( const Slapi_Entry *e, const char *text)
  2015. {
  2016. const char *dn= slapi_entry_get_dn_const(e);
  2017. LDAPDebug( LDAP_DEBUG_ANY, "Entry %s ptr=%lx dn=%s\n", text, e, (dn==NULL?"NULL":dn));
  2018. }
  2019. #endif
  2020. char *
  2021. slapi_entry_get_dn( Slapi_Entry *e )
  2022. {
  2023. /* jcm - This is evil... we have to cast away the const. */
  2024. return (char*)(slapi_sdn_get_dn(slapi_entry_get_sdn_const(e)));
  2025. }
  2026. char *
  2027. slapi_entry_get_ndn( Slapi_Entry *e )
  2028. {
  2029. /* jcm - This is evil... we have to cast away the const. */
  2030. return (char*)(slapi_sdn_get_ndn(slapi_entry_get_sdn_const(e)));
  2031. }
  2032. const Slapi_DN *
  2033. slapi_entry_get_sdn_const( const Slapi_Entry *e )
  2034. {
  2035. return &e->e_sdn;
  2036. }
  2037. Slapi_DN *
  2038. slapi_entry_get_sdn( Slapi_Entry *e )
  2039. {
  2040. return &e->e_sdn;
  2041. }
  2042. const Slapi_RDN *
  2043. slapi_entry_get_srdn_const( const Slapi_Entry *e )
  2044. {
  2045. return &e->e_srdn;
  2046. }
  2047. Slapi_RDN *
  2048. slapi_entry_get_srdn( Slapi_Entry *e )
  2049. {
  2050. return &e->e_srdn;
  2051. }
  2052. const char *
  2053. slapi_entry_get_dn_const( const Slapi_Entry *e )
  2054. {
  2055. return (slapi_sdn_get_dn(slapi_entry_get_sdn_const(e)));
  2056. }
  2057. const char *
  2058. slapi_entry_get_rdn_const( const Slapi_Entry *e )
  2059. {
  2060. return (slapi_rdn_get_rdn(slapi_entry_get_srdn_const(e)));
  2061. }
  2062. /* slapi_rdn_get_nrdn could modify srdn in it. So, it cannot take const. */
  2063. const char *
  2064. slapi_entry_get_nrdn_const( const Slapi_Entry *e )
  2065. {
  2066. const char *nrdn =
  2067. slapi_rdn_get_nrdn(slapi_entry_get_srdn((Slapi_Entry *)e));
  2068. if (NULL == nrdn) {
  2069. const char *dn = slapi_entry_get_dn_const(e);
  2070. if (dn) {
  2071. /* cast away const */
  2072. slapi_rdn_init_all_dn((Slapi_RDN *)&e->e_srdn, dn);
  2073. nrdn = slapi_rdn_get_nrdn(slapi_entry_get_srdn((Slapi_Entry *)e));
  2074. }
  2075. }
  2076. return nrdn;
  2077. }
  2078. /*
  2079. * WARNING - The DN is passed in *not* copied.
  2080. */
  2081. void
  2082. slapi_entry_set_dn( Slapi_Entry *e, char *dn )
  2083. {
  2084. slapi_sdn_set_dn_passin(slapi_entry_get_sdn(e),dn);
  2085. }
  2086. void
  2087. slapi_entry_set_normdn( Slapi_Entry *e, char *dn )
  2088. {
  2089. slapi_sdn_set_normdn_passin(slapi_entry_get_sdn(e), dn);
  2090. }
  2091. /*
  2092. * WARNING - The DN is copied.
  2093. * The DN could be dn or RDN.
  2094. */
  2095. void
  2096. slapi_entry_set_rdn( Slapi_Entry *e, char *dn )
  2097. {
  2098. slapi_rdn_set_all_dn(slapi_entry_get_srdn(e),dn);
  2099. }
  2100. void
  2101. slapi_entry_set_sdn( Slapi_Entry *e, const Slapi_DN *sdn )
  2102. {
  2103. slapi_sdn_copy(sdn,slapi_entry_get_sdn(e));
  2104. }
  2105. void
  2106. slapi_entry_set_srdn( Slapi_Entry *e, const Slapi_RDN *srdn )
  2107. {
  2108. slapi_srdn_copy(srdn, slapi_entry_get_srdn(e));
  2109. }
  2110. const char *
  2111. slapi_entry_get_uniqueid( const Slapi_Entry *e )
  2112. {
  2113. return( e->e_uniqueid );
  2114. }
  2115. /*
  2116. * WARNING - The UniqueID is passed in *not* copied.
  2117. */
  2118. void
  2119. slapi_entry_set_uniqueid( Slapi_Entry *e, char *uniqueid )
  2120. {
  2121. e->e_uniqueid = uniqueid;
  2122. /* also add it to the list of attributes - it makes things easier */
  2123. slapi_entry_attr_set_charptr ( e, SLAPI_ATTR_UNIQUEID, uniqueid );
  2124. }
  2125. int
  2126. slapi_entry_first_attr( const Slapi_Entry *e, Slapi_Attr **a )
  2127. {
  2128. return slapi_entry_next_attr( e, NULL, a);
  2129. }
  2130. int
  2131. slapi_entry_next_attr( const Slapi_Entry *e, Slapi_Attr *prevattr, Slapi_Attr **a )
  2132. {
  2133. int done= 0;
  2134. /*
  2135. * We skip over any attributes that have no present values.
  2136. * Our state information storage scheme can cause this, since
  2137. * we have to hang onto the deleted value state information.
  2138. * <jcm - actually we don't do this any more... so this skipping
  2139. * may now be redundant.>
  2140. */
  2141. while(!done)
  2142. {
  2143. if(prevattr==NULL)
  2144. {
  2145. *a = e->e_attrs;
  2146. }
  2147. else
  2148. {
  2149. *a = prevattr->a_next;
  2150. }
  2151. if(*a!=NULL)
  2152. {
  2153. done= !valueset_isempty(&((*a)->a_present_values));
  2154. }
  2155. else
  2156. {
  2157. done= 1;
  2158. }
  2159. if(!done)
  2160. {
  2161. prevattr= *a;
  2162. }
  2163. }
  2164. return( *a ? 0 : -1 );
  2165. }
  2166. int
  2167. slapi_entry_attr_find( const Slapi_Entry *e, const char *type, Slapi_Attr **a )
  2168. {
  2169. int r = -1;
  2170. if(e == NULL){
  2171. return r;
  2172. }
  2173. *a = attrlist_find( e->e_attrs, type );
  2174. if (*a != NULL)
  2175. {
  2176. if(valueset_isempty(&((*a)->a_present_values)))
  2177. {
  2178. /*
  2179. * We ignore attributes that have no present values.
  2180. * Our state information storage scheme can cause this, since
  2181. * we have to hang onto the deleted value state information.
  2182. */
  2183. *a = NULL;
  2184. }
  2185. else
  2186. {
  2187. r = 0;
  2188. }
  2189. }
  2190. return r;
  2191. }
  2192. /* the following functions control virtual attribute cache invalidation */
  2193. static PRInt32 g_virtual_watermark = -1; /* good enough to init */
  2194. int slapi_entry_vattrcache_watermark_isvalid(const Slapi_Entry *e)
  2195. {
  2196. return e->e_virtual_watermark == g_virtual_watermark;
  2197. }
  2198. void slapi_entry_vattrcache_watermark_set(Slapi_Entry *e)
  2199. {
  2200. e->e_virtual_watermark = g_virtual_watermark;
  2201. }
  2202. void slapi_entry_vattrcache_watermark_invalidate(Slapi_Entry *e)
  2203. {
  2204. e->e_virtual_watermark = 0;
  2205. }
  2206. void slapi_entrycache_vattrcache_watermark_invalidate()
  2207. {
  2208. PR_AtomicIncrement(&g_virtual_watermark);
  2209. if (g_virtual_watermark == 0) {
  2210. PR_AtomicIncrement(&g_virtual_watermark);
  2211. }
  2212. }
  2213. /*
  2214. * slapi_entry_vattrcache_findAndTest()
  2215. *
  2216. * returns:
  2217. * SLAPI_ENTRY_VATTR_NOT_RESOLVED--not found in vattrcache; *rc set to -1.
  2218. * SLAPI_ENTRY_VATTR_RESOLVED_ABSENT--present in vattrcache but empty value:
  2219. * means tjhat vattr type is not present in
  2220. * that entry.
  2221. * SLAPI_ENTRY_VATTR_RESOLVED_EXISTS--found vattr in the cache, in which
  2222. * case *rc contains the result of testing
  2223. * the filter f of type filter_type
  2224. * on the value of type in e.
  2225. * rc==-1=>not a filter match
  2226. * rc==0=>a filter match
  2227. * rc>0=>an LDAP error code.
  2228. */
  2229. int
  2230. slapi_entry_vattrcache_findAndTest( const Slapi_Entry *e, const char *type,
  2231. Slapi_Filter *f,
  2232. filter_type_t filter_type,
  2233. int *rc )
  2234. {
  2235. Slapi_Attr *tmp_attr = NULL;
  2236. int r= SLAPI_ENTRY_VATTR_NOT_RESOLVED; /* assume not resolved yet */
  2237. *rc = -1;
  2238. if( slapi_vattrcache_iscacheable(type) &&
  2239. slapi_entry_vattrcache_watermark_isvalid(e) ) {
  2240. if(e->e_virtual_lock == NULL) {
  2241. return r;
  2242. }
  2243. vattrcache_entry_READ_LOCK(e);
  2244. if (e->e_virtual_attrs) {
  2245. tmp_attr = attrlist_find( e->e_virtual_attrs, type );
  2246. if (tmp_attr != NULL) {
  2247. if(valueset_isempty(&(tmp_attr->a_present_values))) {
  2248. /*
  2249. * this is a vattr that has been
  2250. * cached already but does not exist
  2251. */
  2252. /* hard coded for prototype */
  2253. r= SLAPI_ENTRY_VATTR_RESOLVED_ABSENT;
  2254. } else {
  2255. /*
  2256. * this is a cached vattr--test the filter on it.
  2257. */
  2258. r= SLAPI_ENTRY_VATTR_RESOLVED_EXISTS;
  2259. if ( filter_type == FILTER_TYPE_AVA ) {
  2260. *rc = plugin_call_syntax_filter_ava(tmp_attr,
  2261. f->f_choice,
  2262. &f->f_ava);
  2263. } else if ( filter_type == FILTER_TYPE_SUBSTRING) {
  2264. *rc = plugin_call_syntax_filter_sub(NULL, tmp_attr,
  2265. &f->f_sub);
  2266. } else if ( filter_type == FILTER_TYPE_PRES ) {
  2267. /* type is there, that's all we need to know. */
  2268. *rc = 0;
  2269. }
  2270. }
  2271. }
  2272. } else {
  2273. r= SLAPI_ENTRY_VATTR_RESOLVED_ABSENT;
  2274. }
  2275. vattrcache_entry_READ_UNLOCK(e);
  2276. }
  2277. return r;
  2278. }
  2279. /*
  2280. * slapi_entry_vattrcache_find_values_and_type_ex()
  2281. *
  2282. * returns:
  2283. * SLAPI_ENTRY_VATTR_NOT_RESOLVED--not found in vattrcache.
  2284. * SLAPI_ENTRY_VATTR_RESOLVED_ABSENT--found in vattrcache but empty value
  2285. * ==>that vattr type is not present in the
  2286. * entry.
  2287. * SLAPI_ENTRY_VATTR_RESOLVED_EXISTS--found vattr in the vattr cache,
  2288. * in which case **results is a
  2289. * pointer to a duped Slapi_Valueset
  2290. * containing the values of type and
  2291. * **actual_type_name is the actual type
  2292. * name.
  2293. */
  2294. int
  2295. slapi_entry_vattrcache_find_values_and_type_ex( const Slapi_Entry *e,
  2296. const char *type,
  2297. Slapi_ValueSet ***results,
  2298. char ***actual_type_name)
  2299. {
  2300. Slapi_Attr *tmp_attr = NULL;
  2301. int r= SLAPI_ENTRY_VATTR_NOT_RESOLVED; /* assume not resolved yet */
  2302. if( slapi_vattrcache_iscacheable(type) &&
  2303. slapi_entry_vattrcache_watermark_isvalid(e) && e->e_virtual_attrs)
  2304. {
  2305. if(e->e_virtual_lock == NULL) {
  2306. return r;
  2307. }
  2308. vattrcache_entry_READ_LOCK(e);
  2309. tmp_attr = attrlist_find( e->e_virtual_attrs, type );
  2310. if (tmp_attr != NULL)
  2311. {
  2312. if(valueset_isempty(&(tmp_attr->a_present_values)))
  2313. {
  2314. /*
  2315. * this is a vattr that has been
  2316. * cached already but does not exist
  2317. */
  2318. r= SLAPI_ENTRY_VATTR_RESOLVED_ABSENT; /* hard coded for prototype */
  2319. }
  2320. else
  2321. {
  2322. /*
  2323. * this is a cached vattr
  2324. * return a duped copy of the values and type
  2325. */
  2326. char *vattr_type=NULL;
  2327. r= SLAPI_ENTRY_VATTR_RESOLVED_EXISTS;
  2328. *results = (Slapi_ValueSet**)slapi_ch_calloc(1, sizeof(**results));
  2329. **results = valueset_dup(&(tmp_attr->a_present_values));
  2330. *actual_type_name =
  2331. (char**)slapi_ch_malloc(sizeof(**actual_type_name));
  2332. slapi_attr_get_type( tmp_attr, &vattr_type );
  2333. **actual_type_name = slapi_ch_strdup(vattr_type);
  2334. }
  2335. }
  2336. vattrcache_entry_READ_UNLOCK(e);
  2337. }
  2338. return r;
  2339. }
  2340. /*
  2341. * Deprecated in favour of slapi_entry_vattrcache_find_values_and_type_ex()
  2342. * which meshes better with slapi_vattr_values_get_sp_ex().
  2343. */
  2344. SLAPI_DEPRECATED int
  2345. slapi_entry_vattrcache_find_values_and_type( const Slapi_Entry *e,
  2346. const char *type,
  2347. Slapi_ValueSet **results,
  2348. char **actual_type_name)
  2349. {
  2350. Slapi_Attr *tmp_attr = NULL;
  2351. int r= SLAPI_ENTRY_VATTR_NOT_RESOLVED; /* assume not resolved yet */
  2352. if( slapi_vattrcache_iscacheable(type) &&
  2353. slapi_entry_vattrcache_watermark_isvalid(e) && e->e_virtual_attrs)
  2354. {
  2355. if(e->e_virtual_lock == NULL) {
  2356. return r;
  2357. }
  2358. vattrcache_entry_READ_LOCK(e);
  2359. tmp_attr = attrlist_find( e->e_virtual_attrs, type );
  2360. if (tmp_attr != NULL)
  2361. {
  2362. if(valueset_isempty(&(tmp_attr->a_present_values)))
  2363. {
  2364. /*
  2365. * this is a vattr that has been
  2366. * cached already but does not exist
  2367. */
  2368. r= SLAPI_ENTRY_VATTR_RESOLVED_ABSENT; /* hard coded for prototype */
  2369. }
  2370. else
  2371. {
  2372. /*
  2373. * this is a cached vattr
  2374. * return a duped copy of the values and type
  2375. */
  2376. char *vattr_type=NULL;
  2377. r= SLAPI_ENTRY_VATTR_RESOLVED_EXISTS;
  2378. *results = valueset_dup(&(tmp_attr->a_present_values));
  2379. slapi_attr_get_type( tmp_attr, &vattr_type );
  2380. *actual_type_name = slapi_ch_strdup(vattr_type);
  2381. }
  2382. }
  2383. vattrcache_entry_READ_UNLOCK(e);
  2384. }
  2385. return r;
  2386. }
  2387. SLAPI_DEPRECATED int
  2388. slapi_entry_attr_merge( Slapi_Entry *e, const char *type, struct berval **vals )
  2389. {
  2390. Slapi_Value **values= NULL;
  2391. int rc=0;
  2392. valuearray_init_bervalarray(vals,&values); /* JCM SLOW FUNCTION */
  2393. rc = slapi_entry_attr_merge_sv(e, type, values);
  2394. valuearray_free(&values);
  2395. return(rc);
  2396. }
  2397. int
  2398. slapi_entry_attr_merge_sv(Slapi_Entry *e, const char *type, Slapi_Value **vals )
  2399. {
  2400. attrlist_merge_valuearray( &e->e_attrs, type, vals );
  2401. return 0;
  2402. }
  2403. /*
  2404. * Merge this valuset for type into e's vattrcache list.
  2405. * Creates the type if necessary.
  2406. * Dups valset.
  2407. * Only merge's in cacheable vattrs.
  2408. */
  2409. int
  2410. slapi_entry_vattrcache_merge_sv(Slapi_Entry *e, const char *type,
  2411. Slapi_ValueSet *valset)
  2412. {
  2413. Slapi_Value **vals = NULL;
  2414. /* only attempt to merge if it's a cacheable attribute */
  2415. if ( slapi_vattrcache_iscacheable(type) ) {
  2416. if(e->e_virtual_lock == NULL) {
  2417. return 0;
  2418. }
  2419. vattrcache_entry_WRITE_LOCK(e);
  2420. if(!slapi_entry_vattrcache_watermark_isvalid(e) && e->e_virtual_attrs)
  2421. {
  2422. attrlist_free(e->e_virtual_attrs);
  2423. e->e_virtual_attrs = NULL;
  2424. }
  2425. if(valset)
  2426. vals = valueset_get_valuearray(valset);
  2427. /* dups the type (if necessary) and vals */
  2428. attrlist_merge_valuearray( &e->e_virtual_attrs, type, vals);
  2429. slapi_entry_vattrcache_watermark_set(e);
  2430. vattrcache_entry_WRITE_UNLOCK(e);
  2431. }
  2432. return 0;
  2433. }
  2434. int
  2435. slapi_entry_attr_delete( Slapi_Entry *e, const char *type )
  2436. {
  2437. return( attrlist_delete(&e->e_attrs, type) );
  2438. }
  2439. SLAPI_DEPRECATED int
  2440. slapi_entry_attr_replace( Slapi_Entry *e, const char *type, struct berval **vals )
  2441. {
  2442. slapi_entry_attr_delete(e, type);
  2443. slapi_entry_attr_merge(e, type, vals);
  2444. return 0;
  2445. }
  2446. int
  2447. slapi_entry_attr_replace_sv( Slapi_Entry *e, const char *type, Slapi_Value **vals )
  2448. {
  2449. slapi_entry_attr_delete(e, type);
  2450. slapi_entry_attr_merge_sv(e, type, vals);
  2451. return 0;
  2452. }
  2453. int
  2454. slapi_entry_add_value (Slapi_Entry *e, const char *type, const Slapi_Value *value)
  2455. {
  2456. Slapi_Attr **a= NULL;
  2457. attrlist_find_or_create(&e->e_attrs, type, &a);
  2458. if(value != (Slapi_Value *) NULL) {
  2459. slapi_valueset_add_value ( &(*a)->a_present_values, value);
  2460. }
  2461. return 0;
  2462. }
  2463. int
  2464. slapi_entry_add_string(Slapi_Entry *e, const char *type, const char *value)
  2465. {
  2466. Slapi_Attr **a= NULL;
  2467. attrlist_find_or_create(&e->e_attrs, type, &a);
  2468. valueset_add_string ( &(*a)->a_present_values, value, CSN_TYPE_UNKNOWN, NULL);
  2469. return 0;
  2470. }
  2471. int
  2472. slapi_entry_delete_string(Slapi_Entry *e, const char *type, const char *value)
  2473. {
  2474. Slapi_Attr *a= attrlist_find(e->e_attrs, type);
  2475. if (a != NULL)
  2476. valueset_remove_string(a,&a->a_present_values, value);
  2477. return 0;
  2478. }
  2479. /* caller must free with slapi_ch_array_free */
  2480. char **
  2481. slapi_entry_attr_get_charray( const Slapi_Entry* e, const char *type)
  2482. {
  2483. int ignore;
  2484. return slapi_entry_attr_get_charray_ext(e, type, &ignore);
  2485. }
  2486. /*
  2487. * The extension also gathers the number of values.
  2488. * The caller must free with slapi_ch_array_free
  2489. */
  2490. char **
  2491. slapi_entry_attr_get_charray_ext( const Slapi_Entry* e, const char *type, int *numVals)
  2492. {
  2493. char **parray = NULL;
  2494. Slapi_Attr* attr = NULL;
  2495. slapi_entry_attr_find(e, type, &attr);
  2496. int count = 0;
  2497. if(numVals == NULL){
  2498. return NULL;
  2499. }
  2500. if(attr!=NULL){
  2501. int hint;
  2502. Slapi_Value *v = NULL;
  2503. for (hint = slapi_attr_first_value(attr, &v);
  2504. hint != -1;
  2505. hint = slapi_attr_next_value(attr, hint, &v))
  2506. {
  2507. const struct berval *bvp = slapi_value_get_berval(v);
  2508. char *p = slapi_ch_malloc(bvp->bv_len + 1);
  2509. memcpy(p, bvp->bv_val, bvp->bv_len);
  2510. p[bvp->bv_len]= '\0';
  2511. charray_add(&parray, p);
  2512. count++;
  2513. }
  2514. }
  2515. *numVals = count;
  2516. return parray;
  2517. }
  2518. char *
  2519. slapi_entry_attr_get_charptr( const Slapi_Entry* e, const char *type)
  2520. {
  2521. char *p= NULL;
  2522. Slapi_Attr* attr;
  2523. slapi_entry_attr_find(e, type, &attr);
  2524. if(attr!=NULL)
  2525. {
  2526. Slapi_Value *v;
  2527. const struct berval *bvp;
  2528. slapi_valueset_first_value( &attr->a_present_values, &v);
  2529. bvp = slapi_value_get_berval(v);
  2530. p= slapi_ch_malloc(bvp->bv_len + 1);
  2531. memcpy(p, bvp->bv_val, bvp->bv_len);
  2532. p[bvp->bv_len]= '\0';
  2533. }
  2534. return p;
  2535. }
  2536. int
  2537. slapi_entry_attr_get_int( const Slapi_Entry* e, const char *type)
  2538. {
  2539. int r= 0;
  2540. Slapi_Attr* attr;
  2541. slapi_entry_attr_find(e, type, &attr);
  2542. if (attr!=NULL)
  2543. {
  2544. Slapi_Value *v;
  2545. slapi_valueset_first_value( &attr->a_present_values, &v);
  2546. r= slapi_value_get_int(v);
  2547. }
  2548. return r;
  2549. }
  2550. unsigned int
  2551. slapi_entry_attr_get_uint( const Slapi_Entry* e, const char *type)
  2552. {
  2553. unsigned int r= 0;
  2554. Slapi_Attr* attr;
  2555. slapi_entry_attr_find(e, type, &attr);
  2556. if (attr!=NULL)
  2557. {
  2558. Slapi_Value *v;
  2559. slapi_valueset_first_value( &attr->a_present_values, &v);
  2560. r= slapi_value_get_uint(v);
  2561. }
  2562. return r;
  2563. }
  2564. long
  2565. slapi_entry_attr_get_long( const Slapi_Entry* e, const char *type)
  2566. {
  2567. long r = 0;
  2568. Slapi_Attr* attr;
  2569. slapi_entry_attr_find(e, type, &attr);
  2570. if (attr!=NULL)
  2571. {
  2572. Slapi_Value *v;
  2573. slapi_valueset_first_value( &attr->a_present_values, &v);
  2574. r = slapi_value_get_long(v);
  2575. }
  2576. return r;
  2577. }
  2578. unsigned long
  2579. slapi_entry_attr_get_ulong( const Slapi_Entry* e, const char *type)
  2580. {
  2581. unsigned long r = 0;
  2582. Slapi_Attr* attr;
  2583. slapi_entry_attr_find(e, type, &attr);
  2584. if (attr!=NULL)
  2585. {
  2586. Slapi_Value *v;
  2587. slapi_valueset_first_value( &attr->a_present_values, &v);
  2588. r = slapi_value_get_ulong(v);
  2589. }
  2590. return r;
  2591. }
  2592. long long
  2593. slapi_entry_attr_get_longlong( const Slapi_Entry* e, const char *type)
  2594. {
  2595. long long r = 0;
  2596. Slapi_Attr* attr;
  2597. slapi_entry_attr_find(e, type, &attr);
  2598. if (attr!=NULL)
  2599. {
  2600. Slapi_Value *v;
  2601. slapi_valueset_first_value( &attr->a_present_values, &v);
  2602. r = slapi_value_get_longlong(v);
  2603. }
  2604. return r;
  2605. }
  2606. unsigned long long
  2607. slapi_entry_attr_get_ulonglong( const Slapi_Entry* e, const char *type)
  2608. {
  2609. unsigned long long r = 0;
  2610. Slapi_Attr* attr;
  2611. slapi_entry_attr_find(e, type, &attr);
  2612. if (attr!=NULL)
  2613. {
  2614. Slapi_Value *v;
  2615. slapi_valueset_first_value( &attr->a_present_values, &v);
  2616. r = slapi_value_get_ulonglong(v);
  2617. }
  2618. return r;
  2619. }
  2620. PRBool
  2621. slapi_entry_attr_get_bool( const Slapi_Entry* e, const char *type)
  2622. {
  2623. PRBool r = PR_FALSE; /* default if no attr */
  2624. Slapi_Attr* attr;
  2625. slapi_entry_attr_find(e, type, &attr);
  2626. if (attr!=NULL)
  2627. {
  2628. Slapi_Value *v;
  2629. const struct berval *bvp;
  2630. slapi_valueset_first_value( &attr->a_present_values, &v);
  2631. bvp = slapi_value_get_berval(v);
  2632. if ((bvp == NULL) || (bvp->bv_len == 0)) { /* none or empty == false */
  2633. r = PR_FALSE;
  2634. } else if (!PL_strncasecmp(bvp->bv_val, "on", bvp->bv_len)) {
  2635. r = PR_TRUE;
  2636. } else if (!PL_strncasecmp(bvp->bv_val, "off", bvp->bv_len)) {
  2637. r = PR_FALSE;
  2638. } else if (!PL_strncasecmp(bvp->bv_val, "true", bvp->bv_len)) {
  2639. r = PR_TRUE;
  2640. } else if (!PL_strncasecmp(bvp->bv_val, "false", bvp->bv_len)) {
  2641. r = PR_FALSE;
  2642. } else if (!PL_strncasecmp(bvp->bv_val, "yes", bvp->bv_len)) {
  2643. r = PR_TRUE;
  2644. } else if (!PL_strncasecmp(bvp->bv_val, "no", bvp->bv_len)) {
  2645. r = PR_FALSE;
  2646. } else { /* assume numeric: 0 - false: non-zero - true */
  2647. r = (PRBool)slapi_value_get_ulong(v);
  2648. }
  2649. }
  2650. return r;
  2651. }
  2652. void
  2653. slapi_entry_attr_set_charptr( Slapi_Entry* e, const char *type, const char *value)
  2654. {
  2655. struct berval bv;
  2656. struct berval *bvals[2];
  2657. if (value) {
  2658. bvals[0] = &bv;
  2659. bvals[1] = NULL;
  2660. bv.bv_val = (char*)value;
  2661. bv.bv_len = strlen( value );
  2662. slapi_entry_attr_replace( e, type, bvals );
  2663. } else {
  2664. slapi_entry_attr_delete( e, type );
  2665. }
  2666. }
  2667. void
  2668. slapi_entry_attr_set_int( Slapi_Entry* e, const char *type, int l)
  2669. {
  2670. char value[16];
  2671. struct berval bv;
  2672. struct berval *bvals[2];
  2673. bvals[0] = &bv;
  2674. bvals[1] = NULL;
  2675. sprintf(value,"%d",l);
  2676. bv.bv_val = value;
  2677. bv.bv_len = strlen( value );
  2678. slapi_entry_attr_replace( e, type, bvals );
  2679. }
  2680. void
  2681. slapi_entry_attr_set_uint( Slapi_Entry* e, const char *type, unsigned int l)
  2682. {
  2683. char value[16];
  2684. struct berval bv;
  2685. struct berval *bvals[2];
  2686. bvals[0] = &bv;
  2687. bvals[1] = NULL;
  2688. sprintf(value,"%u",l);
  2689. bv.bv_val = value;
  2690. bv.bv_len = strlen( value );
  2691. slapi_entry_attr_replace( e, type, bvals );
  2692. }
  2693. void
  2694. slapi_entry_attr_set_long( Slapi_Entry* e, const char *type, long l)
  2695. {
  2696. char value[16];
  2697. struct berval bv;
  2698. struct berval *bvals[2];
  2699. bvals[0] = &bv;
  2700. bvals[1] = NULL;
  2701. sprintf(value,"%ld",l);
  2702. bv.bv_val = value;
  2703. bv.bv_len = strlen( value );
  2704. slapi_entry_attr_replace( e, type, bvals );
  2705. }
  2706. void
  2707. slapi_entry_attr_set_ulong( Slapi_Entry* e, const char *type, unsigned long l)
  2708. {
  2709. char value[16];
  2710. struct berval bv;
  2711. struct berval *bvals[2];
  2712. bvals[0] = &bv;
  2713. bvals[1] = NULL;
  2714. sprintf(value,"%lu",l);
  2715. bv.bv_val = value;
  2716. bv.bv_len = strlen( value );
  2717. slapi_entry_attr_replace( e, type, bvals );
  2718. }
  2719. /* JCM: The strcasecmp below should really be a bervalcmp
  2720. * deprecatred in favour of slapi_entry_attr_has_syntax_value
  2721. * which does respect the syntax of the attribute type.
  2722. */
  2723. SLAPI_DEPRECATED int
  2724. slapi_entry_attr_hasvalue(const Slapi_Entry *e, const char *type, const char *value) /* JCM - (const char *) => (struct berval *) */
  2725. {
  2726. int r= 0;
  2727. Slapi_Attr *attr;
  2728. Slapi_Value *sval;
  2729. if(slapi_entry_attr_find(e, type, &attr)==0)
  2730. {
  2731. int i= slapi_attr_first_value( attr, &sval );
  2732. while(!r && i!=-1)
  2733. {
  2734. const struct berval *val= slapi_value_get_berval(sval);
  2735. r= (strcasecmp(val->bv_val,value)==0);
  2736. i= slapi_attr_next_value( attr, i, &sval );
  2737. }
  2738. }
  2739. return r;
  2740. }
  2741. /*
  2742. * Checks if e contains an attr type with a value
  2743. * of value.
  2744. * Unlike slapi_entry_attr_hasvalue(), it does teh comparison
  2745. * respecting the syntax of type.
  2746. *
  2747. * returns non-zero if type has value in e, zero otherwise.
  2748. *
  2749. *
  2750. */
  2751. int
  2752. slapi_entry_attr_has_syntax_value(const Slapi_Entry *e,
  2753. const char *type,
  2754. const Slapi_Value *value)
  2755. {
  2756. int r = 0;
  2757. Slapi_Attr *attr;
  2758. if(e == NULL){
  2759. return r;
  2760. }
  2761. if(slapi_entry_attr_find(e, type, &attr)==0)
  2762. {
  2763. const struct berval *bv = slapi_value_get_berval(value);
  2764. if ( bv != NULL) {
  2765. r = (slapi_attr_value_find(attr, bv) == 0);
  2766. }
  2767. }
  2768. return r;
  2769. }
  2770. int
  2771. slapi_entry_rdn_values_present( const Slapi_Entry *e )
  2772. {
  2773. char **dns, **rdns;
  2774. int i, rc;
  2775. Slapi_Attr *attr;
  2776. struct ava ava;
  2777. const char *dn = slapi_entry_get_dn_const(e);
  2778. if (slapi_is_rootdse(dn))
  2779. return 1; /* the root dse has no RDN, so it should default to TRUE */
  2780. /* JCM Use the Slapi_RDN code */
  2781. rc = 1;
  2782. if ( (dns = slapi_ldap_explode_dn( slapi_entry_get_dn_const(e), 0 )) != NULL )
  2783. {
  2784. if ( (rdns = slapi_ldap_explode_rdn( dns[0], 0 )) != NULL )
  2785. {
  2786. for ( i = 0; rdns[i] != NULL; i++ )
  2787. {
  2788. if ( rdn2ava( rdns[i], &ava ) == 0 )
  2789. {
  2790. char *type = slapi_attr_syntax_normalize( ava.ava_type );
  2791. if ( slapi_entry_attr_find( e, type, &attr ) != 0 )
  2792. {
  2793. rc = 0;
  2794. }
  2795. slapi_ch_free((void **)&type);
  2796. if ( 0 == rc ) { /* attribute not found */
  2797. break;
  2798. }
  2799. if ( slapi_attr_value_find( attr, &(ava.ava_value) ) != 0 )
  2800. {
  2801. rc = 0;
  2802. break; /* value not found */
  2803. }
  2804. }
  2805. }
  2806. slapi_ldap_value_free( rdns );
  2807. } else {
  2808. rc = 0; /* Failure: the RDN seems invalid */
  2809. }
  2810. slapi_ldap_value_free( dns );
  2811. }
  2812. else
  2813. {
  2814. rc = 0; /* failure: the RDN seems to be invalid */
  2815. }
  2816. return( rc );
  2817. }
  2818. int
  2819. slapi_entry_add_rdn_values( Slapi_Entry *e )
  2820. {
  2821. const char *dn;
  2822. char **dns, **rdns;
  2823. const Slapi_DN *sdn;
  2824. int i, rc = LDAP_SUCCESS;
  2825. Slapi_Value *foundVal;
  2826. Slapi_Attr *attr;
  2827. if (NULL == e || NULL == (sdn = slapi_entry_get_sdn_const(e))) {
  2828. return( LDAP_SUCCESS );
  2829. }
  2830. /* Preserve the original in case the RDN is missing as an attr-val pair
  2831. * in the entry. */
  2832. dn = slapi_sdn_get_udn(sdn);
  2833. if (slapi_is_rootdse(dn)) {
  2834. return( LDAP_SUCCESS );
  2835. }
  2836. /* JCM Use the Slapi_RDN code */
  2837. /* make sure RDN values are also in the entry */
  2838. if ( (dns = slapi_ldap_explode_dn( dn, 0 )) == NULL ) {
  2839. return( LDAP_INVALID_DN_SYNTAX );
  2840. }
  2841. if ( (rdns = slapi_ldap_explode_rdn( dns[0], 0 )) == NULL ) {
  2842. slapi_ldap_value_free( dns );
  2843. return( LDAP_INVALID_DN_SYNTAX );
  2844. }
  2845. slapi_ldap_value_free( dns );
  2846. for ( i = 0; rdns[i] != NULL && rc == LDAP_SUCCESS; i++ ) {
  2847. struct ava ava;
  2848. char *type;
  2849. if ( rdn2ava( rdns[i], &ava ) != 0 ) {
  2850. slapi_ldap_value_free( rdns );
  2851. return( LDAP_INVALID_DN_SYNTAX );
  2852. }
  2853. foundVal = NULL;
  2854. type = slapi_attr_syntax_normalize( ava.ava_type );
  2855. if ( slapi_entry_attr_find( e, type, &attr ) == 0 ) {
  2856. rc = plugin_call_syntax_filter_ava_sv(attr, LDAP_FILTER_EQUALITY,
  2857. &ava, &foundVal, 0);
  2858. if (rc == 0 && foundVal != NULL) {
  2859. const struct berval *bv = slapi_value_get_berval(foundVal);
  2860. /*
  2861. * A subtlety to consider is that LDAP does not
  2862. * allow two values which compare the same for
  2863. * equality in an attribute at once.
  2864. */
  2865. if ((ava.ava_value.bv_len != bv->bv_len) ||
  2866. (memcmp(ava.ava_value.bv_val, bv->bv_val, bv->bv_len) != 0)) {
  2867. /* bytes not identical so reject */
  2868. LDAPDebug(LDAP_DEBUG_TRACE, "RDN value is not identical to entry value for type %s in entry %s\n",
  2869. type, dn ? dn : "<null>", 0 );
  2870. #if 0
  2871. /*
  2872. * This would be the right thing to do except that
  2873. * it breaks our own clients.
  2874. */
  2875. rc = LDAP_TYPE_OR_VALUE_EXISTS;
  2876. #endif
  2877. }
  2878. /* exact same ava already present in entry, that's OK */
  2879. }
  2880. }
  2881. if (foundVal == NULL) {
  2882. struct berval *vals[2];
  2883. vals[0] = &ava.ava_value;
  2884. vals[1] = NULL;
  2885. rc = slapi_entry_add_values( e, type, vals );
  2886. }
  2887. slapi_ch_free( (void **)&type );
  2888. }
  2889. slapi_ldap_value_free( rdns );
  2890. return( rc );
  2891. }
  2892. /*
  2893. * Function: slapi_entry_has_children
  2894. *
  2895. * Returns: 0 if "p" has no children, 1 if "p" has children.
  2896. *
  2897. * Description: We (RJP+DB) modified this code to take advantage
  2898. * of the subordinatecount operational attribute that
  2899. * each entry now has.
  2900. *
  2901. * Author/Modifier: RJP
  2902. */
  2903. int
  2904. slapi_entry_has_children(const Slapi_Entry *entry)
  2905. {
  2906. Slapi_Attr *attr;
  2907. LDAPDebug( LDAP_DEBUG_TRACE, "=> slapi_has_children( %s )\n", slapi_entry_get_dn_const(entry), 0, 0);
  2908. /*If the subordinatecount exists, and it's nonzero, then return 1.*/
  2909. if (slapi_entry_attr_find( entry, "numsubordinates", &attr) == 0)
  2910. {
  2911. Slapi_Value *sval;
  2912. slapi_attr_first_value( attr, &sval );
  2913. if(sval!=NULL)
  2914. {
  2915. const struct berval *bval = slapi_value_get_berval( sval );
  2916. if(bval!=NULL)
  2917. {
  2918. /* The entry has the attribute, and it's non-zero */
  2919. if (strcmp(bval->bv_val, "0") != 0)
  2920. {
  2921. LDAPDebug( LDAP_DEBUG_TRACE, "<= slapi_has_children 1\n", 0, 0, 0 );
  2922. return(1);
  2923. }
  2924. }
  2925. }
  2926. }
  2927. LDAPDebug( LDAP_DEBUG_TRACE, "<= slapi_has_children 0\n", 0, 0, 0 );
  2928. return(0);
  2929. }
  2930. /*
  2931. * Renames an entry to simulate a MODRDN operation
  2932. */
  2933. int
  2934. slapi_entry_rename(Slapi_Entry *e, const char *newrdn, int deleteoldrdn, Slapi_DN *newsuperior)
  2935. {
  2936. int err = LDAP_SUCCESS;
  2937. Slapi_DN *olddn = NULL;
  2938. Slapi_Mods *smods = NULL;
  2939. Slapi_DN newsrdn;
  2940. LDAPDebug( LDAP_DEBUG_TRACE, "=> slapi_entry_rename\n", 0, 0, 0 );
  2941. slapi_sdn_init(&newsrdn);
  2942. /* Check if entry or newrdn are NULL. */
  2943. if (!e || !newrdn) {
  2944. err = LDAP_PARAM_ERROR;
  2945. goto done;
  2946. }
  2947. /* Get the old DN. */
  2948. olddn = slapi_entry_get_sdn(e);
  2949. /* If deleteoldrdn, find old RDN values and remove them from the entry. */
  2950. if (deleteoldrdn) {
  2951. char *type = NULL;
  2952. char * val = NULL;
  2953. int num_rdns = 0;
  2954. int i = 0;
  2955. Slapi_RDN *oldrdn = slapi_rdn_new_sdn(olddn);
  2956. /* Create mods based on the number of rdn elements. */
  2957. num_rdns = slapi_rdn_get_num_components(oldrdn);
  2958. smods = slapi_mods_new();
  2959. slapi_mods_init(smods, num_rdns + 2);
  2960. /* Loop through old rdns and construct a mod to remove the value. */
  2961. for (i = 0; i < num_rdns; i++) {
  2962. if (slapi_rdn_get_next(oldrdn, i, &type, &val) != -1) {
  2963. slapi_mods_add(smods, LDAP_MOD_DELETE, type, strlen(val), val);
  2964. }
  2965. }
  2966. slapi_rdn_free(&oldrdn);
  2967. /* Apply the mods to the entry. */
  2968. if ((err = slapi_entry_apply_mods(e, slapi_mods_get_ldapmods_byref(smods))) != LDAP_SUCCESS) {
  2969. /* A problem was encountered applying the mods. Bail. */
  2970. goto done;
  2971. }
  2972. }
  2973. /* We remove the parentid and entrydn since the backend will change these.
  2974. * We don't want to give the caller an inconsistent entry. */
  2975. slapi_entry_attr_delete(e, "parentid");
  2976. slapi_entry_attr_delete(e, "entrydn");
  2977. /* Build new DN. If newsuperior is set, just use "newrdn,newsuperior". If
  2978. * newsuperior is not set, need to add newrdn to old superior. */
  2979. slapi_sdn_init_dn_byref(&newsrdn, newrdn);
  2980. if (newsuperior) {
  2981. slapi_sdn_set_parent(&newsrdn, newsuperior);
  2982. } else {
  2983. Slapi_DN oldparent;
  2984. slapi_sdn_init(&oldparent);
  2985. slapi_sdn_get_parent(olddn, &oldparent);
  2986. slapi_sdn_set_parent(&newsrdn, &oldparent);
  2987. slapi_sdn_done(&oldparent);
  2988. }
  2989. /* Set the new DN in the entry. This hands off the memory used by newdn to the entry. */
  2990. slapi_entry_set_sdn(e, &newsrdn);
  2991. /* Set the RDN in the entry. */
  2992. /* note - there isn't a slapi_entry_set_rdn_from_sdn function */
  2993. slapi_rdn_done(slapi_entry_get_srdn(e));
  2994. slapi_rdn_init_all_sdn(slapi_entry_get_srdn(e),&newsrdn);
  2995. /* Add RDN values to entry. */
  2996. err = slapi_entry_add_rdn_values(e);
  2997. done:
  2998. slapi_mods_free(&smods);
  2999. slapi_sdn_done(&newsrdn);
  3000. LDAPDebug( LDAP_DEBUG_TRACE, "<= slapi_entry_rename\n", 0, 0, 0 );
  3001. return err;
  3002. }
  3003. /*
  3004. * Apply a set of modifications to an entry
  3005. */
  3006. int
  3007. slapi_entry_apply_mods( Slapi_Entry *e, LDAPMod **mods )
  3008. {
  3009. return entry_apply_mods(e, mods);
  3010. }
  3011. /*
  3012. * Apply a single mod to an entry
  3013. */
  3014. int slapi_entry_apply_mod( Slapi_Entry *e, LDAPMod *mod )
  3015. {
  3016. return entry_apply_mod(e, mod);
  3017. }
  3018. int
  3019. entry_apply_mods( Slapi_Entry *e, LDAPMod **mods )
  3020. {
  3021. return entry_apply_mods_ignore_error(e, mods, -1);
  3022. }
  3023. int
  3024. entry_apply_mods_ignore_error( Slapi_Entry *e, LDAPMod **mods, int ignore_error )
  3025. {
  3026. int err;
  3027. LDAPMod **mp = NULL;
  3028. LDAPDebug( LDAP_DEBUG_TRACE, "=> entry_apply_mods\n", 0, 0, 0 );
  3029. err = LDAP_SUCCESS;
  3030. for ( mp = mods; mp && *mp; mp++ )
  3031. {
  3032. err = entry_apply_mod( e, *mp );
  3033. if(err == ignore_error){
  3034. (*mp)->mod_op = LDAP_MOD_IGNORE;
  3035. } else if ( err != LDAP_SUCCESS ) {
  3036. break;
  3037. }
  3038. }
  3039. LDAPDebug( LDAP_DEBUG_TRACE, "<= entry_apply_mods %d\n", err, 0, 0 );
  3040. return( err );
  3041. }
  3042. /*
  3043. * apply mod and store the result in the extension
  3044. * return value: 1 - mod is applied and stored in extension
  3045. * -1 - mod is applied and failed
  3046. * 0 - mod is nothing to do with extension
  3047. */
  3048. int
  3049. slapi_entry_apply_mod_extension(Slapi_Entry *e, const LDAPMod *mod, int modcnt)
  3050. {
  3051. Slapi_Value **vals = NULL;
  3052. struct attrs_in_extension *aiep;
  3053. int err = LDAP_SUCCESS;
  3054. int rc = 0; /* by default, mod is nothing to do with extension */
  3055. if ((NULL == e) || (NULL == mod)) {
  3056. return err;
  3057. }
  3058. if (modcnt < 0) {
  3059. int i;
  3060. for (i = 0; mod->mod_bvalues && mod->mod_bvalues[i]; i++) ;
  3061. modcnt = i;
  3062. }
  3063. for (aiep = attrs_in_extension; aiep && aiep->ext_type; aiep++) {
  3064. vals = NULL;
  3065. if (0 == strcasecmp(mod->mod_type, aiep->ext_type)) {
  3066. rc = 1;
  3067. switch (mod->mod_op & ~LDAP_MOD_BVALUES) {
  3068. case LDAP_MOD_ADD:
  3069. if (modcnt > 0) {
  3070. valuearray_init_bervalarray(mod->mod_bvalues, &vals);
  3071. if (vals) {
  3072. /* vals is consumed if successful. */
  3073. err = aiep->ext_set(e, vals, SLAPI_EXT_SET_ADD);
  3074. if (err) {
  3075. slapi_log_error(SLAPI_LOG_FATAL, "entry_apply_mod",
  3076. "ADD: Failed to set %s to extension\n",
  3077. aiep->ext_type);
  3078. valuearray_free(&vals);
  3079. goto bail;
  3080. }
  3081. } else {
  3082. slapi_log_error(SLAPI_LOG_FATAL, "entry_apply_mod",
  3083. "ADD: %s has no values\n",
  3084. aiep->ext_type);
  3085. goto bail;
  3086. }
  3087. }
  3088. break;
  3089. case LDAP_MOD_DELETE:
  3090. if (modcnt > 0) {
  3091. err = aiep->ext_get(e, &vals);
  3092. if (err) {
  3093. slapi_log_error(SLAPI_LOG_FATAL, "entry_apply_mod",
  3094. "DEL: Failed to get %s from extension\n",
  3095. aiep->ext_type);
  3096. goto bail;
  3097. }
  3098. if (vals && *vals) {
  3099. Slapi_Value **myvals = NULL;
  3100. valuearray_add_valuearray(&myvals, vals, 0);
  3101. err = valuearray_subtract_bvalues(myvals,
  3102. mod->mod_bvalues);
  3103. if (err > 0) { /* err values are subtracted */
  3104. /*
  3105. * mvals contains original values minus
  3106. * to-be-deleted value. ext_set replaces the
  3107. * original value with the delta.
  3108. */
  3109. /* myvals is consumed if successful. */
  3110. err = aiep->ext_set(e, myvals, SLAPI_EXT_SET_REPLACE);
  3111. if (err) {
  3112. slapi_log_error(SLAPI_LOG_FATAL,
  3113. "entry_apply_mod",
  3114. "DEL: Failed to set %s "
  3115. "to extension\n",
  3116. aiep->ext_type);
  3117. valuearray_free(&myvals);
  3118. goto bail;
  3119. }
  3120. }
  3121. }
  3122. } else {
  3123. /* ext_set replaces the existing value with NULL */
  3124. err = aiep->ext_set(e, NULL, SLAPI_EXT_SET_REPLACE);
  3125. if (err) {
  3126. slapi_log_error(SLAPI_LOG_FATAL, "entry_apply_mod",
  3127. "DEL: Failed to set %s to extension\n",
  3128. aiep->ext_type);
  3129. goto bail;
  3130. }
  3131. }
  3132. break;
  3133. case LDAP_MOD_REPLACE:
  3134. if (modcnt > 0) {
  3135. /* ext_set replaces the existing value with the new value */
  3136. valuearray_init_bervalarray(mod->mod_bvalues, &vals);
  3137. if (vals) {
  3138. /* vals is consumed if successful. */
  3139. err = aiep->ext_set(e, vals, SLAPI_EXT_SET_REPLACE);
  3140. if (err) {
  3141. slapi_log_error(SLAPI_LOG_FATAL, "entry_apply_mod",
  3142. "REPLACE: Failed to set %s to extension\n",
  3143. aiep->ext_type);
  3144. valuearray_free(&vals);
  3145. goto bail;
  3146. }
  3147. } else {
  3148. slapi_log_error(SLAPI_LOG_FATAL, "entry_apply_mod",
  3149. "REPLACE: %s has no values\n",
  3150. aiep->ext_type);
  3151. goto bail;
  3152. }
  3153. }
  3154. break;
  3155. default:
  3156. rc = 0;
  3157. break;
  3158. }
  3159. }
  3160. }
  3161. bail:
  3162. if (rc > 0) {
  3163. if (err) {
  3164. rc = -1;
  3165. } else {
  3166. rc = 1;
  3167. }
  3168. }
  3169. return rc;
  3170. }
  3171. /*
  3172. * Apply a modification to an entry
  3173. */
  3174. int
  3175. entry_apply_mod( Slapi_Entry *e, const LDAPMod *mod )
  3176. {
  3177. int i;
  3178. int bvcnt;
  3179. int err = LDAP_SUCCESS;
  3180. PRBool sawsubentry=PR_FALSE;
  3181. for ( i = 0; mod->mod_bvalues != NULL && mod->mod_bvalues[i] != NULL; i++ ) {
  3182. if((strcasecmp(mod->mod_type,"objectclass") == 0)
  3183. && (strncasecmp((const char *)mod->mod_bvalues[i]->bv_val,"ldapsubentry",mod->mod_bvalues[i]->bv_len) == 0))
  3184. sawsubentry=PR_TRUE;
  3185. LDAPDebug( LDAP_DEBUG_ARGS, " %s: %s\n", mod->mod_type, mod->mod_bvalues[i]->bv_val, 0 );
  3186. }
  3187. bvcnt = i;
  3188. /*
  3189. * If err == 0, apply mod.
  3190. * If err == 1, mod is successfully set to extension.
  3191. * If err == -1, setting mod to extension failed.
  3192. */
  3193. err = slapi_entry_apply_mod_extension(e, mod, bvcnt);
  3194. if (err) {
  3195. if (1 == err) {
  3196. err = LDAP_SUCCESS;
  3197. } else {
  3198. err = LDAP_OPERATIONS_ERROR;
  3199. }
  3200. goto done;
  3201. }
  3202. switch ( mod->mod_op & ~LDAP_MOD_BVALUES )
  3203. {
  3204. case LDAP_MOD_ADD:
  3205. LDAPDebug( LDAP_DEBUG_ARGS, " add: %s\n", mod->mod_type, 0, 0 );
  3206. if(sawsubentry) e->e_flags |= SLAPI_ENTRY_LDAPSUBENTRY;
  3207. err = slapi_entry_add_values( e, mod->mod_type, mod->mod_bvalues );
  3208. break;
  3209. case LDAP_MOD_DELETE:
  3210. LDAPDebug( LDAP_DEBUG_ARGS, " delete: %s\n", mod->mod_type, 0, 0 );
  3211. if(sawsubentry) e->e_flags |= 0;
  3212. err = slapi_entry_delete_values( e, mod->mod_type, mod->mod_bvalues );
  3213. break;
  3214. case LDAP_MOD_REPLACE:
  3215. LDAPDebug( LDAP_DEBUG_ARGS, " replace: %s\n", mod->mod_type, 0, 0 );
  3216. err = entry_replace_values( e, mod->mod_type, mod->mod_bvalues );
  3217. break;
  3218. }
  3219. done:
  3220. LDAPDebug( LDAP_DEBUG_ARGS, " -\n", 0, 0, 0 );
  3221. return( err );
  3222. }
  3223. /*
  3224. * Add an array of "vals" to entry "e".
  3225. */
  3226. SLAPI_DEPRECATED int
  3227. slapi_entry_add_values(
  3228. Slapi_Entry *e,
  3229. const char *type,
  3230. struct berval **vals
  3231. )
  3232. {
  3233. Slapi_Value **values= NULL;
  3234. int rc=0;
  3235. valuearray_init_bervalarray(vals,&values); /* JCM SLOW FUNCTION */
  3236. rc=slapi_entry_add_values_sv(e,type,values);
  3237. valuearray_free(&values);
  3238. return(rc);
  3239. }
  3240. /*
  3241. * Add an array of "vals" to entry "e".
  3242. */
  3243. int
  3244. slapi_entry_add_values_sv(Slapi_Entry *e,
  3245. const char *type,
  3246. Slapi_Value **vals)
  3247. {
  3248. int rc= LDAP_SUCCESS;
  3249. if (valuearray_isempty(vals))
  3250. {
  3251. /*
  3252. * No values to add (unexpected but acceptable).
  3253. */
  3254. }
  3255. else
  3256. {
  3257. Slapi_Attr **a= NULL;
  3258. Slapi_Attr **alist= &e->e_attrs;
  3259. attrlist_find_or_create(alist, type, &a);
  3260. if (slapi_attr_is_dn_syntax_attr(*a)) {
  3261. valuearray_dn_normalize_value(vals);
  3262. (*a)->a_flags |= SLAPI_ATTR_FLAG_NORMALIZED_CES;
  3263. }
  3264. rc= attr_add_valuearray(*a,vals,slapi_entry_get_dn_const(e));
  3265. }
  3266. return( rc );
  3267. }
  3268. /*
  3269. * Add a value set of "vs" to entry "e".
  3270. *
  3271. * 0 is success anything else failure.
  3272. */
  3273. int
  3274. slapi_entry_add_valueset(Slapi_Entry *e, const char *type, Slapi_ValueSet *vs)
  3275. {
  3276. Slapi_Value *v;
  3277. int i= slapi_valueset_first_value(vs,&v);
  3278. while(i!=-1) {
  3279. slapi_entry_add_value( e, type, v);
  3280. i= slapi_valueset_next_value(vs,i,&v);
  3281. }/* while */
  3282. return(0);
  3283. }
  3284. /*
  3285. * Delete an array of bervals from entry.
  3286. *
  3287. * Note that if this function fails, it leaves the values for "type" within
  3288. * "e" in an indeterminate state. The present value set may be truncated.
  3289. */
  3290. SLAPI_DEPRECATED int
  3291. slapi_entry_delete_values(
  3292. Slapi_Entry *e,
  3293. const char *type,
  3294. struct berval **vals
  3295. )
  3296. {
  3297. Slapi_Value **values= NULL;
  3298. int rc=0;
  3299. valuearray_init_bervalarray(vals,&values); /* JCM SLOW FUNCTION */
  3300. rc=slapi_entry_delete_values_sv(e,type,values);
  3301. valuearray_free(&values);
  3302. return(rc);
  3303. }
  3304. static int
  3305. delete_values_sv_internal(
  3306. Slapi_Entry *e,
  3307. const char *type,
  3308. Slapi_Value **valuestodelete,
  3309. int flags
  3310. )
  3311. {
  3312. Slapi_Attr *a;
  3313. int retVal= LDAP_SUCCESS;
  3314. /*
  3315. * If type is in the protected_attrs_all list, we could ignore the failure,
  3316. * as the attribute could only exist in the entry in the memory when the
  3317. * add/mod operation is done, while the retried entry from the db does not
  3318. * contain the attribute.
  3319. */
  3320. #if defined(USE_OLD_UNHASHED)
  3321. if (is_type_protected(type) || is_type_forbidden(type))
  3322. #else
  3323. if (is_type_protected(type))
  3324. #endif
  3325. {
  3326. flags |= SLAPI_VALUE_FLAG_IGNOREERROR;
  3327. }
  3328. /* delete the entire attribute */
  3329. if ( valuestodelete == NULL || valuestodelete[0] == NULL ){
  3330. LDAPDebug( LDAP_DEBUG_ARGS, "removing entire attribute %s\n",
  3331. type, 0, 0 );
  3332. retVal = attrlist_delete( &e->e_attrs, type);
  3333. if (flags & SLAPI_VALUE_FLAG_IGNOREERROR) {
  3334. return LDAP_SUCCESS;
  3335. }
  3336. return(retVal ? LDAP_NO_SUCH_ATTRIBUTE : LDAP_SUCCESS);
  3337. }
  3338. /* delete specific values - find the attribute first */
  3339. a= attrlist_find(e->e_attrs, type);
  3340. if ( a == NULL ) {
  3341. LDAPDebug( LDAP_DEBUG_ARGS, "could not find attribute %s\n",
  3342. type, 0, 0 );
  3343. if (flags & SLAPI_VALUE_FLAG_IGNOREERROR) {
  3344. return LDAP_SUCCESS;
  3345. }
  3346. return( LDAP_NO_SUCH_ATTRIBUTE );
  3347. }
  3348. {
  3349. retVal= valueset_remove_valuearray(&a->a_present_values, a, valuestodelete, flags, NULL);
  3350. if(retVal==LDAP_SUCCESS)
  3351. {
  3352. /*
  3353. * all values have been deleted -- remove entire attribute
  3354. */
  3355. if ( valueset_isempty(&a->a_present_values) )
  3356. {
  3357. attrlist_delete( &e->e_attrs, a->a_type );
  3358. }
  3359. }
  3360. else
  3361. {
  3362. /* Failed
  3363. * - Duplicate value
  3364. * - Value not found
  3365. * - Operations error
  3366. */
  3367. if ( retVal==LDAP_OPERATIONS_ERROR )
  3368. {
  3369. LDAPDebug( LDAP_DEBUG_ANY, "Possible existing duplicate "
  3370. "value for attribute type %s found in "
  3371. "entry %s\n", a->a_type, slapi_entry_get_dn_const(e), 0 );
  3372. }
  3373. if (flags & SLAPI_VALUE_FLAG_IGNOREERROR) {
  3374. retVal = LDAP_SUCCESS;
  3375. }
  3376. }
  3377. }
  3378. return( retVal );
  3379. }
  3380. /*
  3381. * Delete an array of present values from an entry.
  3382. *
  3383. * Note that if this function fails, it leaves the values for "type" within
  3384. * "e" in an indeterminate state. The present value set may be truncated.
  3385. */
  3386. int
  3387. slapi_entry_delete_values_sv(
  3388. Slapi_Entry *e,
  3389. const char *type,
  3390. Slapi_Value **valuestodelete
  3391. )
  3392. {
  3393. return( delete_values_sv_internal( e, type, valuestodelete,
  3394. 0 /* Do Not Ignore Errors */ ));
  3395. }
  3396. int
  3397. entry_replace_values(
  3398. Slapi_Entry *e,
  3399. const char *type,
  3400. struct berval **vals
  3401. )
  3402. {
  3403. return attrlist_replace( &e->e_attrs, type, vals );
  3404. }
  3405. int
  3406. entry_replace_values_with_flags(
  3407. Slapi_Entry *e,
  3408. const char *type,
  3409. struct berval **vals,
  3410. int flags
  3411. )
  3412. {
  3413. return attrlist_replace_with_flags( &e->e_attrs, type, vals, flags );
  3414. }
  3415. int
  3416. slapi_entry_flag_is_set( const Slapi_Entry *e, unsigned char flag )
  3417. {
  3418. return( e->e_flags & flag );
  3419. }
  3420. void slapi_entry_set_flag( Slapi_Entry *e, unsigned char flag)
  3421. {
  3422. e->e_flags |= flag;
  3423. }
  3424. void slapi_entry_clear_flag( Slapi_Entry *e, unsigned char flag)
  3425. {
  3426. e->e_flags &= ~flag;
  3427. }
  3428. /*
  3429. * Add the missing values in `vals' to an entry.
  3430. *
  3431. * Note that if this function fails, it leaves the values for "type" within
  3432. * "e" in an indeterminate state. The present value set may be truncated.
  3433. */
  3434. int
  3435. slapi_entry_merge_values_sv(
  3436. Slapi_Entry *e,
  3437. const char *type,
  3438. Slapi_Value **vals
  3439. )
  3440. {
  3441. int rc;
  3442. rc = delete_values_sv_internal( e, type, vals, SLAPI_VALUE_FLAG_IGNOREERROR );
  3443. if ( rc == LDAP_SUCCESS || rc == LDAP_NO_SUCH_ATTRIBUTE ) {
  3444. rc = slapi_entry_attr_merge_sv( e, type, vals );
  3445. }
  3446. return( rc );
  3447. }
  3448. void
  3449. send_referrals_from_entry(Slapi_PBlock *pb, Slapi_Entry *referral)
  3450. {
  3451. Slapi_Value *val=NULL;
  3452. Slapi_Attr *attr=NULL;
  3453. int i=0, numValues=0;
  3454. struct berval **refscopy=NULL;
  3455. struct berval **url=NULL;
  3456. slapi_entry_attr_find( referral, "ref", &attr );
  3457. if(attr != NULL) {
  3458. slapi_attr_get_numvalues(attr, &numValues );
  3459. if(numValues > 0) {
  3460. url=(struct berval **) slapi_ch_malloc((numValues + 1) * sizeof(struct berval*));
  3461. }
  3462. for (i = slapi_attr_first_value(attr, &val); i != -1;
  3463. i = slapi_attr_next_value(attr, i, &val)) {
  3464. url[i]=(struct berval*)slapi_value_get_berval(val);
  3465. }
  3466. url[numValues]=NULL;
  3467. }
  3468. refscopy = ref_adjust(pb, url, slapi_entry_get_sdn(referral), 0);
  3469. send_ldap_result(pb, LDAP_REFERRAL,
  3470. slapi_entry_get_dn(referral), NULL, 0, refscopy );
  3471. if(url != NULL) {
  3472. slapi_ch_free( (void **)&url );
  3473. }
  3474. if ( refscopy != NULL ) {
  3475. ber_bvecfree( refscopy );
  3476. }
  3477. }
  3478. /*
  3479. * slapi_entry_diff: perform diff between entry e1 and e2
  3480. * and set mods to smods which updates e1 to e2.
  3481. * diff_ctrl: SLAPI_DUMP_NOOPATTRS => skip operational attributes
  3482. */
  3483. void
  3484. slapi_entry_diff(Slapi_Mods *smods, Slapi_Entry *e1, Slapi_Entry *e2, int diff_ctrl)
  3485. {
  3486. Slapi_Attr *e1_attr = NULL;
  3487. Slapi_Attr *e2_attr = NULL;
  3488. char *e1_attr_name = NULL;
  3489. char *e2_attr_name = NULL;
  3490. int rval = 0;
  3491. slapi_mods_init(smods, 0);
  3492. for (slapi_entry_first_attr(e1, &e1_attr); e1_attr;
  3493. slapi_entry_next_attr(e1, e1_attr, &e1_attr))
  3494. {
  3495. /* skip operational attributes if not requested */
  3496. if ((diff_ctrl & SLAPI_DUMP_NOOPATTRS) &&
  3497. slapi_attr_flag_is_set(e1_attr, SLAPI_ATTR_FLAG_OPATTR))
  3498. continue;
  3499. slapi_attr_get_type(e1_attr, &e1_attr_name);
  3500. rval = slapi_entry_attr_find(e2, e1_attr_name, &e2_attr);
  3501. if (0 == rval)
  3502. {
  3503. int i;
  3504. Slapi_Value *e1_val;
  3505. /* attr e1_attr_names is shared with e2 */
  3506. /* XXX: not very efficient.
  3507. * needs to be rewritten for the schema w/ lots of attributes
  3508. */
  3509. for (i = slapi_attr_first_value(e1_attr, &e1_val); i != -1;
  3510. i = slapi_attr_next_value(e1_attr, i, &e1_val))
  3511. {
  3512. if (0 != slapi_attr_value_find(e2_attr,
  3513. slapi_value_get_berval(e1_val)))
  3514. {
  3515. /* attr-value e1_val not found in e2_attr; add it */
  3516. LDAPDebug(LDAP_DEBUG_TRACE,
  3517. "slapi_entry_diff: attr-val of %s is not in e2; "
  3518. "add it\n",
  3519. e1_attr_name, 0, 0);
  3520. slapi_mods_add(smods, LDAP_MOD_ADD, e1_attr_name,
  3521. e1_val->bv.bv_len, e1_val->bv.bv_val);
  3522. }
  3523. }
  3524. }
  3525. else
  3526. {
  3527. /* attr e1_attr_names not found in e2 */
  3528. LDAPDebug(LDAP_DEBUG_TRACE,
  3529. "slapi_entry_diff: attr %s is not in e2; add it\n",
  3530. e1_attr_name, 0, 0);
  3531. slapi_mods_add_mod_values(smods, LDAP_MOD_ADD,
  3532. e1_attr_name,
  3533. attr_get_present_values(e1_attr));
  3534. }
  3535. }
  3536. /* if the attribute is multi-valued, the untouched values should be put */
  3537. for (slapi_entry_first_attr(e2, &e2_attr); e2_attr;
  3538. slapi_entry_next_attr(e2, e2_attr, &e2_attr)) {
  3539. /* skip operational attributes if not requested */
  3540. if ((diff_ctrl & SLAPI_DUMP_NOOPATTRS) &&
  3541. slapi_attr_flag_is_set(e2_attr, SLAPI_ATTR_FLAG_OPATTR))
  3542. continue;
  3543. slapi_attr_get_type(e2_attr, &e2_attr_name);
  3544. rval = slapi_entry_attr_find(e1, e2_attr_name, &e1_attr);
  3545. if (0 == rval)
  3546. {
  3547. int i;
  3548. Slapi_Value *e2_val;
  3549. /* attr e2_attr_names is shared with e1 */
  3550. /* XXX: not very efficient.
  3551. * needs to be rewritten for the schema w/ lots of attributes
  3552. */
  3553. for (i = slapi_attr_first_value(e2_attr, &e2_val); i != -1;
  3554. i = slapi_attr_next_value(e2_attr, i, &e2_val))
  3555. {
  3556. if (0 != slapi_attr_value_find(e1_attr,
  3557. slapi_value_get_berval(e2_val)))
  3558. {
  3559. /* attr-value e2_val not found in e1_attr; delete it */
  3560. LDAPDebug(LDAP_DEBUG_TRACE,
  3561. "slapi_entry_diff: attr-val of %s is not in e1; "
  3562. "delete it\n",
  3563. e2_attr_name, 0, 0);
  3564. slapi_mods_add(smods, LDAP_MOD_DELETE, e2_attr_name,
  3565. e2_val->bv.bv_len, e2_val->bv.bv_val);
  3566. }
  3567. }
  3568. }
  3569. else
  3570. {
  3571. /* attr e2_attr_names not in e1 */
  3572. LDAPDebug(LDAP_DEBUG_TRACE,
  3573. "slapi_entry_diff: attr %s is not in e1; delete it\n",
  3574. e2_attr_name, 0, 0);
  3575. slapi_mods_add_mod_values(smods, LDAP_MOD_DELETE, e2_attr_name, NULL);
  3576. }
  3577. }
  3578. return;
  3579. }
  3580. /* delete the entry (and sub entries if any) specified with dn */
  3581. static void
  3582. delete_subtree(Slapi_PBlock *pb, const char *dn, void *plg_id)
  3583. {
  3584. Slapi_PBlock mypb;
  3585. int ret = 0;
  3586. int opresult;
  3587. slapi_search_internal_set_pb(pb, dn, LDAP_SCOPE_SUBTREE, "(objectclass=*)",
  3588. NULL, 0, NULL, NULL, plg_id, 0);
  3589. slapi_search_internal_pb(pb);
  3590. slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_RESULT, &ret);
  3591. if (ret == LDAP_SUCCESS) {
  3592. Slapi_Entry **entries = NULL;
  3593. Slapi_Entry **ep = NULL;
  3594. Slapi_DN *rootDN = slapi_sdn_new_dn_byval(dn);
  3595. slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES, &entries);
  3596. for (ep = entries; ep && *ep; ep++) {
  3597. const Slapi_DN *sdn = slapi_entry_get_sdn_const(*ep);
  3598. if (slapi_sdn_compare(sdn, rootDN) == 0)
  3599. continue;
  3600. pblock_init(&mypb);
  3601. slapi_delete_internal_set_pb(&mypb, slapi_sdn_get_dn(sdn),
  3602. NULL, NULL, plg_id, 0);
  3603. slapi_delete_internal_pb(&mypb);
  3604. slapi_pblock_get(&mypb, SLAPI_PLUGIN_INTOP_RESULT, &opresult);
  3605. pblock_done(&mypb);
  3606. }
  3607. slapi_sdn_free(&rootDN);
  3608. }
  3609. pblock_done(pb);
  3610. pblock_init(pb);
  3611. slapi_delete_internal_set_pb(pb, dn, NULL, NULL, plg_id, 0);
  3612. slapi_delete_internal_pb(pb);
  3613. slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_RESULT, &opresult);
  3614. pblock_done(pb);
  3615. }
  3616. /*
  3617. * slapi_entries_diff: diff between entry array old_entries and curr_entries
  3618. * (testall == 0) => return immediately after the 1st diff
  3619. * (testall != 0) => scan all the entries
  3620. * (force_update == 0) => just print the diff info
  3621. * (force_update != 0) => force to go back to old
  3622. *
  3623. * return 0, if identical
  3624. * return 1, otherwise
  3625. */
  3626. int
  3627. slapi_entries_diff(Slapi_Entry **old_entries, Slapi_Entry **curr_entries,
  3628. int testall, const char *logging_prestr,
  3629. const int force_update, void *plg_id)
  3630. {
  3631. char *my_logging_prestr = "";
  3632. Slapi_Entry **oep, **cep;
  3633. int rval = 0;
  3634. Slapi_PBlock pb;
  3635. #define SLAPI_ENTRY_FLAG_DIFF_IN_BOTH 0x80
  3636. if (NULL != logging_prestr && '\0' != *logging_prestr)
  3637. {
  3638. my_logging_prestr = slapi_ch_smprintf("%s ", logging_prestr);
  3639. }
  3640. for (oep = old_entries; oep != NULL && *oep != NULL; oep++) {
  3641. for (cep = curr_entries; cep != NULL && *cep != NULL; cep++) {
  3642. if (!slapi_sdn_compare(slapi_entry_get_sdn_const(*oep),
  3643. slapi_entry_get_sdn_const(*cep))) {
  3644. Slapi_Mods *smods = slapi_mods_new();
  3645. LDAPMod *mod;
  3646. int isfirst = 1;
  3647. /* check the attr diff and do modify */
  3648. slapi_entry_diff(smods, *oep, *cep, SLAPI_DUMP_NOOPATTRS);
  3649. for (mod = slapi_mods_get_first_mod(smods);
  3650. mod != NULL;
  3651. mod = slapi_mods_get_next_mod(smods))
  3652. {
  3653. rval = 1;
  3654. if (isfirst)
  3655. {
  3656. LDAPDebug(LDAP_DEBUG_ANY, "%sEntry %s\n", my_logging_prestr,
  3657. slapi_entry_get_dn_const(*oep), 0);
  3658. isfirst = 0;
  3659. }
  3660. switch (mod->mod_op & ~LDAP_MOD_BVALUES)
  3661. {
  3662. case LDAP_MOD_DELETE:
  3663. LDAPDebug(LDAP_DEBUG_ANY,
  3664. " Del Attribute %s Value %s\n",
  3665. mod->mod_type, mod->mod_bvalues?
  3666. mod->mod_bvalues[0]->bv_val:"N/A", 0);
  3667. break;
  3668. case LDAP_MOD_ADD:
  3669. LDAPDebug(LDAP_DEBUG_ANY,
  3670. " Add Attribute %s Value %s\n",
  3671. mod->mod_type, mod->mod_bvalues[0]->bv_val, 0);
  3672. break;
  3673. case LDAP_MOD_REPLACE:
  3674. LDAPDebug(LDAP_DEBUG_ANY,
  3675. " Rep Attribute %s Value %s\n",
  3676. mod->mod_type, mod->mod_bvalues[0]->bv_val, 0);
  3677. break;
  3678. default:
  3679. LDAPDebug(LDAP_DEBUG_ANY,
  3680. " Unknown op %d Attribute %s\n",
  3681. mod->mod_op & ~LDAP_MOD_BVALUES,
  3682. mod->mod_type, 0);
  3683. break;
  3684. }
  3685. if (!testall)
  3686. {
  3687. slapi_mods_free(&smods);
  3688. goto out;
  3689. }
  3690. }
  3691. if (0 == isfirst && force_update && testall)
  3692. {
  3693. pblock_init(&pb);
  3694. slapi_modify_internal_set_pb_ext(&pb,
  3695. slapi_entry_get_sdn_const(*oep),
  3696. slapi_mods_get_ldapmods_byref(smods),
  3697. NULL, NULL, plg_id, 0);
  3698. slapi_modify_internal_pb(&pb);
  3699. pblock_done(&pb);
  3700. }
  3701. slapi_mods_free(&smods);
  3702. slapi_entry_set_flag(*oep, SLAPI_ENTRY_FLAG_DIFF_IN_BOTH);
  3703. slapi_entry_set_flag(*cep, SLAPI_ENTRY_FLAG_DIFF_IN_BOTH);
  3704. }
  3705. }
  3706. }
  3707. for (oep = old_entries; oep != NULL && *oep != NULL; oep++) {
  3708. if (slapi_entry_flag_is_set(*oep, SLAPI_ENTRY_FLAG_DIFF_IN_BOTH)) {
  3709. slapi_entry_clear_flag(*oep, SLAPI_ENTRY_FLAG_DIFF_IN_BOTH);
  3710. } else {
  3711. rval = 1;
  3712. LDAPDebug(LDAP_DEBUG_ANY, "Add %sEntry %s\n",
  3713. my_logging_prestr, slapi_entry_get_dn_const(*oep), 0);
  3714. if (testall)
  3715. {
  3716. if (force_update)
  3717. {
  3718. LDAPMod **mods;
  3719. slapi_entry2mods(*oep, NULL, &mods);
  3720. pblock_init(&pb);
  3721. slapi_add_internal_set_pb(&pb,
  3722. slapi_entry_get_dn_const(*oep), mods, NULL, plg_id, 0);
  3723. slapi_add_internal_pb(&pb);
  3724. freepmods(mods);
  3725. pblock_done(&pb);
  3726. }
  3727. }
  3728. else
  3729. {
  3730. goto out;
  3731. }
  3732. }
  3733. }
  3734. for (cep = curr_entries; cep != NULL && *cep != NULL; cep++) {
  3735. if (slapi_entry_flag_is_set(*cep, SLAPI_ENTRY_FLAG_DIFF_IN_BOTH)) {
  3736. slapi_entry_clear_flag(*cep, SLAPI_ENTRY_FLAG_DIFF_IN_BOTH);
  3737. } else {
  3738. rval = 1;
  3739. LDAPDebug(LDAP_DEBUG_ANY, "Del %sEntry %s\n",
  3740. my_logging_prestr, slapi_entry_get_dn_const(*cep), 0);
  3741. if (testall)
  3742. {
  3743. if (force_update) {
  3744. pblock_init(&pb);
  3745. delete_subtree(&pb, slapi_entry_get_dn_const(*cep), plg_id);
  3746. pblock_done(&pb);
  3747. }
  3748. }
  3749. else
  3750. {
  3751. goto out;
  3752. }
  3753. }
  3754. }
  3755. out:
  3756. if (NULL != logging_prestr && '\0' != *logging_prestr)
  3757. slapi_ch_free_string(&my_logging_prestr);
  3758. return rval;
  3759. }
  3760. /* a helper function to set special rdn to a tombstone entry */
  3761. /* Since this a tombstone, it requires a special treatment for rdn*/
  3762. static int
  3763. _entry_set_tombstone_rdn(Slapi_Entry *e, const char *normdn)
  3764. {
  3765. int rc = 0;
  3766. char *tombstone_rdn = slapi_ch_strdup(normdn);
  3767. if ((0 == PL_strncasecmp(tombstone_rdn, SLAPI_ATTR_UNIQUEID,
  3768. sizeof(SLAPI_ATTR_UNIQUEID) - 1)) &&
  3769. (NULL == PL_strstr(tombstone_rdn, RUV_STORAGE_ENTRY_UNIQUEID))) {
  3770. /* dn starts with "nsuniqueid=" and this is not an RUV */
  3771. char *sepp = PL_strchr(tombstone_rdn, ',');
  3772. /* dn looks like this:
  3773. * nsuniqueid=042d8081-...-ca8fe9f7,uid=tuser,o=abc.com
  3774. * create a new srdn for the original dn
  3775. * uid=tuser,o=abc.com
  3776. */
  3777. if (sepp) {
  3778. Slapi_RDN mysrdn = {0};
  3779. rc = slapi_rdn_init_all_dn(&mysrdn, sepp + 1);
  3780. if (rc) {
  3781. slapi_log_error(SLAPI_LOG_FATAL, "_entry_set_tombstone_rdn",
  3782. "Failed to convert DN %s to RDN\n", sepp + 1);
  3783. slapi_rdn_done(&mysrdn);
  3784. goto bail;
  3785. }
  3786. sepp = PL_strchr(sepp + 1, ',');
  3787. if (sepp) {
  3788. /* nsuniqueid=042d8081-...-ca8fe9f7,uid=tuser, */
  3789. /* ^ */
  3790. *sepp = '\0';
  3791. slapi_rdn_replace_rdn(&mysrdn, tombstone_rdn);
  3792. slapi_entry_set_srdn(e, &mysrdn);
  3793. }
  3794. slapi_rdn_done(&mysrdn);
  3795. }
  3796. }
  3797. bail:
  3798. slapi_ch_free_string(&tombstone_rdn);
  3799. return rc;
  3800. }