diff options
author | Timothy Pearson <kb9vqf@pearsoncomputing.net> | 2015-09-29 02:08:05 -0500 |
---|---|---|
committer | Timothy Pearson <kb9vqf@pearsoncomputing.net> | 2015-09-29 02:08:05 -0500 |
commit | c70ce69a08815fb4da81b2a85fc4a2a10d469cab (patch) | |
tree | 01fd7fc2f2d0b25001f6a096d2c3659e03859d16 /src | |
parent | 11869fce63bd934f43125e0f826cc667eee54f68 (diff) | |
download | libtdeldap-c70ce69a08815fb4da81b2a85fc4a2a10d469cab.tar.gz libtdeldap-c70ce69a08815fb4da81b2a85fc4a2a10d469cab.zip |
Convert the last methods using the kadmin utility to the Heimdal C API
Diffstat (limited to 'src')
-rw-r--r-- | src/libtdeldap.cpp | 197 | ||||
-rw-r--r-- | src/libtdeldap.h | 2 |
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); |