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
Example #2
0
	def admember_join(self, username, password, ad_server_address, progress):
		progress.title = _('Joining UCS into Active Directory domain')
		progress.total = 100.0
		progress.warnings = []
		overall_success = False
		MODULE.process(progress.title)

		def _progress(steps, msg):
			progress.current = float(steps)
			progress.message = msg
			MODULE.process(msg)
			time.sleep(0.2)

		def _err(exc=None, msg=None):

			exc_str = ''
			if exc is not None:
				exc_str = str(exc) or exc.__doc__  # if no message, take the doc string
				exc_class_name = exc.__class__.__name__
				MODULE.error('Join process failed [%s]: %s' % (exc_class_name, exc_str))

			if msg:
				MODULE.error(msg)
			else:
				msg = _('An unexpected error occurred: %s') % exc_str

			progress.finish_with_result({
				'success': False,
				'error': msg,
				'warnings': progress.warnings,
			})

		ad_domain_info = {}
		try:
			admember.check_server_role()
			ad_domain_info = admember.lookup_adds_dc(ad_server_address)
			ad_server_ip = ad_domain_info['DC IP']

			_progress(5, _('Configuring time synchronization...'))
			admember.time_sync(ad_server_ip)
			admember.set_timeserver(ad_server_ip)

			_progress(10, _('Configuring DNS server...'))
			admember.set_nameserver([ad_server_ip])
			admember.prepare_ucr_settings()

			_progress(15, _('Configuring Kerberos settings...'))
			admember.disable_local_heimdal()
			admember.disable_local_samba4()

			_progress(20, _('Configuring reverse DNS settings...'))
			admember.prepare_dns_reverse_settings(ad_domain_info)

			_progress(25, _('Configuring software components...'))

			_step_offset = 30.0
			_nsteps = 35.0

			def _step_handler(step):
				MODULE.process('Package manager progress: %.1f' % step)
				progress.current = (step / 100.0) * _nsteps + _step_offset

			def _err_handler(err):
				MODULE.warn(err)
				progress.warnings.append(err)

			success = admember.remove_install_univention_samba(info_handler=MODULE.process, error_handler=_err_handler, step_handler=_step_handler)
			if not success:
				raise RuntimeError(_('An error occurred while installing necessary software components.'))

			_progress(65, _('Configuring synchronization from AD...'))
			admember.prepare_connector_settings(username, password, ad_domain_info)
			admember.disable_ssl()

			_progress(70, _('Renaming well known SID objects...'))
			admember.rename_well_known_sid_objects(username, password)

			_progress(75, _('Configuring Administrator account...'))
			admember.prepare_administrator(username, password)

			_progress(80, _('Running Samba join script...'))
			admember.run_samba_join_script(username, password)

			_progress(85, _('Configuring DNS entries...'))
			admember.add_domaincontroller_srv_record_in_ad(ad_server_ip, username, password)
			admember.add_host_record_in_ad(uid=username, bindpw=password, sso=True)

			admember.make_deleted_objects_readable_for_this_machine(username, password)
			admember.synchronize_account_position(ad_domain_info, username, password)

			_progress(90, _('Starting Active Directory connection service...'))
			admember.start_service('univention-ad-connector')

			_progress(95, _('Registering LDAP service entry...'))
			admember.add_admember_service_to_localhost()

			overall_success = True
			_progress(100, _('Join has been finished successfully.'))

		# error handling...
		except admember.invalidUCSServerRole as exc:
			_err(exc, _('The AD member mode can only be configured on a DC master server.'))
		except admember.failedADConnect as exc:
			_err(exc, _('Could not connect to AD Server %s. Please verify that the specified address is correct. (%s)') % (ad_domain_info.get('DC DNS Name'), 'admember_join: %s' % (exc,)))
		except admember.domainnameMismatch as exc:
			_err(exc, _('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["Domain"], 'ucs_domain': ucr['domainname']})
		except admember.connectionFailed as exc:
			_err(exc, _('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.failedToSetAdministratorPassword as exc:
			_err(exc, _('Failed to set the password of the UCS Administrator to the Active Directory Administrator password.'))
		except admember.failedToCreateAdministratorAccount as exc:
			_err(exc, _('Failed to create the Administrator account in UCS.'))
		except admember.sambaSidNotSetForAdministratorAccount as exc:
			_err(exc, _('The sambaSID could not set for the Administrator account in UCS.'))
		except admember.failedToSearchForWellKnownSid as exc:
			_err(exc, _('Failed to search for the well known SID.'))
		except admember.failedToAddAdministratorAccountToDomainAdmins as exc:
			_err(exc, _('Failed to add the Administrator account to the Domain Admins group.'))
		except admember.timeSyncronizationFailed as exc:
			_err(exc, _('Could not synchronize the time between the UCS system and the Active Directory domain controller: %s') % exc)
		except RuntimeError as exc:
			_err(exc)
		except Exception as exc:
			# catch all other errors that are unlikely to occur
			_err(exc)
			MODULE.error('Traceback:\n%s' % traceback.format_exc())

		if not overall_success:
			_progress(100, _('Join has been finished with errors.'))
			admember.revert_ucr_settings()
			admember.revert_connector_settings()

		if hasattr(progress, 'result'):
			# some error probably occurred -> return the result in the progress
			return progress.result

		return {'success': success}