summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTimothy Pearson <kb9vqf@pearsoncomputing.net>2015-09-28 07:49:20 +0000
committerTimothy Pearson <kb9vqf@pearsoncomputing.net>2015-09-28 07:49:20 +0000
commit3d6055df7b262d0fcb03b37f58c3b0461eef49e3 (patch)
treef19380ffa6508d915986450137fdd3a133878169
parentbd30e6c65567795863eec5e3e9ac57d6b2b43207 (diff)
downloadlibtdeldap-3d6055df7b262d0fcb03b37f58c3b0461eef49e3.tar.gz
libtdeldap-3d6055df7b262d0fcb03b37f58c3b0461eef49e3.zip
Fix local kadmin access
-rw-r--r--src/Makefile.am2
-rw-r--r--src/libtdeldap.cpp109
-rw-r--r--src/libtdeldap.h1
3 files changed, 97 insertions, 15 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 4d458e2..5d5b855 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -7,7 +7,7 @@ lib_LTLIBRARIES = libtdeldap.la
include_HEADERS = libtdeldap.h ldappasswddlg.h
libtdeldap_la_SOURCES = libtdeldap.cpp ldaplogindlgbase.ui ldaplogindlg.cpp ldappasswddlg.cpp
-libtdeldap_la_LIBADD = -ltdeio $(LIB_TDEUI) -lldap $(LIB_QT) $(LIB_TDECORE) -ltdesu -llber -lkadm5clnt
+libtdeldap_la_LIBADD = -ltdeio $(LIB_TDEUI) -lldap $(LIB_QT) $(LIB_TDECORE) -ltdesu -llber -lkadm5clnt -lkadm5srv
libtdeldap_la_LDFLAGS = -version-info $(lt_current):$(lt_revision):$(lt_age) -no-undefined \
$(all_libraries)
diff --git a/src/libtdeldap.cpp b/src/libtdeldap.cpp
index d240428..9f5f9a5 100644
--- a/src/libtdeldap.cpp
+++ b/src/libtdeldap.cpp
@@ -46,6 +46,35 @@
#include <sys/time.h>
#include <errno.h>
+#if 0
+ #include <sys/socket.h>
+ #include <sys/un.h>
+ #include <hdb.h>
+ #include <kadm5/admin.h>
+ #include <kadm5/private.h>
+ #include <kadm5/kadm5-private.h>
+#else
+ #include <kadm5/admin.h>
+
+ extern "C" {
+ // The following declaration was taken from hdb-protos.h
+ const char *
+ hdb_db_dir (krb5_context /*context*/);
+
+ // The following declaration was taken from kadm5-private.h
+ kadm5_ret_t
+ kadm5_s_init_with_password_ctx (
+ krb5_context /*context*/,
+ const char */*client_name*/,
+ const char */*password*/,
+ const char */*service_name*/,
+ kadm5_config_params */*realm_params*/,
+ unsigned long /*struct_version*/,
+ unsigned long /*api_version*/,
+ void **/*server_handle*/);
+ }
+#endif
+
#include "libtdeldap.h"
#include "ldaplogindlg.h"
#include "ldappasswddlg.h"
@@ -108,13 +137,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), m_krb5admHandle(0), m_krb5admKeytabFilename(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), m_krb5admRealmName(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), m_krb5admHandle(0), m_krb5admKeytabFilename(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), m_krb5admRealmName(0)
{
TQStringList domainChunks = TQStringList::split(".", realm.lower());
m_basedc = "dc=" + domainChunks.join(",dc=");
@@ -1125,13 +1154,31 @@ int LDAPManager::bindKAdmin(LDAPUserInfo user, TQString *errstr) {
admincreds.use_gssapi = true;
}
+ bool use_local_socket = false;
+ if (m_host.startsWith("ldapi://")) {
+ use_local_socket = true;
+ }
+
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());
-
+ if (!use_local_socket) {
+ params.mask |= KADM5_CONFIG_REALM;
+ if (m_krb5admRealmName) {
+ free(m_krb5admRealmName);
+ }
+ if (admincreds.realm != "") {
+ m_krb5admRealmName = strdup(admincreds.realm.upper().ascii());
+ }
+ else {
+ TQString defaultRealm;
+ fetchAndReadTDERealmList(&defaultRealm);
+ m_krb5admRealmName = strdup(defaultRealm.ascii());
+ }
+ params.realm = m_krb5admRealmName;
+ }
+
TQString adminPrincipal = TQString::null;
if (admincreds.username != "") {
adminPrincipal = admincreds.username.lower() + "@" + admincreds.realm.upper();
@@ -1139,14 +1186,43 @@ int LDAPManager::bindKAdmin(LDAPUserInfo user, TQString *errstr) {
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);
+ if (errstr) *errstr = TQString("%1<p>Details:<br>Failed to execute kadm5_init_krb5_context (code %2)").arg(krb5_get_error_message(m_krb5admContext, krb5adm_ret)).arg(krb5adm_ret);
}
else {
- if (m_host.startsWith("ldapi://")) {
+ if (use_local_socket) {
// 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);
+
+ // Read KDC configuration files
+ int temp_ret;
+ char **files;
+ char* config_file;
+ temp_ret = asprintf(&config_file, "%s/kdc.conf", hdb_db_dir(m_krb5admContext));
+ if (temp_ret == -1) {
+ if (errstr) *errstr = i18n("Out of memory");
+ }
+
+ krb5adm_ret = krb5_prepend_config_files_default(config_file, &files);
+ if (krb5adm_ret) {
+ if (errstr) *errstr = i18n("%1<p>Details:<br>Failed to execute krb5_prepend_config_files_default (code %2)").arg(krb5_get_error_message(m_krb5admContext, krb5adm_ret)).arg(krb5adm_ret);
+ }
+
+ krb5adm_ret = krb5_set_config_files(m_krb5admContext, files);
+ krb5_free_config_files(files);
+ if(krb5adm_ret) {
+ if (errstr) *errstr = i18n("%1<p>Details:<br>Failed to execute krb5_set_config_files (code %2)").arg(krb5_get_error_message(m_krb5admContext, krb5adm_ret)).arg(krb5adm_ret);
+ }
+
+ // Bypass password quality checks
+ kadm5_setup_passwd_quality_check(m_krb5admContext, NULL, NULL);
+ krb5adm_ret = kadm5_add_passwd_quality_verifier(m_krb5admContext, NULL);
+ if (krb5adm_ret) {
+ if (errstr) *errstr = i18n("%1<p>Details:<br>Failed to execute kadm5_add_passwd_quality_verifier (code %2)").arg(krb5_get_error_message(m_krb5admContext, krb5adm_ret)).arg(krb5adm_ret);
+ }
+
+ // Initialize context
+ krb5adm_ret = kadm5_s_init_with_password_ctx(m_krb5admContext, KADM5_ADMIN_SERVICE, NULL, 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 (errstr) *errstr = i18n("%1<p>Details:<br>Failed to execute kadm5_s_init_with_password_ctx (code %2)").arg(krb5_get_error_message(m_krb5admContext, krb5adm_ret)).arg(krb5adm_ret);
}
}
else if (admincreds.use_gssapi) {
@@ -1157,14 +1233,14 @@ int LDAPManager::bindKAdmin(LDAPUserInfo user, TQString *errstr) {
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);
+ if (errstr) *errstr = i18n("%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 {
// 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);
+ 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 (errstr) *errstr = i18n("%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) {
@@ -1179,6 +1255,11 @@ int LDAPManager::bindKAdmin(LDAPUserInfo user, TQString *errstr) {
int LDAPManager::unbindKAdmin(TQString *errstr) {
if (m_krb5admKeytabFilename) {
free(m_krb5admKeytabFilename);
+ m_krb5admKeytabFilename = NULL;
+ }
+ if (m_krb5admRealmName) {
+ free(m_krb5admRealmName);
+ m_krb5admRealmName = NULL;
}
kadm5_destroy(m_krb5admHandle);
@@ -1203,12 +1284,12 @@ int LDAPManager::setPasswordForUser(LDAPUserInfo user, TQString *errstr) {
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);
+ 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);
}
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 (errstr) *errstr = i18n("%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);
}
else {
// Success!
diff --git a/src/libtdeldap.h b/src/libtdeldap.h
index 9905eb6..ee685b4 100644
--- a/src/libtdeldap.h
+++ b/src/libtdeldap.h
@@ -612,6 +612,7 @@ class LDAPManager : public TQObject {
krb5_context m_krb5admContext;
void* m_krb5admHandle;
char* m_krb5admKeytabFilename;
+ char* m_krb5admRealmName;
};
#endif // _LIBTDELDAP_H_