|
|
|
@ -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;
|
|
|
|
|