main.c 80 KB

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