#!/usr/bin/python2.6 # -*- coding: utf-8 -*- # # Univention S4 Connector # Upgrade script for NTSecurityDescriptor attributes # # Copyright 2013-2014 Univention GmbH # # http://www.univention.de/ # # All rights reserved. # # The source code of this program is made available # under the terms of the GNU Affero General Public License version 3 # (GNU AGPL V3) as published by the Free Software Foundation. # # Binary versions of this program provided by Univention to you as # well as other copyrighted, protected or trademarked materials like # Logos, graphics, fonts, specific documentations and configurations, # cryptographic keys etc. are subject to a license agreement between # you and Univention and not subject to the GNU AGPL V3. # # In the case you use this program under the terms of the GNU AGPL V3, # the program is provided in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public # License with the Debian GNU/Linux or Univention distribution in file # /usr/share/common-licenses/AGPL-3; if not, see # . import subprocess import sys import string import ldap from optparse import OptionParser import univention.config_registry import univention.admin.uldap import univention.admin.uexceptions def _connect_ucs(configRegistry, binddn, bindpwd): ''' Connect to OpenLDAP ''' if binddn and bindpwd: bindpw = bindpwd else: bindpw_file = configRegistry.get('connector/ldap/bindpw', '/etc/ldap.secret') binddn = configRegistry.get('connector/ldap/binddn', 'cn=admin,'+configRegistry['ldap/base']) bindpw=open(bindpw_file).read() if bindpw[-1] == '\n': bindpw=bindpw[0:-1] host = configRegistry.get('connector/ldap/server', configRegistry.get('ldap/master')) try: port = int(configRegistry.get('connector/ldap/port', configRegistry.get('ldap/master/port'))) except: port = 7389 lo = univention.admin.uldap.access(host=host, port=port, base=configRegistry['ldap/base'], binddn=binddn, bindpw=bindpw, start_tls=2, follow_referral=True) return lo def search_s4(): ''' Search all S4 GPO objects with NTSecurityDescriptor attribute and return a dictonary with dn as key and NTSecurityDescriptor as result. ''' p1 = subprocess.Popen(['ldbsearch -H /var/lib/samba/private/sam.ldb "(&(objectClass=groupPolicyContainer)(NTSecurityDescriptor=*))" dn NTSecurityDescriptor | ldapsearch-wrapper'], stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True) (stdout,stderr) = p1.communicate() if p1.returncode != 0: print stderr sys.exit(p1.returncode) result = {} dn=None for line in stdout.split('\n'): line=line.strip() if line.startswith('dn: '): dn=line[4:] if line.startswith('nTSecurityDescriptor: '): nTSecurityDescriptor=line[len('nTSecurityDescriptor: '):] result[dn] = nTSecurityDescriptor dn=None return result def write_to_ucs(configRegistry, s4_result, binddn, bindpwd): ''' Write the result from search_s4 to UCS LDAP ''' lo = _connect_ucs(configRegistry, binddn, bindpwd) s4_ldap_base = configRegistry.get('connector/s4/ldap/base' ).lower() ucs_ldap_base = configRegistry.get('ldap/base').lower() for s4_dn in s4_result.keys(): ucs_dn = s4_dn.lower().replace(s4_ldap_base, ucs_ldap_base) ml = [] try: for dn, attributes in lo.search(base=ucs_dn, scope=ldap.SCOPE_BASE): ml.append( ('msNTSecurityDescriptor', attributes.get('msNTSecurityDescriptor'), s4_result[s4_dn]) ) if ml: print 'Set msNTSecurityDescriptor for UCS object (%s)' % (ucs_dn) lo.modify(ucs_dn, ml) except univention.admin.uexceptions.noObject: pass except: print 'Failed to set msNTSecurityDescriptor for UCS object (%s)' % (ucs_dn) pass if __name__ == '__main__': parser = OptionParser(usage='msGPOSecurityDescriptor.py (--write2ucs|--write2samba4)') parser.add_option("--write2ucs", dest="write2ucs", action="store_true", help="Write NTSecurityDescriptor from Samba 4 to UCS", default=False) parser.add_option("--binddn", dest="binddn", action="store", help="Binddn for UCS LDAP connection") parser.add_option("--bindpwd", dest="bindpwd", action="store", help="Password for UCS LDAP connection") (options, args) = parser.parse_args() configRegistry = univention.config_registry.ConfigRegistry() configRegistry.load() if options.write2ucs: result = search_s4() write_to_ucs(configRegistry, result, options.binddn, options.bindpwd) else: parser.print_help() sys.exit(1) sys.exit(0)