You are here

DeriveFromEntry.notes.txt in Lightweight Directory Access Protocol (LDAP) 7

========================================
Derive From Entry Configuration Options:
========================================
0. Use Derive from Entry
Property: authorization.deriveFromEntry as boolean

1a. List of groups' ldap entry attribute values.  Can be cn, uid, dn etc. of the entry.   These entries contain multivalued attributes which are member users or nested groups.
Property:  authorization.deriveFromEntryEntries as array of ldap entry attributes
e.g.: array('cn=it,cn=groups,dc=ad,dc=myuniversity,dc=edu', 'cn=people,cn=groups,dc=ad,dc=myuniversity,dc=edu')
e.g.: array('it', 'people')

1b. Attribute who's value is contained in 1a.  This pair will be used to search from group entries.
Property:  authorization.deriveFromEntryEntriesAttr as LDAP attribute name
e.g. 'dn', 'cn', ...

2. Name of multivalued attribute whose value contains members.
Property:  authorization.deriveFromEntryMembershipAttr as LDAP attribute name
e.g.: 'uniquemember', 'member'

3. User's LDAP Entry Attribute which will be held in deriveFromEntryMembershipAttr
Property: authorization.deriveFromEntryAttrMatchingUserAttr as LDAP attribute name
e.g.: 'dn', 'cn'

4. Search all enabled LDAP servers for matching users
Property: authorization.deriveFromEntrySearchAll as boolean

5. Include nested groups.
Property: authorization.deriveFromEntryNested: boolean

6. Convert full dn to value of first attribute.
Property: authorization.deriveFromEntryUseFirstAttr: boolean

7. Class of entries that represent groupgs.
Property: server.groupObjectClass as LDAP attribute value held in objectClass.
e.g.: 'groupOfUniqueNames', 'group'


========================================
Derive From Entry walk-through NOT nested:
========================================

--- configuration ------
0. authorization.deriveFromEntry = 1
1. authorization.deriveFromEntryEntries = array('cn=it,cn=groups,dc=ad,dc=myuniversity,dc=edu', 'cn=people,cn=groups,dc=ad,dc=myuniversity,dc=edu')
1b. authorization.deriveFromEnryEntryAttribute' = 'distinguishedname'
2. authorization.deriveFromEntryMembershipAttr = 'uniquemember'
3. authorization.deriveFromEntryAttrMatchingUserAttr = 'dn'
4. authorization.deriveFromEntrySearchAll = 0
5. authorization.deriveFromEntryNested = 0
6. authorization.deriveFromEntryUseFirstAttr = 1
7. server.groupObjectClass = 'groupOfUniqueNames'

user ldap entry in question:
  'dn' => 'uid=joeprogrammer,ou=it,dc=ad,dc=myuniversity,dc=edu',
  'cn' => 'joeprogrammer',
  'uid' => 'joeprogrammer',
  'mail' => array( 0 => 'joeprogrammer@myuniversity.edu'),
  'uid' => array( 0 => 'joeprogrammer'),


--- walk-through ------
1). foreach base dn, execute the following query:

(&
(objectClass=groupOfUniqueNames)
(|(distinguishedname=cn=it,cn=groups,dc=ad,dc=myuniversity,dc=edu)(distinguishedname=people,cn=groups,dc=ad,dc=myuniversity,dc=edu))
(uniquemember=cn=joeprogrammer,ou=it,dc=ad,dc=myuniversity,dc=edu)
)

in psuedo code:
(&
(objectClass=[server.groupObjectClass])
(|([authorization.deriveFromEnryEntryAttribute]=[authorization.deriveFromEntryEntries[i]])...([authorization.deriveFromEnryEntryAttribute]=[authorization.deriveFromEntryEntries[n]]))
([authorization.deriveFromEntryMembershipAttr]=[user_ldap_entry[deriveFromEntryAttrMatchingUserAttr]])
)


