From 300673e7e43d92c93cf728e6b882b19ff6dae2c0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Sven=20M=C3=A4der?= <maeder@phys.ethz.ch>
Date: Thu, 23 Aug 2018 12:44:00 +0200
Subject: [PATCH] Add support for arbitrary entry searches

---
 bin/check-home-permissions.py | 60 +++++++++++++++++++++++++++++++++++
 lib/isg/dphysldap.py          | 26 ++++++++++-----
 2 files changed, 78 insertions(+), 8 deletions(-)

diff --git a/bin/check-home-permissions.py b/bin/check-home-permissions.py
index 79858af..ab716d4 100755
--- a/bin/check-home-permissions.py
+++ b/bin/check-home-permissions.py
@@ -6,11 +6,22 @@ import pwd
 import grp
 import stat
 import posix1e
+import lib_path
+import lib
+import dphysldap
 
 
+home_dirs = []
+users = {}
+nis_homes = {}
+nis_shares = {}
 owner = []
 permission = []
 acl = []
+bad_home_directory = []
+no_ldap_user = []
+bad_nis_map = []
+no_nis_map = []
 
 
 class Home(object):
@@ -50,9 +61,32 @@ class Home(object):
         return ' '.join([self.filemode, self.uname, self.gname, self.path])
 
 
+def search_ldap():
+    ldap = dphysldap.Ldap()
+    ldap_users = dphysldap.Users(ldap, ['uid', 'uidNumber', 'gidNumber', 'homeDirectory'])
+    entries = dphysldap.Entries(ldap, ['cn', 'nisMapEntry'])
+
+    ldap_users.search('*')
+    for user in ldap_users:
+        users[user['uid'][0]] = user['homeDirectory'][0]
+
+    entries.search('cn: *, nisMapEntry: phd-home*', ['nisObject'])
+    for entry in entries:
+        nis_homes[entry['cn'][0]] = entry['nisMapEntry'][0]
+
+    entries.search('cn: *, nisMapEntry: != phd-home*', ['nisObject'])
+    for entry in entries:
+        nis_shares[entry['cn'][0]] = entry['nisMapEntry'][0]
+
+    print('users: ' + str(len(users)))
+    print('nis_homes: ' + str(len(nis_homes)))
+    print('nis_shares: ' + str(len(nis_shares)))
+
+
 def check_homes(top):
     if not os.path.isdir(top):
         return
+
     for f in os.listdir(top):
         pathname = os.path.join(top, f)
         if not os.path.isdir(pathname):
@@ -69,6 +103,20 @@ def check_homes(top):
         if posix1e.has_extended(home.path):
             acl.append(home)
 
+        if home.name in users:
+            if users[home.name][6:] != home.name:
+                bad_home_directory.append(': '.join([home.name, users[home.name]]))
+            del users[home.name]
+        else:
+            no_ldap_user.append(home)
+
+        if home.name in nis_homes:
+            if nis_homes[home.name].split(':', maxsplit=1)[1] != home.path:
+                bad_nis_map.append(': '.join([home.name, nis_homes[home.name]]))
+            del nis_homes[home.name]
+        else:
+            no_nis_map.append(home)
+
 
 def bad_owner(home):
     if home.name == home.uname and home.name == home.gname:
@@ -94,11 +142,23 @@ def list_homes(homes):
 if __name__ == '__main__':
     arg_count = len(sys.argv) - 1
 
+    search_ldap()
+
     for i, arg in enumerate(sys.argv):
         if i == 0:
             continue
         check_homes(arg)
 
+    print()
+    print('users: ' + str(len(users)))
+    print('nis_homes: ' + str(len(nis_homes)))
+    print('nis_shares: ' + str(len(nis_shares)))
+    print('bad_home_directory: ' + str(len(bad_home_directory)))
+    print('no_ldap_user: ' + str(len(no_ldap_user)))
+    print('bad_nis_map: ' + str(len(bad_nis_map)))
+    print('no_nis_map: ' + str(len(no_nis_map)))
+    print()
+
     if owner:
         print('bad owner or group:')
         print('-------------------')
diff --git a/lib/isg/dphysldap.py b/lib/isg/dphysldap.py
index 55eb0e5..80b2c40 100644
--- a/lib/isg/dphysldap.py
+++ b/lib/isg/dphysldap.py
@@ -205,11 +205,21 @@ class Ldap(object):
         self.obj_user = None
         self.obj_group = None
 
-    def get_entries(self, obj, query='', attributes=None):
+    def get_object(self, classes):
+        """
+        Get an objectDef object from a list of objectClasses
+        """
+        return ldap3.ObjectDef(classes, self.connection)
+
+    def get_entries(self, obj=None, classes=None, base=None, query='', attributes=None):
         """
         Returns a list with entries as dict
         """
-        reader = ldap3.Reader(self.connection, obj, self.base, query, attributes)
+        if base is None:
+            base = self.base
+        if obj is None:
+            obj = self.get_object(classes)
+        reader = ldap3.Reader(self.connection, obj, base, query, attributes)
         reader.search()
         return [Entry(e.entry_attributes_as_dict) for e in reader.entries]
 
@@ -218,8 +228,8 @@ class Ldap(object):
         Returns a list with users as dict
         """
         if not self.obj_user:
-            self.obj_user = ldap3.ObjectDef(self.user_classes, self.connection)
-        entries = self.get_entries(self.obj_user, query=query, attributes=attributes)
+            self.obj_user = self.get_object(self.user_classes)
+        entries = self.get_entries(obj=self.obj_user, query=query, attributes=attributes)
         return [User(e) for e in entries]
 
     def get_groups(self, query='', attributes=None):
@@ -227,8 +237,8 @@ class Ldap(object):
         Returns a list with groups as dict
         """
         if not self.obj_group:
-            self.obj_group = ldap3.ObjectDef(self.group_classes, self.connection)
-        entries = self.get_entries(self.obj_group, query=query, attributes=attributes)
+            self.obj_group = self.get_object(self.group_classes)
+        entries = self.get_entries(obj=self.obj_group, query=query, attributes=attributes)
         return [Group(e) for e in entries]
 
 
@@ -263,13 +273,13 @@ class Entries(list):
         else:
             self.remove_attr(attrs)
 
-    def search(self, query):
+    def search(self, query, classes=None, obj=None, base=None):
         """
         Query syntax: `<attributeName>: <attributeValue(s)>`
         AttributeValue: `a`, `a*`, `*a*`, `a;b`
         """
         self.clear()
-        self.extend(self._ldap.get_entries(query=query, attributes=self.attrs))
+        self.extend(self._ldap.get_entries(obj=obj, classes=classes, base=base, query=query, attributes=self.attrs))
 
 
 class Groups(Entries):
-- 
GitLab