summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTimothy Pearson <kb9vqf@pearsoncomputing.net>2012-06-13 20:56:24 -0500
committerTimothy Pearson <kb9vqf@pearsoncomputing.net>2012-06-13 20:56:24 -0500
commit3ba9d6e8524284bd52d302682575fba68a74ad17 (patch)
tree22ed1616fe0c25917d791c69274e3b7f7b3b44e9
parent7982753d889ecbe324089acee31d825a0ed56024 (diff)
downloadlibtdeldap-3ba9d6e8.tar.gz
libtdeldap-3ba9d6e8.zip
Add service handling routines
-rw-r--r--src/libtdeldap.cpp272
-rw-r--r--src/libtdeldap.h28
2 files changed, 293 insertions, 7 deletions
diff --git a/src/libtdeldap.cpp b/src/libtdeldap.cpp
index 1d5486b..86bd60e 100644
--- a/src/libtdeldap.cpp
+++ b/src/libtdeldap.cpp
@@ -156,7 +156,6 @@ int LDAPManager::bind(TQString* errstr) {
KerberosTicketInfoList m_krbTickets = LDAPManager::getKerberosTicketList();
bool using_ldapi = false;
- bool using_gssapi = false;
if (m_host.startsWith("ldapi://")) {
using_ldapi = true;
}
@@ -177,9 +176,7 @@ int LDAPManager::bind(TQString* errstr) {
m_creds->password = passdlg.m_base->ldapAdminPassword->password();
m_creds->realm = passdlg.m_base->ldapAdminRealm->currentText();
m_creds->use_tls = passdlg.m_base->ldapUseTLS->isOn();
- }
- if (passdlg.use_gssapi) {
- using_gssapi = true;
+ m_creds->use_gssapi = passdlg.use_gssapi;
}
}
else {
@@ -229,7 +226,7 @@ int LDAPManager::bind(TQString* errstr) {
TQCString pass = m_creds->password;
cred.bv_val = pass.data();
cred.bv_len = pass.length();
- if ((!using_ldapi && !using_gssapi)) {
+ if ((!using_ldapi && !m_creds->use_gssapi)) {
if (!ldap_dn.contains(",")) {
// Look for a POSIX account with anonymous bind and the specified account name
TQString uri;
@@ -293,7 +290,7 @@ int LDAPManager::bind(TQString* errstr) {
}
}
- if (using_gssapi) {
+ if (m_creds->use_gssapi) {
retcode = ldap_sasl_interactive_bind_s(m_ldap, "", "GSSAPI", NULL, NULL, LDAP_SASL_AUTOMATIC, sasl_bind_interact_callback, NULL);
}
else {
@@ -1468,6 +1465,109 @@ int LDAPManager::addGroupInfo(LDAPGroupInfo group) {
}
}
+int LDAPManager::addServiceInfo(LDAPServiceInfo service, TQString *errstr) {
+ int retcode;
+ int i;
+ LDAPGroupInfo serviceinfo;
+
+ if (bind() < 0) {
+ return -1;
+ }
+ else {
+ // Use Kerberos kadmin to actually add the service
+ 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];
+ }
+
+ TQCString command = "kadmin";
+ QCStringList args;
+ if (m_host.startsWith("ldapi://")) {
+ args << TQCString("-l") << TQCString("-r") << TQCString(admincreds.realm.upper());
+ }
+ 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());
+ }
+ }
+
+ TQString hoststring = service.name+"/"+service.machine;
+
+ TQString prompt;
+ PtyProcess kadminProc;
+ kadminProc.exec(command, args);
+ prompt = kadminProc.readLine(true);
+ prompt = prompt.stripWhiteSpace();
+ if (prompt == "kadmin>") {
+ kadminProc.writeLine(TQCString("ank --random-key "+hoststring), true);
+ prompt = kadminProc.readLine(true); // Discard our own input
+ prompt = readFullLineFromPtyProcess(&kadminProc);
+ prompt = prompt.stripWhiteSpace();
+ // Use all defaults
+ while (prompt != "kadmin>") {
+ if (prompt.endsWith(" Password:")) {
+ if (admincreds.password == "") {
+ TQCString password;
+ int result = KPasswordDialog::getPassword(password, prompt);
+ if (result == KPasswordDialog::Accepted) {
+ admincreds.password = password;
+ }
+ }
+ if (admincreds.password != "") {
+ kadminProc.writeLine(admincreds.password, true);
+ prompt = kadminProc.readLine(true); // Discard our own input
+ prompt = kadminProc.readLine(true);
+ prompt = prompt.stripWhiteSpace();
+ }
+ }
+ if (prompt.contains("authentication failed")) {
+ if (errstr) *errstr = prompt;
+ 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);
+ }
+ kadminProc.writeLine(TQCString(defaultParam), true);
+ prompt = kadminProc.readLine(true); // Discard our own input
+ prompt = kadminProc.readLine(true);
+ prompt = prompt.stripWhiteSpace();
+ }
+ }
+ if (prompt != "kadmin>") {
+ if (errstr) *errstr = prompt;
+ kadminProc.writeLine("quit", true);
+ return 1;
+ }
+
+ // Success!
+ kadminProc.writeLine("quit", true);
+ unbind(true); // Using kadmin can disrupt our LDAP connection
+
+ // Move Kerberos entries
+ return moveKerberosEntries("o=kerberos,cn=kerberos control,ou=master services,ou=core,ou=realm," + m_basedc, errstr);
+ }
+
+ if (errstr) *errstr = "Internal error. Verify that kadmin exists and can be executed.";
+ return 1; // Failure
+
+ }
+}
+
int LDAPManager::deleteUserInfo(LDAPUserInfo user) {
int retcode;
LDAPUserInfo userinfo;
@@ -1528,6 +1628,26 @@ int LDAPManager::deleteMachineInfo(LDAPMachineInfo machine) {
}
}
+int LDAPManager::deleteServiceInfo(LDAPServiceInfo service) {
+ int retcode;
+ LDAPServiceInfo serviceinfo;
+
+ if (bind() < 0) {
+ return -1;
+ }
+ else {
+ // Delete the base DN entry
+ retcode = ldap_delete_ext_s(m_ldap, service.distinguishedName.ascii(), NULL, NULL);
+ if (retcode != LDAP_SUCCESS) {
+ KMessageBox::error(0, i18n("<qt>LDAP deletion failure<p>Reason: [%3] %4</qt>").arg(retcode).arg(ldap_err2string(retcode)), i18n("LDAP Error"));
+ return -2;
+ }
+ else {
+ return 0;
+ }
+ }
+}
+
LDAPGroupInfo LDAPManager::parseLDAPGroupRecord(LDAPMessage* entry) {
char* dn = NULL;
char* attr;
@@ -1632,6 +1752,52 @@ LDAPMachineInfo LDAPManager::parseLDAPMachineRecord(LDAPMessage* entry) {
return machineinfo;
}
+LDAPServiceInfo LDAPManager::parseLDAPMachineServiceRecord(LDAPMessage* entry) {
+ char* dn = NULL;
+ char* attr;
+ struct berval **vals;
+ BerElement* ber;
+ int i;
+
+ LDAPServiceInfo machineserviceinfo;
+
+ if((dn = ldap_get_dn(m_ldap, entry)) != NULL) {
+ machineserviceinfo.distinguishedName = dn;
+ TQStringList dnParts = TQStringList::split(",", dn);
+ TQString id = dnParts[0];
+ dnParts = TQStringList::split("/", id);
+ id = dnParts[0];
+ dnParts = TQStringList::split("=", id);
+ machineserviceinfo.name = dnParts[1];
+ ldap_memfree(dn);
+ }
+
+ for( attr = ldap_first_attribute(m_ldap, entry, &ber); attr != NULL; attr = ldap_next_attribute(m_ldap, entry, ber)) {
+ if ((vals = ldap_get_values_len(m_ldap, entry, attr)) != NULL) {
+ machineserviceinfo.informationValid = true;
+ TQString ldap_field = attr;
+ i=0;
+ if (ldap_field == "creatorsName") {
+ machineserviceinfo.creatorsName = vals[i]->bv_val;
+ }
+ else if (ldap_field == "tdeBuiltinAccount") {
+ machineserviceinfo.tde_builtin_account = (TQString(vals[i]->bv_val).upper() == "TRUE")?true:false;
+ }
+ else if (ldap_field == "krb5KDCFlags") {
+ machineserviceinfo.status = (LDAPKRB5Flags)(atoi(vals[i]->bv_val));
+ }
+ ldap_value_free_len(vals);
+ }
+ ldap_memfree(attr);
+ }
+
+ if (ber != NULL) {
+ ber_free(ber, 0);
+ }
+
+ return machineserviceinfo;
+}
+
LDAPGroupInfoList LDAPManager::groups(int* mretcode) {
int retcode;
LDAPGroupInfoList groups;
@@ -1702,6 +1868,87 @@ LDAPMachineInfoList LDAPManager::machines(int* mretcode) {
return LDAPMachineInfoList();
}
+LDAPServiceInfoList LDAPManager::services(int* mretcode) {
+ int retcode;
+ LDAPServiceInfoList services;
+
+ if (bind() < 0) {
+ if (mretcode) *mretcode = -1;
+ return LDAPServiceInfoList();
+ }
+ else {
+ int machineSearchRet;
+ LDAPMachineInfoList machineList = machines(&machineSearchRet);
+ if (machineSearchRet != 0) {
+ if (mretcode) *mretcode = -1;
+ return LDAPServiceInfoList();
+ }
+
+ LDAPMachineInfoList::Iterator it;
+ for (it = machineList.begin(); it != machineList.end(); ++it) {
+ LDAPMachineInfo machine = *it;
+ LDAPServiceInfoList thisMachineServiceList = machineServices(machine.distinguishedName);
+ LDAPServiceInfoList::Iterator it2;
+ for (it2 = thisMachineServiceList.begin(); it2 != thisMachineServiceList.end(); ++it2) {
+ services.append(*it2);
+ }
+ }
+
+ if (mretcode) *mretcode = 0;
+ return services;
+ }
+
+ return LDAPServiceInfoList();
+}
+
+LDAPServiceInfoList LDAPManager::machineServices(TQString machine_dn, int* mretcode) {
+ int retcode;
+ LDAPServiceInfoList services;
+
+ if (bind() < 0) {
+ if (mretcode) *mretcode = -1;
+ return LDAPServiceInfoList();
+ }
+ else {
+ LDAPMessage* msg;
+ TQString ldap_base_dn = m_basedc;
+
+ TQStringList machinednParts = TQStringList::split(",", machine_dn);
+ TQString machine_name = machinednParts[0];
+ if (machine_name.startsWith("krb5PrincipalName=host/")) {
+ machine_name = machine_name.remove(0, 23);
+ machine_name.replace("@"+m_realm, "");
+ }
+
+ TQString ldap_filter = TQString("(&(objectClass=krb5Principal)(uid=*/%1))").arg(machine_name);
+ retcode = ldap_search_ext_s(m_ldap, ldap_base_dn.ascii(), LDAP_SCOPE_SUBTREE, ldap_filter.ascii(), ldap_user_and_operational_attributes, 0, NULL, NULL, NULL, 0, &msg);
+ if (retcode != LDAP_SUCCESS) {
+ KMessageBox::error(0, i18n("<qt>LDAP search failure<p>Reason: [%3] %4</qt>").arg(retcode).arg(ldap_err2string(retcode)), i18n("LDAP Error"));
+ if (mretcode) *mretcode = -1;
+ return LDAPServiceInfoList();
+ }
+
+ // Iterate through the returned entries
+ LDAPMessage* entry;
+ for(entry = ldap_first_entry(m_ldap, msg); entry != NULL; entry = ldap_next_entry(m_ldap, entry)) {
+ LDAPServiceInfo sinfo = parseLDAPMachineServiceRecord(entry);
+ sinfo.machine_dn = machine_dn;
+ sinfo.machine = machine_name;
+ if (sinfo.name != "host") {
+ services.append(sinfo);
+ }
+ }
+
+ // clean up
+ ldap_msgfree(msg);
+
+ if (mretcode) *mretcode = 0;
+ return services;
+ }
+
+ return LDAPServiceInfoList();
+}
+
int LDAPManager::writeCertificateFileIntoDirectory(TQByteArray cert, TQString attr, TQString* errstr) {
int retcode;
int i;
@@ -2245,6 +2492,7 @@ TQString LDAPManager::getMachineFQDN() {
LDAPCredentials::LDAPCredentials() {
// TQStrings are always initialized to TQString::null, so they don't need initialization here...
use_tls = true;
+ use_gssapi = false;
}
LDAPCredentials::~LDAPCredentials() {
@@ -2301,6 +2549,18 @@ LDAPMachineInfo::~LDAPMachineInfo() {
//
}
+LDAPServiceInfo::LDAPServiceInfo() {
+ // TQStrings are always initialized to TQString::null, so they don't need initialization here...
+ informationValid = false;
+
+ tde_builtin_account = false;
+ status = (LDAPKRB5Flags)0;
+}
+
+LDAPServiceInfo::~LDAPServiceInfo() {
+ //
+}
+
LDAPTDEBuiltinsInfo::LDAPTDEBuiltinsInfo() {
// TQStrings are always initialized to TQString::null, so they don't need initialization here...
informationValid = false;
diff --git a/src/libtdeldap.h b/src/libtdeldap.h
index 35d3c27..341dff9 100644
--- a/src/libtdeldap.h
+++ b/src/libtdeldap.h
@@ -81,6 +81,7 @@ enum LDAPKRB5Flags {
KRB5_ACTIVE_DEFAULT = KRB5_FORWARDABLE | KRB5_RENEWABLE | KRB5_CLIENT | KRB5_CHANGE_PW,
KRB5_DISABLED_ACCOUNT = KRB5_FORWARDABLE | KRB5_SERVER | KRB5_INVALID | KRB5_REQUIRE_PREAUTH | KRB5_REQUIRE_HWAUTH | KRB5_OK_AS_DELEGATE | KRB5_USER_TO_USER,
KRB5_MACHINE_ACCOUNT_DEFAULT = KRB5_FORWARDABLE | KRB5_PROXIABLE | KRB5_RENEWABLE | KRB5_POSTDATE | KRB5_SERVER | KRB5_CLIENT,
+ KRB5_SERVICE_PRINCIPAL_DEFAULT = KRB5_FORWARDABLE | KRB5_PROXIABLE | KRB5_RENEWABLE | KRB5_POSTDATE | KRB5_SERVER | KRB5_CLIENT,
KRB5_FLAG_MAX = 0x80000000
};
@@ -140,6 +141,7 @@ class LDAPCredentials
TQCString password;
TQString realm;
bool use_tls;
+ bool use_gssapi;
TQString service;
};
@@ -295,7 +297,25 @@ class LDAPMachineInfo
TQString name;
bool tde_builtin_account;
- LDAPKRB5Flags status;
+ LDAPKRB5Flags status; // Default is 126 [KRB5_MACHINE_ACCOUNT_DEFAULT]
+};
+
+class LDAPServiceInfo
+{
+ public:
+ LDAPServiceInfo();
+ ~LDAPServiceInfo();
+
+ public:
+ bool informationValid;
+ TQString distinguishedName;
+ TQString creatorsName;
+
+ TQString name;
+ TQString machine;
+ TQString machine_dn;
+ bool tde_builtin_account;
+ LDAPKRB5Flags status; // Default is 126 [KRB5_SERVICE_PRINCIPAL_DEFAULT]
};
class LDAPTDEBuiltinsInfo
@@ -338,6 +358,7 @@ class KerberosTicketInfo
typedef TQValueList<LDAPUserInfo> LDAPUserInfoList;
typedef TQValueList<LDAPGroupInfo> LDAPGroupInfoList;
typedef TQValueList<LDAPMachineInfo> LDAPMachineInfoList;
+typedef TQValueList<LDAPServiceInfo> LDAPServiceInfoList;
typedef TQValueList<KerberosTicketInfo> KerberosTicketInfoList;
class LDAPManager : public TQObject {
@@ -355,15 +376,19 @@ class LDAPManager : public TQObject {
LDAPUserInfoList users(int* retcode=0);
LDAPGroupInfoList groups(int* retcode=0);
LDAPMachineInfoList machines(int* retcode=0);
+ LDAPServiceInfoList machineServices(TQString machine_dn, int* retcode=0);
+ LDAPServiceInfoList services(int* retcode=0);
LDAPUserInfo getUserByDistinguishedName(TQString dn);
LDAPGroupInfo getGroupByDistinguishedName(TQString dn, TQString *errstr=0);
int updateUserInfo(LDAPUserInfo user);
int updateGroupInfo(LDAPGroupInfo group);
int addUserInfo(LDAPUserInfo user);
int addGroupInfo(LDAPGroupInfo group);
+ int addServiceInfo(LDAPServiceInfo service, TQString *errstr=0);
int deleteUserInfo(LDAPUserInfo user);
int deleteGroupInfo(LDAPGroupInfo group);
int deleteMachineInfo(LDAPMachineInfo machine);
+ int deleteServiceInfo(LDAPServiceInfo service);
LDAPCredentials currentLDAPCredentials();
@@ -400,6 +425,7 @@ class LDAPManager : public TQObject {
LDAPUserInfo parseLDAPUserRecord(LDAPMessage* entry);
LDAPGroupInfo parseLDAPGroupRecord(LDAPMessage* entry);
LDAPMachineInfo parseLDAPMachineRecord(LDAPMessage* entry);
+ LDAPServiceInfo parseLDAPMachineServiceRecord(LDAPMessage* entry);
LDAPTDEBuiltinsInfo parseLDAPTDEBuiltinsRecord(LDAPMessage* entry);
private: