Move keytab export to native Heimdal API

pull/1/head
Timothy Pearson 10 years ago
parent e085706825
commit 11869fce63

@ -1140,13 +1140,19 @@ TQString LDAPManager::readFullLineFromPtyProcess(PtyProcess* proc) {
return result; return result;
} }
int LDAPManager::bindKAdmin(TQString *errstr) { int LDAPManager::bindKAdmin(LDAPCredentials *administrativeCredentials, TQString *errstr) {
int retcode = 1; int retcode = 1;
kadm5_ret_t krb5adm_ret; kadm5_ret_t krb5adm_ret;
kadm5_config_params params; kadm5_config_params params;
LDAPCredentials admincreds = currentLDAPCredentials(); LDAPCredentials admincreds;
if (administrativeCredentials) {
admincreds = *administrativeCredentials;
}
else {
admincreds = currentLDAPCredentials();
}
if (admincreds.use_gssapi) { if (admincreds.use_gssapi) {
// FIXME // FIXME
// Heimdal has issues parsing the keytab file, so for now just prompt for password // Heimdal has issues parsing the keytab file, so for now just prompt for password
@ -1291,7 +1297,14 @@ int LDAPManager::setPasswordForUser(LDAPUserInfo user, TQString *errstr) {
int retcode; int retcode;
kadm5_ret_t krb5adm_ret; kadm5_ret_t krb5adm_ret;
retcode = bindKAdmin(errstr); bool kadmin_unbind_needed = false;
if (m_krb5admHandle) {
retcode = 0;
}
else {
retcode = bindKAdmin(NULL, errstr);
kadmin_unbind_needed = true;
}
if (retcode == 0) { if (retcode == 0) {
retcode = 1; retcode = 1;
krb5_principal user_kadm5_principal; krb5_principal user_kadm5_principal;
@ -1313,9 +1326,11 @@ int LDAPManager::setPasswordForUser(LDAPUserInfo user, TQString *errstr) {
krb5_free_principal(m_krb5admContext, user_kadm5_principal); krb5_free_principal(m_krb5admContext, user_kadm5_principal);
} }
if (kadmin_unbind_needed) {
unbindKAdmin(); unbindKAdmin();
unbind(true); // Using kadmin can disrupt our LDAP connection unbind(true); // Using kadmin can disrupt our LDAP connection
} }
}
return retcode; return retcode;
} }
@ -1843,16 +1858,19 @@ int LDAPManager::addGroupInfo(LDAPGroupInfo group, TQString *errstr) {
} }
int LDAPManager::kAdminAddNewPrincipal(TQString principalName, TQString newPassword, TQString *errstr) { int LDAPManager::kAdminAddNewPrincipal(TQString principalName, TQString newPassword, TQString *errstr) {
if (bind() < 0) {
return -1;
}
else {
int retcode; int retcode;
kadm5_ret_t krb5adm_ret; kadm5_ret_t krb5adm_ret;
int i; int i;
char* password = NULL; char* password = NULL;
retcode = bindKAdmin(errstr); bool kadmin_unbind_needed = false;
if (m_krb5admHandle) {
retcode = 0;
}
else {
retcode = bindKAdmin(NULL, errstr);
kadmin_unbind_needed = true;
}
if (retcode == 0) { if (retcode == 0) {
retcode = 1; retcode = 1;
bool generate_password; bool generate_password;
@ -1978,12 +1996,13 @@ int LDAPManager::kAdminAddNewPrincipal(TQString principalName, TQString newPassw
free(password); free(password);
} }
if (kadmin_unbind_needed) {
unbindKAdmin(); unbindKAdmin();
unbind(true); // Using kadmin can disrupt our LDAP connection unbind(true); // Using kadmin can disrupt our LDAP connection
} }
}
return retcode; return retcode;
}
} }
int LDAPManager::addMachineInfo(LDAPMachineInfo machine, TQString *errstr) { int LDAPManager::addMachineInfo(LDAPMachineInfo machine, TQString *errstr) {
@ -2584,127 +2603,105 @@ LDAPServiceInfoList LDAPManager::machineServices(TQString machine_dn, int* mretc
} }
int LDAPManager::exportKeytabForPrincipal(TQString principal, TQString fileName, TQString *errstr) { int LDAPManager::exportKeytabForPrincipal(TQString principal, TQString fileName, TQString *errstr) {
if (bind() < 0) { int retcode;
return -1; kadm5_ret_t krb5adm_ret;
int i;
bool kadmin_unbind_needed = false;
if (m_krb5admHandle) {
retcode = 0;
} }
else { else {
// Use Kerberos kadmin to export the keytab retcode = bindKAdmin(NULL, errstr);
LDAPCredentials admincreds = currentLDAPCredentials(); kadmin_unbind_needed = true;
if ((admincreds.username == "") && (admincreds.password == "")) {
// Probably GSSAPI
// Get active ticket principal...
KerberosTicketInfoList tickets = LDAPManager::getKerberosTicketList();
TQStringList principalParts = TQStringList::split("@", tickets[0].cachePrincipal, false);
admincreds.username = principalParts[0];
admincreds.realm = principalParts[1];
admincreds.use_gssapi = true;
} }
if (retcode == 0) {
retcode = 1;
TQCString command = "kadmin"; krb5_keytab keytab;
QCStringList args; if (fileName == "") {
if (m_host.startsWith("ldapi://")) { krb5adm_ret = krb5_kt_default(m_krb5admContext, &keytab);
args << TQCString("-l") << TQCString("-r") << TQCString(admincreds.realm.upper());
} }
else { else {
if (admincreds.username == "") { krb5adm_ret = krb5_kt_resolve(m_krb5admContext, fileName.ascii(), &keytab);
args << TQCString("-r") << TQCString(admincreds.realm.upper());
} }
else { if (krb5adm_ret) {
args << TQCString("-p") << TQCString(admincreds.username.lower()+"@"+(admincreds.realm.upper())) << TQCString("-r") << TQCString(admincreds.realm.upper()); 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 {
kadm5_principal_ent_rec principal_record;
krb5_principal principal_entry = NULL;
memset(&principal_record, 0, sizeof(principal_record));
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 {
principal_record.principal = principal_entry;
TQString prompt; krb5adm_ret = kadm5_get_principal(m_krb5admHandle, principal_entry, &principal_record, KADM5_PRINCIPAL | KADM5_KVNO | KADM5_KEY_DATA);
PtyProcess kadminProc; if (krb5adm_ret) {
kadminProc.exec(command, args); if (errstr) *errstr = i18n("%1<p>Details:<br>Failed to execute kadm5_get_principal (code %2)").arg(krb5_get_error_message(m_krb5admContext, krb5adm_ret)).arg(krb5adm_ret);
prompt = readFullLineFromPtyProcess(&kadminProc); retcode = 2;
prompt = prompt.stripWhiteSpace();
if (prompt == "kadmin>") {
if (fileName == "") {
command = TQCString("ext_keytab "+principal);
} }
else { else {
command = TQCString("ext_keytab --keytab=\""+fileName+"\" "+principal); if (principal_record.n_key_data == 0) {
if (errstr) *errstr = i18n("No keys found!<p>If this principal is known to have valid keys, please check your access permissions and try again");
retcode = 2;
} }
kadminProc.enableLocalEcho(false); else {
kadminProc.writeLine(command, true); // Extract keys
do { // Discard our own input krb5_keytab_entry *keys = NULL;
prompt = readFullLineFromPtyProcess(&kadminProc); keys = (krb5_keytab_entry*)calloc(sizeof(*keys), principal_record.n_key_data);
printf("(kadmin) '%s'\n", prompt.ascii()); if (keys == NULL) {
} while ((prompt == TQString(command)) || (prompt == "")); if (errstr) *errstr = i18n("Out of memory");
prompt = prompt.stripWhiteSpace();
// Use all defaults
while (prompt != "kadmin>") {
if (prompt.endsWith(" Password:")) {
if (admincreds.password == "") {
if (tqApp->type() != TQApplication::Tty) {
TQCString password;
int result = KPasswordDialog::getPassword(password, prompt);
if (result == KPasswordDialog::Accepted) {
admincreds.password = password;
} }
else {
int key_count = 0;
for (i = 0; i < principal_record.n_key_data; i++) {
krb5_key_data *kd = &principal_record.key_data[i];
keys[i].principal = principal_record.principal;
keys[i].vno = kd->key_data_kvno;
keys[i].keyblock.keytype = kd->key_data_type[0];
keys[i].keyblock.keyvalue.length = kd->key_data_length[0];
keys[i].keyblock.keyvalue.data = kd->key_data_contents[0];
keys[i].timestamp = time(NULL);
key_count++;
}
if (key_count < 1) {
if (errstr) *errstr = i18n("No keys found!<p>If this principal is known to have valid keys, please check your access permissions and try again");
} }
else { else {
TQFile file; for (i = 0; i < key_count; i++) {
file.open(IO_ReadOnly, stdin); krb5adm_ret = krb5_kt_add_entry(m_krb5admContext, keytab, &keys[i]);
TQTextStream qtin(&file); if (krb5adm_ret) {
admincreds.password = qtin.readLine(); if (errstr) *errstr = i18n("%1<p>Details:<br>Failed to execute krb5_kt_add_entry (code %2)").arg(krb5_get_error_message(m_krb5admContext, krb5adm_ret)).arg(krb5adm_ret);
} }
} }
if (admincreds.password != "") { if (!krb5adm_ret) {
kadminProc.enableLocalEcho(false); // Success!
kadminProc.writeLine(admincreds.password, true); retcode = 0;
do { // Discard our own input
prompt = readFullLineFromPtyProcess(&kadminProc);
printf("(kadmin) '%s'\n", prompt.ascii());
} while (prompt == "");
prompt = prompt.stripWhiteSpace();
} }
} }
if (prompt.contains("authentication failed")) {
if (errstr) *errstr = detailedKAdminErrorMessage(prompt);
kadminProc.enableLocalEcho(false);
kadminProc.writeLine("quit", true);
return 1;
} }
else {
// Extract whatever default is in the [brackets] and feed it back to kadmin free(keys);
TQString defaultParam;
int leftbracket = prompt.find("[");
int rightbracket = prompt.find("]");
if ((leftbracket >= 0) && (rightbracket >= 0)) {
leftbracket++;
defaultParam = prompt.mid(leftbracket, rightbracket-leftbracket);
}
command = TQCString(defaultParam);
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();
} }
kadm5_free_principal_ent(m_krb5admHandle, &principal_record);
} }
if (prompt != "kadmin>") { }
if (errstr) *errstr = detailedKAdminErrorMessage(prompt); krb5_kt_close(m_krb5admContext, keytab);
kadminProc.enableLocalEcho(false);
kadminProc.writeLine("quit", true);
return 1;
} }
// Success! if (kadmin_unbind_needed) {
kadminProc.enableLocalEcho(false); unbindKAdmin();
kadminProc.writeLine("quit", true);
unbind(true); // Using kadmin can disrupt our LDAP connection unbind(true); // Using kadmin can disrupt our LDAP connection
return 0;
} }
if (errstr) *errstr = "Internal error. Verify that kadmin exists and can be executed.";
return 1; // Failure
} }
return retcode;
} }
int LDAPManager::writeCertificateFileIntoDirectory(TQByteArray cert, TQString attr, TQString* errstr) { int LDAPManager::writeCertificateFileIntoDirectory(TQByteArray cert, TQString attr, TQString* errstr) {
@ -5170,144 +5167,31 @@ int LDAPManager::writeOpenSSLConfigurationFile(LDAPRealmConfig realmcfg, LDAPUse
} }
int LDAPManager::bondRealm(TQString adminUserName, const char * adminPassword, TQString adminRealm, TQString *errstr) { int LDAPManager::bondRealm(TQString adminUserName, const char * adminPassword, TQString adminRealm, TQString *errstr) {
TQCString command = "kadmin"; LDAPCredentials admincreds;
QCStringList args; admincreds.username = adminUserName;
args << TQCString("-p") << TQCString(adminUserName+"@"+(adminRealm.upper())) << TQCString("-r") << TQCString(adminRealm.upper()); admincreds.password = adminPassword;
admincreds.realm = adminRealm;
TQString hoststring = "host/"+getMachineFQDN(); admincreds.use_gssapi = false;
TQString prompt;
PtyProcess kadminProc;
kadminProc.exec(command, args);
prompt = readFullLineFromPtyProcess(&kadminProc);
prompt = prompt.stripWhiteSpace();
if (prompt == "kadmin>") {
command = TQCString("ext "+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.contains("authentication failed")) {
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;
}
else if (prompt.endsWith("Principal does not exist")) {
do { // Wait for command prompt
prompt = readFullLineFromPtyProcess(&kadminProc);
printf("(kadmin) '%s'\n", prompt.ascii());
} while (prompt == "");
command = TQCString("ank --random-key "+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();
// Use all defaults
while (prompt != "kadmin>") {
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.contains("authentication failed")) {
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;
}
else {
// Extract whatever default is in the [brackets] and feed it back to kadmin
TQString defaultParam;
int leftbracket = prompt.find("[");
int rightbracket = prompt.find("]");
if ((leftbracket >= 0) && (rightbracket >= 0)) {
leftbracket++;
defaultParam = prompt.mid(leftbracket, rightbracket-leftbracket);
}
command = TQCString(defaultParam);
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();
}
}
command = TQCString("ext "+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 != "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;
}
// Success! TQString hoststring = "host/" + getMachineFQDN();
kadminProc.enableLocalEcho(false);
kadminProc.writeLine("quit", true);
return 0; int retcode;
} LDAPManager* ldap_mgr = new LDAPManager(adminRealm, TQString::null);
else if (prompt == "kadmin>") { retcode = ldap_mgr->bindKAdmin(&admincreds, errstr);
// Success! if (!retcode) {
kadminProc.enableLocalEcho(false); retcode = ldap_mgr->exportKeytabForPrincipal(hoststring, TQString::null, errstr);
kadminProc.writeLine("quit", true); if (retcode == 2) {
// Principal not found, create it
return 0; retcode = ldap_mgr->kAdminAddNewPrincipal(hoststring, TQString::null, errstr);
if (!retcode) {
retcode = ldap_mgr->exportKeytabForPrincipal(hoststring, TQString::null, errstr);
} }
// Failure
if (errstr) *errstr = prompt;
while (prompt == "") { // Wait for command prompt
prompt = readFullLineFromPtyProcess(&kadminProc);
printf("(kadmin) '%s'\n", prompt.ascii());
} }
kadminProc.enableLocalEcho(false); ldap_mgr->unbindKAdmin();
kadminProc.writeLine("quit", true);
return 1;
} }
delete ldap_mgr;
if (errstr) *errstr = "Internal error. Verify that kadmin exists and can be executed."; return retcode;
return 1; // Failure
} }
int LDAPManager::unbondRealm(LDAPRealmConfig realmcfg, TQString adminUserName, const char * adminPassword, TQString adminRealm, TQString *errstr) { int LDAPManager::unbondRealm(LDAPRealmConfig realmcfg, TQString adminUserName, const char * adminPassword, TQString adminRealm, TQString *errstr) {

@ -589,7 +589,7 @@ class LDAPManager : public TQObject {
static int unbondRealm(LDAPRealmConfig realmcfg, TQString adminUserName, const char * adminPassword, TQString adminRealm, TQString *errstr=0); static int unbondRealm(LDAPRealmConfig realmcfg, TQString adminUserName, const char * adminPassword, TQString adminRealm, TQString *errstr=0);
private: private:
int bindKAdmin(TQString *errstr=0); int bindKAdmin(LDAPCredentials *administrativeCredentials=NULL, TQString *errstr=0);
int unbindKAdmin(TQString *errstr=0); int unbindKAdmin(TQString *errstr=0);
int kAdminAddNewPrincipal(TQString principalName, TQString newPassword, TQString *errstr=0); int kAdminAddNewPrincipal(TQString principalName, TQString newPassword, TQString *errstr=0);
LDAPUserInfo parseLDAPUserRecord(LDAPMessage* entry); LDAPUserInfo parseLDAPUserRecord(LDAPMessage* entry);

Loading…
Cancel
Save