[checkmk-commits] Check_MK Git: check_mk: userdb/ldap: Implemented page hook

git version control git at mathias-kettner.de
Wed Nov 21 14:35:05 CET 2012


Module: check_mk
Branch: master
Commit: 277c6f6750f84b1205072764b6bde7f95a30c2eb
URL:    http://git.mathias-kettner.de/git/?p=check_mk.git;a=commit;h=277c6f6750f84b1205072764b6bde7f95a30c2eb

Author: Lars Michelsen <lm at mathias-kettner.de>
Date:   Tue Nov 13 15:44:24 2012 +0100

userdb/ldap: Implemented page hook

---

 web/htdocs/index.py        |    4 +++
 web/htdocs/userdb.py       |   51 ++++++++++++++++++++++++++++++++-----------
 web/htdocs/wato.py         |    5 ++++
 web/plugins/userdb/ldap.py |   16 ++++++++++++-
 4 files changed, 61 insertions(+), 15 deletions(-)

diff --git a/web/htdocs/index.py b/web/htdocs/index.py
index e2fd68f..fc90b52 100644
--- a/web/htdocs/index.py
+++ b/web/htdocs/index.py
@@ -286,6 +286,10 @@ def handler(req, profiling = True):
                 else:
                     return result
 
+        # Call userdb page hooks which are executed on a regular base to e.g. syncronize
+        # information withough explicit user triggered actions
+        userdb.hook_page()
+
         # Set all permissions, read site config, and similar stuff
         config.login(html.req.user)
 
diff --git a/web/htdocs/userdb.py b/web/htdocs/userdb.py
index 164fb44..960bfe7 100644
--- a/web/htdocs/userdb.py
+++ b/web/htdocs/userdb.py
@@ -100,6 +100,11 @@ def create_non_existing_user(connector_id, username):
     # Call the sync function for this new user
     hook_sync(connector_id = connector_id, only_username = username)
 
+def user_locked(username):
+    import wato
+    users = wato.load_users()
+    return users[username].get('locked', False)
+
 #   .----------------------------------------------------------------------.
 #   |                     _   _             _                              |
 #   |                    | | | | ___   ___ | | _____                       |
@@ -113,19 +118,31 @@ def create_non_existing_user(connector_id, username):
 def hook_login(username, password):
     for connector in multisite_user_connectors:
         handler = connector.get('login', None)
-        if handler:
-            result = handler(username, password)
-            # None  -> User unknown, means continue with other connectors
-            # True  -> success
-            # False -> failed
-            if result == True:
-                # Check wether or not the user exists (and maybe create it)
-                create_non_existing_user(connector['id'], username)
-
-                return result
-
-            elif result == False:
-                return result
+        if not handler:
+            continue
+
+        result = handler(username, password)
+        # None  -> User unknown, means continue with other connectors
+        # True  -> success
+        # False -> failed
+        if result == True:
+            # Check wether or not the user exists (and maybe create it)
+            create_non_existing_user(connector['id'], username)
+
+            # Now, after successfull login (and optional user account
+            # creation), check wether or not the user is locked.
+            # In e.g. htpasswd connector this is checked by validating the
+            # password against the hash in the htpasswd file prefixed with
+            # a "!". But when using other conectors it might be neccessary
+            # to validate the user "locked" attribute.
+            lock_handler = connector.get('locked', None)
+            if lock_handler:
+                result = not lock_handler(username) # returns True if locked
+
+            return result
+
+        elif result == False:
+            return result
 
 # Hook function can be registered here to be executed to synchronize all users.
 # Is called on:
@@ -150,3 +167,11 @@ def hook_sync(connector_id = None, add_to_changelog = False, only_username = Non
                     )
                 else:
                     raise
+
+# Hook function can be registered here to execute actions on a "regular" base without
+# user triggered action. This hook is called on each page load.
+def hook_page():
+    for connector in multisite_user_connectors:
+        handler = connector.get('page', None)
+        if handler:
+            handler()
diff --git a/web/htdocs/wato.py b/web/htdocs/wato.py
index 7c96457..83f443c 100644
--- a/web/htdocs/wato.py
+++ b/web/htdocs/wato.py
@@ -8449,9 +8449,14 @@ def save_users(profiles):
     # users from htpasswd are lost. If you start managing users with
     # WATO, you should continue to do so or stop doing to for ever...
     # Locked accounts get a '!' before their password. This disable it.
+    # FIXME: implement as 'save'-hook in htpasswd connector
     filename = defaults.htpasswd_file
     out = create_user_file(filename, "w")
     for id, user in profiles.items():
+        # only process users which are handled by htpasswd connector
+        if user.get('connector', 'htpasswd') != 'htpasswd':
+            continue
+
         if user.get("password"):
             if user.get("locked", False):
                 locksym = '!'
diff --git a/web/plugins/userdb/ldap.py b/web/plugins/userdb/ldap.py
index d0b9b9e..8713402 100644
--- a/web/plugins/userdb/ldap.py
+++ b/web/plugins/userdb/ldap.py
@@ -261,6 +261,7 @@ ldap_attribute_plugins['alias'] = {
 # Connector hook functions
 #
 
+# This function only validates credentials, no locked checking or similar
 def ldap_login(username, password):
     ldap_connect()
     # Returns None when the user is not found or not uniq, else returns the
@@ -328,17 +329,28 @@ def ldap_sync(add_to_changelog, only_username):
 
 # Calculates the attributes of the users which are locked for users managed
 # by this connector
-def ldap_locked():
+def ldap_locked_attributes():
     locked = set([ 'password' ]) # This attributes are locked in all cases!
     for key in config.ldap_active_plugins:
         locked.update(ldap_attribute_plugins[key]['set_attributes'])
     return list(locked)
 
+# Is called on every multisite http request
+def ldap_page():
+    # FIXME: Implement
+    pass
+
 multisite_user_connectors.append({
     'id':    'ldap',
     'title': _('LDAP (AD, OpenLDAP)'),
 
     'login':             ldap_login,
     'sync':              ldap_sync,
-    'locked_attributes': ldap_locked,
+    'page':              ldap_page,
+    'locked':            user_locked, # no ldap check, just check the WATO attribute.
+                                      # This handles setups where the locked attribute is not
+                                      # synchronized and the user is enabled in LDAP and disabled
+                                      # in Check_MK. When the user is locked in LDAP a login is
+                                      # not possible.
+    'locked_attributes': ldap_locked_attributes,
 })



More information about the checkmk-commits mailing list