/*************************************************************************** * Copyright (C) 2012 by Timothy Pearson * * kb9vqf@pearsoncomputing.net * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "sha1.h" #include "ldapcontroller.h" #include "realmwizard.h" #include "processingdialog.h" // FIXME // Connect this to CMake/Automake #define KDE_CONFDIR "/etc/trinity" #define LDAP_KEYTAB_FILE "/etc/ldap/ldap.keytab" // FIXME // This assumes Debian! // RedHat would be "/etc/sysconfig/ldap" #define LDAP_DEFAULT_FILE "/etc/default/slapd" #define HEIMDAL_DEFAULT_FILE "/etc/default/heimdal-kdc" #define SASL_DEFAULT_FILE "/etc/default/saslauthd" #define SASL_CONTROL_FILE "/etc/ldap/sasl2/slapd.conf" #define ROLE_WORKSTATION 0 #define ROLE_REALM_CONTROLLER 1 typedef KGenericFactory ldapFactory; K_EXPORT_COMPONENT_FACTORY( kcm_ldapcontroller, ldapFactory("kcmldapcontroller")) LDAPController::LDAPController(TQWidget *parent, const char *name, const TQStringList&) : KCModule(parent, name), myAboutData(0) { TQVBoxLayout *layout = new TQVBoxLayout(this, KDialog::marginHint(), KDialog::spacingHint()); m_systemconfig = new KSimpleConfig( TQString::fromLatin1( KDE_CONFDIR "/ldap/ldapconfigrc" )); m_systemconfig->setFileWriteMode(S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); KAboutData* about = new KAboutData("ldapcontroller", I18N_NOOP("TDE LDAP Controller"), "0.1", I18N_NOOP("TDE LDAP Controller Control Panel Module"), KAboutData::License_GPL, I18N_NOOP("(c) 2012 Timothy Pearson"), 0, 0); about->addAuthor("Timothy Pearson", 0, "kb9vqf@pearsoncomputing.net"); setAboutData( about ); m_base = new LDAPControllerConfigBase(this); layout->add(m_base); m_base->systemRole->clear(); m_base->systemRole->insertItem("Workstation", ROLE_WORKSTATION); m_base->systemRole->insertItem("Realm Controller", ROLE_REALM_CONTROLLER); setRootOnlyMsg(i18n("LDAP controller settings take effect system wide, and require administrator access to modify
To alter the system's realm controller settings, click on the \"Administrator Mode\" button below.")); setUseRootOnlyMsg(true); connect(m_base->systemEnableSupport, TQT_SIGNAL(clicked()), this, TQT_SLOT(changed())); connect(m_base->systemEnableSupport, TQT_SIGNAL(clicked()), this, TQT_SLOT(processLockouts())); connect(m_base->systemRole, TQT_SIGNAL(activated(const TQString&)), this, TQT_SLOT(systemRoleChanged())); m_fqdn = getMachineFQDN(); // FIXME // This assumes Debian! m_ldapUserName = "openldap"; m_ldapGroupName = "openldap"; load(); if (getuid() != 0 || !m_systemconfig->checkConfigFilesWritable( true )) { m_base->systemEnableSupport->setEnabled(false); } processLockouts(); }; LDAPController::~LDAPController() { } // FIXME // This should be moved to a TDE core library TQString LDAPController::getMachineFQDN() { struct addrinfo hints, *info, *p; int gai_result; char hostname[1024]; hostname[1023] = '\0'; gethostname(hostname, 1023); memset(&hints, 0, sizeof hints); hints.ai_family = AF_UNSPEC; // IPV4 or IPV6 hints.ai_socktype = SOCK_STREAM; hints.ai_flags = AI_CANONNAME; if ((gai_result = getaddrinfo(hostname, NULL, &hints, &info)) != 0) { return TQString(hostname); } TQString fqdn = TQString(hostname); for (p=info; p!=NULL; p=p->ai_next) { fqdn = TQString(p->ai_canonname); } freeaddrinfo(info); return fqdn; } void LDAPController::systemRoleChanged() { if (m_base->systemRole->currentItem() != m_prevRole) { if (m_base->systemRole->currentItem() == ROLE_REALM_CONTROLLER) { // Verify that this workstation was not already bonded to an LDAP realm! bool bonded = false; TQStringList cfgRealms = m_systemconfig->groupList(); for (TQStringList::Iterator it(cfgRealms.begin()); it != cfgRealms.end(); ++it) { if ((*it).startsWith("LDAPRealm-")) { m_systemconfig->setGroup(*it); if (m_systemconfig->readBoolEntry("bonded", false) == true) { bonded = true; } } } if (bonded) { KMessageBox::error(0, i18n("You are already bonded to a realm!

Please unbond from all realms before selecting a Realm Controller role"), i18n("Common Sense Failure")); m_base->systemRole->setCurrentItem(0); } else { // Something will probably change save(); RealmWizard realmwizard(this, m_fqdn, this); if (realmwizard.exec() < 0) { // Wizard was cancelled // Back out all changes! m_base->systemRole->setCurrentItem(ROLE_WORKSTATION); save(); } // Something probably changed load(); } } if (m_base->systemRole->currentItem() == ROLE_WORKSTATION) { // RAJA FIXME } } } void LDAPController::processLockouts() { bool enabled = (m_base->systemEnableSupport->isEnabled() && m_base->systemEnableSupport->isChecked()); m_base->systemRole->setEnabled(enabled); } void LDAPController::load() { bool thisIsMyMachine; m_systemconfig->setGroup(NULL); m_base->systemEnableSupport->setChecked(m_systemconfig->readBoolEntry("EnableLDAP", false)); if (m_fqdn == m_systemconfig->readEntry("HostFQDN", "")) { thisIsMyMachine = true; } else { thisIsMyMachine = false; } TQString ldapRole = m_systemconfig->readEntry("LDAPRole", "Workstation"); if (!thisIsMyMachine) { ldapRole = "Workstation"; } if (ldapRole == "Realm Controller") { m_base->systemRole->setCurrentItem(ROLE_REALM_CONTROLLER); } else { m_base->systemRole->setCurrentItem(ROLE_WORKSTATION); } m_prevRole = m_base->systemRole->currentItem(); } void LDAPController::defaults() { // } void LDAPController::save() { m_systemconfig->setGroup(NULL); m_systemconfig->writeEntry("EnableLDAP", m_base->systemEnableSupport->isChecked()); m_systemconfig->writeEntry("LDAPRole", m_base->systemRole->currentText()); m_systemconfig->sync(); if (m_base->systemEnableSupport->isChecked()) { // // Write the Kerberos5 configuration file // writeKrb5ConfFile(); // // Write the LDAP configuration file // writeLDAPConfFile(); // // Write the NSSwitch configuration file // writeNSSwitchFile(); // // Write the PAM configuration files // writePAMFiles(); // // Write the cron files // writeCronFiles(); } load(); } void replacePlaceholdersInFile(TQString infile, TQString outfile, LDAPRealmConfig realmconfig, TQString adminUserName, TQString adminGroupName, TQString machineAdminGroupName, const char * adminPassword, TQString rootUserName, const char * rootPassword, int ldifSchemaNumber=-1, uid_t userid=-1, gid_t groupid=-1, TQString ldapusername=TQString::null, TQString ldapgroupname=TQString::null) { SHA1 sha; sha.process(rootPassword, strlen(rootPassword)); TQString rootpw_hash = sha.base64Hash(); sha.reset(); sha.process(adminPassword, strlen(rootPassword)); TQString adminpw_hash = sha.base64Hash(); // RAJA FIXME // Created needed strings TQStringList domainChunks = TQStringList::split(".", realmconfig.name.lower()); TQString basedcname = "dc=" + domainChunks.join(",dc="); TQString simpledcname = domainChunks[0]; TQString simpledcnamecap = simpledcname.lower(); simpledcnamecap[0] = simpledcnamecap[0].upper(); TQString timestamp = TQDateTime::currentDateTime().toString(TQt::ISODate); timestamp.replace("-", ""); timestamp.replace(":", ""); timestamp.replace("T", ""); TQFile ifile(infile); TQFile ofile(outfile); if (ifile.open(IO_ReadOnly)) { if (ofile.open(IO_WriteOnly)) { TQString line; TQTextStream istream(&ifile); TQTextStream ostream(&ofile); while (!istream.atEnd()) { line = istream.readLine(); line.replace("@@@REALM_DCNAME@@@", basedcname); line.replace("@@@REALM_UCNAME@@@", realmconfig.name.upper()); line.replace("@@@REALM_LCNAME@@@", realmconfig.name.lower()); line.replace("@@@ADMINSERVER@@@", realmconfig.admin_server); line.replace("@@@ADMINPORT@@@", TQString("%1").arg(realmconfig.admin_server_port)); line.replace("@@@KDCSERVER@@@", realmconfig.kdc); line.replace("@@@KDCPORT@@@", TQString("%1").arg(realmconfig.kdc_port)); line.replace("@@@ROOTUSER@@@", rootUserName); line.replace("@@@ROOTPW_SHA@@@", rootpw_hash); line.replace("@@@ADMINUSER@@@", adminUserName); line.replace("@@@ADMINGROUP@@@", adminGroupName); line.replace("@@@LOCALADMINGROUP@@@", machineAdminGroupName); line.replace("@@@ADMINPW_SHA@@@", adminpw_hash); line.replace("@@@PKINIT_REQUIRE_EKU@@@", (realmconfig.pkinit_require_eku)?"yes":"no"); line.replace("@@@PKINIT_REQUIRE_KRBTGT_OTHERNAME@@@", (realmconfig.pkinit_require_krbtgt_otherName)?"yes":"no"); line.replace("@@@WIN2K_PKINIT@@@", (realmconfig.win2k_pkinit)?"yes":"no"); line.replace("@@@WIN2K_PKINIT_REQUIRE_BINDING@@@", (realmconfig.win2k_pkinit_require_binding)?"yes":"no"); line.replace("@@@REALM_SIMPLE_CP_NAME@@@", simpledcnamecap); line.replace("@@@REALM_SIMPLE_LC_NAME@@@", simpledcname.lower()); line.replace("@@@TIMESTAMP@@@", timestamp); line.replace("@@@LDAP_KEYTAB_FILE@@@", LDAP_KEYTAB_FILE); line.replace("@@@LDAP_USER_NAME@@@", ldapusername); line.replace("@@@LDAP_GROUP_NAME@@@", ldapgroupname); if (ldifSchemaNumber >= 0) { line.replace("@@@LDIFSCHEMANUMBER@@@", TQString("%1").arg(ldifSchemaNumber)); } ostream << line << "\n"; } ifile.close(); ofile.close(); // Set permissions if ((userid > 0) && (groupid > 0)) { chown(outfile.ascii(), userid, groupid); } } else { //KMessageBox::error(0, i18n("Unable to open output schema file %1 for writing").arg(outfile), i18n("Internal Failure")); printf("[INTERNAL FAILURE] Unable to open output schema file %s for writing\n\r", outfile.ascii()); fflush(stdout); } } else { //KMessageBox::error(0, i18n("Unable to open template schema file %1").arg(infile), i18n("Internal Failure")); printf("[INTERNAL FAILURE] Unable to open template schema file %s\n\r", infile.ascii()); fflush(stdout); } // Keep UI responsive tqApp->processEvents(); } int LDAPController::controlKAdminDaemon(sc_command command) { if (command == SC_RESTART) { // FIXME // This assumes Debian! return system("/etc/init.d/openbsd-inetd restart"); } } int LDAPController::controlSASLServer(sc_command command) { if (command == SC_START) { // FIXME // This assumes Debian! return system("/etc/init.d/saslauthd start"); } if (command == SC_STOP) { // FIXME // This assumes Debian! return system("/etc/init.d/saslauthd stop"); } if (command == SC_RESTART) { // FIXME // This assumes Debian! return system("/etc/init.d/saslauthd restart"); } } int LDAPController::controlHeimdalServer(sc_command command, uid_t userid, gid_t groupid) { if (command == SC_START) { // FIXME // This assumes Debian! return system("/etc/init.d/heimdal-kdc start"); } if (command == SC_STOP) { // FIXME // This assumes Debian! return system("/etc/init.d/heimdal-kdc stop"); } if (command == SC_RESTART) { // FIXME // This assumes Debian! return system("/etc/init.d/heimdal-kdc restart"); } if (command == SC_PURGE) { controlHeimdalServer(SC_STOP); system("rm -f " + TQString(LDAP_KEYTAB_FILE)); // FIXME // This assumes Debian system("rm -f /etc/krb5.keytab"); system("rm -rf /var/lib/heimdal-kdc/*"); } if (command == SC_SETDBPERMS) { if ((userid > 0) && (groupid > 0)) { TQString command; command = TQString("chgrp %1 " + TQString(LDAP_KEYTAB_FILE)).arg(groupid); system(command.ascii()); chmod(LDAP_KEYTAB_FILE, S_IRUSR|S_IWUSR|S_IRGRP); } } } int LDAPController::controlLDAPServer(sc_command command, uid_t userid, gid_t groupid) { if (command == SC_START) { // FIXME // This assumes Debian! return system("/etc/init.d/slapd start"); } if (command == SC_STOP) { // FIXME // This assumes Debian! return system("/etc/init.d/slapd stop"); } if (command == SC_RESTART) { // FIXME // This assumes Debian! return system("/etc/init.d/slapd restart"); } if (command == SC_PURGE) { controlLDAPServer(SC_STOP); // FIXME // This assumes Debian! system("rm -rf /var/lib/ldap/*"); system("rm -rf /etc/ldap/slapd.d/*"); } if (command == SC_SETDBPERMS) { if ((userid > 0) && (groupid > 0)) { // FIXME // This assumes Debian! TQString command; command = TQString("chown -R %1 /var/lib/ldap/*").arg(userid); system(command.ascii()); command = TQString("chgrp -R %1 /var/lib/ldap/*").arg(groupid); system(command.ascii()); command = TQString("chown -R %1 /etc/ldap/slapd.d/*").arg(userid); system(command.ascii()); command = TQString("chgrp -R %1 /etc/ldap/slapd.d/*").arg(groupid); system(command.ascii()); } } return -2; } TQString readFullLineFromPtyProcess(PtyProcess* proc) { TQString result = ""; while ((!result.contains("\n")) && (!result.contains(":")) && (!result.contains(">"))) { result = result + TQString(proc->readLine(false)); tqApp->processEvents(); } return result; } int LDAPController::initializeNewKerberosRealm(TQString realmName, TQString *errstr) { TQCString command = "kadmin"; QCStringList args; args << TQCString("-l"); TQString prompt; PtyProcess kadminProc; kadminProc.exec(command, args); prompt = kadminProc.readLine(true); prompt = prompt.stripWhiteSpace(); if (prompt == "kadmin>") { kadminProc.writeLine(TQCString("init "+realmName), true); prompt = kadminProc.readLine(true); // Discard our own input prompt = readFullLineFromPtyProcess(&kadminProc); prompt = prompt.stripWhiteSpace(); if (prompt.contains("authentication failed")) { if (errstr) *errstr = prompt; kadminProc.writeLine("quit", true); return 1; } else if (prompt.startsWith("Realm max")) { kadminProc.writeLine("unlimited", true); prompt = kadminProc.readLine(true); // Discard our own input prompt = readFullLineFromPtyProcess(&kadminProc); prompt = prompt.stripWhiteSpace(); if (prompt.startsWith("Realm max")) { kadminProc.writeLine("unlimited", true); prompt = kadminProc.readLine(true); // Discard our own input prompt = readFullLineFromPtyProcess(&kadminProc); prompt = prompt.stripWhiteSpace(); } if (prompt != "kadmin>") { if (errstr) *errstr = prompt; kadminProc.writeLine("quit", true); return 1; } // Success! kadminProc.writeLine("quit", true); return 0; } // Failure if (errstr) *errstr = prompt; kadminProc.writeLine("quit", true); return 1; } if (errstr) *errstr = "Internal error. Verify that kadmin exists and can be executed."; return 1; // Failure } int LDAPController::addHostEntryToKerberosRealm(TQString kerberosHost, TQString *errstr) { TQCString command = "kadmin"; QCStringList args; args << TQCString("-l"); TQString hoststring = "host/"+kerberosHost; TQString prompt; PtyProcess kadminProc; kadminProc.exec(command, args); prompt = kadminProc.readLine(true); prompt = prompt.stripWhiteSpace(); if (prompt == "kadmin>") { kadminProc.writeLine(TQCString("ext "+hoststring), true); prompt = kadminProc.readLine(true); // Discard our own input prompt = readFullLineFromPtyProcess(&kadminProc); prompt = prompt.stripWhiteSpace(); if (prompt.contains("authentication failed")) { if (errstr) *errstr = prompt; kadminProc.writeLine("quit", true); return 1; } else if (prompt.endsWith("Principal does not exist")) { kadminProc.writeLine(TQCString("ank --random-key "+hoststring), true); prompt = kadminProc.readLine(true); // Discard our own input prompt = readFullLineFromPtyProcess(&kadminProc); prompt = prompt.stripWhiteSpace(); // Use all defaults while (prompt != "kadmin>") { if (prompt.contains("authentication failed")) { if (errstr) *errstr = prompt; kadminProc.writeLine("quit", true); return 1; } else { // Extract whatever default is in the [brackets] and feed it back to kadmin TQString defaultParam; int leftbracket = prompt.find("["); int rightbracket = prompt.find("]"); if ((leftbracket >= 0) && (rightbracket >= 0)) { leftbracket++; defaultParam = prompt.mid(leftbracket, rightbracket-leftbracket); } kadminProc.writeLine(TQCString(defaultParam), true); prompt = kadminProc.readLine(true); // Discard our own input prompt = kadminProc.readLine(true); prompt = prompt.stripWhiteSpace(); } } kadminProc.writeLine(TQCString("ext "+hoststring), true); prompt = kadminProc.readLine(true); // Discard our own input prompt = readFullLineFromPtyProcess(&kadminProc); prompt = prompt.stripWhiteSpace(); if (prompt != "kadmin>") { if (errstr) *errstr = prompt; kadminProc.writeLine("quit", true); return 1; } // Success! kadminProc.writeLine("quit", true); return 0; } else if (prompt == "kadmin>") { // Success! kadminProc.writeLine("quit", true); return 0; } // Failure if (errstr) *errstr = prompt; kadminProc.writeLine("quit", true); return 1; } if (errstr) *errstr = "Internal error. Verify that kadmin exists and can be executed."; return 1; // Failure } int LDAPController::addLDAPEntryToKerberosRealm(TQString ldapProcessOwnerName, TQString ldapHost, TQString *errstr) { TQCString command = "kadmin"; QCStringList args; args << TQCString("-l"); TQString hoststring = ldapProcessOwnerName+"/"+ldapHost; TQString prompt; PtyProcess kadminProc; kadminProc.exec(command, args); prompt = kadminProc.readLine(true); prompt = prompt.stripWhiteSpace(); if (prompt == "kadmin>") { kadminProc.writeLine(TQCString("ext --keytab="+TQString(LDAP_KEYTAB_FILE)+" "+hoststring), true); prompt = kadminProc.readLine(true); // Discard our own input prompt = readFullLineFromPtyProcess(&kadminProc); prompt = prompt.stripWhiteSpace(); if (prompt.contains("authentication failed")) { if (errstr) *errstr = prompt; kadminProc.writeLine("quit", true); return 1; } else if (prompt.endsWith("Principal does not exist")) { kadminProc.writeLine(TQCString("ank --random-key "+hoststring), true); prompt = kadminProc.readLine(true); // Discard our own input prompt = readFullLineFromPtyProcess(&kadminProc); prompt = prompt.stripWhiteSpace(); // Use all defaults while (prompt != "kadmin>") { if (prompt.contains("authentication failed")) { if (errstr) *errstr = prompt; kadminProc.writeLine("quit", true); return 1; } else { // Extract whatever default is in the [brackets] and feed it back to kadmin TQString defaultParam; int leftbracket = prompt.find("["); int rightbracket = prompt.find("]"); if ((leftbracket >= 0) && (rightbracket >= 0)) { leftbracket++; defaultParam = prompt.mid(leftbracket, rightbracket-leftbracket); } kadminProc.writeLine(TQCString(defaultParam), true); prompt = kadminProc.readLine(true); // Discard our own input prompt = kadminProc.readLine(true); prompt = prompt.stripWhiteSpace(); } } kadminProc.writeLine(TQCString("ext --keytab="+TQString(LDAP_KEYTAB_FILE)+" "+hoststring), true); prompt = kadminProc.readLine(true); // Discard our own input prompt = readFullLineFromPtyProcess(&kadminProc); prompt = prompt.stripWhiteSpace(); if (prompt != "kadmin>") { if (errstr) *errstr = prompt; kadminProc.writeLine("quit", true); return 1; } // Success! kadminProc.writeLine("quit", true); return 0; } else if (prompt == "kadmin>") { // Success! kadminProc.writeLine("quit", true); return 0; } // Failure if (errstr) *errstr = prompt; kadminProc.writeLine("quit", true); return 1; } if (errstr) *errstr = "Internal error. Verify that kadmin exists and can be executed."; return 1; // Failure } int LDAPController::setKerberosPasswordForUser(LDAPCredentials user, TQString *errstr) { if (user.password == "") { return 0; } TQCString command = "kadmin"; QCStringList args; args << TQCString("-l") << TQCString("-r") << TQCString(user.realm.upper()); TQString prompt; PtyProcess kadminProc; kadminProc.exec(command, args); prompt = kadminProc.readLine(true); prompt = prompt.stripWhiteSpace(); if (prompt == "kadmin>") { kadminProc.writeLine(TQCString("passwd "+user.username), true); prompt = kadminProc.readLine(true); // Discard our own input prompt = readFullLineFromPtyProcess(&kadminProc); prompt = prompt.stripWhiteSpace(); if (prompt.contains("authentication failed")) { if (errstr) *errstr = prompt; kadminProc.writeLine("quit", true); return 1; } else if ((prompt.endsWith(" Password:")) && (prompt.startsWith(TQString(user.username + "@")))) { kadminProc.writeLine(user.password, true); prompt = kadminProc.readLine(true); // Discard our own input prompt = kadminProc.readLine(true); prompt = prompt.stripWhiteSpace(); if ((prompt.endsWith(" Password:")) && (prompt.startsWith("Verify"))) { kadminProc.writeLine(user.password, true); prompt = kadminProc.readLine(true); // Discard our own input prompt = kadminProc.readLine(true); prompt = prompt.stripWhiteSpace(); } if (prompt != "kadmin>") { if (errstr) *errstr = prompt; kadminProc.writeLine("quit", true); return 1; } // Success! kadminProc.writeLine("quit", true); return 0; } else if (prompt == "kadmin>") { // Success! kadminProc.writeLine("quit", true); return 0; } // Failure if (errstr) *errstr = prompt; kadminProc.writeLine("quit", true); return 1; } if (errstr) *errstr = "Internal error. Verify that kadmin exists and can be executed."; return 1; // Failure } int LDAPController::createNewLDAPRealm(TQWidget* dialogparent, LDAPRealmConfig realmconfig, TQString adminUserName, TQString adminGroupName, TQString machineAdminGroupName, const char * adminPassword, TQString rootUserName, const char * rootPassword, TQString adminRealm, TQString *errstr) { int ldifSchemaNumber; ProcessingDialog pdialog(dialogparent); pdialog.setStatusMessage(i18n("Loading data for realm deployment...")); pdialog.raise(); pdialog.setActiveWindow(); tqApp->processEvents(); // Reset improperly uninitialized variables realmconfig.bonded = true; // Find the templates TQString templateDir = locate("data", "kcmldapcontroller/skel/heimdal/heimdal.defaults"); templateDir.replace("heimdal/heimdal.defaults", ""); if (templateDir == "") { if (errstr) *errstr = i18n("Unable to locate required template files"); pdialog.closeDialog(); return -1; } KTempDir configTempDir; configTempDir.setAutoDelete(true); configTempDir.setAutoDelete(false); // RAJA DEBUG ONLY FIXME TQString destDir = "/etc/"; pdialog.setStatusMessage(i18n("Stopping servers...")); // Stop SASL if (controlSASLServer(SC_STOP) != 0) { if (errstr) *errstr = i18n("Unable to stop SASL server"); pdialog.closeDialog(); return -1; } // Stop Heimdal if (controlHeimdalServer(SC_STOP) != 0) { if (errstr) *errstr = i18n("Unable to stop Kerberos server"); pdialog.closeDialog(); return -1; } // Stop slapd if (controlLDAPServer(SC_STOP) != 0) { if (errstr) *errstr = i18n("Unable to stop LDAP server"); pdialog.closeDialog(); return -1; } pdialog.setStatusMessage(i18n("Purging existing LDAP database...")); tqApp->processEvents(); controlHeimdalServer(SC_PURGE); controlLDAPServer(SC_PURGE); pdialog.setStatusMessage(i18n("Installing new LDAP schema...")); tqApp->processEvents(); mkdir(TQString(destDir + "heimdal-kdc").ascii(), S_IRUSR|S_IWUSR|S_IXUSR); mkdir(TQString(destDir + "ldap").ascii(), S_IRUSR|S_IWUSR|S_IXUSR); mkdir(TQString(destDir + "ldap/slapd.d").ascii(), S_IRUSR|S_IWUSR|S_IXUSR); mkdir(TQString(destDir + "ldap/slapd.d/cn=config").ascii(), S_IRUSR|S_IWUSR|S_IXUSR); mkdir(TQString(destDir + "ldap/slapd.d/cn=config/cn=schema").ascii(), S_IRUSR|S_IWUSR|S_IXUSR); // Heimdal replacePlaceholdersInFile(templateDir + "heimdal/heimdal.defaults", HEIMDAL_DEFAULT_FILE, realmconfig, adminUserName, adminGroupName, machineAdminGroupName, adminPassword, rootUserName, rootPassword); replacePlaceholdersInFile(templateDir + "heimdal/kadmind.acl", destDir + "heimdal-kdc/kadmind.acl", realmconfig, adminUserName, adminGroupName, machineAdminGroupName, adminPassword, rootUserName, rootPassword); replacePlaceholdersInFile(templateDir + "heimdal/kdc.conf", destDir + "heimdal-kdc/kdc.conf", realmconfig, adminUserName, adminGroupName, machineAdminGroupName, adminPassword, rootUserName, rootPassword); replacePlaceholdersInFile(templateDir + "heimdal/krb5.conf", destDir + "krb5.conf", realmconfig, adminUserName, adminGroupName, machineAdminGroupName, adminPassword, rootUserName, rootPassword); // RAJA DEBUG // if (system("kstash --random-key") != 0) { // if (errstr) *errstr = i18n("Unable to create Kerberos foundational key"); // pdialog.closeDialog(); // return -1; // } // OpenLDAP replacePlaceholdersInFile(templateDir + "openldap/skel.ldif", configTempDir.name() + "skel.ldif", realmconfig, adminUserName, adminGroupName, machineAdminGroupName, adminPassword, rootUserName, rootPassword); // replacePlaceholdersInFile(templateDir + "openldap/ldap/slapd.conf", destDir + "ldap/slapd.conf", realmconfig, adminUserName, adminGroupName, machineAdminGroupName, adminPassword, rootUserName, rootPassword); replacePlaceholdersInFile(templateDir + "openldap/ldap/slapd.defaults", LDAP_DEFAULT_FILE, realmconfig, adminUserName, adminGroupName, machineAdminGroupName, adminPassword, rootUserName, rootPassword, -1, -1, -1, m_ldapUserName, m_ldapGroupName); // SASL replacePlaceholdersInFile(templateDir + "sasl/saslauthd.defaults", SASL_DEFAULT_FILE, realmconfig, adminUserName, adminGroupName, machineAdminGroupName, adminPassword, rootUserName, rootPassword); replacePlaceholdersInFile(templateDir + "sasl/slapd.conf", SASL_CONTROL_FILE, realmconfig, adminUserName, adminGroupName, machineAdminGroupName, adminPassword, rootUserName, rootPassword); // FIXME // This assumes Debian! // Grant LDAP access to SASL mux pipe system("dpkg-statoverride --remove --quiet /var/run/saslauthd"); system(TQString("dpkg-statoverride --add root %1 710 /var/run/saslauthd").arg(m_ldapGroupName).ascii()); // FIXME // This assumes Debian! system("ln -s /etc/heimdal-kdc/kadmind.acl /var/lib/heimdal-kdc/kadmind.acl"); system("ln -s /etc/heimdal-kdc/kdc.conf /var/lib/heimdal-kdc/kdc.conf"); struct stat sb; uid_t slapd_uid = 0; gid_t slapd_gid = 0; // Get LDAP user uid/gid struct passwd *pwd; pwd = getpwnam(m_ldapUserName); slapd_uid = pwd->pw_uid; slapd_gid = pwd->pw_gid; // SECURITY // Make sure that the ldapi:/// socket in /var/run/slapd/ldapi is NOT world readable/writable (technically the permissions are for the directory containing the ldapi socket) // This would mean that anyone with access to the server running LDAP can dump the KRB5 keys! // FIXME // Can we do anything about this now? // Base database configuration replacePlaceholdersInFile(templateDir + "openldap/ldif/config.ldif", destDir + "ldap/slapd.d/" + TQString("cn=config.ldif"), realmconfig, adminUserName, adminGroupName, machineAdminGroupName, adminPassword, rootUserName, rootPassword, -1, slapd_uid, slapd_gid); replacePlaceholdersInFile(templateDir + "openldap/ldif/schema.ldif", destDir + "ldap/slapd.d/cn=config/" + TQString("cn=schema.ldif"), realmconfig, adminUserName, adminGroupName, machineAdminGroupName, adminPassword, rootUserName, rootPassword, -1, slapd_uid, slapd_gid); ldifSchemaNumber = 0; replacePlaceholdersInFile(templateDir + "openldap/ldif/olcConfig.ldif", destDir + "ldap/slapd.d/cn=config/" + TQString("olcDatabase={%1}config.ldif").arg(ldifSchemaNumber), realmconfig, adminUserName, adminGroupName, machineAdminGroupName, adminPassword, rootUserName, rootPassword, ldifSchemaNumber, slapd_uid, slapd_gid); replacePlaceholdersInFile(templateDir + "openldap/ldif/moduleConfig.ldif", destDir + "ldap/slapd.d/cn=config/" + TQString("cn=module{%1}.ldif").arg(ldifSchemaNumber), realmconfig, adminUserName, adminGroupName, machineAdminGroupName, adminPassword, rootUserName, rootPassword, ldifSchemaNumber, slapd_uid, slapd_gid); ldifSchemaNumber = 1; replacePlaceholdersInFile(templateDir + "openldap/ldif/olcDatabase.ldif", destDir + "ldap/slapd.d/cn=config/" + TQString("olcDatabase={%1}hdb.ldif").arg(ldifSchemaNumber), realmconfig, adminUserName, adminGroupName, machineAdminGroupName, adminPassword, rootUserName, rootPassword, ldifSchemaNumber, slapd_uid, slapd_gid); // Schema files ldifSchemaNumber = 0; replacePlaceholdersInFile(templateDir + "openldap/ldif/core.ldif", destDir + "ldap/slapd.d/cn=config/cn=schema/" + TQString("cn={%1}core.ldif").arg(ldifSchemaNumber), realmconfig, adminUserName, adminGroupName, machineAdminGroupName, adminPassword, rootUserName, rootPassword, ldifSchemaNumber, slapd_uid, slapd_gid); ldifSchemaNumber = 1; replacePlaceholdersInFile(templateDir + "openldap/ldif/cosine.ldif", destDir + "ldap/slapd.d/cn=config/cn=schema/" + TQString("cn={%1}cosine.ldif").arg(ldifSchemaNumber), realmconfig, adminUserName, adminGroupName, machineAdminGroupName, adminPassword, rootUserName, rootPassword, ldifSchemaNumber, slapd_uid, slapd_gid); ldifSchemaNumber = 2; replacePlaceholdersInFile(templateDir + "openldap/ldif/inetorgperson.ldif", destDir + "ldap/slapd.d/cn=config/cn=schema/" + TQString("cn={%1}inetorgperson.ldif").arg(ldifSchemaNumber), realmconfig, adminUserName, adminGroupName, machineAdminGroupName, adminPassword, rootUserName, rootPassword, ldifSchemaNumber, slapd_uid, slapd_gid); ldifSchemaNumber = 3; replacePlaceholdersInFile(templateDir + "openldap/ldif/rfc2307bis.ldif", destDir + "ldap/slapd.d/cn=config/cn=schema/" + TQString("cn={%1}rfc2307bis.ldif").arg(ldifSchemaNumber), realmconfig, adminUserName, adminGroupName, machineAdminGroupName, adminPassword, rootUserName, rootPassword, ldifSchemaNumber, slapd_uid, slapd_gid); ldifSchemaNumber = 4; replacePlaceholdersInFile(templateDir + "openldap/ldif/rfc2739.ldif", destDir + "ldap/slapd.d/cn=config/cn=schema/" + TQString("cn={%1}rfc2739.ldif").arg(ldifSchemaNumber), realmconfig, adminUserName, adminGroupName, machineAdminGroupName, adminPassword, rootUserName, rootPassword, ldifSchemaNumber, slapd_uid, slapd_gid); ldifSchemaNumber = 5; replacePlaceholdersInFile(templateDir + "openldap/ldif/ppolicy.ldif", destDir + "ldap/slapd.d/cn=config/cn=schema/" + TQString("cn={%1}ppolicy.ldif").arg(ldifSchemaNumber), realmconfig, adminUserName, adminGroupName, machineAdminGroupName, adminPassword, rootUserName, rootPassword, ldifSchemaNumber, slapd_uid, slapd_gid); ldifSchemaNumber = 6; replacePlaceholdersInFile(templateDir + "openldap/ldif/ems-core.ldif", destDir + "ldap/slapd.d/cn=config/cn=schema/" + TQString("cn={%1}ems-core.ldif").arg(ldifSchemaNumber), realmconfig, adminUserName, adminGroupName, machineAdminGroupName, adminPassword, rootUserName, rootPassword, ldifSchemaNumber, slapd_uid, slapd_gid); ldifSchemaNumber = 7; replacePlaceholdersInFile(templateDir + "openldap/ldif/hdb.ldif", destDir + "ldap/slapd.d/cn=config/cn=schema/" + TQString("cn={%1}hdb.ldif").arg(ldifSchemaNumber), realmconfig, adminUserName, adminGroupName, machineAdminGroupName, adminPassword, rootUserName, rootPassword, ldifSchemaNumber, slapd_uid, slapd_gid); ldifSchemaNumber = 8; replacePlaceholdersInFile(templateDir + "openldap/ldif/tde-core.ldif", destDir + "ldap/slapd.d/cn=config/cn=schema/" + TQString("cn={%1}tde-core.ldif").arg(ldifSchemaNumber), realmconfig, adminUserName, adminGroupName, machineAdminGroupName, adminPassword, rootUserName, rootPassword, ldifSchemaNumber, slapd_uid, slapd_gid); // Set permissions chmod(TQString(destDir + "heimdal.defaults").ascii(), S_IRUSR|S_IWUSR|S_IRGRP); chmod(TQString(destDir + "heimdal-kdc/kadmind.acl").ascii(), S_IRUSR|S_IWUSR|S_IRGRP); chmod(TQString(destDir + "heimdal-kdc/kdc.conf").ascii(), S_IRUSR|S_IWUSR|S_IRGRP); chmod(TQString(destDir + "krb5.conf").ascii(), S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH); chmod(TQString(configTempDir.name() + "skel.ldif").ascii(), S_IRUSR|S_IWUSR); // chmod(TQString(destDir + "ldap/slapd.conf").ascii(), S_IRUSR|S_IWUSR); chmod(TQString(destDir + "ldap/slapd.defaults").ascii(), S_IRUSR|S_IWUSR|S_IRGRP); pdialog.setStatusMessage(i18n("Loading initial database into LDAP...")); tqApp->processEvents(); // Load database KProcess slapadd; slapadd << "slapadd" << "-l" << configTempDir.name() + "skel.ldif"; slapadd.start(); while (slapadd.isRunning()) { tqApp->processEvents(); } if (slapadd.exitStatus() != 0) { if (errstr) *errstr = i18n("Unable to import initial database into LDAP"); pdialog.closeDialog(); return -1; } controlLDAPServer(SC_SETDBPERMS, slapd_uid, slapd_gid); pdialog.setStatusMessage(i18n("Starting servers...")); tqApp->processEvents(); // Start slapd if (controlLDAPServer(SC_START) != 0) { if (errstr) *errstr = i18n("Unable to start LDAP server"); pdialog.closeDialog(); return -1; } // Start Heimdal if (controlHeimdalServer(SC_START) != 0) { if (errstr) *errstr = i18n("Unable to start Kerberos server"); pdialog.closeDialog(); return -1; } pdialog.setStatusMessage(i18n("Initializing Kerberos database...")); tqApp->processEvents(); TQString errorstring; if (initializeNewKerberosRealm(realmconfig.name.upper(), &errorstring) != 0) { if (errstr) *errstr = i18n("Unable to initialize Kerberos database").append(errorstring); pdialog.closeDialog(); return -1; } if (addHostEntryToKerberosRealm(realmconfig.kdc, &errorstring) != 0) { if (errstr) *errstr = i18n("Unable to add KDC server entry to Kerberos database").arg(m_ldapUserName).append(errorstring); pdialog.closeDialog(); return -1; } if (addLDAPEntryToKerberosRealm(m_ldapUserName, realmconfig.admin_server, &errorstring) != 0) { if (errstr) *errstr = i18n("Unable to add %1 entry to Kerberos database").arg(m_ldapUserName).append(errorstring); pdialog.closeDialog(); return -1; } if (addLDAPEntryToKerberosRealm("ldap", realmconfig.admin_server, &errorstring) != 0) { if (errstr) *errstr = i18n("Unable to add LDAP entry to Kerberos database").append(errorstring); pdialog.closeDialog(); return -1; } controlHeimdalServer(SC_SETDBPERMS, slapd_uid, slapd_gid); // Move all those new Heimdal entries to the correct tree/branch TQStringList domainChunks = TQStringList::split(".", realmconfig.name.lower()); TQString basedcname = "dc=" + domainChunks.join(",dc="); LDAPCredentials* credentials = new LDAPCredentials; credentials->username = "cn="+rootUserName+","+basedcname; credentials->password = rootPassword; credentials->realm = realmconfig.name.upper(); LDAPManager* ldap_mgr = new LDAPManager(realmconfig.name.upper(), realmconfig.admin_server, credentials); if (ldap_mgr->moveKerberosEntries("o=kerberos,cn=kerberos control,ou=master services,ou=core,ou=realm," + basedcname, &errorstring) != 0) { delete ldap_mgr; delete credentials; if (errstr) *errstr = errorstring; pdialog.closeDialog(); return -1; } delete ldap_mgr; delete credentials; // Set @@@ADMINUSER@@@ password in kadmin LDAPCredentials adminuser; adminuser.username = adminUserName; adminuser.password = adminPassword; adminuser.realm = realmconfig.name.upper(); if (setKerberosPasswordForUser(adminuser, &errorstring) != 0) { if (errstr) *errstr = i18n("Unable to set user password in Kerberos database").append(errorstring); pdialog.closeDialog(); return -1; } pdialog.setStatusMessage(i18n("Configuring local system...")); tqApp->processEvents(); // Write the TDE realm configuration file LDAPRealmConfigList realms; realms.insert(realmconfig.name, realmconfig); LDAPManager::writeTDERealmList(realms, m_systemconfig); m_systemconfig->writeEntry("DefaultRealm", realmconfig.name); m_systemconfig->sync(); LDAPManager::writeLDAPConfFile(realmconfig); pdialog.setStatusMessage(i18n("(Re)starting servers...")); tqApp->processEvents(); // Restart slapd if (controlLDAPServer(SC_RESTART) != 0) { if (errstr) *errstr = i18n("Unable to restart LDAP server"); pdialog.closeDialog(); return -1; } // Restart Heimdal if (controlHeimdalServer(SC_RESTART) != 0) { if (errstr) *errstr = i18n("Unable to restart Kerberos server"); pdialog.closeDialog(); return -1; } // Restart kadmind if (controlKAdminDaemon(SC_RESTART) != 0) { if (errstr) *errstr = i18n("Unable to restart Kerberos Administration Service"); pdialog.closeDialog(); return -1; } // Start SASL if (controlSASLServer(SC_START) != 0) { if (errstr) *errstr = i18n("Unable to start SASL server"); pdialog.closeDialog(); return -1; } // RAJA FIXME pdialog.closeDialog(); } int LDAPController::buttons() { return KCModule::Apply|KCModule::Help; } TQString LDAPController::quickHelp() const { return i18n("This module configures an LDAP Realm Controller."); }