univention.udm package

Contents

univention.udm package#

Univention Directory Manager Modules (UDM) API

This is a simplified API for accessing UDM objects. It consists of UDM modules and UDM object. UDM modules are factories for UDM objects. UDM objects manipulate LDAP objects.

The UDM class is a LDAP connection and UDM module factory.

Usage:

from univention.udm import UDM

user_mod = UDM.admin().version(2).get('users/user')

or:

user_mod = UDM.machine().version(2).get('users/user')

or:

user_mod = UDM.credentials('myuser', 's3cr3t').version(2).get('users/user')

obj = user_mod.get(dn)
obj.props.firstname = 'foo'  # modify property
obj.position = 'cn=users,cn=example,dc=com'  # move LDAP object
obj.save()  # apply changes

obj = user_mod.get(dn)
obj.delete()

obj = user_mod.new()
obj.props.username = 'bar'
obj.props.lastname = 'baz'
obj.props.password = 'v3r7s3cr3t'
obj.props.unixhome = '/home/bar'
obj.save()

for obj in user_mod.search('uid=a*'):  # search() returns a generator
    print(obj.props.firstname, obj.props.lastname)

A shortcut exists to get UDM objects directly, without knowing their univention object type:

UDM.admin().version(2).obj_by_dn(dn)

A shortcut exists to get UDM objects directly, knowing their univention object type, but without knowing their DN:

UDM.admin().version(2).get('groups/group').get_by_id('Domain Users')

The API is versioned. A fixed version must be hard coded in your code. Supply it as argument to the UDM module factory or via version():

UDM(lo, 0)              # use API version 0 and an existing LDAP connection object
UDM.admin().version(1)  # use API version 1
UDM.credentials('myuser', 's3cr3t').version(2).obj_by_dn(dn)  # get object using API version 2
  • Version 0: values of UDM properties are the same as with the low level UDM API: mostly strings.

  • Version 1: values of (most) UDM properties are de/encoded to useful Python types (e.g. “0” -> 0 or False)

  • Version 2: an encoder for settings/portal_category properties was added.

The LDAP connection to use must be supplies as an argument to the UDM module factory or set via admin(), machine(), or credentials():

UDM(lo)        # use an already existing uldap connection object
UDM.admin()    # cn=admin connection
UDM.machine()  # machine connection
UDM.credentials(identity, password, base=None, server=None, port=None)  # custom connection,
    # `identity` is either a username or a DN. LDAP base, server FQDN/IP and port are optional.
    # If it is a username, a machine connection is used to retrieve the DN it belongs to.
class univention.udm.UDM(connection: univention.admin.uldap.access, api_version: int | None = None)[source]#

Bases: object

Dynamic factory for creating BaseModule objects:

group_mod = UDM.admin().version(2).get('groups/group')
folder_mod = UDM.machine().version(2).get('mail/folder')
user_mod = UDM.credentials('myuser', 's3cr3t').version(2).get('users/user')

A shortcut exists to get UDM objects directly:

UDM.admin().version(2).obj_by_dn(dn)

Use the provided connection.

Parameters:
  • connection – Any connection object (e.g., univention.admin.uldap.access)

  • api_version (int) – load only UDM modules that support the specified version, can be set later using version().

classmethod admin() Self[source]#

Use a cn=admin connection.

Returns:

a univention.udm.udm.UDM instance

Raises:

univention.udm.exceptions.ConnectionError – Non-Primary systems, server down, etc.

property api_version: int#
classmethod credentials(identity: str, password: str, base: str | None = None, server: str | None = None, port: int | None = None) Self[source]#

Use the provided credentials to open an LDAP connection.

identity must be either a username or a DN. If it is a username, a machine connection is used to retrieve the DN it belongs to.

Parameters:
  • identity (str) – username or user dn to use for LDAP connection

  • password (str) – password of user / DN to use for LDAP connection

  • base (str) – optional search base

  • server (str) – optional LDAP server address as FQDN

  • port (int) – optional LDAP server port

Returns:

a univention.udm.udm.UDM instance

Raises:

univention.udm.exceptions.ConnectionError – Invalid credentials, server down, etc.

get(name: str) BaseModule[source]#

Get an object of BaseModule (or of a subclass) for UDM module name.

Parameters:

name (str) – UDM module name (e.g. users/user)

Returns:

object of a subclass of BaseModule

Raises:
classmethod machine(prefer_local_connection: bool = False) Self[source]#

Use a machine connection.

Parameters:

prefer_local_connection (bool) – Connect to a local LDAP server (on a Replica, this would be the local slapd, on a Managed Node, this would be locally configured in UCR). Else, connect directly to the Primary

Returns:

a univention.udm.udm.UDM instance

Raises:

univention.udm.exceptions.ConnectionError – File permissions, server down, etc.

