API documentation#

bonsai#

LDAPClient#

class bonsai.LDAPClient(url, tls=False)#

A class for configuring the connection to the directory server.

Parameters:
  • url (str|LDAPURL) – an LDAP URL.

  • tls (bool) – Set True to use TLS connection.

Raises:

TypeError – if the url parameter is not string or not a valid LDAP URL.

LDAPClient.connect(is_async=False, timeout=None, **kwargs)#

Open a connection to the LDAP server.

Parameters:
  • is_async (bool) – Set True to use asynchronous connection.

  • timeout (float) – time limit in seconds for the operation.

  • **kwargs – additional keyword arguments that are passed to the async connection object (e.g. an eventloop object as loop parameter).

Returns:

an LDAP connection.

Return type:

LDAPConnection

LDAPClient.get_rootDSE()#

Returns the server’s root DSE entry. The root DSE may contain information about the vendor, the naming contexts, the request controls the server supports, the supported SASL mechanisms, features, schema location, and other information.

Returns:

the root DSE entry.

Return type:

LDAPEntry

An example of getting the root DSE:

>>> client = bonsai.LDAPClient()
>>> client.get_rootDSE()
{'namingContexts': ['dc=bonsai,dc=test'], 'supportedControl': ['2.16.840.1.113730.3.4.18',
'2.16.840.1.113730.3.4.2', '1.3.6.1.4.1.4203.1.10.1', '1.2.840.113556.1.4.319',
'1.2.826.0.1.3344810.2.3', '1.3.6.1.1.13.2', '1.3.6.1.1.13.1', '1.3.6.1.1.12'],
'supportedLDAPVersion': ['3'], 'supportedExtension': ['1.3.6.1.4.1.1466.20037',
'1.3.6.1.4.1.4203.1.11.1', '1.3.6.1.4.1.4203.1.11.3', '1.3.6.1.1.8'],
'supportedSASLMechanisms': ['DIGEST-MD5', 'NTLM', 'CRAM-MD5']}
LDAPClient.set_async_connection_class(conn)#

Set the LDAP connection class for asynchronous connection. The default connection class is bonsai.asyncio.AIOLDAPConnection that uses the asyncio event loop.

Parameters:

conn (BaseLDAPConnection) – the new asynchronous connection class that is a subclass of LDAPConnection.

Raises:

TypeError – if conn parameter is not a subclass of BaseLDAPConnection.

An example to change the default async connection class to a Gevent-based one:

>>> import bonsai
>>> from bonsai.gevent import GeventLDAPConnection
>>> client = bonsai.LDAPClient()
>>> client.set_async_connection_class(GeventLDAPConnection)
>>> client.connect(True)
<bonsai.gevent.geventconnection.GeventLDAPConnection object at 0x7f9b1789c6d8>
LDAPClient.set_auto_page_acquire(val)#

Turn on or off the automatic page acquiring during a paged LDAP search. By turning automatic page acquiring on, it is unnecessary to call ldapsearchiter.acquire_next_page(). It will be implicitly called during iteration.

Parameters:

val (bool) – enabling/disabling auto page acquiring.

Raises:

TypeError – If the parameter is not a bool type.

LDAPClient.set_ca_cert(name)#

Set the name of CA certificate. If the underlying libldap library uses the Mozilla NSS as TLS library the name should be the same one in the cert/key database (that specified with LDAPClient.set_ca_cert_dir()), otherwise it can be the name of the CA cert file.

Note

This method has no effect on MS Windows, because WinLDAP searches for the corresponding CA certificate in the cert store. This means that the necessary certificates have to be installed manually in to the cert store.

Parameters:

name (str) – the name of the CA cert.

Raises:

TypeError – if name parameter is not a string or not None.

LDAPClient.set_ca_cert_dir(path)#

Set the directory of the CA cert. If the underlying libldap library uses the Mozilla NSS as TLS library the path should be the path to the existing cert/key database, otherwise it can be the path of the CA cert file.

Note

This method has no effect on MS Windows, because WinLDAP searches for the corresponding CA certificate in the cert store. This means that the necessary certifications have to be installed manually in to the cert store.

Parameters:

path (str) – the path to the CA directory.

Raises:

TypeError – if path parameter is not a string or not None.

LDAPClient.set_cert_policy(policy)#

Set policy about server certification.

Parameters:

policy (str) –

the cert policy could be one of the following strings:

  • try or demand: the server cert will be verified, and if it fail, then the LDAPClient.connect() will raise an error.

  • never or allow: the server cert will be used without any verification.

Raises:
  • TypeError – if the policy parameter is not a string.

  • ValueError – if the policy not one of the four above.

Warning

Set off the cert verification is dangerous. Without verification there is a chance of man-in-the-middle attack.

LDAPClient.set_client_cert(name)#

Set the name of client certificate. If the underlying libldap library uses the Mozilla NSS as TLS library the name should be the same one in the cert/key database (that specified with LDAPClient.set_ca_cert_dir()), otherwise it can be the name of the client certificate file.

Note

This method has no effect on MS Windows, because WinLDAP searches for the corresponding client certificate based on the servert’s CA cert in the cert store. This means that the necessary certificates have to be installed manually in to the cert store.

Parameters:

name (str) – the name of the client cert.

Raises:

TypeError – if name parameter is not a string or not None.

LDAPClient.set_client_key(name)#

Set the file that contains the private key that matches the certificate of the client that specified with LDAPClient.set_client_cert()).

Note

This method has no effect on MS Windows, because WinLDAP searches for the corresponding client certificate based on the servert’s CA cert in the cert store. This means that the necessary certificates have to be installed manually in to the cert store.

Parameters:

name (str) – the name of the CA cert.

Raises:

TypeError – if name parameter is not a string or not None.

LDAPClient.set_credentials(mechanism, user=None, password=None, realm=None, authz_id=None, keytab=None)#

Set binding mechanism and credential information. All parameters are optional except the mechanism. Different mechanism applies different credential information and ignores the rest. For example:

  • SIMPLE uses the user (as bind DN) and password.

  • EXTERNAL only uses the authz_id as authorization ID.

For other use-cases see this section about authentication mechanisms.

Parameters:
  • mechanism (str) – the name of the binding mechanism.

  • user (str) – the identification of the binding user.

  • password (str) – the password of the user.

  • realm (str) – the (Kerberos) realm of the user.

  • authz_id (str) – the authorization ID for the user.

  • keytab (str) – path to a Kerberos keytab for authentication.

Raises:

TypeError – if mechanism is not string, or any of the other parameters are not string or None, or both of the password and keytab parameters are set.

>>> from bonsai import LDAPClient
>>> client = LDAPClient()
>>> client.set_credentials("SIMPLE", user="cn=user,dc=bonsai,dc=test", password="secret")
>>> client.connect()
<bonsai.LDAPConnection object at 0x7fadf8976440>
LDAPClient.set_extended_dn(extdn_format)#

Set the format of extended distinguished name for LDAP_SERVER_EXTENDED_DN_OID control which extends the entries’ distingushed name with GUID and SID attributes. If the server supports the control, the LDAPEntry objects’ extended_dn attribute will be set (as a string) and the dn attribute will be kept in the simple format.

Setting 0 specifies that the GUID and SID values be returned in hexadecimal string format, while setting 1 will return the GUID and SID values in standard string format. Passing None will remove the control in a format of <GUID=xxxx>;<SID=yyyy>;distinguishedName.

Parameters:

extdn_format (int) – the format of the extended dn. It can be 0, 1 or None.

Raises:
  • TypeError – if the parameter is not int or None.

  • ValueError – if the parameter is not 0, 1 or None.

An example:

>>> client = bonsai.LDAPClient()
>>> client.set_extended_dn(1)
>>> result = conn.search("ou=nerdherd,dc=bonsai,dc=test", 1)
>>> result[0].extended_dn
<GUID=899e4e01-e88d-4dea-ba64-119ed386b61c>;<SID=S-1-5-21-101232111302-1767724339-724445543-12345>;cn=chuck,ou=nerdherd,dc=bonsai,dc=test
>>> result[0].dn
<LDAPDN cn=chuck,ou=nerdherd,dc=bonsai,dc=test>

Note

If the extended dn control is not supported the LDAPEntry’s extended_dn attribute will be None. The LDAP_SERVER_EXTENDED_DN_OID is defined as ‘1.2.840.113556.1.4.529’.

LDAPClient.set_ignore_referrals(val)#

Turn on or off ignoring LDAP referrals in search result. When enabled (default), then possible LDAP referrals won’t be represented in the search result. When disabled and LDAPClient.server_chase_referrals is also disabled, than search result can contain LDAPReference objects along with LDAPEntry objects.

Parameters:

val (bool) – enabling/disabling LDAP referrals in search result.

Raises:

TypeError – If the parameter is not a bool type.

LDAPClient.set_managedsait(val)#

Set ManageDsaIT control for LDAP operations. With ManageDsaIT an LDAP referral can be searched, added and modified as a common LDAP entry.

Parameters:

val (bool) – enabling/disabling ManageDsaIT control.

Raises:

TypeError – If the parameter is not a bool type.

LDAPClient.set_password_policy(ppolicy)#

Enable password policy control, if it is provided by the directory server. Setting it True will change the return value of LDAPClient.connect() and LDAPConnection.open() to a tuple of (conn, ctrl) where the conn is an LDAPConnection, the ctrl is a dict of returned password policy control response that contains the oid, the remaining seconds of password expiration, and the number of remaining grace logins. If the password policy control is not available on the server or not supported by the platform the second item in the returned tuple is None, instead of a dictionary.

By enabling the password policy control the server can send additional error messages related to the user’s account and password during conneting to the server and changing entries.

Parameters:

ppolicy (bool) – enabling/disabling password policy control.

Raises:

TypeError – If the parameter is not a bool type.

An example:

>>> import bonsai
>>> client = bonsai.LDAPClient()
>>> client.set_credentials("SIMPLE", "cn=user,dc=bonsai,dc=test", "secret")
>>> client.set_password_policy(True)
>>> conn, ctrl = client.connect()
>>> conn
<bonsai.ldapconnection.LDAPConnection object at 0x7fa552ab4e28>
>>> ctrl
{'grace': 1, 'expire': 3612, 'oid': '1.3.6.1.4.1.42.2.27.8.5.1'})

Note

Password policy control cannot be used on MS Windows with WinLDAP. In this case after opening a connection the control dictionary will always be None.

LDAPClient.set_raw_attributes(raw_list)#

By default the values of the LDAPEntry are in string format. The values of the listed LDAP attribute’s names in raw_list will be kept in bytearray format.

Parameters:

raw_list (list) – a list of LDAP attribute’s names. The elements must be string and unique.

Raises:
  • TypeError – if any of the list’s element is not a string.

  • ValueError – if the item in the lit is not a unique element.

An example:

>>> client = bonsai.LDAPClient()
>>> client.set_raw_attributes(["cn", "sn"])
>>> conn = client.connect()
>>> conn.search("cn=jeff,ou=nerdherd,dc=bonsai,dc=test", 0, attrlist=['cn', 'sn', 'gn'])
[{'dn': <LDAPDN cn=jeff,ou=nerdherd,dc=bonsai,dc=test>, 'sn': [b'Barnes'], 'cn': [b'jeff'],
'givenName': ['Jeff']}]
LDAPClient.set_sasl_security_properties(no_anonymous=None, no_dict=None, no_plain=None, forward_sec=None, pass_cred=None, min_ssf=None, max_ssf=None, max_bufsize=None)#

Set security properties for SASL mechanism.

Note

This method has no effect on MS Windows.

Parameters:
  • no_anonymous (bool) – Flag for forbiding anonymous logins.

  • no_dict (bool) – Flag for making the mechanism not susceptable to passive dictionary attack.

  • no_plain (bool) – Flag for making mechanism not susceptable to simple passive (eavesdropping) attack.

  • forward_sec (bool) – Flag for setting forward secrecy between sessions.

  • pass_cred (bool) – Flag for requiring mechanisms which pass client credentials.

  • min_ssf (int) – The minimum security strength factor.

  • max_ssf (int) – The maximum security strength factor.

  • max_bufsize (int) – The maximum buffer size.

Raises:
  • TypeError – If the flag parameters are not bool types or the min_ssf, max_ssf and max_bufsize parameters are not int.

  • ValueError – If the min_ssf, max_ssf and max_bufsize parameters are less than 0.

LDAPClient.set_sd_flags(flags)#

Set the flags for retreiving specific portion of the Windows security descriptor.

Parameters:

flags (int|None) – the flags for the security descriptor.

Raises:

TypeError – if the parameter is not int or None.

LDAPClient.set_server_chase_referrals(val)#

Turn on or off chasing LDAP referrals by the server. By turning off server-side referral chasing along with LDAPClient.ignore_referrals, search result can contain LDAPReference objects mixed with LDAPEntry objects.

Parameters:

val (bool) – enabling/disabling LDAP referrals chasing.

Raises:

TypeError – If the parameter is not a bool type.

LDAPClient.set_url(url)#

Set LDAP url for the client.

Parameters:

url (LDAPURL|str) – the LDAP url.

LDAPClient.auto_page_acquire#
The status of automatic page acquiring.

True by default.

LDAPClient.ca_cert#

The name of the CA certificate.

LDAPClient.ca_cert_dir#

The path to the CA certificate.

LDAPClient.cert_policy#

The certification policy.

LDAPClient.client_cert#

The name of the client certificate.

LDAPClient.client_key#

The key file to the client’s certificate.

LDAPClient.credentials#

A dict with the credential information. It cannot be set.

LDAPClient.extended_dn_format#

Format of the extended distinguished name. 0 means hexadecimal string format, 1 standard string format. If it is None, then it’s not set.

LDAPClient.ignore_referrals#

The status of ignoring referrals in search results. True by default.

LDAPClient.managedsait#

The status of using ManageDsaIT control.

LDAPClient.mechanism#

The chosen mechanism for authentication. It cannot be set.

LDAPClient.password_policy#

The status of using password policy.

LDAPClient.raw_attributes#

A list of attributes that should be kept in byte format.

LDAPClient.sd_flags#

The flags for the Windows security descriptor.

LDAPClient.server_chase_referrals#

The status of chasing referrals by the server. False by default.

Changed in version 1.3.0: Default value from True to False.

LDAPClient.tls#

A bool about TLS connection is required. It cannot be set.

LDAPClient.url#

The URL of the directory server.

LDAPConnection#

class bonsai.LDAPConnection(client: LDAPClient)#

Handles synchronous connection to an LDAP server.

Parameters:

client (LDAPClient) – a client object.

LDAPConnection.abandon(msg_id)#

Abandon an ongoing asynchronous operation associated with the given message id. Note that there is no guarantee that the LDAP server will be able to honor the request, which means the operation could be performed anyway. Nevertheless, it is a good programming paradigm to abandon unwanted operations (e.g after a timeout is exceeded).

Parameters:

msg_id (int) – the ID of an ongoing LDAP operation.

LDAPConnection.add(entry, timeout=None)#

Add new entry to the directory server.

Parameters:
  • entry (LDAPEntry) – the new entry.

  • timeout (float) – time limit in seconds for the operation.

Returns:

True, if the operation is finished.

Return type:

bool

LDAPConnection.close()#

Close LDAP connection.

LDAPConnection.delete(dname, timeout=None, recursive=False)#

Remove entry from the directory server.

Parameters:
  • dname (str|LDAPDN) – the string or LDAPDN format of the entry’s DN.

  • timeout (float) – time limit in seconds for the operation.

  • recursive (bool) – remove every entry of the given subtree recursively.

