The lockout attributes are not replicated so it can be difficult and
time consuming to see what their status is on various servers. Add a
user-status command to query all IPA servers and get the lockout attributes.
This isn't done as part of user-show because it is rather expensive.
rob
>From 04021ae7aed06d4a3ea17436bb701ed1304eeb2b Mon Sep 17 00:00:00 2001
From: Rob Crittenden <rcrit...@redhat.com>
Date: Tue, 14 Feb 2012 09:41:25 -0500
Subject: [PATCH] Add status command to retrieve user lockout status
This information is not replicated so pull from all IPA masters
and display the status across all servers.
https://fedorahosted.org/freeipa/ticket/2162
---
API.txt | 10 +++++
ipalib/plugins/user.py | 94 +++++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 103 insertions(+), 1 deletions(-)
diff --git a/API.txt b/API.txt
index ba2248904829aa942545401318a51168163c02a3..a63d6fddd82faf311fcdf99ed2badfd057c9721a 100644
--- a/API.txt
+++ b/API.txt
@@ -3248,6 +3248,16 @@ option: Str('version?', exclude='webui')
output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
output: Entry('result', <type 'dict'>, Gettext('A dictionary representing an LDAP entry', domain='ipa', localedir=None))
output: Output('value', <type 'unicode'>, None)
+command: user_status
+args: 1,3,4
+arg: Str('uid', attribute=True, cli_name='login', maxlength=255, multivalue=False, pattern='^[a-zA-Z0-9_.][a-zA-Z0-9_.-]{0,252}[a-zA-Z0-9_.$-]?$', pattern_errmsg='may only include letters, numbers, _, -, . and $', primary_key=True, query=True, required=True)
+option: Flag('all', autofill=True, cli_name='all', default=False, exclude='webui')
+option: Flag('raw', autofill=True, cli_name='raw', default=False, exclude='webui')
+option: Str('version?', exclude='webui')
+output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
+output: ListOfEntries('result', (<type 'list'>, <type 'tuple'>), Gettext('A list of LDAP entries', domain='ipa', localedir=None))
+output: Output('count', <type 'int'>, None)
+output: Output('truncated', <type 'bool'>, None)
command: user_unlock
args: 1,0,3
arg: Str('uid', attribute=True, cli_name='login', maxlength=255, multivalue=False, pattern='^[a-zA-Z0-9_.][a-zA-Z0-9_.-]{0,252}[a-zA-Z0-9_.$-]?$', pattern_errmsg='may only include letters, numbers, _, -, . and $', primary_key=True, query=True, required=True)
diff --git a/ipalib/plugins/user.py b/ipalib/plugins/user.py
index ad9805bec5db0eee248c45022ee7810293a4109d..5d442c2c9ed9ae2ddb54c240332ddf1687a0b589 100644
--- a/ipalib/plugins/user.py
+++ b/ipalib/plugins/user.py
@@ -18,7 +18,7 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
-from time import gmtime, strftime
+from time import gmtime, strftime, strptime
import copy
import string
@@ -27,9 +27,13 @@ from ipalib import Flag, Int, Password, Str, Bool, Bytes
from ipalib.plugins.baseldap import *
from ipalib.request import context
from ipalib import _, ngettext
+from ipalib import output
from ipapython.ipautil import ipa_generate_password
import posixpath
from ipalib.util import validate_sshpubkey, output_sshpubkey
+if api.env.in_server and api.env.context in ['lite', 'server']:
+ from ipaserver.plugins.ldap2 import ldap2
+ import os
__doc__ = _("""
Users
@@ -79,6 +83,21 @@ user_output_params = (
),
)
+status_output_params = (
+ Str('server',
+ label=_('Server'),
+ ),
+ Str('krbloginfailedcount',
+ label=_('Failed logins'),
+ ),
+ Str('krblastsuccessfulauth',
+ label=_('Last successful authentication'),
+ ),
+ Str('krblastfailedauth',
+ label=_('Last failed authentication'),
+ ),
+ )
+
# characters to be used for generating random user passwords
user_pwdchars = string.digits + string.ascii_letters + '_,.@+-='
@@ -680,3 +699,76 @@ class user_unlock(LDAPQuery):
)
api.register(user_unlock)
+
+class user_status(LDAPQuery):
+ __doc__ = _("""
+ Lockout status of a user account
+
+ An account may become locked if the password is entered incorrectly too
+ many times within a specific time period as controlled by password
+ policy. A locked account is a temporary condition and may be unlocked by
+ an administrator.
+
+ This connects to each IPA master and displays the lockout status on
+ each one.""")
+
+ has_output = output.standard_list_of_entries
+ has_output_params = LDAPSearch.has_output_params + status_output_params
+
+ def execute(self, *keys, **options):
+ ldap = self.obj.backend
+ dn = self.obj.get_dn(*keys, **options)
+ attr_list = ['krbloginfailedcount', 'krblastsuccessfulauth', 'krblastfailedauth']
+
+ masters = []
+ # Get list of masters
+ try:
+ (masters, truncated) = ldap.find_entries(
+ None, ['*'], 'cn=masters,cn=ipa,cn=etc,%s' % api.env.basedn,
+ ldap.SCOPE_ONELEVEL
+ )
+ except errors.NotFound:
+ # If this happens we have some pretty serious problems
+ self.error('No IPA masters found!')
+ pass
+
+ entries = []
+ count = 0
+ for master in masters:
+ host = master[1]['cn'][0]
+ if host == api.env.host:
+ other_ldap = self.obj.backend
+ else:
+ other_ldap = ldap2(shared_instance=False,
+ ldap_uri='ldap://%s' % host,
+ base_dn=self.api.env.basedn)
+ other_ldap.connect(ccache=os.environ['KRB5CCNAME'])
+ try:
+ entry = other_ldap.get_entry(dn, attr_list)
+ newresult = dict()
+ for attr in attr_list:
+ newresult[attr] = entry[1].get(attr, '')
+ if not options.get('raw', False):
+ for attr in ['krblastsuccessfulauth', 'krblastfailedauth']:
+ try:
+ newtime = time.strptime(newresult[attr][0], '%Y%m%d%H%M%S%Z')
+ newresult[attr][0] = unicode(time.strftime('%Y-%m-%dT%H:%M:%SZ', newtime))
+ except Exception, e:
+ self.debug("time conversion failed with %s" % str(e))
+ pass
+ newresult['dn'] = dn
+ newresult['server'] = host
+ entries.append(newresult)
+ count += 1
+ except Exception, e:
+ raise e
+
+ if host != api.env.host:
+ other_ldap.destroy_connection()
+
+ return dict(result=entries,
+ count=count,
+ truncated=False,
+ )
+
+api.register(user_status)
--
1.7.6.5
_______________________________________________
Freeipa-devel mailing list
Freeipa-devel@redhat.com
https://www.redhat.com/mailman/listinfo/freeipa-devel