obj_by_dn(dn: str) BaseObject[source]#

Try to load an UDM object from LDAP. Guess the required UDM module from the univentionObjectType LDAP attribute of the LDAP object.

Parameters:

dn (str) – DN of the object to load

Returns:

object of a subclass of BaseObject

Raises:
version(api_version: int) Self[source]#

Set the version of the API that the UDM modules must support.

Use in a chain of methods to get a UDM module:

UDM.get_admin().version(2).get('groups/group')
Parameters:

api_version (int) – load only UDM modules that support the

Returns:

self (the univention.udm.udm.UDM instance) specified version

Raises:

univention.udm.exceptions.ApiVersionMustNotChange – if called twice

exception univention.udm.ApiVersionMustNotChange(msg: str | None = None, dn: str | None = None, module_name: str | None = None)[source]#

Bases: UdmError

Raised when UDM.version() is called twice.

msg = 'The version of an UDM instance must not be changed.'#
exception univention.udm.ApiVersionNotSupported(msg: str | None = None, module_name: str | None = None, requested_version: int | None = None)[source]#

Bases: UdmError

exception univention.udm.ConnectionError(msg: str | None = None, dn: str | None = None, module_name: str | None = None)[source]#

Bases: UdmError

Raised when something goes wrong getting a connection.

exception univention.udm.CreateError(msg: str | None = None, dn: str | None = None, module_name: str | None = None)[source]#

Bases: UdmError

Raised when an error occurred when creating an object.

exception univention.udm.DeleteError(msg: str | None = None, dn: str | None = None, module_name: str | None = None)[source]#

Bases: UdmError

Raised when a client tries to delete a UDM object but fails.

exception univention.udm.DeletedError(msg: str | None = None, dn: str | None = None, module_name: str | None = None)[source]#

Bases: UdmError

exception univention.udm.ModifyError(msg: str | None = None, dn: str | None = None, module_name: str | None = None)[source]#

Bases: UdmError

Raised if an error occurred when modifying an object.

exception univention.udm.MoveError(msg: str | None = None, dn: str | None = None, module_name: str | None = None)[source]#

Bases: UdmError

Raised if an error occurred when moving an object.

exception univention.udm.MultipleObjects(msg: str | None = None, dn: str | None = None, module_name: str | None = None)[source]#

Bases: UdmError

Raised when more than one UDM object was found when there should be at most one.

exception univention.udm.NoApiVersionSet(msg: str | None = None, dn: str | None = None, module_name: str | None = None)[source]#

Bases: UdmError

Raised when UDM.get() or UDM.obj_by_id() is used before setting an API version.

msg = 'No API version has been set.'#
exception univention.udm.NoObject(msg: str | None = None, dn: str | None = None, module_name: str | None = None)[source]#

Bases: UdmError

Raised when a UDM object could not be found at a DN.

exception univention.udm.NoSuperordinate(msg: str | None = None, dn: str | None = None, module_name: str | None = None, superordinate_types: Collection[str] | None = None)[source]#

Bases: UdmError

Raised when no superordinate was supplied but one is needed.

exception univention.udm.NotYetSavedError(msg: str | None = None, dn: str | None = None, module_name: str | None = None)[source]#

Bases: UdmError

Raised when a client tries to delete or reload a UDM object that is not yet saved.

msg = 'Object has not been created/loaded yet.'#
exception univention.udm.UdmError(msg: str | None = None, dn: str | None = None, module_name: str | None = None)[source]#

Bases: Exception

Base class of Exceptions raised by (simplified) UDM modules.

msg = ''#
exception univention.udm.UnknownModuleType(msg: str | None = None, dn: str | None = None, module_name: str | None = None)[source]#

Bases: UdmError

Raised when an LDAP object has no or empty attribute univentionObjectType.

exception univention.udm.UnknownProperty(msg: str | None = None, dn: str | None = None, module_name: str | None = None)[source]#

Bases: UdmError

Raised when a client tries to set a property on BaseObject.props, that it does not support.

exception univention.udm.WrongObjectType(msg: str | None = None, dn: str | None = None, module_name: str | None = None, univention_object_type: str | None = None)[source]#

Bases: UdmError

Raised when the LDAP object to be loaded does not match the module type (BaseModule.name).

Subpackages#

Submodules#

univention.udm.base module#

Base classes for (simplified) UDM modules and objects.

class univention.udm.base.LdapMapping(ldap2udm, udm2ldap)#

Bases: tuple

Create new instance of LdapMapping(ldap2udm, udm2ldap)

ldap2udm: Mapping[str, str]#

Alias for field number 0

udm2ldap: Mapping[str, str]#

Alias for field number 1

class univention.udm.base.BaseObjectProperties(udm_obj: BaseObject)[source]#

Bases: object

Container for UDM properties.

class univention.udm.base.BaseObject[source]#