Returns:

True, if the operation is finished.

Return type:

bool

LDAPConnection.fileno()#

Return the file descriptor of the underlying socket that is used for the LDAP connection.

Returns:

The file descriptor.

Return type:

int

LDAPConnection.get_result(msg_id, timeout=None)#

Get the result of an ongoing asynchronous operation associated with the given message id. The method blocks the caller until the given timeout parameter is passed or the result is arrived. If the operation is not finished until the timeout, it returns None. If the timeout is None, it returns immediately.

Parameters:
  • msg_id (int) – the ID of an ongoing LDAP operation.

  • timeout (float) – time limit in seconds for waiting on the result.

Returns:

the result of the operation.

Return type:

depending on the type of the operation.

Raises:

bonsai.InvalidMessageID – if the message ID is invalid or the associated operation is already finished

LDAPConnection.open(timeout=None)#

Open the LDAP connection.

Parameters:

timeout (float) – time limit in seconds for the operation.

Returns:

The LDAPConnection object itself.

Return type:

LDAPConnection.

LDAPConnection.modify_password(user=None, new_password=None, old_password=None, timeout=None)#

Set a new password for the given user.

Parameters:
  • user (str|LDAPDN) – the identification of the user. If not set, the owner of the current LDAP session will be associated.

  • new_password (str) – the new password. If not set, the server will generate one and the new password will be returned by this method.

  • old_password (str) – the current password of the user.

  • timeout (float) – time limit in seconds for the operation.

Returns:

if the new_password is not set, then the generated password, True otherwise.

Return type:

str|bool

See also

RFC about the LDAP Password Modify extended operation RFC3062.

LDAPConnection.search(base=None, scope=None, filter_exp=None, attrlist=None, timeout=None, sizelimit=0, attrsonly=False, sort_order=None)#

Perform a search on the directory server. A base DN and a search scope is always necessary to perform a search, but these values - along with the attribute’s list and search filter - can also be set with the LDAPClient LDAP URL parameter. The parameters, which are passed to the LDAPConnection.search() method will overrule the previously set ones with the LDAP URL.

Setting sort_order will invoke server side sorting LDAP control, based on the provided attribute list.

>>> from bonsai import LDAPClient
>>> client = LDAPClient("ldap://localhost") # without additional parameters
>>> conn = client.connect()
>>> conn.search("ou=nerdherd,dc=bonsai,dc=test", 1, "(cn=ch*)", ["cn", "sn", "gn"])
[{'dn': <LDAPDN cn=chuck,ou=nerdherd,dc=bonsai,dc=test>, 'sn': ['Bartowski'], 'cn': ['chuck'],
'givenName': ['Chuck']}]
>>> client = LDAPClient("ldap://localhost/ou=nerdherd,dc=bonsai,dc=test?cn,sn,gn?one?(cn=ch*)") # with additional parameters
>>> conn = client.connect()
>>> conn.search()
[{'dn': <LDAPDN cn=chuck,ou=nerdherd,dc=bonsai,dc=test>, 'sn': ['Bartowski'], 'cn': ['chuck'],
'givenName': ['Chuck']}]
>>> conn.search(filter_exp="(cn=j*)")
[{'dn': <LDAPDN cn=jeff,ou=nerdherd,dc=bonsai,dc=test>, 'sn': ['Barnes'], 'cn': ['jeff'],
'givenName': ['Jeff']}]
Parameters:
  • base (str) – the base DN of the search.

  • scope (int) – the scope of the search. An LDAPSearchScope also can be used as value.

  • filter_exp (str) – string to filter the search in LDAP search filter syntax.

  • attrlist (list) – list of attribute’s names to receive only those attributes from the directory server.

  • timeout (float) – time limit in seconds for the search.

  • sizelimit (int) – the number of entries to limit the search.

  • attrsonly (bool) – if it’s set True, search result will contain only the name of the attributes without their values.

  • sort_order (list) – list of attribute’s names to use for server-side ordering, start name with ‘-’ for descending order.

Returns:

the search result.

Return type:

list

Perform a search that returns a paged search result. The number of entries on a page is limited with the page_size parameter. The return value is an ldapsearchiter which is an iterable object. By default, after returning the last entry on the page it automatically requests the next page from the server until the final page is delivered. This functionality can be disabled by setting the LDAPClient.auto_page_acquire to false. Then the next page can be acquired manually by calling the ldapsearchiter.acquire_next_page() method.

Parameters:
  • base (str) – the base DN of the search.

  • scope (int) – the scope of the search. An LDAPSearchScope also can be used as value.

  • filter_exp (str) – string to filter the search in LDAP search filter syntax.

  • attrlist (list) – list of attribute’s names to receive only those attributes from the directory server.

  • timeout (float) – time limit in seconds for the search.

  • sizelimit (int) – the number of entries to limit the search.

  • attrsonly (bool) – if it’s set True, search result will contain only the name of the attributes without their values.

  • sort_order (list) – list of attribute’s names to use for server-side ordering, start name with ‘-’ for descending order.

  • page_size (int) – the number of entries on a page.

Returns:

the search result.

Return type:

ldapsearchiter

Perform a search using virtual list view control. To perform the search the server side sort control has to be set with sort_order. The result set will be shifted to the offset or attrvalue and contains the specific number of entries after and before, set with after_count and before_count. The est_list_count is an estimation of the entire searched list that helps to the server to position the target entry.

The result of the operation is a tuple of a list and a dictionary. The dictionary contains the VLV server response: the target position and the real list size. Thi list contains the searched entries.

For further details using these controls please see LDAP controls.

Parameters:
  • base (str) – the base DN of the search.

  • scope (int) – the scope of the search. An LDAPSearchScope also can be used as value.

  • filter_exp (str) – string to filter the search in LDAP search filter syntax.

  • attrlist (list) – list of attribute’s names to receive only those attributes from the directory server.

  • timeout (float) – time limit in seconds for the search.

  • sizelimit (int) – the number of entries to limit the search.

  • attrsonly (bool) – if it’s set True, search result will contain only the name of the attributes without their values.

  • sort_order (list) – list of attribute’s names to use for server-side ordering, start name with ‘-’ for descending order.

  • offset (int) – an offset of the search result to select a target entry for virtual list view (VLV).

  • before_count (int) – the number of entries before the target entry for VLV.

  • after_count (int) – the number of entries after the target entry for VLV.

  • est_list_count (int) – the estimated content count of the entire list for VLV.

  • attrvalue – an attribute value (of the attribute that is used for sorting) for identifying the target entry for VLV.

Returns:

the search result.

Return type:

(list, dict)

LDAPConnection.whoami(timeout=None)#

This method can be used to obtain authorization identity.

Parameters:

timeout (float) – time limit in seconds for the operation.

Returns:

the authorization ID.

Return type:

str

See also

RFC about the LDAP Who am I extended operation RFC4532.

LDAPConnection.closed#

A readonly attribute about the connection’s state.

LDAPConnection.is_async#

A readonly attribute to define that the connections is asynchronous.

LDAPDN#

Class for representing LDAP distinguished names.

See also

RFC about LDAP: String Representation of Distinguished Names RFC4514.

Example for working with LDAPDN objects.

