Пример #1
0
    def _check_usersid_join_permissions(self, lo, usersid):
        allowed_groups = ucr.get('ucsschool/windows/join/groups',
                                 'Domain Admins').split(',')

        result = lo.searchDn(
            ldap.filter.filter_format('sambaSID=%s', [usersid]))
        if not result:
            raise UMC_Error('SID %s was not found.' % (usersid, ))

        user_dn = result[0]
        MODULE.info("Found user with DN %s" % (user_dn, ))

        result = lo.search(ldap.filter.filter_format('uniqueMember=%s',
                                                     [user_dn]),
                           attr=['cn'])
        if not result:
            raise UMC_Error('No group memberships for SID %s found.' %
                            (usersid, ))

        for dn, attr in result:
            if attr.get('cn', [])[0] in allowed_groups:
                return

        raise UMC_Error(
            'SID %s is not member of one of the following groups: %s. The allowed groups can be modified by setting the UCR variable ucsschool/windows/join/groups.'
            % (usersid, allowed_groups))
    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
Пример #3
0
 def _change_services(self, services, action):
     error_messages = []
     for srv in services:
         process = subprocess.Popen(('/usr/sbin/service', srv, action),
                                    stdout=subprocess.PIPE,
                                    stderr=subprocess.STDOUT)
         output = process.communicate()[0]
         if process.returncode:
             try:
                 MODULE.warn('Error during %s of %s: %s' %
                             (action, srv, output.strip()))
                 process = subprocess.Popen(
                     ('/bin/systemctl', 'status', srv),
                     stdout=subprocess.PIPE,
                     stderr=subprocess.STDOUT)
                 output = process.communicate()[0]
             except EnvironmentError:
                 pass
             error_messages.append(
                 '%s\n%s' %
                 ({
                     'start': _('Starting the service %s failed:'),
                     'stop': _('Stopping the service %s failed:'),
                     'restart': _('Restarting the service %s failed:'),
                 }[action] % srv, output.strip()))
     if error_messages:
         raise UMC_Error('\n\n'.join(error_messages))
     return {'success': True}
	def add(self, request):
		# does the same as put
		ucr.load()
		already_set = set(ucr.keys()) & set(v['object']['key'] for v in request.options)
		if already_set:
			raise UMC_Error(_('The UCR variable %s is already set.') % ('", "'.join(already_set)))

		self.put(request)
	def remove(self, request):
		variables = [x for x in [x.get('object') for x in request.options] if x is not None]
		for var in variables:
			if self.is_readonly(var):
				raise UMC_Error(_('The UCR variable %s is read-only and can not be removed!') % (var,))

		handler_unset(variables)
		self.finished(request.id, True)
	def _change_start_type(self, service_names, start_type):
		service_info = ServiceInfo()
		services = [(service_name, service_info.services[service_name]) for service_name in service_names if service_name in service_info.services]
		values = ['%s=%s' % (service.get('start_type', '%s/autostart' % (service_name,)), start_type) for service_name, service in services]
		univention.config_registry.handler_set(values)
		failed = [x for x in service_names if not service_info.services.get(x)]
		if failed:
			raise UMC_Error('%s %s' % (_('Could not change start type of the following services:'), ', '.join(failed)))
Пример #7
0
	def _check_error(self, request, partition_name):  # TODO
		try:
			fs = fstab.File()
			mt = mtab.File()
		except IOError as error:
			MODULE.error('Could not open %s' % error.filename)
			raise ValueError(_('Could not open %s') % error.filename)

		partition = fs.find(spec=partition_name)
		if partition:
			mounted_partition = mt.get(partition.spec)
			if mounted_partition:
				if 'usrquota' not in mounted_partition.options and 'usrjquota=aquota.user' not in mounted_partition.options:
					raise UMC_Error(_('The following partition is mounted without quota support: %s') % partition_name)
			else:
				raise UMC_Error(_('The following partition is currently not mounted: %s') % partition_name)
		else:
			raise UMC_Error(_('No partition found (%s)') % partition_name)
Пример #8
0
 def get(self, request):
     """get a specific item of self.data"""
     try:
         item = self.data[request.options['item']]
     except IndexError:
         MODULE.error('A invalid item was accessed.')
         raise UMC_Error(_('The item %d does not exists.') %
                         (request.options['item'], ),
                         status=400)
     self.finished(request.id, self.data[item])