Bases: object

Base class for UDM object classes.

Usage:

Creation of instances is always done through BaseModule.new(), BaseModule.get() or BaseModule.search().

Modify an object:

user.props.firstname = 'Peter'
user.props.lastname = 'Pan'
user.save()

Move an object:

user.position = 'cn=users,ou=Company,dc=example,dc=com'
user.save()

Delete an object:

obj.delete()

After saving a BaseObject, it is reload()ed automatically because UDM hooks and listener modules often add, modify or remove properties when saving to LDAP. As this involves LDAP, it can be disabled if the object is not used afterwards and performance is an issue:

user_mod.meta.auto_reload = False

Don’t instantiate a BaseObject directly. Use BaseModule.get(), BaseModule.new() or BaseModule.search().

udm_prop_class#

alias of BaseObjectProperties

reload() Self[source]#

Refresh object from LDAP.

Returns:

self

save() Self[source]#

Save object to LDAP.

Returns:

self

Raises:

univention.udm.exceptions.MoveError – when a move operation fails

delete(remove_childs: bool = False) None[source]#

Remove the object (and optionally its child nodes) from the LDAP database.

Parameters:

remove_childs (bool) – if there are UDM objects below this objects DN, recursively remove them before removing this object

class univention.udm.base.BaseModuleMetadata(meta: BaseModule.Meta)[source]#

Bases: object

Base class for UDM module meta data.

auto_open = True#

Whether UDM objects should be open()ed.

auto_reload = True#

Whether UDM objects should be reload()ed after saving.

instance(udm_module: BaseModule, api_version: int) Self[source]#
property identifying_property: str#

UDM property of which the mapped LDAP attribute is used as first component in a DN, e.g. username (LDAP attribute uid) or name (LDAP attribute cn).

lookup_filter(filter_s: str | None = None) str[source]#

Filter the UDM module uses to find its corresponding LDAP objects.

This can be used in two ways:

  • get the filter to find all objects:

    myfilter_s = obj.meta.lookup_filter()
    
  • get the filter to find a subset of the corresponding LDAP objects (filter_s will be combined with & to the filter for all objects):

    myfilter = obj.meta.lookup_filter('(|(givenName=A*)(givenName=B*))')
    
Parameters:

filter_s (str) – optional LDAP filter expression

Returns:

an LDAP filter string

property mapping: LdapMapping#

UDM properties to LDAP attributes mapping and vice versa.

Returns:

a namedtuple containing two mappings: a) from UDM property to LDAP attribute and b) from LDAP attribute to UDM property

class univention.udm.base.ModuleMeta(name: str, bases: tuple[type, ...], attrs: dict[str, Any])[source]#

Bases: Plugin

udm_meta_class#

alias of BaseModuleMetadata

class univention.udm.base.BaseModule(name: str, connection: Any, api_version: int)[source]#

Bases: object

Base class for UDM module classes. UDM modules are basically UDM object factories.

Get module using:

user_mod = UDM.admin/machine/credentials().version(2).get('users/user')

Create fresh, not yet saved BaseObject:

new_user = user_mod.new()

Load an existing object:

group = group_mod.get('cn=test,cn=groups,dc=example,dc=com')
group = group_mod.get_by_id('Domain Users')

Search and load existing objects:

dc_slaves = dc_slave_mod.search(filter_s='cn=s10*')
campus_groups = group_mod.search(base='ou=campus,dc=example,dc=com')

Load existing object(s) without open()ing them:

user_mod.meta.auto_open = False
user = user_mod.get(dn)
user.props.groups == []
meta = BaseModuleMetadata(supported_api_versions=[], suitable_for=[], used_api_version=None)#
new(superordinate: str | BaseObject | None = None) BaseObject[source]#

Create a new, unsaved BaseObject object.

Parameters:

superordinate – DN or UDM object this one references as its superordinate (required by some modules)

Returns:

a new, unsaved BaseObject object

get(dn: str) BaseObject[source]#

Load UDM object from LDAP.

Parameters:

dn (str) – DN of the object to load.

Returns:

an existing BaseObject instance.

Raises:
get_by_id(id: str) BaseObject[source]#

Load UDM object from LDAP by searching for its ID.

This is a convenience function around search().

Parameters:

id (str) – ID of the object to load (e.g. username (uid) for users/user, name (cn) for groups/group etc.)

Returns:

an existing BaseObject object.

Raises:
search(filter_s: str = '', base: str = '', scope: str = 'sub', sizelimit: int = 0) Iterator[BaseObject][source]#

Get all UDM objects from LDAP that match the given filter.

Parameters:
  • filter_s (str) – LDAP filter (only object selector like uid=foo required, objectClasses will be set by the UDM module)

  • base (str) – LDAP search base.

  • scope (str) – LDAP search scope, e.g. base or sub or one.

  • sizelimit (int) – LDAP size limit for searched results.

