template-migrate5to7 101 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091
  1. #{{PERL-EXEC}}
  2. #
  3. # BEGIN COPYRIGHT BLOCK
  4. # This Program is free software; you can redistribute it and/or modify it under
  5. # the terms of the GNU General Public License as published by the Free Software
  6. # Foundation; version 2 of the License.
  7. #
  8. # This Program is distributed in the hope that it will be useful, but WITHOUT
  9. # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  10. # FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
  11. #
  12. # You should have received a copy of the GNU General Public License along with
  13. # this Program; if not, write to the Free Software Foundation, Inc., 59 Temple
  14. # Place, Suite 330, Boston, MA 02111-1307 USA.
  15. #
  16. # In addition, as a special exception, Red Hat, Inc. gives You the additional
  17. # right to link the code of this Program with code not covered under the GNU
  18. # General Public License ("Non-GPL Code") and to distribute linked combinations
  19. # including the two, subject to the limitations in this paragraph. Non-GPL Code
  20. # permitted under this exception must only link to the code of this Program
  21. # through those well defined interfaces identified in the file named EXCEPTION
  22. # found in the source code files (the "Approved Interfaces"). The files of
  23. # Non-GPL Code may instantiate templates or use macros or inline functions from
  24. # the Approved Interfaces without causing the resulting work to be covered by
  25. # the GNU General Public License. Only Red Hat, Inc. may make changes or
  26. # additions to the list of Approved Interfaces. You must obey the GNU General
  27. # Public License in all respects for all of the Program code and other code used
  28. # in conjunction with the Program except the Non-GPL Code covered by this
  29. # exception. If you modify this file, you may extend this exception to your
  30. # version of the file, but you are not obligated to do so. If you do not wish to
  31. # provide this exception without modification, you must delete this exception
  32. # statement from your version and license this file solely under the GPL without
  33. # exception.
  34. #
  35. #
  36. # Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
  37. # Copyright (C) 2005 Red Hat, Inc.
  38. # All rights reserved.
  39. # END COPYRIGHT BLOCK
  40. #
  41. # enable the use of our bundled perldap with our bundled ldapsdk libraries
  42. # all of this nonsense can be omitted if the mozldapsdk and perldap are
  43. # installed in the operating system locations (e.g. /usr/lib /usr/lib/perl5)
  44. BEGIN {
  45. my $sroot = "{{DS-ROOT}}";
  46. push @INC, "$sroot/lib/perl/arch", "$sroot/lib/perl";
  47. if ($ENV{LD_LIBRARY_PATH}) {
  48. $ENV{LD_LIBRARY_PATH} .= ":";
  49. }
  50. $ENV{LD_LIBRARY_PATH} .= "$sroot/shared/lib";
  51. # this is only needed for HP/ux PA-RISC, but it doesn't hurt other platforms
  52. if ($ENV{SHLIB_PATH}) {
  53. $ENV{SHLIB_PATH} .= ":";
  54. }
  55. $ENV{SHLIB_PATH} .= "$sroot/shared/lib";
  56. }
  57. # Migrate a 5.x directory server to a 7.0 directory server
  58. #######################################################################################################
  59. # enable the use of Perldap functions
  60. require DynaLoader;
  61. use Getopt::Std;
  62. use Mozilla::LDAP::Conn;
  63. use Mozilla::LDAP::Entry;
  64. use Mozilla::LDAP::LDIF;
  65. use Mozilla::LDAP::Utils qw(:all);
  66. use Mozilla::LDAP::API qw(:api :ssl :apiv3 :constant); # Direct access to C API
  67. use Time::localtime;
  68. use File::Basename;
  69. use Class::Struct ;
  70. #######################################################################################################
  71. sub usage {
  72. print(STDERR "\nUsage: $0 -D rootdn { -w password | -w - | -j filename } -p port \n");
  73. print(STDERR " -o oldInstancePath -n newInstancePath [-t tracelevel] [-L logfile]\n");
  74. print(STDERR "************** parameters in brackets are optionals, others are required **************\n");
  75. print(STDERR " Opts: -D rootdn - new 7.0 Directory Manager\n");
  76. print(STDERR " : -w password - new 7.0 Directory Manager's password\n");
  77. print(STDERR " : -w - - Prompt for new 7.0 Directory Manager's password\n");
  78. print(STDERR " : -j filename - Read new 7.0 Directory Manager's password from file\n");
  79. print(STDERR " : -p port - new 7.0 Directory Server port\n");
  80. print(STDERR " : -o oldInstancePath - Path of the old instance to migrate \n");
  81. print(STDERR " : -n newInstancePath - Path of the new 7.0 instance\n");
  82. print(STDERR " : [-d dataPath] - Path to directory containing data files to import into new instance\n");
  83. print(STDERR " : [-v oldVersion] - Version of old instance (obtained by running $slapdExecName -v\n");
  84. print(STDERR " : [-t tracelevel] - (optional) specify the level of trace (0..3)\n");
  85. print(STDERR " : [-L logfile] - (optional) specify the file to log the migration report \n");
  86. }
  87. ########################################################################################################
  88. BEGIN {
  89. require 'uname.lib' ;
  90. $isNT = -d '\\';
  91. $PATHSEP = $isNT ? "\\" : "/";
  92. ${SEP} = $isNT ? ";" : ":" ;
  93. @INC = ( '.', '../../../admin/admin/bin');
  94. grep { s@/@\\@g } @INC if $isNT;
  95. $script_suffix = $isNT ? ".bat" : "";
  96. $exe_suffix = $isNT ? ".exe" : "";
  97. # NT needs quotes around some things unix doesn't
  98. $quote = $isNT ? "\"" : "";
  99. # If this variable is set, all file/directory creation will make sure the mode
  100. # and ownership of the destination is the same as the source
  101. $PRESERVE = 1 if (!$isNT);
  102. $script_suffix = $isNT ? ".bat" : "";
  103. $exe_suffix = $isNT ? ".exe" : "";
  104. if ($isNT) {
  105. $os = "WINNT";
  106. } else {
  107. $os = &uname("-s");
  108. }
  109. if ($isNT) {
  110. # we have to pass batch files directly to the NT command interpreter
  111. $com_spec = $ENV{ComSpec};
  112. if (!$com_spec) {
  113. $com_spec = $ENV{COMSPEC};
  114. }
  115. if (!$com_spec || ! -f $com_spec) {
  116. # find the first available command interpreter
  117. foreach $drive (c..z) {
  118. $com_spec = "$drive:\\winnt\\system32\\cmd.exe";
  119. last if (-f $com_spec);
  120. $com_spec = undef;
  121. }
  122. if (! $com_spec) {
  123. # punt and pray
  124. $com_spec = 'c:\winnt\system32\cmd.exe';
  125. }
  126. }
  127. }
  128. if ( $os eq "AIX" ) {
  129. $dll_suffix = "_shr.a";
  130. }
  131. elsif ( $os eq "HP-UX" ) {
  132. $dll_suffix = ".sl";
  133. }
  134. elsif ( $os eq "WINNT" ) {
  135. $dll_suffix = ".dll";
  136. }
  137. else {
  138. $dll_suffix = ".so";
  139. }
  140. $slapdExecName = $isNT ? 'slapd.exe' : './ns-slapd';
  141. select STDERR;
  142. $| = 1;
  143. select STDOUT;
  144. $| = 1;
  145. }
  146. SWITCH: {
  147. if ($os eq "AIX") {
  148. $LIB_PATH = "LIBPATH" ;
  149. last SWITCH ;
  150. }
  151. if ($os eq "HP-UX") {
  152. $LIB_PATH = "SHLIB_PATH" ;
  153. last SWITCH ;
  154. }
  155. if ($isNT) {
  156. $LIB_PATH = "PATH" ;
  157. last SWITCH ;
  158. }
  159. else {
  160. $LIB_PATH = "LD_LIBRARY_PATH" ;
  161. last SWITCH ;
  162. }
  163. }
  164. # old parameters
  165. ${oldDir} = "" ;
  166. ${oldname} = "" ;
  167. ${oldHome} = "" ;
  168. ${oldConfDir} = "" ;
  169. ${oldlocaluser} ;
  170. ${olduid} ;
  171. ${oldgid} ;
  172. # new parameters
  173. ${root} = "{{DS-ROOT}}" ;
  174. ${type} = "" ;
  175. ${newname} = "" ;
  176. ${newport} = "" ;
  177. ${rootDN} = "" ;
  178. ${rootpwd} = "" ;
  179. ${localhost} = "" ;
  180. ${LogFileReport} = "" ;
  181. ${newuid} ;
  182. ${localuser} ;
  183. ${newgid} ;
  184. $NO_INPUT_USER = 0 ; # by default user can give inputs during the migration process
  185. ${curdir} = getCwd();
  186. ${slapdExecDir} = "${root}${PATHSEP}bin${PATHSEP}slapd${PATHSEP}server${PATHSEP}";
  187. # in 7.0 the replica Id is setup to a static value
  188. $replicaIdvalue = 65535;
  189. # specify the level of trace
  190. $TRACELEVEL=1;
  191. $LDAP_SERVER_UNREACHABLE = 81;
  192. # get input users
  193. &getParameters() ;
  194. ${oldDir} = &normalizeDir("${oldDir}");
  195. ${oldHome} = "${oldDir}${PATHSEP}$type-$oldname" ;
  196. ${oldConfDir} = "${oldHome}${PATHSEP}config${PATHSEP}" ;
  197. ${oldSchemaDir} = "${oldConfDir}schema${PATHSEP}";
  198. ${oldDSEldif} = "${oldConfDir}dse.ldif";
  199. ${serverHome} = "${root}${PATHSEP}$type-$newname" ;
  200. ${schemaDir} = "$serverHome${PATHSEP}config${PATHSEP}schema${PATHSEP}";
  201. ${DSEldif} = "$serverHome${PATHSEP}config${PATHSEP}dse.ldif";
  202. ${ldif_rep} = "${oldConfDir}ldif${PATHSEP}" ;
  203. ${oldSlapdExecDir} = "${oldDir}${PATHSEP}bin${PATHSEP}slapd${PATHSEP}server${PATHSEP}";
  204. open(LOGFILE, ">> $LogFileReport");
  205. printTrace("\noldDir: $oldDir, oldHome: $oldHome, \noldConfDir: $oldConfDir, \nldif_rep: $ldif_rep, \nrootDN: $rootDN, \nPort: $newport, \nNewname: $newname\n",3);
  206. printTrace("\nLIB_PATH: $LIB_PATH",4);
  207. if (!(-d $serverHome)) {
  208. printMsg("\n$serverHome doesn't exist\n");
  209. exit(1);
  210. }
  211. if (!(-d $oldHome)) {
  212. printMsg("\n$oldHome doesn't exist\n");
  213. exit(1);
  214. }
  215. if ($olddatadir && !(-d $olddatadir)) {
  216. print("\n$olddatadir doesn't exist\n");
  217. exit(1);
  218. }
  219. %HashParametersName = ();
  220. # The following hash displays only general server parameters to migrate under cn=config
  221. %GeneralSrvParamToMigrate = (
  222. 'nsslapd-accesscontrol'=> '\n',
  223. 'nsslapd-errorlog-logging-enabled'=> '\n',
  224. 'nsslapd-accesslog-logging-enabled'=> '\n',
  225. 'nsslapd-auditlog-logging-enabled'=> '\n',
  226. 'nsslapd-accesslog-level'=> '\n',
  227. 'nsslapd-accesslog-logbuffering'=> '\n',
  228. 'nsslapd-accesslog-logexpirationtime'=> '\n',
  229. 'nsslapd-accesslog-logexpirationtimeunit'=> '\n',
  230. 'nsslapd-accesslog-logmaxdiskspace'=> '\n',
  231. 'nsslapd-accesslog-logminfreediskspace'=> '\n',
  232. 'nsslapd-accesslog-logrotationtime'=> '\n',
  233. 'nsslapd-accesslog-logrotationtimeunit'=> '\n',
  234. 'nsslapd-accesslog-maxlogsize'=> '\n',
  235. 'nsslapd-accesslog-maxLogsPerDir'=> '\n',
  236. 'nsslapd-attribute-name-exceptions'=> '\n',
  237. 'nsslapd-auditlog-logexpirationtime'=> '\n',
  238. 'nsslapd-auditlog-logexpirationtimeunit'=> '\n',
  239. 'nsslapd-auditlog-logmaxdiskspace'=> '\n',
  240. 'nsslapd-auditlog-logminfreediskspace'=> '\n',
  241. 'nsslapd-auditlog-logrotationtime'=> '\n',
  242. 'nsslapd-auditlog-logrotationtimeunit'=> '\n',
  243. 'nsslapd-auditlog-maxlogsize'=> '\n',
  244. 'nsslapd-auditlog-maxLogsPerDir'=> '\n',
  245. 'nsslapd-certmap-basedn'=> '\n',
  246. 'nsslapd-ds4-compatible-schema'=> '\n',
  247. 'nsslapd-enquote-sup-oc'=> '\n',
  248. 'nsslapd-errorlog-level'=> '\n',
  249. 'nsslapd-errorlog-logexpirationtime'=> '\n',
  250. 'nsslapd-errorlog-logexpirationtimeunit'=> '\n',
  251. 'nsslapd-errorlog-logmaxdiskspace'=> '\n',
  252. 'nsslapd-errorlog-logminfreediskspace'=> '\n',
  253. 'nsslapd-errorlog-logrotationtime'=> '\n',
  254. 'nsslapd-errorlog-logrotationtimeunit'=> '\n',
  255. 'nsslapd-errorlog-maxlogsize'=> '\n',
  256. 'nsslapd-errorlog-maxlogsperdir'=> '\n',
  257. 'nsslapd-groupevalnestlevel'=> '\n',
  258. 'nsslapd-idletimeout'=> '\n',
  259. 'nsslapd-ioblocktimeout'=> '\n',
  260. 'nsslapd-lastmod'=> '\n',
  261. 'nsslapd-listenhost'=> '\n',
  262. 'nsslapd-maxdescriptors'=> '\n',
  263. 'nsslapd-nagle'=> '\n',
  264. 'nsslapd-readonly'=> '\n',
  265. 'nsslapd-referralmode'=> '\n',
  266. 'nsslapd-plugin-depends-on-name'=> '\n',
  267. 'nsslapd-plugin-depends-on-type'=> '\n',
  268. 'nsslapd-referral'=> '\n',
  269. 'nsslapd-reservedescriptors'=> '\n',
  270. 'nsslapd-rootpwstoragescheme'=> '\n',
  271. 'nsslapd-schemacheck'=> '\n',
  272. 'nsslapd-secureport'=> '\n',
  273. 'nsslapd-security'=> '\n',
  274. 'nsslapd-sizelimit'=> '\n',
  275. 'nsslapd-ssl3ciphers'=> '\n',
  276. 'nsslapd-timelimit'=> '\n',
  277. 'passwordchange'=> '\n',
  278. 'passwordchecksyntax'=> '\n',
  279. 'passwordexp'=> '\n',
  280. 'passwordhistory'=> '\n',
  281. 'passwordinhistory'=> '\n',
  282. 'passwordlockout'=> '\n',
  283. 'passwordlockoutduration'=> '\n',
  284. 'passwordmaxage'=> '\n',
  285. 'passwordmaxfailure'=> '\n',
  286. 'passwordminage'=> '\n',
  287. 'passwordminlength'=> '\n',
  288. 'passwordmustchange'=> '\n',
  289. 'passwordresetfailurecount' => '\n',
  290. 'passwordstoragescheme' => '\n',
  291. 'passwordunlock' => '\n',
  292. 'passwordwarning' => '\n'
  293. );
  294. # the following hash displays global parameters related to database stored under cn=config,cn=ldbm database,cn=plugins,cn=config
  295. %GlobalConfigLDBMparamToMigrate = (
  296. 'nsslapd-allidsthreshold' => '\n',
  297. 'nsslapd-lookthroughlimit' => '\n',
  298. 'nsslapd-mode' => '\n',
  299. 'nsslapd-dbcachesize' => '\n',
  300. 'nsslapd-cache-autosize' => '\n',
  301. 'nsslapd-cache-autosize-split' => '\n',
  302. 'nsslapd-db-transaction-logging' => '\n',
  303. 'nsslapd-import-cachesize' => '\n'
  304. );
  305. # the following hash displays specific parameters to each backends and stored under cn=DBname,cn=ldbm database,cn=plugins,cn=config
  306. %LDBMparamToMigrate = (
  307. 'nsslapd-cachesize' => '\n',
  308. 'nsslapd-cachememsize' => '\n',
  309. 'nsslapd-readonly' => '\n',
  310. 'nsslapd-require-index' => '\n'
  311. );
  312. %ChainingConfigParams = (
  313. 'nsactivechainingcomponents' => '\n',
  314. 'nstransmittedcontrols' => '\n'
  315. );
  316. %ChainingDefaultInstanceConfigParams = (
  317. 'nsabandonedsearchcheckinterval' => '\n',
  318. 'nsbindconnectionslimit' => '\n',
  319. 'nsbindtimeout' => '\n',
  320. 'nsbindretrylimit' => '\n',
  321. 'nshoplimit' => '\n',
  322. 'nsmaxresponsedelay' => '\n',
  323. 'nsmaxtestresponsedelay' => '\n',
  324. 'nschecklocalaci' => '\n',
  325. 'nsconcurrentbindlimit' => '\n',
  326. 'nsconcurrentoperationslimit' => '\n',
  327. 'nsconnectionlife' => '\n',
  328. 'nsoperationconnectionslimit' => '\n',
  329. 'nsproxiedauthorization' => '\n',
  330. 'nsreferralonscopedsearch' => '\n',
  331. 'nsslapd-sizelimit' => '\n',
  332. 'nsslapd-timelimit' => '\n'
  333. );
  334. %changelog5params = (
  335. 'nsslapd-changelogmaxage' => '\n',
  336. 'nsslapd-changelogmaxentries' => '\n'
  337. );
  338. @SNMPparams = (
  339. 'nssnmpenabled',
  340. 'nssnmporganization',
  341. 'nssnmplocation',
  342. 'nssnmpcontact',
  343. 'nssnmpdescription',
  344. 'nssnmpmasterhost',
  345. 'nssnmpmasterport',
  346. 'nssnmpenabled',
  347. 'aci'
  348. );
  349. %stdIncludes = (
  350. "." => "\n",
  351. ".." => "\n",
  352. "30ns-common.ldif " => "\n",
  353. "50ns-mail.ldif " => "\n",
  354. "50ns-news.ldif" => "\n",
  355. "50iplanet-servicemgt.ldif"=> "\n",
  356. "50netscape-servicemgt.ldif"=> "\n",
  357. "50ns-mcd-browser.ldif" => "\n",
  358. "50ns-proxy.ldif" => "\n",
  359. "00core.ldif" => "\n",
  360. "50ns-admin.ldif" => "\n",
  361. "50ns-mcd-config.ldif " => "\n",
  362. "50ns-value.ldif" => "\n",
  363. "05rfc2247.ldif" => "\n",
  364. "50ns-calendar.ldif" => "\n",
  365. "50ns-mcd-li.ldif" => "\n",
  366. "50ns-wcal.ldif" => "\n",
  367. "05rfc2927.ldif" => "\n",
  368. "50ns-certificate.ldif" => "\n",
  369. "50ns-mcd-mail.ldif" => "\n",
  370. "50ns-web.ldif" => "\n",
  371. "10rfc2307.ldif" => "\n",
  372. "50ns-compass.ldif" => "\n",
  373. "50ns-media.ldif" => "\n",
  374. "20subscriber.ldif" => "\n",
  375. "50ns-delegated-admin.ldif"=> "\n",
  376. "50ns-mlm.ldif" => "\n",
  377. "25java-object.ldif" => "\n",
  378. "50ns-directory.ldif" => "\n",
  379. "50ns-msg.ldif" => "\n",
  380. "28pilot.ldif" => "\n",
  381. "50ns-legacy.ldif" => "\n",
  382. "50ns-netshare.ldif" => "\n"
  383. );
  384. # Backends migrated (Backend CN attribute value)
  385. @BACKENDS = () ;
  386. # All pairs of suffix-backend are registered in this hashtable
  387. %oldBackends = () ;
  388. #store the backend instances to migrate
  389. @LDBM_backend_instances = ();
  390. #store the mapping tree
  391. @Mapping_tree_entries = ();
  392. #store the suffix and the associated chaining backend
  393. %oldChainingBackends = ();
  394. #store the multiplexor bind entries to migrate
  395. %MultiplexorBindDNEntriesToMigrate = ();
  396. #store the Replica bind DN entries to migrate
  397. %ReplicaBindDNEntriesToMigrate = ();
  398. # list of standard plugins
  399. %stdPlugins = (
  400. "7-bit check" => "\n",
  401. "acl plugin" => "\n",
  402. "acl preoperation" => "\n",
  403. "binary syntax" => "\n",
  404. "case exact string syntax" => "\n",
  405. "case ignore string syntax" => "\n",
  406. "chaining database" => "\n",
  407. "class of service" => "\n",
  408. "country string syntax" => "\n",
  409. "distinguished name syntax" => "\n",
  410. "generalized time syntax" => "\n",
  411. "integer syntax" => "\n",
  412. "internationalization plugin" => "\n",
  413. "ldbm database" => "\n",
  414. "legacy replication plugin" => "\n",
  415. "multimaster replication plugin" => "\n",
  416. "octet string syntax" => "\n",
  417. "clear" => "\n",
  418. "crypt" => "\n",
  419. "ns-mta-md5" => "\n",
  420. "sha" => "\n",
  421. "ssha" => "\n",
  422. "postal address syntax" => "\n",
  423. "referential integrity postoperation" => "\n",
  424. "retro changelog plugin" => "\n",
  425. "roles plugin" => "\n",
  426. "telephone syntax" => "\n",
  427. "uid uniqueness" => "\n",
  428. "uri syntax" => "\n"
  429. );
  430. # list of indexes that have disappeared from the new schema compared to 5.0
  431. %deniedIndexes = (
  432. 'dncomp' => "\n"
  433. );
  434. @default_indexes = ();
  435. @indexes = ();
  436. # list of user added Plugin's. In 7.0, they 'll need to be recompiled
  437. @badPlugins = () ;
  438. @pluginAttrs = (
  439. "objectclass",
  440. "cn",
  441. "nsslapd-pluginpath",
  442. "nsslapd-plugininitfunc",
  443. "nsslapd-plugintype",
  444. "nsslapd-pluginenabled",
  445. "nsslapd-plugin-depends-on-type",
  446. "nsslapd-pluginid",
  447. "nsslapd-pluginversion",
  448. "nsslapd-pluginvendor"
  449. );
  450. @nsds5replicaAttrs = (
  451. 'objectclass',
  452. 'nsDS5ReplicaRoot',
  453. 'nsDS5ReplicaType',
  454. 'nsDS5ReplicaLegacyConsumer',
  455. 'nsDS5flags',
  456. 'nsDS5ReplicaId',
  457. 'nsDS5ReplicaPurgeDelay',
  458. 'nsDS5ReplicaBinddn',
  459. 'cn',
  460. 'nsDS5ReplicaReferral'
  461. );
  462. # array of replicas to migrate
  463. @new6replicas = ();
  464. # array of replication agreements to migrate
  465. @replicationAgreements = ();
  466. # compare LDIF standard config files with standard ones
  467. CompareStdConfigFiles() ;
  468. die "\n\n The version of product you want to migrate is not a 5.x Directory Server\n" unless ($oldVersion == 5) ;
  469. # Shutdown the legacy Directory instance
  470. printTrace("\nShutdown the legacy Directory Server instance: ${oldHome}",0);
  471. &stopServer($oldDir, 'slapd-'.$oldname);
  472. # get the hostname of the new LDAP server
  473. my $LDAPservername = &getLDAPservername();
  474. # get the uid and gid of the 7.0 slapd user
  475. ($localuser, $newuid, $newgid) = getuid_gid();
  476. # get the uid and gid of the 5.x slapd user
  477. ($oldlocaluser, $olduid, $oldgid) = getolduid_gid();
  478. printTrace("\n7.0 localuser: $localuser, uid: $newuid, gid: $newgid",2);
  479. printTrace("\n5.x localuser: $oldlocaluser, uid: $olduid, gid: $oldgid",2);
  480. # backup 7.0 configuration files in <6server_root>/slapd-instancename/config
  481. printTrace("\nBackup $serverHome${PATHSEP}config on $serverHome${PATHSEP}config_backup ...",0);
  482. &backupConfigFiles();
  483. # migrate the schema (need to stop and start the 7.0 server)
  484. printTrace("\nMigrate the schema...",0);
  485. MigrateSchema();
  486. # start the server unless it is already started
  487. &startServer() unless (isDirectoryAlive());
  488. ############### Connect to the 7.0 LDAP Directory Server ######################
  489. $ENV{"$LIB_PATH"} = $new_libpath;
  490. die "\n Migration aborted. Make sure your old and new Directory Server are installed on the same machine \n" if ( $LDAPservername == -1 );
  491. $conn = new Mozilla::LDAP::Conn($LDAPservername,$newport,$rootDN,$rootpwd) or die "\n Unable to contact the $Version.$Minor LDAP server: $LDAPservername\n";
  492. # Cconnection to 7.0 LDAP server is successful !
  493. printTrace("\nConnected to $Version.$Minor LDAP server",0) ;
  494. # Parse the main configuration file: dse.ldif
  495. printTrace("\n\nParse the old DSE ldif file: $oldDSEldif *****",0, 1);
  496. printTrace("\nThis may take a while ...\n",0);
  497. &MigrateDSEldif();
  498. #migrate LDBM backend instances
  499. printTrace("\n\nMigrate LDBM backend instances...",0,1);
  500. &migrateLDBM_backend_instances();
  501. #migrate mapping tree entries
  502. printTrace("\n\nMigrate mapping tree...",0,1);
  503. &migrateMappingTree();
  504. #migrate default indexes
  505. printTrace("\n\nMigrate default indexes...",0,1);
  506. migrateDefaultIndexes();
  507. #migrate indexes
  508. printTrace("\n\nMigrate indexes...",0,1);
  509. migrateIndexes();
  510. #migrate replicas
  511. printTrace("\n\nMigrate replicas...",0,1);
  512. &MigrateNSDS5_replica();
  513. #migrate replication agreements
  514. printTrace("\n\nMigrate replication agreements...",0,1);
  515. &MigrateNSDS_replication_agreement();
  516. #migrate key/cert databases
  517. printTrace("\n\nMigrate key/cert databases...",0,1);
  518. &MigrateSSL();
  519. # migrate certmap.conf
  520. printTrace("\n\nMigrate Certmap.conf...",0,1);
  521. &MigrateCertmap() ;
  522. ################## Close the connection to 7.0 LDAP Server #####################
  523. printTrace("\n\n***** Close the LDAP connection to the new Directory Server instance ***** ",0);
  524. $conn->close;
  525. ################## stop the new instance and Export/Import the data, restart the server ##################
  526. if (@BACKENDS) {
  527. &stopServer($root,'slapd-'.$newname);
  528. if ($olddatadir) {
  529. printTrace("\nData already contained in $olddatadir...\n",0,1) ;
  530. $ldif_rep = "$olddatadir${PATHSEP}";
  531. } else {
  532. printTrace("\nData processing...\n",0,1) ;
  533. # migrate data for each backend: 5.x -> LDIF files
  534. &manydb2Ldif($ldif_rep);
  535. }
  536. # migrate LDIF data to the new database: LDIF -> New
  537. &manyLdif2db($ldif_rep);
  538. &migrateChangelog();
  539. printTrace("\n***** Migrate ReplicaBindDN entries...\n",0,1);
  540. &importReplicaBindDNEntries();
  541. printTrace("\n***** Migrate MultiplexorBindDN entries...\n",0,1);
  542. &importMultiplexorBindDNEntries();
  543. &startServer() unless (isDirectoryAlive());
  544. }
  545. else {
  546. printTrace("\nINFORMATION - There are no non-standard or non-already existing suffixes to migrate\n",0);
  547. &migrateChangelog();
  548. printTrace("\n***** Migrate ReplicaBindDN entries...\n",0,1);
  549. &importReplicaBindDNEntries();
  550. printTrace("\n***** Migrate MultiplexorBindDN entries...\n",0,1);
  551. &importMultiplexorBindDNEntries();
  552. }
  553. printMsg("\n\n ****** End of migration ******\n\n");
  554. close(LOGFILE);
  555. ###########################################################################################
  556. # get input users
  557. sub getParameters {
  558. my $exit = 0 ;
  559. my $i = 0;
  560. my $pwdfile= "";
  561. while ($i <= $#ARGV) {
  562. if ( "$ARGV[$i]" eq "-D" ) { # directory manager
  563. if (! $rootDN) {
  564. $rootDN = $ARGV[++$i] ;
  565. }
  566. else {
  567. &usage() ;
  568. exit(1);
  569. }
  570. } elsif ("$ARGV[$i]" eq "-w") { # password
  571. if (! $rootpwd) {
  572. $rootpwd = $ARGV[++$i] ;
  573. }
  574. else {
  575. &usage() ;
  576. exit(1);
  577. }
  578. } elsif ("$ARGV[$i]" eq "-j") { # password file
  579. if (! $pwdfile) {
  580. $pwdfile = $ARGV[++$i] ;
  581. }
  582. else {
  583. &usage() ;
  584. exit(1);
  585. }
  586. } elsif ("$ARGV[$i]" eq "-o") { # old instance path
  587. if (! $oldHome ) {
  588. $oldHome = $ARGV[++$i] ;
  589. grep { s@\\@/@g } $oldHome if $isNT ;
  590. if ($oldHome =~ /[\"]?(.*)?[\"]?/) { $oldHome = $1 ; }
  591. if ($oldHome =~ m@^(.*)/([^-/]*)-([^/]*)[/]?$@) {
  592. $oldDir = $1 ;
  593. $type = $2 ;
  594. $oldname = $3 ;
  595. if ($isNT) {
  596. $oldDir = lc($oldDir) ;
  597. $type = lc($type) ;
  598. $oldname = lc($oldname) ;
  599. $oldHome = lc($oldHome) ;
  600. grep { s@/@\\@g } $oldDir ;
  601. grep { s@/@\\@g } $oldHome ;
  602. }
  603. }
  604. else {
  605. print("\nThe old instance path is not correct. It must be like slapd-instancename");
  606. &usage();
  607. exit(1);
  608. }
  609. }
  610. else {
  611. &usage() ;
  612. exit(1);
  613. }
  614. } elsif ("$ARGV[$i]" eq "-n") { # new instance path
  615. if (! $serverHome ) {
  616. $serverHome = $ARGV[++$i] ;
  617. grep { s@\\@/@g } $root if $isNT ;
  618. grep { s@\\@/@g } $serverHome if $isNT ;
  619. if ($serverHome =~ /[\"]?(.*)?[\"]?/) { $serverHome = $1 ; }
  620. if ($serverHome =~ m@^(.*?)/?([^/-]*)-([^/]*)[/]?$@) {
  621. $root = $1 if ($1);
  622. $type = $2 ;
  623. $newname = $3 ;
  624. if ($isNT) {
  625. $root = lc($root) ;
  626. $type = lc($type) ;
  627. $newname = lc($newname) ;
  628. $serverHome = lc($serverHome) ;
  629. grep { s@/@\\@g } $root ;
  630. grep { s@/@\\@g } $serverHome ;
  631. }
  632. }
  633. else {
  634. print("\nThe new instance path is not correct. It must be like slapd-instancename");
  635. &usage();
  636. exit(1);
  637. }
  638. }
  639. else {
  640. &usage() ;
  641. exit(1);
  642. }
  643. } elsif ("$ARGV[$i]" eq "-p") { # new DS port
  644. if (! $newport ) {
  645. $newport = $ARGV[++$i] ;
  646. }
  647. else {
  648. &usage() ;
  649. exit(1);
  650. }
  651. } elsif ("$ARGV[$i]" eq "-d") { # old instance LDIF data dir
  652. if (! $olddatadir ) {
  653. $olddatadir = $ARGV[++$i] ;
  654. }
  655. else {
  656. &usage() ;
  657. exit(1);
  658. }
  659. } elsif ("$ARGV[$i]" eq "-v") { # old version
  660. if (! $oldversionstr ) {
  661. $oldversionstr = $ARGV[++$i] ;
  662. }
  663. else {
  664. &usage() ;
  665. exit(1);
  666. }
  667. } elsif ("$ARGV[$i]" eq "-t") { # TRACELEVEL
  668. my $value = $ARGV[++$i] ;
  669. if ($value =~ /[0-3]/) {
  670. $TRACELEVEL = $value ;
  671. }
  672. else {
  673. print("\nThe tracelevel must belong to 0..3 interval");
  674. &usage();
  675. exit();
  676. }
  677. } elsif ("$ARGV[$i]" eq "-noinput") { # no user interventions during processing
  678. $NO_INPUT_USER = 1 ;
  679. } elsif ("$ARGV[$i]" eq "-L") { # migration logfile
  680. $LogFileReport = $ARGV[++$i] ;
  681. }
  682. else {
  683. print("\nThe option $ARGV[$i] is not recognized");
  684. &usage() ;
  685. exit(1);
  686. }
  687. $i++;
  688. }
  689. if (! $rootDN) {
  690. print("\nThe rootDN is missing");
  691. $exit = 1;
  692. }
  693. if ($pwdfile ne "") {
  694. # Open file and get the password
  695. unless (open (RPASS, $pwfile)) {
  696. die "Error, cannot open password file $passwdfile\n";
  697. }
  698. $rootpwd = <RPASS>;
  699. chomp($rootpwd);
  700. close(RPASS);
  701. } elsif ($rootpwd eq "-"){
  702. # Read the password from terminal
  703. die "The '-w -' option requires an extension library (Term::ReadKey) which is not\n",
  704. "part of the standard perl distribution. If you want to use it, you must\n",
  705. "download and install the module. You can find it at\n",
  706. "http://www.perl.com/CPAN/CPAN.html\n";
  707. # Remove the previous line and uncomment the following 6 lines once you have installed Term::ReadKey module.
  708. # use Term::ReadKey;
  709. # print "Bind Password: ";
  710. # ReadMode('noecho');
  711. # $rootpwd = ReadLine(0);
  712. # chomp($rootpwd);
  713. # ReadMode('normal');
  714. }
  715. if (! $rootpwd) {
  716. print("\nThe rootpwd is missing");
  717. $exit = 1 ;
  718. }
  719. if (! $newport) {
  720. print("\nThe port is missing");
  721. $exit = 1;
  722. }
  723. if (! $serverHome) {
  724. print("\nThe new instance path is missing");
  725. $exit = 1;
  726. }
  727. if (! $oldHome) {
  728. print("\nThe old instance path is missing");
  729. $exit = 1;
  730. }
  731. if ((! $LogFileReport) && $serverHome) {
  732. ($sec, $min, $hour, $dd, $mm, $yy) = &GetTime();
  733. $LogFileReport = "${serverHome}${PATHSEP}logs${PATHSEP}Migration_${dd}${mm}${yy}_${hour}${min}${sec}.log";
  734. }
  735. if ($exit) {
  736. &usage() ;
  737. exit(1);
  738. }
  739. }
  740. ###################################################################################################
  741. sub MigrateSchema{
  742. my $FilesChanged = "";
  743. my $AllDiffs = "";
  744. my $NoChanges = "" ;
  745. my $lineToBegin = 0 ;
  746. opendir(SCHEMADIR, $oldSchemaDir) or
  747. die "Error: could not open migrated config dir $oldSchemaDir: $!";
  748. foreach $file (readdir(SCHEMADIR)) {
  749. if (! exists($stdIncludes{lc($file)})) {
  750. my $newSchemaFile = $schemaDir . $file;
  751. if (-f $newSchemaFile ) {
  752. # The ldif file already exists. Make a diff and warn the user if different.
  753. if (diff($newSchemaFile, $oldSchemaDir.$file)) {
  754. &stopServer($root,'slapd-'.$newname) if (isDirectoryAlive());
  755. $AllDiffs .= "\n$file";
  756. copyBinFile("$oldSchemaDir$file", $newSchemaFile);
  757. }
  758. }
  759. else {
  760. &stopServer($root,'slapd-'.$newname) if (isDirectoryAlive());
  761. $AllDiffs .= "\n$file";
  762. copyBinFile("$oldSchemaDir$file", $newSchemaFile);
  763. }
  764. }
  765. }
  766. closedir(SCHEMADIR);
  767. if ($AllDiffs) {
  768. printMsg("\n\n***********************************************************************");
  769. printMsg("\nThe following LDIF files have been migrated:");
  770. printMsg("$AllDiffs");
  771. printMsg("\n*************************************************************************\n\n");
  772. }
  773. &startServer() if (! isDirectoryAlive());
  774. }
  775. ###################################################################################################
  776. # This subroutine is used to parse the dse.ldif file and call specific routines to act with entries
  777. sub MigrateDSEldif {
  778. printTrace("\nMigrate DSE entries...",1);
  779. my $tempoAlreadyDone = 0;
  780. open( DSELDIF, "< $oldDSEldif" ) || die "Can't open $oldDSEldif: $!: ";
  781. my $in = new Mozilla::LDAP::LDIF(*DSELDIF) ;
  782. while ($entry = readOneEntry $in) {
  783. $typeOfEntry = getTypeOfEntry($entry);
  784. SWITCH: {
  785. if ($typeOfEntry eq "LDBM_BACKEND_INSTANCE"){
  786. parseLDBM_backend_instance($entry);
  787. last SWITCH;
  788. }
  789. if ($typeOfEntry eq "MAPPING_TREE"){
  790. parseMapping_tree($entry);
  791. last SWITCH;
  792. }
  793. if ($typeOfEntry eq "DEFAULT_INDEX"){
  794. parseDefaultIndex($entry);
  795. last SWITCH;
  796. }
  797. if ($typeOfEntry eq "INDEX"){
  798. parseIndex($entry);
  799. last SWITCH;
  800. }
  801. if ($typeOfEntry eq "STANDARD_PLUGIN"){
  802. migrateStdPlugin($entry);
  803. last SWITCH;
  804. }
  805. if ($typeOfEntry eq "CONFIG_NODE"){
  806. migrateConfig_Node($entry);
  807. last SWITCH;
  808. }
  809. if ($typeOfEntry eq "CONFIG_LDBM_DATABASE"){
  810. migrateConfig_LDBM_database($entry);
  811. last SWITCH;
  812. }
  813. if ($typeOfEntry eq "CHAINING_BACKEND_CONFIG"){
  814. migrateChainingBE_config($entry);
  815. last SWITCH;
  816. }
  817. if ($typeOfEntry eq "CHAINING_BACKEND_INSTANCE"){
  818. migrateChainingBE_instance($entry);
  819. last SWITCH;
  820. }
  821. if ($typeOfEntry eq "NSDS5_REPLICA"){
  822. parseNSDS5_replica($entry);
  823. last SWITCH;
  824. }
  825. if ($typeOfEntry eq "NSDS_REPLICATION_AGREEMENT"){
  826. parseNSDS_replication_agreement($entry);
  827. last SWITCH;
  828. }
  829. if ($typeOfEntry eq "CHANGELOG5"){
  830. migrateChangelog5($entry);
  831. last SWITCH;
  832. }
  833. if ($typeOfEntry eq "REPLICATION"){
  834. migrateReplication($entry);
  835. last SWITCH;
  836. }
  837. if ($typeOfEntry eq "SECURITY"){
  838. migrateSecurity($entry);
  839. last SWITCH;
  840. }
  841. if ($typeOfEntry eq "SNMP"){
  842. migrateSNMP($entry);
  843. last SWITCH;
  844. }
  845. }
  846. }
  847. close(DSELDIF);
  848. }
  849. #############################################################################
  850. # returns the "type of an entry". If the entry is not to be migrated its type is "NOT_MIGRATED_TYPE"
  851. sub getTypeOfEntry{
  852. my $entry = shift;
  853. my $DN = $entry->getDN(1) ; # 1 is to normalize the returned DN
  854. if (($DN =~ /cn=ldbm database,cn=plugins,cn=config$/i) && (isObjectclass($entry,"nsBackendInstance"))) {
  855. return "LDBM_BACKEND_INSTANCE";
  856. }
  857. if (($DN =~ /cn=mapping tree,cn=config$/i) && (isObjectclass($entry,"nsMappingTree"))) {
  858. return "MAPPING_TREE";
  859. }
  860. if (($DN =~ /cn=default indexes,cn=config,cn=ldbm database,cn=plugins,cn=config$/i) && (isObjectclass($entry,"nsIndex"))) {
  861. return "DEFAULT_INDEX";
  862. }
  863. if (isObjectclass($entry,"nsIndex")) {
  864. return "INDEX";
  865. }
  866. if ((isObjectclass($entry,"nsSlapdPlugin")) && (isStdPlugin($entry))) {
  867. return "STANDARD_PLUGIN";
  868. }
  869. if ($DN =~ /^cn=config$/i) {
  870. return "CONFIG_NODE";
  871. }
  872. if ($DN =~ /^cn=config,cn=ldbm database,cn=plugins,cn=config$/i) {
  873. return "CONFIG_LDBM_DATABASE";
  874. }
  875. if (($DN =~ /^cn=config,cn=chaining database,cn=plugins,cn=config$/i) || ($DN =~ /^cn=default instance config,cn=chaining database,cn=plugins,cn=config$/i)){
  876. return "CHAINING_BACKEND_CONFIG";
  877. }
  878. if (($DN =~ /cn=chaining database,cn=plugins,cn=config$/i) && (isObjectclass($entry,"nsBackendInstance"))) {
  879. return "CHAINING_BACKEND_INSTANCE";
  880. }
  881. if (isObjectclass($entry,"nsDS5Replica")) {
  882. return "NSDS5_REPLICA";
  883. }
  884. if (isObjectclass($entry,"nsDS5ReplicationAgreement")) {
  885. return "NSDS_REPLICATION_AGREEMENT";
  886. }
  887. if ($DN =~ /^cn=changelog5,cn=config$/i) {
  888. return "CHANGELOG5";
  889. }
  890. if (($DN =~ /cn=replication,cn=config$/i) && ($DN !~ /^cn=replication,cn=config$/i)) {
  891. return "REPLICATION";
  892. }
  893. if ($DN =~ /cn=encryption,cn=config$/i) {
  894. return "SECURITY";
  895. }
  896. if ($DN =~ /^cn=SNMP,cn=config$/i) {
  897. return "SNMP";
  898. }
  899. return "NOT_MIGRATED_TYPE";
  900. }
  901. #############################################################################
  902. #############################################################################
  903. # returns 1 if the objectclass given in parameter is present in the objectclasses values of the entry
  904. # given in parameter, 0 else
  905. sub isObjectclass {
  906. my $entry = shift;
  907. my $objectclass = shift;
  908. return ($entry->hasValue("objectclass",$objectclass,1));
  909. }
  910. #############################################################################
  911. sub isStdPlugin {
  912. my $entry = shift;
  913. my $CN = $entry->{cn}[0];
  914. if (isObjectclass($entry,"nsSlapdPlugin")) {
  915. return 1 if ($stdPlugins{lc($CN)});
  916. }
  917. return 0;
  918. }
  919. #############################################################################
  920. sub alreadyExistsInNew{
  921. my $entry = shift;
  922. my $mustExist = shift;
  923. my $DN = $entry->getDN(1); # 1 to normalize the DN
  924. # We have a name change of "uid uniqueness" plugin in DS6.x
  925. # to "attribute uniqueness"
  926. $DN =~ s/uid\ uniqueness/attribute\ uniqueness/ if ($DN =~ /uid\ uniqueness/);
  927. return searchEntry($DN, $mustExist);
  928. }
  929. #############################################################################
  930. sub searchEntry {
  931. my $DN = shift;
  932. my $mustExist = shift;
  933. my $res = $conn->search($DN, "base", "objectclass=*");
  934. my $cpt = 5;
  935. if ($res) {
  936. return $res;
  937. }
  938. else {
  939. my $errorCode = $conn->getErrorCode();
  940. while (($errorCode eq $LDAP_SERVER_UNREACHABLE) && cpt && (! $res)) {
  941. printMsg("\ntry to reconnect to search $DN");
  942. $conn = new Mozilla::LDAP::Conn($LDAPservername,$newport,$rootDN,$rootpwd) or die "\n Unable to contact the $Version.$Minor LDAP server: $LDAPservername\n";
  943. $res = $conn->search($DN, "base", "objectclass=*");
  944. $errorCode = $conn->getErrorCode();
  945. $cpt--;
  946. }
  947. if ($res){
  948. return $res ;
  949. }
  950. elsif (($errorCode eq $LDAP_SERVER_UNREACHABLE) || ($mustExist)) {
  951. my $msg = $conn->getErrorString();
  952. printMsg("\n\n*** Failed to search: $DN");
  953. printMsg("\n*** Error Msg: $msg, Error code: $errorCode");
  954. }
  955. return 0;
  956. }
  957. }
  958. #############################################################################
  959. sub addEntryToNew{
  960. my $entry = shift;
  961. my $typeOfEntry = shift;
  962. my $trace = shift;
  963. my $res = $conn->add($entry);
  964. my $DN = $entry->getDN(1);
  965. my $cpt = 5;
  966. if ($res) {
  967. printTrace("\n$typeOfEntry - Add successfull: $DN",$trace);
  968. return 1;
  969. }
  970. else {
  971. my $errorCode = $conn->getErrorCode();
  972. while (($errorCode eq $LDAP_SERVER_UNREACHABLE) && cpt && (! $res)) {
  973. printMsg("\ntry to reconnect to add $DN");
  974. $conn = new Mozilla::LDAP::Conn($LDAPservername,$newport,$rootDN,$rootpwd) or die "\n Unable to contact the $Version.$Minor LDAP server: $LDAPservername\n";
  975. $res = $conn->add($entry);
  976. $errorCode = $conn->getErrorCode();
  977. $cpt--;
  978. }
  979. if ($res){
  980. printTrace("\n$typeOfEntry - Add successfull: $DN",$trace);
  981. return 1;
  982. }
  983. else {
  984. my $msg = $conn->getErrorString();
  985. printMsg("\n\n*** $typeOfEntry: Add Failed: $DN");
  986. printMsg("\n*** Error Msg: $msg, Error code: $errorCode");
  987. return 0;
  988. }
  989. }
  990. }
  991. #############################################################################
  992. sub updateEntry{
  993. my $entry = shift;
  994. my $typeOfEntry = shift;
  995. my $CHECK = shift;
  996. my $trace = shift;
  997. my $cpt = 5;
  998. if ($CHECK) {
  999. if (! hasChanged($entry, $typeOfEntry)) {
  1000. return 1;
  1001. }
  1002. }
  1003. my $res = $conn->update($entry);
  1004. my $DN = $entry->getDN(1);
  1005. if ($res) {
  1006. printTrace("\n$typeOfEntry - Update successfull: $DN",$trace);
  1007. return 1 ;
  1008. }
  1009. else {
  1010. my $errorCode = $conn->getErrorCode();
  1011. while (($errorCode eq $LDAP_SERVER_UNREACHABLE) && cpt && (! $res)) {
  1012. printMsg("\ntry to reconnect to update $DN");
  1013. $conn = new Mozilla::LDAP::Conn($LDAPservername,$newport,$rootDN,$rootpwd) or die "\n Unable to contact the $Version.$Minor LDAP server: $LDAPservername\n";
  1014. $res = $conn->update($entry);
  1015. $errorCode = $conn->getErrorCode();
  1016. $cpt--;
  1017. }
  1018. if ($res){
  1019. printTrace("\n$typeOfEntry - Update successfull: $DN",$trace);
  1020. return 1;
  1021. }
  1022. else {
  1023. my $msg = $conn->getErrorString();
  1024. printMsg("\n\n*** $typeOfEntry - Update Failed: $DN");
  1025. printMsg("\n*** Error Msg: $msg, Error code: $errorCode");
  1026. return 0;
  1027. }
  1028. }
  1029. }
  1030. #############################################################################
  1031. # returns 1 if the entry to migrate and the current entry are different one another
  1032. sub hasChanged {
  1033. my $entry = shift;
  1034. my $typeOfEntry = shift;
  1035. my $DN = $entry->getDN(1);
  1036. my $newEntry = searchEntry($DN,1);
  1037. return 1 if (! $newEntry); # we shoudn't be in that case ...
  1038. # do the stuff to check wether the entry has changed or not given its type
  1039. if (($typeOfEntry eq "DEFAULT_INDEX") || ($typeOfEntry eq "INDEX")){
  1040. my @indexTypes = $entry->getValues("nsIndexType");
  1041. my @newIndexTypes = $newEntry->getValues("nsIndexType");
  1042. my @nsmatchingrules = $entry->getValues("nsmatchingrule");
  1043. my @newMatchingRules = $newEntry->getValues("nsmatchingrule");
  1044. return 1 if (Diffs(\@indexTypes, \@newIndexTypes));
  1045. return 1 if (Diffs(\@nsmatchingrules,\@newMatchingRules));
  1046. return 0;
  1047. }
  1048. if ($typeOfEntry eq "CHANGELOG5"){
  1049. printTrace("\nCheck wether changelog has changed or not",3);
  1050. my @params = keys(%changelog5params);
  1051. foreach $param (@params){
  1052. my @values = $entry->getValues($param);
  1053. my @newValues = $newEntry->getValues($param);
  1054. return 1 if (Diffs(\@values,\@newValues));
  1055. }
  1056. return 0;
  1057. }
  1058. if ($typeOfEntry eq "SNMP"){
  1059. foreach $param (@SNMPparams){
  1060. my @values = $entry->getValues($param);
  1061. my @newValues = $newEntry->getValues($param);
  1062. return 1 if (Diffs(\@values,\@newValues));
  1063. }
  1064. return 0;
  1065. }
  1066. # we don't know how to compare such type of entry => just return 1
  1067. return 1 ;
  1068. }
  1069. sub isAsystemIndex {
  1070. my $index = shift;
  1071. return ($index->hasValue("nsSystemIndex","true",1));
  1072. }
  1073. sub updatePathInPluginArgs {
  1074. my $plugin = shift;
  1075. my $argNum = 0;
  1076. my $argPrefix = "nsslapd-pluginarg";
  1077. my $cont = 1;
  1078. my $Unix_oldDir = ${oldDir} ;
  1079. my $Unix_root = ${root} ;
  1080. grep { s@\\@/@g } $Unix_oldDir if $isNT;
  1081. grep { s@\\@/@g } $Unix_root if $isNT;
  1082. while ($cont) {
  1083. my $arg = $argPrefix . $argNum ;
  1084. if ($plugin->exists($arg)) {
  1085. $_ = $plugin->{$arg}[0] ;
  1086. s@$Unix_oldDir@$Unix_root@ig ;
  1087. s/$type-$oldname/$type-$newname/ig ;
  1088. $plugin->setValues($arg, $_) ;
  1089. }
  1090. else {
  1091. $cont = 0 ;
  1092. }
  1093. $argNum++;
  1094. }
  1095. return $plugin;
  1096. }
  1097. sub Diffs {
  1098. my $valuesToMigrate = shift;
  1099. my $currentValues = shift;
  1100. return 1 if (getDiff(\@{$valuesToMigrate},\@{$currentValues}));
  1101. return 1 if (getDiff(\@{$currentValues},\@{$valuesToMigrate}));
  1102. return 0 ;
  1103. }
  1104. sub getDiff {
  1105. # we get references to arrays
  1106. my $elements = shift ;
  1107. my $existing_elements = shift ;
  1108. my %count = () ;
  1109. my %countEE = () ;
  1110. @diff = () ;
  1111. foreach $e (@{$elements}, @{$existing_elements}) { $count{$e}++ ;}
  1112. foreach $e (@{existing_elements}) { $countEE{$e}++ ;}
  1113. foreach $e (@{$elements}) {
  1114. # if $e is only present in @$elements, we push it to the diff array
  1115. if (($count{$e} == 1) && ($countEE{$e} == 0)) {
  1116. push @diff, $e ;
  1117. }
  1118. }
  1119. return @diff ;
  1120. }
  1121. sub registerSuffix_Backend {
  1122. my $ldbmDatabase = shift;
  1123. my $CN = $ldbmDatabase->{cn}[0];
  1124. my $suffixArg = "nsslapd-suffix";
  1125. my $suffix = $ldbmDatabase->{$suffixArg}[0];
  1126. $oldBackends{$suffix} = $CN;
  1127. }
  1128. #############################################################################
  1129. # #
  1130. # #
  1131. # #
  1132. #############################################################################
  1133. sub migrateLDBM_backend_instances {
  1134. foreach $entry (@LDBM_backend_instances) {
  1135. my $DN = $entry->getDN(1); # 1 is to normalize the DN
  1136. my $CN = $entry->{cn}[0];
  1137. my $expLdif;
  1138. my $confirm = "No";
  1139. my $dest = "$serverHome${PATHSEP}db_backup" ;
  1140. my $newSlapdExecDir = "$root${PATHSEP}bin${PATHSEP}slapd${PATHSEP}server";
  1141. if ($DN =~/cn=netscaperoot,cn=ldbm database/i){
  1142. printTrace("\n\n*** INFORMATION - NetscapeRoot is NOT migrated",0);
  1143. }
  1144. else {
  1145. if(alreadyExistsInNew($entry)){
  1146. printMsg("\n\n*** LDBM_BACKEND_INSTANCE - $DN already exists");
  1147. printMsg("\n*** Migration will overwrite existing database");
  1148. printMsg("\nDo you want to continue Yes/No [No] ?") ;
  1149. my $answer = <STDIN> ;
  1150. if ($answer =~ /y|yes/i) {
  1151. printMsg("Do you want to export the existing data Yes/No [Yes] ?");
  1152. my $answer = <STDIN> ;
  1153. if (!($answer =~ /n|no/i)) {
  1154. mkdir $dest, 0700 unless (-d $dest);
  1155. $expLdif = "$dest${PATHSEP}$CN.ldif";
  1156. while (!($confirm =~ /y|yes/i)) {
  1157. printMsg("\nEnter the full pathname of the file [$expLdif]:") ;
  1158. $answer = <STDIN> ;
  1159. chomp($expLdif = $answer) unless ($answer eq "\n");
  1160. printMsg("\nExisting data will be exported under $expLdif");
  1161. printMsg("\nContinue Yes/No [No] ?");
  1162. $confirm = <STDIN>;
  1163. }
  1164. $ENV{"$LIB_PATH"}=$new_libpath;
  1165. chdir($newSlapdExecDir) or die "\nCould not change directory to $newSlapdExecDir: $!\n";
  1166. printTrace("\nNow backing up database $CN in $expLdif\n",0);
  1167. &stopServer($root,'slapd-'.$newname);
  1168. &db2Ldif($expLdif, $CN, $serverHome);
  1169. &startServer() unless (isDirectoryAlive());
  1170. }
  1171. push @BACKENDS, $CN;
  1172. } else {
  1173. printMsg("\n*** Migration will not update it");
  1174. break;
  1175. }
  1176. } else {
  1177. printTrace("\nWe should add the backend instance $DN",3);
  1178. my $suffixarg = "nsslapd-suffix" ;
  1179. my $suffixname= $entry->{$suffixarg}[0] ;
  1180. my $newEntry = $conn->newEntry() ;
  1181. $newEntry->setDN($DN);
  1182. $newEntry->setValues("objectclass", "top", "extensibleObject", "nsBackendInstance" );
  1183. $newEntry->setValues("cn", $CN );
  1184. $newEntry->setValues($suffixarg, $suffixname);
  1185. my @params = keys(%LDBMparamToMigrate);
  1186. foreach $param (@params) {
  1187. my @values = $entry->getValues($param);
  1188. $newEntry->setValues($param, @values) if (@values);
  1189. }
  1190. if (addEntryToNew($newEntry, "LDBM_BACKEND_INSTANCE",1)) {
  1191. push @BACKENDS, $CN;
  1192. }
  1193. }
  1194. }
  1195. }
  1196. }
  1197. sub parseLDBM_backend_instance {
  1198. my $entry = shift;
  1199. &registerSuffix_Backend($entry);
  1200. push @LDBM_backend_instances, $entry;
  1201. }
  1202. #############################################################################
  1203. sub migrateMappingTree {
  1204. foreach $entry (@Mapping_tree_entries) {
  1205. my $DN = $entry->getDN(1); # 1 si to normalize the DN
  1206. if ($DN =~/cn=\"o=netscaperoot\",cn=mapping tree,cn=config/i){
  1207. # DO NOTHING
  1208. }
  1209. else {
  1210. if(alreadyExistsInNew($entry)){
  1211. printMsg("\n\n*** MAPPING_TREE - $DN already exists");
  1212. printMsg("\n*** Migration will not add the suffix");
  1213. }
  1214. else {
  1215. addEntryToNew($entry, "MAPPING_TREE",1);
  1216. }
  1217. }
  1218. }
  1219. }
  1220. sub parseMapping_tree{
  1221. my $entry = shift;
  1222. push @Mapping_tree_entries, $entry;
  1223. }
  1224. #############################################################################
  1225. sub migrateDefaultIndexes {
  1226. foreach $index (@default_indexes) {
  1227. my $CN = $index->{cn}[0];
  1228. my $newIndex ;
  1229. if ((! isAsystemIndex($index)) && (! $deniedIndexes{lc($CN)})) {
  1230. if ($newIndex = alreadyExistsInNew($index)) {
  1231. if (! isAsystemIndex($newIndex)) {
  1232. updateEntry($index, "DEFAULT_INDEX", 1, 2);
  1233. }
  1234. }
  1235. else {
  1236. addEntryToNew($index, "DEFAULT_INDEX", 2);
  1237. }
  1238. }
  1239. }
  1240. }
  1241. sub parseDefaultIndex{
  1242. my $index = shift;
  1243. push @default_indexes, $index;
  1244. }
  1245. #############################################################################
  1246. sub migrateIndexes {
  1247. foreach $index (@indexes) {
  1248. my $CN = $index->{cn}[0];
  1249. my $newIndex;
  1250. if ((! isAsystemIndex($index)) && (! $deniedIndexes{lc($CN)}) && (DN !~ /cn=netscaperoot,cn=index/i)){
  1251. if ($newIndex = alreadyExistsInNew($index)) {
  1252. if (! isAsystemIndex($newIndex)) {
  1253. updateEntry($index, "INDEX", 1, 2);
  1254. }
  1255. }
  1256. else {
  1257. addEntryToNew($index, "INDEX", 2);
  1258. }
  1259. }
  1260. }
  1261. }
  1262. sub parseIndex{
  1263. my $index = shift;
  1264. push @indexes, $index;
  1265. }
  1266. #############################################################################
  1267. sub newLDIFplugin {
  1268. my $currentPlugin = shift;
  1269. my $DN = $currentPlugin->getDN(1);
  1270. my $newPlugin = $conn->newEntry() ;
  1271. $newPlugin->setDN($DN);
  1272. foreach $Attr (@pluginAttrs) {
  1273. my @values = $currentPlugin->getValues($Attr);
  1274. $newPlugin->setValues($Attr, @values) if (@values);
  1275. }
  1276. return $newPlugin;
  1277. }
  1278. sub migrateStdPlugin{
  1279. my $plugin = shift;
  1280. my $DN = $plugin->getDN(1);
  1281. my $pluginEnable = "nsslapd-pluginEnabled";
  1282. my $argNum = 0;
  1283. my $argPrefix = "nsslapd-pluginarg";
  1284. my $currentPlugin ;
  1285. if ($currentPlugin = alreadyExistsInNew($plugin, 1)) {
  1286. $plugin = updatePathInPluginArgs($plugin);
  1287. my $pluginEnableValue = $plugin->{$pluginEnable}[0];
  1288. my $cont = 1;
  1289. my $pluginHasChanged = 0;
  1290. my $newPlugin = &newLDIFplugin($currentPlugin);
  1291. if (! $currentPlugin->hasValue($pluginEnable,$pluginEnableValue,1)){
  1292. $newPlugin->setValues($pluginEnable, $pluginEnableValue);
  1293. $pluginHasChanged = 1 unless ($pluginHasChanged);
  1294. }
  1295. while($cont){
  1296. my $arg = $argPrefix . $argNum ;
  1297. if ($plugin->exists($arg)) {
  1298. my @values = $plugin->getValues($arg);
  1299. my $value = $values[0] ;
  1300. $newPlugin->setValues($arg, $value) if (@values);
  1301. if ($currentPlugin->exists($arg)) {
  1302. if (! $currentPlugin->hasValue($arg,$value,1)) {
  1303. $pluginHasChanged = 1 unless ($pluginHasChanged);
  1304. }
  1305. }
  1306. else {
  1307. $pluginHasChanged = 1 unless ($pluginHasChanged);
  1308. }
  1309. }
  1310. else {
  1311. if ($currentPlugin->exists($arg)) {
  1312. # Just Warn the user. Do nothing.
  1313. printTrace("\nCompared to the old instance, the current new plugin $DN belongs this attribute: $arg",2);
  1314. }
  1315. else {
  1316. $cont = 0 ;
  1317. }
  1318. }
  1319. $argNum++;
  1320. }
  1321. updateEntry($newPlugin, "STANDARD_PLUGIN", 0, 1) if ($pluginHasChanged);
  1322. }
  1323. }
  1324. #############################################################################
  1325. sub migrateConfig_Node{
  1326. my $config_node = shift;
  1327. my @params = keys(%GeneralSrvParamToMigrate);
  1328. my $hasChanged = 0;
  1329. my $newConfigNode;
  1330. if ($newConfigNode = alreadyExistsInNew($config_node, 1)){
  1331. foreach $param (@params) {
  1332. if ($config_node->exists($param)){
  1333. my @valuesToMigrate = $config_node->getValues($param);
  1334. if (@valuesToMigrate){
  1335. if ($newConfigNode->exists($param)){
  1336. my @currentValues = $newConfigNode->getValues($param);
  1337. if (Diffs(\@valuesToMigrate, \@currentValues)) {
  1338. $newConfigNode->setValues($param, @valuesToMigrate);
  1339. $hasChanged = 1 unless ($hasChanged);
  1340. printTrace("\nParam to update: $param with value @valuesToMigrate",3);
  1341. }
  1342. }
  1343. else {
  1344. $newConfigNode->setValues($param, @valuesToMigrate);
  1345. $hasChanged = 1 unless ($hasChanged);
  1346. printTrace("\nParam to update: $param with value @valuesToMigrate",3);
  1347. }
  1348. }
  1349. }
  1350. }
  1351. updateEntry($newConfigNode, "CONFIG_NODE", 0, 1) if ($hasChanged);
  1352. }
  1353. }
  1354. #############################################################################
  1355. sub migrateConfig_LDBM_database{
  1356. my $config_ldbm = shift;
  1357. my @params = keys(%GlobalConfigLDBMparamToMigrate);
  1358. my $hasChanged = 0;
  1359. my $newConfigLdbm ;
  1360. if ($newConfigLdbm = alreadyExistsInNew($config_ldbm, 1)) {
  1361. foreach $param (@params) {
  1362. if ($config_ldbm->exists($param)){
  1363. my @valuesToMigrate = $config_ldbm->getValues($param);
  1364. if (@valuesToMigrate){
  1365. if ($newConfigLdbm->exists($param)){
  1366. my @currentValues = $newConfigLdbm->getValues($param);
  1367. if (Diffs(\@valuesToMigrate, \@currentValues)) {
  1368. $newConfigLdbm->setValues($param, @valuesToMigrate);
  1369. $hasChanged = 1 unless ($hasChanged);
  1370. }
  1371. }
  1372. else {
  1373. $newConfigLdbm->setValues($param, @valuesToMigrate);
  1374. $hasChanged = 1 unless ($hasChanged);
  1375. }
  1376. }
  1377. }
  1378. }
  1379. updateEntry($newConfigLdbm, "CONFIG_LDBM_DATABASE", 0, 1) if ($hasChanged);
  1380. }
  1381. }
  1382. #############################################################################
  1383. sub migrateChainingBE_config{
  1384. my $chaining_config = shift;
  1385. my $DN = $chaining_config->getDN(1);
  1386. my @params = ();
  1387. my $hasChanged = 0;
  1388. my $newChainingConfig;
  1389. if ($DN =~ /^cn=config,cn=chaining database,cn=plugins,cn=config$/i){
  1390. $newChainingConfig = searchEntry("cn=config,cn=chaining database,cn=plugins,cn=config");
  1391. @params = keys(%ChainingConfigParams);
  1392. }
  1393. if ($DN =~ /^cn=default instance config,cn=chaining database,cn=plugins,cn=config$/i){
  1394. $newChainingConfig = searchEntry("cn=default instance config,cn=chaining database,cn=plugins,cn=config");
  1395. @params = keys(%ChainingDefaultInstanceConfigParams);
  1396. }
  1397. foreach $param (@params) {
  1398. if ($chaining_config->exists($param)){
  1399. my @valuesToMigrate = $chaining_config->getValues($param);
  1400. if (@valuesToMigrate){
  1401. printTrace("\nParam: $param values To migrate: @valuesToMigrate",3);
  1402. if ($newChainingConfig->exists($param)){
  1403. my @currentValues = $newChainingConfig->getValues($param);
  1404. printTrace("\nParam: $param new current values: @currentValues",3);
  1405. if (Diffs(\@valuesToMigrate, \@currentValues)) {
  1406. $newChainingConfig->setValues($param, @valuesToMigrate);
  1407. $hasChanged = 1 unless ($hasChanged);
  1408. }
  1409. }
  1410. else {
  1411. $newChainingConfig->setValues($param, @valuesToMigrate);
  1412. $hasChanged = 1 unless ($hasChanged);
  1413. }
  1414. }
  1415. }
  1416. }
  1417. updateEntry($newChainingConfig, "CHAINING_BACKEND_CONFIG", 0, 1) if ($hasChanged);
  1418. }
  1419. #############################################################################
  1420. sub registerSuffix_ChainingBE {
  1421. my $ldbmDatabase = shift;
  1422. my $CN = $ldbmDatabase->{cn}[0];
  1423. my $suffixArg = "nsslapd-suffix";
  1424. my $suffix = $ldbmDatabase->{$suffixArg}[0];
  1425. $oldChainingBackends{$suffix} = $CN;
  1426. }
  1427. sub storeMultiplexorBindDN {
  1428. my $chaining_instance = shift;
  1429. my $DN = $chaining_instance->getDN(1);
  1430. if ($chaining_instance->exists("nsMultiplexorBindDN")){
  1431. my $bindDN = $chaining_instance->{nsMultiplexorBindDN}[0];
  1432. my $newBindDN = searchEntry($bindDN);
  1433. if (! $newBindDN){
  1434. # the bindDN entry doesn't yet exist in new => it will have to be migrated
  1435. $MultiplexorBindDNEntriesToMigrate{$bindDN}="\n" ;
  1436. printTrace("\nThe bindDN: $bindDN need to be migrated",3);
  1437. }
  1438. else {
  1439. # do nothing as the entry already exists in new
  1440. }
  1441. }
  1442. }
  1443. sub importMultiplexorBindDNEntries {
  1444. # import all entries present in @MultiplexorBindDNEntriesToMigrate in new
  1445. my @MultiplexorBindDNs = keys (%MultiplexorBindDNEntriesToMigrate);
  1446. my $ldif_dir = $ldif_rep;
  1447. foreach $bindDN (@MultiplexorBindDNs) {
  1448. printTrace("\nimportMultiplexorBindDNEntries: bindDN to migrate: $bindDN",3);
  1449. # get the backend in which is stored the bind DN entry
  1450. my $backendtoExportFrom = getBackendtoExportFrom($bindDN);
  1451. printTrace("\nbackendtoExportFrom is: $backendtoExportFrom",3);
  1452. # check wether the backend has been imported in new or not
  1453. if (! alreadyMigrated($backendtoExportFrom)) {
  1454. if ($backendtoExportFrom ne $NULL) {
  1455. # if not imported => we need to import the binf DN entry
  1456. &startServer() unless (isDirectoryAlive());
  1457. $conn = new Mozilla::LDAP::Conn($LDAPservername,$newport,$rootDN,$rootpwd) or die "\n Unable to contact the $Version.$Minor LDAP server: $LDAPservername\n";
  1458. &ExportAndAddEntry($bindDN, $backendtoExportFrom, $ldif_dir);
  1459. }
  1460. else {
  1461. # do nothing
  1462. }
  1463. }
  1464. }
  1465. # remove the empty ldif directory
  1466. rmdir($ldif_dir) if (-d $ldif_dir);
  1467. # close the LDAP connection to new
  1468. $conn->close if ($conn);
  1469. }
  1470. sub migrateChainingBE_instance{
  1471. my $chaining_instance = shift;
  1472. my $DN = $chaining_instance->getDN(1);
  1473. &registerSuffix_ChainingBE($chaining_instance);
  1474. if (alreadyExistsInNew($chaining_instance)) {
  1475. # already exists
  1476. printMsg("\n\n*** CHAINING_BACKEND_INSTANCE - $DN already exists");
  1477. printMsg("\n*** Migration will not update it");
  1478. }
  1479. else {
  1480. &migrate_credential($chaining_instance, "nsmultiplexorcredentials");
  1481. addEntryToNew($chaining_instance, "CHAINING_BACKEND_INSTANCE", 1);
  1482. storeMultiplexorBindDN($chaining_instance);
  1483. }
  1484. }
  1485. #############################################################################
  1486. # create a new LDIF representation of a new replica consumer
  1487. sub newLDIFreplica {
  1488. my $replica = shift;
  1489. my $DN = $replica->getDN(1);
  1490. my $newReplica = $conn->newEntry() ;
  1491. my $MASTER_OR_MULTIMASTER = "3" ;
  1492. $newReplica->setDN($DN);
  1493. foreach $Attr (@nsds5replicaAttrs) {
  1494. my @values = $replica->getValues($Attr);
  1495. $newReplica->setValues($Attr, @values) if (@values);
  1496. }
  1497. my $replicaType = $replica->{nsDS5ReplicaType}[0];
  1498. if ($replicaType eq $MASTER_OR_MULTIMASTER) {
  1499. my @nsState = $replica->getValues("nsState");
  1500. $newReplica->setValues("nsState", @nsState);
  1501. }
  1502. else {
  1503. $newReplica->setValues("nsDS5ReplicaId", $replicaIdvalue);
  1504. }
  1505. return $newReplica;
  1506. }
  1507. sub MigrateNSDS5_replica{
  1508. foreach $replica (@new6replicas) {
  1509. my $DN = $replica->getDN(1);
  1510. my $newReplica;
  1511. my @removeAttrs = qw(nsstate nsds5replicaname nsds5replicachangecount);
  1512. for (@removeAttrs) {
  1513. $replica->remove($_);
  1514. }
  1515. if (alreadyExistsInNew($replica)) {
  1516. # replica already exists
  1517. printMsg("\n\n*** NSDS5_REPLICA - $DN already exists");
  1518. printMsg("\n*** Migration will not update it");
  1519. }
  1520. else {
  1521. $newReplica = &newLDIFreplica($replica);
  1522. addEntryToNew($newReplica, "NSDS5_REPLICA", 1);
  1523. }
  1524. storeReplicaBindDN($replica);
  1525. }
  1526. }
  1527. sub parseNSDS5_replica{
  1528. my $replica = shift;
  1529. push @new6replicas, $replica;
  1530. }
  1531. sub storeReplicaBindDN {
  1532. my $replica = shift;
  1533. my $DN = $replica->getDN(1);
  1534. if ($replica->exists("nsDS5ReplicaBindDN")){
  1535. my $bindDN = $replica->{nsDS5ReplicaBindDN}[0];
  1536. my $newBindDN = searchEntry($bindDN);
  1537. if (! $newBindDN){
  1538. # the bindDN entry doesn't yet exist in new => it will have to be migrated
  1539. $ReplicaBindDNEntriesToMigrate{$bindDN}="\n" ;
  1540. printTrace("\nThe bindDN: $bindDN need to be migrated",3);
  1541. }
  1542. else {
  1543. # do nothing as the entry already exists in new
  1544. }
  1545. }
  1546. }
  1547. sub importReplicaBindDNEntries {
  1548. # import all entries present in @ReplicaBindDNEntriesToMigrate in new
  1549. my @ReplicaBindDNs = keys (%ReplicaBindDNEntriesToMigrate);
  1550. my $ldif_dir = $ldif_rep;
  1551. my $replBind_entry = "";
  1552. my @bindDN_elements = "";
  1553. my $bindDN_parent = "";
  1554. my $parentBind_entry = "";
  1555. foreach $bindDN (@ReplicaBindDNs) {
  1556. printTrace("\nimportReplicaBindDNEntries: bindDN to migrate: $bindDN",3);
  1557. # get the backend in which is stored the bind DN entry
  1558. my $backendtoExportFrom = getBackendtoExportFrom($bindDN);
  1559. printTrace("\nbackendtoExportFrom is: $backendtoExportFrom",3);
  1560. # If backend is from config, read the entry from dse.ldif and add to new - NGK
  1561. if ($backendtoExportFrom eq "cn=config") {
  1562. my $norm_bindDN = normalizeDN($bindDN);
  1563. @bindDN_elements = ldap_explode_dn($norm_bindDN, 0);
  1564. # @bindDN_elements = split(/,/,$norm_bindDN);
  1565. my $junk = shift(@bindDN_elements);
  1566. if ($#bindDN_elements >= 1) {
  1567. $bindDN_parent = normalizeDN(join(",", @bindDN_elements));
  1568. }
  1569. printTrace("\nOpening DSE.ldif",3);
  1570. open( DSELDIF, "< $oldDSEldif" ) || die "Can't open $oldDSEldif: $!: ";
  1571. my $in = new Mozilla::LDAP::LDIF(*DSELDIF);
  1572. while ($entry = readOneEntry $in) {
  1573. my $DN = $entry->getDN(1);
  1574. if ($DN eq $norm_bindDN) {
  1575. $replBind_entry = $entry;
  1576. }
  1577. if ($bindDN_parent ne "") {
  1578. if ($DN eq $bindDN_parent) {
  1579. $parentBind_entry = $entry;
  1580. }
  1581. }
  1582. }
  1583. close(DSELDIF);
  1584. &startServer() unless (isDirectoryAlive());
  1585. $conn = new Mozilla::LDAP::Conn($LDAPservername,$newport,$rootDN,$rootpwd) or die "\n Unable to contact the $Version.$Minor LDAP server: $LDAPservername\n";
  1586. if ($bindDN_parent ne "") {
  1587. addEntryToNew($parentBind_entry, BINDDN_PARENT, 0);
  1588. }
  1589. printTrace("\nAdding BindDN with addEntryToNew",3);
  1590. addEntryToNew($replBind_entry, BINDDN, 0);
  1591. } else {
  1592. # check wether the backend has been imported in new or not
  1593. if (! alreadyMigrated($backendtoExportFrom)) {
  1594. if ($backendtoExportFrom ne $NULL) {
  1595. # if not imported => we need to import the bind DN entry
  1596. &startServer() unless (isDirectoryAlive());
  1597. $conn = new Mozilla::LDAP::Conn($LDAPservername,$newport,$rootDN,$rootpwd) or die "\n Unable to contact the $Version.$Minor LDAP server: $LDAPservername\n";
  1598. &ExportAndAddEntry($bindDN, $backendtoExportFrom, $ldif_dir);
  1599. }
  1600. else {
  1601. # do nothing
  1602. }
  1603. }
  1604. }
  1605. }
  1606. # remove the empty ldif directory
  1607. rmdir($ldif_dir) if (-d $ldif_dir);
  1608. # close the LDAP connection to new
  1609. $conn->close if ($conn);
  1610. }
  1611. sub alreadyMigrated {
  1612. my $backendToCheck = shift;
  1613. foreach $backend (@BACKENDS) {
  1614. return 1 if ($backend eq $backendToCheck);
  1615. }
  1616. return 0 ;
  1617. }
  1618. sub belongsSuffix {
  1619. my $suffix = shift;
  1620. my $bindDN = shift;
  1621. return ($bindDN =~ /$suffix\s*$/i);
  1622. }
  1623. sub length {
  1624. my $suffix = shift;
  1625. my $count = 0;
  1626. while ($suffix =~ /./g) {
  1627. $count++;
  1628. }
  1629. return $count ;
  1630. }
  1631. sub getBackendtoExportFrom {
  1632. my $bindDN = shift ;
  1633. my $sizeOfSuffix = 0 ;
  1634. my $NULL = "";
  1635. my @oldSuffixes = keys(%oldBackends);
  1636. my @oldChainingSuffixes = keys(%oldChainingBackends);
  1637. my $bindDN_backend = $NULL;
  1638. my $config = "cn=config";
  1639. my $norm_bindDN = normalizeDN($bindDN);
  1640. # Check if bindDN exists in cn=config - NGK
  1641. if (belongsSuffix($config,$norm_bindDN)) {
  1642. $bindDN_backend = $config;
  1643. printTrace("\ngetBackendtoExportFrom: bindDN_backend: $bindDN_backend",3);
  1644. } else {
  1645. foreach $suffix (@oldSuffixes){
  1646. printTrace("\ngetBackendtoExportFrom: suffix to compare with is: $suffix",3);
  1647. if ((belongsSuffix($suffix,$norm_bindDN)) && (length($suffix) > $sizeOfSuffix)) {
  1648. $sizeOfSuffix = length($suffix);
  1649. $bindDN_backend = $oldBackends{$suffix};
  1650. printTrace("\ngetBackendtoExportFrom: bindDN_backend: $bindDN_backend, sizeOfSuffix: $sizeOfSuffix",3);
  1651. }
  1652. }
  1653. foreach $suffix (@oldChainingSuffixes){
  1654. printTrace("\ngetBackendtoExportFrom: suffix to compare with is a chained suffix: $suffix",3);
  1655. if ((belongsSuffix($suffix,$norm_bindDN)) && (length($suffix) > $sizeOfSuffix)) {
  1656. printMsg("\n\n*** Entry stored on a remote backend - $norm_bindDN");
  1657. printMsg("\n*** We don't migrate it");
  1658. return $NULL;
  1659. }
  1660. }
  1661. }
  1662. return $bindDN_backend;
  1663. }
  1664. sub getBackendtoImportTo {
  1665. my $bindDN = shift;
  1666. my $sizeOfSuffix = 0;
  1667. my $NULL = "";
  1668. my $suffixArg = "nsslapd-suffix";
  1669. my $bindDN_backend = $NULL;
  1670. open( DSELDIF, "< $DSEldif" ) || die "Can't open $DSEldif: $!: ";
  1671. my $in = new Mozilla::LDAP::LDIF(*DSELDIF) ;
  1672. while ($entry = readOneEntry $in) {
  1673. $typeOfEntry = getTypeOfEntry($entry);
  1674. if ($typeOfEntry eq "LDBM_BACKEND_INSTANCE"){
  1675. my $suffix = $entry->{$suffixArg}[0];
  1676. if ((belongsSuffix($suffix,$bindDN)) && (length($suffix) > $sizeOfSuffix)) {
  1677. $sizeOfSuffix = length($suffix);
  1678. $bindDN_backend = $entry->{cn}[0];
  1679. }
  1680. }
  1681. }
  1682. close(DSELDIF);
  1683. return $bindDN_backend ;
  1684. }
  1685. sub ExportAndAddEntry {
  1686. my $DN = shift;
  1687. my $backendtoExportFrom = shift;
  1688. my $ldif_dir = shift;
  1689. my $ldif = "$ldif_dir${PATHSEP}$backendtoExportFrom.ldif" ;
  1690. # first: export entry pointed out by the $DN to $ldif file
  1691. $ENV{"$LIB_PATH"}=$old_libpath;
  1692. if (! $ldif_dir) { $ldif_dir = $ldif_rep ;}
  1693. if (!(-d $ldif_dir)) {
  1694. mkdir($ldif_dir,0777) or die "\ncan't create $ldif_dir to store temporary ldif files\n";
  1695. }
  1696. chdir($oldSlapdExecDir) or die "\nCould not change directory to $oldSlapdExecDir: $!\n";
  1697. &db2Ldif($ldif, $backendtoExportFrom, $oldHome, $DN);
  1698. chdir($curdir) or die "\nCould not change directory to $curdir: $!\n";
  1699. # then: Add it to new
  1700. if (! $conn) {
  1701. $conn = new Mozilla::LDAP::Conn($LDAPservername,$newport,$rootDN,$rootpwd) or die "\n Unable to contact the $Version.$Minor LDAP server: $LDAPservername\n";
  1702. }
  1703. open( BINDDNLDIF, "< $ldif" ) || die "\nCan't open $ldif: $!: \n";
  1704. my $in = new Mozilla::LDAP::LDIF(*BINDDNLDIF) ;
  1705. while ($entry = readOneEntry $in) {
  1706. my $entryDN = $entry->getDN(1);
  1707. if ($DN eq $entryDN) {
  1708. addEntryToNew($entry, "nsds5ReplicaBindDN", 0);
  1709. }
  1710. }
  1711. close(BINDDNLDIF);
  1712. # remove the ldif file after the import
  1713. unlink($ldif) ;
  1714. }
  1715. #############################################################################
  1716. sub MigrateNSDS_replication_agreement {
  1717. foreach $replicationAgreement (@replicationAgreements) {
  1718. my $DN = $replicationAgreement->getDN(1);
  1719. if (alreadyExistsInNew($replicationAgreement)){
  1720. # replication agreement already exists
  1721. printMsg("\n\n*** NSDS_REPLICATION_AGREEMENT - $DN already exists");
  1722. printMsg("\n*** Migration will not update it");
  1723. }
  1724. else {
  1725. &migrate_credential($replicationAgreement, "nsDS5ReplicaCredentials");
  1726. addEntryToNew($replicationAgreement, "NSDS_REPLICATION_AGREEMENT", 1);
  1727. }
  1728. }
  1729. }
  1730. sub parseNSDS_replication_agreement{
  1731. my $replicationAgreement = shift;
  1732. push @replicationAgreements, $replicationAgreement ;
  1733. }
  1734. #############################################################################
  1735. sub migrateChangelog5{
  1736. my $changelog = shift;
  1737. my $DN = $changelog->getDN(1);
  1738. my $changelogdir = "nsslapd-changelogdir";
  1739. if (alreadyExistsInNew($changelog)){
  1740. # cn=changelog5,cn=config already exists in new
  1741. my $newChangelog = searchEntry($DN);
  1742. my @newChangelogdir = $newChangelog->getValues($changelogdir);
  1743. $changelog->setValues($changelogdir, @newChangelogdir);
  1744. updateEntry($changelog, "CHANGELOG5", 0, 1);
  1745. }
  1746. else {
  1747. # cn=changelog5,cn=config need to be created in new.
  1748. # the changelogdir value must be setup to <new_root_server>/slapd-instance/changelogdb
  1749. $changelog->setValues($changelogdir,"${serverHome}${PATHSEP}changelogdb");
  1750. addEntryToNew($changelog, "CHANGELOG5", 1);
  1751. }
  1752. }
  1753. sub migrateChangelog {
  1754. my $oldchangelogdir = "";
  1755. my $newchangelogdir = "";
  1756. my $changelogdir = "nsslapd-changelogdir";
  1757. my $CL5DN = "cn=changelog5,cn=config";
  1758. printTrace("\n\n***** Migrate Changelog...",0,1);
  1759. open( DSELDIF, "< $oldDSEldif" ) || die "Can't open $oldDSEldif: $!: ";
  1760. my $in = new Mozilla::LDAP::LDIF(*DSELDIF);
  1761. while ($entry = readOneEntry $in) {
  1762. $typeOfEntry = getTypeOfEntry($entry);
  1763. if ($typeOfEntry eq "CHANGELOG5"){
  1764. $oldchangelogdir = ($entry->getValues($changelogdir))[0];
  1765. }
  1766. }
  1767. close(DSELDIF);
  1768. if ($oldchangelogdir) {
  1769. # If using olddatadir to migrate from, the path of the changelogdb
  1770. # from the dse.ldif may not match the path where the old server
  1771. # root was archived. We may need to modify oldchangelogdir so the
  1772. # copy of the changelog files succeeds.
  1773. unless(-e $oldchangelogdir) {
  1774. if($olddatadir) {
  1775. my @cldbpath = split(/\//,$oldchangelogdir);
  1776. until($cldbpath[0] =~/^slapd-/) {
  1777. shift(@cldbpath);
  1778. }
  1779. my $tmpcldbpath = join(${PATHSEP}, @cldbpath);
  1780. $oldchangelogdir = "$oldDir${PATHSEP}$tmpcldbpath";
  1781. }
  1782. # If oldchangelogdir still looks to be wrong, prompt for the
  1783. # location instead of just failing on the copydir operation
  1784. # and bombing out of the migration.
  1785. unless(-e $oldchangelogdir) {
  1786. print("\n\nThe old changelog directory \"$oldchangelogdir\" doesn't exist. Please enter the correct path: ");
  1787. $oldchangelogdir = <STDIN>;
  1788. }
  1789. }
  1790. &startServer() unless (isDirectoryAlive());
  1791. $conn = new Mozilla::LDAP::Conn($LDAPservername,$newport,$rootDN,$rootpwd) or die "\n Unable to contact the $Version.$Minor LDAP server: $LDAPservername\n";
  1792. my $newChangelog = searchEntry($CL5DN);
  1793. $newchangelogdir = ($newChangelog->getValues($changelogdir))[0];
  1794. stopServer($root,'slapd-'.$newname);
  1795. printTrace("\ncopying $oldchangelogdir${PATHSEP}* to $newchangelogdir",3);
  1796. copyDir("$oldchangelogdir","$newchangelogdir");
  1797. # We need to modify the DBVERSION file for a new verision of the db
  1798. open(DBVERSION,">$newchangelogdir${PATHSEP}DBVERSION") || die "Can't overwrite $newchangelogdir${PATHSEP}DBVERSION: $! ";
  1799. print DBVERSION "Changelog5/NSMMReplicationPlugin/3.0";
  1800. close(DBVERSION);
  1801. &startServer() unless (isDirectoryAlive());
  1802. }
  1803. }
  1804. #############################################################################
  1805. sub migrateReplication{
  1806. my $replication = shift;
  1807. my $DN = $replication->getDN(1);
  1808. if (alreadyExistsInNew($replication)){
  1809. # replication agreement already exists
  1810. printMsg("\n\n*** $DN already exists");
  1811. printMsg("\n*** Migration will not update it");
  1812. }
  1813. else {
  1814. addEntryToNew($replication, "REPLICATION", 1);
  1815. }
  1816. }
  1817. #############################################################################
  1818. sub migrateSecurity{
  1819. my $security = shift;
  1820. if ($entry->hasValue("objectClass", "nsEncryptionConfig")) {
  1821. my $certfile = "alias/slapd-" . $newname . "-cert8.db";
  1822. my $keyfile = "alias/slapd-" . $newname. "-key3.db";
  1823. $entry->setValues("nsCertfile",$certfile) if ! $entry->hasValue("nsCertfile",$certfile);
  1824. $entry->setValues("nsKeyfile",$keyfile) if ! $entry->hasValue("nsKeyfile",$keyfile);
  1825. }
  1826. if (alreadyExistsInNew($security)){
  1827. # already exists in new
  1828. updateEntry($security, "SECURITY", 0, 1);
  1829. }
  1830. else {
  1831. addEntryToNew($security, "SECURITY", 1);
  1832. }
  1833. }
  1834. #############################################################################
  1835. sub migrateSNMP{
  1836. my $snmp = shift;
  1837. if (alreadyExistsInNew($snmp)){
  1838. # already exists in new
  1839. updateEntry($snmp, "SNMP", 0, 1);
  1840. }
  1841. else {
  1842. addEntryToNew($snmp, "SNMP", 1);
  1843. }
  1844. }
  1845. #############################################################################
  1846. # printMsg print message to the user standard output.
  1847. sub printMsg {
  1848. my $TypeMsg = shift ;
  1849. my $Msg = shift ;
  1850. my $LineNb = shift ;
  1851. if ($LineNb) {
  1852. printTrace("Line: $LineNb, $TypeMsg, $Msg");
  1853. }
  1854. else {
  1855. printTrace("$TypeMsg $Msg");
  1856. }
  1857. }
  1858. #############################################################################
  1859. # print message error to the user standard output.
  1860. sub printTrace {
  1861. my $Msg = shift ;
  1862. my $level = shift ;
  1863. my $sep = shift ;
  1864. if ($sep) {
  1865. print "\n-------------------------------------------------------------------------";
  1866. print LOGFILE "\n-------------------------------------------------------------------------";
  1867. }
  1868. if ($level <= $TRACELEVEL) {
  1869. print($Msg);
  1870. print LOGFILE $Msg ;
  1871. }
  1872. }
  1873. #############################################################################
  1874. # this subroutine implements a very stupid version of diff
  1875. sub diff {
  1876. my $f1 = shift;
  1877. my $f2 = shift;
  1878. my $lineToBeginWith = shift;
  1879. my $NULL = "" ;
  1880. my $diff_f1 = $NULL ;
  1881. my $diff_f2 = $NULL ;
  1882. my $retval = $NULL ;
  1883. my $ret;
  1884. open(F1, "$f1") or die "Could not open file $f1";
  1885. open(F2, "$f2") or close(F1), die "Could not open file $f2";
  1886. while (defined($l1 = <F1>)) {
  1887. if ($lineToBeginWith){
  1888. $lineToBeginWith -- ;
  1889. next ;
  1890. }
  1891. next if ($l1 =~ /^\#/);
  1892. $ret = defined($l2 = <F2>);
  1893. if ($ret) {
  1894. $ret = defined($l2 = <F2>) while ($ret && ($l2 =~ /^\#/)) ;
  1895. if ($ret) {
  1896. if (!($l1 eq $l2)) {
  1897. # ignore whitespace
  1898. $l1_clean = $l1 ;
  1899. $l2_clean = $l2 ;
  1900. $l1_clean =~ s/\s//g;
  1901. $l2_clean =~ s/\s//g;
  1902. if (!($l1_clean eq $l2_clean)) {
  1903. $diff_f1 .= "${l1}" unless ($l1_clean eq $NULL);
  1904. $diff_f2 .= "${l2}" unless ($l2_clean eq $NULL);
  1905. }
  1906. }
  1907. }
  1908. else {
  1909. next if ($l1 =~ /^\s*$/) ;
  1910. $diff_f1 .= "${l1}";
  1911. }
  1912. }
  1913. else {
  1914. next if ($l1 =~ /^\s*$/) ;
  1915. $diff_f1 .= "${l1}";
  1916. }
  1917. }
  1918. while (defined($l2 = <F2>)) {
  1919. if (($l2 =~ /^\#/) || ($l2 =~ /^\s*$/)) {
  1920. next ;
  1921. }
  1922. else {
  1923. $diff_f2 .= "${l2}" ;
  1924. }
  1925. }
  1926. close(F1);
  1927. close(F2);
  1928. $retval .= "- differences present in your config file but not in standard file:\n\n". "$diff_f1\n" if ($diff_f1) ;
  1929. $retval .= "- differences present in standard file but not in your config file:\n\n" . "$diff_f2" if ($diff_f2) ;
  1930. return $retval ;
  1931. }
  1932. sub CompareStdConfigFiles {
  1933. # Compare each configuration file against its default version. If it has changed,
  1934. # notify the user that the file has changed and will need to be checked by the
  1935. # user. This should be safe to do because there should be no path information
  1936. # stored in these conf files, which are just schema stuff.
  1937. # printTrace("\nCheck if standard configuration files have changed",3);
  1938. # get the version of the DS to migrate
  1939. ($oldVersion, $oldMinor) = &getVersion($oldDir, $oldversionstr);
  1940. # get the version of the new DS
  1941. ($Version, $Minor) = &getVersion($root);
  1942. # get old LIB_PATH
  1943. $old_libpath = &getLibPath($oldDir, $oldVersion, $oldMinor);
  1944. # get new LIB_PATH
  1945. $new_libpath = &getLibPath($root, $Version, $Minor);
  1946. my $origFilePath = "$oldDir${PATHSEP}bin${PATHSEP}slapd${PATHSEP}install${PATHSEP}schema${PATHSEP}" ;
  1947. my $FilesChanged = "";
  1948. my $AllDiffs = "***********************************************************************";
  1949. my $NoChanges = "" ;
  1950. my $lineToBegin = 0 ;
  1951. opendir(CONFDIR, $oldSchemaDir) or
  1952. die "Error: could not open migrated config dir $oldConfDir: $!";
  1953. foreach $file (readdir(CONFDIR)) {
  1954. $origFile = $origFilePath . $file ;
  1955. $configFile = $oldSchemaDir . $file ;
  1956. if (( exists($stdIncludes{lc($file)})) && (-f $origFile)) {
  1957. $diffs = &diff($configFile, $origFile, $lineToBegin);
  1958. $lineToBegin = 0 if $lineToBegin ;
  1959. if ($diffs) {
  1960. $FilesChanged .= "\n$configFile";
  1961. $AllDiffs .= "\n$configFile is different than the standard configuration file" ;
  1962. $AllDiffs .= "\nYou will need to check this file and make sure its changes are compatible ";
  1963. $AllDiffs .= "with the new directory server\nHere are the differences:\n";
  1964. $AllDiffs .= "$diffs \n\n";
  1965. $AllDiffs .= "***********************************************************************";
  1966. }
  1967. else {
  1968. $NoChanges .= "\n$configFile";
  1969. }
  1970. }
  1971. }
  1972. closedir(CONFDIR);
  1973. if ($FilesChanged) {
  1974. printTrace("\nNo changes to old configuration files:$NoChanges",3) ;
  1975. printTrace("\n***********************************************************************",3) ;
  1976. printMsg("\nThe following standard files have been modified: $FilesChanged");
  1977. if ($NO_INPUT_USER) {
  1978. # do nothing
  1979. }
  1980. else {
  1981. printMsg("\nDo you want to see the differences Yes/No [No] ?") ;
  1982. my $answer = <STDIN> ;
  1983. if ($answer =~ /y|yes/i) {
  1984. printMsg("$AllDiffs");
  1985. }
  1986. printMsg("\nDo you want to continue the migration Yes/No [No] ?");
  1987. $answer = <STDIN> ;
  1988. if (! ($answer =~ /y|yes/i)) {
  1989. exit(1);
  1990. }
  1991. }
  1992. }
  1993. }
  1994. #############################################################################
  1995. # this is used to run the system() call, capture exit and signal codes,
  1996. # and die() upon badness; the first argument is a directory to change
  1997. # dir to, if any, and the rest are passed to system()
  1998. sub mySystem {
  1999. my $rc = &mySystemNoDie(@_);
  2000. my ($dir, @args) = @_;
  2001. if ($rc == 0) {
  2002. # success
  2003. } elsif ($rc == 0xff00) {
  2004. die "Error executing @args: error code $rc: $!";
  2005. } elsif ($rc > 0x80) {
  2006. $rc >>= 8;
  2007. die "Error executing @args: error code $rc: $!";
  2008. } else {
  2009. if ($rc & 0x80) {
  2010. $rc &= ~0x80;
  2011. }
  2012. die "Error executing @args: received signal $rc: $!";
  2013. }
  2014. # usually won't get return value
  2015. return $rc;
  2016. }
  2017. # This version does not die but just returns the error code
  2018. sub mySystemNoDie {
  2019. my ($dir, @args) = @_;
  2020. if ($dir && ($dir ne "")) {
  2021. chdir($dir) or die "Could not change directory to $dir: $!";
  2022. }
  2023. my $cmd = $args[0];
  2024. # the system {$cmd} avoids some NT shell quoting problems if the $cmd
  2025. # needs to be quoted e.g. contains spaces; the map puts double quotes
  2026. # around the arguments on NT which are stripped by the command
  2027. # interpreter cmd.exe; but don't quote things which are already quoted
  2028. my @fixargs = map { /^[\"].*[\"]$/ ? $_ : $quote . $_ . $quote } @args;
  2029. my $rc = 0;
  2030. if ($cmd =~ /[.](bat|cmd)$/) {
  2031. # we have to pass batch files directly to the NT command interpreter
  2032. $cmd = $com_spec;
  2033. # print "system $cmd /c \"@fixargs\"\n";
  2034. $rc = 0xffff & system {$cmd} '/c', "\"@fixargs\"";
  2035. } else {
  2036. # print "system $cmd @fixargs\n";
  2037. $rc = 0xffff & system {$cmd} @fixargs;
  2038. }
  2039. chdir(${curdir}) or die "Could not change directory to $curdir: $!";
  2040. return $rc;
  2041. }
  2042. ###########################################################################################
  2043. # #
  2044. # Export/Import of the backends in @BACKENDS #
  2045. # #
  2046. ###########################################################################################
  2047. sub manydb2Ldif {
  2048. my $ldif_dir = shift;
  2049. $ENV{"$LIB_PATH"}=$old_libpath;
  2050. if (! $ldif_dir) { $ldif_dir = $ldif_rep ;}
  2051. if (!(-d $ldif_dir)) {
  2052. mkdir($ldif_dir,0777) or die "can't create $ldif_dir to store temporary ldif files";
  2053. }
  2054. chdir($oldSlapdExecDir) or die "Could not change directory to $oldSlapdExecDir: $!";
  2055. foreach $backend (@BACKENDS) {
  2056. my $ldif = "${ldif_dir}$backend.ldif" ;
  2057. &db2Ldif($ldif, $backend, $oldHome);
  2058. }
  2059. print " Done.\n";
  2060. chdir($curdir) or die "Could not change directory to $curdir: $!";
  2061. }
  2062. sub db2Ldif {
  2063. my $ldif = shift ;
  2064. my $backend = shift ;
  2065. my $home = shift ;
  2066. my $include_suffix = shift ;
  2067. my $db2ldif_param ;
  2068. if ($include_suffix) {
  2069. $db2ldif_param = "db2ldif -r -D $home -n $backend -a $ldif -s \"$include_suffix\"";
  2070. }
  2071. else {
  2072. $db2ldif_param = "db2ldif -r -D $home -n $backend -a $ldif";
  2073. }
  2074. open(DB2LDIF, "${quote}${quote}$slapdExecName${quote} $db2ldif_param${quote} 2>&1 |") or die "Could not run ns-slapd program $ldif2db_exe\n";
  2075. sleep(1); # allow some data to accumulate in the pipe
  2076. my $ii = 0;
  2077. while (<DB2LDIF>) {
  2078. ++$ii;
  2079. if (($ii % 250) == 0) {
  2080. printMsg(" Processing...\n");
  2081. }
  2082. printMsg($_);
  2083. }
  2084. close(DB2LDIF);
  2085. # set the ownership of the ldif file; should be the same as the 5.x slapd user id
  2086. if ((! $isNt) && ($oldlocaluser ne $localuser)) {
  2087. if (-f $ldif) {
  2088. chown( $newuid, $newgid, $ldif) or printMsg("\nUnable to change the ownership of $ldif to $localuser") ;
  2089. }
  2090. }
  2091. }
  2092. sub manyLdif2db {
  2093. my $ldif_dir = shift;
  2094. $ENV{"$LIB_PATH"}=$new_libpath;
  2095. chdir($slapdExecDir) or die "Could not change directory to $slapdExecDir: $!";
  2096. foreach $backend (@BACKENDS) {
  2097. my $ldif = "${ldif_dir}$backend.ldif" ;
  2098. &Ldif2db($ldif, $backend);
  2099. }
  2100. # remove the empty ldif directory
  2101. # but not if using the data dir
  2102. if (!$olddatadir) {
  2103. rmdir($ldif_dir);
  2104. }
  2105. chdir($curdir) or die "Could not change directory to $curdir: $!";
  2106. }
  2107. sub Ldif2db {
  2108. my $ldif = shift ;
  2109. my $backend = shift ;
  2110. my $ldif2db_param = "ldif2db -D $serverHome -n $backend -i $ldif";
  2111. open(LDIF2DB, "${quote}${quote}$slapdExecName${quote} $ldif2db_param${quote} 2>&1 |") or die "Could not run ns-slapd program $ldif2db_exe\n";
  2112. sleep(1); # allow some data to accumulate in the pipe
  2113. while (<LDIF2DB>) {
  2114. printMsg($_);
  2115. }
  2116. close(LDIF2DB);
  2117. # remove the ldif file after the import
  2118. # but not if using the data dir
  2119. if (!$olddatadir) {
  2120. unlink($ldif) ;
  2121. }
  2122. }
  2123. ###########################################################################################
  2124. # #
  2125. # Running/Stopping the Server #
  2126. # #
  2127. ###########################################################################################
  2128. sub isDirectoryAlive {
  2129. die "\n Migration aborted. Make sure your old and new Directory Servers are installed on the same machine \n" if ( $LDAPservername == -1 );
  2130. my $test_conn = new Mozilla::LDAP::Conn($LDAPservername,$newport,$rootDN,$rootpwd);
  2131. if ($test_conn) {
  2132. $test_conn->close();
  2133. return 1;
  2134. }
  2135. else {
  2136. return 0 ;
  2137. }
  2138. }
  2139. sub startServer {
  2140. my $instanceDir = ${serverHome} ;
  2141. my $errLog = $instanceDir . $PATHSEP . 'logs' . $PATHSEP . 'errors';
  2142. # emulate tail -f
  2143. # if the last line we see does not contain "slapd started", try again
  2144. my $done = 0;
  2145. my $started = 0;
  2146. my $code = 0;
  2147. my $lastLine = "";
  2148. my $timeout = time + 240; # 4 minutes
  2149. $ENV{"$LIB_PATH"}=$new_libpath;
  2150. my $startCmd = $instanceDir . $PATHSEP . 'start' . $script_suffix;
  2151. if (! -f $startCmd) {
  2152. $startCmd = $instanceDir . $PATHSEP . 'start-slapd' . $script_suffix;
  2153. }
  2154. $code = &mySystem($instanceDir,$startCmd);
  2155. open(IN, $errLog) or die "Could not open error log $errLog: $!";
  2156. my $pos = tell(IN);
  2157. while (($done == 0) && (time < $timeout)) {
  2158. for (; ($done == 0) && ($_ = <IN>); $pos = tell(IN)) {
  2159. $lastLine = $_;
  2160. # print;
  2161. # the server has already been started and shutdown once . . .
  2162. if (/slapd started\./) {
  2163. $started++;
  2164. if ($started == 2) {
  2165. $done = 1;
  2166. }
  2167. # sometimes the server will fail to come up; in that case, restart it
  2168. } elsif (/Initialization Failed/) {
  2169. # print "Server failed to start: $_";
  2170. $code = &mySystem($instanceDir, $startCmd);
  2171. # sometimes the server will fail to come up; in that case, restart it
  2172. } elsif (/exiting\./) {
  2173. # print "Server failed to start: $_";
  2174. #$code = &mySystem($startCmd);
  2175. $code = &mySystem($instanceDir, $startCmd);
  2176. }
  2177. }
  2178. if ($lastLine =~ /PR_Bind/) {
  2179. # server port conflicts with another one, just report and punt
  2180. print $lastLine;
  2181. print "This server cannot be started until the other server on this\n";
  2182. print "port is shutdown.\n";
  2183. $done = 1;
  2184. }
  2185. if ($done == 0) {
  2186. # rest a bit, then . . .
  2187. sleep(2);
  2188. # . . . reset the EOF status of the file desc
  2189. seek(IN, $pos, 0);
  2190. }
  2191. }
  2192. close(IN);
  2193. sleep(5);
  2194. die "\nUnable to start the $Version.$Minor Directory Server\n" unless (isDirectoryAlive());
  2195. return 0;
  2196. }
  2197. sub stopServer {
  2198. my $root = shift;
  2199. my $name = shift;
  2200. $maxStopIterations = 5;
  2201. print "\nShutting down server $name . . .\n";
  2202. $ENV{"$LIB_PATH"}=$new_libpath;
  2203. $stopCmd = $quote . $root . $PATHSEP . $name . $PATHSEP . 'stop' . $script_suffix . $quote;
  2204. if (! -f $stopCmd) {
  2205. $stopCmd = $quote . $root . $PATHSEP . $name . $PATHSEP . 'stop-slapd' . $script_suffix . $quote;
  2206. }
  2207. if (! -f $stopCmd) {
  2208. # no stop command, probably a 1.X system; for NT, we'll try net stop
  2209. # for unix, we'll get the pid and kill it
  2210. if ($isNT) {
  2211. $stopCmd = 'net stop ' . $name;
  2212. } else {
  2213. # see if there is a pid file
  2214. $pidfile = $root . $PATHSEP . $name . $PATHSEP . 'logs' .
  2215. $PATHSEP . 'pid';
  2216. if (open(PIDFILE, $pidfile)) {
  2217. chomp($pid = <PIDFILE>);
  2218. close(PIDFILE);
  2219. while ($maxStopIterations-- && !$exitCode) {
  2220. $exitCode = kill(15, $pid);
  2221. }
  2222. $stopCmd = undef;
  2223. }
  2224. }
  2225. }
  2226. # keep looping until the stop cmd returns an error code, which usually
  2227. # means that what ever we want to stop is stopped, or some other error
  2228. # occurred e.g. permission, or no such service
  2229. $exitCode = &runAndIgnoreOutput($stopCmd);
  2230. # print "stopServer: exitCode=$exitCode\n";
  2231. while ($stopCmd && $maxStopIterations-- && $exitCode) {
  2232. $exitCode = &runAndIgnoreOutput($stopCmd);
  2233. # print "stopServer: exitCode=$exitCode\n";
  2234. }
  2235. if (!$maxStopIterations) {
  2236. print "Warning: could not shutdown the server: $!\n";
  2237. }
  2238. sleep(10) ;
  2239. $exitCode = 0;
  2240. }
  2241. sub runAndIgnoreOutput {
  2242. my $cmd = shift;
  2243. printMsg(".");
  2244. open(RUNCMD, "${quote}$cmd${quote} 2>&1 |") or die "Error: could not run $cmd: $!";
  2245. printMsg(".");
  2246. sleep(1); # allow pipe to fill with data
  2247. printMsg(".");
  2248. while (<RUNCMD>) {
  2249. # print;
  2250. }
  2251. my $code = close(RUNCMD);
  2252. # print "runAndIgnore: code=$code status=$?\n";
  2253. return $?;
  2254. }
  2255. #############################################################################
  2256. # migrate SSL info
  2257. sub MigrateSSL {
  2258. my $secPwd = 'bidon' ;
  2259. # copy the SSL directory
  2260. &copyDir("$oldHome${PATHSEP}ssl","$serverHome${PATHSEP}ssl") if (-d "$oldHome${PATHSEP}ssl");
  2261. # copy the cert db and key files
  2262. if ( -d "$oldDir${PATHSEP}alias") {
  2263. $aliasDir = "$root${PATHSEP}alias";
  2264. if (! -d $aliasDir) {
  2265. mkdir($aliasDir, 0750);
  2266. }
  2267. &stopServer($root,'slapd-'.$newname);
  2268. my $keydb = "$aliasDir${PATHSEP}slapd-$newname-key3.db" ;
  2269. my $certdb = "$aliasDir${PATHSEP}slapd-$newname-cert8.db" ;
  2270. my $certdb7 = "$aliasDir${PATHSEP}slapd-$newname-cert7.db" ;
  2271. my $old_keydb = "$oldDir${PATHSEP}alias${PATHSEP}slapd-$oldname-key3.db" ;
  2272. my $old_certdb = "$oldDir${PATHSEP}alias${PATHSEP}slapd-$oldname-cert7.db";
  2273. my $keydb_backup = "$aliasDir${PATHSEP}slapd-$newname-key3.db_backup" ;
  2274. my $certdb_backup = "$aliasDir${PATHSEP}slapd-$newname-cert7.db_backup" ;
  2275. if (-f $old_keydb) {
  2276. if (-f $keydb) {
  2277. if ($NO_INPUT_USER) {
  2278. printMsg("\n$keydb already exists. backup in $keydb_backup ...");
  2279. &copyBinFile($keydb,$keydb_backup);
  2280. &copyBinFile($old_keydb,$keydb);
  2281. }
  2282. else {
  2283. print("\n\n$keydb already exists. Do you want to overwrite it ? [no]: ");
  2284. my $answer = <STDIN> ;
  2285. if ($answer =~ /^y|yes$/i) {
  2286. &copyBinFile($old_keydb,$keydb);
  2287. }
  2288. }
  2289. }
  2290. else {
  2291. &copyBinFile($old_keydb,$keydb);
  2292. }
  2293. }
  2294. if (-f $old_certdb) {
  2295. $mode = (stat($old_certdb))[2] if $PRESERVE;
  2296. if (-f $certdb) {
  2297. if ($NO_INPUT_USER) {
  2298. printMsg("\n$certdb already exists. backup in $certdb_backup ...");
  2299. &copyBinFile($certdb,$certdb_backup);
  2300. unlink($certdb) || print "Couldn't delete $certdb : $!\n";
  2301. &copyBinFile($old_certdb,$certdb7);
  2302. }
  2303. else {
  2304. print("\n\n$certdb already exists. Do you want to overwrite it ? [no]: ");
  2305. my $answer = <STDIN> ;
  2306. if ($answer =~ /^y|yes$/i) {
  2307. unlink($certdb) || print "Couldn't delete $certdb : $!\n";
  2308. &copyBinFile($old_certdb,$certdb7);
  2309. }
  2310. }
  2311. }
  2312. else {
  2313. &copyBinFile($old_certdb,$certdb7);
  2314. }
  2315. }
  2316. # copy the old password file
  2317. if (-f "$oldDir${PATHSEP}alias${PATHSEP}$type-$oldname-pin.txt") {
  2318. &copyBinFile(
  2319. "$oldDir${PATHSEP}alias${PATHSEP}$type-$oldname-pin.txt",
  2320. "$aliasDir${PATHSEP}$type-$newname-pin.txt"
  2321. );
  2322. }
  2323. &startServer();
  2324. if ($PRESERVE) {
  2325. chown($newuid,$newgid,$certdb) || print "Failed to set uid $newuid gid $newgid on $certdb : $!\n";
  2326. chmod($mode,$certdb) || print "Failed to set mode $mode on $certdb : $!\n";
  2327. }
  2328. }
  2329. }
  2330. sub DisableSSL {
  2331. my $entry = $conn->search("cn=config","base","objectclass=*");
  2332. my $LDAPparam = "nsslapd-security" ;
  2333. my $Value = "off" ;
  2334. if ($entry->{$LDAPparam}[0] ne $Value) {
  2335. printTrace("\nDisable SSL...",1);
  2336. $entry->setValues($LDAPparam, $Value);
  2337. }
  2338. my $res = $conn->update($entry);
  2339. if ($res) {
  2340. printTrace("\nSSL disabled",2);
  2341. }
  2342. else {
  2343. printMsg("\nCan't disabled SSL. The server may have problems to start");
  2344. }
  2345. }
  2346. # enable the migration of client authentication informations
  2347. sub MigrateCertmap {
  2348. # backup the old certmap.conf and replace it with the new one
  2349. my $oldCertmap = "$oldDir${PATHSEP}shared${PATHSEP}config${PATHSEP}certmap.conf";
  2350. my $newCertmap = "$root${PATHSEP}shared${PATHSEP}config${PATHSEP}certmap.conf" ;
  2351. my $backupCertmap = "$root${PATHSEP}shared${PATHSEP}config${PATHSEP}certmap.conf_backup" ;
  2352. if (-f $oldCertmap) {
  2353. if ($NO_INPUT_USER) {
  2354. printMsg("\n$newCertmap has been backup in $backupCertmap");
  2355. &copyBinFile($newCertmap,$backupCertmap);
  2356. &copyBinFile($oldCertmap,$newCertmap);
  2357. }
  2358. else {
  2359. my $Ask = 1 ;
  2360. while ($Ask) {
  2361. printMsg("\n\nWhere do you want to back up the file $newCertmap [$backupCertmap] ?") ;
  2362. my $Answer = <STDIN> ;
  2363. $backupCertmap = $Answer if ($Answer ne "\n");
  2364. chomp($backupCertmap);
  2365. printTrace("\nDest: .$backupCertmap.",4);
  2366. if (-e $backupCertmap) {
  2367. printMsg("\n\n$backupCertmap already exists. Do you want to overwrite it Yes/No [No] ?") ;
  2368. if (<STDIN> =~ /yes|y/i) {
  2369. $Ask = 0 ;
  2370. }
  2371. else {
  2372. $backupCertmap = "$root${PATHSEP}shared${PATHSEP}config${PATHSEP}certmap.conf_backup" ;
  2373. }
  2374. }
  2375. else {
  2376. $Ask = 0 ;
  2377. }
  2378. }
  2379. printTrace("\nBackup file: $newCertmap in $backupCertmap",4);
  2380. &copyBinFile($newCertmap,$backupCertmap);
  2381. &copyBinFile($oldCertmap,$newCertmap);
  2382. }
  2383. }
  2384. else {
  2385. }
  2386. }
  2387. sub hasChangedoldCertmap {
  2388. my $certmapfile = shift ;
  2389. my @reference = ("certmap default default",
  2390. "default:DNComps",
  2391. "default:FilterComps e") ;
  2392. my $cpt = 0 ;
  2393. printTrace("\nhasChangedoldCertmap",3);
  2394. open(CERTMAP,"< $certmapfile");
  2395. while (<CERTMAP>) {
  2396. if ((! /^\s*#/) && (! /^\s*$/)) {
  2397. my $ref = $reference[$cpt] ;
  2398. printTrace("\nValue: $_, ref: $ref",4);
  2399. if (! /^\s*$ref\s*$/) {
  2400. return 1 ;
  2401. }
  2402. else {
  2403. $cpt++ ;
  2404. }
  2405. }
  2406. }
  2407. close (CERTMAP);
  2408. printTrace("\ncpt: $cpt",4);
  2409. if ($cpt < $#reference) {
  2410. return 1 ;
  2411. }
  2412. else {
  2413. return 0 ;
  2414. }
  2415. }
  2416. ###########################################################################################
  2417. # #
  2418. # Copy directory and files functions #
  2419. # #
  2420. ###########################################################################################
  2421. sub copyDir {
  2422. my $src = shift;
  2423. my $dest = shift;
  2424. my $exclude = shift;
  2425. opendir( SRC, $src ) or die "Can't open directory $src: $!: ";
  2426. my $mode;
  2427. my $uid;
  2428. my $gid;
  2429. mkdir ( $dest , 0755 ) or die "\nCan't create directory $dest. \nPlease check you have enough rights to create it and/or check that your parent directory exists.\n" if !( -e $dest );
  2430. if ($PRESERVE) {
  2431. $mode = (stat($src))[2];
  2432. ($uid, $gid) = (stat(_))[4..5];
  2433. # Make sure files owned by the old user are owned by the
  2434. # new user
  2435. if ($uid == $olduid) {
  2436. $uid = $newuid;
  2437. $gid = $newgid;
  2438. }
  2439. chown $uid, $gid, $dest;
  2440. chmod $mode, $dest;
  2441. }
  2442. local ( @files ) = readdir ( SRC );
  2443. closedir( SRC );
  2444. for ( @files ) {
  2445. if ( $_ eq "." || $_ eq ".." ) {
  2446. next;
  2447. } elsif ( $exclude && /$exclude/ ) {
  2448. next;
  2449. } elsif( -d "$src${PATHSEP}$_") {
  2450. &copyDir ( "$src${PATHSEP}$_", "$dest${PATHSEP}$_" );
  2451. } else {
  2452. &copyBinFile ( "$src${PATHSEP}$_", "$dest${PATHSEP}$_");
  2453. }
  2454. }
  2455. }
  2456. sub copyBinFile {
  2457. my $src = shift;
  2458. my $dest = shift;
  2459. my $buf = "";
  2460. my $bufsize = 8192;
  2461. open( SRC, $src ) || die "Can't open $src: $!\n";
  2462. # if we are given a directory destination instead of a file, extract the
  2463. # filename portion of the source to use as the destination filename
  2464. if (-d $dest) {
  2465. $dest = $dest . $PATHSEP . &basename($src);
  2466. }
  2467. open( DEST, ">$dest" ) || die "Can't create $dest: $!\n";
  2468. binmode SRC;
  2469. binmode DEST;
  2470. if ($PRESERVE) {
  2471. $mode = (stat($src))[2];
  2472. ($uid, $gid) = (stat(_))[4..5];
  2473. # Make sure files owned by the old user are owned by the
  2474. # new user
  2475. if ($uid == $olduid) {
  2476. $uid = $newuid;
  2477. $gid = $newgid;
  2478. }
  2479. chown $uid, $gid, $dest;
  2480. chmod $mode, $dest;
  2481. }
  2482. while (read(SRC, $buf, $bufsize)) {
  2483. print DEST $buf;
  2484. }
  2485. close( SRC );
  2486. close( DEST );
  2487. }
  2488. #############################################################################################################
  2489. # backup 5.x configuration files #
  2490. # backup the directory <root_server5>/slapd-instance/config dans <root_server5>/slapd-instance/BackupConfig # #
  2491. # #
  2492. #############################################################################################################
  2493. sub backupConfigFiles {
  2494. # backup the 5.x config files
  2495. my $src = "$serverHome${PATHSEP}config" ;
  2496. my $dest = "$serverHome${PATHSEP}config_backup" ;
  2497. if ($NO_INPUT_USER) {
  2498. printMsg("\n$src has been backup in $dest");
  2499. &copyDir($src,$dest);
  2500. }
  2501. else {
  2502. my $Ask = 1 ;
  2503. while ($Ask) {
  2504. printMsg("\n\nWhere do you want to back up your configuration directory [$dest] ?") ;
  2505. my $Answer = <STDIN> ;
  2506. $dest = $Answer if ($Answer ne "\n");
  2507. chomp($dest);
  2508. printTrace("\nDest: .$dest.",4);
  2509. if (-e $dest) {
  2510. printMsg("\n\n$dest already exists. Do you want to overwrite it Yes/No [No] ?") ;
  2511. if (<STDIN> =~ /yes|y/i) {
  2512. $Ask = 0 ;
  2513. }
  2514. else {
  2515. $dest = "$serverHome${PATHSEP}config_backup" ;
  2516. }
  2517. }
  2518. else {
  2519. $Ask = 0 ;
  2520. }
  2521. }
  2522. printTrace("\nBackup Directory: $src in $dest",4);
  2523. &copyDir($src,$dest);
  2524. }
  2525. }
  2526. #############################################################################
  2527. sub getLDAPservername {
  2528. my $oldLDAPservername;
  2529. my $LDAPservername;
  2530. my $localhost = "nsslapd-localhost";
  2531. open(OLDDSELDIF, "< $oldDSEldif") or die "\nError: could not open old config file $oldDSEldif \n";
  2532. my $in = new Mozilla::LDAP::LDIF(*OLDDSELDIF) ;
  2533. while ($entry = readOneEntry $in) {
  2534. my $DN = $entry->getDN(1) ;
  2535. if ($DN =~ /^cn=config$/i) {
  2536. my @values = $entry->getValues($localhost);
  2537. if ($entry->size($localhost)) {
  2538. $oldLDAPservername = $values[0];
  2539. printTrace("\nName of the old LDAP server: $oldLDAPservername",3);
  2540. }
  2541. break;
  2542. }
  2543. }
  2544. close(OLDSELDIF);
  2545. open( DSELDIF, "< $DSEldif" ) || die "\nCan't open $DSEldif \n";
  2546. my $in = new Mozilla::LDAP::LDIF(*DSELDIF) ;
  2547. while ($entry = readOneEntry $in) {
  2548. my $DN = $entry->getDN(1) ;
  2549. if ($DN =~ /^cn=config$/i) {
  2550. my @values = $entry->getValues($localhost);
  2551. if ($entry->size($localhost)) {
  2552. $LDAPservername = $values[0];
  2553. printTrace("\nName of the new LDAP server: $LDAPservername",3);
  2554. }
  2555. break;
  2556. }
  2557. }
  2558. close(DSELDIF);
  2559. # check ol and new Directory Instance are installed on the same physical machine.
  2560. if (lc($oldLDAPservername) ne lc($LDAPservername)) {
  2561. # warn the user he tries to migrate a 4.x server installed on a different machine from the 5.x one
  2562. printMsg("\n\nYour old instance is on $oldLDAPservername, whereas your new instance is on $LDAPservername. Migration on different machines is not supported. Do you want to continue ? Yes/No [No]:") ;
  2563. if (! (<STDIN> =~ /yes|y/i)) {
  2564. return -1;
  2565. }
  2566. }
  2567. return $LDAPservername ;
  2568. }
  2569. #############################################################################
  2570. sub getLibPath {
  2571. my $myDir = shift;
  2572. my $myVersion = shift;
  2573. my $myMinor = shift;
  2574. if ($isNT) {
  2575. return $ENV{"$LIB_PATH"};
  2576. }
  2577. if (($myVersion >= 6) && ($myMinor >= 2)) {
  2578. return
  2579. "$myDir${PATHSEP}bin${PATHSEP}slapd${PATHSEP}lib${SEP}".
  2580. "$myDir${PATHSEP}bin${PATHSEP}slapd${PATHSEP}server${SEP}".
  2581. $ENV{"$LIB_PATH"};
  2582. } else {
  2583. return "$myDir${PATHSEP}lib${SEP}".$ENV{"$LIB_PATH"};
  2584. }
  2585. }
  2586. #############################################################################
  2587. sub getVersion {
  2588. my $dir = shift;
  2589. my $versionstr = shift;
  2590. my $version = 0;
  2591. my $minor = 0;
  2592. my $buildNumber = 0;
  2593. my $progDir = "${PATHSEP}bin${PATHSEP}slapd${PATHSEP}server${PATHSEP}";
  2594. my $progDir2 = "${PATHSEP}bin${PATHSEP}slapd${PATHSEP}";
  2595. # find the slapd executable
  2596. if (!$versionstr) { # version not specified on cmd line - find it
  2597. $prog = $dir . $progDir . $slapdExecName;
  2598. if (! -f $prog) {
  2599. $prog = $dir . $progDir2 . $slapdExecName;
  2600. if (-f $prog && $isNT) {
  2601. # if slapd is in bin/slapd and we're on NT, just assume version 1;
  2602. # apparently, slapd.exe doesn't like the -v argument . . .
  2603. return ( '1', $minor );
  2604. }
  2605. else{
  2606. die "Could not run slapd program $prog: $!";
  2607. }
  2608. }
  2609. else {
  2610. chdir($dir . $progDir);
  2611. }
  2612. $cur_libpath=$ENV{"$LIB_PATH"};
  2613. $ENV{"$LIB_PATH"}=
  2614. "$dir${PATHSEP}lib${SEP}".
  2615. "$dir${PATHSEP}bin${PATHSEP}slapd${PATHSEP}lib${SEP}".
  2616. "$dir${PATHSEP}bin${PATHSEP}slapd${PATHSEP}server${SEP}".
  2617. $ENV{"$LIB_PATH"};
  2618. # read the old version from the old slapd program
  2619. open(F, "${quote}${quote}$prog${quote} -v${quote} 2>&1 |") or
  2620. die "Could not run slapd program $prog: $!";
  2621. sleep(1); # allow some data to accumulate in the pipe
  2622. # print "Output from $prog -v:\n";
  2623. while (<F>) {
  2624. if (/^Netscape-Directory/ || /^iPlanet-Directory/i) {
  2625. $versionstr = $_;
  2626. last;
  2627. }
  2628. }
  2629. $code = close(F);
  2630. # print "$prog returned code=$code status=$?\n";
  2631. $ENV{"$LIB_PATH"}=$cur_libpath;
  2632. }
  2633. if ($versionstr =~ /^Netscape-Directory\/(\d+)\.(\d+)(?:b\d)*\s+(\S+)/) {
  2634. $version = $1;
  2635. $minor = $2;
  2636. $buildNumber = $3;
  2637. }
  2638. elsif ($versionstr =~ /^Netscape-Directory\(restrict?ed-mode\)\/(\d+)\.(\d+)\s+(\S+)/) { # we can have restricted-mode or restriced-mode ...
  2639. $version = $1;
  2640. $minor = $2;
  2641. $buildNumber = $3;
  2642. }
  2643. elsif ($versionstr =~ /^iPlanet-Directory\/(\d+)\.(\d+)\s+(\S+)/i) {
  2644. $version = $1;
  2645. $minor = $2;
  2646. $buildNumber = $3;
  2647. } elsif ($versionstr =~ /(\d+)\.(\d+)/) {
  2648. $version = $1;
  2649. $minor = $2;
  2650. }
  2651. if ($version == 0) {
  2652. die "\nCould not determine version of the directory server in $dir: \n";
  2653. }
  2654. # distinguish the 4.1 and the 4.11 thanks to the buildNumber
  2655. if (($version == 4) && ($minor == 1)){
  2656. if (! ($buildNumber =~ /^B99\.16/)) {
  2657. # it's not a 4.1 Netscape Directory Server => it's a 4.11
  2658. $minor = 11 ;
  2659. }
  2660. }
  2661. chdir($curdir) or die "Could not change directory to $curdir: $!" ;
  2662. return ( $version, $minor );
  2663. }
  2664. ###############################################################################################
  2665. sub normalizeDir {
  2666. my $dir = shift ;
  2667. my $dir_prec = "" ;
  2668. while ($dir_prec ne $dir) {
  2669. $dir_prec = $dir ;
  2670. if ($isNT) {
  2671. grep { s@\\\\@\\@g } $dir ;
  2672. }
  2673. else {
  2674. grep { s@//@/@g } $dir ;
  2675. }
  2676. }
  2677. return $dir ;
  2678. }
  2679. ###############################################################################################
  2680. sub GetTime {
  2681. my $tm = localtime;
  2682. (my $sec, my $min, my $hour, my $dd, my $mm, my $yy) = ($tm->sec, $tm->min, $tm->hour, $tm->mday, ($tm->mon)+1, ($tm->year)+1900);
  2683. $sec = "0$sec" unless $sec > 9 ;
  2684. $min = "0$min" unless $min > 9 ;
  2685. $hour = "0$hour" unless $hour > 9 ;
  2686. $dd = "0$dd" unless $dd > 9 ;
  2687. $mm = "0$mm" unless $mm > 9 ;
  2688. return ($sec, $min, $hour, $dd, $mm, $yy);
  2689. }
  2690. ###############################################################################################
  2691. # get uid and group id of the 5.x slapd server.
  2692. # The uid is done through the nsslapd-localuser attribute
  2693. sub getuid_gid {
  2694. my $newuid ;
  2695. my $newgid ;
  2696. my $localuser ;
  2697. my $localuser_attr = "nsslapd-localuser" ;
  2698. if (! $isNT) {
  2699. &startServer() unless (isDirectoryAlive());
  2700. my $conn = new Mozilla::LDAP::Conn($LDAPservername,$newport,$rootDN,$rootpwd) or die "\n Can't contact the $Version.$Minor LDAP server: $LDAPservername\n";
  2701. my $entry = $conn->search("cn=config ", "base","objectclass=*", 0, ($localuser_attr)) ;
  2702. # Tests wether we succeed to get the entry cn=config
  2703. die "\nCan't get the entry cn=config \n" unless ($entry);
  2704. my @values = $entry->getValues($localuser_attr);
  2705. $conn->close();
  2706. if ($#values == -1 || ($values[0] eq "") ) { # tests wether the nsslapd-localuser attribute has a value
  2707. printMsg("\nNo localuser has been found in the configuration of the directory. ");
  2708. if ($NO_INPUT_USER) {
  2709. printMsg("\nWe considered nobody as the localuser");
  2710. $localuser = "nobody" ;
  2711. }
  2712. else {
  2713. my $Ask = 1 ;
  2714. while ($Ask) {
  2715. printMsg("\nUnder what user does your $Version.$Minor directory server run [nobody] ? ") ;
  2716. $localuser = <STDIN> ;
  2717. chomp($localuser);
  2718. $localuser = "nobody" if ($localuser eq "");
  2719. ($newuid, $newgid) = (getpwnam("$localuser"))[2..3] ;
  2720. if ($newuid) {
  2721. $Ask = 0 ;
  2722. }
  2723. else {
  2724. printMsg("\nError: $localuser is unknown from the system ");
  2725. }
  2726. }
  2727. }
  2728. }
  2729. else {
  2730. $localuser = $values[0]; # returns the first value (we should only have one localuser)
  2731. my $size = $#values ;
  2732. }
  2733. ($newuid, $newgid) = (getpwnam("$localuser"))[2..3] ;
  2734. return ($localuser, $newuid, $newgid) ;
  2735. }
  2736. else {
  2737. return () ;
  2738. }
  2739. }
  2740. sub getolduid_gid {
  2741. my $oldlocaluser ;
  2742. my $localuserAttr = "nsslapd-localuser";
  2743. my $entry ;
  2744. if (! $isNT) {
  2745. open( DSELDIF, "< $oldDSEldif" ) || die "Can't open $oldDSEldif: $!: ";
  2746. my $in = new Mozilla::LDAP::LDIF(*DSELDIF) ;
  2747. while ($entry = readOneEntry $in) {
  2748. $typeOfEntry = getTypeOfEntry($entry);
  2749. if ($typeOfEntry eq "CONFIG_NODE") {
  2750. $oldlocaluser = $entry->{$localuserAttr}[0] if ($entry->exists($localuserAttr));
  2751. break ;
  2752. }
  2753. }
  2754. close(DSE);
  2755. ($olduid, $oldgid) = (getpwnam("$oldlocaluser"))[2..3] ;
  2756. return ($oldlocaluser, $olduid, $oldgid) ;
  2757. }
  2758. else {
  2759. return ();
  2760. }
  2761. }
  2762. ###############################################################################################
  2763. # get current directory
  2764. sub getCwd {
  2765. my $command = $isNT ? "cd" : "/bin/pwd";
  2766. open(PWDCMD, "$command 2>&1 |") or
  2767. die "Error: could not execute $command: $!";
  2768. # without the following sleep, reading from the pipe will
  2769. # return nothing; I guess it gives the pwd command time
  2770. # to get some data to read . . .
  2771. sleep(1);
  2772. my $currentdir;
  2773. while (<PWDCMD>) {
  2774. if (!$currentdir) {
  2775. chomp($currentdir = $_);
  2776. }
  2777. }
  2778. my $code = close(PWDCMD);
  2779. # if ($code || $?) {
  2780. # print "$command returned code=$code status=$? dir=$curdir\n";
  2781. # }
  2782. # print "getCwd curdir=\[$curdir\]\n";
  2783. return $currentdir;
  2784. }
  2785. ################################
  2786. # Need to migrate the credential.
  2787. # If the credential can not be migrated, leave it at it is
  2788. ################################
  2789. sub migrate_credential{
  2790. my $entry_to_modify = shift;
  2791. my $credentials_attr = shift;
  2792. my @old_value = $entry_to_modify->getValues($credentials_attr);
  2793. my $migratecredExecName = 'migratecred';
  2794. my $credOldHome = $oldHome;
  2795. my $credServerHome = $serverHome;
  2796. if ($isNT) {
  2797. # oldHome may be pointing to the archived copy of the
  2798. # instance dir which may be different than the path that
  2799. # the instance was originally installed as on Windows. If
  2800. # this path is not the original install path, then the
  2801. # credential will not be migrated correctly. We should
  2802. # prompt the user on Windows for the correct path.
  2803. print "\n\nThe old instance path must be the same as where it was";
  2804. print "\ninitially installed, not where it was archived in order";
  2805. print "\nfor this step to succeed. Please verify that the path";
  2806. print "\nis correct. Note that case sensitivity is important here.";
  2807. print "\n\nOld Instance Directory: $credOldHome";
  2808. print "\nIs this correct? (y/n): ";
  2809. chomp(my $answer = <STDIN>);
  2810. if (!($answer =~ /y|yes/i)) {
  2811. print "\nPlease enter the correct path for the old instance directory: ";
  2812. chomp($credOldHome = <STDIN>);
  2813. }
  2814. print "\n\nThe new instance path must also be correct for this step";
  2815. print "\nto succeed. Please verify that the path is correct. Note";
  2816. print "\nthat case sensitivity is important here.";
  2817. print "\n\nNew Instance Directory: $credServerHome";
  2818. print "\nIs this correct? (y/n): ";
  2819. chomp(my $answer = <STDIN>);
  2820. if (!($answer =~ /y|yes/i)) {
  2821. print "\nPlease enter the correct path for the new instance directory: ";
  2822. chomp($credServerHome = <STDIN>);
  2823. }
  2824. }
  2825. # print "\nMigratecred command is: ${quote}$root${PATHSEP}bin${PATHSEP}slapd${PATHSEP}server${PATHSEP}$migratecredExecName${quote} -o $credOldHome -n $credServerHome -c @old_value\n";
  2826. my @new_cred = `${quote}$root${PATHSEP}bin${PATHSEP}slapd${PATHSEP}server${PATHSEP}$migratecredExecName${quote} -o $credOldHome -n $credServerHome -c @old_value`;
  2827. if ( $? == 0 )
  2828. {
  2829. $entry_to_modify->setValues($credentials_attr, @new_cred);
  2830. }
  2831. }