2. All entries returned represent groups that user is a member of.
Their DNs are added to the list of authorizations or the first attribute value
if authorization.deriveFromEntryUseFirstAttr is true.


========================================
Derive From Entry walk-through NESTED:
========================================

--- configuration ------
0. authorization.deriveFromEntry = 1
1. authorization.deriveFromEntryEntries = array('cn=it,cn=groups,dc=ad,dc=myuniversity,dc=edu', 'cn=people,cn=groups,dc=ad,dc=myuniversity,dc=edu')
1b. authorization.deriveFromEnryEntryAttribute = 'distinguishedname'
2. authorization.deriveFromEntryMembershipAttr = 'uniquemember'
3. authorization.deriveFromEntryAttrMatchingUserAttr = 'dn'
4. authorization.deriveFromEntrySearchAll = 0
5. authorization.deriveFromEntryNested = 1
6. authorization.deriveFromEntryUseFirstAttr = 1
7. server.groupObjectClass = 'groupOfUniqueNames'

user ldap entry in question:
  'dn' => 'uid=joeprogrammer,ou=it,dc=ad,dc=myuniversity,dc=edu',
  'mail' => array( 0 => 'joeprogrammer@myuniversity.edu'),
  'uid' => array( 0 => 'joeprogrammer'),


--- walk-through ------
1). foreach base dn, execute the following query:

(&
(objectClass=groupOfUniqueNames)
(|(distinguishedname=cn=it,cn=groups,dc=ad,dc=myuniversity,dc=edu)(cn=people,cn=groups,dc=ad,dc=myuniversity,dc=edu))
)

in psuedo code:
(&
(objectClass=[server.groupObjectClass])
(|([authorization.deriveFromEnryEntryAttribute]=[authorization.deriveFromEntryEntries[i]])...([authorization.deriveFromEnryEntryAttribute]=[authorization.deriveFromEntryEntries[n]]))
)


2. All entries returned represent groups that user MIGHT be a member of.  examples:

  'dn' => 'cn=it,cn=groups,dc=ad,dc=myuniversity,dc=edu',
  'objectclass' => array( 0 => 'groupofuniquenames'),
  'uniquemember' => array(
    0 => 'cn=developers,cn=groups,dc=ad,dc=myuniversity,dc=edu',
    1 => 'cn=sysadmins,cn=groups,dc=ad,dc=myuniversity,dc=edu',
    2 => 'uid=joeprojectmanager,ou=it,dc=ad,dc=myuniversity,dc=edu',
  ),

  'dn' => 'cn=people,cn=groups,dc=ad,dc=myuniversity,dc=edu',
  'objectclass' => array( 0 => 'groupofuniquenames'),
  'uniquemember' => array(
     0 => 'cn=students,cn=groups,dc=ad,dc=myuniversity,dc=edu',
     1 => 'cn=staff,cn=groups,dc=ad,dc=myuniversity,dc=edu',
  ),




3. foreach returned entry from query 1. (authorization.deriveFromEntryEntries):

  if 'uniquemember' contains a value matching 'uid=joeprogrammer,ou=it,dc=ad,dc=myuniversity,dc=edu', add that entry's DN to authorizations
  in psuedo code: if group[authorization.deriveFromEntryMembershipAttr] contains user[authorization.deriveFromEntryAttrMatchingUserAttr],
  add corresponding authorization.deriveFromEntryEntries entry to authorizations


  else recurse through uniquemembers.  if user's entry is found, add corresponding
  authorization.deriveFromEntryEntries entry to authorizations
  (not the DN that has the user in uniquemembers)


4A.  recursion:

In the above example the first recursion query looks like:
(&
  (objectClass=groupofuniquenames)
  (|
    (distinguishedname=cn=developers,cn=groups,dc=ad,dc=myuniversity,dc=edu)
    (distinguishedname=cn=sysadmins,cn=groups,dc=ad,dc=myuniversity,dc=eduu)
    (distinguishedname=uid=joeprojectmanager,ou=it,dc=ad,dc=myuniversity,dc=edu)
  )
)

