summaryrefslogtreecommitdiffstats
path: root/ipa-server
diff options
context:
space:
mode:
authorRob Crittenden <rcritten@redhat.com>2008-03-31 11:36:13 -0400
committerRob Crittenden <rcritten@redhat.com>2008-03-31 11:36:13 -0400
commit58cfc7ab6861f47a85c8d275579a773a0fd79ea0 (patch)
treee667292d8361be8362c0f224fb73ebf4f5230b59 /ipa-server
parent1737dbb17431f0ea8f8203eb0aeafc474bd35520 (diff)
downloadfreeipa-58cfc7ab6861f47a85c8d275579a773a0fd79ea0.tar.gz
freeipa-58cfc7ab6861f47a85c8d275579a773a0fd79ea0.tar.xz
freeipa-58cfc7ab6861f47a85c8d275579a773a0fd79ea0.zip
Fix account activation.
We do account activation by using a Class of Service based on group membership. A problem can happen if the entry itself has an nsaccountlock attribute and you try doing Class of Service work as well because the local attribute has priority. So try to detect that the entry has a local nsAccountLock attribute and report an appropriate error. Don't allow the admins or editors groups to be de-activated. Return a better error message if account [in]activation fails. Catch errors when doing group [in]activation. 439230
Diffstat (limited to 'ipa-server')
-rw-r--r--ipa-server/ipa-gui/ipagui/subcontrollers/group.py17
-rw-r--r--ipa-server/xmlrpc-server/funcs.py59
2 files changed, 64 insertions, 12 deletions
diff --git a/ipa-server/ipa-gui/ipagui/subcontrollers/group.py b/ipa-server/ipa-gui/ipagui/subcontrollers/group.py
index eac5cb0b..6196d13d 100644
--- a/ipa-server/ipa-gui/ipagui/subcontrollers/group.py
+++ b/ipa-server/ipa-gui/ipagui/subcontrollers/group.py
@@ -315,12 +315,17 @@ class GroupController(IPAController):
kw['nsAccountLock'] = "false"
modify_no_update = False
- if kw.get('nsAccountLock') == "false" and new_group.getValues('nsaccountlock') == "true":
- client.mark_group_active(kw.get('cn'))
- modify_no_update = True
- elif kw.get('nsAccountLock') == "true" and new_group.nsaccountlock != "true":
- client.mark_group_inactive(kw.get('cn'))
- modify_no_update = True
+ try:
+ if kw.get('nsAccountLock') == "false" and new_group.getValues('nsaccountlock') == "true":
+ client.mark_group_active(kw.get('cn'))
+ modify_no_update = True
+ elif kw.get('nsAccountLock') == "true" and new_group.nsaccountlock != "true":
+ client.mark_group_inactive(kw.get('cn'))
+ modify_no_update = True
+ except ipaerror.IPAError, e:
+ turbogears.flash("Group status change failed: " + str(e) + "<br/>" + e.detail[0].get('desc','') + ". " + e.detail[0].get('info',''))
+ return dict(form=group_edit_form, group=kw, members=member_dicts,
+ tg_template='ipagui.templates.groupedit')
#
# Add members
diff --git a/ipa-server/xmlrpc-server/funcs.py b/ipa-server/xmlrpc-server/funcs.py
index 5190b09f..1c74dfbc 100644
--- a/ipa-server/xmlrpc-server/funcs.py
+++ b/ipa-server/xmlrpc-server/funcs.py
@@ -349,6 +349,37 @@ class IPAServer:
return result
+ def __has_nsaccountlock(self, dn, opts):
+ """Check to see if an entry has the nsaccountlock attribute.
+ This attribute is provided by the Class of Service plugin so
+ doing a search isn't enough. It is provided by the two
+ entries cn=inactivated and cn=activated. So if the entry has
+ the attribute and isn't in either cn=activated or cn=inactivated
+ then the attribute must be in the entry itself.
+
+ Returns True or False
+ """
+ # First get the entry. If it doesn't have nsaccountlock at all we
+ # can exit early.
+ entry = self.get_entry_by_dn(dn, ['dn', 'nsaccountlock', 'memberof'], opts)
+ if not entry.get('nsaccountlock'):
+ return False
+
+ # Now look to see if they are in activated or inactivated
+ # entry is a member
+ memberof = entry.get('memberof')
+ if isinstance(memberof, basestring):
+ memberof = [memberof]
+ for m in memberof:
+ inactivated = m.find("cn=inactivated")
+ activated = m.find("cn=activated")
+ # if they are in either group that means that the nsaccountlock
+ # value comes from there, otherwise it must be in this entry.
+ if inactivated >= 0 or activated >= 0:
+ return False
+
+ return True
+
# Higher-level API
def get_aci_entry(self, sattrs, opts=None):
@@ -1030,18 +1061,26 @@ class IPAServer:
# First, check the entry status
entry = self.get_entry_by_dn(dn, ['dn', 'nsAccountlock'], opts)
- if entry.get('nsaccountlock', 'false') == "false":
+ if entry.get('nsaccountlock', 'false').lower() == "false":
logging.debug("IPA: already active")
- raise ipaerror.gen_exception(ipaerror.LDAP_EMPTY_MODLIST)
+ raise ipaerror.gen_exception(ipaerror.STATUS_ALREADY_ACTIVE)
+
+ if self.__has_nsaccountlock(dn, opts):
+ logging.debug("IPA: appears to have the nsaccountlock attribute")
+ raise ipaerror.gen_exception(ipaerror.STATUS_HAS_NSACCOUNTLOCK)
group = self.get_entry_by_cn("inactivated", None, opts)
- res = self.remove_member_from_group(entry.get('dn'), group.get('dn'), opts)
+ try:
+ self.remove_member_from_group(entry.get('dn'), group.get('dn'), opts)
+ except ipaerror.exception_for(ipaerror.LDAP_NOT_FOUND):
+ # Perhaps the user is there as a result of group membership
+ pass
# Now they aren't a member of inactivated directly, what is the status
# now?
entry = self.get_entry_by_dn(dn, ['dn', 'nsAccountlock'], opts)
- if entry.get('nsaccountlock', 'false') == "false":
+ if entry.get('nsaccountlock', 'false').lower() == "false":
# great, we're done
logging.debug("IPA: removing from inactivated did it.")
return res
@@ -1063,9 +1102,13 @@ class IPAServer:
entry = self.get_entry_by_dn(dn, ['dn', 'nsAccountlock', 'memberOf'], opts)
- if entry.get('nsaccountlock', 'false') == "true":
+ if entry.get('nsaccountlock', 'false').lower() == "true":
logging.debug("IPA: already marked as inactive")
- raise ipaerror.gen_exception(ipaerror.LDAP_EMPTY_MODLIST)
+ raise ipaerror.gen_exception(ipaerror.STATUS_ALREADY_INACTIVE)
+
+ if self.__has_nsaccountlock(dn, opts):
+ logging.debug("IPA: appears to have the nsaccountlock attribute")
+ raise ipaerror.gen_exception(ipaerror.STATUS_HAS_NSACCOUNTLOCK)
# First see if they are in the activated group as this will override
# the our inactivation.
@@ -1091,6 +1134,8 @@ class IPAServer:
if not isinstance(uid,basestring) or len(uid) == 0:
raise ipaerror.gen_exception(ipaerror.INPUT_INVALID_PARAMETER)
+ if uid == "admin":
+ raise ipaerror.gen_exception(ipaerror.INPUT_CANT_INACTIVATE)
user = self.get_user_by_uid(uid, ['dn', 'uid'], opts)
return self.mark_entry_inactive(user.get('dn'))
@@ -1820,6 +1865,8 @@ class IPAServer:
if not isinstance(cn,basestring) or len(cn) == 0:
raise ipaerror.gen_exception(ipaerror.INPUT_INVALID_PARAMETER)
+ if cn == "admins" or cn == "editors":
+ raise ipaerror.gen_exception(ipaerror.INPUT_CANT_INACTIVATE)
group = self.get_entry_by_cn(cn, ['dn', 'uid'], opts)
return self.mark_entry_inactive(group.get('dn'))