summaryrefslogtreecommitdiffstats
path: root/src/libtdeldap.cpp
diff options
context:
space:
mode:
authorTimothy Pearson <kb9vqf@pearsoncomputing.net>2013-03-21 00:05:19 -0500
committerTimothy Pearson <kb9vqf@pearsoncomputing.net>2013-03-21 00:05:19 -0500
commitfae0948a282c3cb72299692c9cb0af261ea5d80a (patch)
treea1fa3a7808d966d8d196fa5e63e8c53bed676021 /src/libtdeldap.cpp
parente0f5e6ac4e90ddd00a941914f1aca4494c9a0e31 (diff)
downloadlibtdeldap-fae0948a282c3cb72299692c9cb0af261ea5d80a.tar.gz
libtdeldap-fae0948a282c3cb72299692c9cb0af261ea5d80a.zip
Move core code from the bonding utility to this library
Diffstat (limited to 'src/libtdeldap.cpp')
-rw-r--r--src/libtdeldap.cpp222
1 files changed, 201 insertions, 21 deletions
diff --git a/src/libtdeldap.cpp b/src/libtdeldap.cpp
index eef035a..c065eeb 100644
--- a/src/libtdeldap.cpp
+++ b/src/libtdeldap.cpp
@@ -1,5 +1,5 @@
/***************************************************************************
- * Copyright (C) 2012 by Timothy Pearson *
+ * Copyright (C) 2012-2013 by Timothy Pearson *
* kb9vqf@pearsoncomputing.net *
* *
* This program is free software; you can redistribute it and/or modify *
@@ -56,12 +56,21 @@
// FIXME
// This assumes Debian!
+#define KRB5_FILE "/etc/krb5.conf"
+
+#define NSSWITCH_FILE "/etc/nsswitch.conf"
+
+#define PAMD_DIRECTORY "/etc/pam.d/"
+#define PAMD_COMMON_ACCOUNT "common-account"
+#define PAMD_COMMON_AUTH "common-auth"
+
#define LDAP_FILE "/etc/ldap/ldap.conf"
#define LDAP_SECONDARY_FILE "/etc/ldap.conf"
#define LDAP_TERTIARY_FILE "/etc/libnss-ldap.conf"
+
#define TDELDAP_SUDO_D_FILE "/etc/sudoers.d/tde-realm-admins"
-#define CRON_UPDATE_NSS_FILE "/etc/cron.daily/upd-local-nss-db"
+#define CRON_UPDATE_NSS_FILE "/etc/cron.daily/upd-local-nss-db"
#define CRON_UPDATE_NSS_COMMAND "/usr/sbin/nss_updatedb ldap"
int requested_ldap_version = LDAP_VERSION3;
@@ -2229,7 +2238,7 @@ int LDAPManager::moveKerberosEntries(TQString newSuffix, TQString* errstr) {
return -1;
}
-void LDAPManager::writeLDAPConfFile(LDAPRealmConfig realmcfg) {
+int LDAPManager::writeLDAPConfFile(LDAPRealmConfig realmcfg, TQString *errstr) {
KSimpleConfig* systemconfig;
TQString m_defaultRealm;
int m_ldapVersion;
@@ -2276,37 +2285,39 @@ void LDAPManager::writeLDAPConfFile(LDAPRealmConfig realmcfg) {
}
if (chmod(LDAP_FILE, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH) < 0) {
- printf("ERROR: Unable to change permissions of \"%s\"\n\r", LDAP_FILE);
- return;
+ if (errstr) *errstr = TQString("Unable to change permissions of \"%1\"").arg(LDAP_FILE);
+ return -1;
}
// Create symbolic link to secondary LDAP configuration file
if (fileExists(LDAP_SECONDARY_FILE)) {
if (unlink(LDAP_SECONDARY_FILE) < 0) {
- printf("ERROR: Unable to unlink \"%s\"\n\r", LDAP_SECONDARY_FILE);
- return;
+ if (errstr) *errstr = TQString("Unable to unlink \"%s\"").arg(LDAP_SECONDARY_FILE);
+ return -1;
}
}
command = TQString("ln -s %1 %2").arg(LDAP_FILE).arg(LDAP_SECONDARY_FILE);
if (system(command) < 0) {
- printf("ERROR: Execution of \"%s\" failed!\n\r", command.ascii());
- return;
+ if (errstr) *errstr = TQString("Execution of \"%s\" failed").arg(command.ascii());
+ return -1;
}
// Create symbolic link to tertiary LDAP configuration file
if (fileExists(LDAP_TERTIARY_FILE)) {
if (unlink(LDAP_TERTIARY_FILE) < 0) {
- printf("ERROR: Unable to unlink \"%s\"\n\r", LDAP_TERTIARY_FILE);
- return;
+ if (errstr) *errstr = TQString("Unable to unlink \"%s\"").arg(LDAP_TERTIARY_FILE);
+ return -1;
}
}
command = TQString("ln -s %1 %2").arg(LDAP_FILE).arg(LDAP_TERTIARY_FILE);
if (system(command) < 0) {
- printf("ERROR: Execution of \"%s\" failed!\n\r", command.ascii());
- return;
+ if (errstr) *errstr = TQString("Execution of \"%s\" failed").arg(command.ascii());
+ return -1;
}
delete systemconfig;
+
+ return 0;
}
LDAPTDEBuiltinsInfo LDAPManager::parseLDAPTDEBuiltinsRecord(LDAPMessage* entry) {
@@ -2486,7 +2497,7 @@ int LDAPManager::writeSudoersConfFile(TQString *errstr) {
return 0;
}
-void LDAPManager::writeCronFiles() {
+int LDAPManager::writeClientCronFiles(TQString *errstr) {
TQFile file(CRON_UPDATE_NSS_FILE);
if (file.open(IO_WriteOnly)) {
TQTextStream stream( &file );
@@ -2501,9 +2512,11 @@ void LDAPManager::writeCronFiles() {
}
if (system(CRON_UPDATE_NSS_COMMAND) < 0) {
- printf("ERROR: Execution of \"%s\" failed!\n\r", CRON_UPDATE_NSS_COMMAND);
- return;
+ if (errstr) *errstr = TQString("Execution of \"%s\" failed").arg(CRON_UPDATE_NSS_COMMAND);
+ return -1;
}
+
+ return 0;
}
void LDAPManager::writePrimaryRealmCertificateUpdateCronFile() {
@@ -2565,7 +2578,7 @@ LDAPRealmConfigList LDAPManager::readTDERealmList(KSimpleConfig* config, bool di
return realms;
}
-void LDAPManager::writeTDERealmList(LDAPRealmConfigList realms, KSimpleConfig* config) {
+int LDAPManager::writeTDERealmList(LDAPRealmConfigList realms, KSimpleConfig* config, TQString *errstr) {
LDAPRealmConfigList::Iterator it;
for (it = realms.begin(); it != realms.end(); ++it) {
LDAPRealmConfig realmcfg = it.data();
@@ -2599,6 +2612,8 @@ void LDAPManager::writeTDERealmList(LDAPRealmConfigList realms, KSimpleConfig* c
}
}
}
+
+ return 0;
}
TQDateTime LDAPManager::getCertificateExpiration(TQString certfile) {
@@ -2744,7 +2759,170 @@ TQString LDAPManager::getMachineFQDN() {
return fqdn;
}
-int LDAPManager::bondRealm(LDAPRealmConfig realmcfg, TQString adminUserName, const char * adminPassword, TQString adminRealm, TQString *errstr) {
+LDAPClientRealmConfig LDAPManager::loadClientRealmConfig(KSimpleConfig* config, bool useDefaults) {
+ LDAPClientRealmConfig clientRealmConfig;
+
+ config->setReadDefaults(useDefaults);
+
+ config->setGroup(NULL);
+ clientRealmConfig.enable_bonding = config->readBoolEntry("EnableLDAP", false);
+ clientRealmConfig.defaultRealm = config->readEntry("DefaultRealm", TQString::null);
+ clientRealmConfig.ticketLifetime = config->readNumEntry("TicketLifetime", 86400);
+ clientRealmConfig.ldapRole = config->readEntry("LDAPRole", "Workstation");
+ if (LDAPManager::getMachineFQDN() == config->readEntry("HostFQDN", "")) {
+ clientRealmConfig.configurationVerifiedForLocalMachine = true;
+ }
+ else {
+ clientRealmConfig.configurationVerifiedForLocalMachine = false;
+ }
+
+ clientRealmConfig.ldapVersion = config->readNumEntry("ConnectionLDAPVersion", 3);
+ clientRealmConfig.ldapTimeout = config->readNumEntry("ConnectionLDAPTimeout", 2);
+ clientRealmConfig.bindPolicy = config->readEntry("ConnectionBindPolicy", "soft");
+ clientRealmConfig.ldapBindTimeout = config->readNumEntry("ConnectionBindTimeout", 2);
+ clientRealmConfig.passwordHash = config->readEntry("ConnectionPasswordHash", "exop");
+ clientRealmConfig.ignoredUsers = config->readEntry("ConnectionIgnoredUsers", DEFAULT_IGNORED_USERS_LIST);
+
+ return clientRealmConfig;
+}
+
+int LDAPManager::saveClientRealmConfig(LDAPClientRealmConfig clientRealmConfig, KSimpleConfig* config, TQString *errstr) {
+ config->setGroup(NULL);
+ config->writeEntry("EnableLDAP", clientRealmConfig.enable_bonding);
+ config->writeEntry("HostFQDN", clientRealmConfig.hostFQDN);
+
+ if (clientRealmConfig.defaultRealm != "") {
+ config->writeEntry("DefaultRealm", clientRealmConfig.defaultRealm);
+ }
+ else {
+ config->deleteEntry("DefaultRealm");
+ }
+ config->writeEntry("TicketLifetime", clientRealmConfig.ticketLifetime);
+
+ config->writeEntry("ConnectionLDAPVersion", clientRealmConfig.ldapVersion);
+ config->writeEntry("ConnectionLDAPTimeout", clientRealmConfig.ldapTimeout);
+ config->writeEntry("ConnectionBindPolicy", clientRealmConfig.bindPolicy);
+ config->writeEntry("ConnectionBindTimeout", clientRealmConfig.ldapBindTimeout);
+ config->writeEntry("ConnectionPasswordHash", clientRealmConfig.passwordHash);
+ config->writeEntry("ConnectionIgnoredUsers", clientRealmConfig.ignoredUsers);
+
+ return 0;
+}
+
+int LDAPManager::writeClientKrb5ConfFile(LDAPClientRealmConfig clientRealmConfig, LDAPRealmConfigList realmList, TQString *errstr) {
+ TQFile file(KRB5_FILE);
+ if (file.open(IO_WriteOnly)) {
+ TQTextStream stream( &file );
+
+ stream << "# This file was automatically generated by TDE\n";
+ stream << "# All changes will be lost!\n";
+ stream << "\n";
+
+ // Defaults
+ stream << "[libdefaults]\n";
+ stream << " ticket_lifetime = " << clientRealmConfig.ticketLifetime << "\n";
+ if (clientRealmConfig.defaultRealm != "") {
+ stream << " default_realm = " << clientRealmConfig.defaultRealm << "\n";
+ }
+ stream << "\n";
+
+ // Realms
+ stream << "[realms]\n";
+ LDAPRealmConfigList::Iterator it;
+ for (it = realmList.begin(); it != realmList.end(); ++it) {
+ LDAPRealmConfig realmcfg = it.data();
+ stream << " " << realmcfg.name << " = {\n";
+ stream << " kdc = " << realmcfg.kdc << ":" << realmcfg.kdc_port << "\n";
+ stream << " admin_server = " << realmcfg.admin_server << ":" << realmcfg.admin_server_port << "\n";
+ stream << " pkinit_require_eku = " << (realmcfg.pkinit_require_eku?"true":"false") << "\n";
+ stream << " pkinit_require_krbtgt_otherName = " << (realmcfg.pkinit_require_krbtgt_otherName?"true":"false") << "\n";
+ stream << " win2k_pkinit = " << (realmcfg.win2k_pkinit?"yes":"no") << "\n";
+ stream << " win2k_pkinit_require_binding = " << (realmcfg.win2k_pkinit_require_binding?"yes":"no") << "\n";
+ stream << " }\n";
+ }
+ stream << "\n";
+
+ // Domain aliases
+ stream << "[domain_realm]\n";
+ LDAPRealmConfigList::Iterator it2;
+ for (it2 = realmList.begin(); it2 != realmList.end(); ++it2) {
+ LDAPRealmConfig realmcfg = it2.data();
+ TQStringList domains = realmcfg.domain_mappings;
+ for (TQStringList::Iterator it3 = domains.begin(); it3 != domains.end(); ++it3 ) {
+ stream << " " << *it3 << " = " << realmcfg.name << "\n";
+ }
+ }
+
+ file.close();
+ }
+
+ return 0;
+}
+
+int LDAPManager::writeNSSwitchFile(TQString *errstr) {
+ TQFile file(NSSWITCH_FILE);
+ if (file.open(IO_WriteOnly)) {
+ TQTextStream stream( &file );
+
+ stream << "# This file was automatically generated by TDE\n";
+ stream << "# All changes will be lost!\n";
+ stream << "\n";
+ stream << "passwd: files ldap [NOTFOUND=return] db" << "\n";
+ stream << "group: files ldap [NOTFOUND=return] db" << "\n";
+ stream << "shadow: files ldap [NOTFOUND=return] db" << "\n";
+ stream << "\n";
+ stream << "hosts: files mdns4_minimal [NOTFOUND=return] dns mdns4" << "\n";
+ stream << "networks: files" << "\n";
+ stream << "\n";
+ stream << "protocols: db files" << "\n";
+ stream << "services: db files" << "\n";
+ stream << "ethers: db files" << "\n";
+ stream << "rpc: db files" << "\n";
+ stream << "\n";
+ stream << "netgroup: nis" << "\n";
+
+ file.close();
+ }
+
+ return 0;
+}
+
+int LDAPManager::writePAMFiles(TQString *errstr) {
+ TQFile file(PAMD_DIRECTORY PAMD_COMMON_ACCOUNT);
+ if (file.open(IO_WriteOnly)) {
+ TQTextStream stream( &file );
+
+ stream << "# This file was automatically generated by TDE\n";
+ stream << "# All changes will be lost!\n";
+ stream << "\n";
+ stream << "account sufficient pam_unix.so nullok_secure" << "\n";
+ stream << "account sufficient pam_ldap.so" << "\n";
+ stream << "account required pam_permit.so" << "\n";
+
+ file.close();
+ }
+
+ TQFile file2(PAMD_DIRECTORY PAMD_COMMON_AUTH);
+ if (file2.open(IO_WriteOnly)) {
+ TQTextStream stream( &file2 );
+
+ stream << "# This file was automatically generated by TDE\n";
+ stream << "# All changes will be lost!\n";
+ stream << "\n";
+ stream << "auth [default=ignore success=ignore] pam_mount.so" << "\n";
+ stream << "auth sufficient pam_unix.so nullok try_first_pass" << "\n";
+ stream << "auth [default=ignore success=1 service_err=reset] pam_krb5.so ccache=/tmp/krb5cc_%u use_first_pass" << "\n";
+ stream << "auth [default=die success=done] pam_ccreds.so action=validate use_first_pass" << "\n";
+ stream << "auth sufficient pam_ccreds.so action=store use_first_pass" << "\n";
+ stream << "auth required pam_deny.so" << "\n";
+
+ file2.close();
+ }
+
+ return 0;
+}
+
+int LDAPManager::bondRealm(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());
@@ -2778,6 +2956,10 @@ int LDAPManager::bondRealm(LDAPRealmConfig realmcfg, TQString adminUserName, con
return 1;
}
else if (prompt.endsWith("Principal does not exist")) {
+ do { // Wait for command prompt
+ prompt = readFullLineFromPtyProcess(&kadminProc);
+ printf("(kadmin) '%s'\n\r", prompt.ascii());
+ } while (prompt == "");
command = TQCString("ank --random-key "+hoststring);
kadminProc.writeLine(command, true);
do { // Discard our own input
@@ -2834,14 +3016,12 @@ int LDAPManager::bondRealm(LDAPRealmConfig realmcfg, TQString adminUserName, con
// Success!
kadminProc.writeLine("quit", true);
- realmcfg.bonded = true;
return 0;
}
else if (prompt == "kadmin>") {
// Success!
kadminProc.writeLine("quit", true);
- realmcfg.bonded = true;
return 0;
}
@@ -2898,7 +3078,7 @@ int LDAPManager::unbondRealm(LDAPRealmConfig realmcfg, TQString adminUserName, c
kadminProc.writeLine("quit", true);
// Delete keys from keytab
- command = TQString("ktutil remove -p %1").arg(hostprinc);
+ command = TQString("ktutil remove -p %1").arg(hoststring+"@"+adminRealm.upper());
if (system(command) < 0) {
printf("ERROR: Execution of \"%s\" failed!\n\r", command.data());
return 1; // Failure