diff options
author | Timothy Pearson <[email protected]> | 2012-06-11 02:10:36 -0500 |
---|---|---|
committer | Timothy Pearson <[email protected]> | 2012-06-11 02:10:36 -0500 |
commit | 072098e10daf6fb9a0af0065d9b1130c5405bd0d (patch) | |
tree | e8f4d033a91762be90768e6e69a4ac4c70481052 /src/libtdeldap.cpp | |
parent | df417d4eda7b5900fd99666093d5b346d4a8aefb (diff) | |
download | libtdeldap-072098e10daf6fb9a0af0065d9b1130c5405bd0d.tar.gz libtdeldap-072098e10daf6fb9a0af0065d9b1130c5405bd0d.zip |
Add a variety of ticket management functions
Diffstat (limited to 'src/libtdeldap.cpp')
-rw-r--r-- | src/libtdeldap.cpp | 332 |
1 files changed, 331 insertions, 1 deletions
diff --git a/src/libtdeldap.cpp b/src/libtdeldap.cpp index cbb5b69..6d954a8 100644 --- a/src/libtdeldap.cpp +++ b/src/libtdeldap.cpp @@ -35,6 +35,7 @@ #include <ksimpleconfig.h> #include <tdesu/process.h> #include <ksslcertificate.h> +#include <krfcdate.h> #include <ldap.h> #include <stdlib.h> @@ -153,6 +154,8 @@ printf("[RAJA DEBUG 600.0] In LDAPManager::bind(%p)\n\r", errstr); fflush(stdout return 0; } + KerberosTicketInfoList m_krbTickets = LDAPManager::getKerberosTicketList(); + bool using_ldapi = false; bool using_gssapi = false; if (m_host.startsWith("ldapi://")) { @@ -164,7 +167,7 @@ printf("[RAJA DEBUG 600.0] In LDAPManager::bind(%p)\n\r", errstr); fflush(stdout } else { printf("[RAJA DEBUG 660.1]\n\r"); fflush(stdout); - LDAPPasswordDialog passdlg(0); + LDAPPasswordDialog passdlg(0, 0, (m_krbTickets.count() > 0)); passdlg.m_base->ldapAdminRealm->setEnabled(false); passdlg.m_base->ldapAdminRealm->insertItem(m_realm); passdlg.m_base->ldapUseTLS->setChecked(true); @@ -865,6 +868,11 @@ int LDAPManager::setPasswordForUser(LDAPUserInfo user, TQString *errstr) { // RAJA FIXME // How to handle GSSAPI auth? + // We can't really at this point + // GSSAPI and friends ONLY WORK if 'kinit -S kadmin/admin' was run after the inital TGT was granted + // What we need is a proper ticket management system + // Also, why doesn't 'kgetcred kadmin/admin' work? + // For now, let's just prompt for the password if admincreds.password == "" TQCString command = "kadmin"; QCStringList args; @@ -928,6 +936,314 @@ int LDAPManager::setPasswordForUser(LDAPUserInfo user, TQString *errstr) { return 1; // Failure } +TQString klistDateTimeToRFCDateTime(TQString datetime) { + // HACK HACK HACK + // FIXME + TQString ret; + TQString command = TQString("date -R -d \"%1\"").arg(datetime); + FILE *output = popen(command.ascii(), "r"); + TQFile f; + f.open(IO_ReadOnly, output); + TQTextStream stream(&f); + ret = stream.readLine(); + f.close(); + pclose(output); + + return ret; +} + +#define KLIST_CREDENTIALS_CACHE_STRING "Credentials cache: " +#define KLIST_PRINCIPAL_STRING "Principal: " +#define KLIST_CACHE_VERSION_STRING "Cache version: " +#define KLIST_SERVER_STRING "Server: " +#define KLIST_CLIENT_STRING "Client: " +#define KLIST_ENCTYPE_STRING "Ticket etype: " +#define KLIST_TICKET_LENGTH_STRING "Ticket length: " +#define KLIST_AUTHTIME_STRING "Auth time: " +#define KLIST_STARTTIME_STRING "Start time: " +#define KLIST_STOPTIME_STRING "End time: " +#define KLIST_FLAGS_STRING "Ticket flags: " +#define KLIST_ADDRESSES_STRING "Ticket flags: " +#define KLIST_NO_TICKET_FILE "klist: No ticket file: " +#define KLIST_KVNO_STRING "kvno" + +#define KLIST_ADDRESSLESS_STRING "addressless" + +#define KLIST_KRB5_TICKET_RESERVED "reserved" +#define KLIST_KRB5_TICKET_FORWARDABLE "forwardable" +#define KLIST_KRB5_TICKET_FORWARDED "forwarded" +#define KLIST_KRB5_TICKET_PROXIABLE "proxiable" +#define KLIST_KRB5_TICKET_PROXY "proxy" +#define KLIST_KRB5_TICKET_MAY_POSTDATE "may-postdate" +#define KLIST_KRB5_TICKET_POSTDATED "postdated" +#define KLIST_KRB5_TICKET_INVALID "invalid" +#define KLIST_KRB5_TICKET_RENEWABLE "renewable" +#define KLIST_KRB5_TICKET_INITIAL "initial" +#define KLIST_KRB5_TICKET_PREAUTHENT "pre-authent" +#define KLIST_KRB5_TICKET_HW_AUTHENT "hw-authent" +#define KLIST_KRB5_TICKET_TRANSIT_CHECKED "transited-policy-checked" +#define KLIST_KRB5_TICKET_OK_AS_DELEGATE "ok-as-delegate" +#define KLIST_KRB5_TICKET_ANONYMOUS "anonymous" +#define KLIST_KRB5_TICKET_ENC_PA_REP "enc-pa-rep" + +KerberosTicketInfoList LDAPManager::getKerberosTicketList(TQString cache, TQString *cacheFileName) { + KerberosTicketInfo ticket; + KerberosTicketInfoList list; + + TQString global_ccache; + TQString global_principal; + TQString global_cachevers; + + TQString line; + FILE *output = popen("klist -v 2>&1", "r"); + TQFile f; + f.open(IO_ReadOnly, output); + TQTextStream stream(&f); + while ( !stream.atEnd() ) { + line = stream.readLine(); + line = line.stripWhiteSpace(); + if (line == "") { + if (ticket.informationValid) { + ticket.cacheURL = global_ccache; + ticket.cachePrincipal = global_principal; + ticket.cacheVersion = global_cachevers.toInt(); + list.append(ticket); + } + ticket = KerberosTicketInfo(); + } + else if (line.startsWith(KLIST_NO_TICKET_FILE)) { + line.remove(0, strlen(KLIST_NO_TICKET_FILE)); + line.prepend("FILE:"); + if (cacheFileName) *cacheFileName = line; + } + else if (line.startsWith(KLIST_CREDENTIALS_CACHE_STRING)) { + line.remove(0, strlen(KLIST_CREDENTIALS_CACHE_STRING)); + global_ccache = line; + if (cacheFileName) *cacheFileName = line; + } + else if (line.startsWith(KLIST_PRINCIPAL_STRING)) { + line.remove(0, strlen(KLIST_PRINCIPAL_STRING)); + global_principal = line; + } + else if (line.startsWith(KLIST_CACHE_VERSION_STRING)) { + line.remove(0, strlen(KLIST_CACHE_VERSION_STRING)); + global_cachevers = line; + } + else if (line.startsWith(KLIST_SERVER_STRING)) { + line.remove(0, strlen(KLIST_SERVER_STRING)); + ticket.serverPrincipal = line; + ticket.informationValid = true; + } + else if (line.startsWith(KLIST_CLIENT_STRING)) { + line.remove(0, strlen(KLIST_CLIENT_STRING)); + ticket.clientPrincipal = line; + ticket.informationValid = true; + } + else if (line.startsWith(KLIST_ENCTYPE_STRING)) { + line.remove(0, strlen(KLIST_ENCTYPE_STRING)); + TQString kvno = line; + int commaloc = line.find(","); + kvno.remove(0, commaloc+1); + kvno.replace(KLIST_KVNO_STRING, ""); + kvno = kvno.stripWhiteSpace(); + line.truncate(commaloc); + ticket.encryptionType = line; + ticket.keyVersionNumber = kvno.toInt(); + ticket.informationValid = true; + } + else if (line.startsWith(KLIST_TICKET_LENGTH_STRING)) { + line.remove(0, strlen(KLIST_TICKET_LENGTH_STRING)); + ticket.ticketSize = line.toInt(); + ticket.informationValid = true; + } + else if (line.startsWith(KLIST_AUTHTIME_STRING)) { + line.remove(0, strlen(KLIST_AUTHTIME_STRING)); + line.replace("(expired)", ""); + line = line.simplifyWhiteSpace(); + line = klistDateTimeToRFCDateTime(line); + ticket.authenticationTime.setTime_t(KRFCDate::parseDate(line)); + ticket.informationValid = true; + } + else if (line.startsWith(KLIST_STARTTIME_STRING)) { + line.remove(0, strlen(KLIST_STARTTIME_STRING)); + line.replace("(expired)", ""); + line = line.simplifyWhiteSpace(); + line = klistDateTimeToRFCDateTime(line); + ticket.validStartTime.setTime_t(KRFCDate::parseDate(line)); + ticket.informationValid = true; + } + else if (line.startsWith(KLIST_STOPTIME_STRING)) { + line.remove(0, strlen(KLIST_STOPTIME_STRING)); + line.replace("(expired)", ""); + line = line.simplifyWhiteSpace(); + line = klistDateTimeToRFCDateTime(line); + ticket.validEndTime.setTime_t(KRFCDate::parseDate(line)); + ticket.informationValid = true; + } + else if (line.startsWith(KLIST_FLAGS_STRING)) { + line.remove(0, strlen(KLIST_FLAGS_STRING)); + TQStringList flags = TQStringList::split(",", line, FALSE); + for (TQStringList::Iterator it = flags.begin(); it != flags.end(); ++it) { + if ((*it) == KLIST_KRB5_TICKET_RESERVED) { + ticket.flags = ticket.flags | KRB5_TICKET_RESERVED; + } + else if ((*it) == KLIST_KRB5_TICKET_FORWARDABLE) { + ticket.flags = ticket.flags | KRB5_TICKET_FORWARDABLE; + } + else if ((*it) == KLIST_KRB5_TICKET_FORWARDED) { + ticket.flags = ticket.flags | KRB5_TICKET_FORWARDED; + } + else if ((*it) == KLIST_KRB5_TICKET_PROXIABLE) { + ticket.flags = ticket.flags | KRB5_TICKET_PROXIABLE; + } + else if ((*it) == KLIST_KRB5_TICKET_PROXY) { + ticket.flags = ticket.flags | KRB5_TICKET_PROXY; + } + else if ((*it) == KLIST_KRB5_TICKET_MAY_POSTDATE) { + ticket.flags = ticket.flags | KRB5_TICKET_MAY_POSTDATE; + } + else if ((*it) == KLIST_KRB5_TICKET_POSTDATED) { + ticket.flags = ticket.flags | KRB5_TICKET_POSTDATED; + } + else if ((*it) == KLIST_KRB5_TICKET_INVALID) { + ticket.flags = ticket.flags | KRB5_TICKET_INVALID; + } + else if ((*it) == KLIST_KRB5_TICKET_RENEWABLE) { + ticket.flags = ticket.flags | KRB5_TICKET_RENEWABLE; + } + else if ((*it) == KLIST_KRB5_TICKET_INITIAL) { + ticket.flags = ticket.flags | KRB5_TICKET_INITIAL; + } + else if ((*it) == KLIST_KRB5_TICKET_PREAUTHENT) { + ticket.flags = ticket.flags | KRB5_TICKET_PREAUTHENT; + } + else if ((*it) == KLIST_KRB5_TICKET_HW_AUTHENT) { + ticket.flags = ticket.flags | KRB5_TICKET_HW_AUTHENT; + } + else if ((*it) == KLIST_KRB5_TICKET_TRANSIT_CHECKED) { + ticket.flags = ticket.flags | KRB5_TICKET_TRANSIT_CHECKED; + } + else if ((*it) == KLIST_KRB5_TICKET_OK_AS_DELEGATE) { + ticket.flags = ticket.flags | KRB5_TICKET_OK_AS_DELEGATE; + } + else if ((*it) == KLIST_KRB5_TICKET_ANONYMOUS) { + ticket.flags = ticket.flags | KRB5_TICKET_ANONYMOUS; + } + else if ((*it) == KLIST_KRB5_TICKET_ENC_PA_REP) { + ticket.flags = ticket.flags | KRB5_TICKET_ENC_PA_REP; + } + } + ticket.informationValid = true; + } + else if (line.startsWith(KLIST_ADDRESSES_STRING)) { + line.remove(0, strlen(KLIST_ADDRESSES_STRING)); + if (line != KLIST_ADDRESSLESS_STRING) { + // FIXME + // What is the separator? + ticket.addresses = TQStringList(line); + } + ticket.informationValid = true; + } + } + f.close(); + pclose(output); + + return list; +} + +int LDAPManager::getKerberosPassword(LDAPCredentials &creds, TQString prompt, bool requestServicePrincipal, TQWidget* parent) +{ + int i; + + KSimpleConfig* systemconfig = new KSimpleConfig( TQString::fromLatin1( KDE_CONFDIR "/ldap/ldapconfigrc" )); + systemconfig->setGroup(NULL); + TQString defaultRealm = systemconfig->readEntry("DefaultRealm", TQString::null); + LDAPRealmConfigList realms = LDAPManager::readTDERealmList(systemconfig, false); + delete systemconfig; + + if (creds.realm != "") { + defaultRealm = creds.realm; + } + LDAPPasswordDialog passdlg(parent, 0, false); + passdlg.m_base->ldapAdminRealm->setEnabled(true); + LDAPRealmConfigList::Iterator it; + i=0; + for (it = realms.begin(); it != realms.end(); ++it) { + passdlg.m_base->ldapAdminRealm->insertItem((*it).name); + if ((*it).name == defaultRealm) { + passdlg.m_base->ldapAdminRealm->setCurrentItem(i); + } + i++; + } + passdlg.m_base->passprompt->setText(prompt); + passdlg.m_base->ldapUseTLS->hide(); + if (requestServicePrincipal) { + passdlg.m_base->kerberosOtherInfoString->show(); + passdlg.m_base->kerberosServicePrincipal->show(); + } + if (creds.username != "") { + passdlg.m_base->ldapAdminUsername->setText(creds.username); + passdlg.m_base->ldapAdminPassword->setFocus(); + } + const int ret = passdlg.exec(); + if (ret == KDialog::Accepted) { + creds.username = passdlg.m_base->ldapAdminUsername->text(); + creds.password = passdlg.m_base->ldapAdminPassword->password(); + creds.realm = passdlg.m_base->ldapAdminRealm->currentText(); + creds.service = passdlg.m_base->kerberosServicePrincipal->text(); + creds.use_tls = passdlg.m_base->ldapUseTLS->isOn(); + } + return ret; +} + +int LDAPManager::obtainKerberosTicket(LDAPCredentials creds, TQString principal, TQString *errstr) { + TQCString command = "kinit"; + QCStringList args; + if (principal == "") { + args << TQCString(creds.username + "@" + creds.realm.upper()); + } + else { + args << TQCString("-S") << TQCString(principal) << TQCString(creds.username + "@" + creds.realm.upper()); + } + + TQString prompt; + PtyProcess kadminProc; + kadminProc.exec(command, args); + prompt = kadminProc.readLine(true); + prompt = prompt.stripWhiteSpace(); + if (prompt.endsWith(" Password:")) { + kadminProc.writeLine(creds.password, true); + prompt = kadminProc.readLine(true); // Discard our own input + prompt = kadminProc.readLine(true); + prompt = prompt.stripWhiteSpace(); + } + if (prompt != "") { + if (errstr) *errstr = prompt; + return 1; + } + + // Success! + return 0; +} + +int LDAPManager::destroyKerberosTicket(TQString principal, TQString *errstr) { + TQString ret; + TQString command = TQString("kdestroy --credential=\"%1\"").arg(principal); + FILE *output = popen(command.ascii(), "r"); + TQFile f; + f.open(IO_ReadOnly, output); + TQTextStream stream(&f); + ret = stream.readLine(); + f.close(); + pclose(output); + + if (ret != "") { + if (errstr) *errstr = ret; + return -1; + } + return 0; +} + int LDAPManager::updateGroupInfo(LDAPGroupInfo group) { int retcode; int i; @@ -1992,4 +2308,18 @@ LDAPTDEBuiltinsInfo::~LDAPTDEBuiltinsInfo() { // } +KerberosTicketInfo::KerberosTicketInfo() { + // TQStrings are always initialized to TQString::null, so they don't need initialization here... + informationValid = false; + + cacheVersion = -1; + keyVersionNumber = -1; + ticketSize = -1; + flags = (KRB5TicketFlags)0; +} + +KerberosTicketInfo::~KerberosTicketInfo() { + // +} + #include "libtdeldap.moc"
\ No newline at end of file |