>>> import bonsai
>>> dn = bonsai.LDAPDN("cn=testuser,dc=bonsai,dc=test")
>>> dn
<LDAPDN cn=testuser,dc=bonsai,dc=test>
>>> dn.rdns # Get RDNs in tuple format.
((('cn', 'testuser'),), (('dc', 'bonsai'),), (('dc', 'test'),))
>>> str(dn) # Convert to string.
'cn=testuser,dc=bonsai,dc=test'
>>> dn[1] # Get the second RDN.
'dc=bonsai'
>>> dn[0] # Get the first RDN.
'cn=testuser'
>>> dn[1] = "ou=nerdherd,dc=bonsai" # Change the second RDN.
>>> dn
<LDAPDN cn=testuser,ou=nerdherd,dc=bonsai,dc=test>
>>> other_dn = bonsai.LDAPDN("cn=testuser,ou=nerdherd,dc=bonsai,dc=test")
>>> dn == other_dn
True
>>> dn[1:3] # Get the second and third RDN.
'ou=nerdherd,dc=bonsai'
>>> dn[1:3] = 'ou=buymore,dc=bonsai' # Change them.
>>> dn
<LDAPDN cn=testuser,ou=buymore,dc=bonsai,dc=test>
class bonsai.LDAPDN(strdn: str)#

A class for handling valid LDAP distinguished name.

Parameters:

strdn (str) – a string representation of LDAP distinguished name.

LDAPDN.__getitem__(idx)#

Return the string format of the relative distinguished names in the LDAPDN.

Parameters:

idx (int) – the indices of the RDNs.

Returns:

the string format of the RDNs.

Return type:

str

LDAPDN.__setitem__(idx, value)#

Set the string format of the relative distinguished names in the LDAPDN.

Parameters:
  • idx (int) – the indices of the RDNs.

  • value (str) – the new RDNs.

LDAPDN.__eq__(other)#

Check equality of two LDAPDNs by their string formats or their sanitized string formats.

LDAPDN.__str__() str#

Return the full string format of the distinguished name.

LDAPDN.rdns#

The tuple of relative distinguished name.

LDAPEntry#

class bonsai.LDAPEntry(dn[, conn])#
LDAPEntry.change_attribute(name, optype, *values)#

Change an attribute of the entry with explicit LDAP modification type by listing the values as parameters. An attribute can be removed entirely if the optype is delete and no values are passed. This method can be useful for changing write-only attributes (e.g. passwords).

Parameters:
  • name (str) – the name of the attribute.

  • optype (int) – the operation type, 0 for adding, 1 for deleting and 2 for replacing. An LDAPModOp also can be used as value.

  • *values – the new value or values of the attribute.

Note

It is possible to create an inconsistent state that the server will reject. To get a clean state use LDAPEntry.clear_attribute_changes().

LDAPEntry.clear() None#

Remove all items from the dictionary.

LDAPEntry.clear_attribute_changes(name)#

Clear all added and deleted changes of an attribute.

Parameters:

name (str) – the name of the attribute.

LDAPEntry.delete(timeout=None, recursive=False)#

Remove LDAP entry from the dictionary server.

Parameters:
  • timeout (float) – time limit in seconds for the operation.

  • recursive (bool) – remove every entry of the given subtree recursively.

Returns:

True, if the operation is finished.

Return type:

bool

LDAPEntry.get(key, default=None)#

Return the value for key if key is in the LDAPEntry, else default. (Same as dict’s get method.)

LDAPEntry.items(exclude_dn=False)#

Same functionality as dict.items() but with an optional exclude_dn keyword-only argument. When exclude_dn is True it returns a generator of the LDAPEntry’s key-value pairs without the dn key and value.

Parameters:

exclude_dn (bool) – exclude dn key from the list.

Returns:

sequence of key-value pairs.

Return type:

dict_items, generator

LDAPEntry.keys(exclude_dn=False)#

Same functionality as dict.keys() but with an optional exclude_dn keyword-only argument. When exclude_dn is True it returns a generator of the LDAPEntry’s keys without the dn key.

Parameters:

exclude_dn (bool) – exclude dn key from the list.

Returns:

sequence of keys.

Return type:

dict_keys, generator

Note

Be aware when the exclude_dn argument of LDAPEntry.items(), LDAPEntry.keys() or LDAPEntry.values() is set to True you lose the benefits of dict views and get a generator object that will be sensitive of adding and removing items to the entry.

LDAPEntry.modify(timeout=None)#

Send entry’s modifications to the dictionary server.

Parameters:

timeout (float) – time limit in seconds for the operation.

Returns:

True, if the operation is finished.

Return type:

bool

LDAPEntry.rename(newdn, timeout=None, delete_old_rdn=True)#

Change the entry’s distinguished name.

Parameters:
  • newdn (str|LDAPDN) – the new DN of the entry.

  • timeout (float) – time limit in seconds for the operation.

  • delete_old_rdn (bool) – remove old RDN with renaming.

Returns:

True, if the operation is finished.

Return type:

bool

LDAPEntry.update(*args, **kwds)#

Update the LDAPEntry with the key/value pairs from other, overwriting existing keys. (Same as dict’s update method.)

LDAPEntry.values(exclude_dn=False)#

Same functionality as dict.values() but with an optional exclude_dn keyword-only argument. When exclude_dn is True it returns a generator of the LDAPEntry’s values without the value of the dn key.

Parameters:

exclude_dn (bool) – exclude dn key from the list.

Returns:

sequence of values.

Return type:

dict_values, generator

LDAPEntry.connection#

The LDAPConnection object of the entry. Needs to be set for any LDAP operations.

LDAPEntry.dn#

The distinguished name of the entry.

>>> from bonsai import LDAPEntry
>>> anna = LDAPEntry('cn=anna,ou=nerdherd,dc=bonsai,dc=test')
>>> anna.dn
<LDAPDN cn=anna,ou=nerdherd,dc=bonsai,dc=test>
>>> str(anna.dn)
'cn=anna,ou=nerdherd,dc=bonsai,dc=test'
LDAPEntry.extended_dn#

The extended DN of the entry. It is None, if the extended DN control is not set or not supported. The attribute is read-only.

LDAPModOp#

class bonsai.LDAPModOp(value)#

Enumeration for LDAP modification operations.

LDAPModOp.ADD = 0#

For adding new values to the attribute.

LDAPModOp.DELETE = 1#

For deleting existing values from the attribute list.

LDAPModOp.REPLACE = 2#

For replacing the existing attribute values.

LDAPReference#

class bonsai.LDAPReference(client, references)#

Object for handling an LDAP reference.

Parameters:
  • client (LDAPClient) – a client object.

  • references (list) – list of valid LDAP URLs (as string or LDAPURL objects).

LDAPReference.client#

The LDAP client.

LDAPReference.references#

The list of LDAPURLs of the references.

LDAPSearchScope#

class bonsai.LDAPSearchScope(value)#

Enumeration for LDAP search scopes.

LDAPSearchScope.BASE = 0#

For searching only the base DN.

LDAPSearchScope.ONELEVEL = 1#

For searching one tree level under the base DN.

LDAPSearchScope.ONE = 1#

Alias for LDAPSearchScope.ONELEVEL.

LDAPSearchScope.SUBTREE = 2#

For searching the entire subtree, including the base DN.

LDAPSearchScope.SUB = 2#

Alias for LDAPSearchScope.SUBTREE.

LDAPURL#

See also

RFC about LDAP: Uniform Resource Locator RFC4516.

class bonsai.LDAPURL(str)#

LDAP URL object for handling LDAP connection informations, such as hostname, port, LDAP bind DN, search attributes, scope (base,sub or one) filter, and extensions. If strurl is None, then the default url is ldap://localhost:389.

Parameters:

strurl (str) – string representation of a valid LDAP URL. Must be started with ldap://, ldaps:// or ldapi://.

Raises:

ValueError – if the string parameter is not a valid LDAP URL.

An example of a valid LDAP URL with port number, base DN, list of attributes and search filter:

>>> from bonsai import LDAPURL
>>> url = LDAPURL("ldap://localhost:789/ou=nerdherd,dc=bonsai,dc=test?cn,sn,gn?sub?(cn=c*)")
>>> url
<LDAPURL ldap://localhost:789/ou=nerdherd,dc=bonsai,dc=test?cn,sn,gn?sub?(cn=c*)>
>>> url.basedn
<LDAPDN ou=nerdherd,dc=bonsai,dc=test>
>>> url.attributes
['cn', 'sn', 'gn']
LDAPURL.get_address() str#

