From 45bfc1dc6edcc27f67acfbebb2d0f22ea06a40c4 Mon Sep 17 00:00:00 2001 From: Timothy Pearson Date: Fri, 1 Mar 2013 00:19:15 -0600 Subject: [PATCH] Use bonding code in libtdeldap Add skeleton code for tdeldapbonding --- cmdline/Makefile.am | 10 +++ cmdline/main.cpp | 176 +++++++++++++++++++++++++++++++++++++++++ src/bondwizard.cpp | 2 +- src/ldapbonding.cpp | 189 +------------------------------------------- src/ldapbonding.h | 3 - subdirs | 1 + 6 files changed, 190 insertions(+), 191 deletions(-) create mode 100644 cmdline/Makefile.am create mode 100644 cmdline/main.cpp diff --git a/cmdline/Makefile.am b/cmdline/Makefile.am new file mode 100644 index 0000000..0e27801 --- /dev/null +++ b/cmdline/Makefile.am @@ -0,0 +1,10 @@ +INCLUDES= $(all_includes) $(KDE_INCLUDES)/tde + +bin_PROGRAMS = tdeldapbonding + +tdeldapbonding_SOURCES = main.cpp + +tdeldapbonding_METASOURCES = AUTO +tdeldapbonding_LDFLAGS = $(all_libraries) $(KDE_RPATH) $(LIB_QT) -lDCOP $(LIB_TDECORE) $(LIB_TDEUI) -ltdefx $(LIB_KIO) -ltdetexteditor -ltdeldap + +KDE_OPTIONS = nofinal diff --git a/cmdline/main.cpp b/cmdline/main.cpp new file mode 100644 index 0000000..55a21de --- /dev/null +++ b/cmdline/main.cpp @@ -0,0 +1,176 @@ +/*************************************************************************** + * 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 + +// FIXME +// Connect this to CMake/Automake +#define KDE_CONFDIR "/etc/trinity" + +static const char description[] = + I18N_NOOP("TDE utility for managing workstations in a Kerberos realm"); + +static const char version[] = "v0.0.1"; + +static const TDECmdLineOptions options[] = +{ + { "adminusername ", I18N_NOOP("Specifies the username of the administrative user with permissions to perform the requested task"), 0 }, + { "adminpasswordfile ", I18N_NOOP("Specifies the location of a file which contains the password of the administrative user"), 0 }, + { "!+command", I18N_NOOP("The command to execute on the Kerberos realm. Valid commands are: bond unbond disable"), 0 }, + { "!+realm", I18N_NOOP("The Kerberos realm on which to execute the specified command. Example: MY.REALM"), 0 }, + { "", I18N_NOOP("This utility requires an administrative user and password to be specified on the command line to function!"), 0 }, + TDECmdLineLastOption // End of options. +}; + +int main(int argc, char *argv[]) +{ + TDEAboutData aboutData( "tdeldapbonding", I18N_NOOP("Kerberos Realm Bonding Manager"), + version, description, TDEAboutData::License_GPL, + "(c) 2013, Timothy Pearson"); + aboutData.addAuthor("Timothy Pearson",0, "kb9vqf@pearsoncomputing.net"); + TDECmdLineArgs::init(argc, argv, &aboutData); + TDECmdLineArgs::addCmdLineOptions(options); + KUniqueApplication::addCmdLineOptions(); + TDEApplication::disableAutoDcopRegistration(); + + TDEApplication app(false, false); + + TDEStartupInfo::appStarted(); + + KSimpleConfig systemconfig( TQString::fromLatin1( KDE_CONFDIR "/ldap/ldapconfigrc" )); + systemconfig.setFileWriteMode(S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); + + //====================================================================================================================================================== + // + // Manager code follows + // + //====================================================================================================================================================== + + TDECmdLineArgs *args = TDECmdLineArgs::parsedArgs(); + if (args->count() > 1) { + int retcode; + + TQString command = TQString(args->arg(0)); + TQString realm = TQString(args->arg(1)); + + systemconfig.setGroup("LDAPRealm-" + realm); + TQString host = systemconfig.readEntry("admin_server"); + LDAPCredentials credentials; + if (args->isSet("adminusername") && args->isSet("adminpasswordfile")) { + TQString passFileName = args->getOption("adminpasswordfile"); + TQFile passFile(passFileName); + if (!passFile.open(IO_ReadOnly)) { + printf("[ERROR] Unable to open specified password file '%s'\n\r", passFileName.ascii()); fflush(stdout); + return -1; + } + TQTextStream stream(&passFile); + credentials.username = args->getOption("adminusername"); + credentials.password = stream.readLine(); + passFile.close(); + } + else { + credentials.use_gssapi = true; + } + credentials.realm = realm; + LDAPManager ldapmanager(realm, host, &credentials); + +// FIXME +// Move core bonding functionality from ldapbonding.cpp into libtdeldap, then ***properly*** activate this code! +// if (command == "bond") { +// // FIXME +// LDAPRealmConfig realmConfig; +// TQString errorString; +// +// realmConfig.name = realm; +// realmConfig.bonded = ; +// realmConfig.uid_offset; +// realmConfig.gid_offset; +// realmConfig.domain_mappings; +// realmConfig.kdc; +// realmConfig.kdc_port; +// realmConfig.admin_server; +// realmConfig.admin_server_port; +// realmConfig.pkinit_require_eku; +// realmConfig.pkinit_require_krbtgt_otherName; +// realmConfig.win2k_pkinit; +// realmConfig.win2k_pkinit_require_binding; +// +// if (LDAPManager::bondRealm(realmConfig, credentials.username, credentials.password, credentials.realm, &errorString) == 0) { +// // Success! +// } +// else { +// // Failure +// return -1; +// } +// } +// else if (command == "unbond") { +// // FIXME +// TQString errorString; +// +// if (LDAPManager::unbondRealm(realm, credentials.username, credentials.password, credentials.realm, &errorString) == 0) { +// // Success! +// } +// else { +// // Failure +// return -1; +// } +// } +// else if (command == "disable") { +// // FIXME +// } +// else { + TDECmdLineArgs::usage(i18n("An invalid command was specified")); + return -1; +// } + } + else { + if (args->count() > 0) { + TDECmdLineArgs::usage(i18n("No Kerberos realm was specified")); + return -1; + } + else { + TDECmdLineArgs::usage(i18n("No command was specified")); + return -1; + } + } + + //====================================================================================================================================================== + + return 0; +} diff --git a/src/bondwizard.cpp b/src/bondwizard.cpp index a71fdaa..db96f03 100644 --- a/src/bondwizard.cpp +++ b/src/bondwizard.cpp @@ -202,7 +202,7 @@ void BondWizard::accept(){ cancelButton()->setEnabled(false); finishpage->setEnabled(false); - if (m_ldapConfig->bondRealm(m_finalRealm, finishpage->ldapAdminUsername->text(), finishpage->ldapAdminPassword->password(), finishpage->ldapAdminRealm->text(), &errorString) == 0) { + if (LDAPManager::bondRealm(m_finalRealm, finishpage->ldapAdminUsername->text(), finishpage->ldapAdminPassword->password(), finishpage->ldapAdminRealm->text(), &errorString) == 0) { done(0); } else { diff --git a/src/ldapbonding.cpp b/src/ldapbonding.cpp index e7ce4ab..b7e1c23 100644 --- a/src/ldapbonding.cpp +++ b/src/ldapbonding.cpp @@ -339,7 +339,7 @@ void LDAPConfig::reBondToRealm() { passdlg.m_base->ldapAdminRealm->setText(realmName); if (passdlg.exec() == TQDialog::Accepted) { setEnabled(false); - if (bondRealm(m_realms[realmName], passdlg.m_base->ldapAdminUsername->text(), passdlg.m_base->ldapAdminPassword->password(), passdlg.m_base->ldapAdminRealm->text(), &errorString) == 0) { + if (LDAPManager::bondRealm(m_realms[realmName], 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); @@ -378,7 +378,7 @@ void LDAPConfig::deactivateRealm() { 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 (unbondRealm(m_realms[realmName], passdlg.m_base->ldapAdminUsername->text(), passdlg.m_base->ldapAdminPassword->password(), passdlg.m_base->ldapAdminRealm->text(), &errorString) == 0) { + 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); @@ -395,191 +395,6 @@ void LDAPConfig::deactivateRealm() { updateRealmList(); } -int LDAPConfig::bondRealm(LDAPRealmConfig realmcfg, TQString adminUserName, const char * adminPassword, TQString adminRealm, TQString *errstr) { - TQCString command = "kadmin"; - QCStringList args; - args << TQCString("-p") << TQCString(adminUserName+"@"+(adminRealm.upper())) << TQCString("-r") << TQCString(adminRealm.upper()); - - TQString hoststring = "host/"+m_fqdn; - - 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.endsWith(" Password:")) { - kadminProc.enableLocalEcho(false); - kadminProc.writeLine(adminPassword, true); - do { // Discard our own input - prompt = LDAPManager::readFullLineFromPtyProcess(&kadminProc); - printf("(kadmin) '%s'\n\r", prompt.ascii()); - } while (prompt == ""); - 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")) { - // Wait for kadmin to be ready for the next command - if (!prompt.contains("kadmin>")) { - prompt = ""; - } - while (prompt == "") { - prompt = LDAPManager::readFullLineFromPtyProcess(&kadminProc); - printf("(kadmin) '%s'\n\r", prompt.ascii()); - } - 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.endsWith(" Password:")) { - kadminProc.enableLocalEcho(false); - kadminProc.writeLine(adminPassword, true); - do { // Discard our own input - prompt = LDAPManager::readFullLineFromPtyProcess(&kadminProc); - printf("(kadmin) '%s'\n\r", prompt.ascii()); - } while (prompt == ""); - prompt = prompt.stripWhiteSpace(); - } - 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); - - realmcfg.bonded = true; - m_realms.remove(realmcfg.name); - m_realms.insert(realmcfg.name, realmcfg); - save(); - return 0; - } - else if (prompt == "kadmin>") { - // Success! - kadminProc.enableLocalEcho(false); - kadminProc.writeLine("quit", true); - - realmcfg.bonded = true; - m_realms.remove(realmcfg.name); - m_realms.insert(realmcfg.name, realmcfg); - save(); - 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 LDAPConfig::unbondRealm(LDAPRealmConfig realmcfg, TQString adminUserName, const char * adminPassword, TQString adminRealm, TQString *errstr) { - Q_UNUSED(realmcfg); - - TQCString command = "kadmin"; - QCStringList args; - args << TQCString("-p") << TQCString(adminUserName+"@"+(adminRealm.upper())); - - TQString hoststring = "host/"+m_fqdn; - - TQString prompt; - PtyProcess kadminProc; - kadminProc.exec(command, args); - prompt = LDAPManager::readFullLineFromPtyProcess(&kadminProc); - prompt = prompt.stripWhiteSpace(); - if (prompt == "kadmin>") { - command = TQCString("delete "+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.endsWith(" Password:")) { - kadminProc.enableLocalEcho(false); - kadminProc.writeLine(adminPassword, 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; - } - - return 1; // Failure -} - void LDAPConfig::realmProperties() { TQListViewItem *selrealm = base->ldapRealmList->selectedItem(); if (selrealm) { diff --git a/src/ldapbonding.h b/src/ldapbonding.h index 7a8376c..a6686a3 100644 --- a/src/ldapbonding.h +++ b/src/ldapbonding.h @@ -55,9 +55,6 @@ class LDAPConfig: public TDECModule virtual TQString quickHelp() const; virtual const TDEAboutData *aboutData() const { return myAboutData; }; - int bondRealm(LDAPRealmConfig realmcfg, TQString adminUserName, const char * adminPassword, TQString adminRealm, TQString *errstr=0); - int unbondRealm(LDAPRealmConfig realmcfg, TQString adminUserName, const char * adminPassword, TQString adminRealm, TQString *errstr=0); - private slots: void processLockouts(); void bondToNewRealm(); diff --git a/subdirs b/subdirs index 894c13f..26107ab 100644 --- a/subdirs +++ b/subdirs @@ -1,3 +1,4 @@ +cmdline doc pics po