Convert the last methods using the kadmin utility to the Heimdal C API

pull/1/head
Timothy Pearson 9 years ago
parent 11869fce63
commit c70ce69a08

@ -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;
}
// ===============================================================================================================

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

Loading…
Cancel
Save