From c113a55b5d13c3b159196871189c2a9ff3241d3e Mon Sep 17 00:00:00 2001 From: Matteo Guadrini Date: Mon, 24 Aug 2020 16:30:43 +0200 Subject: [PATCH 1/7] Fix computer in automatic process --- vmam.py | 99 +++++++++++++++++++++++++++++---------------------------- 1 file changed, 51 insertions(+), 48 deletions(-) diff --git a/vmam.py b/vmam.py index df6c441..6f4ac93 100644 --- a/vmam.py +++ b/vmam.py @@ -1747,57 +1747,60 @@ def cli_start(arguments): debugger(arguments.verbose, wt, 'No "user" in configuration file: LDAP->add_group_type' ) - # Assign computer to VLAN groups - if 'computer' in cfg['LDAP']['add_group_type']: - g = query_ldap(bind_start, cfg['LDAP']['user_base_dn'], - ['member', 'distinguishedname'], - objectclass='group', - name=cfg['VMAM']['vlan_group_id'][vid]) - gdn = g[0].get('dn') - cdn = c_attribute.get('distinguishedname') - # Add VLAN LDAP group to computer account - if cdn not in g[0]['attributes']['member']: - add_to_group(bind_start, gdn, cdn) - print('Add VLAN group {0} to computer {1}'.format(gdn, cdn)) - wt.info( - 'Add VLAN group {0} to computer {1}'.format(gdn, cdn)) - else: - debugger(arguments.verbose, wt, - 'VLAN group {0} already added to ' - 'computer {1}'.format( - cfg['VMAM']['vlan_group_id'][vid], cdn)) - # Add description to computer account - set_user(bind_start, c_attribute.get('distinguishedname'), - description='User: {0} Mac: {1}'.format( - users[0][0], - ' '.join( - [format_mac(mac, cfg['VMAM']['mac_format']) - for mac in macs] - ) - )) - # Remove other VLAN LDAP group - for vgkey, vgvalue in cfg['VMAM']['vlan_group_id'].items(): - # Check if VLAN-ID isn't equal - if vgkey != vid: - g = query_ldap(bind_start, cfg['LDAP']['user_base_dn'], - ['member', 'distinguishedname'], - objectclass='group', name=vgvalue) - gdn = g[0]['dn'] - gmember = g[0]['attributes']['member'] - # Remove member of group - if cdn in gmember: - remove_to_group(bind_start, gdn, cdn) - print( - 'Remove VLAN group {0} to computer {1}'.format( - gdn, cdn)) - wt.info( - 'Remove VLAN group {0} to computer {1}'.format( - gdn, cdn)) + # Assign computer to VLAN groups + if 'computer' in cfg['LDAP']['add_group_type']: + g = query_ldap(bind_start, cfg['LDAP']['user_base_dn'], + ['member', 'distinguishedname'], + objectclass='group', + name=cfg['VMAM']['vlan_group_id'][vid]) + gdn = g[0].get('dn') + cdn = c_attribute.get('distinguishedname') + # Add VLAN LDAP group to computer account + if cdn not in g[0]['attributes']['member']: + add_to_group(bind_start, gdn, cdn) + print('Add VLAN group {0} to computer {1}'.format(gdn, + cdn)) + wt.info( + 'Add VLAN group {0} to computer {1}'.format(gdn, + cdn)) else: debugger(arguments.verbose, wt, - 'No "computer" in configuration file: ' - 'LDAP->add_group_type' + 'VLAN group {0} already added to ' + 'computer {1}'.format( + cfg['VMAM']['vlan_group_id'][vid], cdn)) + # Add description to computer account + set_user(bind_start, c_attribute.get('distinguishedname'), + description='User: {0} Mac: {1}'.format( + users[0][0], + ' '.join( + [format_mac(mac, cfg['VMAM']['mac_format']) + for mac in macs] ) + )) + # Remove other VLAN LDAP group + for vgkey, vgvalue in cfg['VMAM']['vlan_group_id'].items(): + # Check if VLAN-ID isn't equal + if vgkey != vid: + g = query_ldap(bind_start, + cfg['LDAP']['user_base_dn'], + ['member', 'distinguishedname'], + objectclass='group', name=vgvalue) + gdn = g[0]['dn'] + gmember = g[0]['attributes']['member'] + # Remove member of group + if cdn in gmember: + remove_to_group(bind_start, gdn, cdn) + print( + 'Remove VLAN group {0} to computer {1}'.format( + gdn, cdn)) + wt.info( + 'Remove VLAN group {0} to computer {1}'.format( + gdn, cdn)) + else: + debugger(arguments.verbose, wt, + 'No "computer" in configuration file: ' + 'LDAP->add_group_type' + ) else: continue except Exception as err: From 96635edfbd0dd78baf008140a2a3c048fe72b574 Mon Sep 17 00:00:00 2001 From: Matteo Guadrini Date: Thu, 27 Aug 2020 16:43:16 +0200 Subject: [PATCH 2/7] Added support for FreeIpa user creations --- vmam.py | 143 +++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 90 insertions(+), 53 deletions(-) diff --git a/vmam.py b/vmam.py index 6f4ac93..5a0ad01 100644 --- a/vmam.py +++ b/vmam.py @@ -238,7 +238,7 @@ def logwriter(logfile): _format = logging.Formatter('%(asctime)s %(levelname)-4s %(message)s') # Folder exists? leaf = os.path.split(logfile) - if not leaf[0]: + if not os.path.exists(leaf[0]): try: os.makedirs(leaf[0]) except Exception as err: @@ -419,7 +419,7 @@ def new_config(path=(get_platform()['conf_default'])): """ # Folder exists? leaf = os.path.split(path) - if not leaf[0]: + if not os.path.exists(leaf[0]): try: os.makedirs(leaf[0]) except Exception as err: @@ -701,13 +701,12 @@ def new_user(bind_object, username, **attributes): >>> conn = connect_ldap(['dc1.foo.bar']) >>> bind = bind_ldap(conn, r'domain\\user', 'password', tls=True) - >>> new_user(bind, 'CN=ex_user1,OU=User_ex,DC=foo,DC=bar', givenName='User 1', sn='Example') + >>> new_user(bind, 'CN=ex_user1,OU=User_ex,DC=foo,DC=bar', objectClass='user', givenName='User 1', sn='Example') """ # Create user bind_object.add( username, - ['top', 'person', 'organizationalPerson', 'user'], - attributes + attributes=attributes ) return bind_object.result @@ -776,16 +775,16 @@ def set_user_password(bind_object, username, password, *, ldap_version='LDAP'): """ # Set password if ldap_version == 'LDAP': - bind_object.extend.StandardExtendedOperations.modify_password(username, new_password=password, - old_password=None) + bind_object.extend.standard.modify_password(username, new_password=password, + old_password=None) elif ldap_version == 'MS-LDAP': bind_object.extend.microsoft.modify_password(username, new_password=password, old_password=None) elif ldap_version == 'N-LDAP': bind_object.extend.NovellExtendedOperations.set_universal_password(username, new_password=password, old_password=None) else: - bind_object.extend.StandardExtendedOperations.modify_password(username, new_password=password, - old_password=None) + bind_object.extend.standard.modify_password(username, new_password=password, + old_password=None) def add_to_group(bind_object, groupname, members): @@ -1234,17 +1233,49 @@ def cli_new_mac(config, bind, mac, vgroup, logger, arguments, description=None): # Query: check if mac-address exist debugger(arguments.verbose, logger, 'Exist mac-address {0} on LDAP servers {1}?'.format( mac, ','.join(config['LDAP']['servers']))) - ret = query_ldap(bind, config['LDAP']['mac_user_base_dn'], ['samaccountname', 'description'], - samaccountname=mac) - if not ret or not ret[0].get('dn'): - debugger(arguments.verbose, logger, 'Mac-address {0} not exists on LDAP servers {1}'.format( - mac, ','.join(config['LDAP']['servers']))) - # Add mac-address to LDAP - attrs = {'givenname': 'mac-address', + # Create the attribute dictionary + if ldap_v == 'MS-LDAP': + login_attr = 'samaccountname' + user_class = 'user' + group_class = 'group' + group_name = 'name' + u_search_attributes = ['memberof'] + g_search_attributes = ['member', 'distinguishedname'] + attrs = {'objectClass': ['top', 'person', 'organizationalPerson', 'user'], + 'givenname': 'mac-address', 'sn': mac, - 'samaccountname': mac, + login_attr: mac, 'userprincipalname': '{0}@{1}'.format(mac, config['LDAP']['domain']), 'description': description} + else: + # Get uidNumber and gidNumber + ug = query_ldap(bind, config['LDAP']['mac_user_base_dn'], ['uidNumber', 'gidNumber'], uidNumber='*') + if ug: + uid = ug[-1]['attributes']['uidNumber'] + 1 + gid = ug[-1]['attributes']['gidNumber'] + 1 + else: + uid = 1 + gid = 1 + login_attr = 'uid' + user_class = 'inetorgperson' + group_class = 'posixgroup' + group_name = 'cn' + u_search_attributes = ['memberof'] + g_search_attributes = ['member', 'dn'] + attrs = {'objectClass': ['top', 'person', 'organizationalperson', 'inetorgperson', 'posixaccount'], + 'givenname': 'mac-address', + 'sn': mac, + login_attr: mac, + 'cn': mac, + 'homeDirectory': '/tmp/{0}'.format(mac), + 'gidNumber': gid, + 'uidNumber': uid, + 'description': description} + ret = query_ldap(bind, config['LDAP']['mac_user_base_dn'], [login_attr, 'description'], + **{login_attr: mac}) + if not ret or not ret[0].get('dn'): + debugger(arguments.verbose, logger, 'Mac-address {0} not exists on LDAP servers {1}'.format( + mac, ','.join(config['LDAP']['servers']))) # Check write_attrib on configuration file vflag = 'VMAM_MANUAL {0}'.format(VERSION) if arguments.action == 'mac' else 'VMAM_AUTO {0}'.format(VERSION) if config['LDAP']['write_attrib']: @@ -1280,17 +1311,18 @@ def cli_new_mac(config, bind, mac, vgroup, logger, arguments, description=None): for key, value in config['VMAM']['vlan_group_id'].items(): # Check exist VLAN-ID in configuration file if vgroup == key: - g = query_ldap(bind, config['LDAP']['user_base_dn'], ['member', 'distinguishedname'], - objectclass='group', name=value) - u = query_ldap(bind, config['LDAP']['mac_user_base_dn'], ['memberof'], - objectclass='user', name=mac) - gdn = g[0]['dn'] - umember = u[0]['attributes']['memberof'] + g = query_ldap(bind, config['LDAP']['user_base_dn'], g_search_attributes, + **{'objectclass': group_class, group_name: value}) + u = query_ldap(bind, config['LDAP']['mac_user_base_dn'], u_search_attributes, + **{'objectclass': user_class, login_attr: mac}) + gdn = g[0]['dn'] if g else None + umember = u[0]['attributes']['memberof'] if u else [] # Add VLAN LDAP group to user mac address if gdn not in umember: - add_to_group(bind, gdn, dn) - print('Add VLAN group {0} to user {1}'.format(gdn, dn)) - logger.info('Add VLAN group {0} to user {1}'.format(gdn, dn)) + if gdn: + add_to_group(bind, gdn, dn) + print('Add VLAN group {0} to user {1}'.format(gdn, dn)) + logger.info('Add VLAN group {0} to user {1}'.format(gdn, dn)) else: debugger(arguments.verbose, logger, 'VLAN group {0} already added to user {1}'.format( config['VMAM']['vlan_group_id'][vgroup], dn)) @@ -1305,24 +1337,26 @@ def cli_new_mac(config, bind, mac, vgroup, logger, arguments, description=None): exit(16) # Custom group try: - debugger(arguments.verbose, logger, 'Verify custom groups {0} to user {1}'.format( - ','.join(config['LDAP']['other_group']), dn)) - for group in config['LDAP']['other_group']: - g = query_ldap(bind, config['LDAP']['user_base_dn'], ['member', 'distinguishedname'], - objectclass='group', name=group) - u = query_ldap(bind, config['LDAP']['mac_user_base_dn'], ['memberof'], - objectclass='user', name=mac) - gdn = g[0]['dn'] - umember = u[0]['attributes']['memberof'] - # Add VLAN LDAP group to user mac address - if gdn not in umember: - add_to_group(bind, gdn, dn) - print('Add custom groups {0} to user {1}'.format(gdn, dn)) - logger.info('Add custom groups {0} to user {1}'.format(gdn, dn)) - else: - debugger(arguments.verbose, logger, 'Custom groups {0} already added to user {1}'.format( - ','.join(config['LDAP']['other_group']), dn)) - break + if config['LDAP']['other_group']: + debugger(arguments.verbose, logger, 'Verify custom groups {0} to user {1}'.format( + ','.join(config['LDAP']['other_group']), dn)) + for group in config['LDAP']['other_group']: + g = query_ldap(bind, config['LDAP']['user_base_dn'], g_search_attributes, + **{'objectclass': group_class, group_name: group}) + u = query_ldap(bind, config['LDAP']['mac_user_base_dn'], u_search_attributes, + **{'objectclass': user_class, login_attr: mac}) + gdn = g[0]['dn'] if g else None + umember = u[0]['attributes']['memberof'] if u else [] + # Add VLAN LDAP group to user mac address + if gdn not in umember: + if gdn: + add_to_group(bind, gdn, dn) + print('Add custom groups {0} to user {1}'.format(gdn, dn)) + logger.info('Add custom groups {0} to user {1}'.format(gdn, dn)) + else: + debugger(arguments.verbose, logger, 'Custom groups {0} already added to user {1}'.format( + ','.join(config['LDAP']['other_group']), dn)) + break except Exception as err: print('ERROR:', err) logger.error(err) @@ -1334,17 +1368,18 @@ def cli_new_mac(config, bind, mac, vgroup, logger, arguments, description=None): for key, value in config['VMAM']['vlan_group_id'].items(): # Check if VLAN-ID isn't equal if vgroup != key: - g = query_ldap(bind, config['LDAP']['user_base_dn'], ['member', 'distinguishedname'], - objectclass='group', name=value) - u = query_ldap(bind, config['LDAP']['mac_user_base_dn'], ['memberof'], - objectclass='user', name=mac) - gdn = g[0]['dn'] - umember = u[0]['attributes']['memberof'] + g = query_ldap(bind, config['LDAP']['user_base_dn'], g_search_attributes, + **{'objectclass': group_class, group_name: value}) + u = query_ldap(bind, config['LDAP']['mac_user_base_dn'], u_search_attributes, + **{'objectclass': user_class, login_attr: mac}) + gdn = g[0]['dn'] if g else None + umember = u[0]['attributes']['memberof'] if u else [] # Remove member of group if gdn in umember: - remove_to_group(bind, gdn, dn) - print('Remove VLAN group {0} to user {1}'.format(gdn, dn)) - logger.info('Remove VLAN group {0} to user {1}'.format(gdn, dn)) + if gdn: + remove_to_group(bind, gdn, dn) + print('Remove VLAN group {0} to user {1}'.format(gdn, dn)) + logger.info('Remove VLAN group {0} to user {1}'.format(gdn, dn)) except Exception as err: print('ERROR:', err) logger.error(err) @@ -1366,6 +1401,8 @@ def cli_new_mac(config, bind, mac, vgroup, logger, arguments, description=None): except Exception as err: print('ERROR:', err) logger.error(err) + import traceback + traceback.print_last() exit(9) if not exist: print('Mac-address user {0} successfully created'.format(mac)) From a3982dbfeab690fbdae68c89be63e992a05443a7 Mon Sep 17 00:00:00 2001 From: Matteo Guadrini Date: Fri, 28 Aug 2020 09:55:39 +0200 Subject: [PATCH 3/7] Added support for FreeIpa disable user --- vmam.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/vmam.py b/vmam.py index 5a0ad01..2b9b029 100644 --- a/vmam.py +++ b/vmam.py @@ -1431,8 +1431,10 @@ def cli_disable_mac(config, bind, mac, logger, arguments, description=None): # Query: check if mac-address exist debugger(arguments.verbose, logger, 'Exist mac-address {0} on LDAP servers {1}?'.format( mac, ','.join(config['LDAP']['servers']))) - ret = query_ldap(bind, config['LDAP']['mac_user_base_dn'], ['samaccountname', 'description'], - samaccountname=mac) + login_attr = 'samaccountname' if ldap_v == 'MS-LDAP' else 'uid' + u_search_attributes = ['samaccountname', 'description'] if ldap_v == 'MS-LDAP' else ['uid', 'description'] + ret = query_ldap(bind, config['LDAP']['mac_user_base_dn'], u_search_attributes, + **{login_attr: mac}) if ret and ret[0].get('dn'): force = confirm('Do you want to disable {0} mac-address?'.format(mac)) if not arguments.force else True if force: From 21ef635694949a2c0e7d1e8c08bd31e43a6f7f98 Mon Sep 17 00:00:00 2001 From: Matteo Guadrini Date: Fri, 28 Aug 2020 10:13:48 +0200 Subject: [PATCH 4/7] Added support for FreeIpa remove user --- vmam.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/vmam.py b/vmam.py index 2b9b029..7ccfba7 100644 --- a/vmam.py +++ b/vmam.py @@ -1433,8 +1433,7 @@ def cli_disable_mac(config, bind, mac, logger, arguments, description=None): mac, ','.join(config['LDAP']['servers']))) login_attr = 'samaccountname' if ldap_v == 'MS-LDAP' else 'uid' u_search_attributes = ['samaccountname', 'description'] if ldap_v == 'MS-LDAP' else ['uid', 'description'] - ret = query_ldap(bind, config['LDAP']['mac_user_base_dn'], u_search_attributes, - **{login_attr: mac}) + ret = query_ldap(bind, config['LDAP']['mac_user_base_dn'], u_search_attributes, **{login_attr: mac}) if ret and ret[0].get('dn'): force = confirm('Do you want to disable {0} mac-address?'.format(mac)) if not arguments.force else True if force: @@ -1478,7 +1477,9 @@ def cli_delete_mac(config, bind, mac, logger, arguments): # Query: check if mac-address exist debugger(arguments.verbose, logger, 'Exist mac-address {0} on LDAP servers {1}?'.format( mac, ','.join(config['LDAP']['servers']))) - ret = query_ldap(bind, config['LDAP']['mac_user_base_dn'], ['samaccountname'], samaccountname=mac) + login_attr = 'samaccountname' if ldap_v == 'MS-LDAP' else 'uid' + u_search_attributes = ['samaccountname'] if ldap_v == 'MS-LDAP' else ['uid'] + ret = query_ldap(bind, config['LDAP']['mac_user_base_dn'], u_search_attributes, **{login_attr: mac}) if ret and ret[0].get('dn'): force = confirm('Do you want to delete {0} mac-address?'.format(mac)) if not arguments.force else True if force: From 7d12cdef1e2eda4db2f80ec01e60b843c68023e9 Mon Sep 17 00:00:00 2001 From: Matteo Guadrini Date: Fri, 28 Aug 2020 11:27:51 +0200 Subject: [PATCH 5/7] Fix LDAP user creation --- vmam.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/vmam.py b/vmam.py index 7ccfba7..88afdb4 100644 --- a/vmam.py +++ b/vmam.py @@ -1262,7 +1262,8 @@ def cli_new_mac(config, bind, mac, vgroup, logger, arguments, description=None): group_name = 'cn' u_search_attributes = ['memberof'] g_search_attributes = ['member', 'dn'] - attrs = {'objectClass': ['top', 'person', 'organizationalperson', 'inetorgperson', 'posixaccount'], + attrs = {'objectClass': ['top', 'person', 'organizationalPerson', 'inetOrgPerson', + 'posixAccount', 'krbPrincipalAux'], 'givenname': 'mac-address', 'sn': mac, login_attr: mac, @@ -1270,6 +1271,7 @@ def cli_new_mac(config, bind, mac, vgroup, logger, arguments, description=None): 'homeDirectory': '/tmp/{0}'.format(mac), 'gidNumber': gid, 'uidNumber': uid, + 'krbPrincipalname': '{0}@{1}'.format(mac, config['LDAP']['domain']), 'description': description} ret = query_ldap(bind, config['LDAP']['mac_user_base_dn'], [login_attr, 'description'], **{login_attr: mac}) From dc79d7f734ac1aa12eedfe5638debef74c1614a0 Mon Sep 17 00:00:00 2001 From: Matteo Guadrini Date: Fri, 28 Aug 2020 15:14:19 +0200 Subject: [PATCH 6/7] Re-enable user if exists and disabled --- vmam.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/vmam.py b/vmam.py index 88afdb4..843dd30 100644 --- a/vmam.py +++ b/vmam.py @@ -1304,6 +1304,11 @@ def cli_new_mac(config, bind, mac, vgroup, logger, arguments, description=None): # Modify description if description not in ret[0]['attributes'].get('description'): set_user(bind, dn, description=description) + # Re-enable user if has been disabled + if ldap_v == 'MS-LDAP': + set_user(bind, dn, pwdLastSet=-1, userAccountControl=66048) + else: + set_user(bind, dn, nsaccountlock='False') exist = True # Add VLAN and custom LDAP group # VLAN-ID group From 06cfd71815a1833303ee10e2ba6e249321c96aae Mon Sep 17 00:00:00 2001 From: Matteo Guadrini Date: Sat, 29 Aug 2020 15:03:22 +0200 Subject: [PATCH 7/7] New version 1.4.0 --- setup.py | 2 +- vmam.1 | 2 +- vmam.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/setup.py b/setup.py index 7925291..32945d5 100644 --- a/setup.py +++ b/setup.py @@ -26,7 +26,7 @@ from setuptools import setup -VERSION = '1.3.3' +VERSION = '1.4.0' if not os.path.exists('bin'): os.makedirs('bin') diff --git a/vmam.1 b/vmam.1 index 43fb851..b0d4b87 100644 --- a/vmam.1 +++ b/vmam.1 @@ -1,6 +1,6 @@ .\" Manpage for vmam. .\" Contact matteo.guadrini@hotmail.it to correct errors or typos. -.TH man 1 "9 May 2020" "1.3.3" "vmam man page" +.TH man 1 "29 Aug 2020" "1.4.0" "vmam man page" .SH NAME vmam \- VLAN Mac\-address Authentication Manager .SH SYNOPSIS diff --git a/vmam.py b/vmam.py index 843dd30..a13e292 100644 --- a/vmam.py +++ b/vmam.py @@ -193,7 +193,7 @@ def check_module(module): # endregion # region Global variable -VERSION = '1.3.3' +VERSION = '1.4.0' __all__ = ['logwriter', 'debugger', 'confirm', 'read_config', 'get_platform', 'new_config', 'bind_ldap', 'check_connection', 'check_config', 'connect_ldap', 'unbind_ldap', 'query_ldap', 'check_ldap_version', 'new_user', 'set_user', 'delete_user', 'set_user_password', 'add_to_group', 'remove_to_group',