Returns:

iterator of BaseObject objects

univention.udm.binary_props module#

Classes for holding binary UDM object properties.

class univention.udm.binary_props.FileType(mime_type, encoding, text)#

Bases: tuple

Create new instance of FileType(mime_type, encoding, text)

encoding: str#

Alias for field number 1

mime_type: str#

Alias for field number 0

text: str#

Alias for field number 2

univention.udm.binary_props.get_file_type(filename_or_file: str | BinaryIO) FileType[source]#

Get mime_type and encoding of file filename_or_file.

Handles both magic libraries.

Parameters:

filename_or_file – filename or open file

Returns:

mime_type and encoding of filename_or_file

class univention.udm.binary_props.BaseBinaryProperty(name: str, encoded_value: bytes | None = None, raw_value: bytes | None = None)[source]#

Bases: object

Container for a binary UDM property.

Data can be set and retrieved in both its raw form or encoded for LDAP.

Internally data is held in the encoded state (the form in which it will be saved to LDAP).

property encoded: bytes#
property raw: bytes#
property content_type: FileType#
class univention.udm.binary_props.Base64BinaryProperty(name: str, encoded_value: bytes | None = None, raw_value: bytes | None = None)[source]#

Bases: BaseBinaryProperty

Container for a binary UDM property encoded using base64.

obj.props.<prop>.encoded == base64.b64encode(obj.props.<prop>.decoded)

>>> binprop = Base64BinaryProperty('example', raw_value=b'raw value')
>>> Base64BinaryProperty('example', encoded_value=binprop.encoded).raw == b'raw value'
True
>>> import base64
>>> binprop.encoded == base64.b64encode(binprop.raw)
True
property raw: bytes#
class univention.udm.binary_props.Base64Bzip2BinaryProperty(name: str, encoded_value: bytes | None = None, raw_value: bytes | None = None)[source]#

Bases: BaseBinaryProperty

Container for a binary UDM property encoded using base64 after using bzip2.

obj.props.<prop>.encoded == base64.b64encode(obj.props.<prop>.decoded)

>>> binprop = Base64Bzip2BinaryProperty('example', raw_value=b'raw value')
>>> Base64Bzip2BinaryProperty('example', encoded_value=binprop.encoded).raw == b'raw value'
True
>>> import bz2, base64
>>> binprop.encoded == base64.b64encode(bz2.compress(binprop.raw))
True
property raw: bytes#

univention.udm.connections module#

class univention.udm.connections.LDAP_connection[source]#

Bases: object

Caching LDAP connection factory.

classmethod get_admin_connection() access[source]#
classmethod get_machine_connection(ldap_master: bool = True) access[source]#
classmethod get_credentials_connection(identity: str, password: str, base: str | None = None, server: str | None = None, port: int | None = None) access[source]#

univention.udm.encoders module#

En/Decoders for object properties.

class univention.udm.encoders.BaseEncoder(property_name: str | None = None, *args: Any, **kwargs: Any)[source]#

Bases: object

static = False#
encode(value: Any | None = None) Any | None[source]#
decode(value: Any | None = None) Any | None[source]#
class univention.udm.encoders.Base64BinaryPropertyEncoder(property_name: str | None = None, *args: Any, **kwargs: Any)[source]#

Bases: BaseEncoder

static = False#
decode(value: str | None = None) Base64BinaryProperty | None[source]#
encode(value: Base64BinaryProperty | None = None) str | None[source]#
class univention.udm.encoders.Base64Bzip2BinaryPropertyEncoder(property_name: str | None = None, *args: Any, **kwargs: Any)[source]#

Bases: BaseEncoder

static = False#
decode(value: str | None = None) Base64Bzip2BinaryProperty | None[source]#
encode(value: Base64Bzip2BinaryProperty | None = None) str | None[source]#
class univention.udm.encoders.DatePropertyEncoder(property_name: str | None = None, *args: Any, **kwargs: Any)[source]#

Bases: BaseEncoder

static = True#
static decode(value: str | None = None) date | None[source]#
static encode(value: date | None = None) str | None[source]#
class univention.udm.encoders.DisabledPropertyEncoder(property_name: str | None = None, *args: Any, **kwargs: Any)[source]#

Bases: BaseEncoder

static = True#
static decode(value: str | None = None) bool[source]#
static encode(value: bool | None = None) str[source]#
class univention.udm.encoders.HomePostalAddressPropertyEncoder(property_name: str | None = None, *args: Any, **kwargs: Any)[source]#

Bases: BaseEncoder

static = True#
static decode(value: list[list[str]] | None = None) list[dict[str, str]] | None[source]#
static encode(value: list[dict[str, str]] | None = None) list[list[str]] | None[source]#
class univention.udm.encoders.ListOfListOflTextToDictPropertyEncoder(property_name: str | None = None, *args: Any, **kwargs: Any)[source]#

