def getLdapConnection(): '''Create an LDAP connection and initialize UDM User and Group modules''' global lo, po, user_module, simpleauth_module, group_module lo, po = univention.admin.uldap.getAdminConnection() udm.update() user_module = udm.get('users/user') simpleauth_module = udm.get('users/ldap') group_module = udm.get('groups/group') udm.init(lo, po, user_module) udm.init(lo, po, simpleauth_module) udm.init(lo, po, group_module)
def _update_samba(self): forward_module = modules.get("dns/forward_zone") modules.init(self.ldap, self.position, forward_module) host_module = modules.get("dns/host_record") modules.init(self.ldap, self.position, host_module) forward_zones = forward_module.lookup(None, self.ldap, None) for zone in forward_zones: hosts = host_module.lookup(None, self.ldap, "name=gc._msdcs", superordinate=zone) for host in hosts: self._update_host(host)
def create_roleshare_on_server(role, school_ou, share_container_dn, serverfqdn, teacher_group=None, ucr=None, ldap_user_read=None, ldap_user_write=None, ldap_position=None): if not ucr: ucr = univention.config_registry.ConfigRegistry() ucr.load() if not teacher_group: teacher_groupname = '-'.join( (ucs_school_name_i18n(role_teacher), school_ou)) teacher_group = Group(name=teacher_groupname, school=school_ou).get_udm_object(ldap_user_read) if not teacher_group: raise univention.admin.uexceptions.noObject( 'Group not found: %s.' % teacher_groupname) else: teacher_groupname = teacher_group['name'] custom_groupname_domainadmins = custom_groupname('Domain Admins') try: udm_module_name = 'shares/share' udm_modules.init(ldap_user_write, ldap_position, udm_modules.get(udm_module_name)) share_container = udm_uldap.position(share_container_dn) udm_obj = udm_modules.get(udm_module_name).object( None, ldap_user_write, share_container) udm_obj.open() udm_obj.options = ['samba'] udm_obj['name'] = roleshare_name(role, school_ou, ucr) udm_obj['path'] = os.path.join('/home', roleshare_path(role, school_ou, ucr)) udm_obj['host'] = serverfqdn udm_obj['group'] = teacher_group['gidNumber'] udm_obj['sambaBrowseable'] = "0" udm_obj['sambaWriteable'] = "0" udm_obj['sambaValidUsers'] = '@"%s" @"%s"' % ( teacher_groupname, custom_groupname_domainadmins) udm_obj['sambaCustomSettings'] = [ ('admin users', '@"%s" @"%s"' % (teacher_groupname, custom_groupname_domainadmins)) ] udm_obj.create() except univention.admin.uexceptions.objectExists as exc: print 'Object exists: %s' % (exc.args[0], ) else: print 'Object created: %s' % _2utf8(udm_obj.dn)
def _find_forward_zone(self): forward_module = modules.get("dns/forward_zone") modules.init(self.ldap, self.position, forward_module) forward_zones = forward_module.lookup( None, self.ldap, "zone=%(domainname)s" % self.changeset.ucr) if forward_zones: return forward_zones[0].dn
def _attrs_for_easy_filter(cls): ret = [] module = udm_modules.get(cls._meta.udm_module) for key, prop in module.property_descriptions.iteritems(): if prop.include_in_default_search: ret.append(key) return ret
def _get_module(module, lo, pos): _update_modules() mod = udm_modules.get(module) if module not in _initialized: udm_modules.init(lo, pos, mod) _initialized.add(module) return mod
def from_udm(cls): univention.admin.modules.update() (ldap_connection, position) = univention.admin.uldap.getMachineConnection() module = udm_modules.get('mail/folder') for instance in module.lookup(None, ldap_connection, ''): instance.open() yield cls(instance)
def create_without_hooks(self, lo, validate): if self.exists(lo): return False logger.info('Creating %r', self) if validate: self.validate(lo) if self.errors: raise ValidationError(self.errors.copy()) pos = udm_uldap.position(ucr.get('ldap/base')) container = self.position if not container: logger.error('%r cannot determine a container. Unable to create!', self) return False try: pos.setDn(container) udm_obj = udm_modules.get(self._meta.udm_module).object( None, lo, pos, superordinate=self.get_superordinate(lo)) udm_obj.open() # here is the real logic self.do_create(udm_obj, lo) # get it fresh from the database (needed for udm_obj._exists ...) self.set_dn(self.dn) logger.info('%r successfully created', self) return True finally: self.invalidate_cache()
def get_object_real( self, module, dn ): if self._cached.has_key( dn ): return self._cached[ dn ] if isinstance( module, basestring ): if self._modules.has_key( module ): module = self._modules[ module ] else: name = module module = ua_modules.get( name ) ua_modules.init( self._access, self._position, module ) self._modules[ name ] = module elif module == None: module = self.identify( dn ) if not module: return None ua_modules.init( self._access, self._position, module ) new = ua_objects.get( module, self._config, self._access, position = self._position, dn = dn ) # if the object is not valid it should be displayed as an empty object try: new.open() except Exception, e: # write the traceback in the logfile import traceback ud.debug( ud.ADMIN, ud.ERROR, 'The object %s could not be opened' % dn ) try: tb = traceback.format_exc().encode( 'ascii', 'replace' ).replace( '%', '?' ) # this might fail because of problems with univention.debug ud.debug( ud.ADMIN, ud.ERROR, 'Traceback: %s' % tb ) except: pass
def _iterate_objects(self): for module_name, udm_property, replace_type in self.referers: module = modules.get(module_name) if not module: self.logger.debug("Unknown module '%s", module_name) continue self.logger.info("Processing %s", module_name) modules.init(self.ldap, self.position, module) yield module, udm_property, replace_type
def _find_reverse_zone(self): new_default = self.changeset.new_interfaces.get_default_ipv4_address() reverse_module = modules.get("dns/reverse_zone") modules.init(self.ldap, self.position, reverse_module) reverse_zones = reverse_module.lookup(None, self.ldap, None) for zone in reverse_zones: zone.open() # may be unneeded network = convert_udm_subnet_to_network(zone.info["subnet"]) if new_default in network: return zone.dn
def __set_users_module(): global users_module if users_module: return try: # get the users/user UDM module udm_modules.update() users_module = udm_modules.get('users/user') except udm_errors.base as e: # UDM error, user module coule not be initiated CORE.warn('An error occurred getting the UDM users/user module: %s' % e)
def _update_sso(self): forward_module = modules.get("dns/forward_zone") modules.init(self.ldap, self.position, forward_module) host_module = modules.get("dns/host_record") modules.init(self.ldap, self.position, host_module) sso_fqdn = self.changeset.ucr.get('ucs/server/sso/fqdn') forward_zones = forward_module.lookup(None, self.ldap, None) for forward_zone in forward_zones: zone = forward_zone.get('zone') if not sso_fqdn.endswith(zone): continue sso_name = sso_fqdn[:-(len(zone) + 1)] hosts = host_module.lookup(None, self.ldap, "relativeDomainName=%s" % sso_name, superordinate=forward_zone) for host in hosts: self._update_host(host)
def _update_reverse_zones(self, computer): reverse_module = modules.get("dns/reverse_zone") modules.init(self.ldap, self.position, reverse_module) reverse_zones = reverse_module.lookup(None, self.ldap, None) for zone in reverse_zones: zone.open() # may be unneeded computer.info["dnsEntryZoneReverse"] = [ [zone.dn, str(addr.ip)] for zone in reverse_zones for addr in (self.changeset.new_ipv4s + self.changeset.new_ipv6s) if addr.ip in convert_udm_subnet_to_network(zone.info["subnet"]) ]
def __initModule(self): self.module = None self.identifier = None if getattr(self, 'modname', None) is None: return self.module = umod.get(self.modname) if getattr(self, 'identifier', None) is None: descriptions = self.module.property_descriptions identifiers = [prop for prop in descriptions if descriptions[prop].identifies] if identifiers: self.identifier = identifiers[0]
def _remove_old_network(self): network_dn = "cn=default,cn=networks,%(ldap/base)s" % self.changeset.ucr network_module = modules.get("networks/network") modules.init(self.ldap, self.position, network_module) try: network = univention.admin.objects.get(network_module, None, self.ldap, self.position, network_dn) except noObject: return self.logger.info("Removing '%s'...", network_dn) if not self.changeset.no_act: network.remove()
def __initModule(self): self.module = None self.identifier = None if getattr(self, 'modname', None) is None: return self.module = umod.get(self.modname) if getattr(self, 'identifier', None) is None: descriptions = self.module.property_descriptions identifiers = [ prop for prop in descriptions if descriptions[prop].identifies ] if identifiers: self.identifier = identifiers[0]
def create(self, lo, validate=True): logger.info('Creating %r', self) pos = udm_uldap.position(ucr.get('ldap/base')) pos.setDn(self.position) udm_obj = udm_modules.get(self._meta.udm_module).object(None, lo, pos) udm_obj.open() udm_obj['name'] = self.name try: self.do_create(udm_obj, lo) except objectExists as exc: return exc.args[0] else: return udm_obj.dn
def _create_subnet(self): ipv4 = self.changeset.new_interfaces.get_default_ipv4_address() if not ipv4: return service_module = modules.get("dhcp/service") modules.init(self.ldap, self.position, service_module) subnet_module = modules.get("dhcp/subnet") modules.init(self.ldap, self.position, subnet_module) services = service_module.lookup(None, self.ldap, None) for service in services: subnet = subnet_module.object(None, self.ldap, service.position, superordinate=service) subnet.info["subnet"] = str(ipv4.network) subnet.info["subnetmask"] = str(ipv4.prefixlen) self.logger.info("Creating '%s' with '%r'...", subnet.position.getDn(), subnet.info) if not self.changeset.no_act: subnet.create()
def get_object_real(self, module, dn): if dn in self._cached: return self._cached[dn] if isinstance(module, basestring): if module in self._modules: module = self._modules[module] else: name = module module = ua_modules.get(name) ua_modules.init(self._access, self._position, module) self._modules[name] = module elif module is None: module = self.identify(dn) if not module: return None ua_modules.init(self._access, self._position, module) new = ua_objects.get(module, None, self._access, position=self._position, dn=dn) # if the object is not valid it should be displayed as an empty object try: new.open() except Exception: # write the traceback in the logfile import traceback ud.debug(ud.ADMIN, ud.ERROR, 'The object %s could not be opened' % dn) try: tb = traceback.format_exc().encode('ascii', 'replace').replace( '%', '?') # this might fail because of problems with univention.debug ud.debug(ud.ADMIN, ud.ERROR, 'Traceback: %s' % tb) except: pass for key, value in new.items(): from univention.directory.reports.document import Document if self._format in (Document.TYPE_LATEX, Document.TYPE_RML): i, j = self.format_property(new.descriptions, key, value) new.info[i] = j else: new.info[key] = value self._get_policies(new) self._cached[dn] = new return new
def get( self, name, template_object = None, force_reload = False, ldap_connection = None, ldap_position = None ): UDM_ModuleCache.lock.acquire() try: if name in self and not force_reload: return self[ name ] self[ name ] = udm_modules.get( name ) if self[ name ] is None: return None udm_modules.init( ldap_connection, ldap_position, self[ name ], template_object, force_reload=force_reload ) return self[ name ] finally: UDM_ModuleCache.lock.release()
def __init__( self, username, password ): global users_module self.__username = username self.__password = password self.__user_dn = None signals.Provider.__init__( self ) self.core_i18n = Translation( 'univention-management-console' ) self.i18n = I18N_Manager() self.i18n[ 'umc-core' ] = I18N() # stores the module processes [ modulename ] = <> self.__processes = {} self.__killtimer = {} lo = ldap.open( ucr[ 'ldap/server/name' ], int( ucr.get( 'ldap/server/port', 7389 ) ) ) try: # get LDAP connection with machine account self.lo, self.po = udm_uldap.getMachineConnection( ldap_master = False ) # get the LDAP DN of the authorized user ldap_dn = self.lo.searchDn( '(&(uid=%s)(objectClass=posixAccount))' % self.__username ) if ldap_dn: self.__user_dn = ldap_dn[ 0 ] CORE.info( 'The LDAP DN for user %s is %s' % ( self.__username, self.__user_dn ) ) else: CORE.info( 'The LDAP DN for user %s could not be found' % self.__username ) # initiate the users/user UDM module udm_modules.update() users_module = udm_modules.get('users/user') udm_modules.init(self.lo, self.po, users_module) except ( ldap.LDAPError, IOError ) as e: # problems connection to LDAP server or the server is not joined (machine.secret is missing) CORE.warn('An error occurred connecting to the LDAP server: %s' % e) self.lo = None users_module = None except udm_errors.base as e: # UDM error, user module coule not be initiated CORE.warn('An error occurred intializing the UDM users/user module: %s' % e) users_module = None # read the ACLs self.acls = LDAP_ACLs( self.lo, self.__username, ucr[ 'ldap/base' ] ) self.__command_list = moduleManager.permitted_commands( ucr[ 'hostname' ], self.acls ) self.signal_new( 'response' )
def child_modules( self ): """List of child modules""" if self.module is None: return None MODULE.info( 'Collecting child modules ...' ) children = getattr( self.module, 'childmodules', None ) if children is None: MODULE.info( 'No child modules were found' ) return [] modules = [] for child in children: mod = udm_modules.get( child ) if not mod: continue MODULE.info( 'Found module %s' % str( mod ) ) modules.append( { 'id' : child, 'label' : getattr( mod, 'short_description', child ) } ) return modules
def _get_policies(self, obj): dict = {} policies = self._access.getPolicies(obj.dn) for policy_oc, attrs in policies.items(): module_name = ua_objects.ocToType(policy_oc) module = ua_modules.get(module_name) if not module: continue for attr_name, value_dict in attrs.items(): dict[attr_name] = value_dict['value'] for key, value in ua_mapping.mapDict(module.mapping, dict).items(): if self._format: i, j = self.format_property(module.property_descriptions, key, value) obj.info[i] = j else: obj.info[key] = value
def get(self, name, template_object=None, force_reload=False, ldap_connection=None, ldap_position=None): UDM_ModuleCache.lock.acquire() try: if name in self and not force_reload: return self[name] module = udm_modules.get(name) if module is None: return None self[name] = module udm_modules.init(ldap_connection, ldap_position, self[name], template_object, force_reload=force_reload) return self[name] finally: UDM_ModuleCache.lock.release()
def _get_policies( self, obj ): dict={} policies = self._access.getPolicies( obj.dn ) for policy_oc, attrs in policies.items(): module_name = ua_objects.ocToType( policy_oc ) module = ua_modules.get( module_name ) if not module: continue for attr_name, value_dict in attrs.items(): dict[attr_name]=value_dict[ 'value' ] for key, value in ua_mapping.mapDict( module.mapping, dict ).items(): if self._format: i, j = self.format_property( module.property_descriptions, key, value ) obj.info[ i ] = j else: obj.info[ key ] = value
def child_modules(self): """List of child modules""" if self.module is None: return None MODULE.info('Collecting child modules ...') children = getattr(self.module, 'childmodules', None) if children is None: MODULE.info('No child modules were found') return [] modules = [] for child in children: mod = udm_modules.get(child) if not mod: continue MODULE.info('Found module %s' % str(mod)) modules.append({'id': child, 'label': getattr(mod, 'short_description', child)}) return modules
def restore_machine_password(role, ldap_connection): with open('/etc/machine.secret') as fob: password = fob.read().rstrip('\n') if not password: password = univention.lib.misc.createMachinePassword() with open('/etc/machine.secret', 'w') as fob: fob.write(password) computers = udm_modules.get('computers/{}'.format(role)) position = univention.admin.uldap.position(ldap_connection.base) udm_modules.init(ldap_connection, position, computers) filter_expr = ldap.filter.filter_format('(cn=%s)', (socket.gethostname(),)) for computer in computers.lookup(None, ldap_connection, filter_expr): MODULE.process('Restoring password of UDM computer object') computer.open() computer['password'] = password computer.modify()
def __init__(self, klass, meta=None): self.set_from_meta_object(meta, 'udm_module', None) self.set_from_meta_object(meta, 'udm_filter', '') self.set_from_meta_object(meta, 'name_is_unique', False) self.set_from_meta_object(meta, 'allow_school_change', False) udm_module_short = None if self.udm_module: udm_module_short = self.udm_module.split('/')[1] self.set_from_meta_object(meta, 'udm_module_short', udm_module_short) self.set_from_meta_object( meta, 'hook_path', udm_module_short) # default same as udm_module_short if self.udm_module: module = udm_modules.get(self.udm_module) if not module: # happens when the udm_module is not in the standard package # i.e. computers/ucc return for key, attr in klass._attributes.iteritems(): # sanity checks whether we specified everything correctly if attr.udm_name and not attr.extended: # extended? only available after module_init(lo) # we have to trust ourselved here if attr.udm_name not in module.property_descriptions: raise RuntimeError( '%s\'s attribute "%s" has no counterpart in the %s\'s property_descriptions ("%s")!' % (klass.__name__, key, self.udm_module, attr.udm_name)) udm_name = klass._attributes['name'].udm_name ldap_name = module.mapping.mapName(udm_name) self.ldap_name_part = ldap_name ldap_map_function = partial(module.mapping.mapValue, udm_name) self.ldap_map_function = ldap_map_function ldap_unmap_function = partial(module.mapping.unmapValue, module.mapping.mapName(udm_name)) self.ldap_unmap_function = ldap_unmap_function else: # this is to not let models fail when accessing obj.dn # note that without an udm_module it is not possible # to save an object self.ldap_name_part = 'cn' self.ldap_map_function = lambda name: name self.ldap_unmap_function = lambda name: name
def remove_object(udm_module_name, object_dn): listener.setuid(0) try: try: ldap_connection, ldap_position = udm_uldap.getAdminConnection() udm_modules.update() udm_module = udm_modules.get(udm_module_name) udm_modules.init(ldap_connection, ldap_position, udm_module) except udm_errors.ldapError as exc: ud.debug(ud.LISTENER, ud.ERROR, '%s: Error accessing UDM: %s' % (name, exc)) raise exc try: udm_object = udm_module.object(None, ldap_connection, ldap_position, object_dn) udm_object.remove() except (udm_errors.ldapError, udm_errors.noObject) as exc: ud.debug(ud.LISTENER, ud.ERROR, '%s: Error deleting %s: %s.' % (name, object_dn, exc)) raise exc finally: listener.unsetuid()
def groups_assign(self, request, ldap_user_read=None, ldap_position=None): """Assigns default rules to groups: request.options = [ { 'group': <groupDN>, 'rule': <ruleName> }, ... ] """ MODULE.info('internetrules.groups_assign: options: %s' % str(request.options)) # try to load all group rules newRules = {} rmRules = [] for ientry in request.options: # make sure the group exists igrp = udm_objects.get(udm_modules.get('groups/group'), None, ldap_user_read, ldap_position, ientry['group']) if not igrp: raise UMC_Error('unknown group object') igrp.open() # check the rule name irule = ientry['rule'] if irule == '$default$': # remove the rule rmRules.append(igrp['name']) else: try: # make sure the rule name is valid self._parseRule(dict(name=irule)) except ValueError as exc: raise UMC_Error(str(exc)) # add new rule newRules[igrp['name']] = irule # assign default filter rules to groups rules.setGroupRuleName(newRules) rules.unsetGroupRuleName(rmRules) MODULE.info('internetrules.groups_assign: finished') self.finished(request.id, True)
def _create_new_network(self, forward_zone, reverse_zone, dhcp_service): ipv4 = self.changeset.new_interfaces.get_default_ipv4_address() network_position = uldap.position(self.position.getDn()) network_position.setDn("cn=networks,%(ldap/base)s" % self.changeset.ucr) network_module = modules.get("networks/network") modules.init(self.ldap, self.position, network_module) network = network_module.object(None, self.ldap, network_position) network.info["name"] = "default" network.info["network"] = str(ipv4.network) network.info["netmask"] = str(ipv4.netmask) if forward_zone: network.info["dnsEntryZoneForward"] = forward_zone if reverse_zone: network.info["dnsEntryZoneReverse"] = reverse_zone if dhcp_service: network.info["dhcpEntryZone"] = dhcp_service self.logger.info("Creating '%s' with '%r'...", network.position.getDn(), network.info) if not self.changeset.no_act: network.create()
def mark_active(self): if self._todo_list: try: lo, ldap_position = udm_uldap.getAdminConnection() udm_modules.update() udm_module = udm_modules.get(self.udm_module_name) udm_modules.init(lo, ldap_position, udm_module) for object_dn in self._todo_list: try: udm_object = udm_module.object(None, lo, ldap_position, object_dn) udm_object.open() udm_object['active'] = True udm_object.modify() except udm_errors.noObject as e: ud.debug(ud.LISTENER, ud.ERROR, 'Error modifying %s: object not found.' % (object_dn,)) except udm_errors.ldapError as e: ud.debug(ud.LISTENER, ud.ERROR, 'Error modifying %s: %s.' % (object_dn, e)) raise self._todo_list = [] except udm_errors.ldapError as e: ud.debug(ud.LISTENER, ud.ERROR, 'Error accessing UDM: %s' % (e,))
def get_object_real(self, module, dn): if self._cached.has_key(dn): return self._cached[dn] if isinstance(module, basestring): if self._modules.has_key(module): module = self._modules[module] else: name = module module = ua_modules.get(name) ua_modules.init(self._access, self._position, module) self._modules[name] = module elif module == None: module = self.identify(dn) if not module: return None ua_modules.init(self._access, self._position, module) new = ua_objects.get(module, self._config, self._access, position=self._position, dn=dn) # if the object is not valid it should be displayed as an empty object try: new.open() except Exception, e: # write the traceback in the logfile import traceback ud.debug(ud.ADMIN, ud.ERROR, 'The object %s could not be opened' % dn) try: tb = traceback.format_exc().encode('ascii', 'replace').replace( '%', '?') # this might fail because of problems with univention.debug ud.debug(ud.ADMIN, ud.ERROR, 'Traceback: %s' % tb) except: pass
def _get_module(self): modules.update() module_name = "computers/%(server/role)s" % self.changeset.ucr self.module = modules.get(module_name) modules.init(self.ldap, self.position, self.module)
def handler(dn, new, old): """Handle UDM extension modules""" if new: ocs = new.get('objectClass', []) univentionUCSVersionStart = new.get('univentionUCSVersionStart', [b''])[0].decode('UTF-8') univentionUCSVersionEnd = new.get('univentionUCSVersionEnd', [b''])[0].decode('UTF-8') elif old: ocs = old.get('objectClass', []) if b'univentionUDMModule' in ocs: objectclass = 'univentionUDMModule' udm_module_name = 'settings/udm_module' target_subdir = 'univention/admin/handlers' elif b'univentionUDMHook' in ocs: objectclass = 'univentionUDMHook' udm_module_name = 'settings/udm_hook' target_subdir = 'univention/admin/hooks.d' elif b'univentionUDMSyntax' in ocs: objectclass = 'univentionUDMSyntax' udm_module_name = 'settings/udm_syntax' target_subdir = 'univention/admin/syntax.d' else: ud.debug( ud.LISTENER, ud.ERROR, '%s: Undetermined error: unknown objectclass: %s.' % (name, ocs)) # Bug #51622 for UCS 5.0 update: if new and not old: if listener.configRegistry.get( 'server/role') == 'domaincontroller_master': # Remove objects that don't signal Python3 support cmp_start_vs_50 = apt.apt_pkg.version_compare( univentionUCSVersionStart, "5.0") # -1 if univentionUCSVersionStart is unset # cmp_end_vs_499 = apt.apt_pkg.version_compare(univentionUCSVersionEnd, "4.99") # Keep object if cmp_start_vs_50 >= 0 [i.e. Py3] or (cmp_start_vs_50 < and univentionUCSVersionEnd) [or cmp_end_vs_499 == 0] # Otherwise remove it: if cmp_start_vs_50 < 0 and not univentionUCSVersionEnd: ud.debug( ud.LISTENER, ud.WARN, '%s: Removing incompatible extension %s (univentionUCSVersionStart=%r and univentionUCSVersionEnd not set).' % (name, new['cn'][0].decode('UTF-8'), univentionUCSVersionStart)) remove_object(udm_module_name, dn) return if new: current_UCS_version = "%s-%s" % ( listener.configRegistry.get('version/version'), listener.configRegistry.get('version/patchlevel')) if univentionUCSVersionStart and UCS_Version( current_UCS_version) < UCS_Version(univentionUCSVersionStart): ud.debug( ud.LISTENER, ud.INFO, '%s: extension %s requires at least UCS version %s.' % (name, new['cn'][0].decode('UTF-8'), univentionUCSVersionStart)) # Trigger remove on this system old = old or new new = None elif univentionUCSVersionEnd and UCS_Version( current_UCS_version) > UCS_Version(univentionUCSVersionEnd): ud.debug( ud.LISTENER, ud.INFO, '%s: extension %s specifies compatibility only up to and including UCR version %s.' % (name, new['cn'][0].decode('UTF-8'), univentionUCSVersionEnd)) # Trigger remove on this system old = old or new new = None old_relative_filename = None if old: old_relative_filename = old['%sFilename' % objectclass][0].decode('UTF-8') if new: new_version = new.get('univentionOwnedByPackageVersion', [b''])[0].decode('UTF-8') if not new_version: return new_pkgname = new.get('univentionOwnedByPackage', [None])[0] if not new_pkgname: return if old: # check for trivial changes diff_keys = [ key for key in new.keys() if new.get(key) != old.get(key) and key not in ( 'entryCSN', 'modifyTimestamp', 'modifiersName') ] if diff_keys == ['%sActive' % objectclass] and new.get( '%sActive' % objectclass)[0] == b'TRUE': ud.debug( ud.LISTENER, ud.INFO, '%s: %s: activation status changed.' % (name, new['cn'][0])) return elif diff_keys == ['univentionAppIdentifier']: ud.debug( ud.LISTENER, ud.INFO, '%s: %s: App identifier changed.' % (name, new['cn'][0].decode('UTF-8'))) return if new_pkgname == old.get('univentionOwnedByPackage', [None])[0]: old_version = old.get('univentionOwnedByPackageVersion', [b'0'])[0].decode('UTF-8') rc = apt.apt_pkg.version_compare(new_version, old_version) if not rc > -1: ud.debug( ud.LISTENER, ud.WARN, '%s: New version is lower than version of old object (%s), skipping update.' % (name, old_version)) return # ok, basic checks passed, handle the data try: new_object_data = bz2.decompress( new.get('%sData' % objectclass)[0]) except TypeError: ud.debug(ud.LISTENER, ud.ERROR, '%s: Error uncompressing data of object %s.' % (name, dn)) return new_relative_filename = new['%sFilename' % objectclass][0].decode('UTF-8') listener.setuid(0) try: if old_relative_filename and old_relative_filename != new_relative_filename: remove_python_file(objectclass, target_subdir, old_relative_filename) if not install_python_file(objectclass, target_subdir, new_relative_filename, new_object_data): return install_messagecatalog(dn, new, objectclass) install_umcmessagecatalogs(new, old) if objectclass == 'univentionUDMModule': install_umcregistration(dn, new) install_umcicons(dn, new) finally: listener.unsetuid() elif old: # ok, basic checks passed, handle the change listener.setuid(0) try: remove_python_file(objectclass, target_subdir, old_relative_filename) remove_messagecatalog(dn, old, objectclass) remove_umcmessagecatalogs(old) if objectclass == 'univentionUDMModule': remove_umcicons(dn, old) remove_umcregistration(dn, old) finally: listener.unsetuid() # TODO: Kill running univention-cli-server? # Mark new extension object active listener.setuid(0) try: if new: if not listener.configRegistry.get( 'server/role') == 'domaincontroller_master': # Only set active flag on Primary return try: lo, ldap_position = udm_uldap.getAdminConnection() udm_modules.update() udm_module = udm_modules.get(udm_module_name) udm_modules.init(lo, ldap_position, udm_module) try: udm_object = udm_module.object(None, lo, ldap_position, dn) udm_object.open() udm_object['active'] = True udm_object.modify() except udm_errors.ldapError as exc: ud.debug(ud.LISTENER, ud.ERROR, '%s: Error modifying %s: %s.' % (name, dn, exc)) except udm_errors.noObject as exc: ud.debug(ud.LISTENER, ud.ERROR, '%s: Error modifying %s: %s.' % (name, dn, exc)) except udm_errors.ldapError as exc: ud.debug(ud.LISTENER, ud.ERROR, '%s: Error accessing UDM: %s' % (name, exc)) finally: listener.unsetuid()
def test_script_lock_expired_accounts(stopped_s4_connector, udm): # TODO: parametrize """Check cron job script lock_expired_accounts""" # bugs: [35088] print(time.ctime()) udm_modules.update() lo, position = univention.admin.uldap.getAdminConnection() udm_modules.init(lo, position, udm_modules.get('users/user')) def create_user(expiry_days_delta, locked_status): expiry_time = datetime.utcnow() + timedelta(days=expiry_days_delta) userdn, username = udm.create_user( userexpiry=expiry_time.strftime("%Y-%m-%d"), check_for_drs_replication=False, wait_for=False) if locked_status == '1': locktime = time.strftime("%Y%m%d%H%M%SZ", time.gmtime()) subprocess.check_call([ '/usr/bin/python2.7', '-m', 'univention.lib.account', 'lock', '--dn', userdn, '--lock-time', locktime ]) return username userdata = {} for delta, initial_state, expected_state in [ [-9, '0', '0'], [-8, '0', '0'], # [-7, '0', '0'], disabled due to bug #36210 # [-6, '0', '1'], disabled due to bug #36210 [-5, '0', '1'], [-4, '0', '1'], [-3, '0', '1'], [-2, '0', '1'], [-1, '0', '1'], # [0, '0', '1'], disabled due to bug #36210 [1, '0', '0'], [2, '0', '0'], [-4, '1', '1'], # [0, '1', '1'], disabled due to bug #36210 [2, '1', '1'], ]: userdata[create_user(delta, initial_state)] = [initial_state, expected_state] ldap_filter = '(|(uid=' + ')(uid='.join(userdata.keys()) + '))' results = udm_modules.lookup('users/user', None, lo, scope='sub', filter=ldap_filter) if len(results) != len(userdata): print('RESULTS: %r' % (pprint.PrettyPrinter(indent=2).pformat(results), )) utils.fail('Did not find all users prior to script execution!') for entry in results: entry.open() if not entry['locked'] == userdata[entry['username']][0]: utils.fail( 'uid=%s should not be locked for posix prior to script execution!' % (entry['username'], )) print('Calling lock_expired_accounts...') subprocess.check_call([ '/usr/share/univention-directory-manager-tools/lock_expired_accounts', '--only-last-week' ]) print('DONE') results = udm_modules.lookup('users/user', None, lo, scope='sub', filter=ldap_filter) if len(results) != len(userdata): print('RESULTS: %r' % (pprint.PrettyPrinter(indent=2).pformat(results), )) utils.fail('Did not find all users after script execution!') for entry in results: entry.open() if not entry['locked'] == userdata[entry['username']][1]: utils.fail( 'The account uid=%r is not in expected locking state: expected=%r current=%r' % (entry['username'], userdata[entry['username']][1], entry['locked']))