def check_domain(self, username, password, ad_server_address, mode): ad_domain_info = {} try: if mode == 'admember': admember.check_server_role() ad_domain_info = admember.lookup_adds_dc(ad_server_address) ad_server_ip = ad_domain_info['DC IP'] if mode == 'admember': admember.check_domain(ad_domain_info) admember.check_connection(ad_domain_info, username, password) admember.check_ad_account(ad_domain_info, username, password) except admember.invalidUCSServerRole as exc: # check_server_role() MODULE.warn('Failure: %s' % exc) raise UMC_Error( _('The AD member mode can only be configured on a DC master server.' )) except admember.failedADConnect as exc: # lookup_adds_dc() MODULE.warn('Failure: %s' % exc) raise UMC_Error( _('Could not connect to AD Server %s. Please verify that the specified address is correct. (%s)' ) % (ad_server_address, 'check_domain: %s' % (exc, ))) except admember.domainnameMismatch as exc: # check_domain() MODULE.warn('Failure: %s' % exc) raise UMC_Error( _('The domain name of the AD Server (%(ad_domain)s) does not match the local UCS domain name (%(ucs_domain)s). For the AD member mode, it is necessary to setup a UCS system with the same domain name as the AD Server.' ) % { 'ad_domain': ad_domain_info.get("Domain"), 'ucs_domain': ucr['domainname'] }) except admember.connectionFailed as exc: # check_connection() MODULE.warn('Failure: %s' % exc) raise UMC_Error( _('Could not connect to AD Server %s. Please verify that username and password are correct. (Details:\n%s)' ) % (ad_domain_info.get('DC DNS Name'), exc)) except admember.notDomainAdminInAD as exc: # check_ad_account() MODULE.warn('Failure: %s' % exc) raise UMC_Error( _('The given user is not member of the Domain Admins group in Active Directory. This is a requirement for the Active Directory domain join.' )) # final info dict that is returned... replace spaces in the keys with '_' MODULE.info('Preparing info dict...') info = dict([(key.replace(' ', '_'), value) for key, value in ad_domain_info.iteritems()]) info['ssl_supported'] = admember.server_supports_ssl(ad_server_ip) # try to get binddn info['LDAP_BindDN'] = get_ad_binddn_from_name(info['LDAP_Base'], ad_server_ip, username, password) MODULE.info(str(info)) return info
def _enable_ssl_and_test_connection(self, certificate_fname=None): with ucr_rollback(ucr, ['connector/ad/ldap/ssl', 'connector/ad/ldap/certificate']): if certificate_fname: univention.config_registry.handler_set([u'connector/ad/ldap/certificate=%s' % certificate_fname]) server = ucr.get('connector/ad/ldap/host') if server: success = False if admember.server_supports_ssl(server): admember.enable_ssl() try: success = test_connection() except ADNotAvailable: success = False if not success: raise UMC_Error(_('Could not establish an encrypted connection. Either "%r" is not reachable or does not support encryption.') % server) else: MODULE.warn('connector is not configured yet, cannot test connection')
def adconnector_save(self, request): """Saves the Active Directory connection configuration options: Host_IP: IP address of the AD server LDAP_Host: hostname of the AD server LDAP_Base: LDAP base of the AD server LDAP_BindDN: LDAP DN to use for authentication KerberosDomain: kerberos domain PollSleep: time in seconds between polls RetryRejected: how many time to retry a synchronisation MappingSyncMode: synchronisation mode MappingGroupLanguage: language of the AD server return: { 'success' : (True|False), 'message' : <details> } """ for umckey, ucrkey, default in Instance.OPTION_MAPPING: val = request.options.get(umckey, default) if val: if isinstance(val, bool): val = 'yes' if val else 'no' MODULE.info('Setting %s=%s' % (ucrkey, val)) univention.config_registry.handler_set([u'%s=%s' % (ucrkey, val)]) ucr.load() if ucr.get('connector/ad/ldap/ldaps'): MODULE.info('Unsetting connector/ad/ldap/ldaps') univention.config_registry.handler_unset([u'connector/ad/ldap/ldaps']) if ucr.get('connector/ad/ldap/port') == '636': MODULE.info('Setting ldap port to 389') univention.config_registry.handler_set([u'connector/ad/ldap/port=389']) if not request.options.get('LDAP_Password') in (None, '', DO_NOT_CHANGE_PWD): fn = ucr.get('connector/ad/ldap/bindpw', FN_BINDPW) try: with open(fn, 'w') as fd: fd.write(request.options.get('LDAP_Password')) os.chmod(fn, 0o600) os.chown(fn, 0, 0) univention.config_registry.handler_set([u'connector/ad/ldap/bindpw=%s' % fn]) except Exception as e: MODULE.info('Saving bind password failed (filename=%(fn)s ; exception=%(exception)s)' % {'fn': fn, 'exception': str(e.__class__)}) self.finished(request.id, {'success': False, 'message': _('Saving bind password failed (filename=%(fn)s ; exception=%(exception)s)') % {'fn': fn, 'exception': str(e.__class__)}}) return ssldir = '/etc/univention/ssl/%s' % request.options.get('LDAP_Host') if not os.path.exists(ssldir): self._create_certificate(request) return # enter a static host entry such that the AD server's FQDN can be resolved univention.config_registry.handler_set([u'hosts/static/%(Host_IP)s=%(LDAP_Host)s' % request.options]) # check for SSL support on AD side if admember.server_supports_ssl(server=request.options.get('LDAP_Host')): MODULE.process('Enabling SSL...') admember.enable_ssl() else: MODULE.warn('SSL is not supported') admember.disable_ssl() # UCR variables are set, and now we can try to guess the language of # the AD domain ad_lang = guess_ad_domain_language() univention.config_registry.handler_set([u'connector/ad/mapping/group/language=%s' % ad_lang]) self.finished(request.id, {'success': True, 'message': _('Active Directory connection settings have been saved.')})
class Instance(Base, ProgressMixin): OPTION_MAPPING = ( ('LDAP_Host', 'connector/ad/ldap/host', ''), ('LDAP_Base', 'connector/ad/ldap/base', ''), ('LDAP_BindDN', 'connector/ad/ldap/binddn', ''), ('KerberosDomain', 'connector/ad/mapping/kerberosdomain', ''), ('PollSleep', 'connector/ad/poll/sleep', 5), ('RetryRejected', 'connector/ad/retryrejected', 10), ('DebugLevel', 'connector/debug/level', 2), ('DebugFunction', 'connector/debug/function', False), ('MappingSyncMode', 'connector/ad/mapping/syncmode', 'sync'), ('MappingGroupLanguage', 'connector/ad/mapping/group/language', 'de') ) def init(self): self.__update_status() def state(self, request): """Retrieve current status of the Active Directory connection configuration and the service options: {} return: { 'configured' : (True|False), 'certificate' : (True|False), 'running' : (True|False) } """ self.__update_status() self.finished(request.id, { 'ssl_enabled': self.status_ssl, 'password_sync_enabled': self.status_password_sync, 'running': self.status_running, 'certificate': self.status_certificate, 'mode_admember': self.status_mode_admember, 'mode_adconnector': self.status_mode_adconnector, 'configured': self.status_mode_adconnector or self.status_mode_admember, 'server_role': ucr.get('server/role'), }) def load(self, request): """Retrieve current status of the Active Directory connection configuration and the service options: {} return: { <all AD connector UCR variables> } """ result = {} for option, var, default in Instance.OPTION_MAPPING: result[option] = ucr.get(var, default) pwd_file = ucr.get('connector/ad/ldap/bindpw') result['passwordExists'] = bool(pwd_file and os.path.exists(pwd_file)) self.finished(request.id, result) @sanitize(LDAP_Host=StringSanitizer(required=True)) def adconnector_save(self, request): """Saves the Active Directory connection configuration options: Host_IP: IP address of the AD server LDAP_Host: hostname of the AD server LDAP_Base: LDAP base of the AD server LDAP_BindDN: LDAP DN to use for authentication KerberosDomain: kerberos domain PollSleep: time in seconds between polls RetryRejected: how many time to retry a synchronisation MappingSyncMode: synchronisation mode MappingGroupLanguage: language of the AD server return: { 'success' : (True|False), 'message' : <details> } """ self.required_options(request, 'Host_IP') self.required_options(request, *[x[0] for x in Instance.OPTION_MAPPING if x[2] == '']) for umckey, ucrkey, default in Instance.OPTION_MAPPING: val = request.options.get(umckey, default) if val: if isinstance(val, bool): val = val and 'yes' or 'no' MODULE.info('Setting %s=%s' % (ucrkey, val)) univention.config_registry.handler_set([u'%s=%s' % (ucrkey, val)]) ucr.load() if ucr.get('connector/ad/ldap/ldaps'): MODULE.info('Unsetting connector/ad/ldap/ldaps') univention.config_registry.handler_unset([u'connector/ad/ldap/ldaps']) if ucr.get('connector/ad/ldap/port') == '636': MODULE.info('Setting ldap port to 389') univention.config_registry.handler_set([u'connector/ad/ldap/port=389']) if not request.options.get('LDAP_Password') in (None, '', DO_NOT_CHANGE_PWD): fn = ucr.get('connector/ad/ldap/bindpw', FN_BINDPW) try: fd = open(fn, 'w') fd.write(request.options.get('LDAP_Password')) fd.close() os.chmod(fn, 0600) os.chown(fn, 0, 0) univention.config_registry.handler_set([u'connector/ad/ldap/bindpw=%s' % fn]) except Exception, e: MODULE.info('Saving bind password failed (filename=%(fn)s ; exception=%(exception)s)' % {'fn': fn, 'exception': str(e.__class__)}) self.finished(request.id, {'success': False, 'message': _('Saving bind password failed (filename=%(fn)s ; exception=%(exception)s)') % {'fn': fn, 'exception': str(e.__class__)}}) return ssldir = '/etc/univention/ssl/%s' % request.options.get('LDAP_Host') if not os.path.exists(ssldir): self._create_certificate(request) return # enter a static host entry such that the AD server's FQDN can be resolved univention.config_registry.handler_set([u'hosts/static/%(Host_IP)s=%(LDAP_Host)s' % request.options]) # check for SSL support on AD side if admember.server_supports_ssl(server=request.options.get('LDAP_Host')): MODULE.process('Enabling SSL...') admember.enable_ssl() else: MODULE.warn('SSL is not supported') admember.disable_ssl() # UCR variables are set, and now we can try to guess the language of # the AD domain ad_lang = guess_ad_domain_language() univention.config_registry.handler_set([u'connector/ad/mapping/group/language=%s' % ad_lang]) self.finished(request.id, {'success': True, 'message': _('Active Directory connection settings have been saved.')})