diff options
-rw-r--r-- | src/groupconfigdlg.cpp | 20 | ||||
-rw-r--r-- | src/ldapmgr.cpp | 63 | ||||
-rw-r--r-- | src/ldapmgr.h | 2 | ||||
-rw-r--r-- | src/libtdeldap.cpp | 171 | ||||
-rw-r--r-- | src/libtdeldap.h | 4 | ||||
-rw-r--r-- | src/userconfigdlg.cpp | 18 |
6 files changed, 270 insertions, 8 deletions
diff --git a/src/groupconfigdlg.cpp b/src/groupconfigdlg.cpp index 94b70e4..5629d2e 100644 --- a/src/groupconfigdlg.cpp +++ b/src/groupconfigdlg.cpp @@ -45,10 +45,13 @@ GroupConfigDialog::GroupConfigDialog(LDAPGroupInfo group, LDAPConfig* parent, co m_base->addToGroup->setText(i18n("-->")); m_base->removeFromGroup->setText(i18n("<--")); - m_base->groupName->setEnabled(false); + if (group.distinguishedName != "") { + m_base->groupName->setEnabled(false); + } connect(m_base->addToGroup, TQT_SIGNAL(clicked()), this, TQT_SLOT(addSelectedUserToGroup())); connect(m_base->removeFromGroup, TQT_SIGNAL(clicked()), this, TQT_SLOT(removeSelectedUserFromGroup())); + connect(m_base->groupName, TQT_SIGNAL(textChanged(const TQString&)), this, TQT_SLOT(processLockouts())); // Update fields m_base->groupName->setText(m_group.name); @@ -72,7 +75,7 @@ GroupConfigDialog::GroupConfigDialog(LDAPGroupInfo group, LDAPConfig* parent, co } void GroupConfigDialog::slotOk() { - int i; + unsigned int i; // Update data m_group.gid = m_base->groupID->value(); @@ -85,11 +88,22 @@ void GroupConfigDialog::slotOk() { } m_group.userlist = userlist; + // Special handler for new group + if (m_group.distinguishedName == "") { + m_group.name = m_base->groupName->text(); + } + accept(); } void GroupConfigDialog::processLockouts() { - // + // Special handler for new group + if ((m_group.distinguishedName == "") && (m_base->groupName->text() == "")) { + enableButton(KDialogBase::Ok, false); + } + else { + enableButton(KDialogBase::Ok, true); + } } void GroupConfigDialog::addSelectedUserToGroup() { diff --git a/src/ldapmgr.cpp b/src/ldapmgr.cpp index ba45fd1..d506902 100644 --- a/src/ldapmgr.cpp +++ b/src/ldapmgr.cpp @@ -84,8 +84,10 @@ LDAPConfig::LDAPConfig(TQWidget *parent, const char *name, const TQStringList&) connect(base->user_list, TQT_SIGNAL(selectionChanged()), this, TQT_SLOT(userHighlighted())); connect(base->group_list, TQT_SIGNAL(selectionChanged()), this, TQT_SLOT(groupHighlighted())); + connect(base->group_buttonAdd, TQT_SIGNAL(clicked()), this, TQT_SLOT(addNewGroup())); connect(base->user_buttonModify, TQT_SIGNAL(clicked()), this, TQT_SLOT(modifySelectedUser())); connect(base->group_buttonModify, TQT_SIGNAL(clicked()), this, TQT_SLOT(modifySelectedGroup())); + connect(base->group_buttonDelete, TQT_SIGNAL(clicked()), this, TQT_SLOT(removeSelectedGroup())); load(); @@ -108,6 +110,8 @@ void LDAPConfig::load() { // Load realms int i; base->user_ldapRealm->clear(); + base->group_ldapRealm->clear(); + base->machine_ldapRealm->clear(); TQStringList cfgRealms = m_systemconfig->groupList(); for (TQStringList::Iterator it(cfgRealms.begin()); it != cfgRealms.end(); ++it) { if ((*it).startsWith("LDAPRealm-")) { @@ -115,6 +119,8 @@ void LDAPConfig::load() { TQString realmName=*it; realmName.remove(0,strlen("LDAPRealm-")); base->user_ldapRealm->insertItem(realmName); + base->group_ldapRealm->insertItem(realmName); + base->machine_ldapRealm->insertItem(realmName); } } TQString defaultRealm = m_systemconfig->readEntry("DefaultRealm", TQString::null); @@ -122,6 +128,8 @@ void LDAPConfig::load() { for (i=0; i<base->user_ldapRealm->count(); i++) { if (base->user_ldapRealm->text(i).lower() == defaultRealm.lower()) { base->user_ldapRealm->setCurrentItem(i); + base->group_ldapRealm->setCurrentItem(i); + base->machine_ldapRealm->setCurrentItem(i); break; } } @@ -343,11 +351,50 @@ void LDAPConfig::groupHighlighted() { (void)new TQListViewItem(base->group_memberList, user.name, user.commonName, TQString("%1").arg(user.uid)); } - // RAJA FIXME - processLockouts(); } +void LDAPConfig::addNewGroup() { + // Launch a dialog to add the group + LDAPGroupInfo group; + + // Find the next available, reasonable GID + gid_t gid = 100; + LDAPGroupInfoList::Iterator it; + for (it = m_groupInfoList.begin(); it != m_groupInfoList.end(); ++it) { + LDAPGroupInfo group = *it; + if (group.gid >= gid) { + gid = group.gid + 1; + } + } + group.gid = gid; + + GroupConfigDialog groupconfigdlg(group, this); + if (groupconfigdlg.exec() == TQDialog::Accepted) { + group = groupconfigdlg.m_group; + if (group.name != "") { + // Try to find a reasonable place to stuff the new entry + // Do any groups exist right now? + if (m_groupInfoList.begin() != m_groupInfoList.end()) { + group.distinguishedName = (*m_groupInfoList.begin()).distinguishedName; + int eqpos = group.distinguishedName.find("=")+1; + int cmpos = group.distinguishedName.find(",", eqpos); + group.distinguishedName.remove(eqpos, cmpos-eqpos); + group.distinguishedName.insert(eqpos, group.name); + } + else { + group.distinguishedName = "cn=" + group.name + "," + m_ldapmanager->basedn(); + } + m_ldapmanager->addGroupInfo(group); + } + else { + // PEBKAC + KMessageBox::error(0, i18n("<qt>Unable to add new group with no name!<p>Enter a name and try again</qt>"), i18n("Illegal Operation")); + } + } + updateAllInformation(); +} + void LDAPConfig::modifySelectedUser() { // Launch a dialog to edit the user LDAPUserInfo user = selectedUser(); @@ -362,7 +409,7 @@ void LDAPConfig::modifySelectedUser() { } void LDAPConfig::modifySelectedGroup() { - // Launch a dialog to edit the user + // Launch a dialog to edit the group LDAPGroupInfo group = selectedGroup(); // Reload group data from LDAP before launching dialog @@ -371,8 +418,18 @@ void LDAPConfig::modifySelectedGroup() { if (groupconfigdlg.exec() == TQDialog::Accepted) { group = groupconfigdlg.m_group; m_ldapmanager->updateGroupInfo(group); + } + updateAllInformation(); +} + +void LDAPConfig::removeSelectedGroup() { + LDAPGroupInfo group = selectedGroup(); + + if (KMessageBox::warningYesNo(this, i18n("<qt><b>You are about to delete the group %1</b><br>This action cannot be undone<p>Are you sure you want to proceed?</qt>").arg(group.name), i18n("Confirmation Required")) == KMessageBox::Yes) { // RAJA FIXME + m_ldapmanager->deleteGroupInfo(group); } + updateAllInformation(); } diff --git a/src/ldapmgr.h b/src/ldapmgr.h index 8c7e594..6d88ecc 100644 --- a/src/ldapmgr.h +++ b/src/ldapmgr.h @@ -59,8 +59,10 @@ class LDAPConfig: public KCModule void updateGroupsList(); void userHighlighted(); void groupHighlighted(); + void addNewGroup(); void modifySelectedUser(); void modifySelectedGroup(); + void removeSelectedGroup(); void updateAllInformation(); public: diff --git a/src/libtdeldap.cpp b/src/libtdeldap.cpp index b8ce094..b9ffdf4 100644 --- a/src/libtdeldap.cpp +++ b/src/libtdeldap.cpp @@ -47,6 +47,10 @@ LDAPManager::~LDAPManager() { unbind(true); } +TQString LDAPManager::basedn() { + return m_basedc; +} + TQString LDAPManager::realm() { return m_realm; } @@ -505,6 +509,30 @@ LDAPGroupInfo LDAPManager::getGroupByDistinguishedName(TQString dn) { return LDAPGroupInfo(); } +void create_single_attribute_operation(LDAPMod **mods, int *i, TQString attr, TQString value) { + char **values = (char**)malloc(2*sizeof(char*)); + values[0] = strdup(value.ascii()); + values[1] = NULL; + mods[*i]->mod_op = LDAP_MOD_ADD; + mods[*i]->mod_type = strdup(attr.ascii()); + mods[*i]->mod_values = values; + (*i)++; +} + +void create_multiple_attributes_operation(LDAPMod **mods, int *i, TQString attr, TQStringList strings) { + int j=0; + char **values = (char**)malloc((strings.count()+1)*sizeof(char*)); + for ( TQStringList::Iterator it = strings.begin(); it != strings.end(); ++it ) { + values[j] = strdup((*it).ascii()); + j++; + } + values[j] = NULL; + mods[*i]->mod_op = LDAP_MOD_ADD; + mods[*i]->mod_type = strdup(attr.ascii()); + mods[*i]->mod_values = values; + (*i)++; +} + void add_single_attribute_operation(LDAPMod **mods, int *i, TQString attr, TQString value) { mods[*i]->mod_op = LDAP_MOD_DELETE; mods[*i]->mod_type = strdup(attr.ascii()); @@ -539,6 +567,62 @@ void add_multiple_attributes_operation(LDAPMod **mods, int *i, TQString attr, TQ (*i)++; } +int LDAPManager::updateUserInfo(LDAPUserInfo user) { + int retcode; + int i; + LDAPUserInfo userinfo; + + if (bind() < 0) { + return -1; + } + else { + // Assemble the LDAPMod structure + // We will replace attributes by first deleting them, then adding them back with their new values + int number_of_parameters = 43; // 43 primary attributes + number_of_parameters = (number_of_parameters * 2); // MODIFY/DELETE + LDAPMod *mods[number_of_parameters+1]; + for (i=0;i<number_of_parameters;i++) { + mods[i] = new LDAPMod; + mods[i]->mod_type = NULL; + mods[i]->mod_values = NULL; + } + mods[number_of_parameters] = NULL; + + // Load LDAP modification requests from provided data structure + i=0; + add_single_attribute_operation(mods, &i, "uidNumber", TQString("%1").arg(user.uid)); + // RAJA FIXME + // Add the other 42 primary attributes! + + // Perform LDAP update + retcode = ldap_modify_ext_s(m_ldap, user.distinguishedName.ascii(), mods, NULL, NULL); + + // Clean up + for (i=0;i<number_of_parameters;i++) { + if (mods[i]->mod_type != NULL) { + free(mods[i]->mod_type); + } + if (mods[i]->mod_values != NULL) { + int j = 0; + while (mods[i]->mod_values[j] != NULL) { + free(mods[i]->mod_values[j]); + j++; + } + free(mods[i]->mod_values); + } + delete mods[i]; + } + + if (retcode != LDAP_SUCCESS) { + KMessageBox::error(0, i18n("<qt>LDAP modification failure<p>Reason: [%3] %4</qt>").arg(retcode).arg(ldap_err2string(retcode)), i18n("LDAP Error")); + return -2; + } + else { + return 0; + } + } +} + int LDAPManager::updateGroupInfo(LDAPGroupInfo group) { int retcode; int i; @@ -563,7 +647,12 @@ int LDAPManager::updateGroupInfo(LDAPGroupInfo group) { // Load LDAP modification requests from provided data structure i=0; add_single_attribute_operation(mods, &i, "gidNumber", TQString("%1").arg(group.gid)); - add_multiple_attributes_operation(mods, &i, "member", group.userlist); + TQStringList completeGroupList = group.userlist; + TQString placeholderGroup = "cn=placeholder," + m_basedc; + if (!completeGroupList.contains(placeholderGroup)) { + completeGroupList.prepend(placeholderGroup); + } + add_multiple_attributes_operation(mods, &i, "member", completeGroupList); // Perform LDAP update retcode = ldap_modify_ext_s(m_ldap, group.distinguishedName.ascii(), mods, NULL, NULL); @@ -594,6 +683,86 @@ int LDAPManager::updateGroupInfo(LDAPGroupInfo group) { } } +int LDAPManager::addGroupInfo(LDAPGroupInfo group) { + int retcode; + int i; + LDAPGroupInfo groupinfo; + + if (bind() < 0) { + return -1; + } + else { + // Create the base DN entry + int number_of_parameters = 6; // 3 primary attributes + LDAPMod *mods[number_of_parameters+1]; + for (i=0;i<number_of_parameters;i++) { + mods[i] = new LDAPMod; + mods[i]->mod_type = NULL; + mods[i]->mod_values = NULL; + } + mods[number_of_parameters] = NULL; + + TQString placeholderGroup = "cn=placeholder," + m_basedc; + + // Load initial required LDAP object attributes + i=0; + create_single_attribute_operation(mods, &i, "gidNumber", TQString("%1").arg(group.gid)); + create_multiple_attributes_operation(mods, &i, "objectClass", TQStringList::split(" ", "emsGroup groupOfNames posixGroup")); + create_single_attribute_operation(mods, &i, "cn", group.name); + create_multiple_attributes_operation(mods, &i, "member", TQStringList(placeholderGroup)); + // Zivios specific + create_single_attribute_operation(mods, &i, "emsdescription", "None"); + create_single_attribute_operation(mods, &i, "emstype", "GroupEntry"); + + // Add new object + retcode = ldap_add_ext_s(m_ldap, group.distinguishedName.ascii(), mods, NULL, NULL); + + // Clean up + for (i=0;i<number_of_parameters;i++) { + if (mods[i]->mod_type != NULL) { + free(mods[i]->mod_type); + } + if (mods[i]->mod_values != NULL) { + int j = 0; + while (mods[i]->mod_values[j] != NULL) { + free(mods[i]->mod_values[j]); + j++; + } + free(mods[i]->mod_values); + } + delete mods[i]; + } + + if (retcode != LDAP_SUCCESS) { + KMessageBox::error(0, i18n("<qt>LDAP addition failure<p>Reason: [%3] %4</qt>").arg(retcode).arg(ldap_err2string(retcode)), i18n("LDAP Error")); + return -2; + } + else { + return updateGroupInfo(group); + } + } +} + +int LDAPManager::deleteGroupInfo(LDAPGroupInfo group) { + int retcode; + LDAPGroupInfo groupinfo; + + if (bind() < 0) { + return -1; + } + else { + // Delete the base DN entry + retcode = ldap_delete_ext_s(m_ldap, group.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; diff --git a/src/libtdeldap.h b/src/libtdeldap.h index 7e7ae5d..b49393b 100644 --- a/src/libtdeldap.h +++ b/src/libtdeldap.h @@ -169,13 +169,17 @@ class LDAPManager : public TQObject { ~LDAPManager(); TQString realm(); + TQString basedn(); int bind(); int unbind(bool force); LDAPUserInfoList users(); LDAPGroupInfoList groups(); LDAPUserInfo getUserByDistinguishedName(TQString dn); LDAPGroupInfo getGroupByDistinguishedName(TQString dn); + int updateUserInfo(LDAPUserInfo group); int updateGroupInfo(LDAPGroupInfo group); + int addGroupInfo(LDAPGroupInfo group); + int deleteGroupInfo(LDAPGroupInfo group); private: LDAPUserInfo parseLDAPUserRecord(LDAPMessage* entry); diff --git a/src/userconfigdlg.cpp b/src/userconfigdlg.cpp index a2ad641..3487b01 100644 --- a/src/userconfigdlg.cpp +++ b/src/userconfigdlg.cpp @@ -47,9 +47,12 @@ UserConfigDialog::UserConfigDialog(LDAPUserInfo user, LDAPConfig* parent, const for ( TQStringList::Iterator it = availableShells.begin(); it != availableShells.end(); ++it ) { m_base->shell->insertItem(*it, -1); } - m_base->loginName->setEnabled(false); + if (user.distinguishedName != "") { + m_base->loginName->setEnabled(false); + } m_base->lastChanged->setEnabled(false); + connect(m_base->loginName, TQT_SIGNAL(textChanged(const TQString&)), this, TQT_SLOT(processLockouts())); connect(m_base->passwordExpireEnabled, TQT_SIGNAL(clicked()), this, TQT_SLOT(processLockouts())); connect(m_base->passwordExpireDisabled, TQT_SIGNAL(clicked()), this, TQT_SLOT(processLockouts())); connect(m_base->requirePasswordAging, TQT_SIGNAL(clicked()), this, TQT_SLOT(processLockouts())); @@ -113,6 +116,11 @@ void UserConfigDialog::slotOk() { // Update data // RAJA FIXME + // Special handler for new group + if (m_user.distinguishedName == "") { + m_user.name = m_base->loginName->text(); + } + accept(); } @@ -158,6 +166,14 @@ void UserConfigDialog::processLockouts() { ++it; } + // Special handler for new group + if ((m_user.distinguishedName == "") && (m_base->loginName->text() == "")) { + enableButton(KDialogBase::Ok, false); + } + else { + enableButton(KDialogBase::Ok, true); + } + m_prevPrimaryGroup = m_base->primaryGroup->currentText(); } |