def open_ldap_connection(self, binddn=None, bindpw=None, ldap_server=None, admin=False, machine=False): '''Opens a new LDAP connection using the given user LDAP DN and password. The connection is established to the given server or (if None is given) to the server defined by the UCR variable ldap/server/name is used. If admin is set to True, a connection is setup by getAdminConnection(). If machine is set to True, a connection to the master is setup by getMachoneConnection(). ''' assert not (admin and machine) account = utils.UCSTestDomainAdminCredentials() if not ldap_server: ldap_server = self._ucr.get('ldap/master') port = int(self._ucr.get('ldap/server/port', 7389)) try: if admin: lo = udm_uldap.getAdminConnection()[0] elif machine: lo = udm_uldap.getMachineConnection(ldap_master=True)[0] else: lo = udm_uldap.access(host=ldap_server, port=port, base=self._ucr.get('ldap/base'), binddn=account.binddn, bindpw=account.bindpw, start_tls=2) except udm_errors.noObject: raise except LDAPError as exc: raise SchoolLDAPError('Opening LDAP connection failed: %s' % (exc,)) return lo
def get_machine_connection(): # TODO: find out and make a comment why ldap_master is False try: # get LDAP connection with machine account return udm_uldap.getMachineConnection(ldap_master=False) except (LDAPError, IOError) as exc: # problems connection to LDAP server or the server is not joined (machine.secret is missing) CORE.warn('An error occurred connecting to the LDAP server: %s' % exc) return None, None
def wrapper_func( *args, **kwargs ): global _ldap_connection, _ldap_position if _ldap_connection is not None: lo = _ldap_connection po = _ldap_position else: try: lo, po = udm_uldap.getMachineConnection( ldap_master = False ) except LDAPError, e: raise LDAP_ConnectionError( 'Opening LDAP connection failed: %s' % str( e ) )
def get_udm_infos(self, udm_module, udm_filter): # type: (Any, str) -> List[Any] try: self.listener.setuid(0) univention.admin.modules.update() lo, po = getMachineConnection() mod = univention.admin.modules.get(udm_module) return mod.lookup(None, lo, udm_filter) except: self.log_e( "get_udm_infos(%s, %s): Failed to retrieve UDM info:\n%s" % (udm_module, udm_filter, traceback.format_exc())) raise finally: self.listener.unsetuid()
def __init__( self, username, password ): global users_module self.__username = username self.__password = password self.__user_dn = None signals.Provider.__init__( self ) self.core_i18n = Translation( 'univention-management-console' ) self.i18n = I18N_Manager() self.i18n[ 'umc-core' ] = I18N() # stores the module processes [ modulename ] = <> self.__processes = {} self.__killtimer = {} lo = ldap.open( ucr[ 'ldap/server/name' ], int( ucr.get( 'ldap/server/port', 7389 ) ) ) try: # get LDAP connection with machine account self.lo, self.po = udm_uldap.getMachineConnection( ldap_master = False ) # get the LDAP DN of the authorized user ldap_dn = self.lo.searchDn( '(&(uid=%s)(objectClass=posixAccount))' % self.__username ) if ldap_dn: self.__user_dn = ldap_dn[ 0 ] CORE.info( 'The LDAP DN for user %s is %s' % ( self.__username, self.__user_dn ) ) else: CORE.info( 'The LDAP DN for user %s could not be found' % self.__username ) # initiate the users/user UDM module udm_modules.update() users_module = udm_modules.get('users/user') udm_modules.init(self.lo, self.po, users_module) except ( ldap.LDAPError, IOError ) as e: # problems connection to LDAP server or the server is not joined (machine.secret is missing) CORE.warn('An error occurred connecting to the LDAP server: %s' % e) self.lo = None users_module = None except udm_errors.base as e: # UDM error, user module coule not be initiated CORE.warn('An error occurred intializing the UDM users/user module: %s' % e) users_module = None # read the ACLs self.acls = LDAP_ACLs( self.lo, self.__username, ucr[ 'ldap/base' ] ) self.__command_list = moduleManager.permitted_commands( ucr[ 'hostname' ], self.acls ) self.signal_new( 'response' )
def migrate_to_dh_python(): ud.debug(ud.LISTENER, ud.WARN, 'Migrating all UDM extensions from python-support to dh-python') lo, po = udm_uldap.getMachineConnection() for dn, attrs in lo.search( '(|(objectClass=univentionUDMModule)(objectClass=univentionUDMSyntax)(objectClass=univentionUDMHook))' ): ocs = attrs.get('objectClass', []) if b'univentionUDMModule' in ocs: objectclass = 'univentionUDMModule' target_subdir = 'univention/admin/handlers' elif b'univentionUDMHook' in ocs: objectclass = 'univentionUDMHook' target_subdir = 'univention/admin/hooks.d' elif b'univentionUDMSyntax' in ocs: objectclass = 'univentionUDMSyntax' target_subdir = 'univention/admin/syntax.d' else: continue target_filename = attrs.get('%sFilename' % objectclass)[0] if os.path.exists( os.path.join(PYSHARED_DIR, target_subdir, target_filename)) or os.path.exists( os.path.join('/usr/lib/pymodules/python2.7', target_subdir, target_filename)): try: listener.setuid(0) handler(dn, attrs, []) # create files in new location listener.setuid(0) __remove_pymodules_links( objectclass, target_subdir, target_filename) # remove obsolete symlinks listener.setuid(0) __remove_pyshared_file( target_subdir, target_filename) # drop obsolete pyshared files ud.debug( ud.LISTENER, ud.INFO, 'Migrated %s/%s to dh-python.' % (target_subdir, target_filename)) except Exception: ud.debug( ud.LISTENER, ud.ERROR, 'ignoring fatal error %s' % (traceback.format_exc(), ))
def LDAP_Connection( func ): """This decorator function provides an open LDAP connection that can be accessed via the variable ldap_connection and a vaild position within the LDAP directory in the variable ldap_position. It reuses an already open connection or creates a new one. If the function fails with an LDAP error the decorators tries to reopen the LDAP connection and invokes the function again. if it still fails an LDAP_ConnectionError is raised. When using the decorator the method gets two additional keyword arguments. example: @LDAP_Connection def do_ldap_stuff( arg1, arg2, ldap_connection = None, ldap_positio = None ): ... ldap_connection.searchDn( ..., position = ldap_position ) ... """ def wrapper_func( *args, **kwargs ): global _ldap_connection, _ldap_position if _ldap_connection is not None: lo = _ldap_connection po = _ldap_position else: try: lo, po = udm_uldap.getMachineConnection( ldap_master = False ) except LDAPError, e: raise LDAP_ConnectionError( 'Opening LDAP connection failed: %s' % str( e ) ) kwargs[ 'ldap_connection' ] = lo kwargs[ 'ldap_position' ] = po try: ret = func( *args, **kwargs ) _ldap_connection = lo _ldap_position = po return ret except udm_errors.base, e: try: lo, po = udm_uldap.getMachineConnection( ldap_master = False ) except LDAPError, e: raise LDAP_ConnectionError( 'Opening LDAP connection failed: %s' % str( e ) )
def handler(dn, new, old): attrs = new if new else old listener.setuid(0) try: lo = getMachineConnection()[0] user_queue = SqliteQueue(logger=Log) # identify object if users_user_module.identify(dn, attrs): handle_user(dn, new, old, lo, user_queue) elif groups_group_module.identify(dn, attrs): handle_group(dn, new, old, lo, user_queue) elif shares_share_module.identify(dn, attrs): handle_share(dn, new, old, lo, user_queue) else: Log.error('handler: unknown object type: dn: %r\nold=%s\nnew=%s' % (dn, old, new)) pid = None try: if os.path.isfile(FN_PID): content = open(FN_PID, 'r').read().strip() try: pid = int(content) except ValueError: Log.error('%s does not contain a valid PID (%r)' % (FN_PID, content)) except (IOError, OSError) as exc: Log.error('failed to open and read %s: %s' % (FN_PID, exc)) if pid is not None: # inform daemon about pending changes os.kill(pid, signal.SIGUSR1) finally: listener.unsetuid()
def get_machine_connection(): global _machine_connection, _machine_position if not _machine_connection or not _machine_position: _machine_connection, _machine_position = uldap.getMachineConnection() return _machine_connection, _machine_position
def get_machine_connection(): return getMachineConnection()
def run(_umc_instance): # Now a workaround for paramico logging to connector-s4.log # because one of the diagnostic plugins instantiates s4connector.s4.s4() # which initializes univention.debug2, which initializes logging.basicConfig logger = paramiko.util.logging.getLogger() logger.setLevel(logging.CRITICAL) try: lo, position = uldap.getMachineConnection(ldap_master=False) except Exception as err: raise Warning(str(err)) modules.update() ucs_hosts = [] roles = [ 'computers/domaincontroller_backup', 'computers/domaincontroller_master', 'computers/domaincontroller_slave', 'computers/memberserver' ] for role in roles: udm_obj = modules.get(role) modules.init(lo, position, udm_obj) for host in udm_obj.lookup(None, lo, 'cn=*'): if 'docker' in host.oldattr.get('univentionObjectFlag', []): continue if not host.get('ip'): continue host.open() ucs_hosts.append(host['name']) with open('/etc/machine.secret', 'rb') as fd: password = fd.read().strip() gen_msg = _('The ssh connection to at least one other UCS server failed. ') gen_msg += _( 'The following list shows the affected remote servers and the reason for the failed ssh connection:' ) key_msg = _('Host key for server does not match') key_info = _( 'The ssh host key of the remote server has changed (maybe the host was reinstalled). ' ) key_info += _( 'Please repair the host key of the remote server in /root/.ssh/known_hosts on %(fqdn)s.' ) auth_msg = _('Machine authentication failed') auth_info = _( 'Login to the remote server with the uid %(uid)s and the password from /etc/machine.secret failed. ' ) auth_info += _( 'Please check /var/log/auth.log on the remote server for further information.' ) bad = dict() key_failed = False auth_failed = False data = dict(fqdn=ucr['hostname'] + '.' + ucr['domainname'], uid=ucr['hostname'] + '$', hostname=ucr['hostname']) for host in ucs_hosts: client = paramiko.SSHClient() client.load_system_host_keys() client.set_missing_host_key_policy(IgnorePolicy()) fqdn = host + '.' + ucr['domainname'] try: client.connect(fqdn, port=22, username=ucr['hostname'] + '$', password=password, timeout=2, banner_timeout=2, allow_agent=False) client.close() except paramiko.BadHostKeyException as err: bad[fqdn] = key_msg + '!' key_failed = True except paramiko.BadAuthenticationType as err: bad[fqdn] = auth_msg + '!' auth_failed = True except (paramiko.SSHException, socket.timeout) as err: # ignore if host is not reachable and other ssh errors pass except Exception as err: bad[fqdn] = str(err) if bad: msg = gen_msg msg += '\n\n' for host in bad: msg += '%s - %s\n' % (host, bad[host]) if key_failed: msg += '\n' + key_msg + ' - ' + key_info + '\n' if auth_failed: msg += '\n' + auth_msg + ' - ' + auth_info + '\n' msg += '\n' log_msg = msg.splitlines() for line in log_msg: if not re.match(r'^\s*$', line): MODULE.error("%s" % line) MODULE.error("%s" % data) raise Critical(msg % data)