Python ldap install windows

Provide feedback

Saved searches

Use saved searches to filter your results more quickly

Sign up

Tutorial for Installing Python-LDAP in a Virtual Environment on Windows

Python-LDAP is a popular LDAP (Lightweight Directory Access Protocol) library for Python. It is used for accessing and managing directory services such as Microsoft Active Directory. However, installing Python-LDAP in a virtual environment on Windows can be a bit tricky due to the error message “Unable to find vcvarsall.bat”. In this tutorial, we will guide you through the process of installing Python-LDAP in a virtual environment on Windows.

Prerequisites

  • Python 3.6 or later
  • A virtual environment (e.g., virtualenv)
  • A Python package manager (e.g., pip)

Installing Python-LDAP

  1. Create a virtual environment:
virtualenv myenv
  1. Activate the virtual environment:

    • Windows:

    “`
    myenv\Scripts\activate

    * **MacOS/Linux**:


    ```bash
source myenv/bin/activate
  1. Install Python-LDAP:
pip install python-ldap

Troubleshooting

If you encounter the “Unable to find vcvarsall.bat” error message, you can try installing a pre-compiled version of Python-LDAP from the following link: http://www.lfd.uci.edu/~gohlke/pythonlibs/#python-ldap

Conclusion

Installing Python-LDAP in a virtual environment on Windows can be a bit challenging due to the “Unable to find vcvarsall.bat” error message. However, by following the steps outlined in this tutorial, you should be able to successfully install Python-LDAP in your virtual environment.

Installation is straightforward and can be done via a package manager or from the source.

Installation with a package manager

You need the pip package (or another package manager that can download and install from pyPI) to
install ldap3. Then you can download and install the ldap3 library directly from pyPI:

This library has two dependencies (the pyasn1 module and the pycryptodomex module), you can install it or let the installer do it for you.

If you need to access a server with the Kerberos SASL authentication mechanism you must install the gssapi or the winkerberos package with:

pip install ldap3[gssapi]
pip install ldap3[winkerberos]

ldap3 includes a backport (from Python 3.4.3) of ssl.check_hostnames to be used on older
(version < 2.7.10) Python version. If you want to use a more up to date version of the check_hostnames feature you can
install the backports.ssl_check_hostnames package that should be kept updated with the Standard Library of the latest
Python release by its maintainers.

Installation from the source

You can download the latest source from https://github.com/cannatag/ldap3 then you can install the library with:

Global configuration

in the ldap3.utils.config package there are some configurable settings:

  • POOLING_LOOP_TIMEOUT = 10 # number of seconds to wait before restarting a cycle to find an active server in the pool

  • RESPONSE_SLEEPTIME = 0.05 # seconds to wait while waiting for a response in asynchronous strategies

  • RESPONSE_WAITING_TIMEOUT = 3 # waiting timeout for receiving a response in asynchronous strategies

  • SOCKET_SIZE = 4096 # socket byte size

  • CHECK_AVAILABILITY_TIMEOUT = 2.5 # default timeout for socket connect when checking availability

  • RESET_AVAILABILITY_TIMEOUT = 5 # default timeout for resetting the availability status when checking candidate addresses

  • RESTARTABLE_SLEEPTIME = 2 # time to wait in a restartable strategy before retrying the request

  • RESTARTABLE_TRIES = 3 # number of times to retry in a restartable strategy before giving up. Set to True for unlimited retries

  • REUSABLE_THREADED_POOL_SIZE = 5

  • REUSABLE_THREADED_LIFETIME = 3600 # 1 hour

  • DEFAULT_THREADED_POOL_NAME = ‘REUSABLE_DEFAULT_POOL’

  • ADDRESS_INFO_REFRESH_TIME = 300 # seconds to wait before refreshing address info from dns

  • ADDITIONAL_ENCODINGS = [‘latin-1’] # some broken LDAP implementation may have different encoding than those expected by RFCs

  • IGNORE_MALFORMED_SCHEMA = False # some flaky LDAP servers returns malformed schema. If True no expection is raised and schema is thrown away

This parameters are library-wide and usually you should keep the default values.

You can use the get_config_parameter() and set_config_parameter() functions in the ldap3 namespace to get and set the configurable parameters at runtime.

Importing objects and constants

All objects and constants needed to use the ldap3 library can be imported from the ldap3 namespace:

