diff options
author | Timothy Pearson <kb9vqf@pearsoncomputing.net> | 2015-09-29 00:35:24 -0500 |
---|---|---|
committer | Timothy Pearson <kb9vqf@pearsoncomputing.net> | 2015-09-29 00:35:24 -0500 |
commit | 11869fce63bd934f43125e0f826cc667eee54f68 (patch) | |
tree | be326c169d4423c2c43f0531ba06edba3f9d14d3 | |
parent | e0857068258b5ee898f67fb84aac4637c524c026 (diff) | |
download | libtdeldap-11869fce63bd934f43125e0f826cc667eee54f68.tar.gz libtdeldap-11869fce63bd934f43125e0f826cc667eee54f68.zip |
Move keytab export to native Heimdal API
-rw-r--r-- | src/libtdeldap.cpp | 596 | ||||
-rw-r--r-- | src/libtdeldap.h | 2 |
2 files changed, 241 insertions, 357 deletions
diff --git a/src/libtdeldap.cpp b/src/libtdeldap.cpp index 93ec360..19812d5 100644 --- a/src/libtdeldap.cpp +++ b/src/libtdeldap.cpp @@ -1140,13 +1140,19 @@ TQString LDAPManager::readFullLineFromPtyProcess(PtyProcess* proc) { return result; } -int LDAPManager::bindKAdmin(TQString *errstr) { +int LDAPManager::bindKAdmin(LDAPCredentials *administrativeCredentials, TQString *errstr) { int retcode = 1; kadm5_ret_t krb5adm_ret; kadm5_config_params params; - LDAPCredentials admincreds = currentLDAPCredentials(); + LDAPCredentials admincreds; + if (administrativeCredentials) { + admincreds = *administrativeCredentials; + } + else { + admincreds = currentLDAPCredentials(); + } if (admincreds.use_gssapi) { // FIXME // 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; 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) { retcode = 1; krb5_principal user_kadm5_principal; @@ -1313,8 +1326,10 @@ int LDAPManager::setPasswordForUser(LDAPUserInfo user, TQString *errstr) { krb5_free_principal(m_krb5admContext, user_kadm5_principal); } - unbindKAdmin(); - unbind(true); // Using kadmin can disrupt our LDAP connection + if (kadmin_unbind_needed) { + unbindKAdmin(); + unbind(true); // Using kadmin can disrupt our LDAP connection + } } return retcode; @@ -1843,147 +1858,151 @@ int LDAPManager::addGroupInfo(LDAPGroupInfo group, TQString *errstr) { } int LDAPManager::kAdminAddNewPrincipal(TQString principalName, TQString newPassword, TQString *errstr) { - if (bind() < 0) { - return -1; + int retcode; + kadm5_ret_t krb5adm_ret; + int i; + char* password = NULL; + + bool kadmin_unbind_needed = false; + if (m_krb5admHandle) { + retcode = 0; } else { - int retcode; - kadm5_ret_t krb5adm_ret; - int i; - char* password = NULL; - - retcode = bindKAdmin(errstr); - if (retcode == 0) { - retcode = 1; - bool generate_password; - if (newPassword == "") { - generate_password = true; - } - else { - generate_password = false; - password = strdup(newPassword.ascii()); - } + retcode = bindKAdmin(NULL, errstr); + kadmin_unbind_needed = true; + } + if (retcode == 0) { + retcode = 1; + bool generate_password; + if (newPassword == "") { + generate_password = true; + } + else { + generate_password = false; + password = strdup(newPassword.ascii()); + } - // Construct and add new principal record - kadm5_principal_ent_rec principal_record; - kadm5_principal_ent_rec default_record; - kadm5_principal_ent_rec *default_entry = NULL; - krb5_principal principal_entry = NULL; - int mask = 0; + // Construct and add new principal record + kadm5_principal_ent_rec principal_record; + kadm5_principal_ent_rec default_record; + kadm5_principal_ent_rec *default_entry = NULL; + krb5_principal principal_entry = NULL; + int mask = 0; - memset(&principal_record, 0, sizeof(principal_record)); - 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 (code %2)").arg(krb5_get_error_message(m_krb5admContext, krb5adm_ret)).arg(krb5adm_ret); - } - principal_record.principal = principal_entry; - mask |= KADM5_PRINCIPAL; + memset(&principal_record, 0, sizeof(principal_record)); + 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 (code %2)").arg(krb5_get_error_message(m_krb5admContext, krb5adm_ret)).arg(krb5adm_ret); + } + principal_record.principal = principal_entry; + mask |= KADM5_PRINCIPAL; - default_entry = &default_record; - krb5adm_ret = kadm5_get_default_principal_info(m_krb5admContext, m_krb5admHandle, principal_entry, default_entry); - if (krb5adm_ret) { - default_entry = NULL; - if (errstr) *errstr = i18n("%1<p>Details:<br>Failed to execute kadm5_get_default_principal_info (code %2)").arg(krb5_get_error_message(m_krb5admContext, krb5adm_ret)).arg(krb5adm_ret); - } - else { - // Use defaults - principal_record.max_life = default_entry->max_life; - principal_record.max_renewable_life = default_entry->max_renewable_life; - principal_record.princ_expire_time = default_entry->princ_expire_time; - principal_record.pw_expiration = default_entry->pw_expiration; - principal_record.attributes = default_entry->attributes & ~KRB5_KDB_DISALLOW_ALL_TIX; - principal_record.policy = strdup(default_entry->policy); - - if (generate_password) { - const char charset[] = - "@$%&*()-+=:,/<>?0123456789" - "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - "abcdefghijklmnopqrstuvwxyz"; - const size_t max_index = (sizeof(charset) - 2); - - TQFile randomNode("/dev/urandom"); - if (randomNode.open(IO_ReadOnly)) { - password = (char*)malloc(sizeof(char) * KRB5_ANK_RANDOM_PASSWORD_LENGTH); - if (password) { - if (randomNode.readBlock(password, KRB5_ANK_RANDOM_PASSWORD_LENGTH) < KRB5_ANK_RANDOM_PASSWORD_LENGTH) { - free(password); - password = NULL; - } - else { - for (i = 0; i < KRB5_ANK_RANDOM_PASSWORD_LENGTH - 1; i++) { - while ((unsigned char)password[i] > max_index) { - password[i] -= max_index; - } - password[i] = charset[(int)password[i]]; + default_entry = &default_record; + krb5adm_ret = kadm5_get_default_principal_info(m_krb5admContext, m_krb5admHandle, principal_entry, default_entry); + if (krb5adm_ret) { + default_entry = NULL; + if (errstr) *errstr = i18n("%1<p>Details:<br>Failed to execute kadm5_get_default_principal_info (code %2)").arg(krb5_get_error_message(m_krb5admContext, krb5adm_ret)).arg(krb5adm_ret); + } + else { + // Use defaults + principal_record.max_life = default_entry->max_life; + principal_record.max_renewable_life = default_entry->max_renewable_life; + principal_record.princ_expire_time = default_entry->princ_expire_time; + principal_record.pw_expiration = default_entry->pw_expiration; + principal_record.attributes = default_entry->attributes & ~KRB5_KDB_DISALLOW_ALL_TIX; + principal_record.policy = strdup(default_entry->policy); + + if (generate_password) { + const char charset[] = + "@$%&*()-+=:,/<>?0123456789" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz"; + const size_t max_index = (sizeof(charset) - 2); + + TQFile randomNode("/dev/urandom"); + if (randomNode.open(IO_ReadOnly)) { + password = (char*)malloc(sizeof(char) * KRB5_ANK_RANDOM_PASSWORD_LENGTH); + if (password) { + if (randomNode.readBlock(password, KRB5_ANK_RANDOM_PASSWORD_LENGTH) < KRB5_ANK_RANDOM_PASSWORD_LENGTH) { + free(password); + password = NULL; + } + else { + for (i = 0; i < KRB5_ANK_RANDOM_PASSWORD_LENGTH - 1; i++) { + while ((unsigned char)password[i] > max_index) { + password[i] -= max_index; } - password[i] = 0; + password[i] = charset[(int)password[i]]; } + password[i] = 0; } - randomNode.close(); - } - if (password) { - principal_record.attributes |= KRB5_KDB_DISALLOW_ALL_TIX; - mask |= KADM5_ATTRIBUTES; - } - else { - if (errstr) *errstr = i18n("Unable to generate random password"); } + randomNode.close(); } - if (password) { - krb5adm_ret = kadm5_create_principal(m_krb5admHandle, &principal_record, mask, password); - if (krb5adm_ret) { - if (errstr) *errstr = i18n("%1<p>Details:<br>Failed to execute kadm5_create_principal (code %2)").arg(krb5_get_error_message(m_krb5admContext, krb5adm_ret)).arg(krb5adm_ret); - } - else { - if (generate_password) { - krb5_keyblock *new_keys; - int key_count; - krb5adm_ret = kadm5_randkey_principal(m_krb5admHandle, principal_entry, &new_keys, &key_count); - if (krb5adm_ret) { - key_count = 0; - } - for (i = 0; i < key_count; i++) { - krb5_free_keyblock_contents(m_krb5admContext, &new_keys[i]); - } - if (key_count > 0) { - free(new_keys); - } - kadm5_get_principal(m_krb5admHandle, principal_entry, &principal_record, KADM5_PRINCIPAL | KADM5_KVNO | KADM5_ATTRIBUTES); - krb5_free_principal(m_krb5admContext, principal_entry); - principal_entry = principal_record.principal; - principal_record.attributes &= (~KRB5_KDB_DISALLOW_ALL_TIX); - principal_record.kvno = 1; - krb5adm_ret = kadm5_modify_principal(m_krb5admHandle, &principal_record, KADM5_ATTRIBUTES | KADM5_KVNO); - if (krb5adm_ret) { - if (errstr) *errstr = i18n("%1<p>Details:<br>Failed to execute kadm5_modify_principal (code %2)").arg(krb5_get_error_message(m_krb5admContext, krb5adm_ret)).arg(krb5adm_ret); - } - else { - retcode = 0; - } + principal_record.attributes |= KRB5_KDB_DISALLOW_ALL_TIX; + mask |= KADM5_ATTRIBUTES; + } + else { + if (errstr) *errstr = i18n("Unable to generate random password"); + } + } + + if (password) { + krb5adm_ret = kadm5_create_principal(m_krb5admHandle, &principal_record, mask, password); + if (krb5adm_ret) { + if (errstr) *errstr = i18n("%1<p>Details:<br>Failed to execute kadm5_create_principal (code %2)").arg(krb5_get_error_message(m_krb5admContext, krb5adm_ret)).arg(krb5adm_ret); + } + else { + if (generate_password) { + krb5_keyblock *new_keys; + int key_count; + krb5adm_ret = kadm5_randkey_principal(m_krb5admHandle, principal_entry, &new_keys, &key_count); + if (krb5adm_ret) { + key_count = 0; + } + for (i = 0; i < key_count; i++) { + krb5_free_keyblock_contents(m_krb5admContext, &new_keys[i]); + } + if (key_count > 0) { + free(new_keys); + } + kadm5_get_principal(m_krb5admHandle, principal_entry, &principal_record, KADM5_PRINCIPAL | KADM5_KVNO | KADM5_ATTRIBUTES); + krb5_free_principal(m_krb5admContext, principal_entry); + principal_entry = principal_record.principal; + principal_record.attributes &= (~KRB5_KDB_DISALLOW_ALL_TIX); + principal_record.kvno = 1; + krb5adm_ret = kadm5_modify_principal(m_krb5admHandle, &principal_record, KADM5_ATTRIBUTES | KADM5_KVNO); + if (krb5adm_ret) { + if (errstr) *errstr = i18n("%1<p>Details:<br>Failed to execute kadm5_modify_principal (code %2)").arg(krb5_get_error_message(m_krb5admContext, krb5adm_ret)).arg(krb5adm_ret); } else { retcode = 0; } } + else { + retcode = 0; + } } } + } - kadm5_free_principal_ent(m_krb5admHandle, &principal_record); - if (default_entry) { - kadm5_free_principal_ent(m_krb5admHandle, default_entry); - } + kadm5_free_principal_ent(m_krb5admHandle, &principal_record); + if (default_entry) { + kadm5_free_principal_ent(m_krb5admHandle, default_entry); + } - if (password) { - free(password); - } + if (password) { + free(password); + } + if (kadmin_unbind_needed) { unbindKAdmin(); unbind(true); // Using kadmin can disrupt our LDAP connection } - - return retcode; } + + return retcode; } 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) { - if (bind() < 0) { - return -1; + int retcode; + kadm5_ret_t krb5adm_ret; + int i; + + bool kadmin_unbind_needed = false; + if (m_krb5admHandle) { + retcode = 0; } else { - // Use Kerberos kadmin to export the keytab - LDAPCredentials admincreds = currentLDAPCredentials(); - 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; - } - - TQCString command = "kadmin"; - QCStringList args; - if (m_host.startsWith("ldapi://")) { - args << TQCString("-l") << TQCString("-r") << TQCString(admincreds.realm.upper()); + 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 { - if (admincreds.username == "") { - args << TQCString("-r") << TQCString(admincreds.realm.upper()); - } - else { - args << TQCString("-p") << TQCString(admincreds.username.lower()+"@"+(admincreds.realm.upper())) << TQCString("-r") << TQCString(admincreds.realm.upper()); - } + 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 { + kadm5_principal_ent_rec principal_record; + krb5_principal principal_entry = NULL; - TQString prompt; - PtyProcess kadminProc; - kadminProc.exec(command, args); - prompt = readFullLineFromPtyProcess(&kadminProc); - prompt = prompt.stripWhiteSpace(); - if (prompt == "kadmin>") { - if (fileName == "") { - command = TQCString("ext_keytab "+principal); + 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 { - command = TQCString("ext_keytab --keytab=\""+fileName+"\" "+principal); - } - 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:")) { - if (admincreds.password == "") { - if (tqApp->type() != TQApplication::Tty) { - TQCString password; - int result = KPasswordDialog::getPassword(password, prompt); - if (result == KPasswordDialog::Accepted) { - admincreds.password = password; - } + principal_record.principal = principal_entry; + + krb5adm_ret = kadm5_get_principal(m_krb5admHandle, principal_entry, &principal_record, KADM5_PRINCIPAL | KADM5_KVNO | KADM5_KEY_DATA); + if (krb5adm_ret) { + 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); + retcode = 2; + } + else { + 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; + } + else { + // Extract keys + krb5_keytab_entry *keys = NULL; + keys = (krb5_keytab_entry*)calloc(sizeof(*keys), principal_record.n_key_data); + if (keys == NULL) { + if (errstr) *errstr = i18n("Out of memory"); } else { - TQFile file; - file.open(IO_ReadOnly, stdin); - TQTextStream qtin(&file); - admincreds.password = qtin.readLine(); + 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 { + for (i = 0; i < key_count; i++) { + krb5adm_ret = krb5_kt_add_entry(m_krb5admContext, keytab, &keys[i]); + if (krb5adm_ret) { + 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 (!krb5adm_ret) { + // Success! + retcode = 0; + } + } } + + free(keys); } - if (admincreds.password != "") { - kadminProc.enableLocalEcho(false); - kadminProc.writeLine(admincreds.password, 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 = 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 - 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); - kadminProc.enableLocalEcho(false); - kadminProc.writeLine("quit", true); - return 1; - } + krb5_kt_close(m_krb5admContext, keytab); + } - // Success! - kadminProc.enableLocalEcho(false); - kadminProc.writeLine("quit", true); + if (kadmin_unbind_needed) { + unbindKAdmin(); 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) { @@ -5170,144 +5167,31 @@ int LDAPManager::writeOpenSSLConfigurationFile(LDAPRealmConfig realmcfg, LDAPUse } int LDAPManager::bondRealm(TQString adminUserName, const char * adminPassword, TQString adminRealm, TQString *errstr) { - TQCString command = "kadmin"; - QCStringList args; - args << TQCString("-p") << TQCString(adminUserName+"@"+(adminRealm.upper())) << TQCString("-r") << TQCString(adminRealm.upper()); + LDAPCredentials admincreds; + admincreds.username = adminUserName; + admincreds.password = adminPassword; + admincreds.realm = adminRealm; + admincreds.use_gssapi = false; - TQString hoststring = "host/"+getMachineFQDN(); + TQString hoststring = "host/" + getMachineFQDN(); - 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; + int retcode; + LDAPManager* ldap_mgr = new LDAPManager(adminRealm, TQString::null); + retcode = ldap_mgr->bindKAdmin(&admincreds, errstr); + if (!retcode) { + retcode = ldap_mgr->exportKeytabForPrincipal(hoststring, TQString::null, errstr); + if (retcode == 2) { + // Principal not found, create it + retcode = ldap_mgr->kAdminAddNewPrincipal(hoststring, TQString::null, errstr); + if (!retcode) { + retcode = ldap_mgr->exportKeytabForPrincipal(hoststring, TQString::null, errstr); } - - // 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; - while (prompt == "") { // Wait for command prompt - prompt = readFullLineFromPtyProcess(&kadminProc); - printf("(kadmin) '%s'\n", prompt.ascii()); - } - kadminProc.enableLocalEcho(false); - kadminProc.writeLine("quit", true); - return 1; + ldap_mgr->unbindKAdmin(); } + delete ldap_mgr; - if (errstr) *errstr = "Internal error. Verify that kadmin exists and can be executed."; - return 1; // Failure + return retcode; } int LDAPManager::unbondRealm(LDAPRealmConfig realmcfg, TQString adminUserName, const char * adminPassword, TQString adminRealm, TQString *errstr) { diff --git a/src/libtdeldap.h b/src/libtdeldap.h index a62c429..aafa072 100644 --- a/src/libtdeldap.h +++ b/src/libtdeldap.h @@ -589,7 +589,7 @@ class LDAPManager : public TQObject { static int unbondRealm(LDAPRealmConfig realmcfg, TQString adminUserName, const char * adminPassword, TQString adminRealm, TQString *errstr=0); private: - int bindKAdmin(TQString *errstr=0); + int bindKAdmin(LDAPCredentials *administrativeCredentials=NULL, TQString *errstr=0); int unbindKAdmin(TQString *errstr=0); int kAdminAddNewPrincipal(TQString principalName, TQString newPassword, TQString *errstr=0); LDAPUserInfo parseLDAPUserRecord(LDAPMessage* entry); |