Bases: BaseEncoder

static = True#
static decode(value: list[list[str]] | None = None) dict[str, str] | None[source]#
static encode(value: dict[str, str] | None = None) list[list[str]] | None[source]#
class univention.udm.encoders.MultiLanguageTextAppcenterPropertyEncoder(property_name: str | None = None, *args: Any, **kwargs: Any)[source]#

Bases: BaseEncoder

static = True#
static decode(value: list[str] | None = None) dict[str, str] | None[source]#
static encode(value: dict[str, str] | None = None) list[str] | None[source]#
class univention.udm.encoders.SambaGroupTypePropertyEncoder(property_name: str | None = None, *args: Any, **kwargs: Any)[source]#

Bases: BaseEncoder

static = True#
choices = {'': '', '2': 'Domain Group', '3': 'Local Group', '5': 'Well-Known Group'}#
choices_reverted = {'': '', 'Domain Group': '2', 'Local Group': '3', 'Well-Known Group': '5'}#
classmethod decode(value: list[str] | None = None) str | None[source]#
classmethod encode(value: str | None = None) list[str] | None[source]#
class univention.udm.encoders.SambaLogonHoursPropertyEncoder(property_name: str | None = None, *args: Any, **kwargs: Any)[source]#

Bases: BaseEncoder

static = True#
classmethod decode(value: list[int] | None = None) list[str] | None[source]#
classmethod encode(value: list[str] | None = None) list[int] | None[source]#
class univention.udm.encoders.StringCaseInsensitiveResultLowerBooleanPropertyEncoder(property_name: str | None = None, *args: Any, **kwargs: Any)[source]#

Bases: BaseEncoder

static = True#
result_case_func = 'lower'#
false_string = 'false'#
true_string = 'true'#
classmethod decode(value: str | None = '') bool[source]#
classmethod encode(value: bool | None = None) str[source]#
class univention.udm.encoders.StringCaseInsensitiveResultUpperBooleanPropertyEncoder(property_name: str | None = None, *args: Any, **kwargs: Any)[source]#

Bases: StringCaseInsensitiveResultLowerBooleanPropertyEncoder

result_case_func = 'upper'#
class univention.udm.encoders.StringIntBooleanPropertyEncoder(property_name: str | None = None, *args: Any, **kwargs: Any)[source]#

Bases: BaseEncoder

static = True#
static decode(value: str | None = None) bool[source]#
static encode(value: bool | None = None) str[source]#
class univention.udm.encoders.StringIntPropertyEncoder(property_name: str | None = None, *args: Any, **kwargs: Any)[source]#

Bases: BaseEncoder

static = False#
decode(value: str | None = None) int | None[source]#
static encode(value: int | None = None) str | None[source]#
class univention.udm.encoders.StringListToList(property_name: str | None = None, *args: Any, **kwargs: Any)[source]#

Bases: BaseEncoder

static = True#
separator = ' '#
classmethod decode(value: str | None = None) list[str] | None[source]#
classmethod encode(value: list[str] | None = None) str | None[source]#
class univention.udm.encoders.DnListPropertyEncoder(property_name: str | None = None, connection: Any | None = None, api_version: int | None = None, *args: Any, **kwargs: Any)[source]#

Bases: BaseEncoder

Given a list of DNs, return the same list with an additional member objs. objs is a lazy object that will become the list of UDM objects the DNs refer to, when accessed.

dn_list_property_encoder_for() will dynamically produce subclasses of this for every UDM module required.

static = False#
udm_module_name = ''#
class DnsList(iterable=(), /)[source]#

Bases: list

objs = None#
class MyProxy[source]#

Bases: Proxy

decode(value: list[str] | None = None) list[str] | None[source]#
static encode(value: list[str] | None = None) list[str] | None[source]#
property udm: Any#
class univention.udm.encoders.PoliciesEncoder(property_name: str | None = None, connection: Any | None = None, api_version: int | None = None, module_name: str | None = None, *args: Any, **kwargs: Any)[source]#

Bases: BaseEncoder

static = False#
decode(value: Any | None = None) dict[Any, list[Any]][source]#
encode(value: dict[Any, list[Any]] | None = None) list[Any][source]#
class univention.udm.encoders.CnameListPropertyEncoder(property_name: str | None = None, connection: Any | None = None, api_version: int | None = None, *args: Any, **kwargs: Any)[source]#

Bases: DnListPropertyEncoder

Given a list of CNAMEs, return the same list with an additional member objs. objs is a lazy object that will become the list of UDM objects the CNAMEs refer to, when accessed.

