Fix potential kadmin failures

Export static kadmin process read method
pull/1/head
Timothy Pearson 12 years ago
parent 5ac43b8c56
commit 98058c6c16

@ -40,6 +40,7 @@
#include <ldap.h> #include <ldap.h>
#include <stdlib.h> #include <stdlib.h>
#include <sys/time.h> #include <sys/time.h>
#include <errno.h>
#include "libtdeldap.h" #include "libtdeldap.h"
#include "ldaplogindlg.h" #include "ldaplogindlg.h"
@ -69,6 +70,16 @@ enum ErrorCauseLocation {
ERRORCAUSE_LOCATION_BIND = 0 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) 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()); TQStringList domainChunks = TQStringList::split(".", realm.lower());
@ -85,6 +96,13 @@ LDAPManager::~LDAPManager() {
unbind(true); 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) { TQString LDAPManager::ldapdnForRealm(TQString realm) {
TQStringList domainChunks = TQStringList::split(".", realm.lower()); TQStringList domainChunks = TQStringList::split(".", realm.lower());
TQString basedc = "dc=" + domainChunks.join(",dc="); 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" // 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 // 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) // (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 = ""; TQString result = "";
while ((!result.contains("\r")) && while ((!result.contains("\r")) &&
(!result.contains(">")) && (!result.contains(">")) &&
@ -897,6 +915,7 @@ int LDAPManager::setPasswordForUser(LDAPUserInfo user, TQString *errstr) {
prompt = prompt.stripWhiteSpace(); prompt = prompt.stripWhiteSpace();
if (prompt == "kadmin>") { if (prompt == "kadmin>") {
command = TQCString("passwd "+user.name); command = TQCString("passwd "+user.name);
kadminProc.enableLocalEcho(false);
kadminProc.writeLine(command, true); kadminProc.writeLine(command, true);
do { // Discard our own input do { // Discard our own input
prompt = readFullLineFromPtyProcess(&kadminProc); prompt = readFullLineFromPtyProcess(&kadminProc);
@ -904,6 +923,7 @@ int LDAPManager::setPasswordForUser(LDAPUserInfo user, TQString *errstr) {
} while (prompt == TQString(command)); } while (prompt == TQString(command));
prompt = prompt.stripWhiteSpace(); prompt = prompt.stripWhiteSpace();
if ((prompt.endsWith(" Password:")) && (prompt.startsWith(TQString(user.name + "@")))) { if ((prompt.endsWith(" Password:")) && (prompt.startsWith(TQString(user.name + "@")))) {
kadminProc.enableLocalEcho(false);
kadminProc.writeLine(user.new_password, true); kadminProc.writeLine(user.new_password, true);
do { // Discard our own input do { // Discard our own input
prompt = readFullLineFromPtyProcess(&kadminProc); prompt = readFullLineFromPtyProcess(&kadminProc);
@ -911,6 +931,7 @@ int LDAPManager::setPasswordForUser(LDAPUserInfo user, TQString *errstr) {
} while (prompt == ""); } while (prompt == "");
prompt = prompt.stripWhiteSpace(); prompt = prompt.stripWhiteSpace();
if ((prompt.endsWith(" Password:")) && (prompt.startsWith("Verify"))) { if ((prompt.endsWith(" Password:")) && (prompt.startsWith("Verify"))) {
kadminProc.enableLocalEcho(false);
kadminProc.writeLine(user.new_password, true); kadminProc.writeLine(user.new_password, true);
do { // Discard our own input do { // Discard our own input
prompt = readFullLineFromPtyProcess(&kadminProc); prompt = readFullLineFromPtyProcess(&kadminProc);
@ -927,6 +948,7 @@ int LDAPManager::setPasswordForUser(LDAPUserInfo user, TQString *errstr) {
} }
} }
if (admincreds.password != "") { if (admincreds.password != "") {
kadminProc.enableLocalEcho(false);
kadminProc.writeLine(admincreds.password, true); kadminProc.writeLine(admincreds.password, true);
do { // Discard our own input do { // Discard our own input
prompt = readFullLineFromPtyProcess(&kadminProc); prompt = readFullLineFromPtyProcess(&kadminProc);
@ -936,23 +958,27 @@ int LDAPManager::setPasswordForUser(LDAPUserInfo user, TQString *errstr) {
} }
} }
if (prompt != "kadmin>") { if (prompt != "kadmin>") {
if (errstr) *errstr = prompt; if (errstr) *errstr = detailedKAdminErrorMessage(prompt);
kadminProc.enableLocalEcho(false);
kadminProc.writeLine("quit", true); kadminProc.writeLine("quit", true);
return 1; return 1;
} }
// Success! // Success!
kadminProc.enableLocalEcho(false);
kadminProc.writeLine("quit", true); kadminProc.writeLine("quit", true);
return 0; return 0;
} }
else if (prompt == "kadmin>") { else if (prompt == "kadmin>") {
// Success! // Success!
kadminProc.enableLocalEcho(false);
kadminProc.writeLine("quit", true); kadminProc.writeLine("quit", true);
return 0; return 0;
} }
// Failure // Failure
if (errstr) *errstr = prompt; if (errstr) *errstr = detailedKAdminErrorMessage(prompt);
kadminProc.enableLocalEcho(false);
kadminProc.writeLine("quit", true); kadminProc.writeLine("quit", true);
return 1; return 1;
} }
@ -1243,6 +1269,7 @@ int LDAPManager::obtainKerberosTicket(LDAPCredentials creds, TQString principal,
prompt = readFullLineFromPtyProcess(&kadminProc); prompt = readFullLineFromPtyProcess(&kadminProc);
prompt = prompt.stripWhiteSpace(); prompt = prompt.stripWhiteSpace();
if (prompt.endsWith(" Password:")) { if (prompt.endsWith(" Password:")) {
kadminProc.enableLocalEcho(false);
kadminProc.writeLine(creds.password, true); kadminProc.writeLine(creds.password, true);
do { // Discard our own input do { // Discard our own input
prompt = readFullLineFromPtyProcess(&kadminProc); prompt = readFullLineFromPtyProcess(&kadminProc);
@ -1251,7 +1278,7 @@ int LDAPManager::obtainKerberosTicket(LDAPCredentials creds, TQString principal,
prompt = prompt.stripWhiteSpace(); prompt = prompt.stripWhiteSpace();
} }
if ((prompt != "") && (prompt != "TDE process terminated")) { if ((prompt != "") && (prompt != "TDE process terminated")) {
if (errstr) *errstr = prompt; if (errstr) *errstr = detailedKAdminErrorMessage(prompt);
return 1; return 1;
} }
@ -1271,7 +1298,7 @@ int LDAPManager::obtainKerberosServiceTicket(TQString principal, TQString *errst
pclose(output); pclose(output);
if (ret != "") { if (ret != "") {
if (errstr) *errstr = ret; if (errstr) *errstr = detailedKAdminErrorMessage(ret);
return -1; return -1;
} }
return 0; return 0;
@ -1289,7 +1316,7 @@ int LDAPManager::destroyKerberosTicket(TQString principal, TQString *errstr) {
pclose(output); pclose(output);
if (ret != "") { if (ret != "") {
if (errstr) *errstr = ret; if (errstr) *errstr = detailedKAdminErrorMessage(ret);
return -1; return -1;
} }
return 0; return 0;
@ -1543,6 +1570,7 @@ int LDAPManager::addServiceInfo(LDAPServiceInfo service, TQString *errstr) {
prompt = prompt.stripWhiteSpace(); prompt = prompt.stripWhiteSpace();
if (prompt == "kadmin>") { if (prompt == "kadmin>") {
command = TQCString("ank --random-key "+hoststring); command = TQCString("ank --random-key "+hoststring);
kadminProc.enableLocalEcho(false);
kadminProc.writeLine(command, true); kadminProc.writeLine(command, true);
do { // Discard our own input do { // Discard our own input
prompt = readFullLineFromPtyProcess(&kadminProc); prompt = readFullLineFromPtyProcess(&kadminProc);
@ -1560,6 +1588,7 @@ int LDAPManager::addServiceInfo(LDAPServiceInfo service, TQString *errstr) {
} }
} }
if (admincreds.password != "") { if (admincreds.password != "") {
kadminProc.enableLocalEcho(false);
kadminProc.writeLine(admincreds.password, true); kadminProc.writeLine(admincreds.password, true);
do { // Discard our own input do { // Discard our own input
prompt = readFullLineFromPtyProcess(&kadminProc); prompt = readFullLineFromPtyProcess(&kadminProc);
@ -1569,7 +1598,8 @@ int LDAPManager::addServiceInfo(LDAPServiceInfo service, TQString *errstr) {
} }
} }
if (prompt.contains("authentication failed")) { if (prompt.contains("authentication failed")) {
if (errstr) *errstr = prompt; if (errstr) *errstr = detailedKAdminErrorMessage(prompt);
kadminProc.enableLocalEcho(false);
kadminProc.writeLine("quit", true); kadminProc.writeLine("quit", true);
return 1; return 1;
} }
@ -1583,6 +1613,7 @@ int LDAPManager::addServiceInfo(LDAPServiceInfo service, TQString *errstr) {
defaultParam = prompt.mid(leftbracket, rightbracket-leftbracket); defaultParam = prompt.mid(leftbracket, rightbracket-leftbracket);
} }
command = TQCString(defaultParam); command = TQCString(defaultParam);
kadminProc.enableLocalEcho(false);
kadminProc.writeLine(command, true); kadminProc.writeLine(command, true);
do { // Discard our own input do { // Discard our own input
prompt = readFullLineFromPtyProcess(&kadminProc); prompt = readFullLineFromPtyProcess(&kadminProc);
@ -1592,12 +1623,14 @@ int LDAPManager::addServiceInfo(LDAPServiceInfo service, TQString *errstr) {
} }
} }
if (prompt != "kadmin>") { if (prompt != "kadmin>") {
if (errstr) *errstr = prompt; if (errstr) *errstr = detailedKAdminErrorMessage(prompt);
kadminProc.enableLocalEcho(false);
kadminProc.writeLine("quit", true); kadminProc.writeLine("quit", true);
return 1; return 1;
} }
// Success! // Success!
kadminProc.enableLocalEcho(false);
kadminProc.writeLine("quit", true); kadminProc.writeLine("quit", true);
unbind(true); // Using kadmin can disrupt our LDAP connection 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 // Create symbolic link to secondary LDAP configuration file
if (unlink(LDAP_SECONDARY_FILE) < 0) { if (fileExists(LDAP_SECONDARY_FILE)) {
printf("ERROR: Unable to unlink \"%s\"\n\r", LDAP_SECONDARY_FILE); if (unlink(LDAP_SECONDARY_FILE) < 0) {
return; 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); command = TQString("ln -s %1 %2").arg(LDAP_FILE).arg(LDAP_SECONDARY_FILE);
if (system(command) < 0) { if (system(command) < 0) {
@ -2154,9 +2189,11 @@ void LDAPManager::writeLDAPConfFile(LDAPRealmConfig realmcfg) {
} }
// Create symbolic link to tertiary LDAP configuration file // Create symbolic link to tertiary LDAP configuration file
if (unlink(LDAP_TERTIARY_FILE) < 0) { if (fileExists(LDAP_TERTIARY_FILE)) {
printf("ERROR: Unable to unlink \"%s\"\n\r", LDAP_TERTIARY_FILE); if (unlink(LDAP_TERTIARY_FILE) < 0) {
return; 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); command = TQString("ln -s %1 %2").arg(LDAP_FILE).arg(LDAP_TERTIARY_FILE);
if (system(command) < 0) { 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()); printf("ERROR: Unable to change owner of \"%s\"\n\r", kdc_certfile.ascii());
return -1; return -1;
} }
if (unlink(kdc_reqfile.ascii()) < 0) { if (fileExists(kdc_reqfile.ascii())) {
printf("ERROR: Unable to unlink \"%s\"\n\r", kdc_reqfile.ascii()); if (unlink(kdc_reqfile.ascii()) < 0) {
return -1; printf("ERROR: Unable to unlink \"%s\"\n\r", kdc_reqfile.ascii());
return -1;
}
} }
return 0; 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()); printf("ERROR: Unable to change owner of \"%s\"\n\r", ldap_certfile.ascii());
return -1; return -1;
} }
if (unlink(ldap_reqfile.ascii()) < 0) { if (fileExists(ldap_reqfile.ascii())) {
printf("ERROR: Unable to unlink \"%s\"\n\r", ldap_reqfile.ascii()); if (unlink(ldap_reqfile.ascii()) < 0) {
return -1; printf("ERROR: Unable to unlink \"%s\"\n\r", ldap_reqfile.ascii());
return -1;
}
} }
return 0; return 0;

@ -361,6 +361,8 @@ typedef TQValueList<LDAPMachineInfo> LDAPMachineInfoList;
typedef TQValueList<LDAPServiceInfo> LDAPServiceInfoList; typedef TQValueList<LDAPServiceInfo> LDAPServiceInfoList;
typedef TQValueList<KerberosTicketInfo> KerberosTicketInfoList; typedef TQValueList<KerberosTicketInfo> KerberosTicketInfoList;
class PtyProcess;
class LDAPManager : public TQObject { class LDAPManager : public TQObject {
Q_OBJECT Q_OBJECT
@ -421,6 +423,9 @@ class LDAPManager : public TQObject {
static int obtainKerberosServiceTicket(TQString principal, TQString *errstr=0); static int obtainKerberosServiceTicket(TQString principal, TQString *errstr=0);
static int destroyKerberosTicket(TQString principal, TQString *errstr=0); static int destroyKerberosTicket(TQString principal, TQString *errstr=0);
static TQString detailedKAdminErrorMessage(TQString initialMessage);
static TQString readFullLineFromPtyProcess(PtyProcess* proc);
private: private:
LDAPUserInfo parseLDAPUserRecord(LDAPMessage* entry); LDAPUserInfo parseLDAPUserRecord(LDAPMessage* entry);
LDAPGroupInfo parseLDAPGroupRecord(LDAPMessage* entry); LDAPGroupInfo parseLDAPGroupRecord(LDAPMessage* entry);

Loading…
Cancel
Save