проверить права доступа ldap с помощью python

Я пишу веб-интерфейс (django) для сервера LDAP. Существуют разные люди с разными привилегиями, поэтому я настроил LDAP ACL, чтобы контролировать, кто может просматривать или редактировать определенный атрибут. Теперь легко определить, есть ли у конкретного пользователя права на чтение — попробуйте прочитать, и вы увидите, что у вас получится. Но я не вижу элегантного способа различать доступ для чтения и записи до того, как я на самом деле попытаюсь внести некоторые изменения. То есть хотелось бы, чтобы в интерфейсе было понятно, есть ли у вошедшего в систему пользователя доступ на запись, или он может только читать. Чтобы пользователи не пытались изменить атрибут, который они не могут.

Единственное, что пришло мне в голову, это попробовать временно вписать в атрибут какой-нибудь фиктивный элемент и посмотреть, получится ли это. Если это так, исходное значение будет восстановлено, и я знаю, что у этого пользователя есть права на запись. Затем я могу отобразить этот атрибут как редактируемый. Проблема заключается в том, что если сервер выйдет из строя после того, как фиктивный файл был записан и до того, как исходное значение будет восстановлено, я останусь с фиктивными значениями на моем сервере LDAP.

Что мне нужно, так это какой-то способ запросить ACL, аналогично тому, как я могу запросить определения схемы. Но, может быть, это «запрещено» LDAP?

Любые идеи?

Исаак


person Isaac    schedule 19.11.2010    source источник
comment
Какой сервер Ldap вы используете? Какой интерфейс/привязки вы используете для доступа к нему?   -  person ThomasH    schedule 19.11.2010
comment
Я использую привязки ldap openldap 2.3.32 и python 2.6 (импорт ldap)   -  person Isaac    schedule 19.11.2010
comment
Мне приходит в голову, что мне не нужно писать манекен, чтобы увидеть, есть ли у меня доступ для записи. Я мог бы просто попытаться записать исходное значение, что приведет к ошибке, если у меня нет доступа для записи, и ничего не изменит, если у меня есть доступ для чтения. Тем не менее, выглядит не так элегантно.   -  person Isaac    schedule 19.11.2010
comment
import ldap выдает ошибку в моем vanilla python2.6, поэтому вы, должно быть, установили сторонний модуль. Что он?   -  person ThomasH    schedule 19.11.2010
comment
Хм, я использую python-ldap с сайта python-ldap.org, а для точно, оба упакованы для сервера Ubuntu 10.04.   -  person Isaac    schedule 19.11.2010


Ответы (3)


ACL, на openldap организованы по OU и/или DN проверяются с помощью regexp

ex :

access to attrs=userPassword
    by anonymous auth
    by self write
    by dn.base="ou=users_with_userPassword_write_access,dc=myproduct,dc=org" write
    by dn.exact="cn=manager,dc=myproduct,dc=org" write
    by * none

access to *
    by dn.exact="cn=manager,dc=myproduct,dc=org" write
    by dn.base="ou=users_with_powerfull_write_access,dc=myproduct,dc=org" write
    by * none

Итак, что касается DN зарегистрированного пользователя (whoami_s с python-ldap), вы можете определить, есть ли у пользователя какие-либо права. Вам не нужно проверять, можете ли вы записывать данные, реализовывать функцию в своем приложении django, которая проверяет DN.

Может быть, вы говорите, что ACL генерируются динамически?


Что касается вашего комментария, если ваш ACL является статическим, чтобы узнать ACL, проще всего реализовать средство python, которое реализует эти ACL. С моим предыдущим примером:

W_ACCESS_OU = "ou=users_with_powerfull_write_access,dc=myproduct,dc=org"
def check_write_access(user_dn):
    return is_dn_base(W_ACCESS_OU, user_dn)

На данный момент python-ldap не может получить списки управления доступом slapd.conf... И анализировать slapd.conf небезопасно (поскольку slapd.conf может находиться «где угодно» в системе, а объявление списков контроля доступа может быть сложно разобрать). ), также требуется много времени, чтобы попытаться записать данные на серверную часть LDAP.

Я знаю, что это не очень удовлетворительно. Другим решением является использование «пользователя службы». Только этот пользователь имеет доступ для записи к серверной части LDAP.

Это упрощает написание ACL:

access to *
    by dn.exact="cn=manager,dc=myproduct,dc=org" write
    by * none

Затем на обычных пользователях вы устанавливаете флаг авторизации. Ваше приложение проверяет флаг, когда ваш зарегистрированный пользователь хочет что-то сделать. И если этот флаг в порядке, пользователь сервиса записывает данные на Backend.

Это стратегия, которую мы используем в одном из наших приложений.

В обоих случаях проверка ACL выполняется нашим приложением, а не серверной частью ldap.

person ohe    schedule 19.11.2010
comment
Извините, я могу быть медленным в понимании, но: если я знаю свое DN, как я узнаю о ACL? ACL определен в slapd.conf, который, по крайней мере концептуально, неизвестен моему приложению django. Вы предлагаете мне разобрать slapd.conf из django? - person Isaac; 19.11.2010
comment
Чтобы ответить на ваш вопрос: мой ACL является статическим. Тем не менее, я могу время от времени менять некоторые настройки, поэтому я хотел бы иметь одно место для их определения. - person Isaac; 19.11.2010

Я думаю, что попробую «тестовый» подход, если он слишком медленный, возможно, с некоторым кэшированием. Причина, по которой я хочу сохранить определение ACL только на сервере ldap, заключается в том, что есть другие способы взаимодействия с сервером (будут инструменты cli, а также стандартные инструменты ldap), поэтому я хотел бы сохранить все эти интерфейсы. в синхронизации ACL, только с одним местом для определения ACL

person Isaac    schedule 22.11.2010

В OpenLDAP определения ACL находятся за пределами DIT. Если вы хотите получить доступ к ACL с запросом ldap, вы можете использовать FedoraDS (сервер каталогов 389): http://directory.fedoraproject.org/wiki/Howto:AccessControl

Вы также можете увидеть OpenDS (https://www.opends.org)

person Bertera    schedule 22.03.2011