from ldap3 import Connection, Server, ANONYMOUS, SIMPLE, SYNC, ASYNC

Library errors

You can deal with errors in two different ways. By default in synchronous strategies each LDAP operation returns a
True/False value that specifies if the operation has been successful or not. In case of failures you can check the
error description in the `last_error` attribute of the Connection object. In some cases an exception of the custom
hierarchy starting from the `LDAPExceptionError` class is raised with a description of the error condition in the args
attribute.

If you prefer to deal always with Exceptions you can set the raise_exceptions attribute to True in the Connection
object definition. From now on the Connection will raise exceptions for all operations that return result codes
different from RESULT_SUCCESS, RESULT_COMPARE_FALSE, RESULT_COMPARE_TRUE, RESULT_REFERRAL.

Communication exceptions have multiple inheritance either from `LDAPCommunicationError` and the specific socket exception.

Exceptions are defined in the ldap3.core.exceptions package.

Last updated on 2 April 2015

TL;DR: Architecture is important (duh), download the 64bit exe from here.


I recently had a horrendous time trying to install python-ldap on Windows 7 64bit so I decided to write a short post for when my future self needs to install it again in the hope that it will go much more smoothly.

As it turns out I missed one key piece of information, the “preferred point for downloading the ‘official’ source distribution is now the PyPI repository which supports installing via setuptools” (http://www.python-ldap.org/download.shtml) BUT this only has 32bit versions, not 64bit!

Therefore installing using pip or the exe fails (obvious in hindsight).

Here are some of the super helpful error message I encountered while I epically failed to take architectures into account:

1) Installing using pip (pip install python-ldap) requires Visual C++ 2008 Express Edition installed, which I didn’t have so resulted in:

error: Unable to find vcvarsall.bat

To fix, install it free from Microsoft here because it will be required for other modules in the future. Then read 2).

2) Installing using pip (pip install python-ldap) tries to install a 32bit version which isn’t much use when the OS and Python interpreter are 64bit so results in:

ValueError: [u'path']

To fix: there is not a 64bit version in the pip repo as far as I am aware – skip to the punch line below.

3) Installing using the officially distributed executable on PyPI failed to find my Python install in the registry and gave me this error:

Python version 2.7 required, which was not found in the registry.

I use ActiveState Python because it comes with pywin32  but apparently it didn’t put the entry in the registry. Looking at the documentation afterwards it appears as though the installer didn’t run with admin privileges and therefore created entries under KEY_CURRENT_USER and not under HKEY_LOCAL_MACHINE.

4) After fixing 3) the exe was able to complete installation (and for a few brief moments I was happy…), but when I tried to import the module it failed with this error:

ImportError: DLL load failed: %1 is not a valid Win32 application

This is once again because of an architecture mismatch, my Python interpreter is 64bit but the module is 32bit.


After a cup of tea I noticed that the architecture problem and found the alternative installers by Christoph Gohlke here. (The python-ldap download page links to the maintainer’s (Waldemar Osuch) webpage which links to Christoph Gohlke’s page.)

I was then able to download and install the 64bit version with no problems.


As always, if you have any comments or suggestions please feel free to get in touch.

Выгрузка почтовых адресов из Active Directory с помощью Python

Опубликовано:

Мы рассмотрим простой скрипт для получение всех возможных почтовых адресов по LDAP из Active Directory. Скрипт можно взять за основу и использовать для других реализаций глобального каталога.

Готовим систему
    На компьютере, где будет запускаться скрипт
    Сервер Active Directory
Процесс написания скрипта
    Подключение по ldap
    Получение пользователей AD
    Фильтр по почтовому атрибуту
    Выгрузка списка адресов электронной почты
Пример готового скрипта

Подготовка системы

Рассмотрим процесс подготовки компьютера, на котором будет запускаться скрипт и сервера Active Directory.

Компьютер

В данном примере скрипт будет запускаться на компьютере с Linux.

1. Для начала установим сам Python и дополнительные компоненты:

а) На системах RPM (Red Hat, CentOS, Fedora):

yum install python3 python3-devel openldap-devel

б) На системах DEB (Debian, Ubuntu):

apt-get install python3 python3-pip libsasl2-dev python-dev libldap2-dev libssl-dev

2. Также установим модуль ldap для python:

pip3 install python-ldap

3. Создадим каталог, в котором будет находиться скрипт:

mkdir /scripts

Создадим сам скрипт:

vi /scripts/get_email_from_ad.py

#!/usr/bin/env python3
# -*- encoding: utf-8 -*-

* в данном примере мы создали скрипт get_email_from_ad.py с двумя строчками — шебангом и определением кодировки.

4. Даем разрешение скрипту на запуск:

chmod +x /scripts/get_email_from_ad.py

Active Directory

Для подключения к глобальному каталогу по LDAP нам нужна учетная запись для прохождения авторизации на сервере. Нужна учетная запись с минимальными правами.

Лучше всего для задач скрипта создать отдельного пользователя. В данной инструкции для связывания с Active Directory будет использоваться учетная запись export_emails. Создать ее можно с помощью инструмента Пользователи и компьютеры Active Directory.

Написание скрипта

Чтобы было проще разобраться, начнем разработку по шагам.

1. Подключение по LDAP

Для начала просто подключимся к глобальному каталогу. В наш скрипт добавим:

import ldap

try:
    lconn = ldap.initialize(‘ldap://dmosk.local:389’)
    lconn.protocol_version = ldap.VERSION3
    lconn.set_option(ldap.OPT_REFERRALS, 0)
    lconn.simple_bind_s(‘export_emails@dmosk.local’, ‘export_emails_12345!’)
except ldap.SERVER_DOWN:
    print(«Error connection to AD»)

* в данном примере мы подключаемся к серверу dmosk.local (домен должен разрешаться в любой из серверов глобального каталога) по порту 389. Для прохождения аутентификации мы используем логин export_emails и пароль export_emails_12345! (учетная запись, которая заранее нами была создана в Active Directory). Также мы указываем, что используется 3 версия протокола ldap и не должны использоваться рефералы.

Пробуем запустить скрипт:

/scripts/get_email_from_ad.py

Он должен вернуть пустую строку. Если мы получим ошибку, то необходимо проверить связь с сервером и корректность введелнных данных (логина и пароля).

2. Получение списка пользователей

Научимся извлекать пользователей по ldap. Добавим в наш скрипт:

base = «DC=dmosk,DC=local»
scope = ldap.SCOPE_SUBTREE
filter = «(&(objectcategory=person))»
attrs = [‘displayname’,’title’]
result_set = []

ldap_result_id = lconn.search_ext(base, scope, filter, attrs)

try:
  while 1:
    result_type, result_data = lconn.result(ldap_result_id, 0)
    if (result_data == []):
      break
    else:
      if result_type == ldap.RES_SEARCH_ENTRY:
        result_set.append(result_data)
except ldap.SIZELIMIT_EXCEEDED:
    print()

print(result_set)

* где:

  • base — начальный контейнер, с которого начинаем поиск объектов.
  • scope — область поиска. В нашем примере используется SCOPE_SUBTREE, что означает искать также в дочерних объектах.
  • filter — задаем фильтр. В текущем примере ищем объекты person (пользователи).
  • attrs — атрибуты объектов, которые нас интересуют.
  • result_set — массив данных с полученным результатом.
  • ldap_result_id — идентификатор поиска объектов в каталоге.

Запускаем наш скрипт:

/scripts/get_email_from_ad.py

Мы должны получить массив данных всех найденных пользователей и их атрибутов.

3. Получение почтовых атрибутов

На этом этапе мы отсеем все объекты, у которых нет адреса электронной почты. В итоге, наш массив данных будет содержать пользователей и атрибуты с адресами электронной почты.

Откроем наш скрипт и заменим строки:


filter = «(&(objectcategory=person))»
attrs = [‘displayname’,’title’]

… на:

filter = «(&(mail=*))»
attrs = [‘mail’,’proxyAddresses’]

* в данном примере мы выгрузим все объекты, у которых есть адрес почты (не пустой атрибут mail). Нас будут интересовать 2 атрибута — собственно, mail и proxyAddresses, в котором могут быть перечислены все возможные адреса объекта.
* данный фильтр позволит получить список не только пользователей, но и групп. Возможно, вам это не нужно. Тогда можно изменить наш фильтр, например на «(&(objectcategory=person)(mail=*))» — тогда мы получим только пользователей, у которых есть электронные адреса.

Запускаем наш скрипт:

/scripts/get_email_from_ad.py

Мы должны получить список объектов с адресами электронной почты.

4. Получение списка адресов электронной почты

На конец, вытащим почтовые адреса и составим общий список.

В нашем скрипте удаляем строку:

print(result_set)

Добавляем строки:

all_emails = []
for user in result_set:
    proxyAddresses = user[0][1].get(‘proxyAddresses’)
    mail = user[0][1].get(‘mail’)
    if (proxyAddresses):
        for email_b in proxyAddresses:
            email = email_b.decode(«utf-8»)
            all_emails.append(email.split(‘:’)[1])
    else:
        all_emails.append(mail[0].decode(«utf-8»))

unique_all_emails = list(set(all_emails))
print(*unique_all_emails, sep = ‘\n’)

* и так, данными действиями мы перебираем полученный массив пользователей и извлекаем все email-адреса. Если у пользователя не пустой атрибут proxyAddresses, значит берем адреса из него, если у пользователя есть только mail, то берем его. В итоге, все данные помещаем в массив all_emails, который в конце преобразовываем для получения уникальных значений (в каталоге могут хранится одинаковые email для разных объектов).

Запускаем наш скрипт:

/scripts/get_email_from_ad.py

Мы должны получить список уникальных email-адресов для всех объектов, которые были найдены в глобальном каталоге.

Пример готового скрипта

Написанный нами скрипт можно представить так:

  1. #!/usr/bin/env python3
  2. # -*- encoding: utf-8 -*-
  3.  
  4. # Импортируем python-модули
  5. import ldap
  6.  
  7. # Задаем необходимые переменные
  8. domain = ‘dmosk.local’
  9. base = ‘DC=dmosk,DC=local’
  10. bind_dn = f’export_emails@{domain}’
  11. bind_dn_password = ‘export_emails_12345!’
  12. scope = ldap.SCOPE_SUBTREE
  13. filter = «(&(mail=*))»
  14. attrs = [‘mail’,’proxyAddresses’]
  15. result_set = []
  16. all_emails = []
  17.  
  18. # Подключаемся к глобальному каталогу по LDAP
  19. try:
  20.     lconn = ldap.initialize(f’ldap://{domain}:389′)
  21.     lconn.protocol_version = ldap.VERSION3
  22.     lconn.set_option(ldap.OPT_REFERRALS, 0)
  23.     lconn.simple_bind_s(bind_dn, bind_dn_password)
  24. except ldap.SERVER_DOWN:
  25.     print(«Error connection to AD»)
  26.  
  27. # Получаем результаты поиска объектов в AD
  28. ldap_result_id = lconn.search_ext(base, scope, filter, attrs)
  29.  
  30. Все результаты поиска объектов заносим в переменную result_set
  31. try:
  32.   while 1:
  33.     result_type, result_data = lconn.result(ldap_result_id, 0)
  34.     if (result_data == []):
  35.       break
  36.     else:
  37.       if result_type == ldap.RES_SEARCH_ENTRY:
  38.         result_set.append(result_data)
  39. except ldap.SIZELIMIT_EXCEEDED:
  40.     print()
  41.  
  42. # Получаем список email-адресов и заносим его в переменную all_emails
  43. for user in result_set:
  44.     proxyAddresses = user[0][1].get(‘proxyAddresses’)
  45.     mail = user[0][1].get(‘mail’)
  46.     if (proxyAddresses):
  47.         for email_b in proxyAddresses:
  48.             email = email_b.decode(«utf-8»)
  49.             all_emails.append(email.split(‘:’)[1])
  50.     else:
  51.         all_emails.append(mail[0].decode(«utf-8»))
  52.  
  53. # Получаем уникальные значения электронных адресов и заносим их в переменную unique_all_emails
  54. unique_all_emails = list(set(all_emails))
  55.  
  56. # Выводим результат на экран
  57. print(*unique_all_emails, sep = ‘\n’)

Понравилась статья? Поделить с друзьями:
0 0 голоса
Рейтинг статьи
Подписаться
Уведомить о
guest

0 комментариев
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии
  • Команда для открытия командной строки windows 10
  • Как изменить название устройства в windows 10
  • Glfw error 65542 minecraft windows 10
  • Не открывается windows boot manager
  • Profilelist в реестре windows 10