Para delegar la posibilidad de realizar cambios de password en un usuario estándar de OpenDJ Directory Services Project (antiguo Sun OpenDS) es necesario establecer ciertos privilegios y ACIs (Access control instructions) al usuario.
En primera instancia, lo normal es pensar que asignar privilegios sería suficiente, vamos a ver el caso. Tenemos un usuario estándar sin privilegios llamado user.1:
# ./ldapsearch -D "cn=directory manager" -w password -b "dc=example,dc=com" "(uid=user.1)" '+' dn: uid=user.1,ou=People,dc=example,dc=com numSubordinates: 0 structuralObjectClass: inetOrgPerson pwdPolicySubentry: cn=Default Password Policy,cn=Password Policies,cn=config subschemaSubentry: cn=schema hasSubordinates: false entryDN: uid=user.1,ou=people,dc=example,dc=com entryUUID: 4e9b7847-edcb-3791-b11b-7505f4a55af4
Si quisiéramos con este usuario, cambiar la clave a otro usuario, lógicamente recibiríamos el error de que no tenemos suficientes privilegios para realizar la operación. Usando este usuario sin privilegios como Bind DN intentamos cambiar la clave de otro usuario (user.2):
# ./ldappasswordmodify -D "uid=user.1,ou=People,dc=example,dc=com" \ -w user.1 -a "uid=user.2,ou=People,dc=example,dc=com" -n user.2 The LDAP password modify operation failed with result code 50 Error Message: You do not have sufficient privileges to perform password reset operations
Lógicamente no tenemos privilegios, en el log vemos algo más de información:
[25/Dec/2012:21:58:26 +0100] CONNECT conn=4 from=127.0.0.1:54354 to=127.0.0.1:389 protocol=LDAP [25/Dec/2012:21:58:26 +0100] BIND REQ conn=4 op=0 msgID=1 type=SIMPLE dn="uid=user.1,ou=People,dc=example,dc=com" [25/Dec/2012:21:58:26 +0100] BIND RES conn=4 op=0 msgID=1 result=0 authDN="uid=user.1,ou=People,dc=example,dc=com" etime=14 [25/Dec/2012:21:58:26 +0100] EXTENDED REQ conn=4 op=1 msgID=2 name="Password Modify" oid="1.3.6.1.4.1.4203.1.11.1" [25/Dec/2012:21:58:26 +0100] EXTENDED RES conn=4 op=1 msgID=2 result=50 message= "You do not have sufficient privileges to perform password reset operations" etime=19 [25/Dec/2012:21:58:26 +0100] UNBIND REQ conn=4 op=2 msgID=3
[25/Dec/2012:21:58:26 +0100] DISCONNECT conn=4 reason="Client Unbind"
Vamos entonces a asignarle privilegios de lectura de configuración y cambio de password. Para ello creamos un ldif en el que añadamos a user.1 los privilegios (ds-privilege-name) de lectura de configuración (config-read) y cambio de passwords (password-reset)
# cat privilegios.ldif dn: uid=user.1,ou=People,dc=example,dc=com changetype: modify add: ds-privilege-name ds-privilege-name: config-read ds-privilege-name: password-reset # ./ldapmodify -D "cn=directory manager" -w password --filename privilegios.ldif Processing MODIFY request for uid=user.1,ou=People,dc=example,dc=com MODIFY operation successful for DN uid=user.1,ou=People,dc=example,dc=com
Consultamos de nuevo el usuario y vemos que efectivamente tiene los permisos asignados:
# ./ldapsearch -D "cn=directory manager" -w password -b "dc=example,dc=com" "(uid=user.1)" '+' dn: uid=user.1,ou=People,dc=example,dc=com numSubordinates: 0 structuralObjectClass: inetOrgPerson ds-privilege-name: config-read ds-privilege-name: password-reset pwdPolicySubentry: cn=Default Password Policy,cn=Password Policies,cn=config subschemaSubentry: cn=schema hasSubordinates: false entryDN: uid=user.1,ou=people,dc=example,dc=com entryUUID: 4e9b7847-edcb-3791-b11b-7505f4a55af4 pwdChangedTime: 20121225205717.192Z modifyTimestamp: 20121225210153Z modifiersName: cn=Directory Manager,cn=Root DNs,cn=config
Vamos entonces a volver a intentar cambiar la clave de otro usuario (user.2):
# ./ldappasswordmodify -D "uid=user.1,ou=People,dc=example,dc=com" \ -w user.1 -a "uid=user.2,ou=People,dc=example,dc=com" -n user.2 The LDAP password modify operation failed with result code 50 Error Message: The entry uid=user.2,ou=People,dc=example,dc=com cannot be modified due to insufficient access rights
Todavía no funciona porque pese a tener asignados estos permisos. OpenDJ protege este tipo de privilegios anteponiéndoles ACIs (Access control instructions), de modo que si queremos que el usuario pueda cambiar passwords de otros usuarios, también habrá que permitirle ciertas ACI para evitar que se antepongan a los privilegios. En definitiva, los privilegios son complementarios a las ACI.
En estos casos lo óptimo es, por ejemplo, usar un grupo de administración e ir asignando las ACi en lugar de hacerlo de forma individual, pero para este ejemplo las asignamos directamente al usuario. Tenéis toda la documentación de las ACI en la guía de administración de OpenDJ.
Asigno los ACI Permissions de lectura y escritura al user.1:
# ./dsconfig -h localhost -D "cn=Directory Manager" \ -w password -X -n set-access-control-handler-prop \ --add global-aci:"(target=\"ldap:///dc=example,dc=com\") \ (targetattr = \"*\")(version 3.0; acl \"allow read/write user.1\"; \ allow(read,write) userdn = \"ldap:///uid=user.1,ou=People,dc=example,dc=com\";)"
Y ahora sí que puedo realizar los cambios de password a otros usuarios:
# ./ldappasswordmodify -D "uid=user.1,ou=People,dc=example,dc=com" \ -w user.1 -a "uid=user.2,ou=People,dc=example,dc=com" -n user.2 The LDAP password modify operation was successful
Os recomiendo revisar bien el enlace de la guía de administración que he publicado en el anterior párrafo para ampliar toda esta información.