From e250af14f783b06ed307bd8a3092ff8178345127 Mon Sep 17 00:00:00 2001 From: Tanner Collin Date: Tue, 4 Feb 2020 23:16:07 -0700 Subject: [PATCH] Complete LDAP API functions and simplify --- ldapserver/ldap_functions.py | 205 ++++++++--------------------------- ldapserver/server.py | 4 +- 2 files changed, 45 insertions(+), 164 deletions(-) diff --git a/ldapserver/ldap_functions.py b/ldapserver/ldap_functions.py index 7cb9f65..b34ff9d 100644 --- a/ldapserver/ldap_functions.py +++ b/ldapserver/ldap_functions.py @@ -16,190 +16,71 @@ l.set_option(ldap.OPT_X_TLS,ldap.OPT_X_TLS_DEMAND) l.set_option(ldap.OPT_X_TLS_DEMAND, True) l.set_option(ldap.OPT_DEBUG_LEVEL, 255) -# === Protospace === -BASE = 'DC=ps,DC=protospace,DC=ca' -#BASE_Members = 'OU=XTest,OU=GroupsOU,DC=ps,DC=protospace,DC=ca' -BASE_Members = 'OU=MembersOU,DC=ps,DC=protospace,DC=ca' -BASE_Groups = 'OU=GroupsOU,DC=ps,DC=protospace,DC=ca' +BASE_MEMBERS = 'OU=Test,OU=GroupsOU,DC=ps,DC=protospace,DC=ca' # testing +#BASE_MEMBERS = 'OU=MembersOU,DC=ps,DC=protospace,DC=ca' # prod -def search(query): +def find_user(username): ''' Search for a user by sAMAccountname ''' - try: - bind = l.simple_bind_s(secrets.LDAP_USERNAME, secrets.LDAP_PASSWORD) + l.simple_bind_s(secrets.LDAP_USERNAME, secrets.LDAP_PASSWORD) + criteria = '(&(objectClass=user)(sAMAccountName={})(!(objectClass=computer)))'.format(username) + results = l.search_s(BASE_MEMBERS, ldap.SCOPE_SUBTREE, criteria, ['displayName','sAMAccountName','email'] ) - criteria = '(&(objectClass=user)(sAMAccountName={})(!(objectClass=computer)))'.format(query) - results = l.search_s(BASE_Members, ldap.SCOPE_SUBTREE, criteria, ['displayName','sAMAccountName','email'] ) + if len(results) != 1: + abort(HTTP_NOTFOUND) - print(" =============") - print(" Found %d Objects" % len(results)) - print(" =============") - - for result in results: - dn, attr = result - print(dn, attr) - - if (len(results) == 1): - print("length = 1") - - return(len(results)) - - finally: - l.unbind() - -def find_user(query): - ''' - Search for a user by sAMAccountname - ''' - try: - bind = l.simple_bind_s(secrets.LDAP_USERNAME, secrets.LDAP_PASSWORD) - criteria = '(&(objectClass=user)(sAMAccountName={})(!(objectClass=computer)))'.format(query) - results = l.search_s(BASE_Members, ldap.SCOPE_SUBTREE, criteria, ['displayName','sAMAccountName','email'] ) - - if len(results) != 1: - return False - - return results[0][0] - finally: - l.unbind() - print('unbound find') - -def findgroup(query): - ''' - Search for a group by sAMAccountname - ''' - try: - bind = l.simple_bind_s(secrets.LDAP_USERNAME, secrets.LDAP_PASSWORD) - - criteria = '(&(objectClass=group)(sAMAccountName={}))'.format(query) - results = l.search_s(BASE_Groups, ldap.SCOPE_SUBTREE, criteria, ['displayName','sAMAccountName'] ) - - for result in results: - #print(" --- ") - #print(results) - dn, attr = result - print(dn, attr) - - rCode = "OK" - - except Exception as inst: - print("== Entering Except ==") - rCode = type(inst) - print(type(inst)) # the exception instance - - finally: - l.unbind() - return(rCode) + return results[0][0] def create_user(first, last, username, email, password): ''' Create a User; required data is first, last, email, username, password Note: this creates a disabled user, then sets a password, then enables the user ''' - try: - bind = l.simple_bind_s(secrets.LDAP_USERNAME, secrets.LDAP_PASSWORD) - dn = 'CN={} {},{}'.format(first, last, BASE_Members) - full_name = '{} {}'.format(first, last) + l.simple_bind_s(secrets.LDAP_USERNAME, secrets.LDAP_PASSWORD) + dn = 'CN={} {},{}'.format(first, last, BASE_MEMBERS) + full_name = '{} {}'.format(first, last) - ldif = [ - ('objectClass', [b'top', b'person', b'organizationalPerson', b'user']), - ('cn', [full_name.encode()]), - ('userPrincipalName', [username.encode()]), - ('sAMAccountName', [username.encode()]), - ('givenName', [first.encode()]), - ('sn', [last.encode()]), - ('DisplayName', [full_name.encode()]), - ('userAccountControl', [b'514']), - ('mail', [email.encode()]), - ] + ldif = [ + ('objectClass', [b'top', b'person', b'organizationalPerson', b'user']), + ('cn', [full_name.encode()]), + ('userPrincipalName', [username.encode()]), + ('sAMAccountName', [username.encode()]), + ('givenName', [first.encode()]), + ('sn', [last.encode()]), + ('DisplayName', [full_name.encode()]), + ('userAccountControl', [b'514']), + ('mail', [email.encode()]), + ] - l.add_s(dn, ldif) - rCode = "OK" + l.add_s(dn, ldif) - # set password - pass_quotes = '"{}"'.format(password) - pass_uni = pass_quotes.encode('utf-16-le') - change_des = [(ldap.MOD_REPLACE, 'unicodePwd', [pass_uni])] - result = l.modify_s(dn, change_des) + # set password + pass_quotes = '"{}"'.format(password) + pass_uni = pass_quotes.encode('utf-16-le') + change_des = [(ldap.MOD_REPLACE, 'unicodePwd', [pass_uni])] + result = l.modify_s(dn, change_des) - # 512 will set user account to enabled - mod_acct = [(ldap.MOD_REPLACE, 'userAccountControl', b'512')] - result = l.modify_s(dn, mod_acct) - - finally: - print("== Entering Finally ==") - l.unbind() - return(rCode) - -def create_group(groupname): - ''' - Create a group, for proof of concept, will usually be done manually - ''' - try: - dn = 'CN={},{}'.format(groupname, BASE) - bind = l.simple_bind_s(secrets.LDAP_USERNAME, secrets.LDAP_PASSWORD) - - ldif = [ - ('objectClass', [b'group']), - ('groupType', [b'-2147483646']), - ('cn', [groupname.encode()]), - ('name', [groupname.encode()]), - ('sAMAccountName', [groupname.encode()]), - ] - - l.add_s(dn, ldif) - - finally: - l.unbind() + # 512 will set user account to enabled + mod_acct = [(ldap.MOD_REPLACE, 'userAccountControl', b'512')] + result = l.modify_s(dn, mod_acct) def set_password(username, password): - try: - bind = l.simple_bind_s(secrets.LDAP_USERNAME, secrets.LDAP_PASSWORD) - criteria = '(&(objectClass=user)(sAMAccountName={})(!(objectClass=computer)))'.format(username) - results = l.search_s(BASE_Members, ldap.SCOPE_SUBTREE, criteria, ['displayName','sAMAccountName','email'] ) + l.simple_bind_s(secrets.LDAP_USERNAME, secrets.LDAP_PASSWORD) + criteria = '(&(objectClass=user)(sAMAccountName={})(!(objectClass=computer)))'.format(username) + results = l.search_s(BASE_MEMBERS, ldap.SCOPE_SUBTREE, criteria, ['displayName','sAMAccountName','email'] ) - if len(results) != 1: - abort(HTTP_NOTFOUND) + if len(results) != 1: + abort(HTTP_NOTFOUND) - dn = results[0][0] - - # set password - pass_quotes = '"{}"'.format(password) - pass_uni = pass_quotes.encode('utf-16-le') - change_des = [(ldap.MOD_REPLACE, 'unicodePwd', [pass_uni])] - result = l.modify_s(dn, change_des) - finally: - l.unbind() + dn = results[0][0] + # set password + pass_quotes = '"{}"'.format(password) + pass_uni = pass_quotes.encode('utf-16-le') + change_des = [(ldap.MOD_REPLACE, 'unicodePwd', [pass_uni])] + result = l.modify_s(dn, change_des) if __name__ == '__main__': - -# =========================================== -# Sample Progams -# =========================================== - #print("----------------------------------------------------------------------------------------") - #i = 3 - # - #if ( i == 1): - # rCode = find_user('*') - #elif (i == 2): - # rCode = search('*') - #elif (i == 3): - # rCode = create_user( - # 'billy', - # 'gates', - # 'billy.gates', - # 'billy.gates@protospace.ca', - # 'P@ssw0rd99' - # ) - #elif ( i == 4): - # create_group('testgroup') - #else: - # print("No function selected") - # - # - #print("ReturnCode = " + str(rCode)) - #print(find_user('tanner.collin')) print(set_password('dsaftanner.collin', 'Supersecret@@')) diff --git a/ldapserver/server.py b/ldapserver/server.py index ff61069..c2e51b6 100644 --- a/ldapserver/server.py +++ b/ldapserver/server.py @@ -15,13 +15,13 @@ def check_auth(): def index(): return 'SEE YOU SPACE SAMURAI...' -@app.route('/check-username-exists', methods=['GET']) +@app.route('/find-user', methods=['POST']) def check_username_exists(): check_auth() username = request.form['username'] - return ldap_functions.check_username_exists(username) + return ldap_functions.find_user(username) @app.route('/create-user', methods=['POST']) def create_user():