ILIAS  release_5-4 Revision v5.4.26-12-gabc799a52e6
AttributeAddUsersGroups.php
Go to the documentation of this file.
1<?php
2
12{
22 public function process(&$request)
23 {
24 assert(is_array($request));
25 assert(array_key_exists('Attributes', $request));
26
27 // Log the process
29 $this->title . 'Attempting to get the users groups...'
30 );
31
32 // Reference the attributes, just to make the names shorter
33 $attributes =& $request['Attributes'];
35
36 // Get the users groups from LDAP
37 $groups = $this->getGroups($attributes);
38
39 // Make the array if it is not set already
40 if (!isset($attributes[$map['groups']])) {
41 $attributes[$map['groups']] = array();
42 }
43
44 // Must be an array, else cannot merge groups
45 if (!is_array($attributes[$map['groups']])) {
47 $this->title . 'The group attribute [' . $map['groups'] .
48 '] is not an array of group DNs. ' . $this->var_export($attributes[$map['groups']])
49 );
50 }
51
52 // Add the users group(s)
53 $group_attribute =& $attributes[$map['groups']];
54 $group_attribute = array_merge($group_attribute, $groups);
55 $group_attribute = array_unique($group_attribute);
56
57 // All done
59 $this->title . 'Added users groups to the group attribute [' .
60 $map['groups'] . ']: ' . implode('; ', $groups)
61 );
62 }
63
64
76 protected function getGroups($attributes)
77 {
78 // Log the request
80 $this->title . 'Checking for groups based on the best method for the LDAP product.'
81 );
82
83 // Based on the directory service, search LDAP for groups
84 // If any attributes are needed, prepare them before calling search method
85 switch ($this->product) {
86 case 'ACTIVEDIRECTORY':
87 $groups = $this->getGroupsActiveDirectory($attributes);
88 break;
89 case 'OPENLDAP':
90 $groups = $this->getGroupsOpenLdap($attributes);
91 break;
92 default:
93 // Reference the map, just to make the name shorter
95
96 // Log the general search
98 $this->title . 'Searching LDAP using the default search method.'
99 );
100
101 // Make sure the defined memberOf attribute exists
102 if (!isset($attributes[$map['memberof']])) {
104 $this->title . 'The memberof attribute [' . $map['memberof'] .
105 '] is not defined in the user\'s Attributes: ' . implode(', ', array_keys($attributes)));
106 }
107
108 // MemberOf must be an array of group DN's
109 if (!is_array($attributes[$map['memberof']])) {
111 $this->title . 'The memberof attribute [' . $map['memberof'] .
112 '] is not an array of group DNs. ' . $this->var_export($attributes[$map['memberof']])
113 );
114 }
115
116 // Search for the users group membership, recursively
117 $groups = $this->search($attributes[$map['memberof']]);
118 }
119
120 // All done
122 $this->title . 'User found to be a member of the groups:' . implode('; ', $groups)
123 );
124 return $groups;
125 }
126
127
137 protected function getGroupsOpenLdap($attributes)
138 {
139 // Log the OpenLDAP specific search
141 $this->title . 'Searching LDAP using OpenLDAP specific method.'
142 );
143
144 // Reference the map, just to make the name shorter
146
147 // Print group search string and search for all group names
148 $openldap_base = $this->config->getString('ldap.basedn','ou=groups,dc=example,dc=com');
150 $this->title . "Searching for groups in ldap.basedn ".$openldap_base." with filter (".$map['memberof']."=".$attributes[$map['username']][0].") and attributes ".$map['member']
151 );
152
153 $groups = array();
154 try {
155 // Intention is to filter in 'ou=groups,dc=example,dc=com' for '(memberUid = <value of attribute.username>)' and take only the attributes 'cn' (=name of the group)
156 $all_groups = $this->getLdap()->searchformultiple($openldap_base, array($map['memberof'] => $attributes[$map['username']][0]) , array($map['member']));
157 } catch (SimpleSAML_Error_UserNotFound $e) {
158 return $groups; // if no groups found return with empty (still just initialized) groups array
159 }
160
161 // run through all groups and add each to our groups array
162 foreach ($all_groups as $group_entry) {
163 $groups[] .= $group_entry[$map['member']][0];
164 }
165
166 return $groups;
167 }
168
169
180 {
181 // Log the AD specific search
183 $this->title . 'Searching LDAP using ActiveDirectory specific method.'
184 );
185
186 // Reference the map, just to make the name shorter
188
189 // Make sure the defined dn attribute exists
190 if (!isset($attributes[$map['dn']])) {
192 $this->title . 'The DN attribute [' . $map['dn'] .
193 '] is not defined in the user\'s Attributes: ' . implode(', ', array_keys($attributes)));
194 }
195
196 // DN attribute must have a value
197 if (!isset($attributes[$map['dn']][0]) || !$attributes[$map['dn']][0]) {
199 $this->title . 'The DN attribute [' . $map['dn'] .
200 '] does not have a [0] value defined. ' . $this->var_export($attributes[$map['dn']])
201 );
202 }
203
204 // Pass to the AD specific search
205 return $this->searchActiveDirectory($attributes[$map['dn']][0]);
206 }
207
217 protected function search($memberof)
218 {
219 assert(is_array($memberof));
220
221 // Used to determine what DN's have already been searched
222 static $searched = array();
223
224 // Init the groups variable
225 $groups = array();
226
227 // Shorten the variable name
229
230 // Log the search
232 $this->title . 'Checking DNs for groups.' .
233 ' DNs: '. implode('; ', $memberof) .
234 ' Attributes: ' . $map['memberof'] . ', ' . $map['type'] .
235 ' Group Type: ' . $this->type_map['group']
236 );
237
238 // Work out what attributes to get for a group
239 $use_group_name = FALSE;
240 $get_attributes = array($map['memberof'], $map['type']);
241 if (isset($map['name']) && $map['name']) {
242 $get_attributes[] = $map['name'];
243 $use_group_name = TRUE;
244 }
245
246 // Check each DN of the passed memberOf
247 foreach ($memberof as $dn) {
248
249 // Avoid infinite loops, only need to check a DN once
250 if (isset($searched[$dn])) {
251 continue;
252 }
253
254 // Track all DN's that are searched
255 // Use DN for key as well, isset() is faster than in_array()
256 $searched[$dn] = $dn;
257
258 // Query LDAP for the attribute values for the DN
259 try {
260 $attributes = $this->getLdap()->getAttributes($dn, $get_attributes);
261 } catch (SimpleSAML_Error_AuthSource $e) {
262 continue; // DN must not exist, just continue. Logged by the LDAP object
263 }
264
265 // Only look for groups
266 if (!in_array($this->type_map['group'], $attributes[$map['type']], true)) {
267 continue;
268 }
269
270 // Add to found groups array
271 if ($use_group_name && isset($attributes[$map['name']]) && is_array($attributes[$map['name']])) {
272 $groups[] = $attributes[$map['name']][0];
273 } else {
274 $groups[] = $dn;
275 }
276
277 // Recursively search "sub" groups
278 if (!empty($attributes[$map['memberof']])) {
279 $groups = array_merge($groups, $this->search($attributes[$map['memberof']]));
280 }
281 }
282
283 // Return only the unique group names
284 return array_unique($groups);
285 }
286
287
296 protected function searchActiveDirectory($dn)
297 {
298 assert(is_string($dn) && $dn != '');
299
300 // Shorten the variable name
302
303 // Log the search
305 $this->title . 'Searching ActiveDirectory group membership.' .
306 ' DN: ' . $dn .
307 ' DN Attribute: ' . $map['dn'] .
308 ' Member Attribute: ' . $map['member'] .
309 ' Type Attribute: ' . $map['type'] .
310 ' Type Value: ' . $this->type_map['group'] .
311 ' Base: ' . implode('; ', $this->base_dn)
312 );
313
314 // AD connections should have this set
315 $this->getLdap()->setOption(LDAP_OPT_REFERRALS, 0);
316
317 // Search AD with the specific recursive flag
318 try {
319 $entries = $this->getLdap()->searchformultiple(
320 $this->base_dn,
321 array($map['type'] => $this->type_map['group'], $map['member'] . ':1.2.840.113556.1.4.1941:' => $dn),
322 array($map['dn'])
323 );
324
325 // The search may throw an exception if no entries
326 // are found, unlikely but possible.
327 } catch (SimpleSAML_Error_UserNotFound $e) {
328 return array();
329 }
330
331 //Init the groups
332 $groups = array();
333
334 // Check each entry..
335 foreach ($entries as $entry) {
336 // Check for the DN using the original attribute name
337 if (isset($entry[$map['dn']][0])) {
338 $groups[] = $entry[$map['dn']][0];
339 continue;
340 }
341
342 // Sometimes the returned attribute names are lowercase
343 if (isset($entry[strtolower($map['dn'])][0])) {
344 $groups[] = $entry[strtolower($map['dn'])][0];
345 continue;
346 }
347
348 // AD queries also seem to return the objects dn by default
349 if (isset($entry['dn'])) {
350 $groups[] = $entry['dn'];
351 continue;
352 }
353
354 // Could not find DN, log and continue
356 $this->title . 'The DN attribute [' .
357 implode(', ', array($map['dn'], strtolower($map['dn']), 'dn')) .
358 '] could not be found in the entry. ' . $this->var_export($entry)
359 );
360 }
361
362 // All done
363 return $groups;
364 }
365}
foreach($paths as $path) $request
Definition: asyncclient.php:32
An exception for terminatinating execution or to throw for unit testing.
static debug($string)
Definition: Logger.php:211
static notice($string)
Definition: Logger.php:188
getGroupsActiveDirectory($attributes)
Active Directory optimized search using the required attribute values from the user to get their grou...
searchActiveDirectory($dn)
Searches LDAP using a ActiveDirectory specific filter, looking for group membership for the users DN.
process(&$request)
This is run when the filter is processed by SimpleSAML.
search($memberof)
Looks for groups from the list of DN's passed.
getGroups($attributes)
This section of code was broken out because the child filter AuthorizeByGroup can use this method as ...
getGroupsOpenLdap($attributes)
OpenLDAP optimized search using the required attribute values from the user to get their group member...
getLdap()
Getter for the LDAP connection object.
Definition: BaseFilter.php:259
var_export($value)
Local utility function to get details about a variable, basically converting it to a string to be use...
Definition: BaseFilter.php:306
if(array_key_exists('yes', $_REQUEST)) $attributes
Definition: getconsent.php:85