Return the full address of the host.

>>> import bonsai
>>> url = bonsai.LDAPURL("ldaps://example.com/cn=test,dc=bonsai,dc=test??sub")
>>> url
<LDAPURL ldaps://example.com:636/cn=test,dc=bonsai,dc=test??sub>
>>> url.get_address()
'ldaps://example.com:636'
LDAPURL.__str__() str#

Returns the full format of LDAP URL.

LDAPURL.attributes#

The searching attributes.

LDAPURL.basedn#

The LDAP distinguished name for binding.

LDAPURL.host#

The hostname.

LDAPURL.port#

The portnumber.

LDAPURL.filter_exp#

The searching filter expression.

LDAPURL.scope#

The searching scope.

LDAPURL.scope_num#

Return the searching scope number.

LDAPURL.scheme#

The URL scheme.

LDAPValueList#

class bonsai.LDAPValueList(items)#

Modified list that tracks added and deleted values. It also contains only unique elements. The elements are compared to their lower-cased string representations.

A new LDAPValueList can be created optionally from an existing sequence object.

Parameters:

items – a sequence object.

Raises:

ValueError – if items has a non-unique element.

LDAPValueList.__contains__(item)#

Return key in self.

LDAPValueList.__delitem__(idx)#

Delete self[key].

LDAPValueList.__setitem__(idx, value)#

Set self[key] to value.

LDAPValueList.__add__(other)#

Return self+value.

LDAPValueList.__iadd__(other)#

Implement self+=value.

LDAPValueList.__mul__(value)#

Return self*value.

LDAPValueList.append(item)#

Add a unique item to the end of the LDAPValueList.

Parameters:

item – New item.

Raises:

ValueError – if the item is not unique.

LDAPValueList.extend(items)#

Extend the LDAPValueList by appending all the items in the given list. All element in items must be unique and also not represented in the LDAPValueList.

Parameters:

items – List of new items.

Raises:

ValueError – if any of the items is already in the list.

LDAPValueList.insert(idx, value)#

Insert a unique item at a given position.

Parameters:
  • idx (int) – the position.

  • value – the new item.

Raises:

ValueError – if the item is not unique.

LDAPValueList.remove(value)#

Remove the first item from the LDAPValueList whose value is value.

Parameters:

value – the item to be removed.

Raises:

ValueError – if value is not int the list.

LDAPValueList.pop(idx=-1)#

Remove the item at the given position in the LDAPValueList, and return it. If no index is specified, pop() removes and returns the last item in the list.

Parameters:

idx (int) – optional index.

LDAPValueList.clear() None#

Remove all items from the LDAPValueList.

LDAPValueList.copy() LDAPValueList#

Return a shallow copy of the LDAPValueList. This includes the status and the previously added and deleted items.

Return type:

LDAPValueList

Returns:

The copy of the LDAPValueList.

LDAPValueList.status#
The status of the LDAPValueList. The status can be:
  • 0: unchanged.

  • 1: added or deleted item to list.

  • 2: replaced the entire list.

bonsai.active_directory#

ACE#

class bonsai.active_directory.ACE(ace_type, flags, mask, trustee_sid, object_type, inherited_object_type, application_data)#

A class for the access control entry, that encodes the user rights afforded to a principal.

Parameters:
  • ace_type (ACEType) – the type of the ACE.

  • flags (Set[ACEFlag]) – the set of flags for the ACE.

  • mask (int) – the access mask to encode the user rights as an int.

  • trustee_sid (SID) – the SID of the trustee.

  • object_type (uuid.UUID|None) – a UUID that identifies a property set, property, extended right, or type of child object.

  • inherited_object_type (uuid.UUID|None) – a UUID that identifies the type of child object that can inherit the ACE.

  • application_data (bytes) – optional application data.

Note

For more details, see offical Microsoft docs about ACE.

classmethod ACE.from_binary(data)#

Create an ACE object from a binary blob.

Parameters:

data (bytes) – a little-endian byte ordered byte input.

Returns:

A new ACE instance.

Return type:

ACE

Raises:
  • TypeError – when the parameter is not bytes.

  • ValueError – when the input cannot be parsed as an ACE object.

ACE.to_binary()#

Convert ACE object to binary form with little-endian byte order.

Returns:

Bytes of the binary ACE instance

Return type:

bytes

ACE.__eq__(other)#

Check that ACE object equals to the other object. If the other is also an ACE object, then basically comapre their byte representations.

Parameters:

other (object) – the other object to compare.

ACE.__str__()#

Return the SDDL string representation of the ACE object.

ACE.set_access_rights(rights)#

Set the access rights for the ACE object. The rights parameter can be a set of ACERight objects or an integer.

Parameters:

rights (int|Set[ACERight]) – the access rights

Raises:
  • TypeError – if the parameter not an int or not every item of the set is an ACERight object.

  • ValueError – if the provided number is not a valid access mask.

ACE.set_application_data(data)#

Set application data for the ACE object.

Parameters:

data (bytes) – the application data.

Raises:

TypeError – if the data is not bytes.

ACE.set_flags(flags)#

Set flags for the ACE object.

Parameters:

flags (Set[ACEFlag]) – a set of ACEFlag objects.

Raises:

TypeError – if any of the elements in the set is not an ACEFlag object.

ACE.set_object_type(object_type)#

Set the object type for the ACE object.

Parameters:

object_type (uuid.UUID|None) – the uuid of the object type.

Raises:

TypeError – if the parameter is neither an UUID nor None.

ACE.set_inherited_object_type(object_type)#

Set the inherited object type for the ACE object.

Parameters:

object_type (uuid.UUID|None) – the uuid of the inherited object type.

Raises:

TypeError – if the parameter is neither an UUID nor None.

ACE.set_type(ace_type)#

Set type for the ACE object.

Parameters:

ace_type (ACEType) – the type of the ACE object.

Raises:

TypeError – if the parameter is not an ACEType.

ACE.set_trustee_sid(sid)#

Set the trustee SID for the ACE object.

Parameters:

sid (SID) – the trustee SID of the ACE object.

Raises:

TypeError – if the parameter is not a SID.

ACE.application_data#

The possible application data.

ACE.flags#

The flags of the ACE.

ACE.is_inherited#

Return true if the ACE object is inherited.

ACE.inherited_object_type#

The uuid of the inherited object type.

ACE.mask#

The access mask

ACE.object_type#

The uuid of the object type.

ACE.size#

The binary size of ACE in bytes.

ACE.trustee_sid#

The sid of the trustee.

ACEFlag#

class bonsai.active_directory.ACEFlag(value)#

ACE type-specific control flags.

OBJECT_INHERIT = 1#
CONTAINER_INHERIT = 2#
NO_PROPAGATE_INHERIT = 4#
INHERIT_ONLY = 8#
INHERITED = 16#
SUCCESSFUL_ACCESS = 64#
FAILED_ACCESS = 128#
property short_name: str#

The SDDL short name of the flag.

ACERight#

class bonsai.active_directory.ACERight(value)#

The rights of the ACE.

GENERIC_READ = 2147483648#
GENERIC_WRITE = 67108864#
GENERIC_EXECUTE = 536870912#
GENERIC_ALL = 268435456#
MAXIMUM_ALLOWED = 33554432#
ACCESS_SYSTEM_SECURITY = 16777216#
SYNCHRONIZE = 1048576#
WRITE_OWNER = 524288#
WRITE_DACL = 262144#
READ_CONTROL = 131072#
DELETE = 65536#
DS_CONTROL_ACCESS = 256#
DS_CREATE_CHILD = 1#
DS_DELETE_CHILD = 2#
ACTRL_DS_LIST = 4#
DS_SELF = 8#
DS_READ_PROP = 16#
DS_WRITE_PROP = 32#
DS_DELETE_TREE = 64#
DS_LIST_OBJECT = 128#
property short_name: str#

