diff --git a/admin b/admin index 307fab5..4027b87 160000 --- a/admin +++ b/admin @@ -1 +1 @@ -Subproject commit 307fab5fdad542247fa11a418be0e9635f4b5ebf +Subproject commit 4027b878fb556a51ed29affd578e78aa70997480 diff --git a/confskel/openldap/ldif/config.ldif b/confskel/openldap/ldif/config.ldif index 291975a..2c07bb9 100644 --- a/confskel/openldap/ldif/config.ldif +++ b/confskel/openldap/ldif/config.ldif @@ -27,6 +27,7 @@ olcReverseLookup: FALSE olcSaslHost: @@@ADMINSERVER@@@ olcSaslRealm: @@@REALM_UCNAME@@@ olcSaslSecProps: noplain,noanonymous +olcSizeLimit: 1000000 olcSockbufMaxIncoming: 262143 olcSockbufMaxIncomingAuth: 16777215 olcThreads: 16 diff --git a/confskel/openldap/ldif/olcConfig.ldif b/confskel/openldap/ldif/olcConfig.ldif index 86d5267..a705bae 100644 --- a/confskel/openldap/ldif/olcConfig.ldif +++ b/confskel/openldap/ldif/olcConfig.ldif @@ -1,7 +1,13 @@ dn: olcDatabase={0}config objectClass: olcDatabaseConfig olcDatabase: {0}config -olcAccess: {0}to * by * none +olcAccess: {0}to * + by group/groupOfNames/member.exact="cn=@@@ADMINGROUP@@@,ou=groups,ou=core,ou=realm,@@@REALM_DCNAME@@@" write + by dn.base="uid=@@@ADMINUSER@@@,ou=users,ou=core,ou=realm,@@@REALM_DCNAME@@@" write + by dn.base="cn=@@@ROOTUSER@@@,@@@REALM_DCNAME@@@" write + by sockurl.regex="^ldapi:///$" write + by dynacl/aci write + by * none olcAddContentAcl: TRUE olcLastMod: TRUE olcMaxDerefDepth: 15 diff --git a/src/Makefile.am b/src/Makefile.am index ea3d2ca..6265774 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -5,7 +5,7 @@ SUBDIRS = primaryrealmwizard secondaryrealmwizard # Install this plugin in the KDE modules directory kde_module_LTLIBRARIES = kcm_ldapcontroller.la -kcm_ldapcontroller_la_SOURCES = ldapcontroller.cpp ldapcontrollerconfigbase.ui processingdialog.cpp sha1.cc +kcm_ldapcontroller_la_SOURCES = ldapcontroller.cpp ldapcontrollerconfigbase.ui processingdialog.cpp sha1.cc multimasterreplicationconfigbase.ui multimasterreplicationconfigdlg.cpp kcm_ldapcontroller_la_LIBADD = primaryrealmwizard/libprimaryrealmwizard.la secondaryrealmwizard/libsecondaryrealmwizard.la $(LIB_KIO) $(LIB_TDEUI) -ltdeldap kcm_ldapcontroller_la_LDFLAGS = -avoid-version -module -no-undefined $(all_libraries) diff --git a/src/ldapcontroller.cpp b/src/ldapcontroller.cpp index 0424bcc..f849d8f 100644 --- a/src/ldapcontroller.cpp +++ b/src/ldapcontroller.cpp @@ -24,6 +24,7 @@ #include #include +#include #include #include @@ -54,6 +55,7 @@ #include "primaryrealmwizard/primaryrealmwizard.h" #include "secondaryrealmwizard/secondaryrealmwizard.h" #include "processingdialog.h" +#include "multimasterreplicationconfigdlg.h" #include "ldapcontrollerconfigbase.h" @@ -105,6 +107,9 @@ LDAPController::LDAPController(TQWidget *parent, const char *name, const TQStrin 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); + + m_base->multiMasterReplicationMappings->setAllColumnsShowFocus(true); + m_base->multiMasterReplicationMappings->setFullWidth(true); 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); @@ -130,6 +135,15 @@ LDAPController::LDAPController(TQWidget *parent, const char *name, const TQStrin connect(&m_certRefreshTimer, TQT_SIGNAL(timeout()), this, TQT_SLOT(updateCertDisplay())); + connect(m_base->advancedEnableMultiMasterReplication, TQT_SIGNAL(clicked()), this, TQT_SLOT(changed())); + + connect(m_base->btnAddMultiMasterReplicationMapping, TQT_SIGNAL(clicked()), this, TQT_SLOT(btnAddMultiMasterReplicationMapping())); + connect(m_base->btnEditMultiMasterReplicationMapping, TQT_SIGNAL(clicked()), this, TQT_SLOT(btnEditMultiMasterReplicationMapping())); + connect(m_base->btnRemoveMultiMasterReplicationMapping, TQT_SIGNAL(clicked()), this, TQT_SLOT(btnRemoveMultiMasterReplicationMapping())); + + connect(m_base->multiMasterReplicationMappings, TQT_SIGNAL(selectionChanged()), this, TQT_SLOT(multiMasterReplicationHighlighted())); + connect(m_base->multiMasterReplicationMappings, TQT_SIGNAL(executed(TQListViewItem*)), this, TQT_SLOT(modifySelectedMultiMasterReplication())); + m_fqdn = LDAPManager::getMachineFQDN(); // FIXME @@ -310,6 +324,18 @@ void LDAPController::processLockouts() { canChangeLDAPEnabled = false; } + if (m_base->systemRole->currentItem() == ROLE_PRIMARY_REALM_CONTROLLER) { + TQListViewItem* lvi = m_base->multiMasterReplicationMappings->selectedItem(); + if (lvi) { + m_base->btnEditMultiMasterReplicationMapping->setEnabled(true); + m_base->btnRemoveMultiMasterReplicationMapping->setEnabled(true); + } + else { + m_base->btnEditMultiMasterReplicationMapping->setEnabled(false); + m_base->btnRemoveMultiMasterReplicationMapping->setEnabled(false); + } + } + m_base->systemEnableSupport->setEnabled(canChangeLDAPEnabled); m_base->systemRole->setEnabled(enabled); } @@ -331,6 +357,27 @@ void LDAPController::load() { } if (ldapRole == "Primary Realm Controller") { m_base->systemRole->setCurrentItem(ROLE_PRIMARY_REALM_CONTROLLER); + + // Connect to LDAP + 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; + + // Get replication mappings from LDAP + LDAPMasterReplicationInfo replicationsettings = ldap_mgr->getLDAPMasterReplicationSettings(&errorstring); + m_base->advancedEnableMultiMasterReplication->setChecked(replicationsettings.enabled); + m_base->multiMasterReplicationMappings->clear(); + LDAPMasterReplicationMap::iterator it; + for (it = replicationsettings.serverIDs.begin(); it != replicationsettings.serverIDs.end(); ++it) { + new TQListViewItem(m_base->multiMasterReplicationMappings, TQString("%1").arg((*it).id), (*it).fqdn); + } + + delete ldap_mgr; + delete credentials; } else { m_base->systemRole->setCurrentItem(ROLE_WORKSTATION); @@ -356,6 +403,10 @@ void LDAPController::load() { m_defaultRealm = m_systemconfig->readEntry("DefaultRealm"); if (m_base->systemRole->currentItem() == ROLE_PRIMARY_REALM_CONTROLLER) { + if (m_base->TabWidget2->indexOf(m_base->advancedPrimaryControllerTab) < 0) { + m_base->TabWidget2->insertTab(m_base->advancedPrimaryControllerTab, i18n("Advanced Configuration")); + } + m_base->groupRealmController->show(); m_base->groupRealmCertificates->show(); @@ -387,6 +438,10 @@ void LDAPController::load() { m_certRefreshTimer.start(60*1000); } else { + if (m_base->TabWidget2->indexOf(m_base->advancedPrimaryControllerTab) >= 0) { + m_base->TabWidget2->removePage(m_base->advancedPrimaryControllerTab); + } + m_base->groupRealmController->hide(); m_base->groupRealmCertificates->hide(); @@ -675,11 +730,124 @@ void LDAPController::btnChangeRealmAdminPassword() { } } +void LDAPController::btnAddMultiMasterReplicationMapping() { + // Launch a dialog to add the mapping + LDAPMasterReplicationMapping mapping; + + bool run = true; + MultiMasterReplicationConfigDialog mappingconfigdlg(mapping, m_defaultRealm, this); + while (run && (mappingconfigdlg.exec() == TQDialog::Accepted)) { + mapping = mappingconfigdlg.m_replicationProperties; + // Make sure the provided FQDN and/or UID do not already exist + bool conflict = false; + TQPtrList lst; + TQListViewItemIterator it(m_base->multiMasterReplicationMappings); + while (it.current()) { + if (it.current()->text(0).toInt() == mapping.id) { + conflict = true; + KMessageBox::error(0, i18n("Unable to add new multi-master replication!

