summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTimothy Pearson <kb9vqf@pearsoncomputing.net>2013-01-15 19:35:55 -0600
committerTimothy Pearson <kb9vqf@pearsoncomputing.net>2013-01-15 19:35:55 -0600
commit98058c6c16819a360d4a74c7375b40766d798fb6 (patch)
treef12bc71292bc14f53528f21d24da7944eb805109
parent5ac43b8c561ec81617a50c14c0a068b6d137dab9 (diff)
downloadlibtdeldap-98058c6c.tar.gz
libtdeldap-98058c6c.zip
Fix potential kadmin failures
Export static kadmin process read method
-rw-r--r--src/libtdeldap.cpp81
-rw-r--r--src/libtdeldap.h5
2 files changed, 66 insertions, 20 deletions
diff --git a/src/libtdeldap.cpp b/src/libtdeldap.cpp
index 415a5a7..5c79891 100644
--- a/src/libtdeldap.cpp
+++ b/src/libtdeldap.cpp
@@ -40,6 +40,7 @@
#include <ldap.h>
#include <stdlib.h>
#include <sys/time.h>
+#include <errno.h>
#include "libtdeldap.h"
#include "ldaplogindlg.h"
@@ -69,6 +70,16 @@ enum ErrorCauseLocation {
ERRORCAUSE_LOCATION_BIND = 0
};
+bool fileExists(const char* filename) {
+ struct stat sts;
+ if (stat(filename, &sts) == -1 && errno == ENOENT) {
+ return false;
+ }
+ else {
+ return true;
+ }
+}
+
LDAPManager::LDAPManager(TQString realm, TQString host, TQObject *parent, const char *name) : TQObject(parent, name), m_realm(realm), m_host(host), m_port(0), m_creds(0), m_ldap(0)
{
TQStringList domainChunks = TQStringList::split(".", realm.lower());
@@ -85,6 +96,13 @@ LDAPManager::~LDAPManager() {
unbind(true);
}
+TQString LDAPManager::detailedKAdminErrorMessage(TQString initialMessage) {
+ if (initialMessage.contains("Looping detected inside krb5_get_in_tkt")) {
+ initialMessage.append("<p>").append(i18n("Potential causes")).append(":<br>").append(i18n(" * Invalid credentials")).append("<br>").append(i18n(" * Clock skew between the realm's KDC and this machine")).append("<br>").append(i18n(" * Inability to negotiate a compatible encryption type with the realm's KDC")).append("<br>").append(i18n(" * No connectivity to the realm's KDC"));
+ }
+ return initialMessage;
+}
+
TQString LDAPManager::ldapdnForRealm(TQString realm) {
TQStringList domainChunks = TQStringList::split(".", realm.lower());
TQString basedc = "dc=" + domainChunks.join(",dc=");
@@ -838,7 +856,7 @@ int LDAPManager::updateUserInfo(LDAPUserInfo user) {
// To make matters worse, the colon does not uniquely designate the end of a line; for example the response "kadmin: ext openldap/foo.bar.baz: Principal does not exist"
// One way around this would be to see if the first colon is part of a "kadmin:" string; if so, then the colon is not a reliable end of line indicator for the current line
// (in fact only '\r' should be used as the end of line indicator in that case)
-TQString readFullLineFromPtyProcess(PtyProcess* proc) {
+TQString LDAPManager::readFullLineFromPtyProcess(PtyProcess* proc) {
TQString result = "";
while ((!result.contains("\r")) &&
(!result.contains(">")) &&
@@ -897,6 +915,7 @@ int LDAPManager::setPasswordForUser(LDAPUserInfo user, TQString *errstr) {
prompt = prompt.stripWhiteSpace();
if (prompt == "kadmin>") {
command = TQCString("passwd "+user.name);
+ kadminProc.enableLocalEcho(false);
kadminProc.writeLine(command, true);
do { // Discard our own input
prompt = readFullLineFromPtyProcess(&kadminProc);
@@ -904,6 +923,7 @@ int LDAPManager::setPasswordForUser(LDAPUserInfo user, TQString *errstr) {
} while (prompt == TQString(command));
prompt = prompt.stripWhiteSpace();
if ((prompt.endsWith(" Password:")) && (prompt.startsWith(TQString(user.name + "@")))) {
+ kadminProc.enableLocalEcho(false);
kadminProc.writeLine(user.new_password, true);
do { // Discard our own input
prompt = readFullLineFromPtyProcess(&kadminProc);
@@ -911,6 +931,7 @@ int LDAPManager::setPasswordForUser(LDAPUserInfo user, TQString *errstr) {
} while (prompt == "");
prompt = prompt.stripWhiteSpace();
if ((prompt.endsWith(" Password:")) && (prompt.startsWith("Verify"))) {
+ kadminProc.enableLocalEcho(false);
kadminProc.writeLine(user.new_password, true);
do { // Discard our own input
prompt = readFullLineFromPtyProcess(&kadminProc);
@@ -927,6 +948,7 @@ int LDAPManager::setPasswordForUser(LDAPUserInfo user, TQString *errstr) {
}
}
if (admincreds.password != "") {
+ kadminProc.enableLocalEcho(false);
kadminProc.writeLine(admincreds.password, true);
do { // Discard our own input
prompt = readFullLineFromPtyProcess(&kadminProc);
@@ -936,23 +958,27 @@ int LDAPManager::setPasswordForUser(LDAPUserInfo user, TQString *errstr) {
}
}
if (prompt != "kadmin>") {
- if (errstr) *errstr = prompt;
+ if (errstr) *errstr = 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 = prompt;
+ if (errstr) *errstr = detailedKAdminErrorMessage(prompt);
+ kadminProc.enableLocalEcho(false);
kadminProc.writeLine("quit", true);
return 1;
}
@@ -1243,6 +1269,7 @@ int LDAPManager::obtainKerberosTicket(LDAPCredentials creds, TQString principal,
prompt = readFullLineFromPtyProcess(&kadminProc);
prompt = prompt.stripWhiteSpace();
if (prompt.endsWith(" Password:")) {
+ kadminProc.enableLocalEcho(false);
kadminProc.writeLine(creds.password, true);
do { // Discard our own input
prompt = readFullLineFromPtyProcess(&kadminProc);
@@ -1251,7 +1278,7 @@ int LDAPManager::obtainKerberosTicket(LDAPCredentials creds, TQString principal,
prompt = prompt.stripWhiteSpace();
}
if ((prompt != "") && (prompt != "TDE process terminated")) {
- if (errstr) *errstr = prompt;
+ if (errstr) *errstr = detailedKAdminErrorMessage(prompt);
return 1;
}
@@ -1271,7 +1298,7 @@ int LDAPManager::obtainKerberosServiceTicket(TQString principal, TQString *errst
pclose(output);
if (ret != "") {
- if (errstr) *errstr = ret;
+ if (errstr) *errstr = detailedKAdminErrorMessage(ret);
return -1;
}
return 0;
@@ -1289,7 +1316,7 @@ int LDAPManager::destroyKerberosTicket(TQString principal, TQString *errstr) {
pclose(output);
if (ret != "") {
- if (errstr) *errstr = ret;
+ if (errstr) *errstr = detailedKAdminErrorMessage(ret);
return -1;
}
return 0;
@@ -1543,6 +1570,7 @@ int LDAPManager::addServiceInfo(LDAPServiceInfo service, TQString *errstr) {
prompt = prompt.stripWhiteSpace();
if (prompt == "kadmin>") {
command = TQCString("ank --random-key "+hoststring);
+ kadminProc.enableLocalEcho(false);
kadminProc.writeLine(command, true);
do { // Discard our own input
prompt = readFullLineFromPtyProcess(&kadminProc);
@@ -1560,6 +1588,7 @@ int LDAPManager::addServiceInfo(LDAPServiceInfo service, TQString *errstr) {
}
}
if (admincreds.password != "") {
+ kadminProc.enableLocalEcho(false);
kadminProc.writeLine(admincreds.password, true);
do { // Discard our own input
prompt = readFullLineFromPtyProcess(&kadminProc);
@@ -1569,7 +1598,8 @@ int LDAPManager::addServiceInfo(LDAPServiceInfo service, TQString *errstr) {
}
}
if (prompt.contains("authentication failed")) {
- if (errstr) *errstr = prompt;
+ if (errstr) *errstr = detailedKAdminErrorMessage(prompt);
+ kadminProc.enableLocalEcho(false);
kadminProc.writeLine("quit", true);
return 1;
}
@@ -1583,6 +1613,7 @@ int LDAPManager::addServiceInfo(LDAPServiceInfo service, TQString *errstr) {
defaultParam = prompt.mid(leftbracket, rightbracket-leftbracket);
}
command = TQCString(defaultParam);
+ kadminProc.enableLocalEcho(false);
kadminProc.writeLine(command, true);
do { // Discard our own input
prompt = readFullLineFromPtyProcess(&kadminProc);
@@ -1592,12 +1623,14 @@ int LDAPManager::addServiceInfo(LDAPServiceInfo service, TQString *errstr) {
}
}
if (prompt != "kadmin>") {
- if (errstr) *errstr = prompt;
+ if (errstr) *errstr = detailedKAdminErrorMessage(prompt);
+ kadminProc.enableLocalEcho(false);
kadminProc.writeLine("quit", true);
return 1;
}
// Success!
+ kadminProc.enableLocalEcho(false);
kadminProc.writeLine("quit", true);
unbind(true); // Using kadmin can disrupt our LDAP connection
@@ -2143,9 +2176,11 @@ void LDAPManager::writeLDAPConfFile(LDAPRealmConfig realmcfg) {
}
// Create symbolic link to secondary LDAP configuration file
- if (unlink(LDAP_SECONDARY_FILE) < 0) {
- printf("ERROR: Unable to unlink \"%s\"\n\r", LDAP_SECONDARY_FILE);
- return;
+ if (fileExists(LDAP_SECONDARY_FILE)) {
+ if (unlink(LDAP_SECONDARY_FILE) < 0) {
+ printf("ERROR: Unable to unlink \"%s\"\n\r", LDAP_SECONDARY_FILE);
+ return;
+ }
}
command = TQString("ln -s %1 %2").arg(LDAP_FILE).arg(LDAP_SECONDARY_FILE);
if (system(command) < 0) {
@@ -2154,9 +2189,11 @@ void LDAPManager::writeLDAPConfFile(LDAPRealmConfig realmcfg) {
}
// Create symbolic link to tertiary LDAP configuration file
- if (unlink(LDAP_TERTIARY_FILE) < 0) {
- printf("ERROR: Unable to unlink \"%s\"\n\r", LDAP_TERTIARY_FILE);
- return;
+ if (fileExists(LDAP_TERTIARY_FILE)) {
+ if (unlink(LDAP_TERTIARY_FILE) < 0) {
+ printf("ERROR: Unable to unlink \"%s\"\n\r", LDAP_TERTIARY_FILE);
+ return;
+ }
}
command = TQString("ln -s %1 %2").arg(LDAP_FILE).arg(LDAP_TERTIARY_FILE);
if (system(command) < 0) {
@@ -2529,9 +2566,11 @@ int LDAPManager::generatePublicKerberosCertificate(LDAPCertConfig certinfo, LDAP
printf("ERROR: Unable to change owner of \"%s\"\n\r", kdc_certfile.ascii());
return -1;
}
- if (unlink(kdc_reqfile.ascii()) < 0) {
- printf("ERROR: Unable to unlink \"%s\"\n\r", kdc_reqfile.ascii());
- return -1;
+ if (fileExists(kdc_reqfile.ascii())) {
+ if (unlink(kdc_reqfile.ascii()) < 0) {
+ printf("ERROR: Unable to unlink \"%s\"\n\r", kdc_reqfile.ascii());
+ return -1;
+ }
}
return 0;
@@ -2565,9 +2604,11 @@ int LDAPManager::generatePublicLDAPCertificate(LDAPCertConfig certinfo, LDAPReal
printf("ERROR: Unable to change owner of \"%s\"\n\r", ldap_certfile.ascii());
return -1;
}
- if (unlink(ldap_reqfile.ascii()) < 0) {
- printf("ERROR: Unable to unlink \"%s\"\n\r", ldap_reqfile.ascii());
- return -1;
+ if (fileExists(ldap_reqfile.ascii())) {
+ if (unlink(ldap_reqfile.ascii()) < 0) {
+ printf("ERROR: Unable to unlink \"%s\"\n\r", ldap_reqfile.ascii());
+ return -1;
+ }
}
return 0;
diff --git a/src/libtdeldap.h b/src/libtdeldap.h
index 341dff9..1bad94d 100644
--- a/src/libtdeldap.h
+++ b/src/libtdeldap.h
@@ -361,6 +361,8 @@ typedef TQValueList<LDAPMachineInfo> LDAPMachineInfoList;
typedef TQValueList<LDAPServiceInfo> LDAPServiceInfoList;
typedef TQValueList<KerberosTicketInfo> KerberosTicketInfoList;
+class PtyProcess;
+
class LDAPManager : public TQObject {
Q_OBJECT
@@ -421,6 +423,9 @@ class LDAPManager : public TQObject {
static int obtainKerberosServiceTicket(TQString principal, TQString *errstr=0);
static int destroyKerberosTicket(TQString principal, TQString *errstr=0);
+ static TQString detailedKAdminErrorMessage(TQString initialMessage);
+ static TQString readFullLineFromPtyProcess(PtyProcess* proc);
+
private:
LDAPUserInfo parseLDAPUserRecord(LDAPMessage* entry);
LDAPGroupInfo parseLDAPGroupRecord(LDAPMessage* entry);