The SDDL short name of the access right.

ACEType#

class bonsai.active_directory.ACEType(value)#

Type of the ACE.

ACCESS_ALLOWED = 0#
ACCESS_DENIED = 1#
SYSTEM_AUDIT = 2#
SYSTEM_ALARM = 3#
ACCESS_ALLOWED_COMPOUND = 4#
ACCESS_ALLOWED_OBJECT = 5#
ACCESS_DENIED_OBJECT = 6#
SYSTEM_AUDIT_OBJECT = 7#
SYSTEM_ALARM_OBJECT = 8#
ACCESS_ALLOWED_CALLBACK = 9#
ACCESS_DENIED_CALLBACK = 10#
ACCESS_ALLOWED_CALLBACK_OBJECT = 11#
ACCESS_DENIED_CALLBACK_OBJECT = 12#
SYSTEM_AUDIT_CALLBACK = 13#
SYSTEM_ALARM_CALLBACK = 14#
SYSTEM_AUDIT_CALLBACK_OBJECT = 15#
SYSTEM_ALARM_CALLBACK_OBJECT = 16#
SYSTEM_MANDATORY_LABEL = 17#
SYSTEM_RESOURCE_ATTRIBUTE = 18#
SYSTEM_SCOPED_POLICY_ID = 19#
property short_name: str#

The SDDL short name of the type.

property is_object_type: bool#

Flag for ACE types with objects.

property is_access_allowed: bool#

Flag for ACE types that allow access.

property is_access_denied: bool#

Flag for ACE types that deny access.

ACL#

class bonsai.active_directory.ACL(revision, aces)#

The access control list (ACL) is used to specify a list of individual access control entries (ACEs). An ACL and an array of ACEs comprise a complete access control list.

Parameters:
  • revision (ACLRevision) – the revision of the ACL.

  • aces (List[ACE]) – list of ACE.

Note

For more details, see offical Microsoft docs about ACL.

classmethod ACL.from_binary(data)#

Create an ACL object from a binary blob.

Parameters:

data (bytes) – a little-endian byte ordered byte input.

Returns:

A new ACL instance.

Return type:

ACL

Raises:
  • TypeError – when the parameter is not bytes.

  • ValueError – when the input cannot be parsed as an ACL object.

ACL.to_binary()#

Convert ACL object to binary form with little-endian byte order.

Returns:

Bytes of the binary ACL instance

Return type:

bytes

ACL.set_aces(aces)#

Set a list of ACE object to the ACL.

Parameters:

aces (List[ACE]) – a list of ACE objects.

Raises:

TypeError – if not every element in the list is an ACE object.

ACL.aces#

The list of ACE objects.

ACL.revision#

The revision of ACL.

ACL.size#

The binary size in bytes.

ACLRevision#

class bonsai.active_directory.ACLRevision(value)#

The ACL revision.

ACL_REVISION = 2#
ACL_REVISION_DS = 4#

SecurityDescriptor#

class bonsai.active_directory.SecurityDescriptor(control, owner_sid, group_sid, sacl, dacl, revision=1, sbz1=0)#

A class that defines the security attributes of an object. These attributes specify who owns the object; who can access the object and what they can do with it; what level of audit logging can be applied to the object; and what kind of restrictions apply to the use of the security descriptor. It can contain two types of ACL:

  • A discretionary access control list (DACL) is controlled by the owner of an object or anyone granted WRITE_DAC access to the object. It specifies the access particular users and groups can have to an object. For example, the owner of a file can use a DACL to control which users and groups can and cannot have access to the file.

  • A system access control list (SACL) is similar to the DACL, except that the SACL is used to audit rather than control access to an object. When an audited action occurs, the operating system records the event in the security log. Each ACE in a SACL has a header that indicates whether auditing is triggered by success, failure, or both; a SID that specifies a particular user or security group to monitor; and an access mask that lists the operations to audit.

Parameters:
  • control (dict) – a dict that specifies control access bit flags.

  • owner_sid (SID|None) – the SID of the owner of the object.

  • group_sid (SID|None) – the SID of the group of the object.

  • sacl (ACL|None) – the system access control list.

  • dacl (ACL|None) – the discretionary access control list.

  • revision (int) – the revision of the security descriptor.

  • sbz1 (int) – reserved value.

Note

For more details, see offical Microsoft docs about SECURITY_DESCRIPTOR.

classmethod SecurityDescriptor.from_binary(data)#

Create a SecurityDescriptor object from a binary blob.

Parameters:

data (bytes) – a little-endian byte ordered byte input.

Returns:

A new SecurityDescriptor instance.

Return type:

SecurityDescriptor

Raises:
  • TypeError – when the parameter is not bytes.

  • ValueError – when the input cannot be parsed as a SecurityDescriptor object.

SecurityDescriptor.to_binary()#

Convert SecurityDescriptor object to binary form with little-endian byte order.

Returns:

Bytes of the binary SecurityDescriptor instance

Return type:

bytes

SecurityDescriptor.set_control(control)#

Set the control access bit flags for the SecurityDescriptor object.

Parameters:

control (dict|int) – the control flag either as an int or a dict.

Raises:
  • ValueError – if the provided number is not valid.

  • TypeError – if the parameter neither an int nor a bool value only dict.

SecurityDescriptor.set_owner_sid(owner_sid)#

Set the owner SID for the the SecurityDescriptor object.

Parameters:

owner_sid (SID) – the new owner SID.

Raises:

TypeError – if the parameter is not a SID object.

SecurityDescriptor.set_group_sid(group_sid)#

Set the group SID for the the SecurityDescriptor object.

Parameters:

group_sid (SID) – the new group SID.

Raises:

TypeError – if the parameter is not a SID object.

SecurityDescriptor.set_dacl(dacl)#

Set the discretionary ACL for the the SecurityDescriptor object. It also sets the dacl_present in the control access bit flags accordingly.

Parameters:

dacl (ACL|None) – the ACL object or None.

Raises:

TypeError – if the parameter is not a ACL object or None.

SecurityDescriptor.set_sacl(sacl)#

Set the system ACL for the the SecurityDescriptor object. It also sets the sacl_present in the control access bit flags accordingly.

Parameters:

dacl (ACL|None) – the ACL object or None.

Raises:

TypeError – if the parameter is not a ACL object or None.

SecurityDescriptor.control#

The dict of the control access bit flags.

SecurityDescriptor.dacl#

The discretionary ACL.

SecurityDescriptor.group_sid#

The SID of the group.

SecurityDescriptor.owner_sid#

The SID of the owner.

SecurityDescriptor.revision#

The revision of the security descriptor.

SecurityDescriptor.sacl#

The system ACL.

SecurityDescriptor.sbz1#

Reserved field in the security descriptor structure.

SID#

class bonsai.active_directory.SID(str_rep=None, bytes_le=None)#

A class for representing a Security Identifier, that identifies users, groups, and computer accounts on a Microsoft Windows platform.

Parameters:
  • str_rep (str|None) – a string representation of a SID.

  • bytes_le (bytes|None) – a bytes representation of a SID in little-endian byte order.

Raises:
  • TypeError – when the type of the parameters are invalid, or both parameters are given.

  • ValueError – when the given parameter cannot be parsed as a valid SID.

Note

For more details, see offical Microsoft docs about SID.

SID.__eq__(other)#

Check equality of two SIDs by their identifier_authority and list of subauthorities, or if the other object is a string than by their string formats.

SID.__repr__()#

The representation of SID class.

SID.__str__()#

Return the string format of the SID.

SID.bytes_le#

The byte format of the SID in little-endian byte order.

SID.identifier_authority#

The indentifier that indicates the authority under which the SID was created.

SID.revision#

The revision level of the SID.

