ux-config.cc 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113
  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. /*********************************************************************
  39. **
  40. ** NAME:
  41. ** ux-config.cc
  42. **
  43. ** DESCRIPTION:
  44. ** Fedora Directory Server Pre-installation Program
  45. **
  46. ** NOTES:
  47. ** This program is intended for UNIX only and is NOT thread-safe.
  48. ** Based on the original ux-config.c.
  49. **
  50. *********************************************************************/
  51. extern "C" {
  52. #include <stdio.h>
  53. #include <string.h>
  54. #ifdef AIX
  55. #include <strings.h>
  56. #endif
  57. #include "nspr.h"
  58. #include "plstr.h"
  59. }
  60. /* Newer g++ wants the new std header forms */
  61. #if defined( Linux )
  62. #include <strstream>
  63. using std::ostrstream;
  64. /* But some platforms won't accept those (specifically HP-UX aCC */
  65. #else
  66. #include <strstream.h>
  67. #endif
  68. #include "dialog.h"
  69. #include "ux-config.h"
  70. #include "ux-dialog.h"
  71. #include "install_keywords.h"
  72. #include "utf8.h"
  73. extern "C" {
  74. #include <dsalib.h>
  75. #if defined(__sun) || defined(__hppa) || defined(__osf__) || defined(__linux__) || defined(linux)
  76. #include <netdb.h>
  77. #endif
  78. }
  79. extern const char *DEFAULT_SYSUSER = "root";
  80. extern const char *DEFAULT_OLDROOT = "/usr/ns-home";
  81. const int RECONFIG_EXIT_CODE = 7;
  82. /*
  83. * iDSISolaris is set to 1 for Solaris 9+ specific installation.
  84. * This can be done by passing -S as the command line argument.
  85. */
  86. int iDSISolaris = 0;
  87. static char *
  88. my_strdup(const char *s)
  89. {
  90. char *ret = 0;
  91. if (s)
  92. {
  93. ret = new char[strlen(s) + 1];
  94. strcpy(ret, s);
  95. }
  96. return ret;
  97. }
  98. /*********************************************************************
  99. **
  100. ** METHOD:
  101. ** main
  102. ** DESCRIPTION:
  103. ** This is the ns-config program. This program functions as
  104. ** - The Pre-installation program used during the Installation
  105. ** of the Directory Server. In this case, the program
  106. ** is supposed to be executed by the common installer (ns-setup)
  107. ** and can be executed from anywhere.
  108. **
  109. ** - The stand-alone configuration program used to re-configure
  110. ** the directory server. In this case, the program has
  111. ** to be executed from the serverroot.
  112. **
  113. ** SIDE EFFECTS:
  114. ** None
  115. ** RESTRICTIONS:
  116. **
  117. ** ALGORITHM:
  118. **
  119. **********************************************************************/
  120. int
  121. main(int argc, char **argv)
  122. {
  123. int err = 0;
  124. SlapdPreInstall program(argc, argv);
  125. err = program.init();
  126. if (!err)
  127. {
  128. err = program.start();
  129. }
  130. return err;
  131. }
  132. SlapdPreInstall::SlapdPreInstall(int argc, char **argv) : _reconfig(False)
  133. {
  134. setInstallMode(Interactive);
  135. setInstallType(Typical);
  136. _configured = False;
  137. getOptions(argc, argv);
  138. }
  139. SlapdPreInstall::~SlapdPreInstall()
  140. {
  141. }
  142. void
  143. SlapdPreInstall::getOptions(int argc, char **argv)
  144. {
  145. int opt;
  146. while ((opt = getopt(argc,argv, "l:f:m:rsS")) != EOF)
  147. {
  148. switch (opt)
  149. {
  150. case 'l':
  151. _logFile = strdup(optarg);
  152. break;
  153. case 'f':
  154. _infoFile = strdup(optarg);
  155. break;
  156. case 's':
  157. setInstallMode(Silent);
  158. break;
  159. case 'm':
  160. setInstallType((InstallType)atoi(optarg));
  161. break;
  162. case 'r':
  163. _reconfig = True;
  164. break;
  165. case 'S':
  166. /*
  167. * Solaris 9+ specific installation
  168. */
  169. iDSISolaris = 1;
  170. break;
  171. default:
  172. fprintf(stderr, "SlapdPreInstall::getOptions(): "
  173. "invalid option [%s]\n", argv[optind-1]);
  174. break;
  175. }
  176. }
  177. }
  178. int
  179. SlapdPreInstall::init()
  180. {
  181. char errMsg[256];
  182. struct stat fi;
  183. Bool shell = True;
  184. _installInfo = NULL;
  185. _slapdInfo = new InstallInfo;
  186. if (installMode() != Silent)
  187. {
  188. Dialog::initDisplay("Directory", "Fedora Project");
  189. }
  190. if ((installMode() == Silent && _infoFile == (char *) NULL) ||
  191. (_infoFile != (char *) NULL && InstUtil::fileExists(_infoFile) == False))
  192. {
  193. PR_snprintf(errMsg, sizeof(errMsg), "ERROR: answer cache not found\n");
  194. if (installMode() == Silent)
  195. {
  196. printf(errMsg);
  197. }
  198. else
  199. {
  200. DialogAlert alert(errMsg);
  201. alert.execute();
  202. }
  203. return -1;
  204. }
  205. _serverRoot = InstUtil::getCurrentDir();
  206. if (installMode() != Silent)
  207. {
  208. if (_infoFile == (char *) NULL)
  209. {
  210. // Not executing from the Shell, check if this is the server
  211. if (stat ("admin-serv", &fi) != 0)
  212. {
  213. PR_snprintf(errMsg, sizeof(errMsg), "ERROR: %s is not a server root\n",_serverRoot.data());
  214. DialogAlert alert(errMsg);
  215. alert.execute();
  216. return -1;
  217. }
  218. shell = False;
  219. // if we are here, we are being run to reconfigure
  220. _reconfig = True;
  221. }
  222. }
  223. if (installMode() == Silent)
  224. {
  225. if (_logFile == (char *) NULL)
  226. {
  227. // Should have a logfile
  228. _logFile = _serverRoot + "/setup/install.log";
  229. }
  230. _installLog = new InstallLog (_logFile);
  231. }
  232. if (shell)
  233. {
  234. _installInfo = new InstallInfo(_infoFile);
  235. _serverRoot = _installInfo->get(SLAPD_KEY_SERVER_ROOT);
  236. if (!(_adminInfo = _installInfo->getSection("admin")))
  237. {
  238. _adminInfo = new InstallInfo;
  239. }
  240. }
  241. else
  242. {
  243. // Retrieve configuration data into installInfo
  244. _infoFile = _serverRoot + "/" + "setup/install.inf";
  245. _installInfo = new InstallInfo();
  246. if (initDefaultConfig() == -1) {
  247. const char *guess_host = InstUtil::guessHostname();
  248. if (guess_host) {
  249. PR_snprintf(errMsg, sizeof(errMsg), "ERROR: %s is not an addressable hostname\n",
  250. guess_host);
  251. } else {
  252. PR_snprintf(errMsg, sizeof(errMsg), "ERROR: cannot determine an addressable hostname\n");
  253. }
  254. DialogAlert alert(errMsg);
  255. alert.execute();
  256. return -1;
  257. }
  258. if (getDNSDomain() == NULL) {
  259. const char *guess_domain = InstUtil::guessDomain();
  260. if (guess_domain == NULL) {
  261. PR_snprintf(errMsg, sizeof(errMsg), "ERROR: cannot determine domainname\n");
  262. } else {
  263. PR_snprintf(errMsg, sizeof(errMsg), "ERROR: domainname is not valid for DNS\n");
  264. }
  265. DialogAlert alert(errMsg);
  266. alert.execute();
  267. return -1;
  268. }
  269. }
  270. setDefaultScript(_slapdInfo);
  271. char *url = 0;
  272. char *adminid = 0;
  273. char *admin_domain = 0;
  274. getDefaultLdapInfo(_serverRoot, &url, &adminid, &admin_domain);
  275. if (url && admin_domain) // in some cases adminid is NULL
  276. {
  277. if (!adminid)
  278. {
  279. // look up the admin ID in the config ds
  280. }
  281. // use these values as our default values
  282. _installInfo->set(SLAPD_KEY_K_LDAP_URL, url);
  283. if (adminid)
  284. {
  285. _installInfo->set(SLAPD_KEY_SERVER_ADMIN_ID, adminid);
  286. }
  287. _installInfo->set(SLAPD_KEY_ADMIN_DOMAIN, admin_domain);
  288. // since this server root is already configured to use
  289. // an existing configuration directory server, we will
  290. // not allow the user to install another one here, so
  291. // the directory server created here will be a user
  292. // directory; we will still need to ask for the admin
  293. // user password
  294. _slapdInfo->set(SLAPD_KEY_USE_EXISTING_MC, "Yes");
  295. _slapdInfo->set(SLAPD_KEY_USE_EXISTING_UG, "No");
  296. _slapdInfo->set(SLAPD_KEY_SLAPD_CONFIG_FOR_MC, "No");
  297. }
  298. else
  299. {
  300. _slapdInfo->set(SLAPD_KEY_SLAPD_CONFIG_FOR_MC, "Yes");
  301. }
  302. return 0;
  303. }
  304. /*
  305. * PVO
  306. */
  307. int
  308. SlapdPreInstall::initDefaultConfig()
  309. {
  310. // PVO - should read from DS instead
  311. if (_adminInfo->isEmpty())
  312. {
  313. const char *guess_host = InstUtil::guessHostname();
  314. if (guess_host) {
  315. #if defined(__sun) || defined(__hppa) || defined(__osf__) || defined(__linux__) || defined(linux)
  316. static char test_host[BIG_BUF] = {0};
  317. struct hostent *hp;
  318. PL_strncpyz(test_host,guess_host,sizeof(test_host));
  319. hp = gethostbyname(test_host);
  320. if (hp == NULL) {
  321. return -1;
  322. }
  323. #endif
  324. }
  325. _installInfo->set(SLAPD_KEY_SERVER_ROOT, _serverRoot);
  326. _installInfo->set(SLAPD_KEY_FULL_MACHINE_NAME, guess_host);
  327. _installInfo->set(SLAPD_KEY_K_LDAP_URL, NSString("ldap://")
  328. + guess_host
  329. + "/"
  330. + DEFAULT_LDAP_SUFFIX);
  331. _installInfo->set(SLAPD_KEY_SUITESPOT_USERID, DEFAULT_SSUSER);
  332. _installInfo->set(SS_GROUP, DEFAULT_SSGROUP);
  333. }
  334. else
  335. {
  336. _configured = True;
  337. }
  338. return 0;
  339. }
  340. inline void
  341. changeIndex(int &ii, int incr, int min, int max)
  342. {
  343. ii += incr;
  344. if (ii < min)
  345. ii = min;
  346. if (ii > max)
  347. ii = max;
  348. }
  349. int
  350. SlapdPreInstall::start()
  351. {
  352. // if we're in silent install mode, don't execute any of the dialogs, just
  353. // assume the user knows what he/she is doing . . .
  354. if (installMode() == Silent)
  355. {
  356. if (_reconfig)
  357. shutdownServers();
  358. return 0;
  359. }
  360. // only enable win mode if we are not doing a silent install because
  361. // it messes up terminal settings
  362. enableWinMode();
  363. DialogAction action = DIALOG_NEXT;
  364. int err = 0;
  365. Dialog *advancedDialogList[] = {
  366. &askUseExistingMC,
  367. &askMCHost,
  368. &askMCPort,
  369. &askMCDN,
  370. &askMCAdminDomain,
  371. &askUseExistingUG,
  372. &askUGHost,
  373. &askUGPort,
  374. &askUGSuffix,
  375. &askUGDN,
  376. &askSlapdPort,
  377. &askSlapdServerID,
  378. &askMCAdminID,
  379. &askSlapdSuffix,
  380. &askSlapdRootDN,
  381. &askAdminDomain,
  382. /*
  383. &askReplication,
  384. &askSIR,
  385. &askChangeLogSuffix,
  386. &askChangeLogDir,
  387. &askConsumerDN,
  388. &askSIRHost,
  389. &askSIRPort,
  390. &askSIRDN,
  391. &askSIRSuffix,
  392. &askSIRDays,
  393. &askSIRTimes,
  394. &askCIR,
  395. &askCIRHost,
  396. &askCIRPort,
  397. &askCIRDN,
  398. &askCIRSuffix,
  399. &askCIRInterval,
  400. &askCIRDays,
  401. &askCIRTimes,
  402. &askReplicationDN,
  403. */
  404. &askSample,
  405. &askPopulate,
  406. &askDisableSchemaChecking
  407. };
  408. Dialog *advancediDSISolarisForceUGDialogList[] = {
  409. &askSlapdPort,
  410. &askSlapdServerID,
  411. &askMCHost,
  412. &askMCPort,
  413. &askMCDN,
  414. &askSlapdSuffix,
  415. &askSlapdRootDN,
  416. &askSample,
  417. &askPopulate,
  418. &askDisableSchemaChecking
  419. };
  420. Dialog *normalDialogList[] = {
  421. &askUseExistingMC,
  422. &askMCHost,
  423. &askMCPort,
  424. &askMCDN,
  425. &askUseExistingUG,
  426. &askUGHost,
  427. &askUGPort,
  428. &askUGSuffix,
  429. &askUGDN,
  430. &askSlapdPort,
  431. &askSlapdServerID,
  432. &askMCAdminID,
  433. &askSlapdSuffix,
  434. &askSlapdRootDN,
  435. &askAdminDomain
  436. };
  437. Dialog *normalForceUGDialogList[] = {
  438. &askSlapdPort,
  439. &askSlapdServerID,
  440. &askMCDN,
  441. &askSlapdSuffix,
  442. &askSlapdRootDN
  443. };
  444. Dialog *normaliDSISolarisForceUGDialogList[] = {
  445. &askSlapdPort,
  446. &askSlapdServerID,
  447. &askMCHost,
  448. &askMCPort,
  449. &askMCDN,
  450. &askSlapdSuffix,
  451. &askSlapdRootDN
  452. };
  453. Dialog *expressDialogList[] = {
  454. &askMCAdminID,
  455. &askSlapdRootDN
  456. };
  457. Dialog *expressForceUGDialogList[] = {
  458. &askMCDN,
  459. &askSlapdRootDN
  460. };
  461. Dialog *expressiDSISolarisForceUGDialogList[] = {
  462. &askMCHost,
  463. &askMCPort,
  464. &askMCDN,
  465. &askSlapdRootDN
  466. };
  467. Dialog *reconfigDialogList[] = {
  468. &askReconfigMCAdminPwd
  469. };
  470. const int nNormalDialogs = sizeof(normalDialogList) / sizeof(normalDialogList[0]);
  471. const int nExpressDialogs = sizeof(expressDialogList) / sizeof(expressDialogList[0]);
  472. const int nExpressForceUGDialogs = sizeof(expressForceUGDialogList) / sizeof(expressForceUGDialogList[0]);
  473. const int nExpressiDSISolarisForceUGDialogs = sizeof(expressiDSISolarisForceUGDialogList) / sizeof(expressiDSISolarisForceUGDialogList[0]);
  474. const int nAdvancedDialogs = sizeof(advancedDialogList) / sizeof(advancedDialogList[0]);
  475. const int nAdvancediDSISolarisForceUGDialogs = sizeof(advancediDSISolarisForceUGDialogList) / sizeof(advancediDSISolarisForceUGDialogList[0]);
  476. const int nReconfigDialogs = sizeof(reconfigDialogList) / sizeof(reconfigDialogList[0]);
  477. const int nNormalForceUGDialogs = sizeof(normalForceUGDialogList) / sizeof(normalForceUGDialogList[0]);
  478. const int nNormaliDSISolarisForceUGDialogs = sizeof(normaliDSISolarisForceUGDialogList) / sizeof(normaliDSISolarisForceUGDialogList[0]);
  479. int nDialogs = nNormalDialogs;
  480. Dialog** dialogList = normalDialogList;
  481. if (_reconfig)
  482. {
  483. nDialogs = nReconfigDialogs;
  484. dialogList = reconfigDialogList;
  485. }
  486. else if (installType() == Express)
  487. {
  488. nDialogs = nExpressDialogs;
  489. dialogList = expressDialogList;
  490. }
  491. else if (installType() == Custom)
  492. {
  493. nDialogs = nAdvancedDialogs;
  494. dialogList = advancedDialogList;
  495. }
  496. else if (!iDSISolaris && featureIsEnabled(SLAPD_KEY_USE_EXISTING_MC))
  497. {
  498. if (installType() == Typical)
  499. {
  500. nDialogs = nNormalForceUGDialogs;
  501. dialogList = normalForceUGDialogList;
  502. }
  503. else if (installType() == Express)
  504. {
  505. nDialogs = nExpressForceUGDialogs;
  506. dialogList = expressForceUGDialogList;
  507. }
  508. }
  509. if (iDSISolaris && featureIsEnabled(SLAPD_KEY_USE_EXISTING_MC))
  510. {
  511. if (installType() == Typical)
  512. {
  513. nDialogs = nNormaliDSISolarisForceUGDialogs;
  514. dialogList = normaliDSISolarisForceUGDialogList;
  515. }
  516. else if (installType() == Express)
  517. {
  518. nDialogs = nExpressiDSISolarisForceUGDialogs;
  519. dialogList = expressiDSISolarisForceUGDialogList;
  520. }
  521. else if (installType() == Custom)
  522. {
  523. nDialogs = nAdvancediDSISolarisForceUGDialogs;
  524. dialogList = advancediDSISolarisForceUGDialogList;
  525. }
  526. }
  527. getDefaultScript()->set(SLAPD_KEY_SECURITY_ON, "No");
  528. int ii = 0;
  529. // initialize all dialogs
  530. if (!_reconfig)
  531. {
  532. for (ii = 0; ii < nAdvancedDialogs; ++ii)
  533. {
  534. advancedDialogList[ii]->registerDialogNext(this);
  535. advancedDialogList[ii]->enable8BitInput();
  536. // this next bit of hackery allows us to use the dialog->setup()
  537. // method of each dialog to setup the default values for the
  538. // .inf file; if the SETUP_ONLY flag is set, each setup() method
  539. // will just return DIALOG_NEXT after setting up the default
  540. // values; pretty sneaky, huh?
  541. advancedDialogList[ii]->setUserData(SETUP_DEFAULTS, SETUP_ONLY);
  542. advancedDialogList[ii]->setUserData(ACTION, DIALOG_NEXT);
  543. advancedDialogList[ii]->execute();
  544. advancedDialogList[ii]->setUserData(SETUP_DEFAULTS, (long)0);
  545. }
  546. advancedDialogList[nAdvancedDialogs-1]->registerDialogLast(this);
  547. }
  548. else
  549. {
  550. for (ii = 0; ii < nReconfigDialogs; ++ii)
  551. {
  552. reconfigDialogList[ii]->registerDialogNext(this);
  553. reconfigDialogList[ii]->enable8BitInput();
  554. }
  555. reconfigDialogList[nReconfigDialogs-1]->registerDialogLast(this);
  556. }
  557. ii = 0;
  558. int min = 0;
  559. // keep looping until we hit the end
  560. while (ii < nDialogs)
  561. {
  562. int incr = 1; // go to next by default
  563. Dialog *d = dialogList[ii];
  564. // tell the dialog what the action was that brought it here so that
  565. // the dialog knows if it was called as the result of a next or
  566. // a prev or whatever
  567. d->setUserData(ACTION, (long)action);
  568. // cerr << "set action in dialog " << ii << " to " << action << endl;
  569. // cerr << "DIALOG_PREV, SAME, NEXT = " << DIALOG_PREV << "," << DIALOG_SAME << "," << DIALOG_NEXT << endl;
  570. // execute the dialog
  571. // cerr << "executing dialog number " << ii << endl;
  572. action = d->execute();
  573. if (action == DIALOG_PREV)
  574. {
  575. incr = -1; // go to prev
  576. // cerr << "prev" << endl;
  577. }
  578. else if (action == DIALOG_SAME)
  579. {
  580. incr = 0; // repeat this state
  581. // cerr << "same" << endl;
  582. }
  583. else if (action != DIALOG_NEXT)
  584. {
  585. incr = nDialogs;
  586. err = -1; // could just break here, I suppose . . .
  587. }
  588. else
  589. {
  590. // cerr << "next" << endl;
  591. }
  592. changeIndex(ii, incr, min, nDialogs);
  593. }
  594. if (err == 0)
  595. {
  596. if (!_reconfig)
  597. {
  598. _installInfo->addSection("slapd", _slapdInfo);
  599. if (!_installInfo->getSection("admin") && _adminInfo &&
  600. !_adminInfo->isEmpty())
  601. {
  602. _installInfo->addSection("admin", _adminInfo);
  603. delete _adminInfo;
  604. _adminInfo = 0;
  605. }
  606. if (!_installInfo->get(SLAPD_KEY_K_LDAP_HOST))
  607. {
  608. _installInfo->set(SLAPD_KEY_K_LDAP_HOST,
  609. _installInfo->get(SLAPD_KEY_FULL_MACHINE_NAME));
  610. }
  611. if (!_installInfo->get(SLAPD_KEY_K_LDAP_PORT))
  612. {
  613. _installInfo->set(SLAPD_KEY_K_LDAP_PORT,
  614. _slapdInfo->get(SLAPD_KEY_SERVER_PORT));
  615. }
  616. const char *test = 0;
  617. if (!(test = _installInfo->get(SLAPD_KEY_BASE_SUFFIX)) || !*test)
  618. {
  619. // if there's no config directory suffix we must use
  620. // o=NetscapeRoot
  621. _installInfo->set(SLAPD_KEY_BASE_SUFFIX, DEFAULT_ROOT_DN);
  622. }
  623. // only UG directories have a user base suffix . . .
  624. if (featureIsEnabled(SLAPD_KEY_USE_EXISTING_UG))
  625. _slapdInfo->remove(SLAPD_KEY_SUFFIX);
  626. // if there is no LdapURL and other ldap info in the installInfo, write
  627. // it
  628. if (!_installInfo->get(SLAPD_KEY_K_LDAP_URL))
  629. {
  630. // construct a new LdapURL based on host, port, and suffix
  631. const char *suffix = _installInfo->get(SLAPD_KEY_BASE_SUFFIX);
  632. if (!suffix || !*suffix)
  633. suffix = DEFAULT_ROOT_DN;
  634. NSString ldapURL = NSString("ldap://") +
  635. _installInfo->get(SLAPD_KEY_K_LDAP_HOST) + ":" +
  636. _installInfo->get(SLAPD_KEY_K_LDAP_PORT) + "/" +
  637. suffix;
  638. _installInfo->set(SLAPD_KEY_K_LDAP_URL, ldapURL);
  639. }
  640. if (!featureIsEnabled(SLAPD_KEY_USE_EXISTING_MC))
  641. {
  642. // if this is to be both the MC and the UG host . . .
  643. if (!featureIsEnabled(SLAPD_KEY_USE_EXISTING_UG))
  644. {
  645. // use the MC admin ID for the UG admin ID
  646. if (!_installInfo->get(SLAPD_KEY_USER_GROUP_ADMIN_ID))
  647. _installInfo->set(SLAPD_KEY_USER_GROUP_ADMIN_ID,
  648. _installInfo->get(SLAPD_KEY_SERVER_ADMIN_ID));
  649. if (!_installInfo->get(SLAPD_KEY_USER_GROUP_ADMIN_PWD))
  650. _installInfo->set(SLAPD_KEY_USER_GROUP_ADMIN_PWD,
  651. _installInfo->get(SLAPD_KEY_SERVER_ADMIN_PWD));
  652. }
  653. }
  654. // set the ug ldap url if we need one
  655. if (!_installInfo->get(SLAPD_KEY_USER_GROUP_LDAP_URL))
  656. {
  657. if (featureIsEnabled(SLAPD_KEY_USE_EXISTING_UG))
  658. {
  659. NSString url = NSString("ldap://") +
  660. _installInfo->get(SLAPD_KEY_UG_HOST) + ":" +
  661. _installInfo->get(SLAPD_KEY_UG_PORT) + "/" +
  662. _installInfo->get(SLAPD_KEY_UG_SUFFIX);
  663. _installInfo->set(SLAPD_KEY_USER_GROUP_LDAP_URL, url);
  664. }
  665. else // the directory we're creating is the UG
  666. {
  667. NSString url = NSString("ldap://") +
  668. _installInfo->get(SLAPD_KEY_FULL_MACHINE_NAME) + ":" +
  669. _slapdInfo->get(SLAPD_KEY_SERVER_PORT) + "/" +
  670. _slapdInfo->get(SLAPD_KEY_SUFFIX);
  671. _installInfo->set(SLAPD_KEY_USER_GROUP_LDAP_URL, url);
  672. }
  673. }
  674. if (!_installInfo->get(SLAPD_KEY_USER_GROUP_ADMIN_ID))
  675. _installInfo->set(SLAPD_KEY_USER_GROUP_ADMIN_ID,
  676. _slapdInfo->get(SLAPD_KEY_ROOTDN));
  677. if (!_installInfo->get(SLAPD_KEY_USER_GROUP_ADMIN_PWD))
  678. _installInfo->set(SLAPD_KEY_USER_GROUP_ADMIN_PWD,
  679. _slapdInfo->get(SLAPD_KEY_ROOTDNPWD));
  680. } else {
  681. // for reconfigure, just shutdown the servers
  682. shutdownServers();
  683. }
  684. // remove the fields we don't need
  685. _installInfo->remove(SLAPD_KEY_K_LDAP_HOST);
  686. _installInfo->remove(SLAPD_KEY_K_LDAP_PORT);
  687. _installInfo->remove(SLAPD_KEY_BASE_SUFFIX);
  688. _installInfo->remove(SLAPD_KEY_UG_HOST);
  689. _installInfo->remove(SLAPD_KEY_UG_PORT);
  690. _installInfo->remove(SLAPD_KEY_UG_SUFFIX);
  691. // normalize and convert the DN valued attributes to LDAPv3 style
  692. normalizeDNs();
  693. // format for .inf file
  694. _installInfo->setFormat(1);
  695. // convert internally stored UTF8 to local
  696. _installInfo->toLocal();
  697. _installInfo->write(_infoFile);
  698. }
  699. disableWinMode();
  700. return err;
  701. }
  702. int
  703. SlapdPreInstall::cont()
  704. {
  705. return 0;
  706. }
  707. void
  708. SlapdPreInstall::clear()
  709. {
  710. }
  711. void
  712. SlapdPreInstall::add(Dialog *p)
  713. {
  714. p = p;
  715. }
  716. void
  717. SlapdPreInstall::resetLast()
  718. {
  719. }
  720. void
  721. SlapdPreInstall::addLast(Dialog *p)
  722. {
  723. p = p;
  724. }
  725. void
  726. SlapdPreInstall::setParent(void *parent)
  727. {
  728. parent = parent;
  729. return;
  730. }
  731. void *
  732. SlapdPreInstall::parent() const
  733. {
  734. return (void *) this;
  735. }
  736. void
  737. SlapdPreInstall::setAdminScript(InstallInfo *script)
  738. {
  739. _adminInfo = script;
  740. }
  741. InstallInfo *
  742. SlapdPreInstall::getAdminScript() const
  743. {
  744. return _adminInfo;
  745. }
  746. InstallInfo *
  747. SlapdPreInstall::getBaseScript() const
  748. {
  749. return _installInfo;
  750. }
  751. void
  752. SlapdPreInstall::showAlert(const char *msg)
  753. {
  754. char *localMsg = UTF8ToLocal(msg);
  755. DialogAlert alert(localMsg);
  756. alert.execute();
  757. nsSetupFree(localMsg);
  758. return;
  759. }
  760. int
  761. SlapdPreInstall::verifyRemoteLdap(
  762. const char *host,
  763. const char *port,
  764. const char *suffix,
  765. const char *binddn,
  766. const char *binddnpwd
  767. ) const
  768. {
  769. const char *myhost = getDefaultScript()->get(host);
  770. if (!myhost)
  771. myhost = getBaseScript()->get(host);
  772. const char *myport = getDefaultScript()->get(port);
  773. if (!myport)
  774. myport = getBaseScript()->get(port);
  775. const char *mysuffix = getDefaultScript()->get(suffix);
  776. if (!mysuffix)
  777. mysuffix = getBaseScript()->get(suffix);
  778. if (!mysuffix)
  779. mysuffix = DEFAULT_ROOT_DN;
  780. const char *mydn = getDefaultScript()->get(binddn);
  781. if (!mydn)
  782. mydn = getBaseScript()->get(binddn);
  783. const char *mypwd = getDefaultScript()->get(binddnpwd);
  784. if (!mypwd)
  785. mypwd = getBaseScript()->get(binddnpwd);
  786. char *s = PR_smprintf("ldap://%s:%s/%s", myhost, myport, (suffix && mysuffix) ? mysuffix : "");
  787. int status = authLdapUser(s, mydn, mypwd, NULL, NULL);
  788. PR_smprintf_free(s);
  789. return status;
  790. }
  791. int
  792. SlapdPreInstall::verifyAdminDomain(
  793. const char *host,
  794. const char *port,
  795. const char *suffix,
  796. const char *admin_domain,
  797. const char *binddn,
  798. const char *binddnpwd
  799. ) const
  800. {
  801. const char *myhost = getDefaultScript()->get(host);
  802. if (!myhost)
  803. myhost = getBaseScript()->get(host);
  804. const char *myport = getDefaultScript()->get(port);
  805. if (!myport)
  806. myport = getBaseScript()->get(port);
  807. const char *mysuffix = getDefaultScript()->get(suffix);
  808. if (!mysuffix)
  809. mysuffix = getBaseScript()->get(suffix);
  810. if (!mysuffix)
  811. mysuffix = DEFAULT_ROOT_DN;
  812. const char *mydn = getDefaultScript()->get(binddn);
  813. if (!mydn)
  814. mydn = getBaseScript()->get(binddn);
  815. const char *mypwd = getDefaultScript()->get(binddnpwd);
  816. if (!mypwd)
  817. mypwd = getBaseScript()->get(binddnpwd);
  818. const char *myadmin_domain = getDefaultScript()->get(admin_domain);
  819. if (!myadmin_domain)
  820. myadmin_domain = getBaseScript()->get(admin_domain);
  821. char *s = PR_smprintf("ldap://%s:%s/%s", myhost, myport, (suffix && mysuffix) ? mysuffix : "");
  822. LdapError ldapErr;
  823. Ldap ldap(ldapErr, s, mydn, mypwd);
  824. int status = ldapErr;
  825. if (!status && admin_domain && myadmin_domain && mysuffix)
  826. {
  827. LdapEntry ad(&ldap);
  828. NSString dn = NSString("ou=") + myadmin_domain + ", " + mysuffix;
  829. status = ad.retrieve(dn);
  830. }
  831. PR_smprintf_free(s);
  832. return status;
  833. }
  834. const char *
  835. SlapdPreInstall::getDNSDomain() const
  836. {
  837. static char domain[BIG_BUF] = {0};
  838. if (domain[0])
  839. return domain;
  840. const char *FQDN =
  841. getBaseScript()->get(SLAPD_KEY_FULL_MACHINE_NAME);
  842. if (!FQDN) {
  843. FQDN = InstUtil::guessHostname();
  844. }
  845. const char *ptr = NULL;
  846. if (FQDN != NULL) {
  847. // copy the domain name part (not the hostname) into the suffix
  848. // find the last '.' in the FQDN
  849. ptr = strchr(FQDN, '.');
  850. }
  851. if (FQDN == NULL || ptr == NULL) {
  852. const char *guess_domain = InstUtil::guessDomain();
  853. if (guess_domain) {
  854. /* ensure domain is of at least 2 components */
  855. const char *dptr = strchr(guess_domain, '.');
  856. if (dptr == NULL) {
  857. return NULL;
  858. }
  859. PL_strncpyz(domain, guess_domain, sizeof(domain));
  860. return domain;
  861. } else {
  862. return NULL;
  863. }
  864. }
  865. ++ptr;
  866. PL_strncpyz(domain, ptr, sizeof(domain));
  867. return domain;
  868. }
  869. const char *
  870. SlapdPreInstall::getDefaultSuffix() const
  871. {
  872. const char *SUF = "dc=";
  873. const int SUF_LEN = 3;
  874. static char suffix[BIG_BUF] = {0};
  875. if (suffix[0])
  876. return suffix;
  877. char *sptr = suffix;
  878. PL_strcatn(sptr, sizeof(suffix), SUF);
  879. sptr += SUF_LEN;
  880. for (const char *ptr = getDNSDomain(); ptr && *ptr; *ptr++) {
  881. if (*ptr == '.') {
  882. PL_strcatn(sptr, sizeof(suffix), ", ");
  883. sptr += 2;
  884. PL_strcatn(sptr, sizeof(suffix), SUF);
  885. sptr += SUF_LEN;
  886. } else {
  887. *sptr++ = *ptr;
  888. }
  889. }
  890. *sptr = 0;
  891. if (!*suffix)
  892. PR_snprintf(suffix, sizeof(suffix), "%s%s", SUF, "unknown-domain");
  893. return suffix;
  894. }
  895. const char *
  896. SlapdPreInstall::getConsumerDN() const
  897. {
  898. static char dn[BIG_BUF];
  899. dn[0] = 0;
  900. const char *suffix =
  901. getDefaultScript()->get(SLAPD_KEY_SUFFIX);
  902. if (suffix)
  903. PR_snprintf(dn, sizeof(dn), "cn=Replication Consumer, %s", suffix);
  904. else
  905. PR_snprintf(dn, sizeof(dn), "cn=Replication Consumer");
  906. return dn;
  907. }
  908. int
  909. SlapdPreInstall::featureIsEnabled(const char *which) const
  910. {
  911. const char *val = getDefaultScript()->get(which);
  912. if (!val)
  913. val = getBaseScript()->get(which);
  914. if (!val || !*val || !strncasecmp(val, "no", strlen(val)))
  915. return 0; // feature is disabled
  916. return 1; // feature is enabled
  917. }
  918. void
  919. SlapdPreInstall::shutdownServers()
  920. {
  921. const char *nick = "slapd";
  922. const char *script = "stop-slapd";
  923. int len = strlen(nick);
  924. const char *sroot = getBaseScript()->get(SLAPD_KEY_SERVER_ROOT);
  925. if (!sroot)
  926. return;
  927. DIR* srootdir = opendir(sroot);
  928. if (!srootdir)
  929. return;
  930. struct dirent* entry = 0;
  931. while ((entry = readdir(srootdir)))
  932. {
  933. // look for instance directories
  934. if (!strncasecmp(entry->d_name, nick, len))
  935. {
  936. NSString instanceDir = NSString(sroot) + "/" + entry->d_name;
  937. if (InstUtil::dirExists(instanceDir))
  938. {
  939. NSString prog = instanceDir + "/" + script;
  940. // call the stop-slapd script
  941. if (InstUtil::fileExists(prog))
  942. {
  943. cout << "Shutting down server " << entry->d_name
  944. << " . . . " << flush;
  945. int status = InstUtil::execProgram(prog);
  946. if (status)
  947. // attempt to determine cause of failure
  948. cout << "Could not shutdown server: status=" << status
  949. << " error=" << errno << endl;
  950. else
  951. cout << "Done." << endl;
  952. }
  953. }
  954. }
  955. }
  956. closedir(srootdir);
  957. return;
  958. }
  959. void
  960. SlapdPreInstall::normalizeDNs()
  961. {
  962. static const char *DN_VALUED_ATTRS[] = {
  963. SLAPD_KEY_SUFFIX,
  964. SLAPD_KEY_ROOTDN,
  965. SLAPD_KEY_CIR_SUFFIX,
  966. SLAPD_KEY_CIR_BINDDN,
  967. SLAPD_KEY_REPLICATIONDN,
  968. SLAPD_KEY_CONSUMERDN,
  969. SLAPD_KEY_SIR_SUFFIX,
  970. SLAPD_KEY_SIR_BINDDN
  971. };
  972. static const int N = sizeof(DN_VALUED_ATTRS)/sizeof(DN_VALUED_ATTRS[0]);
  973. static const char *URL_ATTRS[] = {
  974. SLAPD_KEY_K_LDAP_URL,
  975. SLAPD_KEY_USER_GROUP_LDAP_URL
  976. };
  977. static const int NURLS = sizeof(URL_ATTRS)/sizeof(URL_ATTRS[0]);
  978. int ii;
  979. for (ii = 0; _slapdInfo && (ii < N); ++ii)
  980. {
  981. const char *attr = DN_VALUED_ATTRS[ii];
  982. char *dn = my_strdup(_slapdInfo->get(attr));
  983. if (dn)
  984. {
  985. _slapdInfo->remove(attr);
  986. _slapdInfo->set(attr, dn_normalize_convert(dn));
  987. fflush(stdout);
  988. delete [] dn;
  989. }
  990. }
  991. for (ii = 0; _installInfo && (ii < NURLS); ++ii)
  992. {
  993. const char *attr = URL_ATTRS[ii];
  994. const char *url = _installInfo->get(attr);
  995. LDAPURLDesc *desc = 0;
  996. if (url && !ldap_url_parse((char *)url, &desc) && desc)
  997. {
  998. char *dn = dn_normalize_convert(my_strdup(desc->lud_dn));
  999. if (dn)
  1000. {
  1001. char port[6];
  1002. PR_snprintf(port, sizeof(port), "%d", desc->lud_port);
  1003. NSString newurl = NSString("ldap://") + desc->lud_host +
  1004. ":" + port + "/" + dn;
  1005. _installInfo->set(attr, newurl);
  1006. delete [] dn;
  1007. }
  1008. }
  1009. if (desc)
  1010. ldap_free_urldesc(desc);
  1011. }
  1012. }