Пример #9
0
    def create_windows_computer(self,
                                request,
                                ldap_user_read=None,
                                ldap_admin_write=None,
                                ldap_position=None,
                                search_base=None):

        if not search_base.school:
            raise UMC_Error(_('Could not determine schoolOU.'))

        # Set new position
        ldap_position.setDn(search_base.computers)

        self._check_usersid_join_permissions(ldap_user_read,
                                             request.options.get('usersid'))

        # Create the computer account
        computer = univention.admin.handlers.computers.windows.object(
            None, ldap_admin_write, position=ldap_position, superordinate=None)
        computer.open()
        name = request.options.get('name')
        if name[-1] == '$':
            # Samba 3 calls the name in this way
            name = name[:-1]

        # In Samba 3 the samba attributes must be set by Samba itself
        samba3_mode = request.options.get('samba3_mode')
        if samba3_mode and samba3_mode.lower() in ['true', 'yes']:
            computer.options = ['posix']

        computer['name'] = name

        password = request.options.get('password')
        if password:
            decode_password = request.options.get('decode_password')
            if decode_password and decode_password.lower() in ['true', 'yes']:
                # the password is base64 encoded
                password = base64.decodestring(password)
                # decode from utf-16le
                password = password.decode('utf-16le')
                # and remove the quotes
                password = password.strip('"')
            computer['password'] = password

        computer['description'] = request.options.get('description')
        try:
            computer_dn = computer.create()
            already_exists = False
        except univention.admin.uexceptions.objectExists as exc:
            already_exists = True
            computer_dn = exc.args[0]
        self.finished(request.id, {
            'dn': computer_dn,
            'already_exists': already_exists
        })
Пример #10
0
    def remove(self, request):
        variables = filter(lambda x: x is not None,
                           map(lambda x: x.get('object'), request.options))
        for var in variables:
            if self.is_readonly(var):
                raise UMC_Error(
                    _('The UCR variable %s is read-only and can not be removed!'
                      ) % (var, ))

        handler_unset(variables)
        self.finished(request.id, True)
	def put(self, request):
		for _var in request.options:
			var = _var['object']
			value = var['value'] or ''
			key = var['key']
			if self.is_readonly(key):
				raise UMC_Error(_('The UCR variable %s is read-only and can not be changed!') % (key,))
			arg = ['%s=%s' % (key.encode(), value.encode())]
			handler_set(arg)

			# handle descriptions, type, and categories
			if 'descriptions' in var or 'type' in var or 'categories' in var:
				self.__create_variable_info(var)
		self.finished(request.id, True)
Пример #12
0
		def _thread(request):
			partition = request.options['partitionDevice']
			user = request.options['user']
			if isinstance(user, unicode):
				user = user.encode('utf-8')

			size_soft = request.options['sizeLimitSoft']
			size_hard = request.options['sizeLimitHard']
			file_soft = request.options['fileLimitSoft']
			file_hard = request.options['fileLimitHard']
			self._check_error(request, partition)

			if tools.setquota(partition, user, tools.byte2block(size_soft), tools.byte2block(size_hard), file_soft, file_hard):
				raise UMC_Error(_('Failed to modify quota settings for user %(user)s on partition %(partition)s.') % {'user': user, 'partition': partition})

			return {'objects': [], 'success': True}
Пример #13
0
	def _enable_ssl_and_test_connection(self, certificate_fname=None):
		with ucr_rollback(ucr, ['connector/ad/ldap/ssl', 'connector/ad/ldap/certificate']):
			if certificate_fname:
				univention.config_registry.handler_set([u'connector/ad/ldap/certificate=%s' % certificate_fname])
			server = ucr.get('connector/ad/ldap/host')
			if server:
				success = False
				if admember.server_supports_ssl(server):
					admember.enable_ssl()
					try:
						success = test_connection()
					except ADNotAvailable:
						success = False
				if not success:
					raise UMC_Error(_('Could not establish an encrypted connection. Either "%r" is not reachable or does not support encryption.') % server)
			else:
				MODULE.warn('connector is not configured yet, cannot test connection')
Пример #14
0
    def load(self, request):
        user, mailbox = getUserAndMailbox(self._user_dn)
        raise UMC_Error("Es wurde kein Asterisk-Server angelegt!")
        result = {
            "phones/interval": user["ringdelay"],
            "forwarding/number": user.get("forwarding", ""),
            "mailbox/timeout": user["timeout"],
            "mailbox": False,
        }

        if mailbox:
            result.update({
                "mailbox": True,
                "mailbox/password": mailbox["password"],
                "mailbox/email": mailbox["email"],
            })

        self.finished(request.id, result)
    def _change_services(self, services, action):
        error_messages = []
        srvs = ServiceInfo()
        for srv in services:
            service = srvs.get_service(srv)
            try:
                getattr(service, action)()
            except ServiceError as exc:
                MODULE.warn('Error during %s of %s: %s' % (action, srv, exc))
                error_messages.append(
                    '%s\n%s' %
                    ({
                        'start': _('Starting the service %s failed:'),
                        'stop': _('Stopping the service %s failed:'),
                        'restart': _('Restarting the service %s failed:'),
                    }[action] % srv, exc))

        if error_messages:
            raise UMC_Error('\n\n'.join(error_messages))
        return {'success': True}
