summaryrefslogtreecommitdiffstats
path: root/src/libtdeldap.cpp
diff options
context:
space:
mode:
authorTimothy Pearson <kb9vqf@pearsoncomputing.net>2015-09-27 18:07:40 -0500
committerTimothy Pearson <kb9vqf@pearsoncomputing.net>2015-09-27 18:07:40 -0500
commitbd30e6c65567795863eec5e3e9ac57d6b2b43207 (patch)
treee574a52022ced221b5988761ffd0cde22b9bf5fb /src/libtdeldap.cpp
parenta619f64455bf3cd5715505b0cab057ca920fc7a0 (diff)
downloadlibtdeldap-bd30e6c65567795863eec5e3e9ac57d6b2b43207.tar.gz
libtdeldap-bd30e6c65567795863eec5e3e9ac57d6b2b43207.zip
Start to move away from using the kadmin binary to using the kadmin client API
Diffstat (limited to 'src/libtdeldap.cpp')
-rw-r--r--src/libtdeldap.cpp200
1 files changed, 109 insertions, 91 deletions
diff --git a/src/libtdeldap.cpp b/src/libtdeldap.cpp
index 1721bc5..d240428 100644
--- a/src/libtdeldap.cpp
+++ b/src/libtdeldap.cpp
@@ -108,13 +108,13 @@ bool fileExists(const char* filename) {
}
}
-LDAPManager::LDAPManager(TQString realm, TQString host, TQObject *parent, const char *name) : TQObject(parent, name), m_realm(realm), m_host(host), m_port(0), m_creds(0), m_ldap(0)
+LDAPManager::LDAPManager(TQString realm, TQString host, TQObject *parent, const char *name) : TQObject(parent, name), m_realm(realm), m_host(host), m_port(0), m_creds(0), m_ldap(0), m_krb5admHandle(0), m_krb5admKeytabFilename(0)
{
TQStringList domainChunks = TQStringList::split(".", realm.lower());
m_basedc = "dc=" + domainChunks.join(",dc=");
}
-LDAPManager::LDAPManager(TQString realm, TQString host, LDAPCredentials* creds, TQObject *parent, const char *name) : TQObject(parent, name), m_realm(realm), m_host(host), m_port(0), m_creds(creds), m_ldap(0)
+LDAPManager::LDAPManager(TQString realm, TQString host, LDAPCredentials* creds, TQObject *parent, const char *name) : TQObject(parent, name), m_realm(realm), m_host(host), m_port(0), m_creds(creds), m_ldap(0), m_krb5admHandle(0), m_krb5admKeytabFilename(0)
{
TQStringList domainChunks = TQStringList::split(".", realm.lower());
m_basedc = "dc=" + domainChunks.join(",dc=");
@@ -405,6 +405,10 @@ int LDAPManager::bind(TQString* errstr) {
}
int LDAPManager::unbind(bool force, TQString* errstr) {
+ if (m_krb5admHandle) {
+ unbindKAdmin();
+ }
+
if (!m_ldap) {
return 0;
}
@@ -1094,12 +1098,23 @@ TQString LDAPManager::readFullLineFromPtyProcess(PtyProcess* proc) {
return result;
}
-int LDAPManager::setPasswordForUser(LDAPUserInfo user, TQString *errstr) {
- if (user.new_password == "") {
- return 0;
- }
+int LDAPManager::bindKAdmin(LDAPUserInfo user, TQString *errstr) {
+ int retcode = 1;
+
+ kadm5_ret_t krb5adm_ret;
+ kadm5_config_params params;
LDAPCredentials admincreds = currentLDAPCredentials();
+ if (admincreds.use_gssapi) {
+ // FIXME
+ // Heimdal has issues parsing the keytab file, so for now just prompt for password
+ TQCString password;
+ int result = KPasswordDialog::getPassword(password, i18n("Enter password for %1").arg(admincreds.username));
+ if (result == KPasswordDialog::Accepted) {
+ admincreds.password = password;
+ admincreds.use_gssapi = false;
+ }
+ }
if ((admincreds.username == "") && (admincreds.password == "")) {
// Probably GSSAPI
// Get active ticket principal...
@@ -1107,107 +1122,107 @@ int LDAPManager::setPasswordForUser(LDAPUserInfo user, TQString *errstr) {
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());
+ TQString ticketFile;
+ LDAPManager::getKerberosTicketList(TQString::null, &ticketFile);
+
+ memset(&params, 0, sizeof(params));
+ params.mask |= KADM5_CONFIG_REALM;
+ params.realm = const_cast<char *>(admincreds.realm.upper().ascii());
+
+ TQString adminPrincipal = TQString::null;
+ if (admincreds.username != "") {
+ adminPrincipal = admincreds.username.lower() + "@" + admincreds.realm.upper();
+ }
+
+ krb5adm_ret = krb5_init_context(&m_krb5admContext);
+ if (krb5adm_ret) {
+ if (errstr) *errstr = TQString("Internal Error<p>Failed to execute kadm5_init_krb5_context (code %1)").arg(krb5adm_ret);
}
else {
- if (admincreds.username == "") {
- args << TQCString("-r") << TQCString(admincreds.realm.upper());
+ if (m_host.startsWith("ldapi://")) {
+ // Local bind
+ krb5adm_ret = kadm5_init_with_password_ctx(m_krb5admContext, KADM5_ADMIN_SERVICE, admincreds.password.data(), KADM5_ADMIN_SERVICE, &params, KADM5_STRUCT_VERSION, KADM5_API_VERSION_2, &m_krb5admHandle);
+ if (krb5adm_ret) {
+ if (errstr) *errstr = TQString("%1<p>Details:<br>Failed to execute kadm5_init_with_password (code %2)").arg(krb5_get_error_message(m_krb5admContext, krb5adm_ret)).arg(krb5adm_ret);
+ }
+ }
+ else if (admincreds.use_gssapi) {
+ // Keytab authentication / bind
+ if (m_krb5admKeytabFilename) {
+ free(m_krb5admKeytabFilename);
+ }
+ m_krb5admKeytabFilename = strdup(ticketFile.ascii());
+ krb5adm_ret = kadm5_init_with_skey_ctx(m_krb5admContext, KADM5_ADMIN_SERVICE, m_krb5admKeytabFilename, KADM5_ADMIN_SERVICE, &params, KADM5_STRUCT_VERSION, KADM5_API_VERSION_2, &m_krb5admHandle);
+ if (krb5adm_ret) {
+ if (errstr) *errstr = TQString("%1<p>Details:<br>Failed to execute kadm5_init_with_skey (code %2)").arg(krb5_get_error_message(m_krb5admContext, krb5adm_ret)).arg(krb5adm_ret);
+ }
}
else {
- args << TQCString("-p") << TQCString(admincreds.username.lower()+"@"+(admincreds.realm.upper())) << TQCString("-r") << TQCString(admincreds.realm.upper());
+ // Password authentication / bind
+ krb5adm_ret = kadm5_init_with_password_ctx(m_krb5admContext, adminPrincipal.ascii(), admincreds.password.data(), KADM5_ADMIN_SERVICE, &params, KADM5_STRUCT_VERSION, KADM5_API_VERSION_2, &m_krb5admHandle);
+ if (krb5adm_ret) {
+ if (errstr) *errstr = TQString("%1<p>Details:<br>Failed to execute kadm5_init_with_password (code %2)").arg(krb5_get_error_message(m_krb5admContext, krb5adm_ret)).arg(krb5adm_ret);
+ }
+ }
+ if (!krb5adm_ret) {
+ // Success!
+ retcode = 0;
}
}
- TQString prompt;
- PtyProcess kadminProc;
- kadminProc.exec(command, args);
- prompt = readFullLineFromPtyProcess(&kadminProc);
- prompt = prompt.stripWhiteSpace();
- if (prompt == "kadmin>") {
- command = TQCString("passwd "+user.name);
- 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:")) && (prompt.startsWith(TQString(user.name + "@")))) {
- kadminProc.enableLocalEcho(false);
- kadminProc.writeLine(user.new_password, true);
- do { // Discard our own input
- prompt = readFullLineFromPtyProcess(&kadminProc);
- printf("(kadmin) '%s'\n", prompt.ascii());
- } while (prompt == "");
- prompt = prompt.stripWhiteSpace();
- if ((prompt.endsWith(" Password:")) && (prompt.startsWith("Verify"))) {
- kadminProc.enableLocalEcho(false);
- kadminProc.writeLine(user.new_password, true);
- do { // Discard our own input
- prompt = readFullLineFromPtyProcess(&kadminProc);
- printf("(kadmin) '%s'\n", prompt.ascii());
- } while (prompt == "");
- prompt = prompt.stripWhiteSpace();
- }
- 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 {
- TQFile file;
- file.open(IO_ReadOnly, stdin);
- TQTextStream qtin(&file);
- admincreds.password = qtin.readLine();
- }
- }
- 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();
- }
+ return retcode;
+}
+
+int LDAPManager::unbindKAdmin(TQString *errstr) {
+ if (m_krb5admKeytabFilename) {
+ free(m_krb5admKeytabFilename);
+ }
+
+ kadm5_destroy(m_krb5admHandle);
+ krb5_free_context(m_krb5admContext);
+
+ m_krb5admHandle = NULL;
+
+ return 0;
+}
+
+int LDAPManager::setPasswordForUser(LDAPUserInfo user, TQString *errstr) {
+ if (user.new_password == "") {
+ return 0;
+ }
+
+ int retcode;
+ kadm5_ret_t krb5adm_ret;
+
+ retcode = bindKAdmin(user, errstr);
+ if (retcode == 0) {
+ retcode = 1;
+ krb5_principal user_kadm5_principal;
+ krb5adm_ret = krb5_parse_name(m_krb5admContext, user.name.ascii(), &user_kadm5_principal);
+ if (krb5adm_ret) {
+ if (errstr) *errstr = TQString("%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);
+ }
+ else {
+ krb5adm_ret = kadm5_chpass_principal(m_krb5admHandle, user_kadm5_principal, user.new_password.data());
+ if (krb5adm_ret) {
+ if (errstr) *errstr = TQString("%1<p>Details:<br>Failed to execute kadm5_chpass_principal for user '%2' (code %3)").arg(krb5_get_error_message(m_krb5admContext, krb5adm_ret)).arg(user.name).arg(krb5adm_ret);
}
- if (prompt != "kadmin>") {
- if (errstr) *errstr = detailedKAdminErrorMessage(prompt);
- kadminProc.enableLocalEcho(false);
- kadminProc.writeLine("quit", true);
- return 1;
+ else {
+ // Success!
+ retcode = 0;
}
- // Success!
- kadminProc.enableLocalEcho(false);
- kadminProc.writeLine("quit", true);
- return 0;
- }
- else if (prompt == "kadmin>") {
- // Success!
- kadminProc.enableLocalEcho(false);
- kadminProc.writeLine("quit", true);
- return 0;
+ // Clean up
+ krb5_free_principal(m_krb5admContext, user_kadm5_principal);
}
- // Failure
- if (errstr) *errstr = detailedKAdminErrorMessage(prompt);
- kadminProc.enableLocalEcho(false);
- kadminProc.writeLine("quit", true);
- return 1;
+ unbindKAdmin();
}
- if (errstr) *errstr = "Internal error. Verify that kadmin exists and can be executed.";
- return 1; // Failure
+ return retcode;
}
TQString klistDateTimeToRFCDateTime(TQString datetime) {
@@ -1746,6 +1761,7 @@ int LDAPManager::addMachineInfo(LDAPMachineInfo machine, TQString *errstr) {
TQStringList principalParts = TQStringList::split("@", tickets[0].cachePrincipal, false);
admincreds.username = principalParts[0];
admincreds.realm = principalParts[1];
+ admincreds.use_gssapi = true;
}
TQCString command = "kadmin";
@@ -1871,6 +1887,7 @@ int LDAPManager::addServiceInfo(LDAPServiceInfo service, TQString *errstr) {
TQStringList principalParts = TQStringList::split("@", tickets[0].cachePrincipal, false);
admincreds.username = principalParts[0];
admincreds.realm = principalParts[1];
+ admincreds.use_gssapi = true;
}
TQCString command = "kadmin";
@@ -2578,6 +2595,7 @@ int LDAPManager::exportKeytabForPrincipal(TQString principal, TQString fileName,
TQStringList principalParts = TQStringList::split("@", tickets[0].cachePrincipal, false);
admincreds.username = principalParts[0];
admincreds.realm = principalParts[1];
+ admincreds.use_gssapi = true;
}
TQCString command = "kadmin";