udm_module_name = 'dns/alias'#
class univention.udm.encoders.DnsEntryZoneAliasListPropertyEncoder(property_name: str | None = None, connection: Any | None = None, api_version: int | None = None, *args: Any, **kwargs: Any)[source]#

Bases: DnListPropertyEncoder

Given a list of dnsEntryZoneAlias entries, return the same list with an additional member objs. objs is a lazy object that will become the list of UDM objects the dnsEntryZoneAlias entries refer to, when accessed.

udm_module_name = 'dns/alias'#
class univention.udm.encoders.DnsEntryZoneForwardListMultiplePropertyEncoder(property_name: str | None = None, connection: Any | None = None, api_version: int | None = None, *args: Any, **kwargs: Any)[source]#

Bases: DnListPropertyEncoder

Given a list of dnsEntryZoneForward entries, return the same list with an additional member objs. objs is a lazy object that will become the list of UDM objects the dnsEntryZoneForward entries refer to, when accessed.

udm_module_name = 'dns/forward_zone'#
class univention.udm.encoders.DnsEntryZoneForwardListSinglePropertyEncoder(property_name: str | None = None, connection: Any | None = None, api_version: int | None = None, *args: Any, **kwargs: Any)[source]#

Bases: DnsEntryZoneForwardListMultiplePropertyEncoder

Given a list of dnsEntryZoneForward entries, return the same list with an additional member objs. objs is a lazy object that will become the list of UDM objects the dnsEntryZoneForward entries refer to, when accessed.

udm_module_name = 'dns/forward_zone'#
class univention.udm.encoders.DnsEntryZoneReverseListMultiplePropertyEncoder(property_name: str | None = None, connection: Any | None = None, api_version: int | None = None, *args: Any, **kwargs: Any)[source]#

Bases: DnsEntryZoneForwardListMultiplePropertyEncoder

Given a list of dnsEntryZoneReverse entries, return the same list with an additional member objs. objs is a lazy object that will become the list of UDM objects the dnsEntryZoneReverse entries refer to, when accessed.

udm_module_name = 'dns/reverse_zone'#
class univention.udm.encoders.DnsEntryZoneReverseListSinglePropertyEncoder(property_name: str | None = None, connection: Any | None = None, api_version: int | None = None, *args: Any, **kwargs: Any)[source]#

Bases: DnsEntryZoneReverseListMultiplePropertyEncoder

Given a list of dnsEntryZoneReverse entries, return the same list with an additional member objs. objs is a lazy object that will become the list of UDM objects the dnsEntryZoneReverse entries refer to, when accessed.

udm_module_name = 'dns/reverse_zone'#
class univention.udm.encoders.DnPropertyEncoder(property_name: str | None = None, connection: Any = None, api_version: int | None = None, *args: Any, **kwargs: Any)[source]#

Bases: BaseEncoder

Given a DN, return a string object with the DN and an additional member obj. obj is a lazy object that will become the UDM object the DN refers to, when accessed.

dn_property_encoder_for() will dynamically produce subclasses of this for every UDM module required.

static = False#
udm_module_name = ''#
class DnStr[source]#

Bases: str

obj = None#
class MyProxy[source]#

Bases: Proxy

decode(value: str | None = None) str | None[source]#
static encode(value: str | None = None) str | None[source]#
property udm: UDM#
univention.udm.encoders.dn_list_property_encoder_for(udm_module_name: str) type[DnListPropertyEncoder][source]#

Create a (cached) subclass of DnListPropertyEncoder specific for each UDM module.

Parameters:

udm_module_name (str) – name of UDM module (e.g. users/user) or auto if auto-detection should be done. Auto-detection requires one additional LDAP-query per object (still lazy though)!

Returns:

subclass of DnListPropertyEncoder

univention.udm.encoders.dn_property_encoder_for(udm_module_name: str) type[DnPropertyEncoder][source]#

Create a (cached) subclass of DnPropertyEncoder specific for each UDM module.

Parameters:

udm_module_name (str) – name of UDM module (e.g. users/user) or auto if auto-detection should be done. Auto-detection requires one additional LDAP-query per object (still lazy though)!

Returns:

subclass of DnPropertyEncoder

univention.udm.exceptions module#

exception univention.udm.exceptions.UdmError(msg: str | None = None, dn: str | None = None, module_name: str | None = None)[source]#

Bases: Exception

Base class of Exceptions raised by (simplified) UDM modules.

msg = ''#
exception univention.udm.exceptions.ApiVersionMustNotChange(msg: str | None = None, dn: str | None = None, module_name: str | None = None)[source]#

Bases: UdmError

Raised when UDM.version() is called twice.

msg = 'The version of an UDM instance must not be changed.'#
exception univention.udm.exceptions.ConnectionError(msg: str | None = None, dn: str | None = None, module_name: str | None = None)[source]#

Bases: UdmError

Raised when something goes wrong getting a connection.

