summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTimothy Pearson <kb9vqf@pearsoncomputing.net>2015-09-29 02:08:05 -0500
committerTimothy Pearson <kb9vqf@pearsoncomputing.net>2015-09-29 02:08:05 -0500
commitc70ce69a08815fb4da81b2a85fc4a2a10d469cab (patch)
tree01fd7fc2f2d0b25001f6a096d2c3659e03859d16
parent11869fce63bd934f43125e0f826cc667eee54f68 (diff)
downloadlibtdeldap-c70ce69a.tar.gz
libtdeldap-c70ce69a.zip
Convert the last methods using the kadmin utility to the Heimdal C API
-rw-r--r--src/libtdeldap.cpp197
-rw-r--r--src/libtdeldap.h2
2 files changed, 131 insertions, 68 deletions
diff --git a/src/libtdeldap.cpp b/src/libtdeldap.cpp
index 19812d5..690cee9 100644
--- a/src/libtdeldap.cpp
+++ b/src/libtdeldap.cpp
@@ -1111,17 +1111,14 @@ int LDAPManager::updateUserInfo(LDAPUserInfo user, TQString *errstr) {
}
}
-// WARNING
-// kadmin does not have a standard "waiting for user input" character or sequence
-// 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)
+// FIXME
+// Convert anything relying on this method to the Heimdal C API
TQString LDAPManager::readFullLineFromPtyProcess(PtyProcess* proc) {
TQString result = "";
while ((!result.contains("\r")) &&
(!result.contains(">")) &&
- (!((!result.contains("kadmin:")) && (!result.contains("kinit:")) && (!result.contains("ktutil:")) && result.contains(":"))) &&
- (!((result.contains("kadmin:")) && (!result.contains("kinit:")) && (!result.contains("ktutil:")) && result.contains("\r")))
+ (!((!result.contains("kinit:")) && (!result.contains("ktutil:")) && result.contains(":"))) &&
+ (!((!result.contains("kinit:")) && (!result.contains("ktutil:")) && result.contains("\r")))
) {
result = result + TQString(proc->readLine(false));
tqApp->processEvents();
@@ -1307,7 +1304,7 @@ int LDAPManager::setPasswordForUser(LDAPUserInfo user, TQString *errstr) {
}
if (retcode == 0) {
retcode = 1;
- krb5_principal user_kadm5_principal;
+ krb5_principal user_kadm5_principal = NULL;
krb5adm_ret = krb5_parse_name(m_krb5admContext, user.name.ascii(), &user_kadm5_principal);
if (krb5adm_ret) {
if (errstr) *errstr = i18n("%1<p>Details:<br>Failed to execute krb5_parse_name for user '%2' (code %3)").arg(krb5_get_error_message(m_krb5admContext, krb5adm_ret)).arg(user.name).arg(krb5adm_ret);
@@ -1622,15 +1619,15 @@ int LDAPManager::obtainKerberosTicket(LDAPCredentials creds, TQString principal,
}
TQString prompt;
- PtyProcess kadminProc;
- kadminProc.exec(command, args);
- prompt = readFullLineFromPtyProcess(&kadminProc);
+ PtyProcess kinitProc;
+ kinitProc.exec(command, args);
+ prompt = readFullLineFromPtyProcess(&kinitProc);
prompt = prompt.stripWhiteSpace();
if (prompt.endsWith(" Password:")) {
- kadminProc.enableLocalEcho(false);
- kadminProc.writeLine(creds.password, true);
+ kinitProc.enableLocalEcho(false);
+ kinitProc.writeLine(creds.password, true);
do { // Discard our own input
- prompt = readFullLineFromPtyProcess(&kadminProc);
+ prompt = readFullLineFromPtyProcess(&kinitProc);
printf("(kinit) '%s'\n", prompt.ascii());
} while (prompt == "");
prompt = prompt.stripWhiteSpace();
@@ -2005,6 +2002,48 @@ int LDAPManager::kAdminAddNewPrincipal(TQString principalName, TQString newPassw
return retcode;
}
+int LDAPManager::kAdminDeletePrincipal(TQString principalName, TQString *errstr) {
+ int retcode;
+ kadm5_ret_t krb5adm_ret;
+
+ bool kadmin_unbind_needed = false;
+ if (m_krb5admHandle) {
+ retcode = 0;
+ }
+ else {
+ retcode = bindKAdmin(NULL, errstr);
+ kadmin_unbind_needed = true;
+ }
+ if (retcode == 0) {
+ retcode = 1;
+ krb5_principal principal_entry = NULL;
+ krb5adm_ret = krb5_parse_name(m_krb5admContext, principalName.ascii(), &principal_entry);
+ if (krb5adm_ret) {
+ if (errstr) *errstr = i18n("%1<p>Details:<br>Failed to execute krb5_parse_name for principal '%2' (code %3)").arg(krb5_get_error_message(m_krb5admContext, krb5adm_ret)).arg(principalName).arg(krb5adm_ret);
+ }
+ else {
+ krb5adm_ret = kadm5_delete_principal(m_krb5admHandle, principal_entry);
+ if (krb5adm_ret) {
+ if (errstr) *errstr = i18n("%1<p>Details:<br>Failed to execute kadm5_delete_principal for principal '%2' (code %3)").arg(krb5_get_error_message(m_krb5admContext, krb5adm_ret)).arg(principalName).arg(krb5adm_ret);
+ }
+ else {
+ // Success!
+ retcode = 0;
+ }
+
+ // Clean up
+ krb5_free_principal(m_krb5admContext, principal_entry);
+ }
+
+ if (kadmin_unbind_needed) {
+ unbindKAdmin();
+ unbind(true); // Using kadmin can disrupt our LDAP connection
+ }
+ }
+
+ return retcode;
+}
+
int LDAPManager::addMachineInfo(LDAPMachineInfo machine, TQString *errstr) {
LDAPCredentials admincreds = currentLDAPCredentials(true);
TQString hoststring = "host/" + machine.name + "." + admincreds.realm.lower();
@@ -2704,6 +2743,65 @@ int LDAPManager::exportKeytabForPrincipal(TQString principal, TQString fileName,
return retcode;
}
+int LDAPManager::deleteKeytabEntriesForPrincipal(TQString principal, TQString fileName, TQString *errstr) {
+ int retcode;
+ kadm5_ret_t krb5adm_ret;
+
+ bool kadmin_unbind_needed = false;
+ if (m_krb5admHandle) {
+ retcode = 0;
+ }
+ else {
+ retcode = bindKAdmin(NULL, errstr);
+ kadmin_unbind_needed = true;
+ }
+ if (retcode == 0) {
+ retcode = 1;
+
+ krb5_keytab keytab;
+ if (fileName == "") {
+ krb5adm_ret = krb5_kt_default(m_krb5admContext, &keytab);
+ }
+ else {
+ krb5adm_ret = krb5_kt_resolve(m_krb5admContext, fileName.ascii(), &keytab);
+ }
+ if (krb5adm_ret) {
+ if (errstr) *errstr = i18n("%1<p>Details:<br>Failed to open keytab file '%2' (code %3)").arg(krb5_get_error_message(m_krb5admContext, krb5adm_ret)).arg(fileName).arg(krb5adm_ret);
+ }
+ else {
+ krb5_principal principal_entry = NULL;
+
+ krb5adm_ret = krb5_parse_name(m_krb5admContext, principal.ascii(), &principal_entry);
+ if (krb5adm_ret) {
+ if (errstr) *errstr = i18n("%1<p>Details:<br>Failed to execute krb5_parse_name (code %2)").arg(krb5_get_error_message(m_krb5admContext, krb5adm_ret)).arg(krb5adm_ret);
+ }
+ else {
+ krb5_keytab_entry keytab_entry;
+ keytab_entry.principal = principal_entry;
+ keytab_entry.keyblock.keytype = 0;
+ keytab_entry.vno = 0;
+
+ krb5adm_ret = krb5_kt_remove_entry(m_krb5admContext, keytab, &keytab_entry);
+ if (krb5adm_ret) {
+ if (errstr) *errstr = i18n("%1<p>Details:<br>Failed to execute krb5_kt_remove_entry (code %2)").arg(krb5_get_error_message(m_krb5admContext, krb5adm_ret)).arg(krb5adm_ret);
+ }
+ else {
+ // Success!
+ retcode = 0;
+ }
+ }
+ krb5_kt_close(m_krb5admContext, keytab);
+ }
+
+ if (kadmin_unbind_needed) {
+ unbindKAdmin();
+ unbind(true); // Using kadmin can disrupt our LDAP connection
+ }
+ }
+
+ return retcode;
+}
+
int LDAPManager::writeCertificateFileIntoDirectory(TQByteArray cert, TQString attr, TQString* errstr) {
int retcode;
int i;
@@ -5197,65 +5295,28 @@ int LDAPManager::bondRealm(TQString adminUserName, const char * adminPassword, T
int LDAPManager::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/"+getMachineFQDN();
-
- TQString hostprinc = TQStringList::split(".", hoststring)[0];
- hostprinc.append("@"+(adminRealm.upper()));
-
- TQString prompt;
- PtyProcess kadminProc;
- kadminProc.exec(command, args);
- prompt = 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 = readFullLineFromPtyProcess(&kadminProc);
- printf("(kadmin) '%s'\n", prompt.ascii());
- } while ((prompt == TQString(command)) || (prompt == ""));
- prompt = prompt.stripWhiteSpace();
- if (prompt.endsWith(" Password:")) {
- kadminProc.enableLocalEcho(false);
- kadminProc.writeLine(adminPassword, true);
- do { // Discard our own input
- prompt = readFullLineFromPtyProcess(&kadminProc);
- printf("(kadmin) '%s'\n", prompt.ascii());
- } while (prompt == "");
- prompt = prompt.stripWhiteSpace();
- }
- if (prompt != "kadmin>") {
- if (errstr) *errstr = prompt;
- do { // Wait for command prompt
- prompt = readFullLineFromPtyProcess(&kadminProc);
- printf("(kadmin) '%s'\n", prompt.ascii());
- } while (prompt == "");
- kadminProc.enableLocalEcho(false);
- kadminProc.writeLine("quit", true);
- return 1;
- }
+ LDAPCredentials admincreds;
+ admincreds.username = adminUserName;
+ admincreds.password = adminPassword;
+ admincreds.realm = adminRealm;
+ admincreds.use_gssapi = false;
- // Success!
- kadminProc.enableLocalEcho(false);
- kadminProc.writeLine("quit", true);
+ TQString hoststring = "host/" + getMachineFQDN();
- // Delete keys from keytab
- command = TQString("ktutil remove -p %1").arg(hoststring+"@"+adminRealm.upper());
- if (system(command) < 0) {
- printf("ERROR: Execution of \"%s\" failed!\n", command.data());
- return 1; // Failure
+ int retcode;
+ LDAPManager* ldap_mgr = new LDAPManager(adminRealm, TQString::null);
+ retcode = ldap_mgr->bindKAdmin(&admincreds, errstr);
+ if (!retcode) {
+ retcode = ldap_mgr->kAdminDeletePrincipal(hoststring, errstr);
+ if (!retcode) {
+ // Principal and associated keys deleted from server, now delete keys from local keytab...
+ retcode = ldap_mgr->deleteKeytabEntriesForPrincipal(hoststring, TQString::null, errstr);
}
-
- // Success!
- return 0;
+ ldap_mgr->unbindKAdmin();
}
+ delete ldap_mgr;
- return 1; // Failure
+ return retcode;
}
// ===============================================================================================================
diff --git a/src/libtdeldap.h b/src/libtdeldap.h
index aafa072..b404ed7 100644
--- a/src/libtdeldap.h
+++ b/src/libtdeldap.h
@@ -520,6 +520,7 @@ class LDAPManager : public TQObject {
int deleteServiceInfo(LDAPServiceInfo service, TQString *errstr=0);
int exportKeytabForPrincipal(TQString principal, TQString fileName, TQString *errstr=0);
+ int deleteKeytabEntriesForPrincipal(TQString principal, TQString fileName, TQString *errstr=0);
LDAPCredentials currentLDAPCredentials(bool inferGSSAPIData=false);
@@ -592,6 +593,7 @@ class LDAPManager : public TQObject {
int bindKAdmin(LDAPCredentials *administrativeCredentials=NULL, TQString *errstr=0);
int unbindKAdmin(TQString *errstr=0);
int kAdminAddNewPrincipal(TQString principalName, TQString newPassword, TQString *errstr=0);
+ int kAdminDeletePrincipal(TQString principalName, TQString *errstr=0);
LDAPUserInfo parseLDAPUserRecord(LDAPMessage* entry);
LDAPGroupInfo parseLDAPGroupRecord(LDAPMessage* entry);
LDAPMachineInfo parseLDAPMachineRecord(LDAPMessage* entry);