ILIAS  release_5-3 Revision v5.3.23-19-g915713cf615
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(array $attributes)
77 {
78 // Reference the map, just to make the name shorter
80
81 // Log the request
83 $this->title . 'Checking for groups based on the best method for the LDAP product.'
84 );
85
86 // Based on the directory service, search LDAP for groups
87 // If any attributes are needed, prepare them before calling search method
88 switch ($this->product) {
89
90 case 'ACTIVEDIRECTORY':
91
92 // Log the AD specific search
94 $this->title . 'Searching LDAP using ActiveDirectory specific method.'
95 );
96
97 // Make sure the defined dn attribute exists
98 if (!isset($attributes[$map['dn']])) {
100 $this->title . 'The DN attribute [' . $map['dn'] .
101 '] is not defined in the users Attributes: ' . implode(', ', array_keys($attributes))
102 );
103 }
104
105 // DN attribute must have a value
106 if (!isset($attributes[$map['dn']][0]) || !$attributes[$map['dn']][0]) {
108 $this->title . 'The DN attribute [' . $map['dn'] .
109 '] does not have a [0] value defined. ' . $this->var_export($attributes[$map['dn']])
110 );
111 }
112
113 // Pass to the AD specific search
114 $groups = $this->searchActiveDirectory($attributes[$map['dn']][0]);
115 break;
116
117 case 'OPENLDAP':
118 // Log the OpenLDAP specific search
120 $this->title . 'Searching LDAP using OpenLDAP specific method.'
121 );
122 // Print group search string and search for all group names
123 $openldap_base = $this->config->getString('ldap.basedn','ou=groups,dc=example,dc=com');
125 $this->title . "Searching for groups in ldap.basedn ".$openldap_base." with filter (".$map['memberof']."=".$attributes[$map['username']][0].") and attributes ".$map['member']
126 );
127 $groups = array();
128 try {
129 // 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)
130 $all_groups = $this->getLdap()->searchformultiple( $openldap_base, array($map['memberof'] => $attributes[$map['username']][0]) , array($map['member']));
131 } catch (SimpleSAML_Error_UserNotFound $e) {
132 break; // if no groups found return with empty (still just initialized) groups array
133 }
134 // run through all groups and add each to our groups array
135 foreach ($all_groups as $group_entry) {
136 $groups[] .= $group_entry[$map['member']][0];
137 }
138 break;
139
140 default:
141
142 // Log the general search
144 $this->title . 'Searching LDAP using the default search method.'
145 );
146
147 // Make sure the defined memberOf attribute exists
148 if (!isset($attributes[$map['memberof']])) {
150 $this->title . 'The memberof attribute [' . $map['memberof'] .
151 '] is not defined in the users Attributes: ' . implode(', ', array_keys($attributes))
152 );
153 }
154
155 // MemberOf must be an array of group DN's
156 if (!is_array($attributes[$map['memberof']])) {
158 $this->title . 'The memberof attribute [' . $map['memberof'] .
159 '] is not an array of group DNs. ' . $this->var_export($attributes[$map['memberof']])
160 );
161 }
162
163 // Search for the users group membership, recursively
164 $groups = $this->search($attributes[$map['memberof']]);
165 }
166
167 // All done
169 $this->title . 'User found to be a member of the groups:' . implode('; ', $groups)
170 );
171 return $groups;
172 }
173
174
184 protected function search($memberof)
185 {
186 assert('is_array($memberof)');
187
188 // Used to determine what DN's have already been searched
189 static $searched = array();
190
191 // Init the groups variable
192 $groups = array();
193
194 // Shorten the variable name
195 $map =& $this->attribute_map;
196
197 // Log the search
199 $this->title . 'Checking DNs for groups.' .
200 ' DNs: '. implode('; ', $memberof) .
201 ' Attributes: ' . $map['memberof'] . ', ' . $map['type'] .
202 ' Group Type: ' . $this->type_map['group']
203 );
204
205 // Check each DN of the passed memberOf
206 foreach ($memberof as $dn) {
207
208 // Avoid infinite loops, only need to check a DN once
209 if (isset($searched[$dn])) {
210 continue;
211 }
212
213 // Track all DN's that are searched
214 // Use DN for key as well, isset() is faster than in_array()
215 $searched[$dn] = $dn;
216
217 // Query LDAP for the attribute values for the DN
218 try {
219 $attributes = $this->getLdap()->getAttributes($dn, array($map['memberof'], $map['type']));
220 } catch (SimpleSAML_Error_AuthSource $e) {
221 continue; // DN must not exist, just continue. Logged by the LDAP object
222 }
223
224 // Only look for groups
225 if (!in_array($this->type_map['group'], $attributes[$map['type']], true)) {
226 continue;
227 }
228
229 // Add to found groups array
230 $groups[] = $dn;
231
232 // Recursively search "sub" groups
233 $groups = array_merge($groups, $this->search($attributes[$map['memberof']]));
234 }
235
236 // Return only the unique group names
237 return array_unique($groups);
238 }
239
240
249 protected function searchActiveDirectory($dn)
250 {
251 assert('is_string($dn) && $dn != ""');
252
253 // Shorten the variable name
254 $map =& $this->attribute_map;
255
256 // Log the search
258 $this->title . 'Searching ActiveDirectory group membership.' .
259 ' DN: ' . $dn .
260 ' DN Attribute: ' . $map['dn'] .
261 ' Member Attribute: ' . $map['member'] .
262 ' Type Attribute: ' . $map['type'] .
263 ' Type Value: ' . $this->type_map['group'] .
264 ' Base: ' . implode('; ', $this->base_dn)
265 );
266
267 // AD connections should have this set
268 $this->getLdap()->setOption(LDAP_OPT_REFERRALS, 0);
269
270 // Search AD with the specific recursive flag
271 try {
272 $entries = $this->getLdap()->searchformultiple(
273 $this->base_dn,
274 array($map['type'] => $this->type_map['group'], $map['member'] . ':1.2.840.113556.1.4.1941:' => $dn),
275 array($map['dn'])
276 );
277
278 // The search may throw an exception if no entries
279 // are found, unlikely but possible.
280 } catch (SimpleSAML_Error_UserNotFound $e) {
281 return array();
282 }
283
284 //Init the groups
285 $groups = array();
286
287 // Check each entry..
288 foreach ($entries as $entry) {
289
290 // Check for the DN using the original attribute name
291 if (isset($entry[$map['dn']][0])) {
292 $groups[] = $entry[$map['dn']][0];
293 continue;
294 }
295
296 // Sometimes the returned attribute names are lowercase
297 if (isset($entry[strtolower($map['dn'])][0])) {
298 $groups[] = $entry[strtolower($map['dn'])][0];
299 continue;
300 }
301
302 // AD queries also seem to return the objects dn by default
303 if (isset($entry['dn'])) {
304 $groups[] = $entry['dn'];
305 continue;
306 }
307
308 // Could not find DN, log and continue
310 $this->title . 'The DN attribute [' .
311 implode(', ', array($map['dn'], strtolower($map['dn']), 'dn')) .
312 '] could not be found in the entry. ' . $this->var_export($entry)
313 );
314 }
315
316 // All done
317 return $groups;
318 }
319}
An exception for terminatinating execution or to throw for unit testing.
static debug($string)
Definition: Logger.php:213
static notice($string)
Definition: Logger.php:190
getGroups(array $attributes)
This section of code was broken out because the child filter AuthorizeByGroup can use this method as ...
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.
getLdap()
Getter for the LDAP connection object.
Definition: BaseFilter.php:256
var_export($value)
Local utility function to get details about a variable, basically converting it to a string to be use...
Definition: BaseFilter.php:303
$attributes