exception univention.udm.exceptions.ApiVersionNotSupported(msg: str | None = None, module_name: str | None = None, requested_version: int | None = None)[source]#

Bases: UdmError

exception univention.udm.exceptions.CreateError(msg: str | None = None, dn: str | None = None, module_name: str | None = None)[source]#

Bases: UdmError

Raised when an error occurred when creating an object.

exception univention.udm.exceptions.DeletedError(msg: str | None = None, dn: str | None = None, module_name: str | None = None)[source]#

Bases: UdmError

exception univention.udm.exceptions.DeleteError(msg: str | None = None, dn: str | None = None, module_name: str | None = None)[source]#

Bases: UdmError

Raised when a client tries to delete a UDM object but fails.

exception univention.udm.exceptions.NotYetSavedError(msg: str | None = None, dn: str | None = None, module_name: str | None = None)[source]#

Bases: UdmError

Raised when a client tries to delete or reload a UDM object that is not yet saved.

msg = 'Object has not been created/loaded yet.'#
exception univention.udm.exceptions.ModifyError(msg: str | None = None, dn: str | None = None, module_name: str | None = None)[source]#

Bases: UdmError

Raised if an error occurred when modifying an object.

exception univention.udm.exceptions.MoveError(msg: str | None = None, dn: str | None = None, module_name: str | None = None)[source]#

Bases: UdmError

Raised if an error occurred when moving an object.

exception univention.udm.exceptions.NoApiVersionSet(msg: str | None = None, dn: str | None = None, module_name: str | None = None)[source]#

Bases: UdmError

Raised when UDM.get() or UDM.obj_by_id() is used before setting an API version.

msg = 'No API version has been set.'#
exception univention.udm.exceptions.NoObject(msg: str | None = None, dn: str | None = None, module_name: str | None = None)[source]#

Bases: UdmError

Raised when a UDM object could not be found at a DN.

exception univention.udm.exceptions.NoSuperordinate(msg: str | None = None, dn: str | None = None, module_name: str | None = None, superordinate_types: Collection[str] | None = None)[source]#

Bases: UdmError

Raised when no superordinate was supplied but one is needed.

exception univention.udm.exceptions.SearchLimitReached(msg: str | None = None, dn: str | None = None, module_name: str | None = None, search_filter: str | None = None, sizelimit: int | None = None)[source]#

Bases: UdmError

Raised when the search results in more objects than specified by the sizelimit.

exception univention.udm.exceptions.MultipleObjects(msg: str | None = None, dn: str | None = None, module_name: str | None = None)[source]#

Bases: UdmError

Raised when more than one UDM object was found when there should be at most one.

exception univention.udm.exceptions.UnknownModuleType(msg: str | None = None, dn: str | None = None, module_name: str | None = None)[source]#

Bases: UdmError

Raised when an LDAP object has no or empty attribute univentionObjectType.

exception univention.udm.exceptions.UnknownProperty(msg: str | None = None, dn: str | None = None, module_name: str | None = None)[source]#

Bases: UdmError

Raised when a client tries to set a property on BaseObject.props, that it does not support.

exception univention.udm.exceptions.WrongObjectType(msg: str | None = None, dn: str | None = None, module_name: str | None = None, univention_object_type: str | None = None)[source]#

Bases: UdmError

Raised when the LDAP object to be loaded does not match the module type (BaseModule.name).

univention.udm.helpers module#

univention.udm.helpers.get_all_udm_module_names() list[str][source]#

Get the names of all installed UDM modules.

Returns:

list with UDM module names

univention.udm.plugins module#

class univention.udm.plugins.Plugin(name: str, bases: tuple[type, ...], attrs: dict[str, Any])[source]#

Bases: type

Meta class for plugins.

class univention.udm.plugins.Plugins(python_path: str)[source]#

Bases: object

Register Plugin subclasses and iterate over them.

Parameters:

python_path (str) – fully dotted Python path that the plugins will be found below

classmethod add_plugin(plugin: Plugin) None[source]#

Called by Plugin meta class to register a new Plugin subclass.

Parameters:

plugin (type) – a Plugin subclass

load() None[source]#

Load plugins.

univention.udm.udm module#

Univention Directory Manager Modules (UDM) API

This is a simplified API for accessing UDM objects. It consists of UDM modules and UDM object. UDM modules are factories for UDM objects. UDM objects manipulate LDAP objects.

The UDM class is a LDAP connection and UDM module factory.

Usage:

from univention.udm import UDM

user_mod = UDM.admin().version(2).get('users/user')

or:

user_mod = UDM.machine().version(2).get('users/user')

or:

user_mod = UDM.credentials('myuser', 's3cr3t').version(2).get('users/user')

obj = user_mod.get(dn)
obj.props.firstname = 'foo'  # modify property
obj.position = 'cn=users,cn=example,dc=com'  # move LDAP object
obj.save()  # apply changes

