From e47a6249f6e5d2436e9d698d8010a986e7c383ee Mon Sep 17 00:00:00 2001 From: aewens Date: Tue, 8 Jan 2019 18:33:07 +0100 Subject: [PATCH] Moved bin to sbin, added lib and update_passwd_and_group --- .gitignore | 2 +- lib/__init__.py | 1 + lib/helpers.py | 58 ++++++++++++++++++++++++++++++++ lib/ldap_core.py | 65 ++++++++++++++++++++++++++++++++++++ {bin => sbin}/modify_user | 0 {bin => sbin}/new_user | 0 {bin => sbin}/remove_user | 0 {bin => sbin}/sslca | 0 sbin/update_passwd_and_group | 25 ++++++++++++++ 9 files changed, 150 insertions(+), 1 deletion(-) create mode 100644 lib/__init__.py create mode 100644 lib/helpers.py create mode 100644 lib/ldap_core.py rename {bin => sbin}/modify_user (100%) rename {bin => sbin}/new_user (100%) rename {bin => sbin}/remove_user (100%) rename {bin => sbin}/sslca (100%) create mode 100755 sbin/update_passwd_and_group diff --git a/.gitignore b/.gitignore index 6a18ad4..a6ef2c5 100644 --- a/.gitignore +++ b/.gitignore @@ -16,7 +16,7 @@ dist/ downloads/ eggs/ .eggs/ -lib/ +#lib/ lib64/ parts/ sdist/ diff --git a/lib/__init__.py b/lib/__init__.py new file mode 100644 index 0000000..d6a941b --- /dev/null +++ b/lib/__init__.py @@ -0,0 +1 @@ +from ldap_core import LDAPCore diff --git a/lib/helpers.py b/lib/helpers.py new file mode 100644 index 0000000..5018afb --- /dev/null +++ b/lib/helpers.py @@ -0,0 +1,58 @@ +from __future__ import print_function +from sys import stderr +from getpass import getpass +from ldap import initialize, LDAPError, INVALID_CREDENTIALS, SCOPE_SUBTREE + +def eprint(*args, **kwargs): + print(*args, file=stderr, **kwargs) + +def quit(con=None): + if con: + con.unbind_s() + +def ldap_connect(core, anonymous=False): + ldap_host = core.domain + root_user = getattr(core, "root_user", None) + root_pswd = getattr(core, "root_pswd", None) + if not anonymous: + print("Attempting to connect to LDAP...") + if root_pswd is None: + root_pswd = getpass("Password for %s: " % root_user) + try: + con = initialize("ldap://%s" % ldap_host) + try: + if not anonymous: + con.simple_bind_s(root_user, root_pswd) + else: + con.simple_bind_s() + except INVALID_CREDENTIALS: + eprint("Username or password is wrong, or anonymous is disabled") + quit(con) + except LDAPError, e: + if type(e.message) == dict and e.message.has_key("desc"): + eprint("Error: %s" % e.message["desc"]) + else: + eprint(e) + quit(con) + return con + except LDAPError, e: + if type(e.message) == dict and e.message.has_key("desc"): + eprint(e.message["desc"]) + else: + eprint(e) + quit(con) + +def ldap_search(core, find="", ou="", attrs=[], search_dn="", + search="(objectclass=*)", root=False): + con = core.connection + if not len(search_dn) > 0: + search_dn = "%s" % core.dn + + if len(ou) > 0 and len(find) > 0: + search_dn = "%s,ou=%s,%s" % (find, ou, search_dn) + elif len(ou) > 0 and len(find) == 0: + search_dn = "ou=%s,%s" % (ou, search_dn) + elif len(ou) == 0 and len(find) > 0: + search_dn = "%s,%s" % (find, search_dn) + + return con.search_s(search_dn, SCOPE_SUBTREE, search, attrs) \ No newline at end of file diff --git a/lib/ldap_core.py b/lib/ldap_core.py new file mode 100644 index 0000000..6cfb64b --- /dev/null +++ b/lib/ldap_core.py @@ -0,0 +1,65 @@ +from helpers import * + +class LDAPCore: + def __init__(self, root_cred, domain): + self.domain = domain + self.dn = self.__domain_to_dn() + if root_cred: + self.root_name = root_cred[0] + self.root_pswd = root_cred[1] + self.root_user = "cn=%s,%s" % (self.root_name, self.dn) + self.connection = ldap_connect(self) + else: + self.connection = ldap_connect(self, anonymous=True) + + def __domain_to_dn(self, domain=None): + if domain is None: + domain = self.domain + prefix = lambda p: "dc=%s" % p + dcs = list(map(prefix, domain.split("."))) + return ",".join(dcs) + + def close(self): + quit(self.connection) + + def search(self, find="", ou="", attrs=[], search_dn="", + search="(objectclass=*)", root=False): + return ldap_search(self, find, ou, attrs, search_dn, search, root) + + def parse_passwd(self, user_info): + uid = user_info["uid"] + uidn = user_info["uidNumber"] + gidn = user_info["gidNumber"] + gecos = user_info["gecos"] + home = user_info["homeDirectory"] + shell = user_info["loginShell"] + return "%s:x:%s:%s:%s:%s:%s" % (uid, uidn, gidn, gecos, home, shell) + + def parse_group(self, group_info): + cn = group_info["cn"] + gidn = group_info["gidNumber"] + return "%s:x:%s:" % (cn, gidn) + + def users(self): + ldap_users = "ou=People,%s" % self.dn + attrs = [ + "uid", + "uidNumber", + "gidNumber", + "gecos", + "homeDirectory", + "loginShell" + ] + results = self.search(search_dn=ldap_users, attrs=attrs) + users = [self.parse_passwd({ + k: v[0] for k, v in user[1].items() + }) for user in results if len(user[1]) > 0] + return users + + def groups(self): + ldap_users = "ou=Group,%s" % self.dn + results = self.search(search_dn=ldap_users, attrs=["cn","gidNumber"]) + groups = [self.parse_group({ + k: v[0] for k, v in group[1].items() + }) for group in results if len(group[1]) > 0] + return groups diff --git a/bin/modify_user b/sbin/modify_user similarity index 100% rename from bin/modify_user rename to sbin/modify_user diff --git a/bin/new_user b/sbin/new_user similarity index 100% rename from bin/new_user rename to sbin/new_user diff --git a/bin/remove_user b/sbin/remove_user similarity index 100% rename from bin/remove_user rename to sbin/remove_user diff --git a/bin/sslca b/sbin/sslca similarity index 100% rename from bin/sslca rename to sbin/sslca diff --git a/sbin/update_passwd_and_group b/sbin/update_passwd_and_group new file mode 100755 index 0000000..e15cf14 --- /dev/null +++ b/sbin/update_passwd_and_group @@ -0,0 +1,25 @@ +#!/usr/bin/env python + +import sys + +sys.path.insert(0, "/center/lib/center") + +from ldap_core import LDAPCore + +name = "Manager" +domain = "tilde.center" +etc = "/center/etc" +with open("%s/secrets/ldap.secret" % etc, "r") as secret: + pswd = secret.read().strip() +root = (name, pswd) +core = LDAPCore(root, domain) +passwd_file = "%s/passwd" % etc +group_file = "%s/group" % etc +with open(passwd_file, "w") as passwd: + passwd.write("\n".join(core.users()) + "\n") + +with open(group_file, "w") as group: + group.write("\n".join(core.groups()) + "\n") + +core.close() +print("Successfully updated %s and %s!" % (passwd_file, group_file))