Пример #16
0
	def delete_user(self, request, ldap_user_read=None, ldap_user_write=None, ldap_admin_write=None):
		# Bug #44641: workaround with security implications!
		if ucr.is_true('ucsschool/wizards/schoolwizards/workaround/admin-connection'):
			ldap_user_write = ldap_admin_write

		ret = []
		for obj_props in request.options:
			obj_props = obj_props['object']
			try:
				obj = User.from_dn(obj_props['$dn$'], None, ldap_user_write)
			except noObject:
				raise UMC_Error(_('The %s %r does not exists or might have been removed in the meanwhile.') % (getattr(User, 'type_name', None) or User.__name__, User.get_name_from_dn(obj_props['$dn$'])))
			school = obj_props['remove_from_school']
			success = obj.remove_from_school(school, ldap_user_write)
			# obj.old_dn is None when the ucsschool lib has deleted the user after the last school was removed from it
			if success and obj.old_dn is not None:
				success = obj.modify(ldap_user_write)
			if not success:
				success = {'result': {'message': _('Failed to remove user from school.')}}
			ret.append(success)
		return ret
	def get(self, request):
		ucrReg = ConfigRegistry()
		ucrReg.load()
		ucrInfo = ConfigRegistryInfo(registered_only=False)

		# iterate over all requested variables
		results = []
		for key in request.options:
			info = ucrInfo.get_variable(str(key))
			value = ucrReg.get(str(key))
			if not info and (value or '' == value):
				# only the value available
				results.append({'key': key, 'value': value})
			elif info:
				# info (categories etc.) available
				info['value'] = value
				info['key'] = key
				results.append(info.normalize())
			else:
				# variable not available, request failed
				raise UMC_Error(_('The UCR variable %(key)s could not be found') % {'key': key})
		self.finished(request.id, results)
Пример #18
0
def iter_objects_in_request(request, lo, require_dn=False):
	klass = {
		'schoolwizards/schools': School,
		'schoolwizards/users': User,
		'schoolwizards/computers': SchoolComputer,
		'schoolwizards/classes': SchoolClass,
	}[request.flavor]
	for obj_props in request.options:
		obj_props = obj_props['object']
		for key, value in obj_props.iteritems():
			if isinstance(value, basestring):
				obj_props[key] = value.strip()
		if issubclass(klass, User):
			klass = USER_TYPES.get(obj_props.get('type'), User)
		elif issubclass(klass, SchoolComputer):
			klass = COMPUTER_TYPES.get(obj_props.get('type'), SchoolComputer)
		dn = obj_props.get('$dn$')
		if 'name' not in obj_props:
			# important for get_school in district_mode!
			obj_props['name'] = klass.get_name_from_dn(dn)
		if issubclass(klass, SchoolClass):
			# workaround to be able to reuse this function everywhere
			obj_props['name'] = '%s-%s' % (obj_props['school'], obj_props['name'])
		if require_dn:
			try:
				obj = klass.from_dn(dn, obj_props.get('school'), lo)
			except noObject:
				raise UMC_Error(_('The %s %r does not exists or might have been removed in the meanwhile.') % (getattr(klass, 'type_name', klass.__name__), obj_props['name']))
			for key, value in obj_props.iteritems():
				if key in obj._attributes:
					setattr(obj, key, value)
		else:
			obj = klass(**obj_props)
		if dn:
			obj.old_dn = dn
		yield obj
Пример #19
0
	def get_schoolinfo_master(self, school):
		"""
		Fetches LDAP information from master about specified OU.
		This function assumes that the given arguments have already been validated!
		"""

		school_name = school
		try:
			lo, po = get_machine_connection(write=True)
			school = School.from_dn(School(name=school_name).dn, None, lo)
		except noObject:
			exists = False
			class_share_server = None
			home_share_server = None
			educational_slaves = []
			administrative_slaves = []
		except ldap.SERVER_DOWN:
			raise  # handled via UMC
		except ldap.LDAPError as exc:
			MODULE.warn('LDAP error during receiving school info: %s' % (exc,))
			raise UMC_Error(_('The LDAP connection to the master system failed.'))
		else:
			exists = True
			class_share_server = school.class_share_file_server
			home_share_server = school.home_share_file_server
			educational_slaves = [SchoolDCSlave.from_dn(dn, None, lo).name for dn in school.educational_servers]
			administrative_slaves = [SchoolDCSlave.from_dn(dn, None, lo).name for dn in school.administrative_servers]

		return {
			'exists': exists,
			'school': school_name,
			'classShareServer': class_share_server,
			'homeShareServer': home_share_server,
			'educational_slaves': educational_slaves,
			'administrative_slaves': administrative_slaves,
		}