SID.sddl_alias#

The string SDDL alias of the SID if it exists, otherwise it’s None.

SID.size#

The binary size of the SID in bytes.

SID.subauthorities#

A tuple of subauthorities that uniquely identifies a principal relative to the identifier authority.

UserAccountControl#

class bonsai.active_directory.UserAccountControl(flags)#

A class for parsing UserAccountControl field.

Parameters:

flags (int) – integer representing the property flags.

Raises:

TypeError – if flags parameter is not an int.

Note

For more details, see offical Microsoft docs about UserAccountControl.

UserAccountControl.properties#

Dictionary of the UserAccountControl properties.

UserAccountControl.value#

The integer value of the properties.

bonsai.asyncio#

AIOLDAPConnection#

class bonsai.asyncio.AIOLDAPConnection(client, loop=None)#

Asynchronous LDAP connection object that works with asyncio. It has the same methods and properties as bonsai.LDAPConnection, but with the exception of bonsai.LDAPConnection.close() and bonsai.LDAPConnection.fileno() all of them are awaitable.

Parameters:
  • client (LDAPClient) – a client object.

  • loop – an asyncio IO loop.

Note

The default asyncio event loop is changed with Python 3.8 on Windows to ProactorEventLoop. Unfortunately, bonsai’s asyncio connection requires the old SelectorEventLoop. Make sure to change it back before using the module:

if sys.platform == 'win32':
    import asyncio
    asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())

Getting NotImplementedError from the add_reader method of the event loop may indicate that it has not been properly set.

AIOConnectionPool#

class bonsai.asyncio.AIOConnectionPool(client: LDAPClient, minconn: int = 1, maxconn: int = 10, loop: AbstractEventLoop | None = None, **kwargs: Any)#

A connection pool that can be used with asnycio tasks. It’s inherited from bonsai.pool.ConnectionPool.

Parameters:
  • client (LDAPClient) – the bonsai.LDAPClient that’s used to create connections.

  • minconn (int) – the minimum number of connections that’s created after the pool is opened.

  • maxconn (int) – the maximum number of connections in the pool.

  • **kwargs – additional keyword arguments that are passed to the bonsai.LDAPClient.connect() method.

Raises:

ValueError – when the minconn is negative or the maxconn is less than the minconn.

bonsai.gevent#

GeventLDAPConnection#

class bonsai.gevent.GeventLDAPConnection(client: LDAPClient)#

Asynchronous LDAP connection object that works with Gevent. It has the same methods and properties as bonsai.LDAPConnection.

Parameters:

client (LDAPClient) – a client object.

bonsai.ldif#

LDIFReader#

class bonsai.LDIFReader(input_file, autoload=True, max_length=76)#

Create an object for reading LDAP entries from an LDIF format file as described in RFC 2849.

Parameters:
  • input_file (TextIO) – a file-like input object in text mode.

  • autoload (bool) – allow to automatically load external sources from URL.

  • max_length (int) – the maximal line length of the LDIF file.

Raises:

TypeError – if the input_file is not a file-like object or max_length is not an int.

Example of reading an LDIF file:

import bonsai

with open("./users.ldif") as fileobj:
    reader = bonsai.LDIFReader(fileobj)
    for entry in reader:
        print(entry.dn)
LDIFReader.autoload#

Enable/disable autoloading resources in LDIF files.

LDIFReader.input_file#

The file-like object of an LDIF file.

LDIFReader.resource_handlers#

A dictionary of supported resource types. The keys are the schemes, while the values are functions that expect the full URL parameters and return the loaded content in preferably bytes format.

LDIFWriter#

class bonsai.LDIFWriter(output_file, max_length=76)#

Create an object for serialising LDAP entries in LDIF format as described in RFC 2849.

Parameters:
  • output_file (TextIO) – a file-like output object in text mode.

  • max_length (int) – the maximal line length of the LDIF file.

Raises:

TypeError – if the output_file is not a file-like object or max_length is not an int.

LDIFWriter.write_entry(entry)#

Write an LDAP entry to the file in LDIF format.

Parameters:

entry (LDAPEntry) – the LDAP entry to serialise.

>>> import bonsai
>>> output = open("./out.ldif", "w")
>>> writer = bonsai.LDIFWriter(output)
>>> entry = bonsai.LDAPEntry("cn=test")
>>> entry["cn"] = "test"
>>> writer.write_entry(entry)
LDIFWriter.write_entries(entries, write_version=True)#

Write multiple LDAP entry to file in LDIF format, separated with newline and with optional version header.

Parameters:
  • entries (list) – list of LDAP entries.

  • write_version (bool) – if it’s True, write version header.

>>> client = bonsai.LDAPClient()
>>> conn = client.connect()
>>> res = conn.search("ou=nerdherd,dc=bonsai,dc=test", bonsai.LDAPSearchScope.ONE)
>>> output = open("./out.ldif", "w")
>>> writer = bonsai.LDIFWriter(output)
>>> writer.write_entries(res)
LDIFWriter.write_changes(entry)#

Write an LDAP entry’s changes to file in an LDIF-CHANGE format. Only attribute modifications are serialised.

Parameters:

entry (LDAPEntry) – the LDAP entry to serialise.

LDIFWriter.output_file#

The file-like object for an LDIF file.

bonsai.pool#

ConnectionPool#

class bonsai.pool.ConnectionPool(client: LDAPClient, minconn: int = 1, maxconn: int = 10, **kwargs: Any)#

A connection pool object for managing multiple open connections.

Parameters:
  • client (LDAPClient) – the bonsai.LDAPClient that’s used to create connections.

  • minconn (int) – the minimum number of connections that’s created after the pool is opened.

  • maxconn (int) – the maximum number of connections in the pool.

  • **kwargs – additional keyword arguments that are passed to the bonsai.LDAPClient.connect() method.

Raises:

ValueError – when the minconn is negative or the maxconn is less than the minconn.

>>> import bonsai
>>> from bonsai.pool import ConnectionPool
>>> client = bonsai.LDAPClient()
>>> pool = ConnectionPool(client, 1, 2)
>>> pool.open()
>>> conn = pool.get()
>>> conn.whomai()
'anonymus'
>>> pool.put(conn)
>>> pool.close()
ConnectionPool.close() None#

Close the pool and all of its managed connections.

ConnectionPool.get() T#

Get a connection from the connection pool.

Raises:
  • EmptyPool – when the pool is empty.

  • ClosedPool – when the method is called on a closed pool.

Returns:

an LDAP connection object.

ConnectionPool.open() None#

Open the connection pool by initialising the minimal number of connections.

ConnectionPool.put(conn: T) None#

Put back a connection to the connection pool. The caller is allowed to close the connection (if, for instance, it is in an error state), in which case it’s not returned to the pool and a subsequent get will grow the pool if needed.

Parameters:

conn (LDAPConnection) – the connection managed by the pool.

Raises:
  • ClosedPool – when the method is called on a closed pool.

  • PoolError – when tying to put back an object that’s not managed by this pool.

ConnectionPool.spawn(*args: Any, **kwargs: Any) Generator[T, None, None]#

Context manager method that acquires a connection from the pool and returns it on exit. It also opens the pool if it hasn’t been opened before.

Params *args:

the positional arguments passed to bonsai.pool.ConnectionPool.get().

Params **kwargs:

the keyword arguments passed to bonsai.pool.ConnectionPool.get().

Example usage:

import bonsai
from bonsai.pool import ConnectionPool

client = bonsai.LDAPClient()
pool = ConnectionPool(client)
with pool.spawn() as conn:
    print(conn.whoami())

ThreadedConnectionPool#

class bonsai.pool.ThreadedConnectionPool(client: LDAPClient, minconn: int = 1, maxconn: int = 10, block: bool = True, **kwargs: Any)#

A connection pool that can be shared between threads. It’s inherited from bonsai.pool.ConnectionPool.