The provided ID '%1' conflicts with an existing replication mapping.").arg(mapping.id), i18n("Invalid Configuration")); + break; + } + if (it.current()->text(1) == mapping.fqdn) { + conflict = true; + KMessageBox::error(0, i18n("Unable to add new multi-master replication!

The provided FQDN '%1' conflicts with an existing replication mapping.").arg(mapping.fqdn), i18n("Invalid Configuration")); + break; + } + ++it; + } + if (conflict) { + run = true; + } + else { + run = false; + new TQListViewItem(m_base->multiMasterReplicationMappings, TQString("%1").arg(mapping.id), mapping.fqdn); + changed(); + } + } +} + +void LDAPController::btnEditMultiMasterReplicationMapping() { + // Launch a dialog to edit the mapping + LDAPMasterReplicationMapping mapping; + + TQListViewItem* lvi = m_base->multiMasterReplicationMappings->selectedItem(); + if (!lvi) { + return; + } + mapping.id = lvi->text(0).toInt(); + mapping.fqdn = lvi->text(1); + + bool run = true; + MultiMasterReplicationConfigDialog mappingconfigdlg(mapping, m_defaultRealm, this); + while (run && (mappingconfigdlg.exec() == TQDialog::Accepted)) { + mapping = mappingconfigdlg.m_replicationProperties; + // Make sure the provided FQDN and/or UID do not already exist + bool conflict = false; + TQPtrList lst; + TQListViewItemIterator it(m_base->multiMasterReplicationMappings); + while (it.current()) { + if (it.current() == lvi) { + // The selected item will be removed on update, so ignore any conflicts with it... + ++it; + continue; + } + if (it.current()->text(0).toInt() == mapping.id) { + conflict = true; + KMessageBox::error(0, i18n("Unable to add new multi-master replication!