obj = user_mod.get(dn)
obj.delete()

obj = user_mod.new()
obj.props.username = 'bar'
obj.props.lastname = 'baz'
obj.props.password = 'v3r7s3cr3t'
obj.props.unixhome = '/home/bar'
obj.save()

for obj in user_mod.search('uid=a*'):  # search() returns a generator
    print(obj.props.firstname, obj.props.lastname)

A shortcut exists to get UDM objects directly, without knowing their univention object type:

UDM.admin().version(2).obj_by_dn(dn)

A shortcut exists to get UDM objects directly, knowing their univention object type, but without knowing their DN:

UDM.admin().version(2).get('groups/group').get_by_id('Domain Users')

The API is versioned. A fixed version must be hard coded in your code. Supply it as argument to the UDM module factory or via version():

UDM(lo, 0)              # use API version 0 and an existing LDAP connection object
UDM.admin().version(1)  # use API version 1
UDM.credentials('myuser', 's3cr3t').version(2).obj_by_dn(dn)  # get object using API version 2
  • Version 0: values of UDM properties are the same as with the low level UDM API: mostly strings.

  • Version 1: values of (most) UDM properties are de/encoded to useful Python types (e.g. “0” -> 0 or False)

  • Version 2: an encoder for settings/portal_category properties was added.

The LDAP connection to use must be supplies as an argument to the UDM module factory or set via admin(), machine(), or credentials():

UDM(lo)        # use an already existing uldap connection object
UDM.admin()    # cn=admin connection
UDM.machine()  # machine connection
UDM.credentials(identity, password, base=None, server=None, port=None)  # custom connection,
    # `identity` is either a username or a DN. LDAP base, server FQDN/IP and port are optional.
    # If it is a username, a machine connection is used to retrieve the DN it belongs to.
class univention.udm.udm.UDM(connection: univention.admin.uldap.access, api_version: int | None = None)[source]#

Bases: object

Dynamic factory for creating BaseModule objects:

group_mod = UDM.admin().version(2).get('groups/group')
folder_mod = UDM.machine().version(2).get('mail/folder')
user_mod = UDM.credentials('myuser', 's3cr3t').version(2).get('users/user')

A shortcut exists to get UDM objects directly:

UDM.admin().version(2).obj_by_dn(dn)

Use the provided connection.

Parameters:
  • connection – Any connection object (e.g., univention.admin.uldap.access)

  • api_version (int) – load only UDM modules that support the specified version, can be set later using version().

classmethod admin() Self[source]#

Use a cn=admin connection.

Returns:

a univention.udm.udm.UDM instance

Raises:

univention.udm.exceptions.ConnectionError – Non-Primary systems, server down, etc.

classmethod machine(prefer_local_connection: bool = False) Self[source]#

Use a machine connection.

Parameters:

prefer_local_connection (bool) – Connect to a local LDAP server (on a Replica, this would be the local slapd, on a Managed Node, this would be locally configured in UCR). Else, connect directly to the Primary

Returns:

a univention.udm.udm.UDM instance

Raises:

univention.udm.exceptions.ConnectionError – File permissions, server down, etc.

classmethod credentials(identity: str, password: str, base: str | None = None, server: str | None = None, port: int | None = None) Self[source]#

Use the provided credentials to open an LDAP connection.

identity must be either a username or a DN. If it is a username, a machine connection is used to retrieve the DN it belongs to.

Parameters:
  • identity (str) – username or user dn to use for LDAP connection

  • password (str) – password of user / DN to use for LDAP connection

  • base (str) – optional search base

  • server (str) – optional LDAP server address as FQDN

  • port (int) – optional LDAP server port

Returns:

a univention.udm.udm.UDM instance

Raises:

univention.udm.exceptions.ConnectionError – Invalid credentials, server down, etc.

version(api_version: int) Self[source]#

Set the version of the API that the UDM modules must support.

Use in a chain of methods to get a UDM module:

UDM.get_admin().version(2).get('groups/group')
Parameters:

api_version (int) – load only UDM modules that support the

Returns:

self (the univention.udm.udm.UDM instance) specified version

Raises:

univention.udm.exceptions.ApiVersionMustNotChange – if called twice

get(name: str) BaseModule[source]#

Get an object of BaseModule (or of a subclass) for UDM module name.

Parameters:

name (str) – UDM module name (e.g. users/user)

Returns:

object of a subclass of BaseModule

Raises:
obj_by_dn(dn: str) BaseObject[source]#

Try to load an UDM object from LDAP. Guess the required UDM module from the univentionObjectType LDAP attribute of the LDAP object.

Parameters:

dn (str) – DN of the object to load

Returns:

object of a subclass of BaseObject

Raises:
property api_version: int#

univention.udm.utils module#