Parameters:
  • client (LDAPClient) – the bonsai.LDAPClient that’s used to create connections.

  • minconn (int) – the minimum number of connections that’s created after the pool is opened.

  • maxconn (int) – the maximum number of connections in the pool.

  • block (bool) – when it’s True, the get method will block when no connection is available in the pool.

  • **kwargs – additional keyword arguments that are passed to the bonsai.LDAPClient.connect() method.

Raises:

ValueError – when the minconn is negative or the maxconn is less than the minconn.

ThreadedConnectionPool.get(timeout: float | None = None) LDAPConnection#

Get a connection from the connection pool.

Parameters:

timeout (float) – a timeout until waiting for free connection.

Raises:
  • EmptyPool – when the pool is empty.

  • ClosedPool – when the method is called on a closed pool.

Returns:

an LDAP connection object.

bonsai.tornado#

TornadoLDAPConnection#

class bonsai.tornado.TornadoLDAPConnection(client, ioloop=None)#

Asynchronous LDAP connection object that works with Torando. It has the same methods and properties as bonsai.LDAPConnection.

Parameters:
  • client (LDAPClient) – a client object.

  • ioloop – a Tornado IO loop.

bonsai.trio#

TrioLDAPConnection#

class bonsai.trio.TrioLDAPConnection(client)#

Asynchronous LDAP connection object that works with trio. It has the same methods and properties as bonsai.LDAPConnection, but with the exception of bonsai.LDAPConnection.close() and bonsai.LDAPConnection.fileno() all of them are awaitable.

Parameters:

client (LDAPClient) – a client object.

_bonsai#

ldapsearchiter#

Helper class for paged search result.

ldapsearchiter.acquire_next_page()#

Request the next page of result. Returns with the message ID of the search operation. This method can only be used if the LDAPClient.auto_page_acquire is False.

Returns:

an ID of the next search operation.

Return type:

int.

Errors#

class bonsai.LDAPError#

General LDAP error.

class bonsai.LDIFError#

General exception that is raised during reading or writing an LDIF file.

class bonsai.AffectsMultipleDSA#

Raised, when multiple directory server agents are affected.

class bonsai.AlreadyExists#

Raised, when try to add an entry and it already exists in the dictionary.

class bonsai.AuthenticationError#

Raised, when authentication is failed with the server.

class bonsai.AuthMethodNotSupported#

Raised, when the chosen authentication method is not supported.

class bonsai.ConnectionError#

Raised, when client is not able to connect to the server.

class bonsai.ClosedConnection#

Raised, when try to perform LDAP operation with closed connection.

class bonsai.InsufficientAccess#

Raised, when the user has insufficient access rights.

class bonsai.InvalidDN#

Raised, when dn string is not a valid distinguished name.

class bonsai.InvalidMessageID#

Raised, when try to get the result with a message ID that belongs to an unpending or already finished operation.

class bonsai.NoSuchAttribute#

Raised, when the given attribute of an entry does not exist.

class bonsai.NoSuchObjectError#

Raised, when operation (except search) is performed on an entry that is not found in the directory.

class bonsai.NotAllowedOnNonleaf#

Raised, when the operation is not allowed on a nonleaf object.

class bonsai.ObjectClassViolation#

Raised, when try to add or modify an LDAP entry and it violates the object class rules.

class bonsai.ProtocolError#

Raised, when protocol error is happened.

class bonsai.SizeLimitError#

Raised, when the search operation exceeds the client side size limit or server side size limit that’s applied to the bound user.

class bonsai.TimeoutError#

Raised, when the specified timeout is exceeded.

class bonsai.TypeOrValueExists#

Raised, when the attribute already exists or the value has been already assigned.

class bonsai.UnwillingToPerform#

Raised, when the server is not willing to handle requests.

class bonsai.PasswordPolicyError#

General exception for password policy errors.

class bonsai.AccountLocked#

Raised, when the password policy is set, available on the server and the user’s account is locked.

class bonsai.ChangeAfterReset#

Raised, when the password policy is set, available on the server and it signifies that the password must be changed before the user will be allowed to perform any operation (except bind and modify).

class bonsai.InsufficientPasswordQuality#

Raised, when the password policy is set, available on the server and the user’s password is not strong enough.

class bonsai.MustSupplyOldPassword#

Raised, when the password policy is set, available on the server and the existing password is not specified.

class bonsai.PasswordExpired#

Raised, when the password policy is set, available on the server and the user’s password is expired.

class bonsai.PasswordInHistory#

Raised, when the password policy is set, available on the server and the user’s password is in the history.

class bonsai.PasswordModNotAllowed#

Raised, when the password policy is set, available on the server and the user is restricted from changing her password.

class bonsai.PasswordTooShort#

Raised, when the password policy is set, available on the server and the user’s password is too short to be set.

class bonsai.PasswordTooYoung#

Raised, when the password policy is set, available on the server and the user’s password is too young to be modified.

class bonsai.pool.PoolError#

Connection pool related errors.

class bonsai.pool.ClosedPool#

Raised, when the connection pool is closed.

class bonsai.pool.EmptyPool#

Raised, when the connection pool is empty.

Utility functions#

bonsai.utils.escape_attribute_value(attrval)#

Escapes the special character in an attribute value based on RFC 4514.

Parameters:

attrval (str) – the attribute value.

Returns:

The escaped attribute value.

Return type:

str

>>> import bonsai
>>> bonsai.escape_attribute_value(",cn=escaped")
'\\,cn\\=escaped'
bonsai.utils.escape_filter_exp(filter_exp)#

Escapes the special characters in an LDAP filter based on RFC 4515.

Parameters:

filter_exp (str) – the unescaped filter expression.

Returns:

the escaped filter expression.

Return type:

str

>>> import bonsai
>>> filter_exp = "(&(userID={0})(objectClass=user))"
>>> untrusted_input = "*)(userID=*))(|(userID=*"
>>> filter_exp.format(untrusted_input)
'(&(userID=*)(userID=*))(|(userID=*)(objectClass=user))'
>>> filter_exp.format(bonsai.escape_filter_exp(untrusted_input))
'(&(userID=\\2A\\29\\28userID=\\2A\\29\\29\\28|\\28userID=\\2A)(objectClass=user))'
bonsai.get_tls_impl_name()#

Return the identification of the underlying TLS implementation that is used by the LDAP library:

>>> bonsai.get_tls_impl_name()
"MozNSS"

The possible return values are: GnuTLS, OpenSSL, MozNSS and SChannel.

Returns:

A identification of TLS implementation.

Return type:

str

bonsai.get_vendor_info()#

Return the vendor’s name and the version number of the LDAP library:

>>> bonsai.get_vendor_info()
("OpenLDAP", 20440)
Returns:

A tuple of the vendor’s name and the library’s version.

Return type:

tuple

bonsai.has_krb5_support()#
Returns:

True if the module is built with the optional Kerberos/GSSAPI headers.

Return type:

bool

bonsai.set_connect_async(allow)#

Disable/enable asynchronous connection for the underlying socket, which means that the socket is set to be non-blocking when it’s enabled. The default setting is False on every platform. This is an OpenLDAP specific setting (see LDAP_OPT_CONNECT_ASYNC option in the OpenLDAP documentation for further details).

Parameters:

allow (bool) – Enabling/disabling async connect mode.

Warning

Experience shows that this is a delicate setting. Even with a newer OpenLDAP, the TLS library version used by libldap might be unable to handle non-blocking sockets correctly.

bonsai.set_debug(debug, level=0)#

Set debug mode for the module. Turning it on will provide traceback information of C function calls on the standard output.

If the module uses OpenLDAP, then setting the level parameter to a non-zero integer will also give additional info about the libldap function calls.

Parameters:
  • debug (bool) – Enabling/disabling debug mode.

  • level (int) – The debug level (for OpenLDAP only).