/***************************************************************************
* Copyright ( C ) 2012 - 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 <sys/types.h>
# include <signal.h>
# include <tqlayout.h>
# include <tdelocale.h>
# include <tdeglobal.h>
# include <kcombobox.h>
# include <tdeparts/genericfactory.h>
# include <ksimpleconfig.h>
# include <tdeglobalsettings.h>
# include <kstandarddirs.h>
# include <kurlrequester.h>
# include <tdelistview.h>
# include <kopenwith.h>
# include <kpropertiesdialog.h>
# include <tdeio/job.h>
# include <tqdir.h>
# include <tqheader.h>
# include <knuminput.h>
# include <kpassdlg.h>
# include <klineedit.h>
# include <tdemessagebox.h>
# include <tdesu/process.h>
# include "ldapbonding.h"
# include "bondwizard.h"
# include "ldappasswddlg.h"
# include "realmpropertiesdialog.h"
// FIXME
// Connect this to CMake/Automake
# define KDE_CONFDIR " / etc / trinity"
typedef KGenericFactory < LDAPConfig , TQWidget > ldapFactory ;
K_EXPORT_COMPONENT_FACTORY ( kcm_ldapbonding , ldapFactory ( " kcmldapbonding " ) )
KSimpleConfig * systemconfig = 0 ;
LDAPConfig : : LDAPConfig ( TQWidget * parent , const char * name , const TQStringList & )
: TDECModule ( parent , name ) , myAboutData ( 0 )
{
TQVBoxLayout * layout = new TQVBoxLayout ( this , KDialog : : marginHint ( ) , KDialog : : spacingHint ( ) ) ;
systemconfig = new KSimpleConfig ( TQString : : fromLatin1 ( KDE_CONFDIR " /ldap/ldapconfigrc " ) ) ;
systemconfig - > setFileWriteMode ( S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH ) ;
TDEAboutData * about = new TDEAboutData ( " ldap " , I18N_NOOP ( " TDE LDAP Manager " ) , " 0.1 " ,
I18N_NOOP ( " TDE LDAP Manager Control Panel Module " ) ,
TDEAboutData : : License_GPL ,
I18N_NOOP ( " (c) 2012-2013 Timothy Pearson " ) , 0 , 0 ) ;
about - > addAuthor ( " Timothy Pearson " , 0 , " kb9vqf@pearsoncomputing.net " ) ;
setAboutData ( about ) ;
base = new LDAPConfigBase ( this ) ;
layout - > add ( base ) ;
base - > ldapRealmList - > setAllColumnsShowFocus ( true ) ;
base - > ldapRealmList - > setFullWidth ( true ) ;
setRootOnlyMsg ( i18n ( " <b>Bonded LDAP realms take effect system wide, and require administrator access to modify</b><br>To alter the system's bonded LDAP realms, click on the \" Administrator Mode \" button below. " ) ) ;
setUseRootOnlyMsg ( true ) ;
connect ( base - > systemEnableSupport , TQT_SIGNAL ( clicked ( ) ) , this , TQT_SLOT ( changed ( ) ) ) ;
connect ( base - > defaultRealm , TQT_SIGNAL ( activated ( int ) ) , this , TQT_SLOT ( changed ( ) ) ) ;
connect ( base - > ticketLifetime , TQT_SIGNAL ( valueChanged ( int ) ) , this , TQT_SLOT ( changed ( ) ) ) ;
connect ( base - > systemEnableSupport , TQT_SIGNAL ( clicked ( ) ) , this , TQT_SLOT ( processLockouts ( ) ) ) ;
connect ( base - > ldapRealmList , TQT_SIGNAL ( selectionChanged ( ) ) , this , TQT_SLOT ( processLockouts ( ) ) ) ;
connect ( base - > btnBondRealm , TQT_SIGNAL ( clicked ( ) ) , this , TQT_SLOT ( bondToNewRealm ( ) ) ) ;
connect ( base - > btnReBondRealm , TQT_SIGNAL ( clicked ( ) ) , this , TQT_SLOT ( reBondToRealm ( ) ) ) ;
connect ( base - > btnRemoveRealm , TQT_SIGNAL ( clicked ( ) ) , this , TQT_SLOT ( removeRealm ( ) ) ) ;
connect ( base - > btnDeactivateRealm , TQT_SIGNAL ( clicked ( ) ) , this , TQT_SLOT ( deactivateRealm ( ) ) ) ;
connect ( base - > btnRealmProperties , TQT_SIGNAL ( clicked ( ) ) , this , TQT_SLOT ( realmProperties ( ) ) ) ;
connect ( base - > ldapVersion , TQT_SIGNAL ( valueChanged ( int ) ) , this , TQT_SLOT ( changed ( ) ) ) ;
connect ( base - > ldapTimeout , TQT_SIGNAL ( valueChanged ( int ) ) , this , TQT_SLOT ( changed ( ) ) ) ;
connect ( base - > bindPolicy , TQT_SIGNAL ( activated ( int ) ) , this , TQT_SLOT ( changed ( ) ) ) ;
connect ( base - > ldapBindTimeout , TQT_SIGNAL ( valueChanged ( int ) ) , this , TQT_SLOT ( changed ( ) ) ) ;
connect ( base - > passwordHash , TQT_SIGNAL ( activated ( int ) ) , this , TQT_SLOT ( changed ( ) ) ) ;
connect ( base - > ignoredUsers , TQT_SIGNAL ( textChanged ( const TQString & ) ) , this , TQT_SLOT ( changed ( ) ) ) ;
hostFQDN = LDAPManager : : getMachineFQDN ( ) ;
base - > hostFQDN - > setEnabled ( false ) ;
base - > hostFQDN - > clear ( ) ;
base - > hostFQDN - > insertItem ( hostFQDN ) ;
load ( ) ;
systemconfig - > setGroup ( NULL ) ;
if ( ( getuid ( ) ! = 0 ) | | ( ! systemconfig - > checkConfigFilesWritable ( true ) ) | | ( m_clientRealmConfig . ldapRole ! = " Workstation " ) ) {
base - > systemEnableSupport - > setEnabled ( false ) ;
}
processLockouts ( ) ;
} ;
LDAPConfig : : ~ LDAPConfig ( ) {
delete systemconfig ;
}
void LDAPConfig : : load ( ) {
kgs = new TDEGlobalSettings ( ) ;
load ( false ) ;
}
void LDAPConfig : : load ( bool useDefaults )
{
int i ;
m_clientRealmConfig = LDAPManager : : loadClientRealmConfig ( systemconfig , useDefaults ) ;
base - > systemEnableSupport - > setChecked ( m_clientRealmConfig . enable_bonding ) ;
// Load realms
m_realms . clear ( ) ;
m_realms = LDAPManager : : readTDERealmList ( systemconfig , ! m_clientRealmConfig . configurationVerifiedForLocalMachine ) ;
base - > ticketLifetime - > setValue ( m_clientRealmConfig . ticketLifetime ) ;
base - > ldapVersion - > setValue ( m_clientRealmConfig . ldapVersion ) ;
base - > ldapTimeout - > setValue ( m_clientRealmConfig . ldapTimeout ) ;
for ( i = 0 ; i < base - > bindPolicy - > count ( ) ; i + + ) {
if ( base - > bindPolicy - > text ( i ) . lower ( ) = = m_clientRealmConfig . defaultRealm . lower ( ) ) {
base - > bindPolicy - > setCurrentItem ( i ) ;
break ;
}
}
base - > ldapBindTimeout - > setValue ( m_clientRealmConfig . ldapBindTimeout ) ;
for ( i = 0 ; i < base - > passwordHash - > count ( ) ; i + + ) {
if ( base - > passwordHash - > text ( i ) . lower ( ) = = m_clientRealmConfig . passwordHash . lower ( ) ) {
base - > passwordHash - > setCurrentItem ( i ) ;
break ;
}
}
base - > ignoredUsers - > setText ( m_clientRealmConfig . ignoredUsers ) ;
updateRealmList ( ) ;
processLockouts ( ) ;
emit changed ( useDefaults ) ;
}
void LDAPConfig : : updateRealmList ( ) {
base - > ldapRealmList - > clear ( ) ;
base - > defaultRealm - > clear ( ) ;
LDAPRealmConfigList : : Iterator it ;
for ( it = m_realms . begin ( ) ; it ! = m_realms . end ( ) ; + + it ) {
LDAPRealmConfig realmcfg = it . data ( ) ;
( void ) new TQListViewItem ( base - > ldapRealmList , ( ( realmcfg . bonded ) ? i18n ( " Bonded " ) : i18n ( " Deactivated " ) ) , realmcfg . name ) ;
base - > defaultRealm - > insertItem ( realmcfg . name ) ;
}
if ( m_clientRealmConfig . defaultRealm ! = " " ) {
for ( int i = 0 ; i < base - > defaultRealm - > count ( ) ; i + + ) {
if ( base - > defaultRealm - > text ( i ) = = m_clientRealmConfig . defaultRealm ) {
base - > defaultRealm - > setCurrentItem ( i ) ;
break ;
}
}
}
processLockouts ( ) ;
}
void LDAPConfig : : defaults ( ) {
}
void LDAPConfig : : save ( ) {
TQString errorstring ;
m_clientRealmConfig . hostFQDN = hostFQDN ;
m_clientRealmConfig . enable_bonding = base - > systemEnableSupport - > isChecked ( ) ;
m_clientRealmConfig . defaultRealm = base - > defaultRealm - > currentText ( ) ;
m_clientRealmConfig . ticketLifetime = base - > ticketLifetime - > value ( ) ;
m_clientRealmConfig . ldapVersion = base - > ldapVersion - > value ( ) ;
m_clientRealmConfig . ldapTimeout = base - > ldapTimeout - > value ( ) ;
m_clientRealmConfig . bindPolicy = base - > bindPolicy - > currentText ( ) ;
m_clientRealmConfig . ldapBindTimeout = base - > ldapBindTimeout - > value ( ) ;
m_clientRealmConfig . passwordHash = base - > passwordHash - > currentText ( ) ;
m_clientRealmConfig . ignoredUsers = base - > ignoredUsers - > text ( ) ;
// Write system configuration
if ( LDAPManager : : saveClientRealmConfig ( m_clientRealmConfig , systemconfig , & errorstring ) ! = 0 ) {
KMessageBox : : error ( this , i18n ( " <qt><b>Unable to save configuration!</b><p>Details: %2</qt> " ) . arg ( errorstring ) , i18n ( " Unable to Save Configuration " ) ) ;
return ;
}
LDAPManager : : writeTDERealmList ( m_realms , systemconfig ) ;
systemconfig - > sync ( ) ;
if ( m_clientRealmConfig . enable_bonding ) {
// Write the Kerberos5 configuration file
if ( LDAPManager : : writeClientKrb5ConfFile ( m_clientRealmConfig , m_realms , & errorstring ) ! = 0 ) {
KMessageBox : : error ( this , i18n ( " <qt><b>Unable to save configuration!</b><p>Details: %2</qt> " ) . arg ( errorstring ) , i18n ( " Unable to Save Configuration " ) ) ;
return ;
}
// Write the LDAP configuration file
if ( LDAPManager : : writeLDAPConfFile ( m_realms [ m_clientRealmConfig . defaultRealm ] , & errorstring ) ! = 0 ) {
KMessageBox : : error ( this , i18n ( " <qt><b>Unable to save configuration!</b><p>Details: %2</qt> " ) . arg ( errorstring ) , i18n ( " Unable to Save Configuration " ) ) ;
return ;
}
// Write the NSSwitch configuration file
if ( LDAPManager : : writeNSSwitchFile ( & errorstring ) ! = 0 ) {
KMessageBox : : error ( this , i18n ( " <qt><b>Unable to save configuration!</b><p>Details: %2</qt> " ) . arg ( errorstring ) , i18n ( " Unable to Save Configuration " ) ) ;
return ;
}
// Write the PAM configuration files
if ( LDAPManager : : writePAMFiles ( & errorstring ) ! = 0 ) {
KMessageBox : : error ( this , i18n ( " <qt><b>Unable to save configuration!</b><p>Details: %2</qt> " ) . arg ( errorstring ) , i18n ( " Unable to Save Configuration " ) ) ;
return ;
}
// Write the cron files
if ( LDAPManager : : writeClientCronFiles ( ) ! = 0 ) {
KMessageBox : : error ( this , i18n ( " <qt><b>Unable to save configuration!</b><p>Details: %2</qt> " ) . arg ( errorstring ) , i18n ( " Unable to Save Configuration " ) ) ;
return ;
}
if ( m_clientRealmConfig . defaultRealm ! = " " ) {
// Bind anonymously to LDAP
LDAPCredentials * credentials = new LDAPCredentials ;
credentials - > username = " " ;
credentials - > password = " " ;
credentials - > realm = m_clientRealmConfig . defaultRealm . upper ( ) ;
credentials - > use_tls = false ;
LDAPManager * ldap_mgr = new LDAPManager ( m_clientRealmConfig . defaultRealm . upper ( ) , TQString ( " ldap://%1 " ) . arg ( m_realms [ m_clientRealmConfig . defaultRealm ] . admin_server ) . ascii ( ) , credentials ) ;
// Add the domain-wide computer local admin group to local sudoers
ldap_mgr - > writeSudoersConfFile ( & errorstring ) ;
// Get and install the CA root certificate from LDAP
mkdir ( TDE_CERTIFICATE_DIR , 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 ) ;
if ( ldap_mgr - > getTDECertificate ( " publicRootCertificate " , KERBEROS_PKI_PUBLICDIR + m_realms [ m_clientRealmConfig . defaultRealm ] . admin_server + " .ldap.crt " , & errorstring ) ! = 0 ) {
KMessageBox : : sorry ( this , i18n ( " <qt><b>Unable to obtain root certificate for realm %1!</b><p>Details: %2</qt> " ) . arg ( m_clientRealmConfig . defaultRealm . upper ( ) ) . arg ( errorstring ) , i18n ( " Unable to Obtain Certificate " ) ) ;
}
delete ldap_mgr ;
delete credentials ;
}
// Certificates may have changed; force the certificate update daemon to reload its configuration
pid_t certUpdaterPID ;
TQFile pidFile ( TDE_LDAP_CERT_UPDATER_PID_FILE ) ;
if ( pidFile . open ( IO_ReadOnly ) ) {
TQTextStream stream ( & pidFile ) ;
stream > > certUpdaterPID ;
pidFile . close ( ) ;
kill ( certUpdaterPID , SIGHUP ) ;
}
}
load ( ) ;
}
void LDAPConfig : : processLockouts ( ) {
bool panelIsEnabled = ( base - > systemEnableSupport - > isEnabled ( ) & & base - > systemEnableSupport - > isChecked ( ) ) ;
base - > groupRealms - > setEnabled ( panelIsEnabled ) ;
base - > groupKrbDefaults - > setEnabled ( panelIsEnabled ) ;
base - > groupConnectionParameters - > setEnabled ( panelIsEnabled ) ;
TQListViewItem * selrealm = base - > ldapRealmList - > selectedItem ( ) ;
if ( selrealm ) {
LDAPRealmConfig realmcfg = m_realms [ selrealm - > text ( 1 ) ] ;
base - > btnBondRealm - > setEnabled ( true ) ;
base - > btnReBondRealm - > setEnabled ( true ) ;
if ( realmcfg . bonded ) {
base - > btnDeactivateRealm - > setEnabled ( true ) ;
base - > btnRemoveRealm - > setEnabled ( false ) ;
base - > btnRealmProperties - > setEnabled ( false ) ;
}
else {
base - > btnDeactivateRealm - > setEnabled ( false ) ;
base - > btnRemoveRealm - > setEnabled ( true ) ;
base - > btnRealmProperties - > setEnabled ( true ) ;
}
}
else {
base - > btnBondRealm - > setEnabled ( true ) ;
base - > btnReBondRealm - > setEnabled ( false ) ;
base - > btnDeactivateRealm - > setEnabled ( false ) ;
base - > btnRemoveRealm - > setEnabled ( false ) ;
base - > btnRealmProperties - > setEnabled ( false ) ;
}
}
void LDAPConfig : : bondToNewRealm ( ) {
// Something will probably change
save ( ) ;
BondWizard bondwizard ( & m_realms , this , this ) ;
bondwizard . exec ( ) ;
// Something probably changed
load ( ) ;
}
void LDAPConfig : : reBondToRealm ( ) {
TQListViewItem * selrealm = base - > ldapRealmList - > selectedItem ( ) ;
if ( selrealm ) {
TQString realmName = selrealm - > text ( 1 ) ;
LDAPRealmConfig realmcfg = m_realms [ realmName ] ;
// Password prompt...
TQString errorString ;
LDAPPasswordDialog passdlg ( this ) ;
passdlg . m_base - > ldapAdminRealm - > setEnabled ( false ) ;
passdlg . m_base - > ldapAdminRealm - > setText ( realmName ) ;
if ( passdlg . exec ( ) = = TQDialog : : Accepted ) {
setEnabled ( false ) ;
if ( LDAPManager : : unbondRealm ( m_realms [ realmName ] , passdlg . m_base - > ldapAdminUsername - > text ( ) , passdlg . m_base - > ldapAdminPassword - > password ( ) , passdlg . m_base - > ldapAdminRealm - > text ( ) , & errorString ) = = 0 ) {
// Success!
realmcfg . bonded = false ;
m_realms . remove ( realmName ) ;
m_realms . insert ( realmName , realmcfg ) ;
save ( ) ;
if ( LDAPManager : : bondRealm ( passdlg . m_base - > ldapAdminUsername - > text ( ) , passdlg . m_base - > ldapAdminPassword - > password ( ) , passdlg . m_base - > ldapAdminRealm - > text ( ) , & errorString ) = = 0 ) {
// Success!
realmcfg . bonded = true ;
m_realms . remove ( realmName ) ;
m_realms . insert ( realmName , realmcfg ) ;
save ( ) ;
}
else {
KMessageBox : : error ( this , i18n ( " <qt><b>Unable to bond to realm!</b><p>Details: %1</qt> " ) . arg ( errorString ) , i18n ( " Unable to Bond to Realm " ) ) ;
}
}
else {
KMessageBox : : error ( this , i18n ( " <qt><b>Unable to unbond from realm!</b><p>%1</qt> " ) . arg ( errorString ) , i18n ( " Unable to Unbond from Realm " ) ) ;
}
setEnabled ( true ) ;
}
}
updateRealmList ( ) ;
}
void LDAPConfig : : removeRealm ( ) {
TQListViewItem * selrealm = base - > ldapRealmList - > selectedItem ( ) ;
if ( selrealm ) {
m_realms . remove ( selrealm - > text ( 1 ) ) ;
updateRealmList ( ) ;
changed ( ) ;
}
}
void LDAPConfig : : deactivateRealm ( ) {
TQListViewItem * selrealm = base - > ldapRealmList - > selectedItem ( ) ;
if ( selrealm ) {
TQString realmName = selrealm - > text ( 1 ) ;
LDAPRealmConfig realmcfg = m_realms [ realmName ] ;
if ( realmcfg . bonded = = true ) {
// Password prompt...
TQString errorString ;
LDAPPasswordDialog passdlg ( this ) ;
passdlg . m_base - > ldapAdminRealm - > setEnabled ( false ) ;
passdlg . m_base - > ldapAdminRealm - > setText ( realmName ) ;
passdlg . m_base - > passprompt - > setText ( i18n ( " Please provide LDAP realm administrator credentials below to complete the unbonding process " ) ) ;
if ( passdlg . exec ( ) = = TQDialog : : Accepted ) {
setEnabled ( false ) ;
if ( LDAPManager : : unbondRealm ( m_realms [ realmName ] , passdlg . m_base - > ldapAdminUsername - > text ( ) , passdlg . m_base - > ldapAdminPassword - > password ( ) , passdlg . m_base - > ldapAdminRealm - > text ( ) , & errorString ) = = 0 ) {
// Success!
realmcfg . bonded = false ;
m_realms . remove ( realmName ) ;
m_realms . insert ( realmName , realmcfg ) ;
save ( ) ;
}
else {
KMessageBox : : error ( this , i18n ( " <qt><b>Unable to unbond from realm!</b><p>%1</qt> " ) . arg ( errorString ) , i18n ( " Unable to Unbond from Realm " ) ) ;
}
setEnabled ( true ) ;
}
}
}
updateRealmList ( ) ;
}
void LDAPConfig : : realmProperties ( ) {
TQListViewItem * selrealm = base - > ldapRealmList - > selectedItem ( ) ;
if ( selrealm ) {
RealmPropertiesDialog rpdialog ( & m_realms , selrealm - > text ( 1 ) , this ) ;
if ( rpdialog . exec ( ) = = TQDialog : : Accepted ) {
updateRealmList ( ) ;
changed ( ) ;
}
}
}
int LDAPConfig : : buttons ( ) {
return TDECModule : : Apply | TDECModule : : Help ;
}
TQString LDAPConfig : : quickHelp ( ) const
{
return i18n ( " This module configures which LDAP realms TDE uses for authentication. " ) ;
}