main.c 80 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768
  1. /** BEGIN COPYRIGHT BLOCK
  2. * This Program is free software; you can redistribute it and/or modify it under
  3. * the terms of the GNU General Public License as published by the Free Software
  4. * Foundation; version 2 of the License.
  5. *
  6. * This Program is distributed in the hope that it will be useful, but WITHOUT
  7. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  8. * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
  9. *
  10. * You should have received a copy of the GNU General Public License along with
  11. * this Program; if not, write to the Free Software Foundation, Inc., 59 Temple
  12. * Place, Suite 330, Boston, MA 02111-1307 USA.
  13. *
  14. * In addition, as a special exception, Red Hat, Inc. gives You the additional
  15. * right to link the code of this Program with code not covered under the GNU
  16. * General Public License ("Non-GPL Code") and to distribute linked combinations
  17. * including the two, subject to the limitations in this paragraph. Non-GPL Code
  18. * permitted under this exception must only link to the code of this Program
  19. * through those well defined interfaces identified in the file named EXCEPTION
  20. * found in the source code files (the "Approved Interfaces"). The files of
  21. * Non-GPL Code may instantiate templates or use macros or inline functions from
  22. * the Approved Interfaces without causing the resulting work to be covered by
  23. * the GNU General Public License. Only Red Hat, Inc. may make changes or
  24. * additions to the list of Approved Interfaces. You must obey the GNU General
  25. * Public License in all respects for all of the Program code and other code used
  26. * in conjunction with the Program except the Non-GPL Code covered by this
  27. * exception. If you modify this file, you may extend this exception to your
  28. * version of the file, but you are not obligated to do so. If you do not wish to
  29. * provide this exception without modification, you must delete this exception
  30. * statement from your version and license this file solely under the GPL without
  31. * exception.
  32. *
  33. *
  34. * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
  35. * Copyright (C) 2005 Red Hat, Inc.
  36. * All rights reserved.
  37. * END COPYRIGHT BLOCK **/
  38. #include <ldap.h>
  39. #undef OFF
  40. #undef LITTLE_ENDIAN
  41. #include <stdio.h>
  42. #include <string.h>
  43. #include <sys/types.h>
  44. #include <sys/stat.h>
  45. #if !defined(_WIN32) && !defined(aix)
  46. #include <sys/fcntl.h>
  47. #else
  48. #include <fcntl.h>
  49. #endif
  50. #include <time.h>
  51. #include <stdarg.h>
  52. #include <signal.h>
  53. #include <stdlib.h>
  54. #if defined( _WIN32 )
  55. #include "ntslapdmessages.h"
  56. #include "proto-ntutil.h"
  57. #else
  58. #include <sys/time.h>
  59. #include <sys/socket.h>
  60. #include <netinet/in.h>
  61. #include <arpa/inet.h>
  62. #include <netdb.h>
  63. #include <pwd.h> /* getpwnam */
  64. #if !defined(IRIX) && !defined(LINUX)
  65. union semun {
  66. int val;
  67. struct semid_ds *buf;
  68. ushort *array;
  69. };
  70. #endif
  71. #endif
  72. #if !defined(_WIN32)
  73. #include <unistd.h> /* dup2 */
  74. #include <sys/ipc.h>
  75. #include <sys/sem.h>
  76. #include <sys/param.h> /* MAXPATHLEN */
  77. #endif
  78. #if defined(__sun)
  79. #include <sys/utsname.h>
  80. #include <sys/systeminfo.h>
  81. #endif
  82. #include "slap.h"
  83. #include "slapi-plugin.h"
  84. #include "prinit.h"
  85. #include "snmp_collator.h"
  86. #include "fe.h" /* client_auth_init() */
  87. #include "protect_db.h"
  88. #include "getopt_ext.h"
  89. #include "fe.h"
  90. #ifndef LDAP_DONT_USE_SMARTHEAP
  91. #include "smrtheap.h"
  92. #endif
  93. #if defined( XP_WIN32 )
  94. void dostounixpath(char *szText);
  95. #endif
  96. /* Forward Declarations */
  97. static void register_objects();
  98. static void process_command_line(int argc, char **argv, char *myname, char **extraname);
  99. static int slapd_exemode_ldif2db();
  100. static int slapd_exemode_db2ldif(int argc, char **argv);
  101. static int slapd_exemode_db2index();
  102. static int slapd_exemode_archive2db();
  103. static int slapd_exemode_db2archive();
  104. static int slapd_exemode_upgradedb();
  105. static int slapd_exemode_dbtest();
  106. static int slapd_exemode_suffix2instance();
  107. static int slapd_debug_level_string2level( const char *s );
  108. static void slapd_debug_level_log( int level );
  109. static void slapd_debug_level_usage( void );
  110. static void cmd_set_shutdown(int);
  111. /*
  112. * global variables
  113. */
  114. static int slapd_exemode = SLAPD_EXEMODE_UNKNOWN;
  115. static int init_cmd_shutdown_detect()
  116. {
  117. #ifndef _WIN32
  118. /* First of all, we must reset the signal mask to get rid of any blockages
  119. * the process may have inherited from its parent (such as the console), which
  120. * might result in the process not delivering those blocked signals, and thus,
  121. * misbehaving....
  122. */
  123. {
  124. int rc;
  125. sigset_t proc_mask;
  126. LDAPDebug( LDAP_DEBUG_TRACE, "Reseting signal mask....\n", 0, 0, 0);
  127. (void)sigemptyset( &proc_mask );
  128. rc = pthread_sigmask( SIG_SETMASK, &proc_mask, NULL );
  129. LDAPDebug( LDAP_DEBUG_TRACE, " %s \n",
  130. rc ? "Failed to reset signal mask":"....Done (signal mask reset)!!", 0, 0 );
  131. }
  132. #endif
  133. #if defined ( HPUX10 )
  134. PR_CreateThread ( PR_USER_THREAD,
  135. catch_signals,
  136. NULL,
  137. PR_PRIORITY_NORMAL,
  138. PR_GLOBAL_THREAD,
  139. PR_UNJOINABLE_THREAD,
  140. SLAPD_DEFAULT_THREAD_STACKSIZE);
  141. #elif defined ( HPUX11 )
  142. /* In the optimized builds for HPUX, the signal handler doesn't seem
  143. * to get set correctly unless the primordial thread gets a chance
  144. * to run before we make the call to SIGNAL. (At this point the
  145. * the primordial thread has spawned the daemon thread which called
  146. * this function.) The call to DS_Sleep will give the primordial
  147. * thread a chance to run. */
  148. DS_Sleep(0);
  149. #endif
  150. #ifndef _WIN32
  151. (void) SIGNAL( SIGPIPE, SIG_IGN );
  152. (void) SIGNAL( SIGCHLD, slapd_wait4child );
  153. #ifndef LINUX
  154. /* linux uses USR1/USR2 for thread synchronization, so we aren't
  155. * allowed to mess with those.
  156. */
  157. (void) SIGNAL( SIGUSR1, slapd_do_nothing );
  158. (void) SIGNAL( SIGUSR2, cmd_set_shutdown );
  159. #endif
  160. (void) SIGNAL( SIGTERM, cmd_set_shutdown );
  161. (void) SIGNAL( SIGHUP, cmd_set_shutdown );
  162. (void) SIGNAL( SIGINT, cmd_set_shutdown );
  163. #endif /* _WIN32 */
  164. return 0;
  165. }
  166. static void
  167. cmd_set_shutdown (int sig)
  168. {
  169. /* don't log anything from a signal handler:
  170. * you could be holding a lock when the signal was trapped. more
  171. * specifically, you could be holding the logfile lock (and deadlock
  172. * yourself).
  173. */
  174. #if 0
  175. LDAPDebug( LDAP_DEBUG_ANY, "slapd got shutdown signal\n", 0, 0, 0 );
  176. #endif
  177. c_set_shutdown();
  178. #ifndef _WIN32
  179. #ifndef LINUX
  180. /* don't mess with USR1/USR2 on linux, used by libpthread */
  181. (void) SIGNAL( SIGUSR2, cmd_set_shutdown );
  182. #endif
  183. (void) SIGNAL( SIGTERM, cmd_set_shutdown );
  184. (void) SIGNAL( SIGHUP, cmd_set_shutdown );
  185. #endif
  186. }
  187. #ifdef HPUX10
  188. extern void collation_init();
  189. #endif
  190. #ifndef WIN32
  191. /*
  192. Four cases:
  193. - change ownership of all files in directory (strip_fn=PR_FALSE)
  194. - change ownership of all files in directory; but trailing fn needs to be stripped (strip_fn=PR_TRUE)
  195. - fn is relative to root directory (/access); we print error message and let user shoot his foot
  196. - fn is relative to current directory (access); we print error message and let user shoot his other foot
  197. The docs say any valid filename.
  198. */
  199. static void
  200. chown_dir_files(char *name, struct passwd *pw, PRBool strip_fn)
  201. {
  202. PRDir *dir;
  203. PRDirEntry *entry;
  204. char file[MAXPATHLEN + 1];
  205. char *log=NULL, *ptr=NULL;
  206. int rc=0;
  207. log=strdup(name);
  208. if(strip_fn)
  209. {
  210. if((ptr=strrchr(log,'/'))==NULL)
  211. {
  212. LDAPDebug(LDAP_DEBUG_ANY, "Caution changing ownership of ./%s \n",name,0,0);
  213. slapd_chown_if_not_owner(log, pw->pw_uid, -1 );
  214. rc=1;
  215. } else if(log==ptr) {
  216. LDAPDebug(LDAP_DEBUG_ANY, "Caution changing ownership of / directory and its contents to %s\n",pw->pw_name,0,0);
  217. *(++ptr)='\0';
  218. } else {
  219. *ptr='\0';
  220. }
  221. }
  222. if ((!rc) && ((dir = PR_OpenDir(log)) != NULL ))
  223. {
  224. /* change the owner for each of the files in the dir */
  225. while( (entry = PR_ReadDir(dir , PR_SKIP_BOTH )) !=NULL )
  226. {
  227. PR_snprintf(file,MAXPATHLEN+1,"%s/%s",log,entry->name);
  228. slapd_chown_if_not_owner( file, pw->pw_uid, -1 );
  229. }
  230. PR_CloseDir( dir );
  231. }
  232. free(log);
  233. }
  234. /* Changes the owner of the files in the logs and
  235. * config directory to the user that the server runs as.
  236. */
  237. static void
  238. fix_ownership()
  239. {
  240. struct passwd* pw=NULL;
  241. char dirname[MAXPATHLEN + 1];
  242. slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig();
  243. if ( slapdFrontendConfig->localuser != NULL ) {
  244. if ( (pw = getpwnam( slapdFrontendConfig->localuser )) == NULL )
  245. return;
  246. }
  247. else {
  248. return;
  249. }
  250. /* config directory needs to be owned by the local user */
  251. if (slapdFrontendConfig->configdir) {
  252. chown_dir_files(slapdFrontendConfig->configdir, pw, PR_FALSE);
  253. }
  254. /* do access log file, if any */
  255. if (slapdFrontendConfig->accesslog) {
  256. chown_dir_files(slapdFrontendConfig->accesslog, pw, PR_TRUE);
  257. }
  258. /* do audit log file, if any */
  259. if (slapdFrontendConfig->auditlog) {
  260. chown_dir_files(slapdFrontendConfig->auditlog, pw, PR_TRUE);
  261. }
  262. /* do error log file, if any */
  263. if (slapdFrontendConfig->errorlog) {
  264. chown_dir_files(slapdFrontendConfig->errorlog, pw, PR_TRUE);
  265. }
  266. }
  267. #endif
  268. /* Changes identity to the named user
  269. * If username == NULL, does nothing.
  270. * Does nothing on NT regardless.
  271. */
  272. static int main_setuid(char *username)
  273. {
  274. #ifndef _WIN32
  275. if (username != NULL) {
  276. struct passwd *pw;
  277. /* Make sure everything in the log and config directory
  278. * is owned by the correct user */
  279. fix_ownership();
  280. pw = getpwnam (username);
  281. if (pw == NULL) {
  282. int oserr = errno;
  283. LDAPDebug (LDAP_DEBUG_ANY, "getpwnam(%s) == NULL, error %d (%s)\n",
  284. username, oserr, slapd_system_strerror(oserr));
  285. } else {
  286. if (setgid (pw->pw_gid) != 0) {
  287. int oserr = errno;
  288. LDAPDebug (LDAP_DEBUG_ANY, "setgid(%li) != 0, error %d (%s)\n",
  289. (long)pw->pw_gid, oserr, slapd_system_strerror(oserr));
  290. return -1;
  291. }
  292. if (setuid (pw->pw_uid) != 0) {
  293. int oserr = errno;
  294. LDAPDebug (LDAP_DEBUG_ANY, "setuid(%li) != 0, error %d (%s)\n",
  295. (long)pw->pw_uid, oserr, slapd_system_strerror(oserr));
  296. return -1;
  297. }
  298. }
  299. }
  300. #endif
  301. return 0;
  302. }
  303. /* set good defaults for front-end config in referral mode */
  304. static void referral_set_defaults(void)
  305. {
  306. #if !defined(_WIN32) && !defined(AIX)
  307. char errorbuf[SLAPI_DSE_RETURNTEXT_SIZE];
  308. config_set_maxdescriptors( CONFIG_MAXDESCRIPTORS_ATTRIBUTE, "1024", errorbuf, 1);
  309. #endif
  310. }
  311. static int
  312. name2exemode( char *progname, char *s, int exit_if_unknown )
  313. {
  314. int exemode;
  315. if ( strcmp( s, "db2ldif" ) == 0 ) {
  316. exemode = SLAPD_EXEMODE_DB2LDIF;
  317. } else if ( strcmp( s, "ldif2db" ) == 0 ) {
  318. exemode = SLAPD_EXEMODE_LDIF2DB;
  319. } else if ( strcmp( s, "archive2db" ) == 0 ) {
  320. exemode = SLAPD_EXEMODE_ARCHIVE2DB;
  321. } else if ( strcmp( s, "db2archive" ) == 0 ) {
  322. exemode = SLAPD_EXEMODE_DB2ARCHIVE;
  323. } else if ( strcmp( s, "server" ) == 0 ) {
  324. exemode = SLAPD_EXEMODE_SLAPD;
  325. } else if ( strcmp( s, "dbtest" ) == 0 ) {
  326. exemode = SLAPD_EXEMODE_DBTEST;
  327. } else if ( strcmp( s, "db2index" ) == 0 ) {
  328. exemode = SLAPD_EXEMODE_DB2INDEX;
  329. } else if ( strcmp( s, "refer" ) == 0 ) {
  330. exemode = SLAPD_EXEMODE_REFERRAL;
  331. } else if ( strcmp( s, "suffix2instance" ) == 0 ) {
  332. exemode = SLAPD_EXEMODE_SUFFIX2INSTANCE;
  333. }
  334. else if ( strcmp( s, "upgradedb" ) == 0 )
  335. {
  336. exemode = SLAPD_EXEMODE_UPGRADEDB;
  337. }
  338. else if ( exit_if_unknown ) {
  339. fprintf( stderr, "usage: %s -D configdir "
  340. "[ldif2db | db2ldif | archive2db "
  341. "| db2archive | db2index | refer | suffix2instance"
  342. " | upgradedb] "
  343. "[options]\n", progname );
  344. exit( 1 );
  345. } else {
  346. exemode = SLAPD_EXEMODE_UNKNOWN;
  347. }
  348. return( exemode );
  349. }
  350. static void
  351. usage( char *name, char *extraname )
  352. {
  353. char *usagestr = NULL;
  354. char *extraspace;
  355. if ( extraname == NULL ) {
  356. extraspace = extraname = "";
  357. } else {
  358. extraspace = " ";
  359. }
  360. switch( slapd_exemode ) {
  361. case SLAPD_EXEMODE_DB2LDIF:
  362. usagestr = "usage: %s %s%s-D configdir [-n backend-instance-name] [-d debuglevel] "
  363. "[-N] [-a outputfile] [-r] [-C] [{-s includesuffix}*] "
  364. "[{-x excludesuffix}*] [-u] [-U] [-m] [-M] [-E]\n"
  365. "Note: either \"-n backend_instance_name\" or \"-s includesuffix\" is required.\n";
  366. break;
  367. case SLAPD_EXEMODE_LDIF2DB:
  368. usagestr = "usage: %s %s%s-D configdir [-d debuglevel] "
  369. "[-n backend_instance_name] [-O] [-g uniqueid_type] [--namespaceid uniqueID]"
  370. "[{-s includesuffix}*] [{-x excludesuffix}*] [-E] {-i ldif-file}*\n"
  371. "Note: either \"-n backend_instance_name\" or \"-s includesuffix\" is required.\n";
  372. break;
  373. case SLAPD_EXEMODE_DB2ARCHIVE:
  374. usagestr = "usage: %s %s%s-D configdir [-d debuglevel] -a archivedir\n";
  375. break;
  376. case SLAPD_EXEMODE_ARCHIVE2DB:
  377. usagestr = "usage: %s %s%s-D configdir [-d debuglevel] -a archivedir\n";
  378. break;
  379. case SLAPD_EXEMODE_DB2INDEX:
  380. usagestr = "usage: %s %s%s-D configdir -n backend-instance-name "
  381. "[-d debuglevel] {-t attributetype}* {-T VLV Search Name}*\n";
  382. /* JCM should say 'Address Book' or something instead of VLV */
  383. break;
  384. case SLAPD_EXEMODE_REFERRAL:
  385. usagestr = "usage: %s %s%s-D configdir -r referral-url [-p port]\n";
  386. break;
  387. case SLAPD_EXEMODE_DBTEST:
  388. usagestr = "usage: %s %s%s-D configdir -n backend-instance-name "
  389. "[-d debuglevel] [-S] [-v]\n";
  390. break;
  391. case SLAPD_EXEMODE_SUFFIX2INSTANCE:
  392. usagestr = "usage: %s %s%s -D configdir {-s suffix}*\n";
  393. break;
  394. case SLAPD_EXEMODE_UPGRADEDB:
  395. usagestr = "usage: %s %s%s-D configdir [-d debuglevel] [-f] -a archivedir\n";
  396. break;
  397. default: /* SLAPD_EXEMODE_SLAPD */
  398. usagestr = "usage: %s %s%s-D configdir [-d debuglevel] "
  399. "[-i pidlogfile] [-v] [-V]\n";
  400. }
  401. fprintf( stderr, usagestr, name, extraname, extraspace );
  402. }
  403. /*
  404. * These nasty globals are the settings collected from the
  405. * command line by the process_command_line function. The
  406. * various slapd_exemode functions read these to drive their
  407. * execution.
  408. */
  409. static char *extraname;
  410. static char *myname;
  411. static int n_port = 0;
  412. static int s_port = 0;
  413. static char **ldif_file = NULL;
  414. static int ldif_files = 0;
  415. static int ldif_backend = 0;
  416. static char *cmd_line_instance_name = NULL;
  417. static char **cmd_line_instance_names = NULL;
  418. static int skip_db_protect_check = 0;
  419. static char **db2ldif_include = NULL;
  420. static char **db2ldif_exclude = NULL;
  421. static int ldif2db_removedupvals = 1;
  422. static int ldif2db_noattrindexes = 0;
  423. static char **db2index_attrs = NULL;
  424. static int ldif_printkey = EXPORT_PRINTKEY|EXPORT_APPENDMODE;
  425. static char *archive_name = NULL;
  426. static int db2ldif_dump_replica = 0;
  427. static int db2ldif_dump_uniqueid = 1;
  428. static int ldif2db_generate_uniqueid = SLAPI_UNIQUEID_GENERATE_TIME_BASED;
  429. static int ldif2db_load_state= 1;
  430. static char *ldif2db_namespaceid = NULL;
  431. int importexport_encrypt = 0;
  432. static int upgradedb_force = 0;
  433. /* taken from idsktune */
  434. #if defined(__sun)
  435. static void ids_get_platform_solaris(char *buf)
  436. {
  437. struct utsname u;
  438. char sbuf[128];
  439. FILE *fp;
  440. #if defined(sparc) || defined(__sparc)
  441. int is_u = 0;
  442. sbuf[0] = '\0';
  443. sysinfo(SI_MACHINE,sbuf,128);
  444. if (strcmp(sbuf,"sun4u") == 0) {
  445. is_u = 1;
  446. }
  447. sbuf[0] = '\0';
  448. sysinfo(SI_PLATFORM,sbuf,128);
  449. PR_snprintf(buf,sizeof(buf),"%ssparc%s-%s-solaris",
  450. is_u ? "u" : "",
  451. sizeof(long) == 4 ? "" : "v9",
  452. sbuf);
  453. #else
  454. #if defined(i386) || defined(__i386)
  455. sprintf(buf,"i386-unknown-solaris");
  456. #else
  457. sprintf(buf,"unknown-unknown-solaris");
  458. #endif /* not i386 */
  459. #endif /* not sparc */
  460. uname(&u);
  461. if (isascii(u.release[0]) && isdigit(u.release[0])) strcat(buf,u.release);
  462. fp = fopen("/etc/release","r");
  463. if (fp != NULL) {
  464. char *rp;
  465. sbuf[0] = '\0';
  466. fgets(sbuf,128,fp);
  467. fclose(fp);
  468. rp = strstr(sbuf,"Solaris");
  469. if (rp) {
  470. rp += 8;
  471. while(*rp != 's' && *rp != '\0') rp++;
  472. if (*rp == 's') {
  473. char *rp2;
  474. rp2 = strchr(rp,' ');
  475. if (rp2) *rp2 = '\0';
  476. strcat(buf,"_");
  477. strcat(buf,rp);
  478. }
  479. }
  480. }
  481. }
  482. #endif
  483. static void slapd_print_version(int verbose)
  484. {
  485. #if defined(__sun)
  486. char buf[8192];
  487. #endif
  488. char *versionstring = config_get_versionstring();
  489. char *buildnum = config_get_buildnum();
  490. printf( SLAPD_VENDOR_NAME "\n%s B%s\n", versionstring, buildnum);
  491. /* not here in Win32 */
  492. #if !defined(_WIN32)
  493. if (strcmp(buildnum,BUILD_NUM) != 0) {
  494. printf( "ns-slapd: B%s\n", BUILD_NUM);
  495. }
  496. #endif
  497. slapi_ch_free( (void **)&versionstring);
  498. slapi_ch_free( (void **)&buildnum);
  499. if (verbose == 0) return;
  500. #if defined(__sun)
  501. ids_get_platform_solaris(buf);
  502. printf("System: %s\n",buf);
  503. #endif
  504. /* this won't print much with the -v flag as the dse.ldif file
  505. * hasn't be read yet.
  506. */
  507. plugin_print_versions();
  508. }
  509. #if defined( _WIN32 )
  510. /* On Windows, we signal the SCM when we're still starting up */
  511. static int
  512. write_start_pid_file()
  513. {
  514. if( SlapdIsAService() )
  515. {
  516. /* Initialization complete and successful. Set service to running */
  517. LDAPServerStatus.dwCurrentState = SERVICE_START_PENDING;
  518. LDAPServerStatus.dwCheckPoint = 1;
  519. LDAPServerStatus.dwWaitHint = 1000;
  520. if (!SetServiceStatus(hLDAPServerServiceStatus, &LDAPServerStatus)) {
  521. ReportSlapdEvent(EVENTLOG_INFORMATION_TYPE, MSG_SERVER_START_FAILED, 1,
  522. "Could not set Service status.");
  523. exit(1);
  524. }
  525. }
  526. ReportSlapdEvent(EVENTLOG_INFORMATION_TYPE, MSG_SERVER_STARTED, 0, NULL );
  527. return 0;
  528. }
  529. #else /* WIN32 */
  530. /* On UNIX, we create a file with our PID in it */
  531. static int
  532. write_start_pid_file()
  533. {
  534. FILE *fp = NULL;
  535. /*
  536. * The following section of code is closely coupled with the
  537. * admin programs. Please do not make changes here without
  538. * consulting the start/stop code for the admin code.
  539. */
  540. if ( (fp = fopen( start_pid_file, "w" )) != NULL ) {
  541. fprintf( fp, "%d\n", getpid() );
  542. fclose( fp );
  543. return 0;
  544. } else
  545. {
  546. return -1;
  547. }
  548. }
  549. #endif /* WIN32 */
  550. int
  551. main( int argc, char **argv)
  552. {
  553. int return_value = 0;
  554. slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig();
  555. daemon_ports_t ports_info = {0};
  556. Slapi_Backend *be = NULL;
  557. int init_ssl;
  558. #ifndef __LP64__
  559. #if defined(__hpux) && !defined(__ia64)
  560. /* for static constructors */
  561. _main();
  562. #endif
  563. #endif
  564. /*
  565. * Initialize NSPR very early. NSPR supports implicit initialization,
  566. * but it is not bulletproof -- so it is better to be explicit.
  567. */
  568. PR_Init( PR_USER_THREAD, PR_PRIORITY_NORMAL, 0 );
  569. FrontendConfig_init();
  570. #ifdef _WIN32
  571. /* Break into the debugger if DEBUG_BREAK is set in the environment
  572. to "slapd" */
  573. {
  574. char *s = getenv( "DEBUG_BREAK" );
  575. if ( (s != NULL) && !stricmp(s, "slapd") )
  576. DebugBreak();
  577. }
  578. /* do module debug level init for slapd, and libslapd */
  579. module_ldap_debug = &slapd_ldap_debug;
  580. libldap_init_debug_level(&slapd_ldap_debug);
  581. dostounixpath( argv[0] );
  582. _strlwr( argv[0] );
  583. #else /* _WIN32 */
  584. /* Pause for the debugger if DEBUG_SLEEP is set in the environment */
  585. {
  586. char *s = getenv( "DEBUG_SLEEP" );
  587. if ( (s != NULL) && isdigit(*s) ) {
  588. int secs = atoi(s);
  589. printf("slapd pid is %d\n", getpid());
  590. sleep(secs);
  591. }
  592. }
  593. /* used to set configfile to the default config file name here */
  594. #endif /* _WIN32 */
  595. if ( (myname = strrchr( argv[0], '/' )) == NULL ) {
  596. myname = slapi_ch_strdup( argv[0] );
  597. } else {
  598. myname = slapi_ch_strdup( myname + 1 );
  599. }
  600. #if defined( XP_WIN32 )
  601. /* Strip ".exe" if it's there */
  602. {
  603. char *pdot;
  604. if ( (pdot = strrchr( myname, '.' )) != NULL ) {
  605. *pdot = '\0';
  606. }
  607. }
  608. #endif
  609. process_command_line(argc,argv,myname,&extraname);
  610. if (NULL == slapdFrontendConfig->configdir) {
  611. usage( myname, extraname );
  612. exit( 1 );
  613. }
  614. /* display debugging level if it is anything other than the default */
  615. if ( 0 != ( slapd_ldap_debug & ~LDAP_DEBUG_ANY )) {
  616. slapd_debug_level_log( slapd_ldap_debug );
  617. }
  618. #ifndef LDAP_DONT_USE_SMARTHEAP
  619. MemRegisterTask();
  620. #endif
  621. slapd_init();
  622. g_log_init(1);
  623. vattr_init();
  624. if (slapd_exemode == SLAPD_EXEMODE_REFERRAL) {
  625. slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig();
  626. /* make up the config stuff */
  627. referral_set_defaults();
  628. /*
  629. * Process the config files.
  630. */
  631. if (0 == slapd_bootstrap_config(slapdFrontendConfig->configdir)) {
  632. slapi_log_error(SLAPI_LOG_FATAL, "startup",
  633. "The configuration files in directory %s could not be read or were not found. Please refer to the error log or output for more information.\n",
  634. slapdFrontendConfig->configdir);
  635. exit(1);
  636. }
  637. n_port = config_get_port();
  638. s_port = config_get_secureport();
  639. register_objects();
  640. } else {
  641. slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig();
  642. /* The 2 calls below have been moved to this place to make sure that
  643. * they are called before setup_internal_backends to avoid bug 524439 */
  644. /*
  645. * The 2 calls below where being sometimes called AFTER
  646. * ldapi_register_extended_op (such fact was being stated and
  647. * reproducible for some optimized installations at startup (bug
  648. * 524439)... Such bad call was happening in the context of
  649. * setup_internal_backends -> dse_read_file -> load_plugin_entry ->
  650. * plugin_setup -> replication_multimaster_plugin_init ->
  651. * slapi_register_plugin -> plugin_setup ->
  652. * multimaster_start_extop_init -> * slapi_pblock_set ->
  653. * ldapi_register_extended_op... Unfortunately, the server
  654. * design is such that it is assumed that ldapi_init_extended_ops is
  655. * always called first.
  656. * THE FIX: Move the two calls below before a call to
  657. * setup_internal_backends (down in this same function)
  658. */
  659. ldapi_init_extended_ops();
  660. /*
  661. * Initialize the default backend. This should be done before we
  662. * process the config. files
  663. */
  664. defbackend_init();
  665. /*
  666. * Register the extensible objects with the factory.
  667. */
  668. register_objects();
  669. /*
  670. * Register the controls that we support.
  671. */
  672. init_controls();
  673. /*
  674. * Process the config files.
  675. */
  676. if (0 == slapd_bootstrap_config(slapdFrontendConfig->configdir)) {
  677. slapi_log_error(SLAPI_LOG_FATAL, "startup",
  678. "The configuration files in directory %s could not be read or were not found. Please refer to the error log or output for more information.\n",
  679. slapdFrontendConfig->configdir);
  680. exit(1);
  681. }
  682. /* We need to init sasl after we load the bootstrap config since
  683. * the config may be setting the sasl plugin path.
  684. */
  685. init_saslmechanisms();
  686. /* -sduloutre: must be done before any internal search */
  687. /* do it before splitting off to other modes too -robey */
  688. /* -richm: must be done before reading config files */
  689. if (0 != (return_value = compute_init())) {
  690. LDAPDebug(LDAP_DEBUG_ANY, "Initialization Failed 0 %d\n",return_value,0,0);
  691. exit (1);
  692. }
  693. entry_computed_attr_init();
  694. if (0 == setup_internal_backends(slapdFrontendConfig->configdir)) {
  695. slapi_log_error(SLAPI_LOG_FATAL, "startup",
  696. "The configuration files in directory %s could not be read or were not found. Please refer to the error log or output for more information.\n",
  697. slapdFrontendConfig->configdir);
  698. exit(1);
  699. }
  700. n_port = config_get_port();
  701. s_port = config_get_secureport();
  702. }
  703. raise_process_limits(); /* should be done ASAP once config file read */
  704. #ifdef PUMPKIN_HOUR
  705. if ( time( NULL ) > (PUMPKIN_HOUR - 10) ) {
  706. LDAPDebug( LDAP_DEBUG_ANY,
  707. "ERROR: ** This beta software has expired **\n", 0, 0, 0 );
  708. exit( 1 );
  709. }
  710. #endif
  711. /* Set entry points in libslapd */
  712. set_entry_points();
  713. #if defined( XP_WIN32 )
  714. if (slapd_exemode == SLAPD_EXEMODE_SLAPD) {
  715. /* Register with the NT EventLog */
  716. hSlapdEventSource = RegisterEventSource(NULL, pszServerName );
  717. if( !hSlapdEventSource ) {
  718. char szMessage[256];
  719. PR_snprintf( szMessage, sizeof(szMessage), "Directory Server %s is terminating. Failed "
  720. "to set the EventLog source.", pszServerName);
  721. MessageBox(GetDesktopWindow(), szMessage, " ",
  722. MB_ICONEXCLAMATION | MB_OK);
  723. exit( 1 );
  724. }
  725. /* Check to ensure there isn't a copy of this server already running. */
  726. if( MultipleInstances() )
  727. exit( 1 );
  728. }
  729. #endif
  730. /*
  731. * After we read the config file we should make
  732. * sure that everything we needed to read in has
  733. * been read in and we'll start whatever threads,
  734. * etc the backends need to start
  735. */
  736. /* Important: up 'till here we could be running as root (on unix).
  737. * we believe that we've not created any files before here, otherwise
  738. * they'd be owned by root, which is bad. We're about to change identity
  739. * to some non-root user, but before we do, we call the daemon code
  740. * to let it open the listen sockets. If these sockets are low-numbered,
  741. * we need to be root in order to open them.
  742. */
  743. if ((slapd_exemode == SLAPD_EXEMODE_SLAPD) ||
  744. (slapd_exemode == SLAPD_EXEMODE_REFERRAL)) {
  745. ports_info.n_port = (unsigned short)n_port;
  746. if ( slapd_listenhost2addr( config_get_listenhost(),
  747. &ports_info.n_listenaddr ) != 0 ) {
  748. return(1);
  749. }
  750. ports_info.s_port = (unsigned short)s_port;
  751. if ( slapd_listenhost2addr( config_get_securelistenhost(),
  752. &ports_info.s_listenaddr ) != 0 ) {
  753. return(1);
  754. }
  755. return_value = daemon_pre_setuid_init(&ports_info);
  756. if (0 != return_value) {
  757. LDAPDebug( LDAP_DEBUG_ANY, "Failed to init daemon\n",
  758. 0, 0, 0 );
  759. exit(1);
  760. }
  761. }
  762. /* Now, sockets are open, so we can safely change identity now */
  763. #ifndef _WIN32
  764. return_value = main_setuid(slapdFrontendConfig->localuser);
  765. if (0 != return_value) {
  766. LDAPDebug( LDAP_DEBUG_ANY, "Failed to change user and group identity to that of %s\n",
  767. slapdFrontendConfig->localuser, 0, 0 );
  768. exit(1);
  769. }
  770. #endif
  771. /*
  772. * Initialise NSS once for the whole slapd process, whether SSL
  773. * is enabled or not. We use NSS for random number generation and
  774. * other things even if we are not going to accept SSL connections.
  775. * We also need NSS for attribute encryption/decryption on import and export.
  776. */
  777. init_ssl = ( (slapd_exemode == SLAPD_EXEMODE_SLAPD) || importexport_encrypt)
  778. && config_get_security()
  779. && (0 != s_port) && (s_port <= LDAP_PORT_MAX);
  780. /* As of DS 6.1, always do a full initialization so that other
  781. * modules can assume NSS is available
  782. */
  783. if ( slapd_nss_init((slapd_exemode == SLAPD_EXEMODE_SLAPD),
  784. (slapd_exemode != SLAPD_EXEMODE_REFERRAL) /* have config? */ )) {
  785. LDAPDebug(LDAP_DEBUG_ANY,
  786. "ERROR: NSS Initialization Failed.\n", 0, 0, 0);
  787. exit (1);
  788. }
  789. if (slapd_exemode == SLAPD_EXEMODE_SLAPD) {
  790. client_auth_init();
  791. }
  792. if ( init_ssl && ( 0 != slapd_ssl_init())) {
  793. LDAPDebug(LDAP_DEBUG_ANY,
  794. "ERROR: SSL Initialization Failed.\n", 0, 0, 0 );
  795. exit( 1 );
  796. }
  797. if ((slapd_exemode == SLAPD_EXEMODE_SLAPD) ||
  798. (slapd_exemode == SLAPD_EXEMODE_REFERRAL)) {
  799. if ( init_ssl && ( 0 != slapd_ssl_init2(&ports_info.s_socket, 0) ) ) {
  800. LDAPDebug(LDAP_DEBUG_ANY,
  801. "ERROR: SSL Initialization phase 2 Failed.\n", 0, 0, 0 );
  802. exit( 1 );
  803. }
  804. }
  805. /*
  806. * if we were called upon to do special database stuff, do it and be
  807. * done.
  808. */
  809. switch ( slapd_exemode ) {
  810. case SLAPD_EXEMODE_LDIF2DB:
  811. return slapd_exemode_ldif2db();
  812. case SLAPD_EXEMODE_DB2LDIF:
  813. return slapd_exemode_db2ldif(argc,argv);
  814. case SLAPD_EXEMODE_DB2INDEX:
  815. return slapd_exemode_db2index();
  816. case SLAPD_EXEMODE_ARCHIVE2DB:
  817. return slapd_exemode_archive2db();
  818. case SLAPD_EXEMODE_DB2ARCHIVE:
  819. return slapd_exemode_db2archive();
  820. case SLAPD_EXEMODE_DBTEST:
  821. return slapd_exemode_dbtest();
  822. case SLAPD_EXEMODE_REFERRAL:
  823. /* check that all the necessary info was given, then go on */
  824. if (! config_check_referral_mode()) {
  825. LDAPDebug(LDAP_DEBUG_ANY,
  826. "ERROR: No referral URL supplied\n", 0, 0, 0);
  827. usage( myname, extraname );
  828. exit(1);
  829. }
  830. break;
  831. case SLAPD_EXEMODE_SUFFIX2INSTANCE:
  832. return slapd_exemode_suffix2instance();
  833. case SLAPD_EXEMODE_UPGRADEDB:
  834. return slapd_exemode_upgradedb();
  835. case SLAPD_EXEMODE_PRINTVERSION:
  836. slapd_print_version(1);
  837. exit(1);
  838. }
  839. /*
  840. * Detach ourselves from the terminal (unless running in debug mode).
  841. * We must detach before we start any threads since detach forks() on
  842. * UNIX.
  843. * Have to detach after ssl_init - the user may be prompted for the PIN
  844. * on the terminal, so it must be open.
  845. */
  846. detach();
  847. /*
  848. * Now write our PID to the startup PID file.
  849. * This is used by the start up script to determine our PID quickly
  850. * after we fork, without needing to wait for the 'real' pid file to be
  851. * written. That could take minutes. And the start script will wait
  852. * that long looking for it. With this new 'early pid' file, it can avoid
  853. * doing that, by detecting the pid and watching for the process exiting.
  854. * This removes the blank stares all round from start-slapd when the server
  855. * fails to start for some reason
  856. */
  857. write_start_pid_file();
  858. /* Make sure we aren't going to run slapd in
  859. * a mode that is going to conflict with other
  860. * slapd processes that are currently running
  861. */
  862. if ((slapd_exemode != SLAPD_EXEMODE_REFERRAL) &&
  863. ( add_new_slapd_process(slapd_exemode, db2ldif_dump_replica,
  864. skip_db_protect_check) == -1 )) {
  865. LDAPDebug( LDAP_DEBUG_ANY,
  866. "Shutting down due to possible conflicts with other slapd processes\n",
  867. 0, 0, 0 );
  868. exit(1);
  869. }
  870. /*
  871. * Now it is safe to log our first startup message. If we were to
  872. * log anything earlier than now it would appear on the admin startup
  873. * screen twice because before we detach everything is sent to both
  874. * stderr and our error log. Yuck.
  875. */
  876. if (1) {
  877. char *versionstring = config_get_versionstring();
  878. char *buildnum = config_get_buildnum();
  879. LDAPDebug( LDAP_DEBUG_ANY, "%s B%s starting up\n",
  880. versionstring, buildnum, 0 );
  881. slapi_ch_free((void **)&buildnum);
  882. slapi_ch_free((void **)&versionstring);
  883. }
  884. /* -sduloutre: compute_init() and entry_computed_attr_init() moved up */
  885. if (slapd_exemode != SLAPD_EXEMODE_REFERRAL) {
  886. int rc;
  887. Slapi_DN *sdn;
  888. fedse_create_startOK(DSE_FILENAME, DSE_STARTOKFILE,
  889. slapdFrontendConfig->configdir);
  890. eq_init(); /* must be done before plugins started */
  891. snmp_collator_start();
  892. ps_init_psearch_system(); /* must come before plugin_startall() */
  893. /* Initailize the mapping tree */
  894. if (mapping_tree_init())
  895. {
  896. LDAPDebug( LDAP_DEBUG_ANY, "Failed to init mapping tree\n",
  897. 0, 0, 0 );
  898. exit(1);
  899. }
  900. /* initialize UniqueID generator - must be done once backends are started
  901. and event queue is initialized but before plugins are started */
  902. sdn = slapi_sdn_new_dn_byval ("cn=uniqueid generator,cn=config");
  903. rc = uniqueIDGenInit (NULL, sdn, slapd_exemode == SLAPD_EXEMODE_SLAPD);
  904. slapi_sdn_free (&sdn);
  905. if (rc != UID_SUCCESS)
  906. {
  907. LDAPDebug( LDAP_DEBUG_ANY,
  908. "Fatal Error---Failed to initialize uniqueid generator; error = %d. "
  909. "Exiting now.\n", rc, 0, 0 );
  910. exit( 1 );
  911. }
  912. /* --ugaston: register the start-tls plugin */
  913. #ifndef _WIN32
  914. if ( slapd_security_library_is_initialized() != 0 ) {
  915. start_tls_register_plugin();
  916. LDAPDebug( LDAP_DEBUG_PLUGIN,
  917. "Start TLS plugin registered.\n",
  918. 0, 0, 0 );
  919. }
  920. #endif
  921. passwd_modify_register_plugin();
  922. LDAPDebug( LDAP_DEBUG_PLUGIN,
  923. "Password Modify plugin registered.\n", 0, 0, 0 );
  924. plugin_startall(argc, argv, 1 /* Start Backends */, 1 /* Start Globals */);
  925. if (housekeeping_start((time_t)0, NULL) == NULL) {
  926. exit (1);
  927. }
  928. eq_start(); /* must be done after plugins started */
  929. #ifdef HPUX10
  930. /* HPUX linker voodoo */
  931. if (collation_init == NULL) {
  932. exit (1);
  933. }
  934. #endif /* HPUX */
  935. normalize_oc();
  936. if (n_port) {
  937. } else if ( config_get_security()) {
  938. } else {
  939. #ifdef _WIN32
  940. if( SlapdIsAService() )
  941. {
  942. LDAPServerStatus.dwCurrentState = SERVICE_STOPPED;
  943. LDAPServerStatus.dwCheckPoint = 0;
  944. LDAPServerStatus.dwWaitHint = 0;
  945. LDAPServerStatus.dwWin32ExitCode = 1;
  946. LDAPServerStatus.dwServiceSpecificExitCode = 1;
  947. SetServiceStatus(hLDAPServerServiceStatus, &LDAPServerStatus);
  948. /* Log this event */
  949. ReportSlapdEvent(EVENTLOG_INFORMATION_TYPE, MSG_SERVER_START_FAILED, 1,
  950. "Check server port specification");
  951. }
  952. else
  953. {
  954. char szMessage[256];
  955. PR_snprintf( szMessage, sizeof(szMessage), "The Directory Server %s is terminating due to an error. Check server port specification", pszServerName);
  956. MessageBox(GetDesktopWindow(), szMessage, " ", MB_ICONEXCLAMATION | MB_OK);
  957. }
  958. #endif
  959. exit(1);
  960. }
  961. }
  962. {
  963. Slapi_PBlock pb;
  964. memset( &pb, '\0', sizeof(pb) );
  965. pb.pb_backend = be;
  966. }
  967. if (slapd_exemode != SLAPD_EXEMODE_REFERRAL) {
  968. /* else do this after seteuid() */
  969. lite_entries_init();
  970. /* setup cn=tasks tree */
  971. task_init();
  972. /* pw_init() needs to be here since it uses aci function calls. */
  973. pw_init();
  974. /* Initialize the sasl mapping code */
  975. if (sasl_map_init()) {
  976. LDAPDebug( LDAP_DEBUG_ANY, "Failed to initialize sasl mapping code\n", 0, 0, 0 );
  977. }
  978. }
  979. /*
  980. * search_register_reslimits() and daemon_register_reslimits() can
  981. * be called any time before we start accepting client connections.
  982. * We call these even when running in referral mode because they
  983. * do little harm and registering at least one resource limit forces
  984. * the reslimit subsystem to initialize itself... which prevents
  985. * strange error messages from being logged to the error log for
  986. * the first LDAP connection.
  987. */
  988. if ( search_register_reslimits() != SLAPI_RESLIMIT_STATUS_SUCCESS ||
  989. daemon_register_reslimits() != SLAPI_RESLIMIT_STATUS_SUCCESS ) {
  990. exit( 1 );
  991. }
  992. {
  993. time( &starttime );
  994. slapd_daemon(&ports_info);
  995. }
  996. LDAPDebug( LDAP_DEBUG_ANY, "slapd stopped.\n", 0, 0, 0 );
  997. reslimit_cleanup();
  998. compute_terminate();
  999. vattr_cleanup();
  1000. sasl_map_done();
  1001. PR_Cleanup();
  1002. #ifdef _WIN32
  1003. /* Clean up the mutex used to interlock processes, before we exit */
  1004. remove_slapd_process();
  1005. #endif
  1006. #if ( defined( hpux ) || defined( irix ) || defined( aix ) || defined( OSF1 ))
  1007. exit( 0 );
  1008. #else
  1009. return 0;
  1010. #endif
  1011. }
  1012. #if ( defined( hpux ) || defined( irix ))
  1013. void *
  1014. signal2sigaction( int s, void *a )
  1015. {
  1016. struct sigaction act;
  1017. memset(&act, 0, sizeof(struct sigaction));
  1018. act.sa_handler = (VFP)a;
  1019. act.sa_flags = 0;
  1020. (void)sigemptyset( &act.sa_mask );
  1021. (void)sigaddset( &act.sa_mask, s );
  1022. (void)sigaction( s, &act, NULL );
  1023. }
  1024. #endif /* hpux || irix */
  1025. static void
  1026. register_objects()
  1027. {
  1028. get_operation_object_type();
  1029. daemon_register_connection();
  1030. get_entry_object_type();
  1031. mapping_tree_get_extension_type ();
  1032. }
  1033. static void
  1034. process_command_line(int argc, char **argv, char *myname,
  1035. char **extraname)
  1036. {
  1037. int i;
  1038. char errorbuf[SLAPI_DSE_RETURNTEXT_SIZE];
  1039. char *opts;
  1040. static struct opt_ext *long_opts;
  1041. int longopt_index=0;
  1042. /*
  1043. * Refer to the file getopt_ext.h for an overview of how to use the
  1044. * long option names
  1045. *
  1046. */
  1047. /*
  1048. * when a new option letter is used, please move it from the "available"
  1049. * list to the "used" list.
  1050. *
  1051. */
  1052. /*
  1053. * single-letter options already in use:
  1054. *
  1055. * a C c D E d f G g i
  1056. * L l N m n O o P p r S s T t
  1057. * u v V w x Z z
  1058. *
  1059. * 1
  1060. *
  1061. */
  1062. /*
  1063. * single-letter options still available:
  1064. *
  1065. * A B b e F H h I J j
  1066. * K k M Q q R
  1067. * W X Y y
  1068. *
  1069. * 2 3 4 5 6 7 8 9 0
  1070. *
  1071. */
  1072. char *opts_dbtest = "vd:n:SD:";
  1073. struct opt_ext long_options_dbtest[] = {
  1074. {"version",ArgNone,'v'},
  1075. {"debug",ArgRequired,'d'},
  1076. {"backend",ArgRequired,'n'},
  1077. {"allowMultipleProcesses",ArgNone,'S'},
  1078. {"configDir",ArgRequired,'D'},
  1079. {0,0,0}};
  1080. char *opts_db2ldif = "vd:D:ENa:rs:x:CSut:n:UmMo1";
  1081. struct opt_ext long_options_db2ldif[] = {
  1082. {"version",ArgNone,'v'},
  1083. {"debug",ArgRequired,'d'},
  1084. {"dontPrintKey",ArgNone,'n'},
  1085. {"archive",ArgRequired,'a'},
  1086. {"replica",ArgNone,'r'},
  1087. {"include",ArgRequired,'s'},
  1088. {"exclude",ArgRequired,'x'},
  1089. /*{"whatshouldwecallthis",ArgNone,'C'},*/
  1090. {"allowMultipleProcesses",ArgNone,'S'},
  1091. {"noUniqueIds",ArgNone,'u'},
  1092. {"configDir",ArgRequired,'D'},
  1093. {"encrypt",ArgOptional,'E'},
  1094. {"nowrap",ArgNone,'U'},
  1095. {"minimalEncode",ArgNone,'m'},
  1096. {"oneOutputFile",ArgNone,'o'},
  1097. {"multipleOutputFile",ArgNone,'M'},
  1098. {"noVersionNum",ArgNone,'1'},
  1099. {0,0,0}};
  1100. char *opts_ldif2db = "vd:i:g:G:n:s:x:NOCc:St:D:E";
  1101. struct opt_ext long_options_ldif2db[] = {
  1102. {"version",ArgNone,'v'},
  1103. {"debug",ArgRequired,'d'},
  1104. {"ldiffile",ArgRequired,'i'},
  1105. {"generateUniqueId",ArgOptional,'g'},
  1106. {"backend",ArgRequired,'n'},
  1107. {"include",ArgRequired,'s'},
  1108. {"exclude",ArgRequired,'x'},
  1109. {"noindex",ArgNone,'O'},
  1110. /*{"whatshouldwecallthis",ArgNone,'C'},*/
  1111. /*{"whatshouldwecallthis",ArgRequired,'c'},*/
  1112. {"allowMultipleProcesses",ArgNone,'S'},
  1113. {"namespaceid", ArgRequired, 'G'},
  1114. {"nostate",ArgNone,'Z'},
  1115. {"configDir",ArgRequired,'D'},
  1116. {"encrypt",ArgOptional,'E'},
  1117. {0,0,0}};
  1118. char *opts_archive2db = "vd:i:a:n:SD:";
  1119. struct opt_ext long_options_archive2db[] = {
  1120. {"version",ArgNone,'v'},
  1121. {"debug",ArgRequired,'d'},
  1122. {"pidfile",ArgRequired,'i'},
  1123. {"archive",ArgRequired,'a'},
  1124. {"backEndInstName",ArgRequired,'n'},
  1125. {"allowMultipleProcesses",ArgNone,'S'},
  1126. {"configDir",ArgRequired,'D'},
  1127. {0,0,0}};
  1128. char *opts_db2archive = "vd:i:a:SD:";
  1129. struct opt_ext long_options_db2archive[] = {
  1130. {"version",ArgNone,'v'},
  1131. {"debug",ArgRequired,'d'},
  1132. {"pidfile",ArgRequired,'i'},
  1133. {"archive",ArgRequired,'a'},
  1134. {"allowMultipleProcesses",ArgNone,'S'},
  1135. {"configDir",ArgRequired,'D'},
  1136. {0,0,0}};
  1137. char *opts_db2index = "vd:a:t:T:SD:n:s:x:";
  1138. struct opt_ext long_options_db2index[] = {
  1139. {"version",ArgNone,'v'},
  1140. {"debug",ArgRequired,'d'},
  1141. {"backend",ArgRequired,'n'},
  1142. {"archive",ArgRequired,'a'},
  1143. {"indexAttribute",ArgRequired,'t'},
  1144. {"vlvIndex",ArgRequired,'T'},
  1145. {"allowMultipleProcesses",ArgNone,'S'},
  1146. {"configDir",ArgRequired,'D'},
  1147. {"include",ArgRequired,'s'},
  1148. {"exclude",ArgRequired,'x'},
  1149. {0,0,0}};
  1150. char *opts_upgradedb = "vfd:a:D:";
  1151. struct opt_ext long_options_upgradedb[] = {
  1152. {"version",ArgNone,'v'},
  1153. {"debug",ArgRequired,'d'},
  1154. {"force",ArgNone,'f'},
  1155. {"archive",ArgRequired,'a'},
  1156. {"configDir",ArgRequired,'D'},
  1157. {0,0,0}};
  1158. char *opts_referral = "vd:p:r:SD:";
  1159. struct opt_ext long_options_referral[] = {
  1160. {"version",ArgNone,'v'},
  1161. {"debug",ArgRequired,'d'},
  1162. {"port",ArgRequired,'p'},
  1163. {"referralMode",ArgRequired,'r'},
  1164. {"allowMultipleProcesses",ArgNone,'S'},
  1165. {"configDir",ArgRequired,'D'},
  1166. {0,0,0}};
  1167. char *opts_suffix2instance = "s:D:";
  1168. struct opt_ext long_options_suffix2instance[] = {
  1169. {"suffix",ArgRequired,'s'},
  1170. {"instanceDir",ArgRequired,'D'},
  1171. {0,0,0}};
  1172. char *opts_slapd = "vVd:i:SD:w:";
  1173. struct opt_ext long_options_slapd[] = {
  1174. {"version",ArgNone,'v'},
  1175. {"versionFull",ArgNone,'V'},
  1176. {"debug",ArgRequired,'d'},
  1177. {"pidfile",ArgRequired,'i'},
  1178. {"allowMultipleProcesses",ArgNone,'S'},
  1179. {"configDir",ArgRequired,'D'},
  1180. {"startpidfile",ArgRequired,'w'},
  1181. {0,0,0}};
  1182. /*
  1183. * determine which of serveral modes we are executing in.
  1184. */
  1185. *extraname = NULL;
  1186. if (( slapd_exemode = name2exemode( myname, myname, 0 ))
  1187. == SLAPD_EXEMODE_UNKNOWN ) {
  1188. if ( argv[1] != NULL && argv[1][0] != '-' ) {
  1189. slapd_exemode = name2exemode( myname, argv[1], 1 );
  1190. *extraname = argv[1];
  1191. optind_ext = 2; /* make getopt() skip argv[1] */
  1192. optind = 2;
  1193. }
  1194. }
  1195. if ( slapd_exemode == SLAPD_EXEMODE_UNKNOWN ) {
  1196. slapd_exemode = SLAPD_EXEMODE_SLAPD; /* default */
  1197. }
  1198. /*
  1199. * richm: If running in regular slapd server mode, allow the front
  1200. * end dse files (dse.ldif and ldbm.ldif) to be written in case of
  1201. * additions or modifications. In all other modes, these files
  1202. * should only be read and never written.
  1203. */
  1204. if (slapd_exemode == SLAPD_EXEMODE_SLAPD ||
  1205. slapd_exemode == SLAPD_EXEMODE_ARCHIVE2DB || /* bak2db adjusts config */
  1206. slapd_exemode == SLAPD_EXEMODE_UPGRADEDB) /* update idl-switch */
  1207. dse_unset_dont_ever_write_dse_files();
  1208. /* maintain compatibility with pre-5.x options */
  1209. switch( slapd_exemode ) {
  1210. case SLAPD_EXEMODE_DBTEST:
  1211. opts = opts_dbtest;
  1212. long_opts = long_options_dbtest;
  1213. break;
  1214. case SLAPD_EXEMODE_DB2LDIF:
  1215. opts = opts_db2ldif;
  1216. long_opts = long_options_db2ldif;
  1217. break;
  1218. case SLAPD_EXEMODE_LDIF2DB:
  1219. opts = opts_ldif2db;
  1220. long_opts = long_options_ldif2db;
  1221. break;
  1222. case SLAPD_EXEMODE_ARCHIVE2DB:
  1223. opts = opts_archive2db;
  1224. long_opts = long_options_archive2db;
  1225. break;
  1226. case SLAPD_EXEMODE_DB2ARCHIVE:
  1227. init_cmd_shutdown_detect();
  1228. opts = opts_db2archive;
  1229. long_opts = long_options_db2archive;
  1230. break;
  1231. case SLAPD_EXEMODE_DB2INDEX:
  1232. opts = opts_db2index;
  1233. long_opts = long_options_db2index;
  1234. break;
  1235. case SLAPD_EXEMODE_REFERRAL:
  1236. opts = opts_referral;
  1237. long_opts = long_options_referral;
  1238. break;
  1239. case SLAPD_EXEMODE_SUFFIX2INSTANCE:
  1240. opts = opts_suffix2instance;
  1241. long_opts = long_options_suffix2instance;
  1242. break;
  1243. case SLAPD_EXEMODE_UPGRADEDB:
  1244. opts = opts_upgradedb;
  1245. long_opts = long_options_upgradedb;
  1246. break;
  1247. default: /* SLAPD_EXEMODE_SLAPD */
  1248. opts = opts_slapd;
  1249. long_opts = long_options_slapd;
  1250. }
  1251. while ( (i = getopt_ext( argc, argv, opts,
  1252. long_opts, &longopt_index)) != EOF ) {
  1253. char *configdir = 0;
  1254. switch ( i ) {
  1255. #ifdef LDAP_DEBUG
  1256. case 'd': /* turn on debugging */
  1257. if ( optarg_ext[0] == '?'
  1258. || 0 == strcasecmp( optarg_ext, "help" )) {
  1259. slapd_debug_level_usage();
  1260. exit( 1 );
  1261. } else {
  1262. should_detach = 0;
  1263. slapd_ldap_debug = slapd_debug_level_string2level( optarg_ext );
  1264. if ( slapd_ldap_debug < 0 ) {
  1265. slapd_debug_level_usage();
  1266. exit( 1 );
  1267. }
  1268. slapd_ldap_debug |= LDAP_DEBUG_ANY;
  1269. }
  1270. break;
  1271. #else
  1272. case 'd': /* turn on debugging */
  1273. fprintf( stderr,
  1274. "must compile with LDAP_DEBUG for debugging\n" );
  1275. break;
  1276. #endif
  1277. case 'D': /* config dir */
  1278. configdir = rel2abspath( optarg_ext );
  1279. #if defined( XP_WIN32 )
  1280. pszServerName = slapi_ch_malloc( MAX_SERVICE_NAME );
  1281. if( !SlapdGetServerNameFromCmdline(pszServerName, configdir, 1) )
  1282. {
  1283. MessageBox(GetDesktopWindow(), "Failed to get the Directory"
  1284. " Server name from the command-line argument.",
  1285. " ", MB_ICONEXCLAMATION | MB_OK);
  1286. exit( 1 );
  1287. }
  1288. #endif
  1289. if ( config_set_configdir( "configdir (-D)",
  1290. configdir, errorbuf, 1) != LDAP_SUCCESS ) {
  1291. fprintf( stderr, "%s: aborting now\n", errorbuf );
  1292. usage( myname, *extraname );
  1293. exit( 1 );
  1294. }
  1295. slapi_ch_free((void **)&configdir);
  1296. break;
  1297. case 'p': /* port on which to listen (referral mode only) */
  1298. if ( config_set_port ( "portnumber (-p)", optarg_ext,
  1299. errorbuf, CONFIG_APPLY ) != LDAP_SUCCESS ) {
  1300. fprintf( stderr, "%s: aborting now\n", errorbuf );
  1301. usage( myname, *extraname );
  1302. exit( 1 );
  1303. }
  1304. break;
  1305. case 'i': /* set pid log file or ldif2db LDIF file */
  1306. if ( slapd_exemode == SLAPD_EXEMODE_LDIF2DB ) {
  1307. char *p;
  1308. /* if LDIF comes through standard input, skip path checking */
  1309. if ( optarg_ext[0] != '-' || strlen(optarg_ext) != 1) {
  1310. #if defined( XP_WIN32 )
  1311. if ( optarg_ext[0] != '/' && optarg_ext[0] != '\\'
  1312. && (!isalpha( optarg_ext[0] ) || (optarg_ext[1] != ':')) ) {
  1313. fprintf( stderr, "%s file could not be opened: absolute path "
  1314. " required.\n", optarg_ext );
  1315. break;
  1316. }
  1317. #else
  1318. if ( optarg_ext[ 0 ] != '/' ) {
  1319. fprintf( stderr, "%s file could not be opened: absolute path "
  1320. " required.\n", optarg_ext );
  1321. break;
  1322. }
  1323. #endif
  1324. }
  1325. p = (char *) slapi_ch_malloc(strlen(optarg_ext) + 1);
  1326. strcpy(p, optarg_ext);
  1327. charray_add(&ldif_file, p);
  1328. ldif_files++;
  1329. } else {
  1330. pid_file = rel2abspath( optarg_ext );
  1331. }
  1332. break;
  1333. case 'w': /* set startup pid file */
  1334. start_pid_file = rel2abspath( optarg_ext );
  1335. break;
  1336. case 'n': /* which backend to do ldif2db/bak2db for */
  1337. if (slapd_exemode == SLAPD_EXEMODE_LDIF2DB ||
  1338. slapd_exemode == SLAPD_EXEMODE_DBTEST ||
  1339. slapd_exemode == SLAPD_EXEMODE_DB2INDEX ||
  1340. slapd_exemode == SLAPD_EXEMODE_ARCHIVE2DB) {
  1341. /* The -n argument will give the name of a backend instance. */
  1342. cmd_line_instance_name = optarg_ext;
  1343. } else if (slapd_exemode == SLAPD_EXEMODE_DB2LDIF) {
  1344. char *s = slapi_ch_strdup(optarg_ext);
  1345. charray_add(&cmd_line_instance_names, s);
  1346. } else {
  1347. ldif_backend = atoi( optarg_ext );
  1348. }
  1349. break;
  1350. case 's': /* which suffix to include in import/export */
  1351. {
  1352. char *s= slapi_dn_normalize ( slapi_ch_strdup(optarg_ext) );
  1353. charray_add(&db2ldif_include,s);
  1354. }
  1355. break;
  1356. case 'x': /* which suffix to exclude in import/export */
  1357. {
  1358. char *s= slapi_dn_normalize ( slapi_ch_strdup(optarg_ext) );
  1359. charray_add(&db2ldif_exclude,s);
  1360. }
  1361. break;
  1362. case 'r': /* db2ldif for replication */
  1363. if (slapd_exemode == SLAPD_EXEMODE_REFERRAL) {
  1364. if (config_set_referral_mode( "referral (-r)", optarg_ext,
  1365. errorbuf, CONFIG_APPLY) != LDAP_SUCCESS) {
  1366. fprintf(stderr, "%s: aborting now\n",
  1367. errorbuf);
  1368. usage(myname, *extraname);
  1369. exit(1);
  1370. }
  1371. break;
  1372. }
  1373. if (slapd_exemode != SLAPD_EXEMODE_DB2LDIF ) {
  1374. usage( myname, *extraname );
  1375. exit( 1 );
  1376. }
  1377. db2ldif_dump_replica = 1;
  1378. break;
  1379. case 'N': /* do not do ldif2db duplicate value check */
  1380. if ( slapd_exemode != SLAPD_EXEMODE_LDIF2DB &&
  1381. slapd_exemode != SLAPD_EXEMODE_DB2LDIF) {
  1382. usage( myname, *extraname );
  1383. exit( 1 );
  1384. }
  1385. /*
  1386. * -N flag is obsolete, but we silently accept it
  1387. * so we don't break customer's scripts.
  1388. */
  1389. /* The -N flag now does what the -n flag used to do for db2ldif.
  1390. * This is so -n cane be used for the instance name just like
  1391. * with ldif2db. */
  1392. if ( slapd_exemode == SLAPD_EXEMODE_DB2LDIF ) {
  1393. ldif_printkey &= ~EXPORT_PRINTKEY;
  1394. }
  1395. break;
  1396. case 'U': /* db2ldif only */
  1397. if ( slapd_exemode != SLAPD_EXEMODE_DB2LDIF ) {
  1398. usage( myname, *extraname );
  1399. exit( 1 );
  1400. }
  1401. /*
  1402. * don't fold (wrap) long lines (default is to fold),
  1403. * as of ldapsearch -T
  1404. */
  1405. ldif_printkey |= EXPORT_NOWRAP;
  1406. break;
  1407. case 'm': /* db2ldif only */
  1408. if ( slapd_exemode != SLAPD_EXEMODE_DB2LDIF ) {
  1409. usage( myname, *extraname );
  1410. exit( 1 );
  1411. }
  1412. /* minimal base64 encoding */
  1413. ldif_printkey |= EXPORT_MINIMAL_ENCODING;
  1414. break;
  1415. case 'M': /* db2ldif only */
  1416. if ( slapd_exemode != SLAPD_EXEMODE_DB2LDIF ) {
  1417. usage( myname, *extraname );
  1418. exit( 1 );
  1419. }
  1420. /*
  1421. * output ldif is stored in several file called intance_filename.
  1422. * by default, all instances are stored in the single filename.
  1423. */
  1424. ldif_printkey &= ~EXPORT_APPENDMODE;
  1425. break;
  1426. case 'o': /* db2ldif only */
  1427. if ( slapd_exemode != SLAPD_EXEMODE_DB2LDIF ) {
  1428. usage( myname, *extraname );
  1429. exit( 1 );
  1430. }
  1431. /*
  1432. * output ldif is stored in one file.
  1433. * by default, each instance is stored in instance_filename.
  1434. */
  1435. ldif_printkey |= EXPORT_APPENDMODE;
  1436. break;
  1437. case 'C':
  1438. if (slapd_exemode == SLAPD_EXEMODE_LDIF2DB) {
  1439. /* used to mean "Cool new import" (which is now
  1440. * the default) -- ignore
  1441. */
  1442. break;
  1443. }
  1444. if (slapd_exemode == SLAPD_EXEMODE_DB2LDIF) {
  1445. /* possibly corrupted db -- don't look at any
  1446. * file except id2entry. yet another overloaded
  1447. * flag.
  1448. */
  1449. ldif_printkey |= EXPORT_ID2ENTRY_ONLY;
  1450. break;
  1451. }
  1452. usage( myname, *extraname );
  1453. exit( 1 );
  1454. case 'c': /* merge chunk size for Cool new import */
  1455. if ( slapd_exemode != SLAPD_EXEMODE_LDIF2DB ) {
  1456. usage( myname, *extraname );
  1457. exit( 1 );
  1458. }
  1459. ldif2db_removedupvals = atoi(optarg_ext); /* We overload this flag---ok since we always check for dupes in the new code */
  1460. break;
  1461. case 'O': /* only create core db, no attr indexes */
  1462. if ( slapd_exemode != SLAPD_EXEMODE_LDIF2DB ) {
  1463. usage( myname, *extraname );
  1464. exit( 1 );
  1465. }
  1466. ldif2db_noattrindexes = 1;
  1467. break;
  1468. case 't': /* attribute type to index - may be repeated */
  1469. case 'T': /* VLV Search to index - may be repeated */
  1470. if ( slapd_exemode == SLAPD_EXEMODE_DB2INDEX ) {
  1471. char *p= slapi_ch_smprintf("%c%s",i,optarg_ext);
  1472. charray_add( &db2index_attrs, p);
  1473. break;
  1474. }
  1475. usage( myname, *extraname );
  1476. exit(1);
  1477. case 'v': /* print version and exit */
  1478. slapd_print_version(0);
  1479. exit( 1 );
  1480. break;
  1481. case 'V':
  1482. slapd_exemode = SLAPD_EXEMODE_PRINTVERSION;
  1483. break;
  1484. case 'a': /* archive pathname for db */
  1485. archive_name = optarg_ext;
  1486. break;
  1487. case 'Z':
  1488. if (slapd_exemode == SLAPD_EXEMODE_LDIF2DB)
  1489. {
  1490. ldif2db_load_state= 0;
  1491. break;
  1492. }
  1493. usage( myname, *extraname );
  1494. exit(1);
  1495. case 'S': /* skip the check for slad running in conflicting modes */
  1496. skip_db_protect_check = 1;
  1497. break;
  1498. case 'u': /* do not dump uniqueid for db2ldif */
  1499. if ( slapd_exemode != SLAPD_EXEMODE_DB2LDIF ) {
  1500. usage( myname, *extraname );
  1501. exit( 1 );
  1502. }
  1503. db2ldif_dump_uniqueid = 0;
  1504. break;
  1505. case 'g': /* generate uniqueid for ldif2db */
  1506. if ( slapd_exemode != SLAPD_EXEMODE_LDIF2DB ) {
  1507. usage( myname, *extraname );
  1508. exit( 1 );
  1509. }
  1510. if (optarg_ext == NULL){
  1511. printf ("ldif2db: generation type is not specified for -g; "
  1512. "random generation is used\n");
  1513. ldif2db_generate_uniqueid = SLAPI_UNIQUEID_GENERATE_TIME_BASED;
  1514. }
  1515. else if (strcasecmp (optarg_ext, "none") == 0)
  1516. ldif2db_generate_uniqueid = SLAPI_UNIQUEID_GENERATE_NONE;
  1517. else if (strcasecmp (optarg_ext, "deterministic") == 0) /* name based */
  1518. ldif2db_generate_uniqueid = SLAPI_UNIQUEID_GENERATE_NAME_BASED;
  1519. else /* default - time based */
  1520. ldif2db_generate_uniqueid = SLAPI_UNIQUEID_GENERATE_TIME_BASED;
  1521. break;
  1522. case 'G': /* namespace id for name based uniqueid generation for ldif2db */
  1523. if ( slapd_exemode != SLAPD_EXEMODE_LDIF2DB ) {
  1524. usage( myname, *extraname );
  1525. exit( 1 );
  1526. }
  1527. ldif2db_namespaceid = optarg_ext;
  1528. break;
  1529. case 'E': /* encrypt data if importing, decrypt if exporting */
  1530. if ( (slapd_exemode != SLAPD_EXEMODE_LDIF2DB) && (slapd_exemode != SLAPD_EXEMODE_DB2LDIF)) {
  1531. usage( myname, *extraname );
  1532. exit( 1 );
  1533. }
  1534. importexport_encrypt = 1;
  1535. break;
  1536. case 'f': /* upgradedb only */
  1537. if ( slapd_exemode != SLAPD_EXEMODE_UPGRADEDB ) {
  1538. usage( myname, *extraname );
  1539. exit( 1 );
  1540. }
  1541. upgradedb_force = SLAPI_UPGRADEDB_FORCE;
  1542. break;
  1543. case '1': /* db2ldif only */
  1544. if ( slapd_exemode != SLAPD_EXEMODE_DB2LDIF ) {
  1545. usage( myname, *extraname );
  1546. exit( 1 );
  1547. }
  1548. /*
  1549. * do not output "version: 1" to the ldif file
  1550. */
  1551. ldif_printkey |= EXPORT_NOVERSION;
  1552. break;
  1553. default:
  1554. usage( myname, *extraname );
  1555. exit( 1 );
  1556. }
  1557. }
  1558. if ((NULL != cmd_line_instance_names)
  1559. && (NULL != cmd_line_instance_names[1])
  1560. && (ldif_printkey & EXPORT_APPENDMODE))
  1561. {
  1562. fprintf(stderr, "WARNING: several backends are being"
  1563. " exported to a single ldif file\n");
  1564. fprintf(stderr, " use option -M to export to"
  1565. " multiple ldif files\n");
  1566. }
  1567. /* Any leftover arguments? */
  1568. if ( optind_last > optind ) {
  1569. usage( myname, *extraname );
  1570. exit( 1 );
  1571. }
  1572. return;
  1573. }
  1574. static int
  1575. lookup_instance_name_by_suffix(char *suffix,
  1576. char ***suffixes, char ***instances, int isexact)
  1577. {
  1578. Slapi_PBlock *pb = slapi_pblock_new();
  1579. Slapi_Entry **entries = NULL, **ep;
  1580. char *query;
  1581. char *backend;
  1582. char *fullsuffix;
  1583. int rval = -1;
  1584. if (pb == NULL)
  1585. goto done;
  1586. if (isexact)
  1587. query = slapi_ch_smprintf("(&(objectclass=nsmappingtree)(|(cn=\"%s\")(cn=%s)))", suffix, suffix);
  1588. else
  1589. query = slapi_ch_smprintf("(&(objectclass=nsmappingtree)(|(cn=*%s\")(cn=*%s)))", suffix, suffix);
  1590. if (query == NULL)
  1591. goto done;
  1592. slapi_search_internal_set_pb(pb, "cn=mapping tree,cn=config",
  1593. LDAP_SCOPE_SUBTREE, query, NULL, 0, NULL, NULL,
  1594. (void *)plugin_get_default_component_id(), 0);
  1595. slapi_search_internal_pb(pb);
  1596. slapi_ch_free((void **)&query);
  1597. slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_RESULT, &rval);
  1598. if (rval != LDAP_SUCCESS)
  1599. goto done;
  1600. slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES, &entries);
  1601. if ((entries == NULL) || (entries[0] == NULL))
  1602. goto done;
  1603. rval = 0;
  1604. for (ep = entries; *ep; ep++) {
  1605. backend = slapi_entry_attr_get_charptr(*ep, "nsslapd-backend");
  1606. if (backend) {
  1607. charray_add(instances, backend);
  1608. if (suffixes) {
  1609. fullsuffix = slapi_entry_attr_get_charptr(*ep, "cn");
  1610. charray_add(suffixes, fullsuffix); /* NULL is ok */
  1611. }
  1612. }
  1613. }
  1614. done:
  1615. slapi_free_search_results_internal(pb);
  1616. slapi_pblock_destroy(pb);
  1617. return rval;
  1618. }
  1619. int
  1620. lookup_instance_name_by_suffixes(char **included, char **excluded,
  1621. char ***instances)
  1622. {
  1623. char **incl_instances, **excl_instances;
  1624. char **p;
  1625. int rval = -1;
  1626. incl_instances = NULL;
  1627. for (p = included; p && *p; p++) {
  1628. if (lookup_instance_name_by_suffix(*p, NULL, &incl_instances, 0) < 0)
  1629. return rval;
  1630. }
  1631. excl_instances = NULL;
  1632. for (p = excluded; p && *p; p++) {
  1633. if (lookup_instance_name_by_suffix(*p, NULL, &excl_instances, 0) < 0)
  1634. return rval;
  1635. }
  1636. rval = 0;
  1637. charray_subtract(incl_instances, excl_instances, NULL);
  1638. charray_free(excl_instances);
  1639. *instances = incl_instances;
  1640. return rval;
  1641. }
  1642. /* helper function for ldif2db & friends -- given an instance name, lookup
  1643. * the plugin name in the DSE. this assumes the DSE has already been loaded.
  1644. */
  1645. static struct slapdplugin *lookup_plugin_by_instance_name(const char *name)
  1646. {
  1647. Slapi_Entry **entries = NULL;
  1648. Slapi_PBlock *pb = slapi_pblock_new();
  1649. struct slapdplugin *plugin;
  1650. char *query, *dn, *cn;
  1651. int ret = 0;
  1652. if (pb == NULL)
  1653. return NULL;
  1654. query = slapi_ch_smprintf("(&(cn=%s)(objectclass=nsBackendInstance))", name);
  1655. if (query == NULL) {
  1656. slapi_pblock_destroy(pb);
  1657. return NULL;
  1658. }
  1659. slapi_search_internal_set_pb(pb, "cn=plugins,cn=config",
  1660. LDAP_SCOPE_SUBTREE, query, NULL, 0, NULL, NULL,
  1661. (void *)plugin_get_default_component_id(), 0);
  1662. slapi_search_internal_pb(pb);
  1663. slapi_ch_free((void **)&query);
  1664. slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_RESULT, &ret);
  1665. if (ret != LDAP_SUCCESS) {
  1666. slapi_free_search_results_internal(pb);
  1667. slapi_pblock_destroy(pb);
  1668. return NULL;
  1669. }
  1670. slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES, &entries);
  1671. if ((entries == NULL) || (entries[0] == NULL)) {
  1672. slapi_free_search_results_internal(pb);
  1673. slapi_pblock_destroy(pb);
  1674. return NULL;
  1675. }
  1676. /* okay -- have the entry for this instance, now let's chop up the dn */
  1677. /* parent dn is the plugin */
  1678. dn = slapi_dn_parent(slapi_entry_get_dn(entries[0]));
  1679. /* clean up */
  1680. slapi_free_search_results_internal(pb);
  1681. entries = NULL;
  1682. slapi_pblock_destroy(pb);
  1683. pb = NULL; /* this seems redundant . . . until we add code after this line */
  1684. /* now... look up the parent */
  1685. pb = slapi_pblock_new();
  1686. slapi_search_internal_set_pb(pb, dn, LDAP_SCOPE_BASE,
  1687. "(objectclass=nsSlapdPlugin)", NULL, 0, NULL, NULL,
  1688. (void *)plugin_get_default_component_id(), 0);
  1689. slapi_search_internal_pb(pb);
  1690. slapi_ch_free((void **)&dn);
  1691. slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_RESULT, &ret);
  1692. if (ret != LDAP_SUCCESS) {
  1693. slapi_free_search_results_internal(pb);
  1694. slapi_pblock_destroy(pb);
  1695. return NULL;
  1696. }
  1697. slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES, &entries);
  1698. if ((entries == NULL) || (entries[0] == NULL)) {
  1699. slapi_free_search_results_internal(pb);
  1700. slapi_pblock_destroy(pb);
  1701. return NULL;
  1702. }
  1703. cn = slapi_entry_attr_get_charptr(entries[0], "cn");
  1704. slapi_free_search_results_internal(pb);
  1705. slapi_pblock_destroy(pb);
  1706. plugin = plugin_get_by_name(cn);
  1707. slapi_ch_free((void **)&cn);
  1708. return plugin;
  1709. }
  1710. static int
  1711. slapd_exemode_ldif2db()
  1712. {
  1713. int return_value= 0;
  1714. Slapi_PBlock pb;
  1715. struct slapdplugin *plugin;
  1716. slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig();
  1717. if ( ldif_file == NULL ) {
  1718. LDAPDebug( LDAP_DEBUG_ANY,
  1719. "ERROR: Required argument -i <ldiffile> missing\n",
  1720. 0, 0, 0 );
  1721. usage( myname, extraname );
  1722. exit( 1 );
  1723. }
  1724. /* this should be the first time this are called! if the init order
  1725. * is ever changed, these lines should be changed (or erased)!
  1726. */
  1727. mapping_tree_init();
  1728. /*
  1729. * if instance is given, just use it to get the backend.
  1730. * otherwise, we use included/excluded suffix list to specify a backend.
  1731. */
  1732. if (NULL == cmd_line_instance_name) {
  1733. char **instances, **ip;
  1734. int counter;
  1735. if (lookup_instance_name_by_suffixes(db2ldif_include, db2ldif_exclude,
  1736. &instances) < 0) {
  1737. LDAPDebug(LDAP_DEBUG_ANY,
  1738. "ERROR: backend instances name [-n <name>] or "
  1739. "included suffix [-s <suffix>] need to be specified.\n",
  1740. 0, 0, 0);
  1741. exit(1);
  1742. }
  1743. if (instances) {
  1744. for (ip = instances, counter = 0; ip && *ip; ip++, counter++)
  1745. ;
  1746. if (counter == 0) {
  1747. LDAPDebug(LDAP_DEBUG_ANY,
  1748. "ERROR 1: There is no backend instance to import to.\n",
  1749. 0, 0, 0);
  1750. exit(1);
  1751. } else if (counter > 1) {
  1752. int i;
  1753. LDAPDebug(LDAP_DEBUG_ANY,
  1754. "ERROR: There are multiple backend instances specified:\n",
  1755. 0, 0, 0);
  1756. for (i = 0; i < counter; i++)
  1757. LDAPDebug(LDAP_DEBUG_ANY, " : %s\n",
  1758. instances[i], 0, 0);
  1759. exit(1);
  1760. } else {
  1761. LDAPDebug(LDAP_DEBUG_ANY, "Backend Instance: %s\n",
  1762. *instances, 0, 0);
  1763. cmd_line_instance_name = *instances;
  1764. }
  1765. } else {
  1766. LDAPDebug(LDAP_DEBUG_ANY,
  1767. "ERROR 2: There is no backend instance to import to.\n",
  1768. 0, 0, 0);
  1769. exit(1);
  1770. }
  1771. }
  1772. plugin = lookup_plugin_by_instance_name(cmd_line_instance_name);
  1773. if (plugin == NULL) {
  1774. LDAPDebug(LDAP_DEBUG_ANY,
  1775. "ERROR: Could not find backend '%s'.\n",
  1776. cmd_line_instance_name, 0, 0);
  1777. exit(1);
  1778. }
  1779. /* Make sure we aren't going to run slapd in
  1780. * a mode that is going to conflict with other
  1781. * slapd processes that are currently running
  1782. */
  1783. if ( add_new_slapd_process(slapd_exemode, db2ldif_dump_replica,
  1784. skip_db_protect_check) == -1 ) {
  1785. LDAPDebug( LDAP_DEBUG_ANY,
  1786. "Shutting down due to possible conflicts with other slapd processes\n",
  1787. 0, 0, 0 );
  1788. exit(1);
  1789. }
  1790. /* check for slapi v2 support */
  1791. if (! SLAPI_PLUGIN_IS_V2(plugin)) {
  1792. LDAPDebug(LDAP_DEBUG_ANY, "ERROR: %s is too old to do imports.\n",
  1793. plugin->plg_name, 0, 0);
  1794. exit(1);
  1795. }
  1796. memset( &pb, '\0', sizeof(pb) );
  1797. pb.pb_backend = NULL;
  1798. pb.pb_plugin = plugin;
  1799. pb.pb_removedupvals = ldif2db_removedupvals;
  1800. pb.pb_ldif2db_noattrindexes = ldif2db_noattrindexes;
  1801. pb.pb_ldif_generate_uniqueid = ldif2db_generate_uniqueid;
  1802. pb.pb_ldif_namespaceid = ldif2db_namespaceid;
  1803. pb.pb_ldif_encrypt = importexport_encrypt;
  1804. /* pb.pb_ldif_load_state = ldif2db_load_state; */
  1805. pb.pb_instance_name = cmd_line_instance_name;
  1806. pb.pb_ldif_files = ldif_file;
  1807. pb.pb_ldif_include = db2ldif_include;
  1808. pb.pb_ldif_exclude = db2ldif_exclude;
  1809. pb.pb_task_flags = TASK_RUNNING_FROM_COMMANDLINE;
  1810. #ifndef _WIN32
  1811. main_setuid(slapdFrontendConfig->localuser);
  1812. #endif
  1813. if ( plugin->plg_ldif2db != NULL ) {
  1814. return_value = (*plugin->plg_ldif2db)( &pb );
  1815. } else {
  1816. LDAPDebug( LDAP_DEBUG_ANY,
  1817. "ERROR: no ldif2db function defined for "
  1818. "%s\n", plugin->plg_name, 0, 0 );
  1819. return_value = -1;
  1820. }
  1821. slapi_ch_free((void**)&myname );
  1822. charray_free( db2index_attrs );
  1823. charray_free(ldif_file);
  1824. return( return_value );
  1825. }
  1826. static int
  1827. slapd_exemode_db2ldif(int argc, char** argv)
  1828. {
  1829. int return_value= 0;
  1830. Slapi_PBlock pb;
  1831. struct slapdplugin *plugin;
  1832. slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig();
  1833. char *my_ldiffile;
  1834. char **instp;
  1835. /* this should be the first time this are called! if the init order
  1836. * is ever changed, these lines should be changed (or erased)!
  1837. */
  1838. mapping_tree_init();
  1839. /*
  1840. * if instance is given, just pass it to the backend.
  1841. * otherwise, we use included/excluded suffix list to specify a backend.
  1842. */
  1843. if (NULL == cmd_line_instance_names) {
  1844. char **instances, **ip;
  1845. int counter;
  1846. if (lookup_instance_name_by_suffixes(db2ldif_include, db2ldif_exclude,
  1847. &instances) < 0) {
  1848. LDAPDebug(LDAP_DEBUG_ANY,
  1849. "ERROR: backend instances name [-n <name>] or "
  1850. "included suffix [-s <suffix>] need to be specified.\n",
  1851. 0, 0, 0);
  1852. exit(1);
  1853. }
  1854. if (instances) {
  1855. for (ip = instances, counter = 0; ip && *ip; ip++, counter++)
  1856. ;
  1857. if (counter == 0) {
  1858. LDAPDebug(LDAP_DEBUG_ANY,
  1859. "ERROR 1: There is no backend instance to export from.\n",
  1860. 0, 0, 0);
  1861. exit(1);
  1862. } else {
  1863. LDAPDebug(LDAP_DEBUG_ANY, "Backend Instance: %s\n",
  1864. *instances, 0, 0);
  1865. cmd_line_instance_names = instances;
  1866. }
  1867. } else {
  1868. LDAPDebug(LDAP_DEBUG_ANY,
  1869. "ERROR 2: There is no backend instance to export from.\n",
  1870. 0, 0, 0);
  1871. exit(1);
  1872. }
  1873. }
  1874. #ifndef _WIN32
  1875. /* [622984] db2lidf -r changes database file ownership
  1876. * should call setuid before "db2ldif_dump_replica" */
  1877. main_setuid(slapdFrontendConfig->localuser);
  1878. #endif
  1879. for (instp = cmd_line_instance_names; instp && *instp; instp++) {
  1880. int release_me = 0;
  1881. plugin = lookup_plugin_by_instance_name(*instp);
  1882. if (plugin == NULL) {
  1883. LDAPDebug(LDAP_DEBUG_ANY,
  1884. "ERROR: Could not find backend '%s'.\n",
  1885. *instp, 0, 0);
  1886. exit(1);
  1887. }
  1888. if (plugin->plg_db2ldif == NULL) {
  1889. LDAPDebug(LDAP_DEBUG_ANY, "ERROR: no db2ldif function defined for "
  1890. "backend %s - cannot export\n", *instp, 0, 0);
  1891. exit(1);
  1892. }
  1893. /* Make sure we aren't going to run slapd in
  1894. * a mode that is going to conflict with other
  1895. * slapd processes that are currently running
  1896. */
  1897. if ( add_new_slapd_process(slapd_exemode, db2ldif_dump_replica,
  1898. skip_db_protect_check) == -1 ) {
  1899. LDAPDebug( LDAP_DEBUG_ANY,
  1900. "Shutting down due to possible conflicts "
  1901. "with other slapd processes\n",
  1902. 0, 0, 0 );
  1903. exit(1);
  1904. }
  1905. if ( config_is_slapd_lite () &&
  1906. !slapi_config_get_readonly () && is_slapd_running() ) {
  1907. LDAPDebug( LDAP_DEBUG_ANY, "%s\n", LITE_BACKUP_ERR, 0, 0);
  1908. exit ( 1 );
  1909. }
  1910. if (! (SLAPI_PLUGIN_IS_V2(plugin))) {
  1911. LDAPDebug(LDAP_DEBUG_ANY, "ERROR: %s is too old to do exports.\n",
  1912. plugin->plg_name, 0, 0);
  1913. exit(1);
  1914. }
  1915. memset( &pb, '\0', sizeof(pb) );
  1916. pb.pb_backend = NULL;
  1917. pb.pb_plugin = plugin;
  1918. pb.pb_ldif_include = db2ldif_include;
  1919. pb.pb_ldif_exclude = db2ldif_exclude;
  1920. pb.pb_ldif_dump_replica = db2ldif_dump_replica;
  1921. pb.pb_ldif_dump_uniqueid = db2ldif_dump_uniqueid;
  1922. pb.pb_ldif_encrypt = importexport_encrypt;
  1923. pb.pb_instance_name = *instp;
  1924. pb.pb_task_flags = TASK_RUNNING_FROM_COMMANDLINE;
  1925. if (is_slapd_running())
  1926. pb.pb_server_running = 1;
  1927. else
  1928. pb.pb_server_running = 0;
  1929. if (db2ldif_dump_replica) {
  1930. eq_init(); /* must be done before plugins started */
  1931. ps_init_psearch_system(); /* must come before plugin_startall() */
  1932. plugin_startall(argc, argv, 1 /* Start Backends */,
  1933. 1 /* Start Globals */);
  1934. eq_start(); /* must be done after plugins started */
  1935. }
  1936. pb.pb_ldif_file = NULL;
  1937. if ( archive_name ) { /* redirect stdout to this file: */
  1938. char *p, *q;
  1939. #if defined( XP_WIN32 )
  1940. char sep = '\\';
  1941. if (NULL != strchr(archive_name, '/'))
  1942. sep = '/';
  1943. #else
  1944. char sep = '/';
  1945. #endif
  1946. my_ldiffile = archive_name;
  1947. if (ldif_printkey & EXPORT_APPENDMODE) {
  1948. if (instp == cmd_line_instance_names) { /* first export */
  1949. ldif_printkey |= EXPORT_APPENDMODE_1;
  1950. } else {
  1951. ldif_printkey &= ~EXPORT_APPENDMODE_1;
  1952. }
  1953. } else { /* not APPENDMODE */
  1954. if (strcmp(archive_name, "-")) { /* not '-' */
  1955. my_ldiffile =
  1956. (char *)slapi_ch_malloc((unsigned long)(strlen(archive_name)
  1957. + strlen(*instp) + 2));
  1958. p = strrchr(archive_name, sep);
  1959. if (NULL == p) {
  1960. sprintf(my_ldiffile, "%s_%s", *instp, archive_name);
  1961. } else {
  1962. q = p + 1;
  1963. *p = '\0';
  1964. sprintf(my_ldiffile, "%s%c%s_%s",
  1965. archive_name, sep, *instp, q);
  1966. *p = sep;
  1967. }
  1968. release_me = 1;
  1969. }
  1970. }
  1971. fprintf(stderr, "ldiffile: %s\n", my_ldiffile);
  1972. /* just send the filename to the backend and let
  1973. * the backend open it (so they can do special
  1974. * stuff for 64-bit fs)
  1975. */
  1976. pb.pb_ldif_file = my_ldiffile;
  1977. pb.pb_ldif_printkey = ldif_printkey;
  1978. }
  1979. return_value = (plugin->plg_db2ldif)( &pb );
  1980. if (release_me) {
  1981. slapi_ch_free((void **)&my_ldiffile);
  1982. }
  1983. }
  1984. slapi_ch_free( (void**)&myname );
  1985. if (db2ldif_dump_replica) {
  1986. plugin_closeall( 1 /* Close Backends */, 1 /* Close Globals */);
  1987. }
  1988. return( return_value );
  1989. }
  1990. static int
  1991. slapd_exemode_suffix2instance()
  1992. {
  1993. int return_value = 0;
  1994. char **instances = NULL;
  1995. char **suffixes = NULL;
  1996. char **p, **q, **r;
  1997. /* this should be the first time this are called! if the init order
  1998. * is ever changed, these lines should be changed (or erased)!
  1999. */
  2000. mapping_tree_init();
  2001. for (p = db2ldif_include; p && *p; p++) {
  2002. if (lookup_instance_name_by_suffix(*p, &suffixes, &instances, 0) < 0)
  2003. continue;
  2004. fprintf(stderr, "Suffix, Instance name pair(s) under \"%s\":\n", *p);
  2005. if (instances)
  2006. for (q = suffixes, r = instances; *r; q++, r++)
  2007. fprintf(stderr, "\tsuffix %s; instance name \"%s\"\n",
  2008. *q?*q:"-", *r);
  2009. else
  2010. fprintf(stderr, "\tNo instance\n");
  2011. charray_free(suffixes);
  2012. suffixes = NULL;
  2013. charray_free(instances);
  2014. instances = NULL;
  2015. }
  2016. return (return_value);
  2017. }
  2018. static int slapd_exemode_db2index()
  2019. {
  2020. int return_value= 0;
  2021. struct slapdplugin *plugin;
  2022. Slapi_PBlock pb;
  2023. slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig();
  2024. mapping_tree_init();
  2025. /*
  2026. * if instance is given, just use it to get the backend.
  2027. * otherwise, we use included/excluded suffix list to specify a backend.
  2028. */
  2029. if (NULL == cmd_line_instance_name) {
  2030. char **instances, **ip;
  2031. int counter;
  2032. if (lookup_instance_name_by_suffixes(db2ldif_include, db2ldif_exclude,
  2033. &instances) < 0) {
  2034. LDAPDebug(LDAP_DEBUG_ANY,
  2035. "ERROR: backend instances name [-n <name>] or "
  2036. "included suffix [-s <suffix>] need to be specified.\n",
  2037. 0, 0, 0);
  2038. exit(1);
  2039. }
  2040. if (instances) {
  2041. for (ip = instances, counter = 0; ip && *ip; ip++, counter++)
  2042. ;
  2043. if (counter == 0) {
  2044. LDAPDebug(LDAP_DEBUG_ANY,
  2045. "ERROR 1: There is no backend instance to import to.\n",
  2046. 0, 0, 0);
  2047. exit(1);
  2048. } else if (counter > 1) {
  2049. int i;
  2050. LDAPDebug(LDAP_DEBUG_ANY,
  2051. "ERROR: There are multiple backend instances specified:\n",
  2052. 0, 0, 0);
  2053. for (i = 0; i < counter; i++)
  2054. LDAPDebug(LDAP_DEBUG_ANY, " : %s\n",
  2055. instances[i], 0, 0);
  2056. exit(1);
  2057. } else {
  2058. LDAPDebug(LDAP_DEBUG_ANY, "Backend Instance: %s\n",
  2059. *instances, 0, 0);
  2060. cmd_line_instance_name = *instances;
  2061. }
  2062. } else {
  2063. LDAPDebug(LDAP_DEBUG_ANY,
  2064. "ERROR 2: There is no backend instance to import to.\n",
  2065. 0, 0, 0);
  2066. exit(1);
  2067. }
  2068. }
  2069. plugin = lookup_plugin_by_instance_name(cmd_line_instance_name);
  2070. if (plugin == NULL) {
  2071. LDAPDebug(LDAP_DEBUG_ANY,
  2072. "ERROR: Could not find backend '%s'.\n",
  2073. cmd_line_instance_name, 0, 0);
  2074. exit(1);
  2075. }
  2076. /* make sure nothing else is running */
  2077. if (add_new_slapd_process(slapd_exemode, db2ldif_dump_replica,
  2078. skip_db_protect_check) == -1) {
  2079. LDAPDebug(LDAP_DEBUG_ANY,
  2080. "Shutting down due to possible conflicts with other "
  2081. "slapd processes.\n", 0, 0, 0);
  2082. exit(1);
  2083. }
  2084. if ( db2index_attrs == NULL ) {
  2085. usage( myname, extraname );
  2086. exit( 1 );
  2087. }
  2088. memset( &pb, '\0', sizeof(pb) );
  2089. pb.pb_backend = NULL;
  2090. pb.pb_plugin = plugin;
  2091. pb.pb_db2index_attrs = db2index_attrs;
  2092. pb.pb_instance_name = cmd_line_instance_name;
  2093. pb.pb_task_flags = TASK_RUNNING_FROM_COMMANDLINE;
  2094. #ifndef _WIN32
  2095. main_setuid(slapdFrontendConfig->localuser);
  2096. #endif
  2097. return_value = (*plugin->plg_db2index)( &pb );
  2098. slapi_ch_free( (void**)&myname );
  2099. return( return_value );
  2100. }
  2101. static int
  2102. slapd_exemode_db2archive()
  2103. {
  2104. int return_value= 0;
  2105. Slapi_PBlock pb;
  2106. struct slapdplugin *backend_plugin;
  2107. slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig();
  2108. if ((backend_plugin = plugin_get_by_name("ldbm database")) == NULL) {
  2109. LDAPDebug(LDAP_DEBUG_ANY,
  2110. "ERROR: Could not find the ldbm backend plugin.\n",
  2111. 0, 0, 0);
  2112. exit(1);
  2113. }
  2114. if (NULL == archive_name) {
  2115. LDAPDebug( LDAP_DEBUG_ANY,
  2116. "ERROR: no archive directory supplied\n",
  2117. 0, 0, 0 );
  2118. exit( 1 );
  2119. }
  2120. if ( config_is_slapd_lite () && !slapi_config_get_readonly () && is_slapd_running ()) {
  2121. LDAPDebug( LDAP_DEBUG_ANY, "%s\n", LITE_BACKUP_ERR, 0, 0);
  2122. exit ( 1 );
  2123. }
  2124. /* Make sure we aren't going to run slapd in
  2125. * a mode that is going to conflict with other
  2126. * slapd processes that are currently running
  2127. */
  2128. if ( add_new_slapd_process(slapd_exemode, db2ldif_dump_replica,
  2129. skip_db_protect_check) == -1 ) {
  2130. LDAPDebug( LDAP_DEBUG_ANY,
  2131. "Shutting down due to possible conflicts with other slapd processes\n",
  2132. 0, 0, 0 );
  2133. exit(1);
  2134. }
  2135. if (compute_init()) {
  2136. LDAPDebug(LDAP_DEBUG_ANY, "Initialization Failed 0 %d\n",return_value,0,0);
  2137. exit (1);
  2138. }
  2139. memset( &pb, '\0', sizeof(pb) );
  2140. pb.pb_backend = NULL;
  2141. pb.pb_plugin = backend_plugin;
  2142. pb.pb_instance_name = cmd_line_instance_name;
  2143. pb.pb_seq_val = archive_name;
  2144. pb.pb_task_flags = TASK_RUNNING_FROM_COMMANDLINE;
  2145. #ifndef _WIN32
  2146. main_setuid(slapdFrontendConfig->localuser);
  2147. #endif
  2148. return_value = (backend_plugin->plg_db2archive)( &pb );
  2149. return return_value;
  2150. }
  2151. static int
  2152. slapd_exemode_archive2db()
  2153. {
  2154. int return_value= 0;
  2155. Slapi_PBlock pb;
  2156. struct slapdplugin *backend_plugin;
  2157. slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig();
  2158. if ((backend_plugin = plugin_get_by_name("ldbm database")) == NULL) {
  2159. LDAPDebug(LDAP_DEBUG_ANY,
  2160. "ERROR: Could not find the ldbm backend plugin.\n",
  2161. 0, 0, 0);
  2162. exit(1);
  2163. }
  2164. if (NULL == archive_name) {
  2165. LDAPDebug( LDAP_DEBUG_ANY,
  2166. "ERROR: no archive directory supplied\n",
  2167. 0, 0, 0 );
  2168. exit( 1 );
  2169. }
  2170. /* Make sure we aren't going to run slapd in
  2171. * a mode that is going to conflict with other
  2172. * slapd processes that are currently running
  2173. */
  2174. if ( add_new_slapd_process(slapd_exemode, db2ldif_dump_replica,
  2175. skip_db_protect_check) == -1 ) {
  2176. LDAPDebug( LDAP_DEBUG_ANY,
  2177. "Shutting down due to possible conflicts with other slapd processes\n",
  2178. 0, 0, 0 );
  2179. exit(1);
  2180. }
  2181. if (compute_init()) {
  2182. LDAPDebug(LDAP_DEBUG_ANY, "Initialization Failed 0 %d\n",return_value,0,0);
  2183. exit (1);
  2184. }
  2185. memset( &pb, '\0', sizeof(pb) );
  2186. pb.pb_backend = NULL;
  2187. pb.pb_plugin = backend_plugin;
  2188. pb.pb_instance_name = cmd_line_instance_name;
  2189. pb.pb_seq_val = archive_name;
  2190. pb.pb_task_flags = TASK_RUNNING_FROM_COMMANDLINE;
  2191. #ifndef _WIN32
  2192. main_setuid(slapdFrontendConfig->localuser);
  2193. #endif
  2194. return_value = (backend_plugin->plg_archive2db)( &pb );
  2195. return return_value;
  2196. }
  2197. /*
  2198. * functions to convert idl from the old format to the new one
  2199. * (604921) Support a database uprev process any time post-install
  2200. */
  2201. static int
  2202. slapd_exemode_upgradedb()
  2203. {
  2204. int return_value= 0;
  2205. Slapi_PBlock pb;
  2206. struct slapdplugin *backend_plugin;
  2207. slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig();
  2208. if ( archive_name == NULL ) {
  2209. LDAPDebug( LDAP_DEBUG_ANY,
  2210. "ERROR: Required argument -a <backup_dir> missing\n",
  2211. 0, 0, 0 );
  2212. usage( myname, extraname );
  2213. exit( 1 );
  2214. }
  2215. /* this should be the first time this are called! if the init order
  2216. * is ever changed, these lines should be changed (or erased)!
  2217. */
  2218. mapping_tree_init();
  2219. if ((backend_plugin = plugin_get_by_name("ldbm database")) == NULL) {
  2220. LDAPDebug(LDAP_DEBUG_ANY,
  2221. "ERROR: Could not find the ldbm backend plugin.\n",
  2222. 0, 0, 0);
  2223. exit(1);
  2224. }
  2225. /* Make sure we aren't going to run slapd in
  2226. * a mode that is going to conflict with other
  2227. * slapd processes that are currently running
  2228. */
  2229. if (add_new_slapd_process(slapd_exemode, 0, skip_db_protect_check) == -1) {
  2230. LDAPDebug( LDAP_DEBUG_ANY,
  2231. "Shutting down due to possible conflicts with other slapd processes\n",
  2232. 0, 0, 0 );
  2233. exit(1);
  2234. }
  2235. /* check for slapi v2 support */
  2236. if (! SLAPI_PLUGIN_IS_V2(backend_plugin)) {
  2237. LDAPDebug(LDAP_DEBUG_ANY, "ERROR: %s is too old to do convert idl.\n",
  2238. backend_plugin->plg_name, 0, 0);
  2239. exit(1);
  2240. }
  2241. memset( &pb, '\0', sizeof(pb) );
  2242. pb.pb_backend = NULL;
  2243. pb.pb_plugin = backend_plugin;
  2244. pb.pb_seq_val = archive_name;
  2245. pb.pb_seq_type = upgradedb_force;
  2246. pb.pb_task_flags = TASK_RUNNING_FROM_COMMANDLINE;
  2247. /* borrowing import code, so need to set up the import variables */
  2248. pb.pb_ldif_generate_uniqueid = ldif2db_generate_uniqueid;
  2249. pb.pb_ldif_namespaceid = ldif2db_namespaceid;
  2250. pb.pb_ldif2db_noattrindexes = 0;
  2251. pb.pb_removedupvals = 0;
  2252. #ifndef _WIN32
  2253. main_setuid(slapdFrontendConfig->localuser);
  2254. #endif
  2255. if ( backend_plugin->plg_upgradedb != NULL ) {
  2256. return_value = (*backend_plugin->plg_upgradedb)( &pb );
  2257. } else {
  2258. LDAPDebug( LDAP_DEBUG_ANY,
  2259. "ERROR: no upgradedb function defined for "
  2260. "%s\n", backend_plugin->plg_name, 0, 0 );
  2261. return_value = -1;
  2262. }
  2263. slapi_ch_free((void**)&myname );
  2264. return( return_value );
  2265. }
  2266. static int
  2267. slapd_exemode_dbtest()
  2268. {
  2269. int return_value= 0;
  2270. Slapi_PBlock pb;
  2271. struct slapdplugin *plugin;
  2272. if (NULL == cmd_line_instance_name) {
  2273. LDAPDebug(LDAP_DEBUG_ANY,
  2274. "dbtest: Required argument -n <instance name> missing\n", 0, 0, 0);
  2275. usage( myname, extraname );
  2276. exit(1);
  2277. }
  2278. mapping_tree_init();
  2279. plugin = lookup_plugin_by_instance_name(cmd_line_instance_name);
  2280. if (plugin == NULL) {
  2281. LDAPDebug(LDAP_DEBUG_ANY,
  2282. "ERROR: Could not find backend '%s'.\n",
  2283. cmd_line_instance_name, 0, 0);
  2284. exit(1);
  2285. }
  2286. /* Make sure we aren't going to run slapd in
  2287. * a mode that is going to conflict with other
  2288. * slapd processes that are currently running
  2289. */
  2290. if ( add_new_slapd_process(slapd_exemode, db2ldif_dump_replica,
  2291. skip_db_protect_check) == -1 ) {
  2292. LDAPDebug( LDAP_DEBUG_ANY,
  2293. "Shutting down due to possible conflicts with other slapd processes\n",
  2294. 0, 0, 0 );
  2295. exit(1);
  2296. }
  2297. pb.pb_backend = NULL;
  2298. pb.pb_plugin = plugin;
  2299. pb.pb_instance_name = cmd_line_instance_name;
  2300. /* For dbtest, we do _not_ change identity (no setuid()) */
  2301. return_value= (*plugin->plg_dbtest)( &pb );
  2302. return return_value;
  2303. }
  2304. #ifdef LDAP_DEBUG
  2305. /*
  2306. * Table to associate a string with a debug level.
  2307. */
  2308. static struct slapd_debug_level_entry {
  2309. int dle_level; /* LDAP_DEBUG_XXX value */
  2310. const char *dle_string; /* string equivalent; NULL marks end of list */
  2311. char dle_hide;
  2312. } slapd_debug_level_map[] = {
  2313. { LDAP_DEBUG_TRACE, "trace", 0 },
  2314. { LDAP_DEBUG_PACKETS, "packets", 0 },
  2315. { LDAP_DEBUG_ARGS, "arguments", 0 },
  2316. { LDAP_DEBUG_ARGS, "args", 1 },
  2317. { LDAP_DEBUG_CONNS, "connections", 0 },
  2318. { LDAP_DEBUG_CONNS, "conn", 1 },
  2319. { LDAP_DEBUG_CONNS, "conns", 1 },
  2320. { LDAP_DEBUG_BER, "ber", 0 },
  2321. { LDAP_DEBUG_FILTER, "filters", 0 },
  2322. { LDAP_DEBUG_CONFIG, "config", 0 },
  2323. { LDAP_DEBUG_ACL, "accesscontrol", 0 },
  2324. { LDAP_DEBUG_ACL, "acl", 1 },
  2325. { LDAP_DEBUG_ACL, "acls", 1 },
  2326. { LDAP_DEBUG_STATS, "stats", 0 },
  2327. { LDAP_DEBUG_STATS2, "stats2", 0 },
  2328. { LDAP_DEBUG_SHELL, "shell", 1 },
  2329. { LDAP_DEBUG_PARSE, "parsing", 0 },
  2330. { LDAP_DEBUG_HOUSE, "housekeeping", 0 },
  2331. { LDAP_DEBUG_REPL, "replication", 0 },
  2332. { LDAP_DEBUG_REPL, "repl", 1 },
  2333. { LDAP_DEBUG_ANY, "errors", 0 },
  2334. { LDAP_DEBUG_ANY, "ANY", 1 },
  2335. { LDAP_DEBUG_ANY, "error", 1 },
  2336. { LDAP_DEBUG_CACHE, "caches", 0 },
  2337. { LDAP_DEBUG_CACHE, "cache", 1 },
  2338. { LDAP_DEBUG_PLUGIN, "plugins", 0 },
  2339. { LDAP_DEBUG_PLUGIN, "plugin", 1 },
  2340. { LDAP_DEBUG_TIMING, "timing", 0 },
  2341. { LDAP_DEBUG_ACLSUMMARY,"accesscontrolsummary", 0 },
  2342. { LDAP_DEBUG_ALL_LEVELS,"ALL", 0 },
  2343. { 0, NULL, 0 }
  2344. };
  2345. /*
  2346. * Given a string represention of a debug level, map it to a integer value
  2347. * and return that value. -1 is returned upon error, with a message
  2348. * printed to stderr.
  2349. */
  2350. static int
  2351. slapd_debug_level_string2level( const char *s )
  2352. {
  2353. int level, i;
  2354. char *cur, *next, *scopy;
  2355. level = 0;
  2356. cur = scopy = slapi_ch_strdup( s );
  2357. for ( cur = scopy; cur != NULL; cur = next ) {
  2358. if (( next = strchr( cur, '+' )) != NULL ) {
  2359. *next++ = '\0';
  2360. }
  2361. if ( isdigit( *cur )) {
  2362. level |= atoi( cur );
  2363. } else {
  2364. for ( i = 0; NULL != slapd_debug_level_map[i].dle_string; ++i ) {
  2365. if ( strcasecmp( cur, slapd_debug_level_map[i].dle_string )
  2366. == 0 ) {
  2367. level |= slapd_debug_level_map[i].dle_level;
  2368. break;
  2369. }
  2370. }
  2371. if ( NULL == slapd_debug_level_map[i].dle_string ) {
  2372. fprintf( stderr, "Unrecognized debug level \"%s\"\n", cur );
  2373. return -1;
  2374. }
  2375. }
  2376. }
  2377. slapi_ch_free( (void **)&scopy );
  2378. return level;
  2379. }
  2380. /*
  2381. * Print to stderr the string equivalent of level.
  2382. * The ANY level is omitted because it is always present.
  2383. */
  2384. static void
  2385. slapd_debug_level_log( int level )
  2386. {
  2387. int i, count, len;
  2388. char *msg, *p;
  2389. level &= ~LDAP_DEBUG_ANY;
  2390. /* first pass: determine space needed for the debug level string */
  2391. len = 1; /* room for '\0' terminator */
  2392. count = 0;
  2393. for ( i = 0; NULL != slapd_debug_level_map[i].dle_string; ++i ) {
  2394. if ( !slapd_debug_level_map[i].dle_hide &&
  2395. slapd_debug_level_map[i].dle_level != LDAP_DEBUG_ALL_LEVELS
  2396. && 0 != ( level & slapd_debug_level_map[i].dle_level )) {
  2397. if ( count > 0 ) {
  2398. ++len; /* room for '+' character */
  2399. }
  2400. len += strlen( slapd_debug_level_map[i].dle_string );
  2401. ++count;
  2402. }
  2403. }
  2404. /* second pass: construct the debug level string */
  2405. p = msg = slapi_ch_malloc( len );
  2406. count = 0;
  2407. for ( i = 0; NULL != slapd_debug_level_map[i].dle_string; ++i ) {
  2408. if ( !slapd_debug_level_map[i].dle_hide &&
  2409. slapd_debug_level_map[i].dle_level != LDAP_DEBUG_ALL_LEVELS
  2410. && 0 != ( level & slapd_debug_level_map[i].dle_level )) {
  2411. if ( count > 0 ) {
  2412. *p++ = '+';
  2413. }
  2414. strcpy( p, slapd_debug_level_map[i].dle_string );
  2415. p += strlen( p );
  2416. ++count;
  2417. }
  2418. }
  2419. slapi_log_error( SLAPI_LOG_FATAL, SLAPD_VERSION_STR,
  2420. "%s: %s (%d)\n", "debug level", msg, level );
  2421. slapi_ch_free( (void **)&msg );
  2422. }
  2423. /*
  2424. * Display usage/help for the debug level flag (-d)
  2425. */
  2426. static void
  2427. slapd_debug_level_usage( void )
  2428. {
  2429. int i;
  2430. fprintf( stderr, "Debug levels:\n" );
  2431. for ( i = 0; NULL != slapd_debug_level_map[i].dle_string; ++i ) {
  2432. if ( !slapd_debug_level_map[i].dle_hide
  2433. && slapd_debug_level_map[i].dle_level
  2434. != LDAP_DEBUG_ALL_LEVELS) {
  2435. fprintf( stderr, " %6d - %s%s\n",
  2436. slapd_debug_level_map[i].dle_level,
  2437. slapd_debug_level_map[i].dle_string,
  2438. ( 0 == ( slapd_debug_level_map[i].dle_level &
  2439. LDAP_DEBUG_ANY )) ? "" :
  2440. " (always logged)" );
  2441. }
  2442. }
  2443. fprintf( stderr, "To activate multiple levels, add the numeric"
  2444. " values together or separate the\n"
  2445. "values with a + character, e.g., all of the following"
  2446. " have the same effect:\n"
  2447. " -d connections+filters\n"
  2448. " -d 8+32\n"
  2449. " -d 40\n" );
  2450. }
  2451. #endif /* LDAP_DEBUG */