Beispiel #1
0
	def load( self, request ):
		"""Retrieve current status of the UCS Active Directory Connector 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 )
Beispiel #2
0
 def write(self, user_dn, passwd):
     ldap_con = ldap.open("localhost", port=int(ucr.get("ldap/server/port", 7389)))
     ldap_con.simple_bind_s(user_dn, passwd)
     try:
         ldap_con.add_s(self.dn, self.addlist)
     except ldap.ALREADY_EXISTS:
         ldap_con.delete_s(self.dn)
         ldap_con.add_s(self.dn, self.addlist)
     ldap_con.unbind_s()
Beispiel #3
0
	def types( self, request, ldap_connection = None, ldap_position = None ):
		"""Returns the list of object types matching the given flavor or container.

		requests.options = {}
		  'superordinate' -- if available only types for the given superordinate are returned (not for the navigation)
		  'container' -- if available only types suitable for the given container are returned (only for the navigation)

		return: [ { 'id' : <LDAP DN of container or None>, 'label' : <name> }, ... ]
		"""
		if request.flavor != 'navigation':
			module = UDM_Module( request.flavor )
			superordinate = request.options.get( 'superordinate' )
			if superordinate:
				self.finished( request.id, module.types4superordinate( request.flavor, superordinate ) )
			else:
				self.finished( request.id, module.child_modules )
		else:
			container = request.options.get( 'container' )
			if not container:
				# no container is specified, return all existing object types
				MODULE.info('no container specified, returning all object types')
				self.finished( request.id, map( lambda module: { 'id' : module[ 0 ], 'label' : getattr( module[ 1 ], 'short_description', module[ 0 ] ) }, udm_modules.modules.items() ) )
				return

			if 'None' == container:
				# if 'None' is given, use the LDAP base
				container = ucr.get( 'ldap/base' )
				MODULE.info('no container == \'None\', set LDAP base as container')

			# create a list of modules that can be created
			# ... all container types except container/dc
			allowed_modules = set([m for m in udm_modules.containers if udm_modules.name(m) != 'container/dc'])

			# the container may be a superordinate or have one as its parent
			# (or grandparent, ....)
			superordinate = udm_modules.find_superordinate(container, None, ldap_connection)
			if superordinate:
				# there is a superordinate... add its subtypes to the list of allowed modules
				MODULE.info('container has a superordinate: %s' % superordinate)
				allowed_modules.update(udm_modules.subordinates(superordinate))
			else:
				# add all types that do not have a superordinate
				MODULE.info('container has no superordinate')
				allowed_modules.update(filter(lambda mod: not udm_modules.superordinate(mod), udm_modules.modules.values()))

			# make sure that the object type can be created
			allowed_modules = filter(lambda mod: udm_modules.supports(mod, 'add'), allowed_modules)
			MODULE.info('all modules that are allowed: %s' % [udm_modules.name(mod) for mod in allowed_modules])

			# return the final list of object types
			self.finished( request.id, map( lambda module: { 'id' : udm_modules.name(module), 'label' : getattr( module, 'short_description', udm_modules.name(module) ) }, allowed_modules ) )
Beispiel #4
0
	def connect(self, request):
		url = None
		(is_running, passwd_exists, ) = self._get_status()
		port = None
		host = None
		if is_running:
			args = self._get_cmdline()
			if '-rfbport' in args:
				port = args[args.index('-rfbport') + 1]

			fqdn = '%s.%s' % ( ucr.get( 'hostname' ), ucr.get( 'domainname' ) )
			VNC_LINK_BY_NAME, VNC_LINK_BY_IPV4, VNC_LINK_BY_IPV6 = range(3)
			vnc_link_format = VNC_LINK_BY_IPV4
			if vnc_link_format == VNC_LINK_BY_IPV4:
				addrs = socket.getaddrinfo( fqdn, port, socket.AF_INET )
				(family, socktype, proto, canonname, sockaddr) = addrs[0]
				host = sockaddr[0]
			elif vnc_link_format == VNC_LINK_BY_IPV6:
				addrs = socket.getaddrinfo( fqdn, port, socket.AF_INET6 )
				(family, socktype, proto, canonname, sockaddr) = addrs[0]
				host = '[%s]' % sockaddr[0]

		self.finished( request.id, { 'port': port, 'host' : host } )
Beispiel #5
0
	def templates( self, request ):
		"""Returns the list of template objects for the given object
		type.

		requests.options = {}
		  'objectType' -- The UDM module name

		return: [ { 'id' : <LDAP DN of container or None>, 'label' : <name> }, ... ]
		"""
		module = self._get_module_by_request( request )

		result = []
		if module.template:
			template = UDM_Module( module.template )
			objects = template.search( ucr.get( 'ldap/base' ) )
			for obj in objects:
				obj.open()
				result.append( { 'id' : obj.dn, 'label' : obj[ template.identifies ] } )

		self.finished( request.id, result )
Beispiel #6
0
	def nav_container_query( self, request ):
		"""Returns a list of LDAP containers located under the given
		LDAP base (option 'container'). If no base container is
		specified the LDAP base object is returned."""

		if not request.options.get( 'container' ):
			ldap_base = ucr.get( 'ldap/base' )
			self.finished( request.id, [ { 'id' : ldap_base, 'label' : ldap_dn2path( ldap_base ), 'icon' : 'udm-container-dc', 'objectType' : 'container/dc' } ] )
			return

		def _thread( container ):
			success = True
			message = None
			superordinate = None
			result = []
			for base, typ in map( lambda x: x.split( '/' ), self.modules_with_childs ):
				module = UDM_Module( '%s/%s' % ( base, typ ) )
				if module.superordinate:
					if superordinate is None:
						try:
							so_module = UDM_Module( module.superordinate )
							so_obj = so_module.get( request.options.get( 'container' ) )
							superordinate = so_obj
						except UDM_Error: # superordinate object could not be load -> ignore module
							continue
					else:
						so_obj = superordinate
				else:
					so_obj = None
				try:
					for item in module.search( container, scope = 'one', superordinate = so_obj ):
						result.append( { 'id' : item.dn, 'label' : item[ module.identifies ], 'icon' : 'udm-%s-%s' % ( base, typ ), 'path': ldap_dn2path( item.dn ), 'objectType': '%s/%s' % (base, typ) } )
				except UDM_Error, e:
					success = False
					result = None
					message = str( e )

			return result, message, success
	def query(self, pattern):
		ucr.load()
		srvs = ServiceInfo()

		lang = _.im_self.locale.language
		if lang in (None, 'C'):
			lang = 'en'

		result = []
		for name, srv in srvs.services.items():
			key = srv.get('start_type', '%s/autostart' % (name,))
			entry = {
				'service': name,
				'description': srv.get('description[%s]' % (lang,), srv.get('description')),
				'autostart': ucr.get(key, 'yes'),
				'isRunning': srv.running,
			}
			if entry['autostart'] not in ('yes', 'no', 'manually'):
				entry['autostart'] = 'yes'
			for value in entry.values():
				if pattern.match(str(value)):
					result.append(entry)
					break
		return result
def test_identity_provider_certificate():
    # download from all ip addresses of ucs-sso. the IDP certificate (/etc/simplesamlphp/*-idp-certificate.crt)
    # compare this with /usr/share/univention-management-console/saml/idp/*.xml
    # If it fails: univention-run-joinscripts --force --run-scripts 92univention-management-console-web-server

    sso_fqdn = ucr.get('ucs/server/sso/fqdn')
    MODULE.process(
        "Checks ucs-sso by comparing 'ucr get ucs/server/sso/fqdn' with the Location field in /usr/share/univention-management-console/saml/idp/*.xml"
    )
    if not sso_fqdn:
        return
    for host in socket.gethostbyname_ex(sso_fqdn)[2]:
        try:
            with download_tempfile(
                    'https://%s/simplesamlphp/saml2/idp/certificate' %
                (host, ), {'host': sso_fqdn}) as certificate:
                certificate = certificate.read()
                for idp in glob.glob(
                        '/usr/share/univention-management-console/saml/idp/*.xml'
                ):
                    with open(idp) as fd:
                        cert = find_node(
                            fromstring(fd.read()),
                            '{http://www.w3.org/2000/09/xmldsig#}X509Certificate'
                        )
                        if cert.text.strip() not in certificate:
                            MODULE.error(
                                'The certificate of the SAML identity provider does not match.'
                            )
                            raise Critical(
                                _('The certificate of the SAML identity provider does not match.'
                                  ))

        except requests.exceptions.ConnectionError:
            print 'error, connecting'
            pass
def run(_umc_instance):
    if ucr.get('server/role') != 'domaincontroller_master':
        return

    lo, pos = getAdminConnection()
    objects = udm_objects_without_type(lo)
    if len(objects):
        counted_objects = {}
        details = '\n\n' + _('These objects were found:')
        for dn, modules, object_classes in objects:
            for module in modules:
                counted_objects.setdefault(module.short_description, 0)
                counted_objects[module.short_description] += 1
        for module_name in sorted(counted_objects.iterkeys()):
            num_objs = counted_objects[module_name]
            details += '\n· ' + _('%d objects should be "%s"') % (num_objs,
                                                                  module_name)
        raise Warning(description + details,
                      buttons=[{
                          'action':
                          'migrate_objects',
                          'label':
                          _('Migrate %d LDAP objects') % len(objects),
                      }])
def run(_umc_instance):
    if ucr.get('server/role') != 'domaincontroller_master':
        return

    lo, pos = getAdminConnection()
    objs = udm_objects_without_ServerRole(lo)
    details = '\n\n' + _('These objects were found:')

    total_objs = 0
    fixable_objs = 0
    for server_role in sorted(objs):
        num_objs = len(objs[server_role])
        if num_objs:
            total_objs += num_objs
            if server_role:
                fixable_objs += num_objs
                details += '\n· ' + _(
                    'Number of objects that should be marked as "%s": %d') % (
                        server_role,
                        num_objs,
                    )
            else:
                details += '\n· ' + _(
                    'Number of unspecific Windows computer objects with inconsistent univentionObjectType: %d (Can\'t fix this automatically)'
                ) % (num_objs, )
    if total_objs:
        if fixable_objs:
            raise Warning(description + details,
                          buttons=[{
                              'action':
                              'migrate_objects',
                              'label':
                              _('Migrate %d LDAP objects') % fixable_objs,
                          }])
        else:
            raise Warning(description + details, buttons=[])
Beispiel #11
0
    def set_user_attributes(self, username, password, attributes):
        dn, username = self.auth(username, password)
        if self.is_blacklisted(username):
            raise ServiceForbidden()

        user_attributes = [
            attr.strip()
            for attr in ucr.get('self-service/udm_attributes', '').split(',')
        ]
        lo, po = get_user_connection(binddn=dn, bindpw=password)
        user = self.usersmod.object(None, lo, po, dn)
        user.open()
        for propname, value in attributes.items():
            if propname in user_attributes and user.has_property(propname):
                user[propname] = value
        try:
            user.modify()
        except univention.admin.uexceptions.base as exc:
            MODULE.error(
                'set_user_attributes(): modifying the user failed: %s' %
                (traceback.format_exc(), ))
            raise UMC_Error(
                _('The attributes could not be saved: %s') % (UDM_Error(exc)))
        return _("Successfully changed your profile data.")
Beispiel #12
0
		def ucr_try_int(variable, default):
			try:
				return int(ucr.get(variable, default))
			except ValueError:
				MODULE.error('UCR variables %s is not a number, using default: %s' % (variable, default))
				return default
Beispiel #13
0
	def _update_required_attr_of_props_for_registration(self, properties):
		for k in properties.keys():
			if isinstance(properties[k], dict):
				properties[k]['required'] = False
			else:
				properties[k].required = False
		required_ids = set(['PasswordRecoveryEmail', 'password'] + [attr.strip() for attr in ucr.get('umc/self-service/account-registration/udm_attributes/required', '').split(',') if attr.strip()])
		for id_ in required_ids:
			if id_ in properties:
				if isinstance(properties[id_], dict):
					properties[id_]['required'] = True
				else:
					properties[id_].required = True
Beispiel #14
0
	def check_dcmaster_srv_rec(self):
		result = bool(admember.get_domaincontroller_srv_record(ucr.get('domainname')))
		return {'success': result}
Beispiel #15
0
		def _finished( thread, result, request ):
			if self._check_thread_error( thread, result, request ):
				return

			success, data = result
			if not success:
				self.finished( request.id, None, message = str( data ), status = MODULE_ERR_COMMAND_FAILED )
				return

			node_uri = urlparse.urlsplit( request.options[ 'domainURI' ] )
			uri, uuid = urlparse.urldefrag( request.options[ 'domainURI' ] )
			json = object2dict( data )

			## re-arrange a few attributes for the frontend
			# annotations
			for key in json[ 'annotations' ]:
				if key == 'uuid':
					continue
				json[ key ] = json[ 'annotations' ][ key ]

			# type
			json[ 'type' ] = '%(domain_type)s-%(os_type)s' % json

			# STOP here if domain is not available
			if not json[ 'available' ]:
				MODULE.info( 'Domain is not available: %s' % str( json ) )
				self.finished( request.id, json )
				return

			# RAM
			json[ 'maxMem' ] = MemorySize.num2str( json[ 'maxMem' ] )

			# interfaces (fake the special type network:<source>)
			for iface in json[ 'interfaces' ]:
				if iface[ 'type' ] == Interface.TYPE_NETWORK:
					iface[ 'type' ] = 'network:' + iface[ 'source' ]

			# disks
			for disk in json[ 'disks' ]:
				if disk[ 'type' ] == Disk.TYPE_FILE:
					disk[ 'volumeFilename' ] = os.path.basename( disk[ 'source' ] )
					disk[ 'pool' ] = self.get_pool_name( uri, os.path.dirname( disk[ 'source' ] ) )
				else:
					disk[ 'volumeFilename' ] = disk[ 'source' ]
					disk[ 'pool' ] = None
				disk[ 'paravirtual' ] = disk[ 'target_bus' ] in ( 'virtio', 'xen' )
				disk[ 'volumeType' ] = disk[ 'type' ]
				if isinstance( disk[ 'size' ], ( int, long ) ):
					disk[ 'size' ] = MemorySize.num2str( disk[ 'size' ] )

			# graphics
			if json['graphics']:
				try:
					gfx = json[ 'graphics' ][ 0 ]
					json[ 'vnc' ] = True
					json[ 'vnc_host' ] = None
					json[ 'vnc_port' ] = None
					json[ 'kblayout' ] = gfx[ 'keymap' ]
					json[ 'vnc_remote' ] = gfx[ 'listen' ] == '0.0.0.0'
					json[ 'vnc_password' ] = gfx[ 'passwd' ]
					# vnc_password will not be send to frontend
					port = int( json[ 'graphics' ][ 0 ][ 'port' ] )
					if port == -1:
						raise ValueError()
					host = node_uri.netloc
					vnc_link_format = ucr.get('uvmm/umc/vnc/host', 'IPv4') or ''
					match = Domains.RE_VNC.match(vnc_link_format)
					if match:
						family, pattern, substs = match.groups()
						if family:  # IPvX
							family = Domains.SOCKET_FAMILIES[family]
							regex = re.compile(pattern or '.*')
							addrs = socket.getaddrinfo(host, port, family, socket.SOCK_STREAM, socket.SOL_TCP)
							for (family, _socktype, _proto, _canonname, sockaddr) in addrs:
								host, port = sockaddr[:2]
								if regex.search(host):
									break
							else:
								raise LookupError(pattern)
							host = Domains.SOCKET_FORMATS[family] % (host,)
						elif substs:  # NAME
							for subst in substs.split():
								old, new = subst.split('=', 1)
								host = host.replace(old, new)
					elif vnc_link_format:  # overwrite all hosts with fixed host
						host = vnc_link_format
					json[ 'vnc_host' ] = host
					json[ 'vnc_port' ] = port
				except re.error, ex: # port is not valid
					MODULE.warn('Invalid VNC regex: %s' % (ex,))
				except socket.gaierror, ex:
					MODULE.warn('Invalid VNC host: %s' % (ex,))
Beispiel #16
0
	def __update_status( self ):
		ucr.load()
		self.status_configured = bool( ucr.get( 'connector/ad/ldap/host' ) and ucr.get( 'connector/ad/ldap/base' ) and ucr.get( 'connector/ad/ldap/binddn' ) and ucr.get( 'connector/ad/ldap/bindpw' ) )
		fn = ucr.get( 'connector/ad/ldap/certificate' )
		self.status_certificate = bool( fn and os.path.exists( fn ) )
		self.status_running = self.__is_process_running( '*python*univention/connector/ad/main.py*' )
def run(_umc_instance,
        url='http://www.univention.de/',
        connecttimeout=30,
        timeout=30):
    ucr.load()

    proxy = ucr.get('proxy/http')
    if not proxy:
        return

    proxy = urlparse(proxy)
    MODULE.info('The proxy is configured, using host=%r, port=%r' %
                (proxy.hostname, proxy.port))
    curl = pycurl.Curl()
    curl.setopt(pycurl.PROXYTYPE, pycurl.PROXYTYPE_HTTP)
    if proxy.hostname:
        curl.setopt(pycurl.PROXY, proxy.hostname)
    if proxy.port:
        curl.setopt(pycurl.PROXYPORT, proxy.port)
    curl.setopt(pycurl.FOLLOWLOCATION, True)
    curl.setopt(pycurl.MAXREDIRS, 5)
    curl.setopt(pycurl.CONNECTTIMEOUT, connecttimeout)
    curl.setopt(pycurl.TIMEOUT, 30)
    if proxy.username:
        curl.setopt(pycurl.PROXYAUTH, pycurl.HTTPAUTH_ANY)
        credentials = '%s' % (proxy.username, )
        if proxy.password:
            credentials = '%s:%s' % (proxy.username, proxy.password)
        curl.setopt(pycurl.PROXYUSERPWD, credentials)

    curl.setopt(pycurl.URL, url)
    # curl.setopt(pycurl.VERBOSE, bVerbose)

    buf = StringIO.StringIO()
    curl.setopt(pycurl.WRITEFUNCTION, buf.write)
    try:
        curl.perform()
    except pycurl.error as exc:
        try:
            code, msg = exc.args
            msg = '%s (code=%s)' % (msg, code)
            MODULE.info(msg)
        except ValueError:
            MODULE.error(traceback.format_exc())
            code = 0
            msg = str(exc)
        if code == pycurl.E_COULDNT_CONNECT:
            msg = _(
                'The proxy host could not be reached. Make sure that hostname (%(hostname)r) and port (%(port)r) are correctly set up.'
            ) % {
                'hostname': proxy.hostname,
                'port': proxy.port
            }
        elif code == pycurl.E_COULDNT_RESOLVE_PROXY:
            msg = _(
                'The hostname of the proxy could not be resolved. May check your DNS configuration.'
            )
        elif code == pycurl.E_OPERATION_TIMEOUTED:
            msg = _(
                'The server did not respond within %d seconds. Please check your network configuration.'
            ) % (timeout, )
        elif code == 0:
            MODULE.error(traceback.format_exc())

        raise Critical('\n'.join([description, msg]))
    else:
        # page = buf.getvalue()
        # MODULE.info(page[:100])
        buf.close()
        http_status = curl.getinfo(pycurl.HTTP_CODE)
        if http_status >= 400:
            raise Warning('\n'.join([
                description,
                _('The proxy server is reachable but the HTTP response status code (%d) does not indicate success.'
                  ) % (http_status, ),
                _('This warning might be harmless. Nevertheless make sure the authentication credentials (if any) are correct and the proxy server ACLs do not forbid requests to %s.'
                  ) % (url, )
            ]))
    finally:
        curl.close()
	def _check_dcmaster_srv_rec(self):
		if admember.get_domaincontroller_srv_record(ucr.get('domainname')):
			return True
		else:
			return False
Beispiel #19
0
 def init(self):
     self._hostname = ucr.get('hostname')
Beispiel #20
0
	def get_metainfo(self):
		"""Queries the specified DC Master for metainformation about the UCS@school environment"""
		master = ucr.get('ldap/master') or get_master_dns_lookup()
		if not master:
			return
		return self._umc_master(self.username, self.password, master, 'schoolinstaller/get/metainfo/master')
Beispiel #21
0
def system_join(username, password, info_handler, error_handler, step_handler):
	# make sure we got the correct server role
	server_role = ucr.get('server/role')
	assert server_role in ('domaincontroller_slave', 'domaincontroller_backup', 'domaincontroller_master')

	# get the number of join scripts
	n_joinscripts = len(glob.glob('/usr/lib/univention-install/*.inst'))
	steps_per_script = 100.0 / n_joinscripts

	# disable UMC/apache restart
	MODULE.info('disabling UMC and apache server restart')
	subprocess.call(CMD_DISABLE_EXEC)

	try:
		with tempfile.NamedTemporaryFile() as password_file:
			password_file.write('%s' % password)
			password_file.flush()

			# regular expressions for output parsing
			error_pattern = re.compile('^\* Message:\s*(?P<message>.*)\s*$')
			joinscript_pattern = re.compile('(Configure|Running)\s+(?P<script>.*)\.inst.*$')
			info_pattern = re.compile('^(?P<message>.*?)\s*:?\s*\x1b.*$')

			# call to univention-join
			process = None
			if server_role == 'domaincontroller_slave':
				# DC slave -> complete re-join
				MODULE.process('Performing system join...')
				process = subprocess.Popen(['/usr/sbin/univention-join', '-dcaccount', username, '-dcpwd', password_file.name], shell=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE, close_fds=True)
			else:
				# DC backup/master -> only run join scripts
				MODULE.process('Executing join scripts ...')
				process = subprocess.Popen(['/usr/sbin/univention-run-join-scripts', '-dcaccount', username, '-dcpwd', password_file.name], shell=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE, close_fds=True)

			failed_join_scripts = []
			executed_join_scripts = set()

			def parse(line):
				if not line.strip():
					return
				MODULE.process(repr(line.strip()).strip('"\''))

				# parse output... first check for errors
				m = error_pattern.match(line)
				if m:
					error_handler(_('Software packages have been installed, however, the system join could not be completed: %s. More details can be found in the log file /var/log/univention/join.log. Please retry the join process via the UMC module "Domain join" after resolving any conflicting issues.') % m.groupdict().get('message'))
					return

				# check for currently called join script
				m = joinscript_pattern.match(line)
				if m:
					current_script = m.groupdict().get('script')
					info_handler(_('Executing join script %s') % (current_script,))
					if current_script not in executed_join_scripts:
						executed_join_scripts.add(current_script)
						step_handler(steps_per_script)
					if 'failed' in line:
						failed_join_scripts.append(current_script)
					return

				# check for other information
				m = info_pattern.match(line)
				if m:
					info_handler(m.groupdict().get('message'))
					return

			# make stdout file descriptor of the process non-blocking
			fd = process.stdout.fileno()
			fl = fcntl.fcntl(fd, fcntl.F_GETFL)
			fcntl.fcntl(fd, fcntl.F_SETFL, fl | os.O_NONBLOCK)

			unfinished_line = ''
			while True:
				try:
					fd = select.select([process.stdout], [], [])[0][0]
				except IndexError:
					continue  # not ready / no further data
				except select.error as exc:
					if exc.args[0] == errno.EINTR:
						continue
					raise
				# get the next line
				line = fd.read()

				if not line:
					break  # no more text from stdout

				unfinished_line = '' if line.endswith('\n') else '%s%s' % (unfinished_line, line.rsplit('\n', 1)[-1])
				for line in line.splitlines():
					parse(line)
				if unfinished_line:
					parse(unfinished_line)

			# get all remaining output
			stdout, stderr = process.communicate()
			if stderr:
				# write stderr into the log file
				MODULE.warn('stderr from univention-join: %s' % stderr)

			# check for errors
			if process.returncode != 0:
				# error case
				MODULE.warn('Could not perform system join: %s%s' % (stdout, stderr))
				error_handler(_('Software packages have been installed successfully, however, the join process could not be executed. More details can be found in the log file /var/log/univention/join.log. Please retry to join the system via the UMC module "Domain join" after resolving any conflicting issues.'))
			elif failed_join_scripts:
				MODULE.warn('The following join scripts could not be executed: %s' % failed_join_scripts)
				error_handler(_('Software packages have been installed successfully, however, some join scripts could not be executed. More details can be found in the log file /var/log/univention/join.log. Please retry to execute the join scripts via the UMC module "Domain join" after resolving any conflicting issues.'))
	finally:
		# make sure that UMC servers and apache can be restarted again
		MODULE.info('enabling UMC and apache server restart')
		subprocess.call(CMD_ENABLE_EXEC)
Beispiel #22
0
	def create_self_registered_account(self, attributes):
		MODULE.info('create_self_registered_account(): attributes: {}'.format(attributes))
		ucr.load()
		if ucr.is_false('umc/self-service/account-registration/backend/enabled', True):
			msg = _('The account registration was disabled via the Univention Configuration Registry.')
			MODULE.error('create_self_registered_account(): {}'.format(msg))
			raise UMC_Error(msg)
		# filter out attributes that are not valid to set
		allowed_to_set = set(['PasswordRecoveryEmail', 'password'] + [attr.strip() for attr in ucr.get('umc/self-service/account-registration/udm_attributes', '').split(',') if attr.strip()])
		attributes = {k: v for (k, v) in attributes.items() if k in allowed_to_set}
		# validate attributes
		res = self._validate_user_attributes(attributes, self._update_required_attr_of_props_for_registration)
		# check username taken
		if 'username' in attributes:
			try:
				UDM.machine().version(2).get('users/user').get_by_id(attributes['username'])
			except NoObject:
				pass
			else:
				res['username'] = {
					'isValid': False,
					'message': _('The username is already taken'),
				}
		invalid = {k: v for (k, v) in res.items() if not (all(v['isValid']) if isinstance(v['isValid'], list) else v['isValid'])}
		if len(invalid):
			return {
				'success': False,
				'failType': 'INVALID_ATTRIBUTES',
				'data': invalid,
			}

		# check for missing required attributes from umc/self-service/account-registration/udm_attributes/required
		required_attrs = [attr.strip() for attr in ucr.get('umc/self-service/account-registration/udm_attributes/required', '').split(',') if attr.strip()]
		not_found = [attr for attr in required_attrs if attr not in attributes]
		if not_found:
			msg = _('The account could not be created:\nInformation provided is not sufficient. The following properties are missing:\n%s') % ('\n'.join(not_found),)
			MODULE.error('create_self_registered_account(): {}'.format(msg))
			raise UMC_Error(msg)

		univention.admin.modules.update()
		lo, po = get_admin_connection()

		# get usertemplate
		template_dn = ucr.get('umc/self-service/account-registration/usertemplate', '')
		usertemplate = None
		if template_dn:
			usertemplate_mod = univention.admin.modules.get('settings/usertemplate')
			univention.admin.modules.init(lo, po, usertemplate_mod, None, True)
			try:
				usertemplate = usertemplate_mod.object(None, lo, None, template_dn)
			except udm_errors.noObject:
				msg = _('The user template "{}" set by the "umc/self-service/account-registration/usertemplate" UCR variable does not exist. A user account can not be created. Please contact your system administrator.'.format(template_dn))
				MODULE.error('create_self_registered_account(): {}'.format(msg))
				raise UMC_Error(msg)

		# init user module with template
		usersmod = univention.admin.modules.get('users/user')
		univention.admin.modules.init(lo, po, usersmod, usertemplate, True)

		# get user container
		udm = UDM.machine().version(2)
		user_position = univention.admin.uldap.position(po.getBase())
		container_dn = ucr.get('umc/self-service/account-registration/usercontainer', None)
		if container_dn:
			try:
				container = udm.obj_by_dn(container_dn)
			except NoObject:
				msg = _('The container "{}" set by the "umc/self-service/account-registration/usercontainer" UCR variable does not exist. A user account can not be created. Please contact your system administrator.'.format(container_dn))
				MODULE.error('create_self_registered_account(): {}'.format(msg))
				raise UMC_Error(msg)
			else:
				user_position.setDn(container.dn)
		else:
			for dn in usersmod.object.get_default_containers(lo):
				try:
					container = udm.obj_by_dn(dn)
				except NoObject:
					pass
				else:
					user_position.setDn(container.dn)
					break

		# create user
		attributes['PasswordRecoveryEmailVerified'] = 'FALSE'
		attributes['RegisteredThroughSelfService'] = 'TRUE'
		new_user = usersmod.object(None, lo, user_position)
		new_user.open()
		for key, value in attributes.items():
			if key in new_user and value:
				new_user[key] = value
		try:
			new_user.create()
		except univention.admin.uexceptions.base as exc:
			MODULE.error('create_self_registered_account(): could not create user: %s' % (traceback.format_exc(),))
			return {
				'success': False,
				'failType': 'CREATION_FAILED',
				'data': _('The account could not be created:\n%s') % UDM_Error(exc),
			}
		finally:
			# TODO cleanup
			# reinit user module without template.
			# This has to be done since the modules are singletons?
			univention.admin.modules.update()
			self._usersmod = None
			#  univention.admin.modules.init(lo, po, usersmod, None, True)
		try:
			self.send_message(new_user['username'], 'verify_email', new_user['PasswordRecoveryEmail'], raise_on_success=False)
		except Exception:
			verify_token_successfully_send = False
		else:
			verify_token_successfully_send = True
		return {
			'success': True,
			'verifyTokenSuccessfullySend': verify_token_successfully_send,
			'data': {
				'username': new_user['username'],
				'email': new_user['PasswordRecoveryEmail'],
			}
		}
    def status(self, request: Request) -> None:  # TODO: remove unneeded things
        """One call for all single-value variables."""

        result = {}  # type: Dict[str, Any]
        ucr.load()

        try:
            result['erratalevel'] = int(ucr.get('version/erratalevel', 0))
        except ValueError:
            result['erratalevel'] = 0

        result['appliance_mode'] = ucr.is_true('server/appliance')
        result['timestamp'] = int(time())
        result['reboot_required'] = ucr.is_true('update/reboot/required',
                                                False)

        try:
            # be as current as possible.
            what = 'reinitializing UniventionUpdater'
            self.uu.ucr_reinit()

            what = 'getting UCS version'
            result['ucs_version'] = str(self.uu.current_version)

            # if nothing is returned -> convert to empty string.
            what = 'querying available release updates'
            try:
                ver = self.uu.release_update_available(errorsto='exception')
                result[
                    'release_update_available'] = '' if ver is None else str(
                        ver)
            except RequiredComponentError as exc:
                result['release_update_available'] = exc.version

            what = 'querying update-blocking components'
            blocking_components = self.uu.get_all_available_release_updates(
            )[1] or set()
            # check apps
            if result['release_update_available']:
                try:
                    from univention.appcenter.actions import get_action
                    update_check = get_action('update-check')
                    if update_check:
                        blocking_apps = update_check.get_blocking_apps(
                            ucs_version=result['release_update_available'])
                        if blocking_apps:
                            blocking_components.update(set(blocking_apps))
                except (ImportError, ValueError):
                    # the new univention.appcenter package is not installed.
                    # Cannot be a dependency as the app center depends on updater...
                    raise UMC_Error(
                        _('Error checking if installed apps are available for next UCS version.'
                          ))

            result['release_update_blocking_components'] = ' '.join(
                blocking_components)

            # Component counts are now part of the general 'status' data.
            what = "counting components"
            components = [
                bool(comp) for comp in self.uu.get_components(all=True)
            ]
            result['components'] = len(components)
            result['enabled'] = sum(components)

            # HACK: the 'Updates' form polls on the serial file
            #       to refresh itself. Including the serial value
            #       into the form helps us to have a dependent field
            #       that can trigger the refresh of the "Releases"
            #       combobox and the 'package updates available' field.
            result['serial'] = self._serial_file.timestamp()

        except Exception as exc:  # FIXME: don't catch everything
            raise UMC_Error("%s %s %s" % (
                _('Error contacting the update server. Please check your proxy or firewall settings, if any. Or it may be a problem with your configured DNS server.'
                  ),
                _('This is the error message:'),
                exc,
            ),
                            traceback=format_exc())

        self.finished(request.id, [result])
Beispiel #24
0
    def send(self, request, ldap_user_read=None, ldap_position=None):
        ucr.load()
        if not ucr.get('ucsschool/helpdesk/recipient'):
            raise UMC_Error(_(
                'The message could not be send to the helpdesk team: The email address for the helpdesk team is not configured. It must be configured by an administrator via the UCR variable "ucsschool/helpdesk/recipient".'
            ),
                            status=500)

        def _send_thread(sender, recipients, subject, message):
            MODULE.info('sending mail: thread running')

            msg = u'From: %s\r\n' % (sanitize_header(sender), )
            msg += u'To: %s\r\n' % (sanitize_header(', '.join(recipients)), )
            msg += u'Subject: =?UTF-8?Q?%s?=\r\n' % (
                sanitize_header(subject).encode('quopri'), )
            msg += u'Content-Type: text/plain; charset="UTF-8"\r\n'
            msg += u'\r\n'
            msg += message
            msg += u'\r\n'
            msg = msg.encode('UTF-8')

            server = smtplib.SMTP('localhost')
            server.set_debuglevel(0)
            server.sendmail(sender, recipients, msg)
            server.quit()
            return True

        recipients = ucr['ucsschool/helpdesk/recipient'].split(' ')
        school = School.from_dn(
            School(name=request.options['school']).dn, None,
            ldap_user_read).display_name
        category = request.options['category']
        message = request.options['message']

        subject = u'%s (%s: %s)' % (category, _('School'), school)

        try:
            user = User(None, ldap_user_read, ldap_position, self.user_dn)
            user.open()
        except ldap.LDAPError:
            MODULE.error('Errror receiving user information: %s' %
                         (traceback.format_exception(), ))
            user = {
                'displayName': self.username,
                'mailPrimaryAddress': '',
                'mailAlternativeAddress': [],
                'e-mail': [],
                'phone': []
            }
        mails = set([user['mailPrimaryAddress']]) | set(
            user['mailAlternativeAddress']) | set(user['e-mail'])

        sender = user['mailPrimaryAddress']
        if not sender:
            if ucr.get('hostname') and ucr.get('domainname'):
                sender = 'ucsschool-helpdesk@%s.%s' % (ucr['hostname'],
                                                       ucr['domainname'])
            else:
                sender = 'ucsschool-helpdesk@localhost'

        data = [
            (_('Sender'), u'%s (%s)' % (user['displayName'], self.username)),
            (_('School'), school),
            (_('Mail address'), u', '.join(mails)),
            (_('Phone number'), u', '.join(user['phone'])),
            (_('Category'), category),
            (_('Message'), u'\r\n%s' % (message, )),
        ]
        msg = u'\r\n'.join(u'%s: %s' % (key, value) for key, value in data)

        MODULE.info(
            'sending message: %s' %
            ('\n'.join(map(lambda x: repr(x.strip()), msg.splitlines()))), )

        func = notifier.Callback(_send_thread, sender, recipients, subject,
                                 msg)
        MODULE.info('sending mail: starting thread')
        thread = notifier.threads.Simple(
            'HelpdeskMessage', func,
            notifier.Callback(self.thread_finished_callback, request))
        thread.run()
Beispiel #25
0
	def get_school_version(self):
		return ucr.get('appcenter/apps/ucsschool/version')
	def __init__(self):
		super(SearchLimitReached, self).__init__(_('The query you have entered yields too many matching entries. Please narrow down your search by specifying more query parameters. The current size limit of %s can be configured with the UCR variable directory/manager/web/sizelimit.') % ucr.get('directory/manager/web/sizelimit', '2000'))
Beispiel #27
0
	def install(self, request):
		# get all arguments
		username = request.options.get('username')
		password = request.options.get('password')
		master = request.options.get('master')
		school_ou = request.options.get('schoolOU')
		educational_slave = request.options.get('nameEduServer')
		ou_display_name = request.options.get('OUdisplayname', school_ou)  # use school OU name as fallback
		server_type = request.options.get('server_type')
		setup = request.options.get('setup')
		server_role = ucr.get('server/role')
		joined = os.path.exists('/var/univention-join/joined')

		if self._installation_started:
			raise ValueError('The installation was started twice. This should not have happened.')

		if server_role != 'domaincontroller_slave':
			# use the credentials of the currently authenticated user on a master/backup system
			self.require_password()
			username = self.username
			password = self.password
			master = '%s.%s' % (ucr.get('hostname'), ucr.get('domainname'))
		if server_role == 'domaincontroller_backup':
			master = ucr.get('ldap/master')

		self.original_certificate_file = None

		# check for valid school OU
		if ((setup == 'singlemaster' and server_role == 'domaincontroller_master') or server_role == 'domaincontroller_slave') and not RE_OU.match(school_ou):
			raise SchoolInstallerError(_('The specified school OU is not valid.'))

		# check for valid server role
		if server_role not in ('domaincontroller_master', 'domaincontroller_backup', 'domaincontroller_slave'):
			raise SchoolInstallerError(_('Invalid server role! UCS@school can only be installed on the system roles master domain controller, backup domain controller, or slave domain controller.'))

		if server_role == 'domaincontroller_slave' and not server_type:
			raise SchoolInstallerError(_('Server type has to be set for domain controller slave'))

		if server_role == 'domaincontroller_slave' and server_type == 'administrative' and not educational_slave:
			raise SchoolInstallerError(_('The name of an educational server has to be specified if the system shall be configured as administrative server.'))

		if server_role == 'domaincontroller_slave' and server_type == 'administrative' and educational_slave.lower() == ucr.get('hostname').lower():
			raise SchoolInstallerError(_('The name of the educational server may not be equal to the name of the administrative slave.'))

		if server_role == 'domaincontroller_slave':
			# on slave systems, download the certificate from the master in order
			# to be able to build up secure connections
			self.original_certificate_file = self.retrieve_root_certificate(master)

		if server_role != 'domaincontroller_master':
			# check for a compatible environment on the DC master

			masterinfo = self._umc_master(username, password, master, 'schoolinstaller/get/metainfo')
			school_environment = masterinfo['school_environment']
			master_samba_version = masterinfo['samba']
			if not school_environment:
				raise SchoolInstallerError(_('Please install UCS@school on the master domain controller system. Cannot proceed installation on this system.'))
			if master_samba_version == 3:
				raise SchoolInstallerError(_('This UCS domain uses Samba 3 which is no longer supported by UCS@school. Please update all domain systems to samba 4 to be able to continue.'))
			if server_role == 'domaincontroller_slave' and school_environment != 'multiserver':
				raise SchoolInstallerError(_('The master domain controller is not configured for a UCS@school multi server environment. Cannot proceed installation on this system.'))
			if server_role == 'domaincontroller_backup' and school_environment != setup:
				raise SchoolInstallerError(_('The UCS@school master domain controller needs to be configured similarly to this backup system. Please choose the correct environment type for this system.'))
			if server_role == 'domaincontroller_backup' and not joined:
				raise SchoolInstallerError(_('In order to install UCS@school on a backup domain controller, the system needs to be joined first.'))

		# everything ok, try to acquire the lock for the package installation
		lock_aquired = self.package_manager.lock(raise_on_fail=False)
		if not lock_aquired:
			MODULE.warn('Could not aquire lock for package manager')
			raise SchoolInstallerError(_('Cannot get lock for installation process. Another package manager seems to block the operation.'))

		# see which packages we need to install
		MODULE.process('performing UCS@school installation')
		packages_to_install = []
		installed_samba_version = self.get_samba_version()
		if installed_samba_version == 3:
			raise SchoolInstallerError(_('This UCS domain uses Samba 3 which is no longer supported by UCS@school. Please update all domain systems to samba 4 to be able to continue.'))
		if server_role == 'domaincontroller_slave':
			# slave
			packages_to_install.extend(['univention-samba4', 'univention-s4-connector'])
			if server_type == 'educational':
				packages_to_install.append('ucs-school-slave')
			else:
				packages_to_install.append('ucs-school-nonedu-slave')
		else:  # master or backup
			if setup == 'singlemaster':
				if installed_samba_version:
					pass  # do not install samba a second time
				else:  # otherwise install samba4
					packages_to_install.extend(['univention-samba4', 'univention-s4-connector'])
				packages_to_install.append('ucs-school-singlemaster')
			elif setup == 'multiserver':
				packages_to_install.append('ucs-school-master')
			else:
				raise SchoolInstallerError(_('Invalid UCS@school configuration.'))
		MODULE.info('Packages to be installed: %s' % ', '.join(packages_to_install))

		# reset the current installation progress
		steps = 100  # installation -> 100
		if server_role != 'domaincontroller_backup' and not (server_role == 'domaincontroller_master' and setup == 'multiserver'):
			steps += 10  # create_ou -> 10
		if server_role == 'domaincontroller_slave':
			steps += 10  # move_slave_into_ou -> 10
		steps += 100  # system_join -> 100 steps

		self._installation_started = True
		progress_state = self.progress_state
		progress_state.reset(steps)
		progress_state.component = _('Installation of UCS@school packages')
		self.package_manager.reset_status()

		def _thread(_self, packages):
			MODULE.process('Starting package installation')
			with _self.package_manager.locked(reset_status=True, set_finished=True):
				with _self.package_manager.no_umc_restart(exclude_apache=True):
					_self.package_manager.update()
					if not _self.package_manager.install(*packages):
						raise SchoolInstallerError(_('Failed to install packages.'))

			if server_role != 'domaincontroller_backup' and not (server_role == 'domaincontroller_master' and setup == 'multiserver'):
				# create the school OU (not on backup and not on master w/multi server environment)
				MODULE.info('Starting creation of LDAP school OU structure...')
				progress_state.component = _('Creation of LDAP school structure')
				progress_state.info = ''
				try:
					if server_role == 'domaincontroller_slave':
						_educational_slave = ucr.get('hostname') if server_type == 'educational' else educational_slave
						administrative_slave = None if server_type == 'educational' else ucr.get('hostname')
						create_ou_remote(master, username, password, school_ou, ou_display_name, _educational_slave, administrative_slave)
					elif server_role == 'domaincontroller_master':
						create_ou_local(school_ou, ou_display_name)
				except SchoolInstallerError as exc:
					MODULE.error(str(exc))
					raise SchoolInstallerError(_(
						'The UCS@school software packages have been installed, however, a school OU could not be created and consequently a re-join of the system has not been performed. '
						'Please create a new school OU structure using the UMC module "Add school" on the master and perform a domain join on this machine via the UMC module "Domain join".'
					))

				progress_state.add_steps(10)

			if server_role == 'domaincontroller_slave':
				# make sure that the slave is correctly moved below its OU
				MODULE.info('Trying to move the slave entry in the right OU structure...')
				result = umc(username, password, master, 'schoolwizards/schools/move_dc', {'schooldc': ucr.get('hostname'), 'schoolou': school_ou}, 'schoolwizards/schools').result
				if not result.get('success'):
					MODULE.warn('Could not successfully move the slave DC into its correct OU structure:\n%s' % result.get('message'))
					raise SchoolInstallerError(_('Validating the LDAP school OU structure failed. It seems that the current slave system has already been assigned to a different school or that the specified school OU name is already in use.'))

			# system join on a slave system
			progress_state.component = _('Domain join')
			if server_role == 'domaincontroller_slave':
				progress_state.info = _('Preparing domain join...')
				MODULE.process('Starting system join...')
			else:  # run join scripts on DC backup/master
				progress_state.info = _('Executing join scripts...')
				MODULE.process('Running join scripts...')
			system_join(
				username, password,
				info_handler=self.progress_state.info_handler,
				step_handler=self.progress_state.add_steps,
				error_handler=self.progress_state.error_handler,
			)

		def _finished(thread, result):
			MODULE.info('Finished installation')
			progress_state.finish()
			progress_state.info = _('finished...')
			self._installation_started = None
			if isinstance(result, SchoolInstallerError):
				MODULE.warn('Error during installation: %s' % (result,))
				self.restore_original_certificate()
				progress_state.error_handler(str(result))
			elif isinstance(result, BaseException):
				self.restore_original_certificate()
				msg = ''.join(traceback.format_exception(*thread.exc_info))
				MODULE.error('Exception during installation: %s' % msg)
				progress_state.error_handler(_('An unexpected error occurred during installation: %s') % result)

		thread = notifier.threads.Simple('ucsschool-install', notifier.Callback(_thread, self, packages_to_install), notifier.Callback(_finished))
		thread.run()
		self.finished(request.id, None)
	def containers(self):
		"""List of LDAP DNs of default containers"""
		containers = getattr(self.module, 'default_containers', [])
		ldap_base = ucr.get('ldap/base')

		return map(lambda x: {'id': '%s,%s' % (x, ldap_base), 'label': ldap_dn2path('%s,%s' % (x, ldap_base))}, containers)
    def status(self, request):  # TODO: remove unneeded things
        """One call for all single-value variables."""

        result = {}
        ucr.load()

        try:
            result['erratalevel'] = int(ucr.get('version/erratalevel', 0))
        except ValueError:
            result['erratalevel'] = 0

        result['appliance_mode'] = ucr.is_true('server/appliance')
        result['easy_mode'] = ucr.is_true('update/umc/updateprocess/easy',
                                          False)
        result['timestamp'] = int(time())
        result['reboot_required'] = ucr.is_true('update/reboot/required',
                                                False)

        try:
            # be as current as possible.
            what = 'reinitializing UniventionUpdater'
            self.uu.ucr_reinit()

            what = 'getting UCS version'
            result['ucs_version'] = self.uu.get_ucs_version()

            # if nothing is returned -> convert to empty string.
            what = 'querying available release updates'
            try:
                result[
                    'release_update_available'] = self.uu.release_update_available(
                        errorsto='exception')
            except RequiredComponentError as exc:
                result['release_update_available'] = exc.version
            if result['release_update_available'] is None:
                result['release_update_available'] = ''

            what = 'querying update-blocking components'
            blocking_components = self.uu.get_all_available_release_updates(
            )[1]
            result['release_update_blocking_components'] = ' '.join(
                blocking_components or [])

            what = "querying availability for easy mode"

            if result['easy_mode']:
                # updates/available should reflect the need for an update
                easy_update_available = ucr.is_true('update/available', False)
                # but dont rely on ucr! update/available is set during univention-upgrade --check
                # but when was the last time this was run?

                # release update
                easy_update_available = easy_update_available or result[
                    'release_update_available']
                # if no update seems necessary perform a real (expensive) check nonetheless
                easy_update_available = easy_update_available or self.uu.component_update_available(
                )
                result['easy_update_available'] = bool(easy_update_available)
            else:
                result['easy_update_available'] = False

            # Component counts are now part of the general 'status' data.
            what = "counting components"
            c_count = 0
            e_count = 0
            for comp in self.uu.get_all_components():
                c_count = c_count + 1
                if ucr.is_true('repository/online/component/%s' % (comp, ),
                               False):
                    e_count = e_count + 1
            result['components'] = c_count
            result['enabled'] = e_count

            # HACK: the 'Updates' form polls on the serial file
            #       to refresh itself. Including the serial value
            #       into the form helps us to have a dependent field
            #       that can trigger the refresh of the "Releases"
            #       combobox and the 'package updates available' field.
            result['serial'] = self._serial_file.timestamp()

        except Exception as exc:  # FIXME: don't catch everything
            typ = str(type(exc)).strip('<>')
            msg = '[while %s] [%s] %s' % (what, typ, exc)
            result['message'] = msg
            result['status'] = 1
            MODULE.error(msg)

        self.finished(request.id, [result])
	def __init__(self, **kwargs):
		ucr.load()
		self._is_master = ucr.get('server/role') == 'domaincontroller_master'
		self._updates_available = ucr.is_true('update/available')
		self._fqdn = '%s.%s' % (ucr.get('hostname'), ucr.get('domainname'))
		super(UMCError, self).__init__('\n'.join(self._error_msg()), **kwargs)
Beispiel #31
0
import notifier
import notifier.signals
import notifier.threads

from PyQt4.QtCore import QObject, pyqtSlot

import italc
import ldap
import sip
from ldap.filter import filter_format
from ldap.dn import explode_dn

_ = Translation('ucs-school-umc-computerroom').translate

ITALC_DEMO_PORT = int(ucr.get('ucsschool/umc/computerroom/demo/port', 11400))
ITALC_VNC_PORT = int(ucr.get('ucsschool/umc/computerroom/vnc/port', 11100))
ITALC_VNC_UPDATE = float(ucr.get('ucsschool/umc/computerroom/vnc/update', 1))
ITALC_CORE_UPDATE = max(
    1, int(ucr.get('ucsschool/umc/computerroom/core/update', 1)))
ITALC_CORE_TIMEOUT = max(
    1, int(ucr.get('ucsschool/umc/computerroom/core/timeout', 10)))

italc.ItalcCore.init()

italc.ItalcCore.config.setLogLevel(italc.Logger.LogLevelDebug)
italc.ItalcCore.config.setLogToStdErr(True)
italc.ItalcCore.config.setLogFileDirectory('/var/log/univention/')
italc.Logger('ucs-school-umc-computerroom')
italc.ItalcCore.config.setLogonAuthenticationEnabled(False)
Beispiel #32
0
        def _finished(data):
            """
			Process asynchronous UVMM DOMAIN_INFO answer.
			Convert UVMM protocol to JSON.
			"""
            node_uri = urlsplit(request.options['domainURI'])
            uri, _uuid = urldefrag(request.options['domainURI'])
            json = object2dict(data)

            # re-arrange a few attributes for the frontend
            # annotations
            for key in json['annotations']:
                if key == 'uuid':
                    continue
                json[key] = json['annotations'][key]

            # STOP here if domain is not available
            if not json['available']:
                MODULE.info('Domain is not available: %s' % (json, ))
                self.finished(request.id, json)
                return

            # interfaces (fake the special type network:<source>)
            for iface in json['interfaces']:
                if iface['type'] == Interface.TYPE_NETWORK:
                    iface['type'] = 'network:' + iface['source']

            # disks
            for disk in json['disks']:
                disk['volumeFilename'] = os.path.basename(
                    disk['source']) if disk['pool'] else disk['source']
                disk['paravirtual'] = disk['target_bus'] in ('virtio', )
                disk['volumeType'] = disk['type']

            # graphics
            if json['graphics']:
                try:
                    gfx = json['graphics'][0]
                    json['vnc'] = True
                    json['vnc_host'] = None
                    json['vnc_port'] = None
                    json['kblayout'] = gfx['keymap']
                    json['vnc_remote'] = gfx['listen'] == '0.0.0.0'
                    json['vnc_password'] = gfx['passwd']
                    # vnc_password will not be send to frontend
                    port = int(json['graphics'][0]['port'])
                    if port == -1:
                        raise ValueError(json['graphics'][0]['port'])
                    host = node_uri.netloc
                    vnc_link_format = ucr.get('uvmm/umc/vnc/host',
                                              'IPv4') or ''
                    match = Domains.RE_VNC.match(vnc_link_format)
                    if match:
                        family, pattern, substs = match.groups()
                        if family:  # IPvX
                            family = Domains.SOCKET_FAMILIES[family]
                            regex = re.compile(pattern or '.*')
                            addrs = socket.getaddrinfo(host, port, family,
                                                       socket.SOCK_STREAM,
                                                       socket.SOL_TCP)
                            for (family, _socktype, _proto, _canonname,
                                 sockaddr) in addrs:
                                host, port = sockaddr[:2]
                                if regex.search(host):
                                    break
                            else:
                                raise LookupError(pattern)
                            host = Domains.SOCKET_FORMATS[family] % (host, )
                        elif substs:  # NAME
                            for subst in substs.split():
                                old, new = subst.split('=', 1)
                                host = host.replace(old, new)
                    elif vnc_link_format:  # overwrite all hosts with fixed host
                        host = vnc_link_format
                    json['vnc_host'] = host
                    json['vnc_port'] = port
                except re.error as ex:  # port is not valid
                    MODULE.warn('Invalid VNC regex: %s' % (ex, ))
                except socket.gaierror as ex:
                    MODULE.warn('Invalid VNC host: %s' % (ex, ))
                except (ValueError, LookupError) as ex:  # port is not valid
                    MODULE.warn('Failed VNC lookup: %s' % (ex, ))

            # profile (MUST be after mapping annotations)
            profile_dn = json.get('profile')
            profile = None
            if profile_dn:
                for dn, pro in self.profiles:
                    if dn == profile_dn:
                        profile = pro
                        break
                if profile:
                    json['profileData'] = object2dict(profile)

            MODULE.info('Got domain description: %s' % (json, ))
            return json
Beispiel #33
0
    def _settings_set(self,
                      printMode,
                      internetRule,
                      shareMode,
                      period=None,
                      customRule=None):
        """Defines settings for a room"""

        if not self._italc.school or not self._italc.room:
            raise UMC_Error('no room selected')

        # find AT jobs for the room and execute it to remove current settings
        jobs = atjobs.list(extended=True)
        for job in jobs:
            if job.comments.get(Instance.ATJOB_KEY, False) == self._italc.room:
                job.rm()
                subprocess.call(shlex.split(job.command))

        roomInfo = _readRoomInfo(self._italc.roomDN)
        in_exam_mode = roomInfo.get('exam')

        # for the exam mode, remove current settings before setting new ones
        if in_exam_mode and roomInfo.get('cmd'):
            MODULE.info('unsetting room settings for exam (%s): %s' %
                        (roomInfo['exam'], roomInfo['cmd']))
            try:
                subprocess.call(shlex.split(roomInfo['cmd']))
            except (OSError, IOError):
                MODULE.warn(
                    'Failed to reinitialize current room settings: %s' %
                    roomInfo['cmd'])
            _updateRoomInfo(self._italc.roomDN, cmd=None)

        # reset to defaults. No atjob is necessary.
        if internetRule == 'none' and shareMode == 'all' and printMode == 'default':
            self._ruleEndAt = None
            self.reset_smb_connections()
            self.reload_cups()
            return

        # collect new settings
        vset = {}
        vappend = {}
        vunset = []
        vunset_now = []
        vextract = []
        hosts = self._italc.ipAddresses(students_only=True)

        # print mode
        if printMode in ('none', 'all'):
            vextract.append('samba/printmode/hosts/%s' % printMode)
            vappend[vextract[-1]] = hosts
            vextract.append('cups/printmode/hosts/%s' % printMode)
            vappend[vextract[-1]] = hosts
            vunset.append('samba/printmode/room/%s' % self._italc.room)
            vset[vunset[-1]] = printMode
        else:
            vunset_now.append('samba/printmode/room/%s' % self._italc.room)

        # share mode
        if shareMode == 'home':
            vunset.append('samba/sharemode/room/%s' % self._italc.room)
            vset[vunset[-1]] = shareMode
            vextract.append('samba/othershares/hosts/deny')
            vappend[vextract[-1]] = hosts
            vextract.append('samba/share/Marktplatz/hosts/deny')
            vappend[vextract[-1]] = hosts
        else:
            vunset_now.append('samba/sharemode/room/%s' % self._italc.room)

        # internet rule
        if internetRule != 'none':
            vextract.append('proxy/filter/room/%s/ip' % self._italc.room)
            vappend[vextract[-1]] = hosts
            if internetRule == 'custom':
                # remove old rules
                i = 1
                while True:
                    var = 'proxy/filter/setting-user/%s/domain/whitelisted/%d' % (
                        self._username, i)
                    if var in ucr:
                        vunset_now.append(var)
                        i += 1
                    else:
                        break
                vunset.append('proxy/filter/room/%s/rule' % self._italc.room)
                vset[vunset[-1]] = self._username
                vset['proxy/filter/setting-user/%s/filtertype' %
                     self._username] = 'whitelist-block'
                i = 1
                for domain in (customRule or '').split('\n'):
                    MODULE.info('Setting whitelist entry for domain %s' %
                                domain)
                    if not domain:
                        continue
                    parsed = urlparse.urlsplit(domain)
                    MODULE.info('Setting whitelist entry for domain %s' %
                                str(parsed))
                    if parsed.netloc:
                        vset[
                            'proxy/filter/setting-user/%s/domain/whitelisted/%d'
                            % (self._username, i)] = parsed.netloc
                        i += 1
                    elif parsed.path:
                        vset[
                            'proxy/filter/setting-user/%s/domain/whitelisted/%d'
                            % (self._username, i)] = parsed.path
                        i += 1
            else:
                vunset.append('proxy/filter/room/%s/rule' % self._italc.room)
                vset[vunset[-1]] = internetRule
        else:
            vunset_now.append('proxy/filter/room/%s/ip' % self._italc.room)
            vunset_now.append('proxy/filter/room/%s/rule' % self._italc.room)
        # write configuration
        # remove old values
        handler_unset(vunset_now)

        # append values
        ucr.load()
        MODULE.info('Merging UCR variables')
        for key, value in vappend.items():
            if ucr.get(key):
                old = set(ucr[key].split(' '))
                MODULE.info('Old value: %s' % old)
            else:
                old = set()
                MODULE.info('Old value empty')
            new = set(value)
            MODULE.info('New value: %s' % new)
            new = old.union(new)
            MODULE.info('Merged value of %s: %s' % (key, new))
            if not new:
                MODULE.info('Unset variable %s' % key)
                vunset.append(key)
            else:
                vset[key] = ' '.join(new)

        # Workaround for bug 30450:
        # if samba/printmode/hosts/none is not set but samba/printmode/hosts/all then all other hosts
        # are unable to print on samba shares. Solution: set empty value for .../none if no host is on deny list.
        varname = 'samba/printmode/hosts/none'
        if varname not in vset:
            ucr.load()
            if not ucr.get(varname):
                vset[varname] = '""'
        else:
            # remove empty items ('""') in list
            vset[varname] = ' '.join(
                [x for x in vset[varname].split(' ') if x != '""'])
        if varname in vunset:
            vunset.remove(varname)

        # set values
        ucr_vars = sorted('%s=%s' % x for x in vset.items())
        MODULE.info('Writing room rules: %s' % '\n'.join(ucr_vars))
        handler_set(ucr_vars)

        # create at job to remove settings
        unset_vars = ['-r %s' % quote(x) for x in vunset]
        MODULE.info('Will remove: %s' % ' '.join(unset_vars))
        extract_vars = ['-e %s' % quote(x) for x in vextract]
        MODULE.info('Will extract: %s' % ' '.join(extract_vars))

        cmd = '/usr/share/ucs-school-umc-computerroom/ucs-school-deactivate-rules %s %s %s' % (
            ' '.join(unset_vars), ' '.join(extract_vars), ' '.join(
                quote(x) for x in hosts))
        MODULE.info('command for reinitialization is: %s' % (cmd, ))

        if in_exam_mode:
            # Command for the exam mode to be executed manually when changing the settings again...
            _updateRoomInfo(self._italc.roomDN, cmd=cmd)
        else:
            starttime = datetime.datetime.now()
            MODULE.info('Now: %s' % starttime)
            MODULE.info('Endtime: %s' % period)
            starttime = starttime.replace(hour=period.hour,
                                          minute=period.minute,
                                          second=0,
                                          microsecond=0)
            while starttime < datetime.datetime.now(
            ):  # prevent problems due to intra-day limit
                starttime += datetime.timedelta(days=1)

            # AT job for the normal case
            MODULE.info('Remove settings at %s' % (starttime, ))
            atjobs.add(cmd, starttime, {Instance.ATJOB_KEY: self._italc.room})
            self._ruleEndAt = starttime

        self.reset_smb_connections()
        self.reload_cups()
Beispiel #34
0
from datetime import datetime

from univention.lib import atjobs
from univention.lib.i18n import Translation
from univention.management.console.log import MODULE
from univention.management.console.config import ucr

# import univention.admin.modules as udm_modules
import univention.admin.uexceptions as udm_exceptions

import ucsschool.lib.models

_ = Translation('ucs-school-umc-distribution').translate

DISTRIBUTION_CMD = '/usr/lib/ucs-school-umc-distribution/umc-distribution'
DISTRIBUTION_DATA_PATH = ucr.get('ucsschool/datadistribution/cache',
                                 '/var/lib/ucs-school-umc-distribution')
POSTFIX_DATADIR_SENDER = ucr.get('ucsschool/datadistribution/datadir/sender',
                                 'Unterrichtsmaterial')
POSTFIX_DATADIR_SENDER_PROJECT_SUFFIX = ucr.get(
    'ucsschool/datadistribution/datadir/sender/project/suffix', '-Ergebnisse')
POSTFIX_DATADIR_RECIPIENT = ucr.get(
    'ucsschool/datadistribution/datadir/recipient', 'Unterrichtsmaterial')

TYPE_USER = '******'
TYPE_GROUP = 'GROUP'
TYPE_PROJECT = 'PROJECT'


class DistributionException(Exception):
    pass
Beispiel #35
0
	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.')})
Beispiel #36
0
        def _thread():
            # make sure that a project with the same name does not exist
            directory = request.options['directory']
            # get absolute path of project file and test for existance
            fn_test_project = util.distribution.Project.sanitize_project_filename(
                directory)
            if os.path.exists(fn_test_project):
                raise UMC_Error(
                    _('An exam with the name "%s" already exists. Please choose a different name for the exam.'
                      ) % (directory, ))

            # validate the project data and save project
            my.project = util.distribution.Project(
                dict(
                    name=directory,
                    description=request.options['name'],
                    files=request.options.get('files'),
                    sender=sender,
                ))
            my.project.validate()
            my.project.save()

            # copy files into project directory
            if self._tmpDir:
                for ifile in my.project.files:
                    isrc = os.path.join(self._tmpDir, ifile)
                    itarget = os.path.join(my.project.cachedir, ifile)
                    if os.path.exists(isrc):
                        # copy file to cachedir
                        shutil.move(isrc, itarget)
                        os.chown(itarget, 0, 0)

            # open a new connection to the master UMC
            try:
                master = ucr['ldap/master']
                client = Client(master)
                client.authenticate_with_machine_account()
            except (ConnectionError, HTTPError) as exc:
                MODULE.error('Could not connect to UMC on %s: %s' %
                             (master, exc))
                raise UMC_Error(
                    _('Could not connect to master server %s.') %
                    ucr.get('ldap/master'))

            # mark the computer room for exam mode
            progress.component(
                _('Preparing the computer room for exam mode...'))
            client.umc_command(
                'schoolexam-master/set-computerroom-exammode',
                dict(
                    school=request.options['school'],
                    roomdn=request.options['room'],
                )).result  # FIXME: no error handling
            progress.add_steps(5)

            # read all recipients and fetch all user objects
            users = []
            for idn in request.options['recipients']:
                ientry = util.distribution.openRecipients(idn, ldap_user_read)
                if not ientry:
                    continue
                # recipients can in theory be users or groups
                members = []
                if isinstance(ientry, util.distribution.User):
                    members = [ientry]
                elif isinstance(ientry, util.distribution.Group):
                    members = ientry.members
                for entry in members:
                    # ignore exam users
                    user = User.from_dn(entry.dn, None, ldap_user_read)
                    if not user.is_exam_student(ldap_user_read):
                        users.append(entry)

            # start to create exam user accounts
            progress.component(_('Preparing exam accounts'))
            percentPerUser = 25.0 / (1 + len(users))
            examUsers = set()
            student_dns = set()
            usersReplicated = set()
            for iuser in users:
                progress.info(
                    '%s, %s (%s)' %
                    (iuser.lastname, iuser.firstname, iuser.username))
                try:
                    ires = client.umc_command(
                        'schoolexam-master/create-exam-user',
                        dict(
                            school=request.options['school'],
                            userdn=iuser.dn,
                        )).result
                    examuser_dn = ires.get('examuserdn')
                    examUsers.add(examuser_dn)
                    student_dns.add(iuser.dn)
                    MODULE.info('Exam user has been created: %r' % examuser_dn)
                except (ConnectionError, HTTPError) as exc:
                    MODULE.warn(
                        'Could not create exam user account for %r: %s' %
                        (iuser.dn, exc))

                # indicate the the user has been processed
                progress.add_steps(percentPerUser)

            client.umc_command(
                'schoolexam-master/add-exam-users-to-groups',
                dict(
                    users=list(student_dns),
                    school=request.options['school'],
                ))

            progress.add_steps(percentPerUser)

            # wait for the replication of all users to be finished
            progress.component(_('Preparing user home directories'))
            recipients = []  # list of User objects for all exam users
            openAttempts = 30 * 60  # wait max. 30 minutes for replication
            while (len(examUsers) > len(usersReplicated)) and (openAttempts >
                                                               0):
                openAttempts -= 1
                MODULE.info(
                    'waiting for replication to be finished, %s user objects missing'
                    % (len(examUsers) - len(usersReplicated)))
                for idn in examUsers - usersReplicated:
                    try:
                        ldap_user_read.get(idn, required=True)
                    except ldap.NO_SUCH_OBJECT:
                        continue  # not replicated yet
                    iuser = util.distribution.openRecipients(
                        idn, ldap_user_read)
                    if not iuser:
                        continue  # not a users/user object
                    MODULE.info('user has been replicated: %s' % idn)

                    # call hook scripts
                    if 0 != subprocess.call([
                            '/bin/run-parts', CREATE_USER_POST_HOOK_DIR,
                            '--arg', iuser.username, '--arg', iuser.dn,
                            '--arg', iuser.homedir
                    ]):
                        raise ValueError(
                            'failed to run hook scripts for user %r' %
                            (iuser.username))

                    # store User object in list of final recipients
                    recipients.append(iuser)

                    # mark the user as replicated
                    usersReplicated.add(idn)
                    progress.info(
                        '%s, %s (%s)' %
                        (iuser.lastname, iuser.firstname, iuser.username))
                    progress.add_steps(percentPerUser)

                # wait a second
                time.sleep(1)

            progress.add_steps(percentPerUser)

            if openAttempts <= 0:
                MODULE.error(
                    'replication timeout - %s user objects missing: %r ' %
                    ((len(examUsers) - len(usersReplicated)),
                     (examUsers - usersReplicated)))
                raise UMC_Error(
                    _('Replication timeout: could not create all exam users'))

            # update the final list of recipients
            my.project.recipients = recipients
            my.project.save()

            # update local NSS group cache
            if ucr.is_true('nss/group/cachefile', True):
                cmd = ['/usr/lib/univention-pam/ldap-group-to-file.py']
                if ucr.is_true('nss/group/cachefile/check_member', False):
                    cmd.append('--check_member')
                MODULE.info('Updating local nss group cache...')
                if subprocess.call(cmd):
                    MODULE.error('Updating local nss group cache failed: %s' %
                                 ' '.join(cmd))
                else:
                    MODULE.info(
                        'Update of local nss group cache finished successfully.'
                    )

            # distribute exam files
            progress.component(_('Distributing exam files'))
            progress.info('')
            my.project.distribute()
            progress.add_steps(20)

            # prepare room settings via UMCP...
            #   first step: acquire room
            #   second step: adjust room settings
            progress.component(_('Prepare room settings'))
            try:
                user_client = Client(None, self.username, self.password)
            except (ConnectionError, HTTPError) as exc:
                MODULE.warn('Authentication failed: %s' % (exc, ))
                raise UMC_Error(_('Could not connect to local UMC server.'))

            room = request.options['room']
            MODULE.info('Acquire room: %s' % (room, ))
            user_client.umc_command('computerroom/room/acquire',
                                    dict(
                                        room=request.options['room'], )).result
            progress.add_steps(1)
            MODULE.info('Adjust room settings:\n%s' % '\n'.join(
                ['  %s=%s' % (k, v) for k, v in request.options.iteritems()]))
            user_client.umc_command(
                'computerroom/exam/start',
                dict(
                    room=room,
                    examDescription=request.options['name'],
                    exam=directory,
                    examEndTime=request.options.get('examEndTime'),
                )).result
            progress.add_steps(4)
            user_client.umc_command(
                'computerroom/settings/set',
                dict(
                    room=room,
                    internetRule=request.options['internetRule'],
                    customRule=request.options.get('customRule'),
                    shareMode=request.options['shareMode'],
                    printMode='default',
                )).result
            progress.add_steps(5)
Beispiel #37
0
	def change(self, role, ip, netmask, oldip=None):
		'''Return a dict with all necessary values for ipchange read from the current
		status of the system.'''

		# ignore link local addresses (no DHCP address received)
		network = ipaddress.IPv4Network(u'%s/%s' % (ip, netmask), False)
		if network.is_link_local:
			MODULE.error('Ignore link local address change.')
			return

		lo, position = univention.admin.uldap.getAdminConnection()
		hmodule = univention.admin.modules.get('dns/host_record')
		cmodule = univention.admin.modules.get('computers/%s' % (role,))

		# check if already used
		res = univention.admin.modules.lookup(hmodule, None, lo, scope='sub', filter=filter_format('aRecord=%s', (ip,)))
		if res:
			used_by = []
			for i in res:
				if 'name' in i:
					used_by.append(i['name'])
			raise BadRequest('The IP address is already in used by host record(s) for: %s' % ', '.join(used_by))

		# do we have a forward zone for this IP address?
		if oldip and oldip != ip:
			fmodule = univention.admin.modules.get('dns/forward_zone')
			for forwardobject in univention.admin.modules.lookup(fmodule, None, lo, scope='sub', superordinate=None, filter=filter_format('(aRecord=%s)', (oldip,))):
				forwardobject.open()
				forwardobject['a'].remove(oldip)
				forwardobject['a'].append(ip)
				forwardobject.modify()

		# remove old DNS reverse entries with old IP
		server = cmodule.object(None, lo, position, self.user_dn)
		server.open()
		current_ips = server['ip']
		for e in server['dnsEntryZoneReverse']:
			if e[1] in current_ips:
				server['dnsEntryZoneReverse'].remove(e)

		# change IP
		server['ip'] = ip
		MODULE.info('Change IP to %s' % (ip,))
		server.modify()

		# do we have a new reverse zone for this IP address?
		rmodule = univention.admin.modules.get('dns/reverse_zone')
		parts = network.network_address.exploded.split('.')
		while parts[-1] == '0':
			parts.pop()

		while parts:
			subnet = '.'.join(parts)
			parts.pop()
			filter = filter_format('(subnet=%s)', (subnet,))
			reverseobject = univention.admin.modules.lookup(rmodule, None, lo, scope='sub', superordinate=None, filter=filter)
			if reverseobject:
				server = cmodule.object(None, lo, position, self.user_dn)
				server.open()
				server['dnsEntryZoneReverse'].append([reverseobject[0].dn, ip])
				server.modify()
				break

		# Change ucs-sso entry
		# FIXME: this should be done for UCS-in-AD domains as well!
		ucr.load()
		sso_fqdn = ucr.get('ucs/server/sso/fqdn')
		if ucr.is_true('ucs/server/sso/autoregistraton', True):
			fmodule = univention.admin.modules.get('dns/forward_zone')
			forwardobjects = univention.admin.modules.lookup(fmodule, None, lo, scope='sub', superordinate=None, filter=None)
			for forwardobject in forwardobjects:
				zone = forwardobject.get('zone')
				if not sso_fqdn.endswith(zone):
					continue
				sso_name = sso_fqdn[:-(len(zone) + 1)]
				for current_ip in current_ips:
					records = univention.admin.modules.lookup(hmodule, None, lo, scope='sub', superordinate=forwardobject, filter=filter_format('(&(relativeDomainName=%s)(aRecord=%s))', (sso_name, current_ip)))
					for record in records:
						record.open()
						if oldip in record['a']:
							record['a'].remove(oldip)
						record['a'].append(ip)
						record.modify()
Beispiel #38
0
from univention.management.console.config import ucr
from univention.management.console.modules.decorators import sanitize, simple_response
from univention.management.console.modules.sanitizers import StringSanitizer
from univention.management.console.modules import UMC_Error
from univention.management.console.ldap import get_user_connection, get_machine_connection, get_admin_connection, machine_connection

from .tokendb import TokenDB, MultipleTokensInDB
from .sending import get_plugins as get_sending_plugins

_ = Translation('univention-self-service-passwordreset-umc').translate

TOKEN_VALIDITY_TIME = 3600
MEMCACHED_SOCKET = "/var/lib/univention-self-service-passwordreset-umc/memcached.socket"
MEMCACHED_MAX_KEY = 250

SELFSERVICE_MASTER = ucr.get("self-service/backend-server", ucr.get("ldap/master"))
IS_SELFSERVICE_MASTER = '%s.%s' % (ucr.get('hostname'), ucr.get('domainname')) == SELFSERVICE_MASTER

DEREGISTRATION_TIMESTAMP_FORMATTING = '%Y%m%d%H%M%SZ'

if IS_SELFSERVICE_MASTER:
	try:
		from univention.management.console.modules.udm.syntax import widget
		from univention.management.console.modules.udm.udm_ldap import UDM_Error, UDM_Module
		from univention.udm import UDM, NoObject
	except ImportError as exc:
		MODULE.error('Could not load udm module: %s' % (exc,))
		widget = None


def forward_to_master(func):