which might return:

    'dn' => 'cn=developers,cn=groups,dc=ad,dc=myuniversity,dc=edu',
    'objectclass' => array( 0 => 'groupofuniquenames'),
    'uniquemember' => array(
      0 => 'uid=joeprogrammer,ou=it,dc=ad,dc=myuniversity,dc=edu',
    ),

    'dn' => 'cn=sysadmins,cn=groups,dc=ad,dc=myuniversity,dc=edu',
    'objectclass' => array( 0 => 'groupofuniquenames'),
    'uniquemember' => array(
      0 => 'uid=joeprogrammer,ou=it,dc=ad,dc=myuniversity,dc=edu',
      1 => 'cn=sysadmins,cn=groups,dc=ad,dc=myuniversity,dc=edu',
    ),

since uid=joeprogrammer,ou=it,dc=ad,dc=myuniversity,dc=edu is found in the first entry,
  cn=it,cn=groups,dc=ad,dc=myuniversity,dc=edu (the ancestor group) is added
  to the list of authorizations.
  Since authorization.deriveFromEntryUseFirstAttr = 1, its truncated to "it"


4B.  In the above example the second recursion query would look like:

(&
  (objectClass=groupofuniquenames)
  (|
    (distinguishedname=cn=students,cn=groups,dc=ad,dc=myuniversity,dc=edu)
    (distinguishedname=cn=staff,cn=groups,dc=ad,dc=myuniversity,dc=edu)
  )
)

which returns:

    'dn' => 'cn=staff,cn=groups,dc=ad,dc=myuniversity,dc=edu',
    'objectclass' => array( 0 => 'groupofuniquenames'),
    'uniquemember' => array(
      0 => 'cn=it,cn=groups,dc=ad,dc=myuniversity,dc=edu',
      1 => 'uid=unkool,ou=lost,dc=ad,dc=myuniversity,dc=edu',
    ),


    'dn' => 'cn=students,cn=groups,dc=ad,dc=myuniversity,dc=edu',
    'objectclass' => array( 0 => 'groupofuniquenames'),
    'uniquemember' => array(
      0 => 'uid=jdoe,ou=campus accounts,dc=ad,dc=myuniversity,dc=edu',
    ),

4C. leading to the queries:

(&
  (objectClass=groupofuniquenames)
  (|
    (distinguishedname=uid=jdoe,ou=campus accounts,dc=ad,dc=myuniversity,dc=edu)
  )
)
...which returns no entries

and
4D.
(&
  (objectClass=groupofuniquenames)
  (|
    (distinguishedname=cn=it,cn=groups,dc=ad,dc=myuniversity,dc=edu)
    (distinguishedname=uid=unkool,ou=lost,dc=ad,dc=myuniversity,dc=edu)
  )
)

which returns:

  'dn' => 'cn=it,cn=groups,dc=ad,dc=myuniversity,dc=edu',
  'objectclass' => array( 0 => 'groupofuniquenames'),
  'uniquemember' => array(

    0 => 'cn=developers,cn=groups,dc=ad,dc=myuniversity,dc=edu',
    1 => 'cn=sysadmins,cn=groups,dc=ad,dc=myuniversity,dc=edu',
    2 => 'uid=joeprojectmanager,ou=it,dc=ad,dc=myuniversity,dc=edu',
  ),

4E. leading to the query:

  (&
    (objectClass=groupofuniquenames)
    (|
      (distinguishedname=cn=developers,cn=groups,dc=ad,dc=myuniversity,dc=edu)
      (distinguishedname=cn=sysadmins,cn=groups,dc=ad,dc=myuniversity,dc=edu)
      (distinguishedname=uid=joeprojectmanager,ou=it,dc=ad,dc=myuniversity,dc=edu)
    )
  )

