You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
kcmldapcontroller/src/ldapcontroller.cpp

1805 lines
70 KiB

/***************************************************************************
* 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 <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <pwd.h>
#include <tqlayout.h>
#include <klocale.h>
#include <kglobal.h>
#include <kparts/genericfactory.h>
#include <ksimpleconfig.h>
#include <kglobalsettings.h>
#include <kstandarddirs.h>
#include <kurlrequester.h>
#include <klistview.h>
#include <kopenwith.h>
#include <kpropertiesdialog.h>
#include <kio/job.h>
#include <tqdir.h>
#include <tqheader.h>
#include <kcombobox.h>
#include <kmessagebox.h>
#include <tqcheckbox.h>
#include <ktempdir.h>
#include <kprocess.h>
#include <tdesu/process.h>
#include <libtdeldap.h>
#include <kfiledialog.h>
#include <kpassdlg.h>
#include "sha1.h"
#include "ldapcontroller.h"
#include "primaryrealmwizard/primaryrealmwizard.h"
#include "secondaryrealmwizard/secondaryrealmwizard.h"
#include "processingdialog.h"
#include "ldapcontrollerconfigbase.h"
// FIXME
// Connect this to CMake/Automake
#define KDE_CONFDIR "/etc/trinity"
#define TDE_LIBDIR "/opt/trinity/lib"
#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 HEIMDAL_ACL_FILE "/etc/heimdal-kdc/kadmind.acl"
#define ROLE_WORKSTATION 0
#define ROLE_SECONDARY_REALM_CONTROLLER 1
#define ROLE_PRIMARY_REALM_CONTROLLER 2
#define KEY_STRENGTH 2048
typedef KGenericFactory<LDAPController, TQWidget> 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);
TDEAboutData* about = new TDEAboutData("ldapcontroller", I18N_NOOP("TDE LDAP Controller"), "0.1",
I18N_NOOP("TDE LDAP Controller Control Panel Module"),
TDEAboutData::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("Secondary Realm Controller", ROLE_SECONDARY_REALM_CONTROLLER);
m_base->systemRole->insertItem("Primary Realm Controller", ROLE_PRIMARY_REALM_CONTROLLER);
setRootOnlyMsg(i18n("<b>LDAP controller settings take effect system wide, and require administrator access to modify</b><br>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()));
connect(m_base->caRegenerate, TQT_SIGNAL(clicked()), this, TQT_SLOT(btncaRegenerate()));
connect(m_base->caExportKey, TQT_SIGNAL(clicked()), this, TQT_SLOT(btncaExportKey()));
connect(m_base->caExportCert, TQT_SIGNAL(clicked()), this, TQT_SLOT(btncaExportCert()));
connect(m_base->krbRegenerate, TQT_SIGNAL(clicked()), this, TQT_SLOT(btnkrbRegenerate()));
connect(m_base->krbExportKey, TQT_SIGNAL(clicked()), this, TQT_SLOT(btnkrbExportKey()));
connect(m_base->krbExportCert, TQT_SIGNAL(clicked()), this, TQT_SLOT(btnkrbExportCert()));
connect(m_base->ldapRegenerate, TQT_SIGNAL(clicked()), this, TQT_SLOT(btnldapRegenerate()));
connect(m_base->ldapExportKey, TQT_SIGNAL(clicked()), this, TQT_SLOT(btnldapExportKey()));
connect(m_base->ldapExportCert, TQT_SIGNAL(clicked()), this, TQT_SLOT(btnldapExportCert()));
connect(m_base->btnChangeLDAPRootPassword, TQT_SIGNAL(clicked()), this, TQT_SLOT(btnChangeLDAPRootPassword()));
connect(m_base->btnChangeRealmAdminPassword, TQT_SIGNAL(clicked()), this, TQT_SLOT(btnChangeRealmAdminPassword()));
connect(&m_certRefreshTimer, TQT_SIGNAL(timeout()), this, TQT_SLOT(updateCertDisplay()));
m_fqdn = LDAPManager::getMachineFQDN();
// FIXME
// This assumes Debian!
m_ldapUserName = "openldap";
m_ldapGroupName = "openldap";
load();
processLockouts();
};
LDAPController::~LDAPController() {
}
void system_safe(const char * cmdstr) {
if (system(cmdstr) < 0) {
printf("[ERROR] System call to '%s' failed!\n\r", cmdstr);
}
}
void chown_safe(const char * file, uid_t user, gid_t group) {
if (chown(file, user, group) < 0) {
printf("[ERROR] Chown call to '%s' for %d:%d failed!\n\r", file, user, group);
}
}
void LDAPController::systemRoleChanged() {
int previousRole = m_prevRole;
if (m_base->systemRole->currentItem() != m_prevRole) {
// 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 (m_base->systemRole->currentItem() == ROLE_PRIMARY_REALM_CONTROLLER) {
if (previousRole == ROLE_SECONDARY_REALM_CONTROLLER) {
// TODO FIXME
KMessageBox::error(0, i18n("<qt>Secondary realm controller promotion is not yet available<p>If you want to see it implemented, contact the Trinity Desktop developers</qt>"), i18n("Feature Not Yet Available"));
m_base->systemRole->setCurrentItem(previousRole);
}
else {
if (bonded) {
KMessageBox::error(0, i18n("<qt>You are already bonded to a realm!<p>Please unbond from all realms before selecting a Realm Controller role</qt>"), i18n("Common Sense Failure"));
m_base->systemRole->setCurrentItem(previousRole);
}
else {
// Something will probably change
save();
PrimaryRealmWizard realmwizard(this, m_fqdn, m_certconfig, this);
if (realmwizard.exec() < 0) {
// Wizard was cancelled
// Back out all changes!
m_base->systemRole->setCurrentItem(previousRole);
save();
}
else {
// Wizard completed; commit changes
save();
}
// Something probably changed
load();
}
}
}
else if (m_base->systemRole->currentItem() == ROLE_SECONDARY_REALM_CONTROLLER) {
#if 1
// TODO FIXME
KMessageBox::error(0, i18n("<qt>Secondary realm controller support is not yet available<p>If you want to see it implemented, contact the Trinity Desktop developers</qt>"), i18n("Feature Not Yet Available"));
m_base->systemRole->setCurrentItem(previousRole);
#else
if (previousRole == ROLE_PRIMARY_REALM_CONTROLLER) {
// TODO FIXME
KMessageBox::error(0, i18n("<qt>Primary realm controller demotion is not yet available<p>If you want to see it implemented, contact the Trinity Desktop developers</qt>"), i18n("Feature Not Yet Available"));
m_base->systemRole->setCurrentItem(previousRole);
}
else {
if (bonded) {
KMessageBox::error(0, i18n("<qt>You are already bonded to a realm!<p>Please unbond from all realms before selecting a Realm Controller role</qt>"), i18n("Common Sense Failure"));
m_base->systemRole->setCurrentItem(previousRole);
}
else {
// Something will probably change
save();
SecondaryRealmWizard realmwizard(this, m_fqdn, m_certconfig, this);
if (realmwizard.exec() < 0) {
// Wizard was cancelled
// Back out all changes!
m_base->systemRole->setCurrentItem(previousRole);
save();
}
else {
// Wizard completed; commit changes
save();
}
// Something probably changed
load();
}
}
#endif
}
else if (m_base->systemRole->currentItem() == ROLE_WORKSTATION) {
if (KMessageBox::warningYesNo(this, i18n("<qt><b>WARNING</b><br>You are attempting to demote a realm controller<p>This action will <b>PERMANENTLY DESTROY</b> the realm directory stored on this machine<p>If you do not want to do this, select <b>Cancel</b> below</qt>"), i18n("Are you absolutely sure?"), TQString("Continue"), TQString("Cancel")) == KMessageBox::Yes) {
ProcessingDialog pdialog(this);
pdialog.setStatusMessage(i18n("Preparing to demote primary realm controller..."));
pdialog.raise();
pdialog.setActiveWindow();
tqApp->processEvents();
save();
pdialog.setStatusMessage(i18n("Stopping servers..."));
// Stop SASL
if (controlSASLServer(SC_STOP) != 0) {
//
}
// Stop Heimdal
if (controlHeimdalServer(SC_STOP) != 0) {
//
}
// Stop slapd
if (controlLDAPServer(SC_STOP) != 0) {
//
}
pdialog.setStatusMessage(i18n("Purging LDAP database..."));
tqApp->processEvents();
controlHeimdalServer(SC_PURGE);
controlLDAPServer(SC_PURGE);
pdialog.setStatusMessage(i18n("Purging local configuration..."));
tqApp->processEvents();
system_safe(TQString("rm -f %1").arg(CRON_UPDATE_PRIMARY_REALM_CERTIFICATES_FILE));
system_safe(TQString("rm -rf %1").arg(TDE_CERTIFICATE_DIR));
// Write the TDE realm configuration file
LDAPRealmConfigList realms;
LDAPManager::writeTDERealmList(realms, m_systemconfig);
m_systemconfig->setGroup(NULL);
m_systemconfig->deleteEntry("DefaultRealm");
m_systemconfig->sync();
pdialog.closeDialog();
load();
}
else {
m_base->systemRole->setCurrentItem(previousRole);
}
}
}
}
void LDAPController::processLockouts() {
bool enabled = m_base->systemEnableSupport->isChecked();
bool canChangeLDAPEnabled = true;
if (getuid() != 0 || !m_systemconfig->checkConfigFilesWritable( true )) {
canChangeLDAPEnabled = false;
enabled = false;
}
if (m_base->systemRole->currentItem() != ROLE_WORKSTATION) {
canChangeLDAPEnabled = false;
}
m_base->systemEnableSupport->setEnabled(canChangeLDAPEnabled);
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 == "Primary Realm Controller") {
m_base->systemRole->setCurrentItem(ROLE_PRIMARY_REALM_CONTROLLER);
}
else {
m_base->systemRole->setCurrentItem(ROLE_WORKSTATION);
}
m_prevRole = m_base->systemRole->currentItem();
// Load cert config
m_systemconfig->setGroup("Certificates");
m_certconfig.countryName = m_systemconfig->readEntry("countryName");
m_certconfig.stateOrProvinceName = m_systemconfig->readEntry("stateOrProvinceName");
m_certconfig.localityName = m_systemconfig->readEntry("localityName");
m_certconfig.organizationName = m_systemconfig->readEntry("organizationName");
m_certconfig.orgUnitName = m_systemconfig->readEntry("orgUnitName");
m_certconfig.commonName = m_systemconfig->readEntry("commonName");
m_certconfig.emailAddress = m_systemconfig->readEntry("emailAddress");
m_realmconfig = LDAPManager::readTDERealmList(m_systemconfig, !thisIsMyMachine);
if (!thisIsMyMachine) {
LDAPManager::writeTDERealmList(m_realmconfig, m_systemconfig);
}
m_systemconfig->setGroup(NULL);
m_defaultRealm = m_systemconfig->readEntry("DefaultRealm");
if (m_base->systemRole->currentItem() == ROLE_PRIMARY_REALM_CONTROLLER) {
m_base->groupRealmController->show();
m_base->groupRealmCertificates->show();
m_base->realmName->setText(m_defaultRealm);
// Display builtin account and group names, and provide a password reset button for each builtin user (yes, this includes the LDAP admin account!)
// FIXME
// root account should not be locked to "admin"!
// when fixing, please fix the other instance of locked "admin" in realmwizard.cpp ::accept()
m_base->ldapRootUser->setText(TQString("cn=%1,").arg("admin") + LDAPManager::ldapdnForRealm(m_defaultRealm));
TQString realmname = m_defaultRealm.upper();
LDAPCredentials* credentials = new LDAPCredentials;
credentials->username = "";
credentials->password = "";
credentials->realm = realmname;
LDAPManager* ldap_mgr = new LDAPManager(realmname, "ldapi://", credentials);
TQString errorstring;
LDAPTDEBuiltinsInfo builtins = ldap_mgr->getTDEBuiltinMappings(&errorstring);
delete ldap_mgr;
delete credentials;
m_base->realmAdminUser->setText(LDAPManager::cnFromDn(builtins.builtinRealmAdminAccount));
m_base->realmAdminGroup->setText(LDAPManager::cnFromDn(builtins.builtinRealmAdminGroup));
m_base->realmMachineAdminGroup->setText(LDAPManager::cnFromDn(builtins.builtinMachineAdminGroup));
m_base->realmStandardUserGroup->setText(LDAPManager::cnFromDn(builtins.builtinStandardUserGroup));
updateCertDisplay();
m_certRefreshTimer.start(60*1000);
}
else {
m_base->groupRealmController->hide();
m_base->groupRealmCertificates->hide();
m_certRefreshTimer.stop();
}
processLockouts();
}
#define CERT_STATUS_COLOR_ACTIVE TQColor(0, 128, 0)
#define CERT_STATUS_COLOR_STALE TQColor(128, 64, 0)
#define CERT_STATUS_COLOR_EXPIRED TQColor(128, 0, 0)
#define CERT_STATUS_COLOR_NOTFOUND CERT_STATUS_COLOR_EXPIRED
void LDAPController::updateCertDisplay() {
TQDateTime certExpiry;
TQDateTime now = TQDateTime::currentDateTime();
TQDateTime soon = now.addDays(7); // Keep in sync with cert-updater/main.cpp
TQString kdc_certfile = KERBEROS_PKI_KDC_FILE;
kdc_certfile.replace("@@@KDCSERVER@@@", m_realmconfig[m_defaultRealm].kdc);
TQString ldap_certfile = LDAP_CERT_FILE;
ldap_certfile.replace("@@@ADMINSERVER@@@", m_realmconfig[m_defaultRealm].admin_server);
// Certificate Authority
if (TQFile::exists(KERBEROS_PKI_PEM_FILE)) {
certExpiry = LDAPManager::getCertificateExpiration(KERBEROS_PKI_PEM_FILE);
if (certExpiry >= now) {
m_base->caExpiryString->setText("Expires " + certExpiry.toString());
if (certExpiry >= soon) {
m_base->caExpiryString->setPaletteForegroundColor(CERT_STATUS_COLOR_ACTIVE);
}
else {
m_base->caExpiryString->setPaletteForegroundColor(CERT_STATUS_COLOR_STALE);
}
}
else {
m_base->caExpiryString->setText("Expired " + certExpiry.toString());
m_base->caExpiryString->setPaletteForegroundColor(CERT_STATUS_COLOR_EXPIRED);
}
}
else {
m_base->caExpiryString->setText("File not found");
m_base->caExpiryString->setPaletteForegroundColor(CERT_STATUS_COLOR_NOTFOUND);
}
// Kerberos
if (TQFile::exists(kdc_certfile)) {
certExpiry = LDAPManager::getCertificateExpiration(kdc_certfile);
if (certExpiry >= now) {
m_base->krbExpiryString->setText("Expires " + certExpiry.toString());
if (certExpiry >= soon) {
m_base->krbExpiryString->setPaletteForegroundColor(CERT_STATUS_COLOR_ACTIVE);
}
else {
m_base->krbExpiryString->setPaletteForegroundColor(CERT_STATUS_COLOR_STALE);
}
}
else {
m_base->krbExpiryString->setText("Expired " + certExpiry.toString());
m_base->krbExpiryString->setPaletteForegroundColor(CERT_STATUS_COLOR_EXPIRED);
}
}
else {
m_base->krbExpiryString->setText("File not found");
m_base->krbExpiryString->setPaletteForegroundColor(CERT_STATUS_COLOR_NOTFOUND);
}
// LDAP
if (TQFile::exists(ldap_certfile)) {
certExpiry = LDAPManager::getCertificateExpiration(ldap_certfile);
if (certExpiry >= now) {
m_base->ldapExpiryString->setText("Expires " + certExpiry.toString());
if (certExpiry >= soon) {
m_base->ldapExpiryString->setPaletteForegroundColor(CERT_STATUS_COLOR_ACTIVE);
}
else {
m_base->ldapExpiryString->setPaletteForegroundColor(CERT_STATUS_COLOR_STALE);
}
}
else {
m_base->ldapExpiryString->setText("Expired " + certExpiry.toString());
m_base->ldapExpiryString->setPaletteForegroundColor(CERT_STATUS_COLOR_EXPIRED);
}
}
else {
m_base->ldapExpiryString->setText("File not found");
m_base->ldapExpiryString->setPaletteForegroundColor(CERT_STATUS_COLOR_NOTFOUND);
}
}
void LDAPController::btncaRegenerate() {
LDAPManager::generatePublicKerberosCACertificate(m_certconfig);
TQString realmname = m_defaultRealm.upper();
LDAPCredentials* credentials = new LDAPCredentials;
credentials->username = "";
credentials->password = "";
credentials->realm = realmname;
LDAPManager* ldap_mgr = new LDAPManager(realmname, "ldapi://", credentials);
// Upload the contents of KERBEROS_PKI_PEM_FILE to the LDAP server
TQString errorstring;
if (uploadKerberosCAFileToLDAP(ldap_mgr, &errorstring) != 0) {
KMessageBox::error(0, i18n("<qt>Unable to upload new certificate to LDAP server!<p>%1</qt>").arg(errorstring), i18n("Internal Failure"));
}
delete ldap_mgr;
load();
}
void LDAPController::btncaExportKey() {
KURL src = KERBEROS_PKI_PEMKEY_FILE;
KURL dest = KFileDialog::getSaveURL(TQString::null, "*.key|Private Key (*.key)", this, i18n("Select a location to save a copy of the private key..."));
if (!dest.isEmpty()) {
KIO::CopyJob* job = KIO::copy(src, dest, true);
connect(job, TQT_SIGNAL(result(KIO::Job*)), this, TQT_SLOT(slotCertCopyResult(KIO::Job*)));
}
}
void LDAPController::btncaExportCert() {
KURL src = KERBEROS_PKI_PEM_FILE;
KURL dest = KFileDialog::getSaveURL(TQString::null, "*.pem|PKI Certificate Files (*.pem)", this, i18n("Select a location to save a copy of the certificate..."));
if (!dest.isEmpty()) {
KIO::CopyJob* job = KIO::copy(src, dest, true);
connect(job, TQT_SIGNAL(result(KIO::Job*)), this, TQT_SLOT(slotCertCopyResult(KIO::Job*)));
}
}
void LDAPController::btnkrbRegenerate() {
LDAPManager::generatePublicKerberosCertificate(m_certconfig, m_realmconfig[m_defaultRealm]);
load();
}
void LDAPController::btnkrbExportKey() {
TQString kdc_keyfile = KERBEROS_PKI_KDCKEY_FILE;
kdc_keyfile.replace("@@@KDCSERVER@@@", m_realmconfig[m_defaultRealm].kdc);
KURL src = kdc_keyfile;
KURL dest = KFileDialog::getSaveURL(TQString::null, "*.key|Private Key (*.key)", this, i18n("Select a location to save a copy of the private key..."));
if (!dest.isEmpty()) {
KIO::CopyJob* job = KIO::copy(src, dest, true);
connect(job, TQT_SIGNAL(result(KIO::Job*)), this, TQT_SLOT(slotCertCopyResult(KIO::Job*)));
}
}
void LDAPController::btnkrbExportCert() {
TQString kdc_certfile = KERBEROS_PKI_KDC_FILE;
kdc_certfile.replace("@@@KDCSERVER@@@", m_realmconfig[m_defaultRealm].kdc);
KURL src = kdc_certfile;
KURL dest = KFileDialog::getSaveURL(TQString::null, "*.pem|PKI Certificate Files (*.pem)", this, i18n("Select a location to save a copy of the certificate..."));
if (!dest.isEmpty()) {
KIO::CopyJob* job = KIO::copy(src, dest, true);
connect(job, TQT_SIGNAL(result(KIO::Job*)), this, TQT_SLOT(slotCertCopyResult(KIO::Job*)));
}
}
void LDAPController::btnldapRegenerate() {
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;
LDAPManager::generatePublicLDAPCertificate(m_certconfig, m_realmconfig[m_defaultRealm], slapd_uid, slapd_gid);
load();
}
void LDAPController::btnldapExportKey() {
TQString ldap_keyfile = LDAP_CERTKEY_FILE;
ldap_keyfile.replace("@@@ADMINSERVER@@@", m_realmconfig[m_defaultRealm].admin_server);
KURL src = ldap_keyfile;
KURL dest = KFileDialog::getSaveURL(TQString::null, "*.key|Private Key (*.key)", this, i18n("Select a location to save a copy of the private key..."));
if (!dest.isEmpty()) {
KIO::CopyJob* job = KIO::copy(src, dest, true);
connect(job, TQT_SIGNAL(result(KIO::Job*)), this, TQT_SLOT(slotCertCopyResult(KIO::Job*)));
}
}
void LDAPController::btnldapExportCert() {
TQString ldap_certfile = LDAP_CERT_FILE;
ldap_certfile.replace("@@@ADMINSERVER@@@", m_realmconfig[m_defaultRealm].admin_server);
KURL src = ldap_certfile;
KURL dest = KFileDialog::getSaveURL(TQString::null, "*.pem|PKI Certificate Files (*.pem)", this, i18n("Select a location to save a copy of the certificate..."));
if (!dest.isEmpty()) {
KIO::CopyJob* job = KIO::copy(src, dest, true);
connect(job, TQT_SIGNAL(result(KIO::Job*)), this, TQT_SLOT(slotCertCopyResult(KIO::Job*)));
}
}
void LDAPController::slotCertCopyResult(KIO::Job* job) {
if (job->error()) {
job->showErrorDialog(this);
}
}
void LDAPController::btnChangeLDAPRootPassword() {
// NOTE
// There is (currently) no good way to replace the root password
// This convoluted procedure is (currently) the best I can do...
bool ret = false;
TQCString rootPassword;
int result = KPasswordDialog::getNewPassword(rootPassword, i18n("Please enter the new LDAP root password:"));
if (result == KPasswordDialog::Accepted) {
SHA1 sha;
sha.process(rootPassword, strlen(rootPassword));
TQString rootpw_hash = sha.base64Hash();
TQString oldconfigfilename = "/etc/ldap/slapd.d/cn=config/" + TQString("olcDatabase={%1}hdb.ldif.bkp").arg(1);
TQString newconfigfilename = "/etc/ldap/slapd.d/cn=config/" + TQString("olcDatabase={%1}hdb.ldif").arg(1);
if (controlLDAPServer(SC_STOP) == 0) {
rename(newconfigfilename.ascii(), oldconfigfilename.ascii());
TQFile ifile(oldconfigfilename);
TQFile ofile(newconfigfilename);
if (ifile.open(IO_ReadOnly)) {
if (ofile.open(IO_WriteOnly)) {
TQString line;
TQTextStream istream(&ifile);
TQTextStream ostream(&ofile);
while (!istream.atEnd()) {
line = istream.readLine();
if (line.startsWith("olcRootPW:")) {
ostream << "olcRootPW: {SHA}" << rootpw_hash << "\n";
}
else {
ostream << line << "\n";
}
}
ifile.close();
unlink(oldconfigfilename);
ofile.close();
if (controlLDAPServer(SC_START) == 0) {
ret = true;
}
}
else {
ifile.close();
rename(oldconfigfilename.ascii(), newconfigfilename.ascii());
}
}
else {
rename(oldconfigfilename.ascii(), newconfigfilename.ascii());
}
}
if (!ret) {
KMessageBox::error(0, i18n("<qt>Unable to modify LDAP root password<p>Your LDAP server may now be in an inconsistent or disabled state</qt>"), i18n("Internal Failure"));
}
}
}
void LDAPController::btnChangeRealmAdminPassword() {
TQCString adminPassword;
int result = KPasswordDialog::getNewPassword(adminPassword, i18n("Please enter the new realm administrator password:"));
if (result == KPasswordDialog::Accepted) {
TQString realmname = m_defaultRealm.upper();
LDAPCredentials* credentials = new LDAPCredentials;
credentials->username = "";
credentials->password = "";
credentials->realm = realmname;
LDAPManager* ldap_mgr = new LDAPManager(realmname, "ldapi://", credentials);
TQString errorstring;
LDAPTDEBuiltinsInfo builtins = ldap_mgr->getTDEBuiltinMappings(&errorstring);
LDAPUserInfo adminuserinfo = ldap_mgr->getUserByDistinguishedName(builtins.builtinRealmAdminAccount);
if (adminuserinfo.informationValid) {
adminuserinfo.new_password = adminPassword;
ldap_mgr->setPasswordForUser(adminuserinfo, &errorstring);
}
delete ldap_mgr;
delete credentials;
}
}
void LDAPController::defaults() {
//
}
void LDAPController::save() {
m_systemconfig->setGroup(NULL);
m_systemconfig->writeEntry("EnableLDAP", m_base->systemEnableSupport->isChecked());
m_systemconfig->writeEntry("HostFQDN", m_fqdn);
m_systemconfig->writeEntry("LDAPRole", m_base->systemRole->currentText());
// Write cert config
m_systemconfig->setGroup("Certificates");
m_systemconfig->writeEntry("countryName", m_certconfig.countryName);
m_systemconfig->writeEntry("stateOrProvinceName", m_certconfig.stateOrProvinceName);
m_systemconfig->writeEntry("localityName", m_certconfig.localityName);
m_systemconfig->writeEntry("organizationName", m_certconfig.organizationName);
m_systemconfig->writeEntry("orgUnitName", m_certconfig.orgUnitName);
m_systemconfig->writeEntry("commonName", m_certconfig.commonName);
m_systemconfig->writeEntry("emailAddress", m_certconfig.emailAddress);
m_systemconfig->setGroup(NULL);
m_systemconfig->sync();
load();
}
void replacePlaceholdersInFile(TQString infile, TQString outfile, LDAPRealmConfig realmconfig, TQString adminUserName, TQString adminGroupName, TQString machineAdminGroupName, TQString standardUserGroupName, 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();
// 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", "");
TQString kdc_certfile = KERBEROS_PKI_KDC_FILE;
TQString kdc_keyfile = KERBEROS_PKI_KDCKEY_FILE;
TQString ldap_certfile = LDAP_CERT_FILE;
TQString ldap_keyfile = LDAP_CERTKEY_FILE;
kdc_certfile.replace("@@@KDCSERVER@@@", realmconfig.kdc);
kdc_keyfile.replace("@@@KDCSERVER@@@", realmconfig.kdc);
ldap_certfile.replace("@@@ADMINSERVER@@@", realmconfig.admin_server);
ldap_keyfile.replace("@@@ADMINSERVER@@@", realmconfig.admin_server);
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("@@@STANDARDUSERGROUP@@@", standardUserGroupName);
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);
line.replace("@@@TDELIBDIR@@@", TDE_LIBDIR);
line.replace("@@@HEIMDALACLFILE@@@", HEIMDAL_ACL_FILE);
line.replace("@@@KRBPKIPEMFILE@@@", KERBEROS_PKI_PEM_FILE);
line.replace("@@@KRBPKIPEMKEYFILE@@@", KERBEROS_PKI_PEMKEY_FILE);
line.replace("@@@KRBKDCPEMFILE@@@", kdc_certfile);
line.replace("@@@KRBKDCPEMKEYFILE@@@", kdc_keyfile);
line.replace("@@@LDAPPEMFILE@@@", ldap_certfile);
line.replace("@@@LDAPPEMKEYFILE@@@", ldap_keyfile);
if (ldifSchemaNumber >= 0) {
line.replace("@@@LDIFSCHEMANUMBER@@@", TQString("%1").arg(ldifSchemaNumber));
}
ostream << line << "\n";
}
ofile.close();
// Set permissions
if ((userid > 0) && (groupid > 0)) {
chown_safe(outfile.ascii(), userid, groupid);
}
}
else {
//KMessageBox::error(0, i18n("<qt>Unable to open output schema file %1 for writing</qt>").arg(outfile), i18n("Internal Failure"));
printf("[INTERNAL FAILURE] Unable to open output schema file %s for writing\n\r", outfile.ascii()); fflush(stdout);
}
ifile.close();
}
else {
//KMessageBox::error(0, i18n("<qt>Unable to open template schema file %1</qt>").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();
}
13 years ago
int LDAPController::controlKAdminDaemon(sc_command command) {
if (command == SC_RESTART) {
// FIXME
// This assumes Debian!
return system("/etc/init.d/openbsd-inetd restart");
}
return -2;
13 years ago
}
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");
}
return -2;
}
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_safe("rm -f " + TQString(LDAP_KEYTAB_FILE));
// FIXME
// This assumes Debian
system_safe("rm -f /etc/krb5.keytab");
system_safe("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_safe(command.ascii());
chmod(LDAP_KEYTAB_FILE, S_IRUSR|S_IWUSR|S_IRGRP);
}
}
return -2;
}
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_safe("rm -rf /var/lib/ldap/*");
system_safe("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_safe(command.ascii());
command = TQString("chgrp -R %1 /var/lib/ldap/*").arg(groupid);
system_safe(command.ascii());
command = TQString("chown -R %1 /etc/ldap/slapd.d/*").arg(userid);
system_safe(command.ascii());
command = TQString("chgrp -R %1 /etc/ldap/slapd.d/*").arg(groupid);
system_safe(command.ascii());
}
}
return -2;
}
int LDAPController::initializeNewKerberosRealm(TQString realmName, TQString *errstr) {
TQCString command = "kadmin";
QCStringList args;
args << TQCString("-l");
TQString prompt;
PtyProcess kadminProc;
kadminProc.enableLocalEcho(false);
kadminProc.exec(command, args);
prompt = LDAPManager::readFullLineFromPtyProcess(&kadminProc);
prompt = prompt.stripWhiteSpace();
if (prompt == "kadmin>") {
command = TQCString("init "+realmName);
kadminProc.enableLocalEcho(false);
kadminProc.writeLine(command, true);
do { // Discard our own input
prompt = LDAPManager::readFullLineFromPtyProcess(&kadminProc);
printf("(kadmin) '%s'\n\r", prompt.ascii());
} while (prompt == TQString(command));
prompt = prompt.stripWhiteSpace();
if (prompt.contains("authentication failed")) {
if (errstr) *errstr = LDAPManager::detailedKAdminErrorMessage(prompt);
kadminProc.enableLocalEcho(false);
kadminProc.writeLine("quit", true);
return 1;
}
else if (prompt.startsWith("Realm max")) {
command = "unlimited";
kadminProc.enableLocalEcho(false);
kadminProc.writeLine(command, true);
do { // Discard our own input
prompt = LDAPManager::readFullLineFromPtyProcess(&kadminProc);
printf("(kadmin) '%s'\n\r", prompt.ascii());
} while (prompt == TQString(command));
prompt = prompt.stripWhiteSpace();
if (prompt.startsWith("Realm max")) {
command = "unlimited";
kadminProc.enableLocalEcho(false);
kadminProc.writeLine(command, true);
do { // Discard our own input
prompt = LDAPManager::readFullLineFromPtyProcess(&kadminProc);
printf("(kadmin) '%s'\n\r", prompt.ascii());
} while (prompt == TQString(command));
prompt = prompt.stripWhiteSpace();
}
if (prompt != "kadmin>") {
if (errstr) *errstr = LDAPManager::detailedKAdminErrorMessage(prompt);
kadminProc.enableLocalEcho(false);
kadminProc.writeLine("quit", true);
return 1;
}
// Success!
kadminProc.enableLocalEcho(false);
kadminProc.writeLine("quit", true);
return 0;
}
// Failure
if (errstr) *errstr = LDAPManager::detailedKAdminErrorMessage(prompt);
kadminProc.enableLocalEcho(false);
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 = LDAPManager::readFullLineFromPtyProcess(&kadminProc);
prompt = prompt.stripWhiteSpace();
if (prompt == "kadmin>") {
command = TQCString("ext "+hoststring);
kadminProc.enableLocalEcho(false);
kadminProc.writeLine(command, true);
do { // Discard our own input
prompt = LDAPManager::readFullLineFromPtyProcess(&kadminProc);
printf("(kadmin) '%s'\n\r", prompt.ascii());
} while (prompt == TQString(command));
prompt = prompt.stripWhiteSpace();
if (prompt.contains("authentication failed")) {
if (errstr) *errstr = LDAPManager::detailedKAdminErrorMessage(prompt);
kadminProc.enableLocalEcho(false);
kadminProc.writeLine("quit", true);
return 1;
}
else if (prompt.endsWith("Principal does not exist")) {
prompt = LDAPManager::readFullLineFromPtyProcess(&kadminProc);
prompt = prompt.stripWhiteSpace();
if (prompt != "kadmin>") {
if (errstr) *errstr = LDAPManager::detailedKAdminErrorMessage(prompt);
kadminProc.enableLocalEcho(false);
kadminProc.writeLine("quit", true);
return 1;
}
command = TQCString("ank --random-key "+hoststring);
kadminProc.enableLocalEcho(false);
kadminProc.writeLine(command, true);
do { // Discard our own input
prompt = LDAPManager::readFullLineFromPtyProcess(&kadminProc);
printf("(kadmin) '%s'\n\r", prompt.ascii());
} while (prompt == TQString(command));
prompt = prompt.stripWhiteSpace();
// Use all defaults
while (prompt != "kadmin>") {
if (prompt.contains("authentication failed")) {
if (errstr) *errstr = LDAPManager::detailedKAdminErrorMessage(prompt);
kadminProc.enableLocalEcho(false);
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);
}
command = TQCString(defaultParam);
kadminProc.enableLocalEcho(false);
kadminProc.writeLine(command, true);
do { // Discard our own input
prompt = LDAPManager::readFullLineFromPtyProcess(&kadminProc);
printf("(kadmin) '%s'\n\r", prompt.ascii());
} while (prompt == TQString(command));
prompt = prompt.stripWhiteSpace();
}
}
command = TQCString("ext "+hoststring);
kadminProc.enableLocalEcho(false);
kadminProc.writeLine(command, true);
do { // Discard our own input
prompt = LDAPManager::readFullLineFromPtyProcess(&kadminProc);
printf("(kadmin) '%s'\n\r", prompt.ascii());
} while (prompt == TQString(command));
prompt = prompt.stripWhiteSpace();
if (prompt != "kadmin>") {
if (errstr) *errstr = LDAPManager::detailedKAdminErrorMessage(prompt);
kadminProc.enableLocalEcho(false);
kadminProc.writeLine("quit", true);
return 1;
}
// Success!
kadminProc.enableLocalEcho(false);
kadminProc.writeLine("quit", true);
return 0;
}
else if (prompt == "kadmin>") {
// Success!
kadminProc.enableLocalEcho(false);
kadminProc.writeLine("quit", true);
return 0;
}
// Failure
if (errstr) *errstr = LDAPManager::detailedKAdminErrorMessage(prompt);
kadminProc.enableLocalEcho(false);
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 = LDAPManager::readFullLineFromPtyProcess(&kadminProc);
prompt = prompt.stripWhiteSpace();
if (prompt == "kadmin>") {
command = TQCString("ext --keytab="+TQString(LDAP_KEYTAB_FILE)+" "+hoststring);
kadminProc.enableLocalEcho(false);
kadminProc.writeLine(command, true);
do { // Discard our own input
prompt = LDAPManager::readFullLineFromPtyProcess(&kadminProc);
printf("(kadmin) '%s'\n\r", prompt.ascii());
} while (prompt.startsWith("ext --keytab="));
prompt = prompt.stripWhiteSpace();
if (prompt.contains("authentication failed")) {
if (errstr) *errstr = LDAPManager::detailedKAdminErrorMessage(prompt);
kadminProc.enableLocalEcho(false);
kadminProc.writeLine("quit", true);
return 1;
}
else if (prompt.endsWith("Principal does not exist")) {
prompt = LDAPManager::readFullLineFromPtyProcess(&kadminProc);
prompt = prompt.stripWhiteSpace();
if (prompt != "kadmin>") {
if (errstr) *errstr = LDAPManager::detailedKAdminErrorMessage(prompt);
kadminProc.enableLocalEcho(false);
kadminProc.writeLine("quit", true);
return 1;
}
command = TQCString("ank --random-key "+hoststring);
kadminProc.enableLocalEcho(false);
kadminProc.writeLine(command, true);
do { // Discard our own input
prompt = LDAPManager::readFullLineFromPtyProcess(&kadminProc);
printf("(kadmin) '%s'\n\r", prompt.ascii());
} while (prompt == TQString(command));
prompt = prompt.stripWhiteSpace();
// Use all defaults
while (prompt != "kadmin>") {
if (prompt.contains("authentication failed")) {
if (errstr) *errstr = LDAPManager::detailedKAdminErrorMessage(prompt);
kadminProc.enableLocalEcho(false);
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);
}
command = TQCString(defaultParam);
kadminProc.enableLocalEcho(false);
kadminProc.writeLine(command, true);
do { // Discard our own input
prompt = LDAPManager::readFullLineFromPtyProcess(&kadminProc);
printf("(kadmin) '%s'\n\r", prompt.ascii());
} while (prompt == TQString(command));
prompt = prompt.stripWhiteSpace();
}
}
command = TQCString("ext --keytab="+TQString(LDAP_KEYTAB_FILE)+" "+hoststring);
kadminProc.enableLocalEcho(false);
kadminProc.writeLine(command, true);
do { // Discard our own input
prompt = LDAPManager::readFullLineFromPtyProcess(&kadminProc);
printf("(kadmin) '%s'\n\r", prompt.ascii());
} while (prompt.startsWith("ext --keytab="));
prompt = prompt.stripWhiteSpace();
if (prompt != "kadmin>") {
if (errstr) *errstr = LDAPManager::detailedKAdminErrorMessage(prompt);
kadminProc.enableLocalEcho(false);
kadminProc.writeLine("quit", true);
return 1;
}
// Success!
kadminProc.enableLocalEcho(false);
kadminProc.writeLine("quit", true);
return 0;
}
else if (prompt == "kadmin>") {
// Success!
kadminProc.enableLocalEcho(false);
kadminProc.writeLine("quit", true);
return 0;
}
// Failure
if (errstr) *errstr = LDAPManager::detailedKAdminErrorMessage(prompt);
kadminProc.enableLocalEcho(false);
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 = LDAPManager::readFullLineFromPtyProcess(&kadminProc);
prompt = prompt.stripWhiteSpace();
if (prompt == "kadmin>") {
command = TQCString("passwd "+user.username);
kadminProc.enableLocalEcho(false);
kadminProc.writeLine(command, true);
do { // Discard our own input
prompt = LDAPManager::readFullLineFromPtyProcess(&kadminProc);
printf("(kadmin) '%s'\n\r", prompt.ascii());
} while (prompt == TQString(command));
prompt = prompt.stripWhiteSpace();
if (prompt.contains("authentication failed")) {
if (errstr) *errstr = LDAPManager::detailedKAdminErrorMessage(prompt);
kadminProc.enableLocalEcho(false);
kadminProc.writeLine("quit", true);
return 1;
}
else if ((prompt.endsWith(" Password:")) && (prompt.startsWith(TQString(user.username + "@")))) {
kadminProc.enableLocalEcho(false);
kadminProc.writeLine(user.password, true);
do { // Discard our own input
prompt = LDAPManager::readFullLineFromPtyProcess(&kadminProc);
printf("(kadmin) '%s'\n\r", prompt.ascii());
} while (prompt == "");
prompt = prompt.stripWhiteSpace();
if ((prompt.endsWith(" Password:")) && (prompt.startsWith("Verify"))) {
kadminProc.enableLocalEcho(false);
kadminProc.writeLine(user.password, true);
do { // Discard our own input
prompt = LDAPManager::readFullLineFromPtyProcess(&kadminProc);
printf("(kadmin) '%s'\n\r", prompt.ascii());
} while (prompt == "");
prompt = prompt.stripWhiteSpace();
}
if (prompt != "kadmin>") {
if (errstr) *errstr = LDAPManager::detailedKAdminErrorMessage(prompt);
kadminProc.enableLocalEcho(false);
kadminProc.writeLine("quit", true);
return 1;
}
// Success!
kadminProc.enableLocalEcho(false);
kadminProc.writeLine("quit", true);
return 0;
}
else if (prompt == "kadmin>") {
// Success!
kadminProc.enableLocalEcho(false);
kadminProc.writeLine("quit", true);
return 0;
}
// Failure
if (errstr) *errstr = LDAPManager::detailedKAdminErrorMessage(prompt);
kadminProc.enableLocalEcho(false);
kadminProc.writeLine("quit", true);
return 1;
}
if (errstr) *errstr = "Internal error. Verify that kadmin exists and can be executed.";
return 1; // Failure
}
int LDAPController::createRealmCertificates(LDAPCertConfig certinfo, LDAPRealmConfig realmconfig, uid_t ldap_uid, gid_t ldap_gid) {
// Certificate authority certificate
TQString command;
command = TQString("openssl genrsa -out %1 %2").arg(KERBEROS_PKI_PEMKEY_FILE).arg(KEY_STRENGTH);
system_safe(command);
chmod(KERBEROS_PKI_PEMKEY_FILE, S_IRUSR|S_IWUSR);
chown_safe(KERBEROS_PKI_PEMKEY_FILE, 0, 0);
LDAPManager::generatePublicKerberosCACertificate(certinfo);
// KDC certificate
TQString kdc_certfile = KERBEROS_PKI_KDC_FILE;
TQString kdc_keyfile = KERBEROS_PKI_KDCKEY_FILE;
TQString kdc_reqfile = KERBEROS_PKI_KDCREQ_FILE;
kdc_certfile.replace("@@@KDCSERVER@@@", realmconfig.kdc);
kdc_keyfile.replace("@@@KDCSERVER@@@", realmconfig.kdc);
kdc_reqfile.replace("@@@KDCSERVER@@@", realmconfig.kdc);
command = TQString("openssl genrsa -out %1 %2").arg(kdc_keyfile).arg(KEY_STRENGTH);
system_safe(command);
chmod(kdc_keyfile.ascii(), S_IRUSR|S_IWUSR);
chown_safe(kdc_keyfile.ascii(), 0, 0);
LDAPManager::generatePublicKerberosCertificate(certinfo, realmconfig);
// LDAP certificate
TQString ldap_certfile = LDAP_CERT_FILE;
TQString ldap_keyfile = LDAP_CERTKEY_FILE;
TQString ldap_reqfile = LDAP_CERTREQ_FILE;
ldap_certfile.replace("@@@ADMINSERVER@@@", realmconfig.admin_server);
ldap_keyfile.replace("@@@ADMINSERVER@@@", realmconfig.admin_server);
ldap_reqfile.replace("@@@ADMINSERVER@@@", realmconfig.admin_server);
command = TQString("openssl genrsa -out %1 %2").arg(ldap_keyfile).arg(KEY_STRENGTH);
system_safe(command);
chmod(ldap_keyfile.ascii(), S_IRUSR|S_IWUSR);
chown_safe(ldap_keyfile.ascii(), ldap_uid, ldap_gid);
LDAPManager::generatePublicLDAPCertificate(certinfo, realmconfig, ldap_uid, ldap_gid);
return 0;
}
int LDAPController::uploadKerberosCAFileToLDAP(LDAPManager* ldap_mgr, TQString* errstr) {
// Upload the contents of KERBEROS_PKI_PEM_FILE to the LDAP server
TQFile cafile(KERBEROS_PKI_PEM_FILE);
if (cafile.open(IO_ReadOnly)) {
TQByteArray cafiledata = cafile.readAll();
if (ldap_mgr->writeCertificateFileIntoDirectory(cafiledata, "publicRootCertificate", errstr) != 0) {
return -1;
}
return 0;
}
return -1;
}
int LDAPController::uploadKerberosCAKeyFileToLDAP(LDAPManager* ldap_mgr, TQString* errstr) {
// Upload the contents of KERBEROS_PKI_PEMKEY_FILE to the LDAP server
TQFile cafile(KERBEROS_PKI_PEMKEY_FILE);
if (cafile.open(IO_ReadOnly)) {
TQByteArray cafiledata = cafile.readAll();
if (ldap_mgr->writeCertificateFileIntoDirectory(cafiledata, "privateRootCertificateKey", errstr) != 0) {
return -1;
}
return 0;
}
return -1;
}
// #define STRICT_SETUP 1
int LDAPController::createNewSecondaryController(TQWidget* dialogparent, LDAPRealmConfig realmconfig, TQString adminUserName, const char * adminPassword, TQString adminRealm, TQString *errstr) {
// Fortunately this is somewhat simpler than createNewLDAPRealm(...)!
ProcessingDialog pdialog(dialogparent);
pdialog.setStatusMessage(i18n("Loading data for secondary controller..."));
pdialog.raise();
pdialog.setActiveWindow();
tqApp->processEvents();
// TODO FIXME
// Threading would be a good idea here, to keep the GUI responsive while the backend code works
// 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);
TQString destDir = "/etc/";
pdialog.setStatusMessage(i18n("Stopping servers..."));
// Stop SASL
if (controlSASLServer(SC_STOP) != 0) {
#ifdef STRICT_SETUP
if (errstr) *errstr = i18n("Unable to stop SASL server");
pdialog.closeDialog();
return -1;
#endif // STRICT_SETUP
}
// Stop Heimdal
if (controlHeimdalServer(SC_STOP) != 0) {
#ifdef STRICT_SETUP
if (errstr) *errstr = i18n("Unable to stop Kerberos server");
pdialog.closeDialog();
return -1;
#endif // STRICT_SETUP
}
// Stop slapd
if (controlLDAPServer(SC_STOP) != 0) {
#ifdef STRICT_SETUP
if (errstr) *errstr = i18n("Unable to stop LDAP server");
pdialog.closeDialog();
return -1;
#endif // STRICT_SETUP
}
// TODO FIXME
// 1.) Fetch CA private/public certificates from master LDAP server, save them, and also use the public certificate to fill a certificate information structure
// 2.) Bond machine to Kerberos
// 3.) Set up LDAP replication
// 4.) Point local Kerberos and SASL instances to this LDAP server
return -1;
}
int LDAPController::createNewLDAPRealm(TQWidget* dialogparent, LDAPRealmConfig realmconfig, TQString adminUserName, TQString adminGroupName, TQString machineAdminGroupName, TQString standardUserGroupName, const char * adminPassword, TQString rootUserName, const char * rootPassword, TQString adminRealm, LDAPCertConfig certinfo, TQString *errstr) {
Q_UNUSED(adminRealm)
int ldifSchemaNumber;
ProcessingDialog pdialog(dialogparent);
pdialog.setStatusMessage(i18n("Loading data for realm deployment..."));
pdialog.raise();
pdialog.setActiveWindow();
tqApp->processEvents();
// TODO FIXME
// Threading would be a good idea here, to keep the GUI responsive while the backend code works
// 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);
TQString destDir = "/etc/";
pdialog.setStatusMessage(i18n("Stopping servers..."));
// Stop SASL
if (controlSASLServer(SC_STOP) != 0) {
#ifdef STRICT_SETUP
if (errstr) *errstr = i18n("Unable to stop SASL server");
pdialog.closeDialog();
return -1;
#endif // STRICT_SETUP
}
// Stop Heimdal
if (controlHeimdalServer(SC_STOP) != 0) {
#ifdef STRICT_SETUP
if (errstr) *errstr = i18n("Unable to stop Kerberos server");
pdialog.closeDialog();
return -1;
#endif // STRICT_SETUP
}
// Stop slapd
if (controlLDAPServer(SC_STOP) != 0) {
#ifdef STRICT_SETUP
if (errstr) *errstr = i18n("Unable to stop LDAP server");
pdialog.closeDialog();
return -1;
#endif // STRICT_SETUP
}
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);
mkdir(TDE_CERTIFICATE_DIR, S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH);
mkdir(KERBEROS_PKI_ANCHORDIR, S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH);
mkdir(KERBEROS_PKI_PRIVATEDIR, S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH);
mkdir(KERBEROS_PKI_PUBLICDIR, S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH);
// Heimdal
replacePlaceholdersInFile(templateDir + "heimdal/heimdal.defaults", HEIMDAL_DEFAULT_FILE, realmconfig, adminUserName, adminGroupName, machineAdminGroupName, standardUserGroupName, adminPassword, rootUserName, rootPassword);
replacePlaceholdersInFile(templateDir + "heimdal/kadmind.acl", HEIMDAL_ACL_FILE, realmconfig, adminUserName, adminGroupName, machineAdminGroupName, standardUserGroupName, adminPassword, rootUserName, rootPassword);
replacePlaceholdersInFile(templateDir + "heimdal/kdc.conf", destDir + "heimdal-kdc/kdc.conf", realmconfig, adminUserName, adminGroupName, machineAdminGroupName, standardUserGroupName, adminPassword, rootUserName, rootPassword);
replacePlaceholdersInFile(templateDir + "heimdal/krb5.conf", destDir + "krb5.conf", realmconfig, adminUserName, adminGroupName, machineAdminGroupName, standardUserGroupName, adminPassword, rootUserName, rootPassword);
// OpenLDAP
replacePlaceholdersInFile(templateDir + "openldap/skel.ldif", configTempDir.name() + "skel.ldif", realmconfig, adminUserName, adminGroupName, machineAdminGroupName, standardUserGroupName, adminPassword, rootUserName, rootPassword);
// replacePlaceholdersInFile(templateDir + "openldap/ldap/slapd.conf", destDir + "ldap/slapd.conf", realmconfig, adminUserName, adminGroupName, machineAdminGroupName, standardUserGroupName, adminPassword, rootUserName, rootPassword);
replacePlaceholdersInFile(templateDir + "openldap/ldap/slapd.defaults", LDAP_DEFAULT_FILE, realmconfig, adminUserName, adminGroupName, machineAdminGroupName, standardUserGroupName, adminPassword, rootUserName, rootPassword, -1, -1, -1, m_ldapUserName, m_ldapGroupName);
// SASL
replacePlaceholdersInFile(templateDir + "sasl/saslauthd.defaults", SASL_DEFAULT_FILE, realmconfig, adminUserName, adminGroupName, machineAdminGroupName, standardUserGroupName, adminPassword, rootUserName, rootPassword);
replacePlaceholdersInFile(templateDir + "sasl/slapd.conf", SASL_CONTROL_FILE, realmconfig, adminUserName, adminGroupName, machineAdminGroupName, standardUserGroupName, adminPassword, rootUserName, rootPassword);
// OpenSSL
replacePlaceholdersInFile(templateDir + "openssl/pki_extensions", OPENSSL_EXTENSIONS_FILE, realmconfig, adminUserName, adminGroupName, machineAdminGroupName, standardUserGroupName, adminPassword, rootUserName, rootPassword);
// FIXME
// This assumes Debian!
// Grant LDAP access to SASL mux pipe
system_safe("dpkg-statoverride --remove --quiet /var/run/saslauthd");
system_safe(TQString("dpkg-statoverride --add root %1 710 /var/run/saslauthd").arg(m_ldapGroupName).ascii());
// FIXME
// This assumes Debian!
system_safe("ln -s /etc/heimdal-kdc/kadmind.acl /var/lib/heimdal-kdc/kadmind.acl");
system_safe("ln -s /etc/heimdal-kdc/kdc.conf /var/lib/heimdal-kdc/kdc.conf");
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;
13 years ago
// 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, standardUserGroupName, 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, standardUserGroupName, 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, standardUserGroupName, 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, standardUserGroupName, 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, standardUserGroupName, 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, standardUserGroupName, 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, standardUserGroupName, 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, standardUserGroupName, 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, standardUserGroupName, 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, standardUserGroupName, 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, standardUserGroupName, 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, standardUserGroupName, 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, standardUserGroupName, 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, standardUserGroupName, adminPassword, rootUserName, rootPassword, ldifSchemaNumber, slapd_uid, slapd_gid);
// ldifSchemaNumber = 9;
// replacePlaceholdersInFile(templateDir + "openldap/ldif/samba.ldif", destDir + "ldap/slapd.d/cn=config/cn=schema/" + TQString("cn={%1}samba.ldif").arg(ldifSchemaNumber), realmconfig, adminUserName, adminGroupName, machineAdminGroupName, standardUserGroupName, adminPassword, rootUserName, rootPassword, ldifSchemaNumber, slapd_uid, slapd_gid);
// Set permissions
chmod(TQString(HEIMDAL_DEFAULT_FILE).ascii(), S_IRUSR|S_IWUSR|S_IRGRP);
chmod(TQString(HEIMDAL_ACL_FILE).ascii(), S_IRUSR|S_IWUSR|S_IRGRP);
chown_safe(TQString(HEIMDAL_ACL_FILE).ascii(), slapd_uid, 0);
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(LDAP_DEFAULT_FILE).ascii(), S_IRUSR|S_IWUSR|S_IRGRP);
chmod(TQString(SASL_DEFAULT_FILE).ascii(), S_IRUSR|S_IWUSR|S_IRGRP);
chmod(TQString(SASL_CONTROL_FILE).ascii(), S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
chmod(TQString(OPENSSL_EXTENSIONS_FILE).ascii(), S_IRUSR|S_IWUSR);
pdialog.setStatusMessage(i18n("Installing realm certificates..."));
tqApp->processEvents();
if (certinfo.generate_certs) {
// Generate certificates
if (createRealmCertificates(certinfo, realmconfig, slapd_uid, slapd_gid) != 0) {
if (errstr) *errstr = i18n("Unable to install realm certificates");
pdialog.closeDialog();
return -1;
}
m_certconfig = certinfo;
}
else {
// Copy certificates
TQString kdc_certfile = KERBEROS_PKI_KDC_FILE;
TQString kdc_keyfile = KERBEROS_PKI_KDCKEY_FILE;
kdc_certfile.replace("@@@KDCSERVER@@@", realmconfig.kdc);
kdc_keyfile.replace("@@@KDCSERVER@@@", realmconfig.kdc);
TQString ldap_certfile = LDAP_CERT_FILE;
TQString ldap_keyfile = LDAP_CERTKEY_FILE;
ldap_certfile.replace("@@@ADMINSERVER@@@", realmconfig.admin_server);
ldap_keyfile.replace("@@@ADMINSERVER@@@", realmconfig.admin_server);
// Copy files
// FIXME
// There has GOT to be a better way to do this than system()!!!
TQString command;
command = TQString("cp %1 %2").arg(certinfo.provided_kerberos_pem).arg(KERBEROS_PKI_PEMKEY_FILE);
system_safe(command);
command = TQString("cp %1 %2").arg(certinfo.provided_kerberos_pemkey).arg(KERBEROS_PKI_PEM_FILE);
system_safe(command);
command = TQString("cp %1 %2").arg(certinfo.provided_kerberos_crt).arg(kdc_certfile);
system_safe(command);
command = TQString("cp %1 %2").arg(certinfo.provided_kerberos_key).arg(kdc_keyfile);
system_safe(command);
command = TQString("cp %1 %2").arg(certinfo.provided_ldap_crt).arg(ldap_certfile);
system_safe(command);
command = TQString("cp %1 %2").arg(certinfo.provided_ldap_key).arg(ldap_keyfile);
system_safe(command);
// Set permissions
chmod(KERBEROS_PKI_PEMKEY_FILE, S_IRUSR|S_IWUSR);
chown_safe(KERBEROS_PKI_PEMKEY_FILE, 0, 0);
chmod(KERBEROS_PKI_PEM_FILE, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
chown_safe(KERBEROS_PKI_PEM_FILE, 0, 0);
chmod(kdc_keyfile.ascii(), S_IRUSR|S_IWUSR);
chown_safe(kdc_keyfile.ascii(), 0, 0);
chmod(kdc_certfile.ascii(), S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
chown_safe(kdc_certfile.ascii(), 0, 0);
chmod(ldap_keyfile.ascii(), S_IRUSR|S_IWUSR);
chown_safe(ldap_keyfile.ascii(), slapd_uid, slapd_gid);
chmod(ldap_certfile.ascii(), S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
chown_safe(ldap_certfile.ascii(), slapd_uid, slapd_gid);
}
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<p>").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<p>").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<p>").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<p>").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 = "";
credentials->password = "";
credentials->realm = realmconfig.name.upper();
LDAPManager* ldap_mgr = new LDAPManager(realmconfig.name.upper(), "ldapi://", 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;
}
// Upload the contents of KERBEROS_PKI_PEM_FILE to the LDAP server
if (uploadKerberosCAFileToLDAP(ldap_mgr, &errorstring) != 0) {
delete ldap_mgr;
delete credentials;
if (errstr) *errstr = errorstring;
pdialog.closeDialog();
return -1;
}
// Upload the contents of KERBEROS_PKI_PEMKEY_FILE to the LDAP server
if (uploadKerberosCAKeyFileToLDAP(ldap_mgr, &errorstring) != 0) {
delete ldap_mgr;
delete credentials;
if (errstr) *errstr = errorstring;
pdialog.closeDialog();
return -1;
}
// Set @@@ADMINUSER@@@ password in kadmin
LDAPCredentials adminuser;
adminuser.username = adminUserName;
adminuser.password = adminPassword;
adminuser.realm = realmconfig.name.upper();
if (setKerberosPasswordForUser(adminuser, &errorstring) != 0) {
delete ldap_mgr;
delete credentials;
if (errstr) *errstr = i18n("Unable to set user password in Kerberos database<p>").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->setGroup(NULL);
m_systemconfig->writeEntry("DefaultRealm", realmconfig.name);
m_systemconfig->sync();
LDAPManager::writeLDAPConfFile(realmconfig);
// Write the sudoers file
if (ldap_mgr->writeSudoersConfFile(&errorstring) != 0) {
delete ldap_mgr;
delete credentials;
if (errstr) *errstr = i18n("Unable to set local sudo rights<p>").append(errorstring);
pdialog.closeDialog();
return -1;
}
LDAPManager::writePrimaryRealmCertificateUpdateCronFile();
delete ldap_mgr;
delete credentials;
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;
}
13 years ago
// 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;
}
// Write the NSS update crontab file and update NSS database
LDAPManager::writeCronFiles();
pdialog.closeDialog();
return 0;
}
int LDAPController::buttons() {
return KCModule::Apply|KCModule::Help;
}
TQString LDAPController::quickHelp() const
{
return i18n("This module configures an LDAP Realm Controller.");
}