The provided ID '%1' conflicts with an existing replication mapping.").arg(mapping.id), i18n("Invalid Configuration")); + break; + } + if (it.current()->text(1) == mapping.fqdn) { + conflict = true; + KMessageBox::error(0, i18n("Unable to add new multi-master replication!

The provided FQDN '%1' conflicts with an existing replication mapping.").arg(mapping.fqdn), i18n("Invalid Configuration")); + break; + } + ++it; + } + if (conflict) { + run = true; + } + else { + run = false; + if (lvi) { + delete lvi; + } + new TQListViewItem(m_base->multiMasterReplicationMappings, TQString("%1").arg(mapping.id), mapping.fqdn); + changed(); + } + } +} + +void LDAPController::btnRemoveMultiMasterReplicationMapping() { + LDAPMasterReplicationMapping mapping; + + TQListViewItem* lvi = m_base->multiMasterReplicationMappings->selectedItem(); + if (!lvi) { + return; + } + mapping.id = lvi->text(0).toInt(); + mapping.fqdn = lvi->text(1); + + if (KMessageBox::warningYesNo(this, i18n("You are about to remove the muli-master replication mapping for '%1'
This action cannot be undone once committed

Are you sure you want to proceed?").arg(mapping.fqdn), i18n("Confirmation Required")) == KMessageBox::Yes) { + delete lvi; + changed(); + } +} + +void LDAPController::multiMasterReplicationHighlighted() { + processLockouts(); +} + +void LDAPController::modifySelectedMultiMasterReplication() { + btnEditMultiMasterReplicationMapping(); +} + void LDAPController::defaults() { // } void LDAPController::save() { + TQString prevRole = m_systemconfig->readEntry("LDAPRole", "Workstation"); + m_systemconfig->setGroup(NULL); m_systemconfig->writeEntry("EnableLDAP", m_base->systemEnableSupport->isChecked()); m_systemconfig->writeEntry("HostFQDN", m_fqdn); @@ -699,6 +867,36 @@ void LDAPController::save() { m_systemconfig->sync(); + // If role was not changed, update any role-specific advanced settings + if (prevRole == m_systemconfig->readEntry("LDAPRole", "Workstation")) { + if (m_base->systemRole->currentItem() == ROLE_PRIMARY_REALM_CONTROLLER) { + 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; + + // Write multi-master replication settings + LDAPMasterReplicationInfo replicationSettings; + replicationSettings.enabled = m_base->advancedEnableMultiMasterReplication->isChecked(); + replicationSettings.serverIDs.clear(); + TQPtrList lst; + TQListViewItemIterator it(m_base->multiMasterReplicationMappings); + while (it.current()) { + LDAPMasterReplicationMapping mapping; + mapping.id = it.current()->text(0).toInt(); + mapping.fqdn = it.current()->text(1); + replicationSettings.serverIDs.append(mapping); + ++it; + } + if (ldap_mgr->setLDAPMasterReplicationSettings(replicationSettings, NULL) != 0) { + // ERROR + } + } + } + load(); } diff --git a/src/ldapcontroller.h b/src/ldapcontroller.h index c52caad..bfcfdcd 100644 --- a/src/ldapcontroller.h +++ b/src/ldapcontroller.h @@ -82,6 +82,13 @@ class LDAPController: public TDECModule void btnChangeLDAPRootPassword(); void btnChangeRealmAdminPassword(); + void btnAddMultiMasterReplicationMapping(); + void btnEditMultiMasterReplicationMapping(); + void btnRemoveMultiMasterReplicationMapping(); + + void multiMasterReplicationHighlighted(); + void modifySelectedMultiMasterReplication(); + private: int controlKAdminDaemon(sc_command command); int controlSASLServer(sc_command command); diff --git a/src/ldapcontrollerconfigbase.ui b/src/ldapcontrollerconfigbase.ui index 6e3bb47..06cf035 100644 --- a/src/ldapcontrollerconfigbase.ui +++ b/src/ldapcontrollerconfigbase.ui @@ -28,7 +28,7 @@ tab - LDAP Role + LDAP Role @@ -318,6 +318,94 @@ + + + advancedPrimaryControllerTab + + + Advanced Configuration + + + + unnamed + + + + groupMultiMasterReplication + + + Multi-Master Replication + + + + unnamed + + + + advancedEnableMultiMasterReplication + + + &Enable Multi-Master Replication + + + + + + Unique ID + + + true + + + false + + + + + Fully Qualified Domain Name + + + true + + + true + + + + multiMasterReplicationMappings + + + false + + + + + btnAddMultiMasterReplicationMapping + + + Add + + + + + btnEditMultiMasterReplicationMapping + + + Edit + + + + + btnRemoveMultiMasterReplicationMapping + + + Remove + + + + + + diff --git a/src/multimasterreplicationconfigbase.ui b/src/multimasterreplicationconfigbase.ui new file mode 100644 index 0000000..e0cecb1 --- /dev/null +++ b/src/multimasterreplicationconfigbase.ui @@ -0,0 +1,132 @@ + + LDAPMultiMasterReplicationConfigBase + + + LDAPMultiMasterReplicationConfigBase + + + + 0 + 0 + 519 + 356 + + + + + unnamed + + + + TabWidget2 + + + true + + + + detailsTab + + + Kerberos MultiMasterReplication + + + + unnamed + + + + unnamed_layoutwidget + + + + unnamed + + + + detailsIcon + + + + 4 + 5 + 1 + 0 + + + + + + unnamed + + + LDAP master: + + + + + masterName + + + + 3 + 5 + 1 + 0 + + + + + + realmNameLabel + + + + + + + + + + unnamed_layoutwidget + + + + unnamed + + + + masterIDCaption + + + Unique ID: + + + + + masterUID + + + 1 + + + 4095 + + + + + + + + + + + LDAPMultiMasterReplicationConfigBase.ui.h + + + kdialog.h + kpassdlg.h + + + + \ No newline at end of file diff --git a/src/multimasterreplicationconfigdlg.cpp b/src/multimasterreplicationconfigdlg.cpp new file mode 100644 index 0000000..6289b7b --- /dev/null +++ b/src/multimasterreplicationconfigdlg.cpp @@ -0,0 +1,85 @@ +/*************************************************************************** + * Copyright (C) 2013 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 "libtdeldap.h" +#include "multimasterreplicationconfigdlg.h" + +MultiMasterReplicationConfigDialog::MultiMasterReplicationConfigDialog(LDAPMasterReplicationMapping multimasterreplication, TQString realmName, TQWidget* parent, const char* name) + : KDialogBase(parent, name, true, i18n("LDAP Multi-Master Replication Properties"), Ok|Cancel, Ok, true), m_replicationProperties(multimasterreplication), m_ldapconfig(parent), m_realmName(realmName) +{ + m_base = new LDAPMultiMasterReplicationConfigBase(this); + setMainWidget(m_base); + + m_base->detailsIcon->setPixmap(SmallIcon("system.png")); + + m_base->realmNameLabel->setText("."+realmName.lower()); + + connect(m_base->masterName, TQT_SIGNAL(textChanged(const TQString&)), this, TQT_SLOT(processLockouts())); + + m_base->masterUID->setValue(m_replicationProperties.id); + + TQString shortMasterName = m_replicationProperties.fqdn; + if (shortMasterName.endsWith("." + m_realmName.lower())) { + shortMasterName.truncate(shortMasterName.length() - TQString("." + m_realmName).length()); + } + m_base->masterName->setText(shortMasterName); + m_base->masterName->setFocus(); + + processLockouts(); +} + +void MultiMasterReplicationConfigDialog::slotOk() { + m_replicationProperties.fqdn = m_base->masterName->text() + "." + m_realmName.lower(); + m_replicationProperties.id = m_base->masterUID->value(); + + accept(); +} + +void MultiMasterReplicationConfigDialog::processLockouts() { + if (m_base->masterName->text() == "") { + enableButton(KDialogBase::Ok, false); + } + else { + enableButton(KDialogBase::Ok, true); + } +} + +LDAPMasterReplicationMapping MultiMasterReplicationConfigDialog::replicationProperties() { + return m_replicationProperties; +} + +#include "multimasterreplicationconfigdlg.moc" diff --git a/src/multimasterreplicationconfigdlg.h b/src/multimasterreplicationconfigdlg.h new file mode 100644 index 0000000..58d9c01 --- /dev/null +++ b/src/multimasterreplicationconfigdlg.h @@ -0,0 +1,50 @@ +/*************************************************************************** + * Copyright (C) 2013 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. * + ***************************************************************************/ + +#ifndef _MULTIMASTERREPLICATIONCONFIGDIALOG_H_ +#define _MULTIMASTERREPLICATIONCONFIGDIALOG_H_ + +#include + +#include "libtdeldap.h" +#include "multimasterreplicationconfigbase.h" + +class MultiMasterReplicationConfigDialog : public KDialogBase +{ + Q_OBJECT + +public: + MultiMasterReplicationConfigDialog(LDAPMasterReplicationMapping multimasterreplication, TQString realmName, TQWidget* parent = 0, const char* name = 0); + LDAPMasterReplicationMapping replicationProperties(); + +public slots: + void slotOk(); + void processLockouts(); + +public: + LDAPMultiMasterReplicationConfigBase *m_base; + LDAPMasterReplicationMapping m_replicationProperties; + +private: + TQWidget* m_ldapconfig; + TQString m_realmName; +}; + +#endif // _MULTIMASTERREPLICATIONCONFIGDIALOG_H_