diff options
-rw-r--r-- | ipa-admintools/ipa-deluser | 11 | ||||
-rw-r--r-- | ipa-admintools/ipa-usermod | 16 | ||||
-rw-r--r-- | ipa-python/ipaclient.py | 24 | ||||
-rw-r--r-- | ipa-python/rpcclient.py | 48 | ||||
-rw-r--r-- | ipa-server/ipa-gui/ipagui/forms/group.py | 4 | ||||
-rw-r--r-- | ipa-server/ipa-gui/ipagui/subcontrollers/group.py | 35 | ||||
-rw-r--r-- | ipa-server/ipa-gui/ipagui/subcontrollers/user.py | 26 | ||||
-rw-r--r-- | ipa-server/ipa-gui/ipagui/templates/groupeditform.kid | 10 | ||||
-rw-r--r-- | ipa-server/ipa-gui/ipagui/templates/grouplist.kid | 12 | ||||
-rw-r--r-- | ipa-server/ipa-gui/ipagui/templates/groupshow.kid | 7 | ||||
-rw-r--r-- | ipa-server/ipa-gui/ipagui/templates/usereditform.kid | 2 | ||||
-rw-r--r-- | ipa-server/ipa-install/share/bootstrap-template.ldif | 39 | ||||
-rw-r--r-- | ipa-server/ipaserver/dsinstance.py | 2 | ||||
-rw-r--r-- | ipa-server/xmlrpc-server/funcs.py | 104 | ||||
-rw-r--r-- | ipa-server/xmlrpc-server/ipaxmlrpc.py | 5 |
15 files changed, 301 insertions, 44 deletions
diff --git a/ipa-admintools/ipa-deluser b/ipa-admintools/ipa-deluser index 3112420aa..02ba5f132 100644 --- a/ipa-admintools/ipa-deluser +++ b/ipa-admintools/ipa-deluser @@ -57,11 +57,14 @@ def main(): ret = client.delete_user(args[1]) msg = "deleted" else: - ret = client.mark_user_deleted(args[1]) - if (ret == "Success"): + try: + ret = client.mark_user_inactive(args[1]) + except ipa.ipaerror.exception_for(ipa.ipaerror.LDAP_EMPTY_MODLIST): + print "User is already marked inactive" + return 0 + except: + raise print args[1] + " successfully %s" % msg - else: - print args[1] + " " + ret except xmlrpclib.Fault, fault: if fault.faultCode == errno.ECONNREFUSED: print "The IPA XML-RPC service is not responding." diff --git a/ipa-admintools/ipa-usermod b/ipa-admintools/ipa-usermod index 9ebddd2c6..9d3e7794c 100644 --- a/ipa-admintools/ipa-usermod +++ b/ipa-admintools/ipa-usermod @@ -32,7 +32,7 @@ import ldap import errno def usage(): - print "ipa-usermod [-c|--gecos STRING] [-d|--directory STRING] [-f|--firstname STRING] [-l|--lastname STRING] [-s|--shell STRING] [--add attribute=value] [--del attribute] [--set attribute=value] user" + print "ipa-usermod [-a|--activate] [-c|--gecos STRING] [-d|--directory STRING] [-f|--firstname STRING] [-l|--lastname STRING] [-s|--shell STRING] [--add attribute=value] [--del attribute] [--set attribute=value] user" sys.exit(1) def set_add_usage(which): @@ -40,6 +40,8 @@ def set_add_usage(which): def parse_options(): parser = OptionParser() + parser.add_option("-a", "--activate", dest="activate", action="store_true", + help="Activate the user") parser.add_option("-c", "--gecos", dest="gecos", help="Set the GECOS field") parser.add_option("-d", "--directory", dest="directory", @@ -111,7 +113,7 @@ def main(): return 1 # If any options are set we use just those. Otherwise ask for all of them. - if options.gn or options.sn or options.directory or options.gecos or options.mail or options.shell or options.addattr or options.delattr or options.setattr: + if options.gn or options.sn or options.directory or options.gecos or options.mail or options.shell or options.addattr or options.delattr or options.setattr or options.activate: givenname = options.gn lastname = options.sn gecos = options.gecos @@ -236,8 +238,16 @@ def main(): value = cvalue + [value] user.setValue(attr, value) - try: + if options.activate: + try: + client.mark_user_active(user.getValues('uid')) + print "User activated successfully." + except ipa.ipaerror.exception_for(ipa.ipaerror.LDAP_EMPTY_MODLIST): + print "User is already marked active" + return 0 + except: + raise client.update_user(user) except xmlrpclib.Fault, fault: if fault.faultCode == errno.ECONNREFUSED: diff --git a/ipa-python/ipaclient.py b/ipa-python/ipaclient.py index f8c70974a..0eeb2f36f 100644 --- a/ipa-python/ipaclient.py +++ b/ipa-python/ipaclient.py @@ -177,10 +177,16 @@ class IPAClient: return result - def mark_user_deleted(self,uid): + def mark_user_active(self,uid): + """Set a user as active by uid.""" + + result = self.transport.mark_user_active(uid) + return result + + def mark_user_inactive(self,uid): """Set a user as inactive by uid.""" - result = self.transport.mark_user_deleted(uid) + result = self.transport.mark_user_inactive(uid) return result # Groups support @@ -335,6 +341,20 @@ class IPAClient: entries.append(user.User(e)) return entries + + def mark_group_active(self,cn): + """Set a group as active by cn.""" + + result = self.transport.mark_group_active(cn) + return result + + def mark_group_inactive(self,cn): + """Set a group as inactive by cn.""" + + result = self.transport.mark_group_inactive(cn) + return result + +# Configuration def get_ipa_config(self): """Get the IPA configuration""" diff --git a/ipa-python/rpcclient.py b/ipa-python/rpcclient.py index c4ca2ff3e..d4c3dcc8e 100644 --- a/ipa-python/rpcclient.py +++ b/ipa-python/rpcclient.py @@ -318,12 +318,12 @@ class RPCClient: return result - def mark_user_deleted(self,uid): - """Mark a user as deleted/inactive""" + def mark_user_active(self,uid): + """Mark a user as active""" server = self.setup_server() try: - result = server.mark_user_deleted(uid) + result = server.mark_user_active(uid) except xmlrpclib.Fault, fault: raise ipaerror.gen_exception(fault.faultCode, fault.faultString) except socket.error, (value, msg): @@ -331,6 +331,20 @@ class RPCClient: return ipautil.unwrap_binary_data(result) + def mark_user_inactive(self,uid): + """Mark a user as inactive""" + server = self.setup_server() + + try: + result = server.mark_user_inactive(uid) + except xmlrpclib.Fault, fault: + raise ipaerror.gen_exception(fault.faultCode, fault.faultString) + except socket.error, (value, msg): + raise xmlrpclib.Fault(value, msg) + + return ipautil.unwrap_binary_data(result) + + # Group support def get_groups_by_member(self,member_dn,sattrs=None): @@ -601,6 +615,34 @@ class RPCClient: return ipautil.unwrap_binary_data(result) + def mark_group_active(self,cn): + """Mark a group as active""" + server = self.setup_server() + + try: + result = server.mark_group_active(cn) + except xmlrpclib.Fault, fault: + raise ipaerror.gen_exception(fault.faultCode, fault.faultString) + except socket.error, (value, msg): + raise xmlrpclib.Fault(value, msg) + + return ipautil.unwrap_binary_data(result) + + def mark_group_inactive(self,cn): + """Mark a group as inactive""" + server = self.setup_server() + + try: + result = server.mark_group_inactive(cn) + except xmlrpclib.Fault, fault: + raise ipaerror.gen_exception(fault.faultCode, fault.faultString) + except socket.error, (value, msg): + raise xmlrpclib.Fault(value, msg) + + return ipautil.unwrap_binary_data(result) + +# Configuration support + def get_ipa_config(self): """Get the IPA configuration""" server = self.setup_server() diff --git a/ipa-server/ipa-gui/ipagui/forms/group.py b/ipa-server/ipa-gui/ipagui/forms/group.py index 04c0298ad..b67156641 100644 --- a/ipa-server/ipa-gui/ipagui/forms/group.py +++ b/ipa-server/ipa-gui/ipagui/forms/group.py @@ -9,6 +9,10 @@ class GroupFields(): editprotected_hidden = widgets.HiddenField(name="editprotected") + nsAccountLock = widgets.SingleSelectField(name="nsAccountLock", + label="Group Status", + options = [("", "active"), ("true", "inactive")]) + group_orig = widgets.HiddenField(name="group_orig") member_data = widgets.HiddenField(name="member_data") dn_to_info_json = widgets.HiddenField(name="dn_to_info_json") diff --git a/ipa-server/ipa-gui/ipagui/subcontrollers/group.py b/ipa-server/ipa-gui/ipagui/subcontrollers/group.py index 7c05eebc0..dbcc77b9a 100644 --- a/ipa-server/ipa-gui/ipagui/subcontrollers/group.py +++ b/ipa-server/ipa-gui/ipagui/subcontrollers/group.py @@ -22,7 +22,7 @@ log = logging.getLogger(__name__) group_new_form = ipagui.forms.group.GroupNewForm() group_edit_form = ipagui.forms.group.GroupEditForm() -group_fields = ['*'] +group_fields = ['*', 'nsAccountLock'] class GroupController(IPAController): @@ -75,6 +75,9 @@ class GroupController(IPAController): new_group.setValue('description', kw.get('description')) rv = client.add_group(new_group) + + if kw.get('nsAccountLock'): + client.mark_group_inactive(kw.get('cn')) except ipaerror.exception_for(ipaerror.LDAP_DUPLICATE): turbogears.flash("Group with name '%s' already exists" % kw.get('cn')) @@ -224,6 +227,12 @@ class GroupController(IPAController): turbogears.flash("Edit group cancelled") raise turbogears.redirect('/group/show', cn=cn[0]) + if kw.get('editprotected') == '': + # if editprotected set these don't get sent in kw + orig_group_dict = loads(b64decode(kw.get('group_orig'))) + kw['cn'] = orig_group_dict['cn'] + kw['gidnumber'] = orig_group_dict['gidnumber'] + # Decode the member data, in case we need to round trip member_dicts = loads(b64decode(kw.get('member_data'))) @@ -251,6 +260,17 @@ class GroupController(IPAController): if new_group.gidnumber != new_gid: group_modified = True new_group.setValue('gidnumber', new_gid) + else: + new_group.setValue('gidnumber', orig_group_dict.get('gidnumber')) + new_group.setValue('cn', orig_group_dict.get('cn')) + if new_group.cn != kw.get('cn'): + group_modified = True + new_group.setValue('cn', kw['cn']) + + if group_modified: + rv = client.update_group(new_group) + # + # If the group update succeeds, but below operations fail, we if new_group.cn != kw.get('cn'): group_modified = True new_group.setValue('cn', kw['cn']) @@ -268,6 +288,17 @@ class GroupController(IPAController): return dict(form=group_edit_form, group=kw, members=member_dicts, tg_template='ipagui.templates.groupedit') + if kw.get('nsAccountLock') == '': + 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 + # # Add members # @@ -326,7 +357,7 @@ class GroupController(IPAController): cn0 = kw['cn'][0] else: cn0 = kw['cn'] - if group_modified == True: + if group_modified == True or modify_no_update == True: turbogears.flash("%s updated!" % cn0) else: turbogears.flash("No modifications requested.") diff --git a/ipa-server/ipa-gui/ipagui/subcontrollers/user.py b/ipa-server/ipa-gui/ipagui/subcontrollers/user.py index 579379c43..39343b595 100644 --- a/ipa-server/ipa-gui/ipagui/subcontrollers/user.py +++ b/ipa-server/ipa-gui/ipagui/subcontrollers/user.py @@ -197,14 +197,14 @@ class UserController(IPAController): new_user.setValue('carlicense', kw.get('carlicense')) new_user.setValue('labeleduri', kw.get('labeleduri')) - if kw.get('nsAccountLock'): - new_user.setValue('nsAccountLock', 'true') - for custom_field in user_new_form.custom_fields: new_user.setValue(custom_field.name, kw.get(custom_field.name, '')) rv = client.add_user(new_user) + + if kw.get('nsAccountLock'): + client.mark_user_inactive(kw.get('uid')) except ipaerror.exception_for(ipaerror.LDAP_DUPLICATE): turbogears.flash("User with login '%s' already exists" % kw.get('uid')) @@ -482,12 +482,6 @@ class UserController(IPAController): new_user.setValue('carlicense', kw.get('carlicense')) new_user.setValue('labeleduri', kw.get('labeleduri')) - - if kw.get('nsAccountLock'): - new_user.setValue('nsAccountLock', 'true') - else: - new_user.setValue('nsAccountLock', None) - if kw.get('editprotected') == 'true': if kw.get('userpassword'): password_change = True @@ -572,6 +566,20 @@ class UserController(IPAController): user_groups=user_groups_dicts, tg_template='ipagui.templates.useredit') + if kw.get('nsAccountLock') == '': + kw['nsAccountLock'] = "false" + + try: + if kw.get('nsAccountLock') == "false" and new_user.getValues('nsaccountlock') == "true": + client.mark_user_active(kw.get('uid')) + elif kw.get('nsAccountLock') == "true" and new_user.nsaccountlock != "true": + client.mark_user_inactive(kw.get('uid')) + except ipaerror.IPAError, e: + turbogears.flash("User status change failed: " + str(e) + "<br/>" + e.detail[0]['desc']) + return dict(form=user_edit_form, user=kw, + user_groups=user_groups_dicts, + tg_template='ipagui.templates.useredit') + turbogears.flash("%s updated!" % kw['uid']) raise turbogears.redirect('/user/show', uid=kw['uid']) diff --git a/ipa-server/ipa-gui/ipagui/templates/groupeditform.kid b/ipa-server/ipa-gui/ipagui/templates/groupeditform.kid index d46bc731e..6a5c5adb8 100644 --- a/ipa-server/ipa-gui/ipagui/templates/groupeditform.kid +++ b/ipa-server/ipa-gui/ipagui/templates/groupeditform.kid @@ -112,6 +112,16 @@ from ipagui.helpers import ipahelper </script> </td> </tr> + <tr> + <th> + <label class="fieldlabel" for="${group_fields.nsAccountLock.field_id}" py:content="group_fields.nsAccountLock.label" />: + </th> + <td> + <span py:replace="group_fields.nsAccountLock.display(value_for(group_fields.nsAccountLock))" /> + <span py:if="tg.errors.get('nsAccountLock')" class="fielderror" + py:content="tg.errors.get('nsAccountLock')" /> + </td> + </tr> </table> <div> diff --git a/ipa-server/ipa-gui/ipagui/templates/grouplist.kid b/ipa-server/ipa-gui/ipagui/templates/grouplist.kid index 9f9bc4840..9489b3744 100644 --- a/ipa-server/ipa-gui/ipagui/templates/grouplist.kid +++ b/ipa-server/ipa-gui/ipagui/templates/grouplist.kid @@ -20,7 +20,7 @@ </div> <div py:if='(groups != None) and (len(groups) > 0)'> <h2>${len(groups)} results returned:</h2> - <table id="resultstable" class="details sortable resizable"> + <table id="resultstable" class="details sortable resizable" cellspacing="0"> <thead> <tr> <th> @@ -32,7 +32,15 @@ </tr> </thead> <tbody> - <tr py:for="group in groups"> + <tr py:for="group in groups" py:if="group.nsAccountLock != 'true'"> + <td> + <a href="${tg.url('/group/show',cn=group.cn)}">${group.cn}</a> + </td> + <td> + ${group.description} + </td> + </tr> + <tr id="inactive" py:for="group in groups" py:if="group.nsAccountLock == 'true'"> <td> <a href="${tg.url('/group/show',cn=group.cn)}">${group.cn}</a> </td> diff --git a/ipa-server/ipa-gui/ipagui/templates/groupshow.kid b/ipa-server/ipa-gui/ipagui/templates/groupshow.kid index b2f37bf52..8713742d5 100644 --- a/ipa-server/ipa-gui/ipagui/templates/groupshow.kid +++ b/ipa-server/ipa-gui/ipagui/templates/groupshow.kid @@ -11,6 +11,7 @@ cn = group.get('cn') if isinstance(cn, list): cn = cn[0] edit_url = tg.url('/group/edit', cn=cn) +from ipagui.helpers import userhelper ?> <div id="details"> <h1>View Group</h1> @@ -42,6 +43,12 @@ edit_url = tg.url('/group/edit', cn=cn) </th> <td>${group.get("gidnumber")}</td> </tr> + <tr> + <th> + <label class="fieldlabel" py:content="fields.nsAccountLock.label" />: + </th> + <td>${userhelper.account_status_display(group.get("nsAccountLock"))}</td> + </tr> </table> <h2 class="formsection">Group Members</h2> diff --git a/ipa-server/ipa-gui/ipagui/templates/usereditform.kid b/ipa-server/ipa-gui/ipagui/templates/usereditform.kid index c95b36e39..88b778d8c 100644 --- a/ipa-server/ipa-gui/ipagui/templates/usereditform.kid +++ b/ipa-server/ipa-gui/ipagui/templates/usereditform.kid @@ -787,7 +787,7 @@ from ipagui.helpers import ipahelper group_dn = group.get('dn') group_dn_esc = ipahelper.javascript_string_escape(group_dn) - group_name = group.get('cn')[0] + group_name = group.get('cn') group_descr = "[group]" group_type = "group" diff --git a/ipa-server/ipa-install/share/bootstrap-template.ldif b/ipa-server/ipa-install/share/bootstrap-template.ldif index f443b6cb9..257f865be 100644 --- a/ipa-server/ipa-install/share/bootstrap-template.ldif +++ b/ipa-server/ipa-install/share/bootstrap-template.ldif @@ -116,3 +116,42 @@ ipaDefaultLoginShell: /bin/sh ipaDefaultPrimaryGroup: ipausers ipaMaxUsernameLength: 8 ipaPwdExpAdvNotify: 4 + +dn: cn=account inactivation,cn=accounts,$SUFFIX +description: Lock accounts based on group membership +objectClass: top +objectClass: ldapsubentry +objectClass: cosSuperDefinition +objectClass: cosClassicDefinition +cosTemplateDn: cn=cosTemplates,cn=accounts,$SUFFIX +cosAttribute: nsAccountLock operational +cosAttribute: pager +cosSpecifier: memberOf +cn: Account Inactivation + +dn: cn=cosTemplates,cn=accounts,$SUFFIX +objectclass: top +objectclass: nsContainer +cn: cosTemplates + +dn: cn="cn=inactivated,cn=account inactivation,cn=accounts,$SUFFIX", cn=cosTemplates,cn=accounts,$SUFFIX +objectClass: top +objectClass: cosTemplate +objectClass: extensibleobject +nsAccountLock: true +cosPriority: 1 + +dn: cn=inactivated,cn=account inactivation,cn=accounts,$SUFFIX +objectclass: top +objectclass: groupofuniquenames + +dn: cn="cn=activated,cn=account inactivation,cn=accounts,$SUFFIX", cn=cosTemplates,cn=accounts,$SUFFIX +objectClass: top +objectClass: cosTemplate +objectClass: extensibleobject +nsAccountLock: false +cosPriority: 0 + +dn: cn=Activated,cn=Account Inactivation,cn=accounts,$SUFFIX +objectclass: top +objectclass: groupofuniquenames diff --git a/ipa-server/ipaserver/dsinstance.py b/ipa-server/ipaserver/dsinstance.py index d1e8f3abc..3cf80f46a 100644 --- a/ipa-server/ipaserver/dsinstance.py +++ b/ipa-server/ipaserver/dsinstance.py @@ -119,7 +119,7 @@ class DsInstance(service.Service): def __setup_sub_dict(self): server_root = find_server_root() self.sub_dict = dict(FQHN=self.host_name, SERVERID=self.serverid, - PASSWORD=self.dm_password, SUFFIX=self.suffix, + PASSWORD=self.dm_password, SUFFIX=self.suffix.lower(), REALM=self.realm_name, USER=self.ds_user, SERVER_ROOT=server_root) diff --git a/ipa-server/xmlrpc-server/funcs.py b/ipa-server/xmlrpc-server/funcs.py index 85d22993a..5c9f0cf6b 100644 --- a/ipa-server/xmlrpc-server/funcs.py +++ b/ipa-server/xmlrpc-server/funcs.py @@ -36,6 +36,7 @@ import string from types import * import os import re +import logging try: from threading import Lock @@ -49,6 +50,11 @@ ACIContainer = "cn=accounts" DefaultUserContainer = "cn=users,cn=accounts" DefaultGroupContainer = "cn=groups,cn=accounts" +# FIXME: need to check the ipadebug option in ipa.conf +logging.basicConfig(level=logging.DEBUG, + format='%(asctime)s %(levelname)s %(message)s', + stream=sys.stderr) + # # Apache runs in multi-process mode so each process will have its own # connection. This could theoretically drive the total number of connections @@ -674,26 +680,80 @@ class IPAServer: else: raise - def mark_user_deleted (self, uid, opts=None): - """Mark a user as inactive in LDAP. We aren't actually deleting - users here, just making it so they can't log in, etc.""" - user = self.get_user_by_uid(uid, ['dn', 'uid', 'nsAccountlock'], opts) + def mark_entry_active (self, dn, opts=None): + """Mark an entry as active in LDAP.""" - # Are we doing an add or replace operation? - if user.has_key('nsaccountlock'): - if user['nsaccountlock'] == "true": - return "already marked as deleted" - has_key = True - else: - has_key = False + # This can be tricky. The entry itself can be marked inactive + # by being in the inactivated group. It can also be inactivated by + # being the member of an inactive group. + # + # First we try to remove the entry from the inactivated group. Then + # if it is still inactive we have to add it to the activated group + # which will override the group membership. + + logging.debug("IPA: activating entry %s" % dn) + + res = "" + # First, check the entry status + entry = self.get_entry_by_dn(dn, ['dn', 'nsAccountlock'], opts) + + if entry.get('nsaccountlock', 'false') == "false": + logging.debug("IPA: already active") + raise ipaerror.gen_exception(ipaerror.LDAP_EMPTY_MODLIST) + + group = self.get_entry_by_cn("inactivated", None, opts) + res = self.remove_member_from_group(entry.get('dn'), group.get('dn'), opts) + + # 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": + # great, we're done + logging.debug("IPA: removing from inactivated did it.") + return res + + # So still inactive, add them to activated + group = self.get_entry_by_cn("activated", None, opts) + res = self.add_member_to_group(dn, group.get('dn'), opts) + logging.debug("IPA: added to activated.") - conn = self.getConnection(opts) - try: - res = conn.inactivateEntry(user['dn'], has_key) - finally: - self.releaseConnection(conn) return res + def mark_entry_inactive (self, dn, opts=None): + """Mark an entry as inactive in LDAP.""" + + logging.debug("IPA: inactivating entry %s" % dn) + + entry = self.get_entry_by_dn(dn, ['dn', 'nsAccountlock', 'memberOf'], opts) + + if entry.get('nsaccountlock', 'false') == "true": + logging.debug("IPA: already marked as inactive") + raise ipaerror.gen_exception(ipaerror.LDAP_EMPTY_MODLIST) + + # First see if they are in the activated group as this will override + # the our inactivation. + group = self.get_entry_by_cn("activated", None, opts) + self.remove_member_from_group(dn, group.get('dn'), opts) + + # Now add them to inactivated + group = self.get_entry_by_cn("inactivated", None, opts) + res = self.add_member_to_group(dn, group.get('dn'), opts) + + return res + + def mark_user_active(self, uid, opts=None): + """Mark a user as active""" + + user = self.get_user_by_uid(uid, ['dn', 'uid'], opts) + return self.mark_entry_active(user.get('dn')) + + def mark_user_inactive(self, uid, opts=None): + """Mark a user as inactive""" + + user = self.get_user_by_uid(uid, ['dn', 'uid'], opts) + return self.mark_entry_inactive(user.get('dn')) + def delete_user (self, uid, opts=None): """Delete a user. Not to be confused with inactivate_user. This makes the entry go away completely. @@ -1215,6 +1275,18 @@ class IPAServer: return entries + def mark_group_active(self, cn, opts=None): + """Mark a group as active""" + + group = self.get_entry_by_cn(cn, ['dn', 'cn'], opts) + return self.mark_entry_active(group.get('dn')) + + def mark_group_inactive(self, cn, opts=None): + """Mark a group as inactive""" + + group = self.get_entry_by_cn(cn, ['dn', 'uid'], opts) + return self.mark_entry_inactive(group.get('dn')) + # Configuration support def get_ipa_config(self, opts=None): """Retrieve the IPA configuration""" diff --git a/ipa-server/xmlrpc-server/ipaxmlrpc.py b/ipa-server/xmlrpc-server/ipaxmlrpc.py index 23bdcec1e..789233c9f 100644 --- a/ipa-server/xmlrpc-server/ipaxmlrpc.py +++ b/ipa-server/xmlrpc-server/ipaxmlrpc.py @@ -332,7 +332,10 @@ def handler(req, profiling=False): h.register_function(f.find_users) h.register_function(f.update_user) h.register_function(f.delete_user) - h.register_function(f.mark_user_deleted) + h.register_function(f.mark_user_active) + h.register_function(f.mark_user_inactive) + h.register_function(f.mark_group_active) + h.register_function(f.mark_group_inactive) h.register_function(f.modifyPassword) h.register_function(f.get_groups_by_member) h.register_function(f.add_group) |