Package: read-ad
python-read-adCOM-based readonly access for Active Directory in Python 3,forked from Tim Golden's active_directory.py v0.6.7Module descriptionInstallation:pip install read-adModule name:read_adDependencies: 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 athttps://github.com/tjguk/active_directory.Module contentsConstants / Global VariablesConstants for ADO/COM accessADO_COMMAND'ADODB.Command'ADO_CONNECTION'ADODB.Connection'CONNECTION_PROVIDER'ADsDSOObject'CONNECTION_TARGET'Active Directory Provider'Internal cache keywordsCACHE_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.MappingsGLOBAL_CACHEA global cache ofLdapEntryobjects mapped to LDAP Urls,
plus the connection object and the Active Directory root URL.GROUP_TYPESAFlagsMapping()with Active Directory group type bitmasks
(values are taken fromhttps://github.com/tjguk/active_directory/blob/master/active_directory.py#L164)AUTHENTICATION_TYPESAFlagsMapping()with Active Directory authentication type bitmasks
(values are taken fromhttps://github.com/tjguk/active_directory/blob/master/active_directory.py#L172)SAM_ACCOUNT_TYPESAUnsignedIntegerMapping()with Active Directory account type magic numbers
(values are taken fromhttps://github.com/tjguk/active_directory/blob/master/active_directory.py#L187)USER_ACCOUNT_CONTROLAFlagsMapping()with Active Directory user account state bitmasks
(values are taken fromhttps://github.com/tjguk/active_directory/blob/master/active_directory.py#L202)SEARCH_FILTERSA dict ofSearchFilterinstances mapped to the following keywords:'computer'for searching computers bycn'group'for searching groups bycn'ou'for searching organizational units byou'public_folder'for searching public folders bydisplayName'userid'for searching users bysAMAccountNameClassesUnsignedIntegerMapping(**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)AnUnsignedIntegerMappingsubclass 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 athttps://docs.microsoft.com/windows/win32/adsi/searching-with-activex-data-objects-ado.query(query_string, **kwargs)Classmethodthat executes an Active Directory query over a cached connection
(provided by theconnection()helper function, see source code)
and returns an iterator overRecordSetinstances 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=TrueTimeout=1.dump_fields()Returns an iterator over the recordset fields as (name, value) tuplesPathComponent(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'..keywordThe keyword.valueThe value.from_string(string)Constructor (class)method, returns aPathComponentinstance built from keyword and value determined by splittingstringat 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 orPathComponentinstances..componentsThe components of the path (a tuple ofPathComponentinstances).rdnThe relative distinguished name of the LPAP path (the.valueof the first component).urlThe LDAP URL of the path (the distinguished name prefixed with'LDAP://').from_string(string)Constructor (class)method, returns anLdapPathinstance built from the providedstringsplitted 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 theRecordSet.query()class method)
starting atldap_urland using SQL syntax with theWHEREclause genarated by the.where_clause()method..where_clause(*args, **kwargs)Return aWHEREclause for an SQL-like LDAP query string,
built from the provided positional and keyword arguments,
all concatenated usingAND.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_nameNote: LDAP entry attribute names are case insensitive.AllLdapPathand subclasses instances should be instantiated
by using theproduce_entry()function below..empty_attributesA frozenset of the names of all attributes having the value None..ldap_urlThe LDAP URL of the entry..child(single_path_component)Returns anLdapEntrysubclass instance for a relative child of this instance.
Its path is determined by prepending thesingle_path_componentto 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_attributesfrozenset..print_dump()Prints a case-sensitive (i.e. uppercase before lowercase) alphabetically sorted dump
of all non-empty attributes.User(com_object)LdapEntrysubclass for Active Directory usersInteresting attributes include:sAMAccountName- the user IDgivenName- the first namesn- the last nametitle- eg a PhDmanager- 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 fromUSER_ACCOUNT_CONTROL.account_disabledTrueif the account is disabled,Falseif it is active.Group(com_object)LdapEntrysubclass for Active Directory groupsInteresting 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 currentGroupinstance,2.a list of memberGroupinstances and3.a list of memberUserinstances.Public interface functionsproduce_entry(ldap_path, lazy=True)LdapEntryand subclasses factory function.Determines the suitable class out ofLdapEntry,UserorGroupfrom the
COM object found at the LDAP URL.
Generates an instance of this class from the COM object,
stores it inGLOBAL_CACHE(associated to the LDAP path URL),
and returns the Instance.ldap_pathmay be a string containing either a distinguished name or an LDAP URL
(which is basically a distinguished name prefixed with'LDAP://'),
or anLdapPathinstance.iflazyis set toTrue(the default), this function returns
the suitable cached entry if it exists, avoiding expensive lookups
and network traffic.root(server=None)Returns the (cached)LdapEntryinstance 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 assearch_base.
Ifsearch_baseis not given, the LDAP search starts at the LDAP URL of root().Ifactiveis set toTrueorFalseexplicitly, the method returns only
the paths of active (or deactivated) matching entries.Ifsearch_filteris set to a SearchFilter instance,
this method uses that instance to search the Active Directory.
Else, if a keyword matching any of theSEARCH_FILTERSkeys
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'sWHEREclause,
theRecordSet.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 thesearch()function above,
but uses the user search filter (SEARCH_FILTER['userid']) unconditionally.In contrary to plainsearch(), the first
positional argument - if any are provided - is treated differently from the rest:It is matched against each one ofsAMAccountName,displayNameandcnby building suitable conditions joined by'OR'.
The remaining positional arguments are treated normally.get_first_entry(*args, **kwargs)Returns anLdapEntryor subclass instance made from the first found LDAP entry
from an LDAP search usingsearch(), or None if nothing was found.get_first_user(*args, **kwargs)Returns aUserinstance made from the first found LDAP entry
from an LDAP search usingsearch_users(), or None if nothing was found.Examplesimportread_ad# read_ad.root() returns the cached Active Directory root entry# find your own user in active directoryimportgetpassmy_user=read_ad.get_first_user(getpass.getuser())