which returns:

  'dn' => 'cn=developers,cn=groups,dc=ad,dc=myuniversity,dc=edu',
  'objectclass' => array( 0 => 'groupofuniquenames'),
  'uniquemember' => array(
    0 => 'uid=joeprogrammer,ou=it,dc=ad,dc=myuniversity,dc=edu',
  ),

  'dn' => 'cn=sysadmins,cn=groups,dc=ad,dc=myuniversity,dc=edu',
  'objectclass' => array( 0 => 'groupofuniquenames'),
  'uniquemember' => array(
    0 => 'uid=joeprogrammer,ou=it,dc=ad,dc=myuniversity,dc=edu',
    1 => 'cn=sysadmins,cn=groups,dc=ad,dc=myuniversity,dc=edu',
  ),

since uid=joeprogrammer,ou=it,dc=ad,dc=myuniversity,dc=edu is found in the first entry,
cn=people,cn=groups,dc=ad,dc=myuniversity,dc=edu (the ancestor group)
is added to the list of authorizations.
Since authorization.deriveFromEntryUseFirstAttr = 1, its truncated to "people"


==================================================================

File

ldap_authorization/tests/DeriveFromEntry/DeriveFromEntry.notes.txt
View source
  1. ========================================
  2. Derive From Entry Configuration Options:
  3. ========================================
  4. 0. Use Derive from Entry
  5. Property: authorization.deriveFromEntry as boolean
  6. 1a. List of groups' ldap entry attribute values. Can be cn, uid, dn etc. of the entry. These entries contain multivalued attributes which are member users or nested groups.
  7. Property: authorization.deriveFromEntryEntries as array of ldap entry attributes
  8. e.g.: array('cn=it,cn=groups,dc=ad,dc=myuniversity,dc=edu', 'cn=people,cn=groups,dc=ad,dc=myuniversity,dc=edu')
  9. e.g.: array('it', 'people')
  10. 1b. Attribute who's value is contained in 1a. This pair will be used to search from group entries.
  11. Property: authorization.deriveFromEntryEntriesAttr as LDAP attribute name
  12. e.g. 'dn', 'cn', ...
  13. 2. Name of multivalued attribute whose value contains members.
  14. Property: authorization.deriveFromEntryMembershipAttr as LDAP attribute name
  15. e.g.: 'uniquemember', 'member'
  16. 3. User's LDAP Entry Attribute which will be held in deriveFromEntryMembershipAttr
  17. Property: authorization.deriveFromEntryAttrMatchingUserAttr as LDAP attribute name
  18. e.g.: 'dn', 'cn'
  19. 4. Search all enabled LDAP servers for matching users
  20. Property: authorization.deriveFromEntrySearchAll as boolean
  21. 5. Include nested groups.
  22. Property: authorization.deriveFromEntryNested: boolean
  23. 6. Convert full dn to value of first attribute.
  24. Property: authorization.deriveFromEntryUseFirstAttr: boolean
  25. 7. Class of entries that represent groupgs.
  26. Property: server.groupObjectClass as LDAP attribute value held in objectClass.
  27. e.g.: 'groupOfUniqueNames', 'group'
  28. ========================================
  29. Derive From Entry walk-through NOT nested:
  30. ========================================
  31. --- configuration ------
  32. 0. authorization.deriveFromEntry = 1
  33. 1. authorization.deriveFromEntryEntries = array('cn=it,cn=groups,dc=ad,dc=myuniversity,dc=edu', 'cn=people,cn=groups,dc=ad,dc=myuniversity,dc=edu')
  34. 1b. authorization.deriveFromEnryEntryAttribute' = 'distinguishedname'
  35. 2. authorization.deriveFromEntryMembershipAttr = 'uniquemember'
  36. 3. authorization.deriveFromEntryAttrMatchingUserAttr = 'dn'
  37. 4. authorization.deriveFromEntrySearchAll = 0
  38. 5. authorization.deriveFromEntryNested = 0
  39. 6. authorization.deriveFromEntryUseFirstAttr = 1
  40. 7. server.groupObjectClass = 'groupOfUniqueNames'
  41. user ldap entry in question:
  42. 'dn' => 'uid=joeprogrammer,ou=it,dc=ad,dc=myuniversity,dc=edu',
  43. 'cn' => 'joeprogrammer',
  44. 'uid' => 'joeprogrammer',
  45. 'mail' => array( 0 => 'joeprogrammer@myuniversity.edu'),
  46. 'uid' => array( 0 => 'joeprogrammer'),
  47. --- walk-through ------
  48. 1). foreach base dn, execute the following query:
  49. (&
  50. (objectClass=groupOfUniqueNames)
  51. (|(distinguishedname=cn=it,cn=groups,dc=ad,dc=myuniversity,dc=edu)(distinguishedname=people,cn=groups,dc=ad,dc=myuniversity,dc=edu))
  52. (uniquemember=cn=joeprogrammer,ou=it,dc=ad,dc=myuniversity,dc=edu)
  53. )
  54. in psuedo code:
  55. (&
  56. (objectClass=[server.groupObjectClass])
  57. (|([authorization.deriveFromEnryEntryAttribute]=[authorization.deriveFromEntryEntries[i]])...([authorization.deriveFromEnryEntryAttribute]=[authorization.deriveFromEntryEntries[n]]))
  58. ([authorization.deriveFromEntryMembershipAttr]=[user_ldap_entry[deriveFromEntryAttrMatchingUserAttr]])
  59. )
  60. 2. All entries returned represent groups that user is a member of.
  61. Their DNs are added to the list of authorizations or the first attribute value
  62. if authorization.deriveFromEntryUseFirstAttr is true.
  63. ========================================
  64. Derive From Entry walk-through NESTED:
  65. ========================================
  66. --- configuration ------
  67. 0. authorization.deriveFromEntry = 1
  68. 1. authorization.deriveFromEntryEntries = array('cn=it,cn=groups,dc=ad,dc=myuniversity,dc=edu', 'cn=people,cn=groups,dc=ad,dc=myuniversity,dc=edu')
  69. 1b. authorization.deriveFromEnryEntryAttribute = 'distinguishedname'
  70. 2. authorization.deriveFromEntryMembershipAttr = 'uniquemember'
  71. 3. authorization.deriveFromEntryAttrMatchingUserAttr = 'dn'
  72. 4. authorization.deriveFromEntrySearchAll = 0
  73. 5. authorization.deriveFromEntryNested = 1
  74. 6. authorization.deriveFromEntryUseFirstAttr = 1
  75. 7. server.groupObjectClass = 'groupOfUniqueNames'
  76. user ldap entry in question:
  77. 'dn' => 'uid=joeprogrammer,ou=it,dc=ad,dc=myuniversity,dc=edu',
  78. 'mail' => array( 0 => 'joeprogrammer@myuniversity.edu'),
  79. 'uid' => array( 0 => 'joeprogrammer'),
  80. --- walk-through ------
  81. 1). foreach base dn, execute the following query:
  82. (&
  83. (objectClass=groupOfUniqueNames)
  84. (|(distinguishedname=cn=it,cn=groups,dc=ad,dc=myuniversity,dc=edu)(cn=people,cn=groups,dc=ad,dc=myuniversity,dc=edu))
  85. )
  86. in psuedo code:
  87. (&
  88. (objectClass=[server.groupObjectClass])
  89. (|([authorization.deriveFromEnryEntryAttribute]=[authorization.deriveFromEntryEntries[i]])...([authorization.deriveFromEnryEntryAttribute]=[authorization.deriveFromEntryEntries[n]]))
  90. )
  91. 2. All entries returned represent groups that user MIGHT be a member of. examples:
  92. 'dn' => 'cn=it,cn=groups,dc=ad,dc=myuniversity,dc=edu',
  93. 'objectclass' => array( 0 => 'groupofuniquenames'),
  94. 'uniquemember' => array(
  95. 0 => 'cn=developers,cn=groups,dc=ad,dc=myuniversity,dc=edu',
  96. 1 => 'cn=sysadmins,cn=groups,dc=ad,dc=myuniversity,dc=edu',
  97. 2 => 'uid=joeprojectmanager,ou=it,dc=ad,dc=myuniversity,dc=edu',
  98. ),
  99. 'dn' => 'cn=people,cn=groups,dc=ad,dc=myuniversity,dc=edu',
  100. 'objectclass' => array( 0 => 'groupofuniquenames'),
  101. 'uniquemember' => array(
  102. 0 => 'cn=students,cn=groups,dc=ad,dc=myuniversity,dc=edu',
  103. 1 => 'cn=staff,cn=groups,dc=ad,dc=myuniversity,dc=edu',
  104. ),
  105. 3. foreach returned entry from query 1. (authorization.deriveFromEntryEntries):
  106. if 'uniquemember' contains a value matching 'uid=joeprogrammer,ou=it,dc=ad,dc=myuniversity,dc=edu', add that entry's DN to authorizations
  107. in psuedo code: if group[authorization.deriveFromEntryMembershipAttr] contains user[authorization.deriveFromEntryAttrMatchingUserAttr],
  108. add corresponding authorization.deriveFromEntryEntries entry to authorizations
  109. else recurse through uniquemembers. if user's entry is found, add corresponding
  110. authorization.deriveFromEntryEntries entry to authorizations
  111. (not the DN that has the user in uniquemembers)
  112. 4A. recursion:
  113. In the above example the first recursion query looks like:
  114. (&
  115. (objectClass=groupofuniquenames)
  116. (|
  117. (distinguishedname=cn=developers,cn=groups,dc=ad,dc=myuniversity,dc=edu)
  118. (distinguishedname=cn=sysadmins,cn=groups,dc=ad,dc=myuniversity,dc=eduu)
  119. (distinguishedname=uid=joeprojectmanager,ou=it,dc=ad,dc=myuniversity,dc=edu)
  120. )
  121. )
  122. which might return:
  123. 'dn' => 'cn=developers,cn=groups,dc=ad,dc=myuniversity,dc=edu',
  124. 'objectclass' => array( 0 => 'groupofuniquenames'),
  125. 'uniquemember' => array(
  126. 0 => 'uid=joeprogrammer,ou=it,dc=ad,dc=myuniversity,dc=edu',
  127. ),
  128. 'dn' => 'cn=sysadmins,cn=groups,dc=ad,dc=myuniversity,dc=edu',
  129. 'objectclass' => array( 0 => 'groupofuniquenames'),
  130. 'uniquemember' => array(
  131. 0 => 'uid=joeprogrammer,ou=it,dc=ad,dc=myuniversity,dc=edu',
  132. 1 => 'cn=sysadmins,cn=groups,dc=ad,dc=myuniversity,dc=edu',
  133. ),
  134. since uid=joeprogrammer,ou=it,dc=ad,dc=myuniversity,dc=edu is found in the first entry,
  135. cn=it,cn=groups,dc=ad,dc=myuniversity,dc=edu (the ancestor group) is added
  136. to the list of authorizations.
  137. Since authorization.deriveFromEntryUseFirstAttr = 1, its truncated to "it"
  138. 4B. In the above example the second recursion query would look like:
  139. (&
  140. (objectClass=groupofuniquenames)
  141. (|
  142. (distinguishedname=cn=students,cn=groups,dc=ad,dc=myuniversity,dc=edu)
  143. (distinguishedname=cn=staff,cn=groups,dc=ad,dc=myuniversity,dc=edu)
  144. )
  145. )
  146. which returns:
  147. 'dn' => 'cn=staff,cn=groups,dc=ad,dc=myuniversity,dc=edu',
  148. 'objectclass' => array( 0 => 'groupofuniquenames'),
  149. 'uniquemember' => array(
  150. 0 => 'cn=it,cn=groups,dc=ad,dc=myuniversity,dc=edu',
  151. 1 => 'uid=unkool,ou=lost,dc=ad,dc=myuniversity,dc=edu',
  152. ),
  153. 'dn' => 'cn=students,cn=groups,dc=ad,dc=myuniversity,dc=edu',
  154. 'objectclass' => array( 0 => 'groupofuniquenames'),
  155. 'uniquemember' => array(
  156. 0 => 'uid=jdoe,ou=campus accounts,dc=ad,dc=myuniversity,dc=edu',
  157. ),
  158. 4C. leading to the queries:
  159. (&
  160. (objectClass=groupofuniquenames)
  161. (|
  162. (distinguishedname=uid=jdoe,ou=campus accounts,dc=ad,dc=myuniversity,dc=edu)
  163. )
  164. )
  165. ...which returns no entries
  166. and
  167. 4D.
  168. (&
  169. (objectClass=groupofuniquenames)
  170. (|
  171. (distinguishedname=cn=it,cn=groups,dc=ad,dc=myuniversity,dc=edu)
  172. (distinguishedname=uid=unkool,ou=lost,dc=ad,dc=myuniversity,dc=edu)
  173. )
  174. )
  175. which returns:
  176. 'dn' => 'cn=it,cn=groups,dc=ad,dc=myuniversity,dc=edu',
  177. 'objectclass' => array( 0 => 'groupofuniquenames'),
  178. 'uniquemember' => array(
  179. 0 => 'cn=developers,cn=groups,dc=ad,dc=myuniversity,dc=edu',
  180. 1 => 'cn=sysadmins,cn=groups,dc=ad,dc=myuniversity,dc=edu',
  181. 2 => 'uid=joeprojectmanager,ou=it,dc=ad,dc=myuniversity,dc=edu',
  182. ),
  183. 4E. leading to the query:
  184. (&
  185. (objectClass=groupofuniquenames)
  186. (|
  187. (distinguishedname=cn=developers,cn=groups,dc=ad,dc=myuniversity,dc=edu)
  188. (distinguishedname=cn=sysadmins,cn=groups,dc=ad,dc=myuniversity,dc=edu)
  189. (distinguishedname=uid=joeprojectmanager,ou=it,dc=ad,dc=myuniversity,dc=edu)
  190. )
  191. )
  192. which returns:
  193. 'dn' => 'cn=developers,cn=groups,dc=ad,dc=myuniversity,dc=edu',
  194. 'objectclass' => array( 0 => 'groupofuniquenames'),
  195. 'uniquemember' => array(
  196. 0 => 'uid=joeprogrammer,ou=it,dc=ad,dc=myuniversity,dc=edu',
  197. ),
  198. 'dn' => 'cn=sysadmins,cn=groups,dc=ad,dc=myuniversity,dc=edu',
  199. 'objectclass' => array( 0 => 'groupofuniquenames'),
  200. 'uniquemember' => array(
  201. 0 => 'uid=joeprogrammer,ou=it,dc=ad,dc=myuniversity,dc=edu',
  202. 1 => 'cn=sysadmins,cn=groups,dc=ad,dc=myuniversity,dc=edu',
  203. ),
  204. since uid=joeprogrammer,ou=it,dc=ad,dc=myuniversity,dc=edu is found in the first entry,
  205. cn=people,cn=groups,dc=ad,dc=myuniversity,dc=edu (the ancestor group)
  206. is added to the list of authorizations.
  207. Since authorization.deriveFromEntryUseFirstAttr = 1, its truncated to "people"
  208. ==================================================================