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 <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;

@ -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);

Loading…
Cancel
Save