commit 531d91ac6f50e201108dd151475c0c8051e9e3f3 Author: Florian Best Date: Wed Oct 11 16:27:19 2017 +0200 Bug #43129: make mapping/unmapping for extended attributes configurable diff --git a/management/univention-directory-manager-modules/modules/univention/admin/handlers/settings/extended_attribute.py b/management/univention-directory-manager-modules/modules/univention/admin/handlers/settings/extended_attribute.py index 9d404fa..a3656e3 100644 --- a/management/univention-directory-manager-modules/modules/univention/admin/handlers/settings/extended_attribute.py +++ b/management/univention-directory-manager-modules/modules/univention/admin/handlers/settings/extended_attribute.py @@ -378,6 +378,28 @@ identifies=False, copyable=True, ), + 'mapMethod': univention.admin.property( + short_description=_('Map method'), + long_description=_('Defines a custom UDM property to LDAP attribute mapping method.'), + syntax=univention.admin.syntax.string, + multivalue=False, + options=[], + required=False, + may_change=True, + identifies=False, + copyable=True, + ), + 'unmapMethod': univention.admin.property( + short_description=_('Unmap method'), + long_description=_('Defines a custom LDAP attribute to UDM property mapping method.'), + syntax=univention.admin.syntax.string, + multivalue=False, + options=[], + required=False, + may_change=True, + identifies=False, + copyable=True, + ), } layout = [ @@ -425,6 +447,7 @@ ]), Tab(_('Data type'), _('Data type definition'), layout=[ ["syntax", "default"], + ["mapMethod", "unmapMethod"], ["multivalue"], ["valueRequired"], ["mayChange"], @@ -459,6 +482,8 @@ mapping.register('notEditable', 'univentionUDMPropertyValueNotEditable', None, univention.admin.mapping.ListToString) mapping.register('doNotSearch', 'univentionUDMPropertyDoNotSearch', None, univention.admin.mapping.ListToString) mapping.register('copyable', 'univentionUDMPropertyCopyable', None, univention.admin.mapping.ListToString) +mapping.register('mapMethod', 'univentionUDMPropertyMapMethod', None, univention.admin.mapping.ListToString) +mapping.register('unmapMethod', 'univentionUDMPropertyUnMapMethod', None, univention.admin.mapping.ListToString) mapping.register('version', 'univentionUDMPropertyVersion', None, univention.admin.mapping.ListToString) mapping.register('CLIName', 'univentionUDMPropertyCLIName', None, univention.admin.mapping.ListToString) mapping.register('options', 'univentionUDMPropertyOptions') diff --git a/management/univention-directory-manager-modules/modules/univention/admin/modules.py b/management/univention-directory-manager-modules/modules/univention/admin/modules.py index 7c1b42b..cc735d7 100644 --- a/management/univention-directory-manager-modules/modules/univention/admin/modules.py +++ b/management/univention-directory-manager-modules/modules/univention/admin/modules.py @@ -311,21 +311,27 @@ def update_extended_attributes(lo, module, position): ud.debug(ud.ADMIN, ud.ERROR, 'modules update_extended_attributes: ERROR: processing univentionUDMPropertyDoNotSearch throwed exception - assuming doNotSearch=0') doNotSearch = 0 + map_method = '' + unmap_method = '' + # check if CA is multivalue property - if attrs.get('univentionUDMPropertyMultivalue', [''])[0] == '1': - multivalue = 1 - map_method = None - unmap_method = None - else: - multivalue = 0 - map_method = univention.admin.mapping.ListToString - unmap_method = None + multivalue = attrs.get('univentionUDMPropertyMultivalue', [''])[0] == '1' + if not multivalue: + map_method = 'ListToString' if propertySyntaxString == 'boolean': - map_method = univention.admin.mapping.BooleanListToString - unmap_method = univention.admin.mapping.BooleanUnMap + map_method = 'BooleanListToString' + unmap_method = 'BooleanUnMap' # single value ==> use only first value propertyDefault = propertyDefault[0] + # extended attribute for objectClass should not be mapped to any attribute/property + if attrs['univentionUDMPropertyLdapMapping'][0].lower() == 'objectClass'.lower(): + map_method = 'nothing' + unmap_method = 'nothing' + + map_method = getattr(univention.admin.mapping, attrs.get('univentionUDMPropertyMapMethod', [map_method])[0], None) + unmap_method = getattr(univention.admin.mapping, attrs.get('univentionUDMPropertyUnMapMethod', [unmap_method])[0], None) + # Show this attribute in UDM/UMC? if attrs.get('univentionUDMPropertyLayoutDisable', [''])[0] == '1': layoutDisabled = True @@ -363,10 +369,7 @@ def update_extended_attributes(lo, module, position): ) # add LDAP mapping - if attrs['univentionUDMPropertyLdapMapping'][0].lower() != 'objectClass'.lower(): - module.mapping.register(pname, attrs['univentionUDMPropertyLdapMapping'][0], unmap_method, map_method) - else: - module.mapping.register(pname, attrs['univentionUDMPropertyLdapMapping'][0], univention.admin.mapping.nothing, univention.admin.mapping.nothing) + module.mapping.register(pname, attrs['univentionUDMPropertyLdapMapping'][0], unmap_method, map_method) if hasattr(module, 'layout'): tabname = attrs.get('univentionUDMPropertyTranslationTabName;entry-%s' % lang, attrs.get('univentionUDMPropertyLayoutTabName', [_('Custom')]))[0] diff --git a/management/univention-ldap/schema/custom-attribute.schema b/management/univention-ldap/schema/custom-attribute.schema index 6149e4f..e7f0216 100644 --- a/management/univention-ldap/schema/custom-attribute.schema +++ b/management/univention-ldap/schema/custom-attribute.schema @@ -291,6 +291,18 @@ attributetype ( 1.3.6.1.4.1.10176.200.131 NAME 'univentionUDMPropertyCopyable' SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE) +attributetype ( 1.3.6.1.4.1.10176.200.132 NAME 'univentionUDMPropertyMapMethod' + DESC 'defines the UDM property to LDAP attribute mapping method' + EQUALITY caseIgnoreMatch + SUBSTR caseIgnoreSubstringsMatch + SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE) + +attributetype ( 1.3.6.1.4.1.10176.200.133 NAME 'univentionUDMPropertyUnMapMethod' + DESC 'defines the LDAP attribute to UDM property mapping method' + EQUALITY caseIgnoreMatch + SUBSTR caseIgnoreSubstringsMatch + SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE) + objectclass ( 1.3.6.1.4.1.10176.200.199 NAME 'univentionUDMProperty' @@ -327,6 +339,8 @@ objectclass ( 1.3.6.1.4.1.10176.200.199 univentionUDMPropertyTranslationGroupName $ univentionUDMPropertyLayoutGroupPosition $ univentionUDMPropertyLayoutDisable $ + univentionUDMPropertyMapMethod $ + univentionUDMPropertyUnMapMethod $ univentionUDMPropertyCopyable ) ) commit 138d61da1c10e3aacbffd013cb6424ea0c2f8a04 Author: Florian Best Date: Wed Oct 11 16:35:47 2017 +0200 Bug #43129: add loading of mapping.d diff --git a/management/univention-directory-manager-modules/debian/python-univention-directory-manager.install b/management/univention-directory-manager-modules/debian/python-univention-directory-manager.install index 44529cc..6306bf5 100644 --- a/management/univention-directory-manager-modules/debian/python-univention-directory-manager.install +++ b/management/univention-directory-manager-modules/debian/python-univention-directory-manager.install @@ -15,6 +15,7 @@ modules/univention/admin/handlers/computers/*.py usr/share/pyshared/univention/a modules/univention/admin/handlers/kerberos/*.py usr/share/pyshared/univention/admin/handlers/kerberos/ modules/univention/admin/syntax.d/*.py usr/share/pyshared/univention/admin/syntax.d/ modules/univention/admin/hooks.d/*.py usr/share/pyshared/univention/admin/hooks.d/ +modules/univention/admin/mapping.d/*.py usr/share/pyshared/univention/admin/mapping.d/ python-lib/*.py usr/share/pyshared/univention/lib listener/*.py usr/lib/univention-directory-listener/system/ 18python-univention-directory-manager.inst usr/lib/univention-install/ diff --git a/management/univention-directory-manager-modules/modules/univention/admin/__init__.py b/management/univention-directory-manager-modules/modules/univention/admin/__init__.py index e3c6164..823de38 100644 --- a/management/univention-directory-manager-modules/modules/univention/admin/__init__.py +++ b/management/univention-directory-manager-modules/modules/univention/admin/__init__.py @@ -513,6 +513,7 @@ def __init__(self, id, short_description=None, long_description='', members=[]): from univention.admin import modules, objects, syntax, hook, mapping syntax.import_syntax_files() hook.import_hook_files() +mapping.import_mapping_files() if __name__ == '__main__': prop = property('_replace') diff --git a/management/univention-directory-manager-modules/modules/univention/admin/mapping.d/__init__.py b/management/univention-directory-manager-modules/modules/univention/admin/mapping.d/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/management/univention-directory-manager-modules/modules/univention/admin/mapping.py b/management/univention-directory-manager-modules/modules/univention/admin/mapping.py index 2724829..d20ea1d 100644 --- a/management/univention-directory-manager-modules/modules/univention/admin/mapping.py +++ b/management/univention-directory-manager-modules/modules/univention/admin/mapping.py @@ -33,6 +33,27 @@ import univention.debug import types import base64 +import traceback +import sys +import os + + +def import_mapping_files(): + for dir_ in sys.path: + mapping_py = os.path.join(dir_, 'univention/admin/mapping.py') + mapping_d = os.path.join(dir_, 'univention/admin/mapping.d/') + + if os.path.exists(mapping_py) and os.path.isdir(mapping_d): + mapping_files = (os.path.join(mapping_d, f) for f in os.listdir(mapping_d) if f.endswith('.py')) + + for fn in mapping_files: + try: + with open(fn, 'r') as fd: + exec fd in sys.modules[__name__].__dict__ + univention.debug.debug(univention.debug.ADMIN, univention.debug.INFO, 'admin.mapping.import_mapping_files: importing "%s"' % fn) + except (EnvironmentError, ImportError): + univention.debug.debug(univention.debug.ADMIN, univention.debug.ERROR, 'admin.mapping.import_mapping_files: loading %s failed' % fn) + univention.debug.debug(univention.debug.ADMIN, univention.debug.ERROR, 'admin.mapping.import_mapping_files: TRACEBACK:\n%s' % traceback.format_exc()) def DaysToSeconds(days): commit e62048bbb019d5d54731df135314deb59714df26 Author: Florian Best Date: Wed Oct 11 17:19:25 2017 +0200 Bug #43129: register ldap indicies for mapping attributes This should not be done during an errata update! There we need to add them to the postinst and the joinscript! diff --git a/management/univention-ldap/scripts/ldap_setup_index b/management/univention-ldap/scripts/ldap_setup_index index 6104c22..20d29ec 100755 --- a/management/univention-ldap/scripts/ldap_setup_index +++ b/management/univention-ldap/scripts/ldap_setup_index @@ -251,6 +251,8 @@ UDM_PROP_ATTRS = set(( 'univentionUDMPropertyValueMayChange', 'univentionUDMPropertyValueRequired', 'univentionUDMPropertyVersion', + 'univentionUDMPropertyMapMethod', + 'univentionUDMPropertyUnMapMethod', )) RECOMMENDED_LDAP_INDEX = { commit b2ea913e9184147537b0a4d758359f34c5345889 Author: Florian Best Date: Wed Oct 11 17:12:28 2017 +0200 Bug #43129: add univentionUDMMapping diff --git a/base/univention-lib/python/ldap_extension.py b/base/univention-lib/python/ldap_extension.py index 5ac00cb..76cfdc1 100644 --- a/base/univention-lib/python/ldap_extension.py +++ b/base/univention-lib/python/ldap_extension.py @@ -819,6 +819,13 @@ class UniventionUDMHook(UniventionUDMExtension): filesuffix = ".py" +class UniventionUDMMapping(UniventionUDMExtension): + target_container_name = "udm_mapping" + udm_module_name = "settings/udm_mapping" + active_flag_attribute = "univentionUDMMappingActive" + filesuffix = ".py" + + def option_validate_existing_filename(option, opt, value): if not os.path.exists(value): raise OptionValueError("%s: file does not exist: %s" % (opt, value)) @@ -927,6 +934,10 @@ def ucs_registerLDAPExtension(): action="append", type="existing_filename", default=[], help="UDM hook", metavar="") + parser.add_option("--udm_mapping", dest="udm_mapping", + action="append", type="existing_filename", default=[], + help="UDM mapping", metavar="") + parser.add_option("--packagename", dest="packagename", help="Package name") parser.add_option("--packageversion", dest="packageversion", @@ -1041,6 +1052,15 @@ def ucs_registerLDAPExtension(): univentionUDMHook.register(udm_hook, opts, udm_passthrough_options) objects.append(univentionUDMHook) + if opts.udm_mapping: + if UniventionUDMMapping.create_base_container(ucr, udm_passthrough_options) != 0: + sys.exit(1) + + for udm_mapping in opts.udm_mapping: + univentionUDMMapping = UniventionUDMMapping(ucr) + univentionUDMMapping.register(udm_mapping, opts, udm_passthrough_options) + objects.append(univentionUDMMapping) + if opts.udm_module: if UniventionUDMModule.create_base_container(ucr, udm_passthrough_options) != 0: sys.exit(1) @@ -1085,6 +1105,10 @@ def ucs_unregisterLDAPExtension(): action="append", type="string", help="UDM hook", metavar="") + parser.add_option("--udm_mapping", dest="udm_mapping", + action="append", type="string", + help="UDM mapping", metavar="") + # parser.add_option("-v", "--verbose", action="count") udm_passthrough_options = [] @@ -1116,6 +1140,11 @@ def ucs_unregisterLDAPExtension(): univentionUDMHook = UniventionUDMHook(ucr) univentionUDMHook.unregister(udm_hook, opts, udm_passthrough_options) + if opts.udm_mapping: + for udm_mapping in opts.udm_mapping: + univentionUDMMapping = UniventionUDMMapping(ucr) + univentionUDMMapping.unregister(udm_mapping, opts, udm_passthrough_options) + if opts.udm_syntax: for udm_syntax in opts.udm_syntax: univentionUDMSyntax = UniventionUDMSyntax(ucr) diff --git a/management/univention-directory-manager-modules/modules/univention/admin/handlers/settings/udm_mapping.py b/management/univention-directory-manager-modules/modules/univention/admin/handlers/settings/udm_mapping.py new file mode 100644 index 0000000..cbce716 --- /dev/null +++ b/management/univention-directory-manager-modules/modules/univention/admin/handlers/settings/udm_mapping.py @@ -0,0 +1,270 @@ +# -*- coding: utf-8 -*- +# +# Univention Directory Manager Mappings +# direcory manager module for UDM mappings +# +# Copyright 2017 Univention GmbH +# +# http://www.univention.de/ +# +# All rights reserved. +# +# The source code of this program is made available +# under the terms of the GNU Affero General Public License version 3 +# (GNU AGPL V3) as published by the Free Software Foundation. +# +# Binary versions of this program provided by Univention to you as +# well as other copyrighted, protected or trademarked materials like +# Logos, graphics, fonts, specific documentations and configurations, +# cryptographic keys etc. are subject to a license agreement between +# you and Univention and not subject to the GNU AGPL V3. +# +# In the case you use this program under the terms of the GNU AGPL V3, +# the program is provided in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public +# License with the Debian GNU/Linux or Univention distribution in file +# /usr/share/common-licenses/AGPL-3; if not, see +# . + +from univention.admin.layout import Tab, Group +import univention.admin.filter +import univention.admin.handlers +import univention.admin.password +import univention.admin.allocators +import univention.admin.localization +import apt + +translation = univention.admin.localization.translation('univention.admin.handlers.settings') +_ = translation.translate + +OC = "univentionUDMMapping" + +module = 'settings/udm_mapping' +superordinate = 'settings/cn' +childs = 0 +operations = ['add', 'edit', 'remove', 'search', 'move'] +short_description = _('Settings: UDM Mapping') +long_description = '' +options = {} +property_descriptions = { + 'name': univention.admin.property( + short_description=_('UDM mapping name'), + long_description='', + syntax=univention.admin.syntax.string, + multivalue=False, + include_in_default_search=True, + options=[], + required=True, + may_change=True, + identifies=True + ), + 'filename': univention.admin.property( + short_description=_('UDM mapping file name'), + long_description='', + syntax=univention.admin.syntax.BaseFilename, + multivalue=False, + options=[], + required=True, + may_change=True, + default='', + identifies=False + ), + 'data': univention.admin.property( + short_description=_('UDM mapping data'), + long_description='', + syntax=univention.admin.syntax.Base64Bzip2Text, + multivalue=False, + options=[], + required=True, + may_change=True, + identifies=False + ), + 'active': univention.admin.property( + short_description=_('Active'), + long_description='', + syntax=univention.admin.syntax.TrueFalseUp, + default='FALSE', + multivalue=False, + options=[], + required=False, + may_change=True, + identifies=False + ), + 'appidentifier': univention.admin.property( + short_description=_('App identifier'), + long_description='', + syntax=univention.admin.syntax.TextArea, + multivalue=True, + options=[], + required=False, + may_change=True, + identifies=False + ), + 'package': univention.admin.property( + short_description=_('Software package'), + long_description='', + syntax=univention.admin.syntax.string, + multivalue=False, + options=[], + required=False, + may_change=True, + identifies=False + ), + 'packageversion': univention.admin.property( + short_description=_('Software package version'), + long_description='', + syntax=univention.admin.syntax.DebianPackageVersion, + multivalue=False, + options=[], + required=False, + may_change=True, + identifies=False + ), + 'ucsversionstart': univention.admin.property( + short_description=_('Minimal UCS version'), + long_description='', + syntax=univention.admin.syntax.UCSVersion, + multivalue=False, + options=[], + required=False, + may_change=True, + identifies=False + ), + 'ucsversionend': univention.admin.property( + short_description=_('Maximal UCS version'), + long_description='', + syntax=univention.admin.syntax.UCSVersion, + multivalue=False, + options=[], + required=False, + may_change=True, + identifies=False + ), + 'messagecatalog': univention.admin.property( + short_description=_('GNU message catalog for translations'), + long_description='GNU message catalog (syntax: )', + syntax=univention.admin.syntax.Localesubdirname_and_GNUMessageCatalog, + multivalue=True, + include_in_default_search=False, + options=[], + required=False, + may_change=True, + identifies=False, + ), +} + +layout = [ + Tab(_('General'), _('Basic values'), layout=[ + Group(_('General UDM mapping settings'), layout=[ + ["name"], + ["filename"], + ["data"], + ["messagecatalog"], + ]), + Group(_('Metadata'), layout=[ + ["package"], + ["packageversion"], + ["appidentifier"], + ]), + Group(_('UCS Version Dependencies'), layout=[ + ["ucsversionstart"], + ["ucsversionend"], + ]), + Group(_('Activated'), layout=[ + ["active"], + ]), + ]), +] + +mapping = univention.admin.mapping.mapping() +mapping.register('name', 'cn', None, univention.admin.mapping.ListToString) +mapping.register('filename', 'univentionUDMMappingFilename', None, univention.admin.mapping.ListToString) +mapping.register('data', 'univentionUDMMappingData', univention.admin.mapping.mapBase64, univention.admin.mapping.unmapBase64) +mapping.register('active', 'univentionUDMMappingActive', None, univention.admin.mapping.ListToString) +mapping.register('appidentifier', 'univentionAppIdentifier') +mapping.register('package', 'univentionOwnedByPackage', None, univention.admin.mapping.ListToString) +mapping.register('packageversion', 'univentionOwnedByPackageVersion', None, univention.admin.mapping.ListToString) +mapping.register('ucsversionstart', 'univentionUCSVersionStart', None, univention.admin.mapping.ListToString) +mapping.register('ucsversionend', 'univentionUCSVersionEnd', None, univention.admin.mapping.ListToString) +# messagecatalog is handled via object._post_map and object._post_unmap defined below + + +class object(univention.admin.handlers.simpleLdap): + module = module + + def _ldap_addlist(self): + ocs = ['top', 'univentionObjectMetadata', OC] + + return [ + ('objectClass', ocs), + ] + + def _ldap_pre_modify(self): + diff_keys = [key for key in self.info.keys() if self.info.get(key) != self.oldinfo.get(key) and key not in ('active', 'appidentifier')] + if not diff_keys: # check for trivial change + return + if not self.hasChanged('package'): + old_version = self.oldinfo.get('packageversion', '0') + if not apt.apt_pkg.version_compare(self['packageversion'], old_version) > -1: + raise univention.admin.uexceptions.valueInvalidSyntax(_('packageversion: Version must not be lower than the current one.')) + + def _post_unmap(self, info, values): + info['messagecatalog'] = [] + messagecatalog_ldap_attribute = "univentionMessageCatalog" + messagecatalog_ldap_attribute_and_tag_prefix = "%s;entry-lang-" % (messagecatalog_ldap_attribute,) + for ldap_attribute, value_list in values.items(): + if ldap_attribute.startswith(messagecatalog_ldap_attribute_and_tag_prefix): + language_tag = ldap_attribute.split(messagecatalog_ldap_attribute_and_tag_prefix, 1)[1] + mo_data_base64 = univention.admin.mapping.unmapBase64(value_list) + info['messagecatalog'].append((language_tag, mo_data_base64)) + return info + + def _post_map(self, modlist, diff): + messagecatalog_ldap_attribute = "univentionMessageCatalog" + messagecatalog_ldap_attribute_and_tag_prefix = "%s;entry-lang-" % (messagecatalog_ldap_attribute,) + for property_name, old_value, new_value in diff: + if property_name == 'messagecatalog': + old_dict = dict(old_value) + new_dict = dict(new_value) + for language_tag, old_mo_data_base64 in old_dict.items(): + ldap_attribute = ''.join((messagecatalog_ldap_attribute_and_tag_prefix, language_tag)) + new_mo_data_base64 = new_dict.get(language_tag) + if not new_mo_data_base64: # property value has been removed + old_mo_data_binary = univention.admin.mapping.mapBase64(old_mo_data_base64) + modlist.append((ldap_attribute, old_mo_data_binary, None)) + else: + if new_mo_data_base64 != old_mo_data_base64: + old_mo_data_binary = univention.admin.mapping.mapBase64(old_mo_data_base64) + new_mo_data_binary = univention.admin.mapping.mapBase64(new_mo_data_base64) + modlist.append((ldap_attribute, old_mo_data_binary, new_mo_data_binary)) + for language_tag, new_mo_data_base64 in new_dict.items(): + ldap_attribute = ''.join((messagecatalog_ldap_attribute_and_tag_prefix, language_tag)) + if not old_dict.get(language_tag): # property value has been added + new_mo_data_binary = univention.admin.mapping.mapBase64(new_mo_data_base64) + modlist.append((ldap_attribute, None, new_mo_data_binary)) + break + return modlist + + +def lookup(co, lo, filter_s, base='', superordinate=None, scope='sub', unique=False, required=False, timeout=-1, sizelimit=0): + filter = univention.admin.filter.conjunction('&', [ + univention.admin.filter.expression('objectClass', OC), + ]) + + if filter_s: + filter_p = univention.admin.filter.parse(filter_s) + univention.admin.filter.walk(filter_p, univention.admin.mapping.mapRewrite, arg=mapping) + filter.expressions.append(filter_p) + + res = [] + for dn, attrs in lo.search(unicode(filter), base, scope, [], unique, required, timeout, sizelimit): + res.append(object(co, lo, None, dn, attributes=attrs)) + return res + + +def identify(dn, attr, canonical=0): + return OC in attr.get('objectClass', []) diff --git a/management/univention-ldap/schema/udm-extension.schema b/management/univention-ldap/schema/udm-extension.schema index cfeca31..049d2ea 100644 --- a/management/univention-ldap/schema/udm-extension.schema +++ b/management/univention-ldap/schema/udm-extension.schema @@ -116,3 +116,34 @@ objectclass ( univentionUDMExtensionObjectClass:3 NAME 'univentionUDMSyntax' $ univentionMessageCatalog ) ) + +### Definition for univentionUDMMapping + +attributetype ( univentionUDMExtensionAttributeType:41 NAME 'univentionUDMMappingFilename' + DESC 'UDM mapping filename' + SINGLE-VALUE + EQUALITY caseExactMatch + SUBSTR caseExactSubstringsMatch + SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 ) + +attributetype ( univentionUDMExtensionAttributeType:42 NAME 'univentionUDMMappingData' + DESC 'UDM mapping data' + SINGLE-VALUE + SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 ) + +attributetype ( univentionUDMExtensionAttributeType:43 NAME 'univentionUDMMappingActive' + DESC 'Flag indicating availability of the UDM mapping' + SINGLE-VALUE + EQUALITY booleanMatch + SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 ) + +objectclass ( univentionUDMExtensionObjectClass:4 NAME 'univentionUDMMapping' + DESC 'UCS UDM mapping' + SUP 'univentionObjectMetadata' STRUCTURAL + MUST ( cn ) + MAY ( univentionUDMMappingFilename + $ univentionUDMMappingData + $ univentionUDMMappingActive + $ univentionMessageCatalog + ) + )