Então, eu baixei a última fonte do OpenLDAP, compilei com —-enable-sql
, mexi com o slapd.conf
, configurei os arquivos odbc, adicionei as tabelas ao meu banco de dados atual, passei uma semana depurando slapd -d -1
e agora os usuários do MySQL, tornaram-se usuários do LDAP e podem efetuar login.
Eu preciso de ajuda para entender a estrutura básica de um objeto LDAP.
De tudo que eu li, estou assumindo que cada objeto precisa pertencer a um structuralObjectClass
e então cada objeto pode pertencer a muitos outros objectClasses
?
A única coisa que preciso que esse servidor LDAP faça é autenticar os usuários. Não há necessidade de os usuários editarem suas informações. Então eu primeiro expus a seguinte estrutura:
Institute
dn: dc=example,dc=org
dc: example
structuralObjectClass: dcObject
objectClass: organization
o: example
description: Example Company
Groups
Dn: ou=Groups,dc=example,dc=org
Ou: Groups
structuralObjectClass: organizationalUnit
dn: ou=Users,dc=example,dc=org
ou: Users
structuralObjectClass: organizationalUnit
dn: ou=marketing,ou=Groups,dc=example,dc=org
cn: marketing
gidNumber: 1554
structuralObjectClass: posixGroup
memberUid: user1
memberUid: userN
dn: ou=administration,ou=Groups,dc=example,dc=org
cn: administration
gidNumber: 1555
structuralObjectClass: posixGroup
memberUid: user1
memberUid: userN
Users
Dn: uid=user1,ou=Users,dc=example,dc=org
structuralObjectClass: inetOrgPerson
givenName:
displayName:
cn:
uidNumber:
homeDirectory:
sn:
gidNumber:
objectClass: person
objectClass: organizationalPerson
objectClass: posixAccount
objectClass: shadowAccount
Acredito que o OpenLDAP adicionará o top
objectClass
ausente.
Como já tenho um banco de dados com esses usuários e estou mais confortável com RDBMSes em vez de esquemas no LDAP, tenho um pouco de dificuldade em entender por que, quando tento efetuar login, o utilitário ldapsearch
passa por todas as classes de objeto Eu tenho na tabela ldap_oc_mappings em vez de apenas pesquisar o objectClass inetOrgPerson
. Desta forma, não haveria quaisquer consultas desnecessárias. De qualquer forma, estas são as tabelas:
ldap_attr_mappings
+----+-----------+---------------+-----------------------------------------------------------+---------------+---------------------------------+-------------+
| id | oc_map_id | name | sel_expr | from_tbls | join_where | param_order |
+----+-----------+---------------+-----------------------------------------------------------+---------------+---------------------------------+-------------+
| 3 | 1 | sn | users .lName | users | NULL | 3 |
| 4 | 1 | userPassword | concat('{MD5}',BASE64_ENCODE(unhex(users .password))) | users | NOT ISNULL(users .password) | 3 |
| 5 | 1 | displayName | concat(users .fName,' ',users .lName) | users | NULL | 3 |
| 6 | 1 | homeDirectory | users .homeDirectory | users | NULL | 3 |
| 7 | 1 | loginShell | users .loginShell | users | NULL | 3 |
| 8 | 1 | uidNumber | users .uidNumber | users | NULL | 3 |
| 9 | 1 | gidNumber | users .gidNumber | users | NULL | 3 |
| 10 | 1 | cn | users .loginName | users | NULL | 3 |
| 11 | 1 | uid | users .loginName | users | NULL | 3 |
| 12 | 3 | ou | ldap_groups.name | ldap_groups | NULL | 3 |
| 14 | 2 | o | ldap_org_unit.o | ldap_org_unit | NULL | 3 |
| 16 | 2 | dc | ldap_org_unit.o | ldap_org_unit | NULL | 3 |
| 17 | 2 | description | ldap_org_unit.Description | ldap_org_unit | NULL | 3 |
| 18 | 4 | gidNumber | ldap_groups.gid | ldap_groups | NULL | 3 |
| 19 | 4 | cn | ldap_groups.cn | ldap_groups | NULL | 3 |
+----+-----------+---------------+-----------------------------------------------------------+---------------+---------------------------------+-------------+
ldap_oc_mappings
+----+--------------------+---------------+--------------+
| id | name | keytbl | keycol |
+----+--------------------+---------------+--------------+
| 1 | inetOrgperson | users | userID |
| 2 | organization | ldap_org_unit | id |
| 3 | organizationalUnit | ldap_groups | gid |
| 4 | posixGroup | ldap_groups | gid |
+----+--------------------+---------------+--------------+
ldap_entry_objclasses
+----------+---------------+
| entry_id | oc_name |
+----------+---------------+
| 12216 | inetOrgPerson |
| 12216 | posixAccount |
| 12216 | shadowAccount |
+----------+---------------+
As entradas objclasses são apenas para um usuário. Cada usuário tem esses objectClasses atribuídos a eles. Esta é uma visão não uma tabela
ldap_org_unit
+----+-------------+---------------------------------+--------+---------------------+-----------+
| id | o | dn | parent | Description | oc_map_id |
+----+-------------+---------------------------------+--------+---------------------+-----------+
| 1 | Example | DC=Example,DC=org | 0 | Example Co | 2 |
| 2 | Users | ou=Users,DC=example,DC=org | 1 | | 3 |
| 3 | Groups | ou=Groups,DC=example,DC=org | 1 | | 3 |
+----+-------------+---------------------------------+--------+---------------------+-----------+
Acho que os valores principais aqui podem não estar corretos
ldap_groups
+------+----------------+----------------+-----------------------------------------------+
| gid | name | cn | dn |
+------+----------------+----------------+-----------------------------------------------+
| 1554 | Marketing | marketing | cn=marketing,ou=Groups,dc=example,dc=org |
| 1155 | administration | administration | cn=administration,ou=Groups,dc=example,dc=org |
+------+----------------+----------------+-----------------------------------------------+
Lastly: ldap_entries
+-------+-----------------------------------------------+-----------+--------+--------+
| id | dn | oc_map_id | parent | keyval |
+-------+-----------------------------------------------+-----------+--------+--------+
| 1 | DC=EXAMPLE,DC=ORG | 2 | 0 | 1 |
| 2 | OU=USERS,DC=EXAMPLE,DC=ORG | 3 | 1 | 2 |
| 3 | OU=GROUPS,DC=EXAMPLE,DC=ORG | 3 | 1 | 3 |
| 1554 | CN=MARKETING,OU=GROUPS,DC=EXAMPLE,DC=ORG | 4 | 3 | 1554 |
| 1155 | CN=ADMINISTRATION,OU=GROUPS,DC=EXAMPLE,DC=ORG | 4 | 3 | 1155 |
| 22963 | CN=ROOT,DC=EXAMPLE,DC=ORG | 1 | 1554 | 12963 |
| 12216 | CN=USER1,OU=USERS,DC=EXAMPLE,DC=ORG | 1 | 1555 | 2216 |
+-------+-----------------------------------------------+-----------+--------+--------+
Os valores pai estão corretos aqui?
Como eu disse, isso funciona e os usuários podem fazer login. Mas quando executo ldasearch -b "dc=example,dc=org" "(objectclass=*)"
, isso leva muito tempo. Eu li vários artigos afirmando que a razão pela qual os RDBMSes não podem e não devem ser usados para infra-estruturas LDAP é principalmente devido a este problema. Mas é terrivelmente lento, o que me leva a acreditar que existem algumas perguntas desnecessárias e minhas "relações" de mesa não estão corretas.
Os primeiros resultados do ldapsearch
são:
# ROOT, EXAMPLE.ORG
dn: cn=ROOT,dc=EXAMPLE,dc=ORG
objectClass: inetOrgPerson
objectClass: inetOrgPerson
objectClass: posixAccount
objectClass: shadowAccount
cn: root
sn: Admin
uid: root
gidNumber: 1554
uidNumber: 0
loginShell: /bin/bash
displayName: Domain Admin
userPassword:: *******
homeDirectory: /ldaphomes/root
# USER1, USERS, EXAMPLE.ORG
dn: cn=USER1,ou=USERS,dc=EXAMPLE,dc=ORG
objectClass: inetOrgPerson
objectClass: inetOrgPerson
objectClass: posixAccount
objectClass: shadowAccount
cn: user1
sn: User 1
uid: user1
gidNumber: 0
uidNumber: 0
displayName: User 1
userPassword:: ******
Como você pode ver aqui, o objectClass inetOrgPerson aparece duas vezes. Isso é para todos os usuários.
Quando executo isso: ldapsearch -b "dc=example,dc=org" "(cn=user1)"
, o resultado é retornado em milissegundos, o que me leva a acreditar que deve haver uma maneira de informar ao servidor do OpenLDAP para sempre pesquisar com base no CN.
Mm, este foi um longo post / pergunta (s). Portanto, quaisquer comentários sobre o esquema, valores pai ou por que os objectClasses são exibidos duas vezes, ou talvez alguma orientação para otimizar isso é bem-vinda.
Obrigado