Skip to main content

COM-based readonly access for Active Directory in Python 3

Project description

python-read-ad

COM-based readonly access for Active Directory in Python 3, forked from Tim Golden's active_directory.py v0.6.7

Module description

Installation: pip install read-ad

Module name: read_ad

Dependencies: Python 3.x and the pywin32 module (https://pypi.org/project/pywin32/)

Goals: minimum dependencies, maximum speed, easy usage.

In contrast to the original, this module provides read access only. For full-featured Active Directory access, please refer to the latest version of the original, hosted at https://github.com/tjguk/active_directory.

Module contents

Constants / Global Variables

Constants for ADO/COM access

ADO_COMMAND

'ADODB.Command'

ADO_CONNECTION

'ADODB.Connection'

CONNECTION_PROVIDER

'ADsDSOObject'

CONNECTION_TARGET

'Active Directory Provider'

Internal cache keywords

CACHE_KEY_CONNECTION

'_Connection_' as the key for caching the connection object.

CACHE_KEY_ROOT

'_ActiveDirectoryRoot_' as the key for caching the Active Directory root URL.

Mappings

GLOBAL_CACHE

A global cache of LdapEntry objects mapped to LDAP Urls, plus the connection object and the Active Directory root URL.

GROUP_TYPES

A FlagsMapping() with Active Directory group type bitmasks (values are taken from https://github.com/tjguk/active_directory/blob/master/active_directory.py#L164)

AUTHENTICATION_TYPES

A FlagsMapping() with Active Directory authentication type bitmasks (values are taken from https://github.com/tjguk/active_directory/blob/master/active_directory.py#L172)

SAM_ACCOUNT_TYPES

A UnsignedIntegerMapping() with Active Directory account type magic numbers (values are taken from https://github.com/tjguk/active_directory/blob/master/active_directory.py#L187)

USER_ACCOUNT_CONTROL

A FlagsMapping() with Active Directory user account state bitmasks (values are taken from https://github.com/tjguk/active_directory/blob/master/active_directory.py#L202)

SEARCH_FILTERS

A dict of SearchFilter instances mapped to the following keywords:

  • 'computer' for searching computers by cn
  • 'group' for searching groups by cn
  • 'ou' for searching organizational units by ou
  • 'public_folder' for searching public folders by displayName
  • 'userid' for searching users by sAMAccountName

Classes

UnsignedIntegerMapping(**kwargs)

A Mapping of unsigned integers to names with reverse lookup functionality. Member access using a name returns the associated number and vice versa.

.get_name(number)

Explicitly returns the name associated with the given number.

FlagsMapping(**kwargs)

An UnsignedIntegerMapping subclass for bitmasks mapped to flag names

.get_flag_names(number)

Returns a set of all flag names for the bitmasks matching the given number.

Recordset(record)

Wrapper around an ADO recordset as documented at https://docs.microsoft.com/windows/win32/adsi/searching-with-activex-data-objects-ado

.query(query_string, **kwargs)

Classmethod that executes an Active Directory query over a cached connection (provided by the connection() helper function, see source code) and returns an iterator over RecordSet instances for each found result.

The query may be parameterized using keyword arguments. Underscores in the keywords will be replaced by spaces.

The following parameters are preset for the query but may be overridden:

  • Asynchronous=True
  • Timeout=1
.dump_fields()

Returns an iterator over the recordset fields as (name, value) tuples

PathComponent(keyword, value)

Instances of this class represent a single component of an LDAP path, eg 'cn=Users'. They are initialized with a keyword and a value, in this example: 'cn' and 'Users'.

.keyword

The keyword

.value

The value

.from_string(string)

Constructor (class)method, returns a PathComponent instance built from keyword and value determined by splitting string at a non-escaped equals sign (=).

LdapPath(*parts)

Instances of this class represent an LDAP path. They are initialized using the provided parts, which can be either strings or PathComponent instances.

.components

The components of the path (a tuple of PathComponent instances)

.rdn

The relative distinguished name of the LPAP path (the .value of the first component)

.url

The LDAP URL of the path (the distinguished name prefixed with 'LDAP://')

.from_string(string)

Constructor (class)method, returns an LdapPath instance built from the provided string splitted at all non-escaped commas (,).

SearchFilter(primary_key_name, **fixed_parameters)

Instances of this class hold a primary key name and a mapping of fixed parameters for an LDAP search.

.execute_query(ldap_url, *args, **kwargs)

Return an interator from the result of an LDAP query (using the RecordSet.query() class method) starting at ldap_url and using SQL syntax with the WHERE clause genarated by the .where_clause() method.

.where_clause(*args, **kwargs)

Return a WHERE clause for an SQL-like LDAP query string, built from the provided positional and keyword arguments, all concatenated using AND.
The stored fixed parameters override the provided keyword arguments. If a _primary_key_ keyword was provided, its value is built into the clause using the stored primary key name.

LdapEntry(com_object)

Stores a subset of an LDAP entry's attributes. The stored attributes can be accessed via item access using [attribute_name] or (in the case of suitable attribute names) via attribute access using .attribute_name

Note: LDAP entry attribute names are case insensitive.

All LdapPath and subclasses instances should be instantiated by using the produce_entry() function below.

.empty_attributes

A frozenset of the names of all attributes having the value None.

.ldap_url

The LDAP URL of the entry.

.child(single_path_component)

Returns an LdapEntry subclass instance for a relative child of this instance. Its path is determined by prepending the single_path_component to this instance's path.

.stored_attributes_items()

Returns an items dictview of the internal mapping of stored attributes. Please note that empty attributes are not contained here; only their names are stored in the .empty_attributes frozenset.

.print_dump()

Prints a case-sensitive (i.e. uppercase before lowercase) alphabetically sorted dump of all non-empty attributes.

User(com_object)

LdapEntry subclass for Active Directory users

Interesting attributes include:

  • sAMAccountName - the user ID
  • givenName - the first name
  • sn - the last name
  • title - eg a PhD
  • manager - the user's direct boss (distinguished name)
  • memberOf - all groups the user is a direct member of (a tuple of distinguished names)
  • userAccountControl - originally a number, but resolved to a set of flag names from USER_ACCOUNT_CONTROL
.account_disabled

True if the account is disabled, False if it is active.

Group(com_object)

LdapEntry subclass for Active Directory groups

Interesting attributes include:

  • member - all direct members (users and groups, a tuple of distinguished names)
  • memberOf - all groups this group is a direct member of (a tuple of distinguished names)
.walk()

Returns an iterator over tuples, each consisting of: 1. the current Group instance, 2. a list of member Group instances and 3. a list of member User instances.

Public interface functions

produce_entry(ldap_path, lazy=True)

LdapEntry and subclasses factory function.

Determines the suitable class out of LdapEntry, User or Group from the COM object found at the LDAP URL. Generates an instance of this class from the COM object, stores it in GLOBAL_CACHE (associated to the LDAP path URL), and returns the Instance.

ldap_path may be a string containing either a distinguished name or an LDAP URL (which is basically a distinguished name prefixed with 'LDAP://'), or an LdapPath instance.

if lazy is set to True (the default), this function returns the suitable cached entry if it exists, avoiding expensive lookups and network traffic.

root(server=None)

Returns the (cached) LdapEntry instance referring to the root of the logged-on Active Directory tree.

search(*args, active=None, search_base=None, search_filter=None, **kwargs)

Returns an iterator over all found LDAP paths from an LDAP search starting at the LDAP URL specified as search_base. If search_base is not given, the LDAP search starts at the LDAP URL of root().

If active is set to True or False explicitly, the method returns only the paths of active (or deactivated) matching entries.

If search_filter is set to a SearchFilter instance, this method uses that instance to search the Active Directory. Else, if a keyword matching any of the SEARCH_FILTERS keys was provided, that search filter is used with this keyword's value specified as the _primary_key_ keyword's value.
In all other cases, an empty search filter will be instantiated and used.

If positional arguments (*args) were provided and any of them does not contain a valid condition for the query's WHERE clause, the RecordSet.query() method execting the query will return a ValueError and display the faulty query string.

search_users(*args, **kwargs)

Returns an iterator over all found LDAP paths like the search() function above, but uses the user search filter (SEARCH_FILTER['userid']) unconditionally.

In contrary to plain search(), the first positional argument - if any are provided - is treated differently from the rest:
It is matched against each one of sAMAccountName, displayName and cn by building suitable conditions joined by 'OR'. The remaining positional arguments are treated normally.

get_first_entry(*args, **kwargs)

Returns an LdapEntry or subclass instance made from the first found LDAP entry from an LDAP search using search(), or None if nothing was found.

get_first_user(*args, **kwargs)

Returns a User instance made from the first found LDAP entry from an LDAP search using search_users(), or None if nothing was found.

Examples

import read_ad

# read_ad.root() returns the cached Active Directory root entry

# find your own user in active directory
import getpass
my_user = read_ad.get_first_user(getpass.getuser())

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

read-ad-1.0.0.tar.gz (15.9 kB view details)

Uploaded Source

Built Distribution

read_ad-1.0.0-py3-none-any.whl (13.7 kB view details)

Uploaded Python 3

File details

Details for the file read-ad-1.0.0.tar.gz.

File metadata

  • Download URL: read-ad-1.0.0.tar.gz
  • Upload date:
  • Size: 15.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.3.0 pkginfo/1.4.2 requests/2.25.1 setuptools/52.0.0 requests-toolbelt/0.9.1 tqdm/4.57.0 CPython/3.9.2

File hashes

Hashes for read-ad-1.0.0.tar.gz
Algorithm Hash digest
SHA256 8e7486327966c1cf2a3896c70256ac7e4718b7917e139be4da225b701853a816
MD5 7a00fd0069bf79516d405be407d5a4a0
BLAKE2b-256 4cf8b9378ef06a533a59be8e596daf336f66b8787d654850c0818ed30e907336

See more details on using hashes here.

File details

Details for the file read_ad-1.0.0-py3-none-any.whl.

File metadata

  • Download URL: read_ad-1.0.0-py3-none-any.whl
  • Upload date:
  • Size: 13.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.3.0 pkginfo/1.4.2 requests/2.25.1 setuptools/52.0.0 requests-toolbelt/0.9.1 tqdm/4.57.0 CPython/3.9.2

File hashes

Hashes for read_ad-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 c9eaa2d6826edaa1959e75c99e265cb91b259bfb2f65e39447b1f3e7803e809f
MD5 f89c9a7f7953af145aead8606d6ee4c3
BLAKE2b-256 32329a485fd866de10d76fda6661fc1a9f6c455491f44c0c22e3ae55d3b37daa

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page