diff --git a/bin/xymon-permissions.py b/bin/xymon-permissions.py
new file mode 100755
index 0000000000000000000000000000000000000000..1f3f9c33a5b9fe783a273a2c68e65dd5dee0d0a0
--- /dev/null
+++ b/bin/xymon-permissions.py
@@ -0,0 +1,150 @@
+#!/usr/bin/env python3
+
+import os
+import sys
+import pwd
+import grp
+import stat
+import glob
+import posix1e
+import pyxymon as pymon
+
+CHECK_NAME = 'permissions'
+CHECK_VERSION = 2
+LIFETIME = 30
+
+home_dir = '/export/home1/*'
+owner = []
+permission = []
+acl = []
+
+
+class Home(object):
+    """
+    Holds info about a home directory
+    """
+    def __init__(self, name, path, st):
+        self.name = name
+        self.path = path
+        self.st = st
+
+    @property
+    def uid(self):
+        return self.st.st_uid
+
+    @property
+    def gid(self):
+        return self.st.st_gid
+
+    @property
+    def uname(self):
+        return pwd.getpwuid(self.uid).pw_name
+
+    @property
+    def gname(self):
+        return grp.getgrgid(self.gid).gr_name
+
+    @property
+    def filemode(self):
+        return stat.filemode(self.st.st_mode)
+
+    @property
+    def permission(self):
+        return ' '.join([self.filemode, self.path])
+
+    def __str__(self):
+        return ' '.join([self.filemode, self.uname, self.gname, self.path])
+
+
+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):
+            continue
+        st = os.stat(pathname)
+        home = Home(f, pathname, st)
+
+        if bad_owner(home):
+            owner.append(home)
+
+        if bad_permission(home):
+            permission.append(home)
+
+        if posix1e.has_extended(home.path):
+            acl.append(home)
+
+
+def bad_owner(home):
+    if home.name == home.uname and home.name == home.gname:
+        return False
+    return True
+
+
+def bad_permission(home):
+    # d---------
+    if home.st.st_mode == stat.S_IFDIR:
+        return False
+    # drwx------
+    elif home.st.st_mode == stat.S_IFDIR | stat.S_IRUSR | stat.S_IWUSR | stat.S_IXUSR:
+        return False
+    return True
+
+
+def list_homes(homes):
+    for home in homes:
+        print(home)
+
+
+def run_check(xymon):
+    for path in glob.glob(home_dir):
+        check_homes(path)
+
+    if owner:
+        title = 'bad owner or group'
+        content = 'home must be owned by the respective user and the group his user-private-group<br/><br/>'
+        for home in owner:
+            content += ''.join([str(home), '<br/>'])
+        xymon.section(title, content)
+        xymon.color = pymon.STATUS_CRITICAL
+
+    if permission:
+        title = 'bad permissions'
+        content = 'home permission not <code>drwx------</code> (active user) or <code>d---------</code> (blocked user)<br/><br/>'
+        for home in permission:
+            content += ''.join([str(home.permission), '<br/>'])
+        xymon.section(title, content)
+        xymon.color = pymon.STATUS_CRITICAL
+
+    if acl:
+        title = 'bad acls'
+        content = 'home has posix.1e extended ACLs<br/>check acls using `getfacl`, which stands for `get fucking ACL`<br/><br/>'
+        for home in acl:
+            extacl = posix1e.ACL(file=home.path)
+            content += ''.join([home.path, '<br/>'])
+            content += ''.join([str(extacl), '<br/>'])
+        xymon.section(title, content)
+        xymon.color = pymon.STATUS_CRITICAL
+
+def main():
+    """Run xymon check"""
+    xymon = pymon.XymonClient(CHECK_NAME)
+    check_script = os.path.basename(__file__)
+    # The default criticity is set to 'pymon.STATUS_OK'
+    xymon.lifetime = LIFETIME
+    xymon.title('home ownership and permissions')
+
+    try:
+        run_check(xymon)
+    except Exception as e:
+        xymon.color = pymon.STATUS_WARNING
+        xymon.section('Exception', e)
+
+    xymon.footer(check_script, CHECK_VERSION)
+    xymon.send()
+
+
+if __name__ == '__main__':
+    main()
+    sys.exit(0)