Passed
Push — master ( 78c149...755611 )
by Blizzz
14:14
created
lib/public/LDAP/ILDAPProvider.php 1 patch
Indentation   +109 added lines, -109 removed lines patch added patch discarded remove patch
@@ -33,128 +33,128 @@
 block discarded – undo
33 33
  * @since 11.0.0
34 34
  */
35 35
 interface ILDAPProvider {
36
-	/**
37
-	 * Translate a user id to LDAP DN.
38
-	 * @param string $uid user id
39
-	 * @return string
40
-	 * @since 11.0.0
41
-	 */
42
-	public function getUserDN($uid);
36
+    /**
37
+     * Translate a user id to LDAP DN.
38
+     * @param string $uid user id
39
+     * @return string
40
+     * @since 11.0.0
41
+     */
42
+    public function getUserDN($uid);
43 43
 
44
-	/**
45
-	 * Translate a group id to LDAP DN.
46
-	 * @param string $gid group id
47
-	 * @return string
48
-	 * @since 13.0.0
49
-	 */
50
-	public function getGroupDN($gid);
44
+    /**
45
+     * Translate a group id to LDAP DN.
46
+     * @param string $gid group id
47
+     * @return string
48
+     * @since 13.0.0
49
+     */
50
+    public function getGroupDN($gid);
51 51
 
52
-	/**
53
-	 * Translate a LDAP DN to an internal user name.
54
-	 * @param string $dn LDAP DN
55
-	 * @return string with the internal user name
56
-	 * @throws \Exception if translation was unsuccessful
57
-	 * @since 11.0.0
58
-	 */
59
-	public function getUserName($dn);
52
+    /**
53
+     * Translate a LDAP DN to an internal user name.
54
+     * @param string $dn LDAP DN
55
+     * @return string with the internal user name
56
+     * @throws \Exception if translation was unsuccessful
57
+     * @since 11.0.0
58
+     */
59
+    public function getUserName($dn);
60 60
 	
61
-	/**
62
-	 * Convert a stored DN so it can be used as base parameter for LDAP queries.
63
-	 * @param string $dn the DN
64
-	 * @return string
65
-	 * @since 11.0.0
66
-	 */
67
-	public function DNasBaseParameter($dn);
61
+    /**
62
+     * Convert a stored DN so it can be used as base parameter for LDAP queries.
63
+     * @param string $dn the DN
64
+     * @return string
65
+     * @since 11.0.0
66
+     */
67
+    public function DNasBaseParameter($dn);
68 68
 	
69
-	/**
70
-	 * Sanitize a DN received from the LDAP server.
71
-	 * @param array $dn the DN in question
72
-	 * @return array the sanitized DN
73
-	 * @since 11.0.0
74
-	 */
75
-	public function sanitizeDN($dn);
69
+    /**
70
+     * Sanitize a DN received from the LDAP server.
71
+     * @param array $dn the DN in question
72
+     * @return array the sanitized DN
73
+     * @since 11.0.0
74
+     */
75
+    public function sanitizeDN($dn);
76 76
 	
77
-	/**
78
-	 * Return a new LDAP connection resource for the specified user. 
79
-	 * @param string $uid user id
80
-	 * @return resource of the LDAP connection
81
-	 * @since 11.0.0
82
-	 */
83
-	public function getLDAPConnection($uid);
77
+    /**
78
+     * Return a new LDAP connection resource for the specified user. 
79
+     * @param string $uid user id
80
+     * @return resource of the LDAP connection
81
+     * @since 11.0.0
82
+     */
83
+    public function getLDAPConnection($uid);
84 84
 
85
-	/**
86
-	 * Return a new LDAP connection resource for the specified group.
87
-	 * @param string $gid group id
88
-	 * @return resource of the LDAP connection
89
-	 * @since 13.0.0
90
-	 */
91
-	public function getGroupLDAPConnection($gid);
85
+    /**
86
+     * Return a new LDAP connection resource for the specified group.
87
+     * @param string $gid group id
88
+     * @return resource of the LDAP connection
89
+     * @since 13.0.0
90
+     */
91
+    public function getGroupLDAPConnection($gid);
92 92
 	
93
-	/**
94
-	 * Get the LDAP base for users.
95
-	 * @param string $uid user id
96
-	 * @return string the base for users
97
-	 * @throws \Exception if user id was not found in LDAP
98
-	 * @since 11.0.0
99
-	 */
100
-	public function getLDAPBaseUsers($uid);
93
+    /**
94
+     * Get the LDAP base for users.
95
+     * @param string $uid user id
96
+     * @return string the base for users
97
+     * @throws \Exception if user id was not found in LDAP
98
+     * @since 11.0.0
99
+     */
100
+    public function getLDAPBaseUsers($uid);
101 101
 	
102
-	/**
103
-	 * Get the LDAP base for groups.
104
-	 * @param string $uid user id
105
-	 * @return string the base for groups
106
-	 * @throws \Exception if user id was not found in LDAP
107
-	 * @since 11.0.0
108
-	 */
109
-	public function getLDAPBaseGroups($uid);
102
+    /**
103
+     * Get the LDAP base for groups.
104
+     * @param string $uid user id
105
+     * @return string the base for groups
106
+     * @throws \Exception if user id was not found in LDAP
107
+     * @since 11.0.0
108
+     */
109
+    public function getLDAPBaseGroups($uid);
110 110
 	
111
-	/**
112
-	 * Check whether a LDAP DN exists
113
-	 * @param string $dn LDAP DN
114
-	 * @return bool whether the DN exists
115
-	 * @since 11.0.0
116
-	 */
117
-	public function dnExists($dn);
111
+    /**
112
+     * Check whether a LDAP DN exists
113
+     * @param string $dn LDAP DN
114
+     * @return bool whether the DN exists
115
+     * @since 11.0.0
116
+     */
117
+    public function dnExists($dn);
118 118
 	
119
-	/**
120
-	 * Clear the cache if a cache is used, otherwise do nothing.
121
-	 * @param string $uid user id
122
-	 * @since 11.0.0
123
-	 */
124
-	public function clearCache($uid);
119
+    /**
120
+     * Clear the cache if a cache is used, otherwise do nothing.
121
+     * @param string $uid user id
122
+     * @since 11.0.0
123
+     */
124
+    public function clearCache($uid);
125 125
 
126
-	/**
127
-	 * Clear the cache if a cache is used, otherwise do nothing.
128
-	 * @param string $gid group id
129
-	 * @since 13.0.0
130
-	 */
131
-	public function clearGroupCache($gid);
126
+    /**
127
+     * Clear the cache if a cache is used, otherwise do nothing.
128
+     * @param string $gid group id
129
+     * @since 13.0.0
130
+     */
131
+    public function clearGroupCache($gid);
132 132
 
133
-	/**
134
-	 * Get the LDAP attribute name for the user's display name
135
-	 * @param string $uid user id
136
-	 * @return string the display name field
137
-	 * @throws \Exception if user id was not found in LDAP
138
-	 * @since 12.0.0
139
-	 */
140
-	public function getLDAPDisplayNameField($uid);
133
+    /**
134
+     * Get the LDAP attribute name for the user's display name
135
+     * @param string $uid user id
136
+     * @return string the display name field
137
+     * @throws \Exception if user id was not found in LDAP
138
+     * @since 12.0.0
139
+     */
140
+    public function getLDAPDisplayNameField($uid);
141 141
 
142
-	/**
143
-	 * Get the LDAP attribute name for the email
144
-	 * @param string $uid user id
145
-	 * @return string the email field
146
-	 * @throws \Exception if user id was not found in LDAP
147
-	 * @since 12.0.0
148
-	 */
149
-	public function getLDAPEmailField($uid);
142
+    /**
143
+     * Get the LDAP attribute name for the email
144
+     * @param string $uid user id
145
+     * @return string the email field
146
+     * @throws \Exception if user id was not found in LDAP
147
+     * @since 12.0.0
148
+     */
149
+    public function getLDAPEmailField($uid);
150 150
 
151
-	/**
152
-	 * Get the LDAP attribute name for the type of association betweeen users and groups
153
-	 * @param string $gid group id
154
-	 * @return string the configuration, one of: 'memberUid', 'uniqueMember', 'member', 'gidNumber', ''
155
-	 * @throws \Exception if group id was not found in LDAP
156
-	 * @since 13.0.0
157
-	 */
158
-	public function getLDAPGroupMemberAssoc($gid);
151
+    /**
152
+     * Get the LDAP attribute name for the type of association betweeen users and groups
153
+     * @param string $gid group id
154
+     * @return string the configuration, one of: 'memberUid', 'uniqueMember', 'member', 'gidNumber', ''
155
+     * @throws \Exception if group id was not found in LDAP
156
+     * @since 13.0.0
157
+     */
158
+    public function getLDAPGroupMemberAssoc($gid);
159 159
 
160 160
 }
Please login to merge, or discard this patch.
apps/user_ldap/lib/Wizard.php 2 patches
Indentation   +1314 added lines, -1314 removed lines patch added patch discarded remove patch
@@ -42,1320 +42,1320 @@
 block discarded – undo
42 42
 use OCP\ILogger;
43 43
 
44 44
 class Wizard extends LDAPUtility {
45
-	/** @var \OCP\IL10N */
46
-	static protected $l;
47
-	protected $access;
48
-	protected $cr;
49
-	protected $configuration;
50
-	protected $result;
51
-	protected $resultCache = array();
52
-
53
-	const LRESULT_PROCESSED_OK = 2;
54
-	const LRESULT_PROCESSED_INVALID = 3;
55
-	const LRESULT_PROCESSED_SKIP = 4;
56
-
57
-	const LFILTER_LOGIN      = 2;
58
-	const LFILTER_USER_LIST  = 3;
59
-	const LFILTER_GROUP_LIST = 4;
60
-
61
-	const LFILTER_MODE_ASSISTED = 2;
62
-	const LFILTER_MODE_RAW = 1;
63
-
64
-	const LDAP_NW_TIMEOUT = 4;
65
-
66
-	/**
67
-	 * Constructor
68
-	 * @param Configuration $configuration an instance of Configuration
69
-	 * @param ILDAPWrapper $ldap an instance of ILDAPWrapper
70
-	 * @param Access $access
71
-	 */
72
-	public function __construct(Configuration $configuration, ILDAPWrapper $ldap, Access $access) {
73
-		parent::__construct($ldap);
74
-		$this->configuration = $configuration;
75
-		if(is_null(Wizard::$l)) {
76
-			Wizard::$l = \OC::$server->getL10N('user_ldap');
77
-		}
78
-		$this->access = $access;
79
-		$this->result = new WizardResult();
80
-	}
81
-
82
-	public function  __destruct() {
83
-		if($this->result->hasChanges()) {
84
-			$this->configuration->saveConfiguration();
85
-		}
86
-	}
87
-
88
-	/**
89
-	 * counts entries in the LDAP directory
90
-	 *
91
-	 * @param string $filter the LDAP search filter
92
-	 * @param string $type a string being either 'users' or 'groups';
93
-	 * @return int
94
-	 * @throws \Exception
95
-	 */
96
-	public function countEntries(string $filter, string $type): int {
97
-		$reqs = ['ldapHost', 'ldapPort', 'ldapBase'];
98
-		if($type === 'users') {
99
-			$reqs[] = 'ldapUserFilter';
100
-		}
101
-		if(!$this->checkRequirements($reqs)) {
102
-			throw new \Exception('Requirements not met', 400);
103
-		}
104
-
105
-		$attr = ['dn']; // default
106
-		$limit = 1001;
107
-		if($type === 'groups') {
108
-			$result =  $this->access->countGroups($filter, $attr, $limit);
109
-		} else if($type === 'users') {
110
-			$result = $this->access->countUsers($filter, $attr, $limit);
111
-		} else if ($type === 'objects') {
112
-			$result = $this->access->countObjects($limit);
113
-		} else {
114
-			throw new \Exception('Internal error: Invalid object type', 500);
115
-		}
116
-
117
-		return (int)$result;
118
-	}
119
-
120
-	/**
121
-	 * formats the return value of a count operation to the string to be
122
-	 * inserted.
123
-	 *
124
-	 * @param int $count
125
-	 * @return string
126
-	 */
127
-	private function formatCountResult(int $count): string {
128
-		if($count > 1000) {
129
-			return '> 1000';
130
-		}
131
-		return (string)$count;
132
-	}
133
-
134
-	public function countGroups() {
135
-		$filter = $this->configuration->ldapGroupFilter;
136
-
137
-		if(empty($filter)) {
138
-			$output = self::$l->n('%s group found', '%s groups found', 0, array(0));
139
-			$this->result->addChange('ldap_group_count', $output);
140
-			return $this->result;
141
-		}
142
-
143
-		try {
144
-			$groupsTotal = $this->countEntries($filter, 'groups');
145
-		} catch (\Exception $e) {
146
-			//400 can be ignored, 500 is forwarded
147
-			if($e->getCode() === 500) {
148
-				throw $e;
149
-			}
150
-			return false;
151
-		}
152
-		$output = self::$l->n(
153
-			'%s group found',
154
-			'%s groups found',
155
-			$groupsTotal,
156
-			[$this->formatCountResult($groupsTotal)]
157
-		);
158
-		$this->result->addChange('ldap_group_count', $output);
159
-		return $this->result;
160
-	}
161
-
162
-	/**
163
-	 * @return WizardResult
164
-	 * @throws \Exception
165
-	 */
166
-	public function countUsers() {
167
-		$filter = $this->access->getFilterForUserCount();
168
-
169
-		$usersTotal = $this->countEntries($filter, 'users');
170
-		$output = self::$l->n(
171
-			'%s user found',
172
-			'%s users found',
173
-			$usersTotal,
174
-			[$this->formatCountResult($usersTotal)]
175
-		);
176
-		$this->result->addChange('ldap_user_count', $output);
177
-		return $this->result;
178
-	}
179
-
180
-	/**
181
-	 * counts any objects in the currently set base dn
182
-	 *
183
-	 * @return WizardResult
184
-	 * @throws \Exception
185
-	 */
186
-	public function countInBaseDN() {
187
-		// we don't need to provide a filter in this case
188
-		$total = $this->countEntries('', 'objects');
189
-		if($total === false) {
190
-			throw new \Exception('invalid results received');
191
-		}
192
-		$this->result->addChange('ldap_test_base', $total);
193
-		return $this->result;
194
-	}
195
-
196
-	/**
197
-	 * counts users with a specified attribute
198
-	 * @param string $attr
199
-	 * @param bool $existsCheck
200
-	 * @return int|bool
201
-	 */
202
-	public function countUsersWithAttribute($attr, $existsCheck = false) {
203
-		if(!$this->checkRequirements(array('ldapHost',
204
-										   'ldapPort',
205
-										   'ldapBase',
206
-										   'ldapUserFilter',
207
-										   ))) {
208
-			return  false;
209
-		}
210
-
211
-		$filter = $this->access->combineFilterWithAnd(array(
212
-			$this->configuration->ldapUserFilter,
213
-			$attr . '=*'
214
-		));
215
-
216
-		$limit = ($existsCheck === false) ? null : 1;
217
-
218
-		return $this->access->countUsers($filter, array('dn'), $limit);
219
-	}
220
-
221
-	/**
222
-	 * detects the display name attribute. If a setting is already present that
223
-	 * returns at least one hit, the detection will be canceled.
224
-	 * @return WizardResult|bool
225
-	 * @throws \Exception
226
-	 */
227
-	public function detectUserDisplayNameAttribute() {
228
-		if(!$this->checkRequirements(array('ldapHost',
229
-										'ldapPort',
230
-										'ldapBase',
231
-										'ldapUserFilter',
232
-										))) {
233
-			return  false;
234
-		}
235
-
236
-		$attr = $this->configuration->ldapUserDisplayName;
237
-		if ($attr !== '' && $attr !== 'displayName') {
238
-			// most likely not the default value with upper case N,
239
-			// verify it still produces a result
240
-			$count = (int)$this->countUsersWithAttribute($attr, true);
241
-			if($count > 0) {
242
-				//no change, but we sent it back to make sure the user interface
243
-				//is still correct, even if the ajax call was cancelled meanwhile
244
-				$this->result->addChange('ldap_display_name', $attr);
245
-				return $this->result;
246
-			}
247
-		}
248
-
249
-		// first attribute that has at least one result wins
250
-		$displayNameAttrs = array('displayname', 'cn');
251
-		foreach ($displayNameAttrs as $attr) {
252
-			$count = (int)$this->countUsersWithAttribute($attr, true);
253
-
254
-			if($count > 0) {
255
-				$this->applyFind('ldap_display_name', $attr);
256
-				return $this->result;
257
-			}
258
-		}
259
-
260
-		throw new \Exception(self::$l->t('Could not detect user display name attribute. Please specify it yourself in advanced LDAP settings.'));
261
-	}
262
-
263
-	/**
264
-	 * detects the most often used email attribute for users applying to the
265
-	 * user list filter. If a setting is already present that returns at least
266
-	 * one hit, the detection will be canceled.
267
-	 * @return WizardResult|bool
268
-	 */
269
-	public function detectEmailAttribute() {
270
-		if(!$this->checkRequirements(array('ldapHost',
271
-										   'ldapPort',
272
-										   'ldapBase',
273
-										   'ldapUserFilter',
274
-										   ))) {
275
-			return  false;
276
-		}
277
-
278
-		$attr = $this->configuration->ldapEmailAttribute;
279
-		if ($attr !== '') {
280
-			$count = (int)$this->countUsersWithAttribute($attr, true);
281
-			if($count > 0) {
282
-				return false;
283
-			}
284
-			$writeLog = true;
285
-		} else {
286
-			$writeLog = false;
287
-		}
288
-
289
-		$emailAttributes = array('mail', 'mailPrimaryAddress');
290
-		$winner = '';
291
-		$maxUsers = 0;
292
-		foreach($emailAttributes as $attr) {
293
-			$count = $this->countUsersWithAttribute($attr);
294
-			if($count > $maxUsers) {
295
-				$maxUsers = $count;
296
-				$winner = $attr;
297
-			}
298
-		}
299
-
300
-		if($winner !== '') {
301
-			$this->applyFind('ldap_email_attr', $winner);
302
-			if($writeLog) {
303
-				\OCP\Util::writeLog('user_ldap', 'The mail attribute has ' .
304
-					'automatically been reset, because the original value ' .
305
-					'did not return any results.', ILogger::INFO);
306
-			}
307
-		}
308
-
309
-		return $this->result;
310
-	}
311
-
312
-	/**
313
-	 * @return WizardResult
314
-	 * @throws \Exception
315
-	 */
316
-	public function determineAttributes() {
317
-		if(!$this->checkRequirements(array('ldapHost',
318
-										   'ldapPort',
319
-										   'ldapBase',
320
-										   'ldapUserFilter',
321
-										   ))) {
322
-			return  false;
323
-		}
324
-
325
-		$attributes = $this->getUserAttributes();
326
-
327
-		natcasesort($attributes);
328
-		$attributes = array_values($attributes);
329
-
330
-		$this->result->addOptions('ldap_loginfilter_attributes', $attributes);
331
-
332
-		$selected = $this->configuration->ldapLoginFilterAttributes;
333
-		if(is_array($selected) && !empty($selected)) {
334
-			$this->result->addChange('ldap_loginfilter_attributes', $selected);
335
-		}
336
-
337
-		return $this->result;
338
-	}
339
-
340
-	/**
341
-	 * detects the available LDAP attributes
342
-	 * @return array|false The instance's WizardResult instance
343
-	 * @throws \Exception
344
-	 */
345
-	private function getUserAttributes() {
346
-		if(!$this->checkRequirements(array('ldapHost',
347
-										   'ldapPort',
348
-										   'ldapBase',
349
-										   'ldapUserFilter',
350
-										   ))) {
351
-			return  false;
352
-		}
353
-		$cr = $this->getConnection();
354
-		if(!$cr) {
355
-			throw new \Exception('Could not connect to LDAP');
356
-		}
357
-
358
-		$base = $this->configuration->ldapBase[0];
359
-		$filter = $this->configuration->ldapUserFilter;
360
-		$rr = $this->ldap->search($cr, $base, $filter, array(), 1, 1);
361
-		if(!$this->ldap->isResource($rr)) {
362
-			return false;
363
-		}
364
-		$er = $this->ldap->firstEntry($cr, $rr);
365
-		$attributes = $this->ldap->getAttributes($cr, $er);
366
-		$pureAttributes = array();
367
-		for($i = 0; $i < $attributes['count']; $i++) {
368
-			$pureAttributes[] = $attributes[$i];
369
-		}
370
-
371
-		return $pureAttributes;
372
-	}
373
-
374
-	/**
375
-	 * detects the available LDAP groups
376
-	 * @return WizardResult|false the instance's WizardResult instance
377
-	 */
378
-	public function determineGroupsForGroups() {
379
-		return $this->determineGroups('ldap_groupfilter_groups',
380
-									  'ldapGroupFilterGroups',
381
-									  false);
382
-	}
383
-
384
-	/**
385
-	 * detects the available LDAP groups
386
-	 * @return WizardResult|false the instance's WizardResult instance
387
-	 */
388
-	public function determineGroupsForUsers() {
389
-		return $this->determineGroups('ldap_userfilter_groups',
390
-									  'ldapUserFilterGroups');
391
-	}
392
-
393
-	/**
394
-	 * detects the available LDAP groups
395
-	 * @param string $dbKey
396
-	 * @param string $confKey
397
-	 * @param bool $testMemberOf
398
-	 * @return WizardResult|false the instance's WizardResult instance
399
-	 * @throws \Exception
400
-	 */
401
-	private function determineGroups($dbKey, $confKey, $testMemberOf = true) {
402
-		if(!$this->checkRequirements(array('ldapHost',
403
-										   'ldapPort',
404
-										   'ldapBase',
405
-										   ))) {
406
-			return  false;
407
-		}
408
-		$cr = $this->getConnection();
409
-		if(!$cr) {
410
-			throw new \Exception('Could not connect to LDAP');
411
-		}
412
-
413
-		$this->fetchGroups($dbKey, $confKey);
414
-
415
-		if($testMemberOf) {
416
-			$this->configuration->hasMemberOfFilterSupport = $this->testMemberOf();
417
-			$this->result->markChange();
418
-			if(!$this->configuration->hasMemberOfFilterSupport) {
419
-				throw new \Exception('memberOf is not supported by the server');
420
-			}
421
-		}
422
-
423
-		return $this->result;
424
-	}
425
-
426
-	/**
427
-	 * fetches all groups from LDAP and adds them to the result object
428
-	 *
429
-	 * @param string $dbKey
430
-	 * @param string $confKey
431
-	 * @return array $groupEntries
432
-	 * @throws \Exception
433
-	 */
434
-	public function fetchGroups($dbKey, $confKey) {
435
-		$obclasses = array('posixGroup', 'group', 'zimbraDistributionList', 'groupOfNames', 'groupOfUniqueNames');
436
-
437
-		$filterParts = array();
438
-		foreach($obclasses as $obclass) {
439
-			$filterParts[] = 'objectclass='.$obclass;
440
-		}
441
-		//we filter for everything
442
-		//- that looks like a group and
443
-		//- has the group display name set
444
-		$filter = $this->access->combineFilterWithOr($filterParts);
445
-		$filter = $this->access->combineFilterWithAnd(array($filter, 'cn=*'));
446
-
447
-		$groupNames = array();
448
-		$groupEntries = array();
449
-		$limit = 400;
450
-		$offset = 0;
451
-		do {
452
-			// we need to request dn additionally here, otherwise memberOf
453
-			// detection will fail later
454
-			$result = $this->access->searchGroups($filter, array('cn', 'dn'), $limit, $offset);
455
-			foreach($result as $item) {
456
-				if(!isset($item['cn']) && !is_array($item['cn']) && !isset($item['cn'][0])) {
457
-					// just in case - no issue known
458
-					continue;
459
-				}
460
-				$groupNames[] = $item['cn'][0];
461
-				$groupEntries[] = $item;
462
-			}
463
-			$offset += $limit;
464
-		} while ($this->access->hasMoreResults());
465
-
466
-		if(count($groupNames) > 0) {
467
-			natsort($groupNames);
468
-			$this->result->addOptions($dbKey, array_values($groupNames));
469
-		} else {
470
-			throw new \Exception(self::$l->t('Could not find the desired feature'));
471
-		}
472
-
473
-		$setFeatures = $this->configuration->$confKey;
474
-		if(is_array($setFeatures) && !empty($setFeatures)) {
475
-			//something is already configured? pre-select it.
476
-			$this->result->addChange($dbKey, $setFeatures);
477
-		}
478
-		return $groupEntries;
479
-	}
480
-
481
-	public function determineGroupMemberAssoc() {
482
-		if(!$this->checkRequirements(array('ldapHost',
483
-										   'ldapPort',
484
-										   'ldapGroupFilter',
485
-										   ))) {
486
-			return  false;
487
-		}
488
-		$attribute = $this->detectGroupMemberAssoc();
489
-		if($attribute === false) {
490
-			return false;
491
-		}
492
-		$this->configuration->setConfiguration(array('ldapGroupMemberAssocAttr' => $attribute));
493
-		$this->result->addChange('ldap_group_member_assoc_attribute', $attribute);
494
-
495
-		return $this->result;
496
-	}
497
-
498
-	/**
499
-	 * Detects the available object classes
500
-	 * @return WizardResult|false the instance's WizardResult instance
501
-	 * @throws \Exception
502
-	 */
503
-	public function determineGroupObjectClasses() {
504
-		if(!$this->checkRequirements(array('ldapHost',
505
-										   'ldapPort',
506
-										   'ldapBase',
507
-										   ))) {
508
-			return  false;
509
-		}
510
-		$cr = $this->getConnection();
511
-		if(!$cr) {
512
-			throw new \Exception('Could not connect to LDAP');
513
-		}
514
-
515
-		$obclasses = array('groupOfNames', 'groupOfUniqueNames', 'group', 'posixGroup', '*');
516
-		$this->determineFeature($obclasses,
517
-								'objectclass',
518
-								'ldap_groupfilter_objectclass',
519
-								'ldapGroupFilterObjectclass',
520
-								false);
521
-
522
-		return $this->result;
523
-	}
524
-
525
-	/**
526
-	 * detects the available object classes
527
-	 * @return WizardResult
528
-	 * @throws \Exception
529
-	 */
530
-	public function determineUserObjectClasses() {
531
-		if(!$this->checkRequirements(array('ldapHost',
532
-										   'ldapPort',
533
-										   'ldapBase',
534
-										   ))) {
535
-			return  false;
536
-		}
537
-		$cr = $this->getConnection();
538
-		if(!$cr) {
539
-			throw new \Exception('Could not connect to LDAP');
540
-		}
541
-
542
-		$obclasses = array('inetOrgPerson', 'person', 'organizationalPerson',
543
-						   'user', 'posixAccount', '*');
544
-		$filter = $this->configuration->ldapUserFilter;
545
-		//if filter is empty, it is probably the first time the wizard is called
546
-		//then, apply suggestions.
547
-		$this->determineFeature($obclasses,
548
-								'objectclass',
549
-								'ldap_userfilter_objectclass',
550
-								'ldapUserFilterObjectclass',
551
-								empty($filter));
552
-
553
-		return $this->result;
554
-	}
555
-
556
-	/**
557
-	 * @return WizardResult|false
558
-	 * @throws \Exception
559
-	 */
560
-	public function getGroupFilter() {
561
-		if(!$this->checkRequirements(array('ldapHost',
562
-										   'ldapPort',
563
-										   'ldapBase',
564
-										   ))) {
565
-			return false;
566
-		}
567
-		//make sure the use display name is set
568
-		$displayName = $this->configuration->ldapGroupDisplayName;
569
-		if ($displayName === '') {
570
-			$d = $this->configuration->getDefaults();
571
-			$this->applyFind('ldap_group_display_name',
572
-							 $d['ldap_group_display_name']);
573
-		}
574
-		$filter = $this->composeLdapFilter(self::LFILTER_GROUP_LIST);
575
-
576
-		$this->applyFind('ldap_group_filter', $filter);
577
-		return $this->result;
578
-	}
579
-
580
-	/**
581
-	 * @return WizardResult|false
582
-	 * @throws \Exception
583
-	 */
584
-	public function getUserListFilter() {
585
-		if(!$this->checkRequirements(array('ldapHost',
586
-										   'ldapPort',
587
-										   'ldapBase',
588
-										   ))) {
589
-			return false;
590
-		}
591
-		//make sure the use display name is set
592
-		$displayName = $this->configuration->ldapUserDisplayName;
593
-		if ($displayName === '') {
594
-			$d = $this->configuration->getDefaults();
595
-			$this->applyFind('ldap_display_name', $d['ldap_display_name']);
596
-		}
597
-		$filter = $this->composeLdapFilter(self::LFILTER_USER_LIST);
598
-		if(!$filter) {
599
-			throw new \Exception('Cannot create filter');
600
-		}
601
-
602
-		$this->applyFind('ldap_userlist_filter', $filter);
603
-		return $this->result;
604
-	}
605
-
606
-	/**
607
-	 * @return bool|WizardResult
608
-	 * @throws \Exception
609
-	 */
610
-	public function getUserLoginFilter() {
611
-		if(!$this->checkRequirements(array('ldapHost',
612
-										   'ldapPort',
613
-										   'ldapBase',
614
-										   'ldapUserFilter',
615
-										   ))) {
616
-			return false;
617
-		}
618
-
619
-		$filter = $this->composeLdapFilter(self::LFILTER_LOGIN);
620
-		if(!$filter) {
621
-			throw new \Exception('Cannot create filter');
622
-		}
623
-
624
-		$this->applyFind('ldap_login_filter', $filter);
625
-		return $this->result;
626
-	}
627
-
628
-	/**
629
-	 * @return bool|WizardResult
630
-	 * @param string $loginName
631
-	 * @throws \Exception
632
-	 */
633
-	public function testLoginName($loginName) {
634
-		if(!$this->checkRequirements(array('ldapHost',
635
-			'ldapPort',
636
-			'ldapBase',
637
-			'ldapLoginFilter',
638
-		))) {
639
-			return false;
640
-		}
641
-
642
-		$cr = $this->access->connection->getConnectionResource();
643
-		if(!$this->ldap->isResource($cr)) {
644
-			throw new \Exception('connection error');
645
-		}
646
-
647
-		if(mb_strpos($this->access->connection->ldapLoginFilter, '%uid', 0, 'UTF-8')
648
-			=== false) {
649
-			throw new \Exception('missing placeholder');
650
-		}
651
-
652
-		$users = $this->access->countUsersByLoginName($loginName);
653
-		if($this->ldap->errno($cr) !== 0) {
654
-			throw new \Exception($this->ldap->error($cr));
655
-		}
656
-		$filter = str_replace('%uid', $loginName, $this->access->connection->ldapLoginFilter);
657
-		$this->result->addChange('ldap_test_loginname', $users);
658
-		$this->result->addChange('ldap_test_effective_filter', $filter);
659
-		return $this->result;
660
-	}
661
-
662
-	/**
663
-	 * Tries to determine the port, requires given Host, User DN and Password
664
-	 * @return WizardResult|false WizardResult on success, false otherwise
665
-	 * @throws \Exception
666
-	 */
667
-	public function guessPortAndTLS() {
668
-		if(!$this->checkRequirements(array('ldapHost',
669
-										   ))) {
670
-			return false;
671
-		}
672
-		$this->checkHost();
673
-		$portSettings = $this->getPortSettingsToTry();
674
-
675
-		if(!is_array($portSettings)) {
676
-			throw new \Exception(print_r($portSettings, true));
677
-		}
678
-
679
-		//proceed from the best configuration and return on first success
680
-		foreach($portSettings as $setting) {
681
-			$p = $setting['port'];
682
-			$t = $setting['tls'];
683
-			\OCP\Util::writeLog('user_ldap', 'Wiz: trying port '. $p . ', TLS '. $t, ILogger::DEBUG);
684
-			//connectAndBind may throw Exception, it needs to be catched by the
685
-			//callee of this method
686
-
687
-			try {
688
-				$settingsFound = $this->connectAndBind($p, $t);
689
-			} catch (\Exception $e) {
690
-				// any reply other than -1 (= cannot connect) is already okay,
691
-				// because then we found the server
692
-				// unavailable startTLS returns -11
693
-				if($e->getCode() > 0) {
694
-					$settingsFound = true;
695
-				} else {
696
-					throw $e;
697
-				}
698
-			}
699
-
700
-			if ($settingsFound === true) {
701
-				$config = array(
702
-					'ldapPort' => $p,
703
-					'ldapTLS' => (int)$t
704
-				);
705
-				$this->configuration->setConfiguration($config);
706
-				\OCP\Util::writeLog('user_ldap', 'Wiz: detected Port ' . $p, ILogger::DEBUG);
707
-				$this->result->addChange('ldap_port', $p);
708
-				return $this->result;
709
-			}
710
-		}
711
-
712
-		//custom port, undetected (we do not brute force)
713
-		return false;
714
-	}
715
-
716
-	/**
717
-	 * tries to determine a base dn from User DN or LDAP Host
718
-	 * @return WizardResult|false WizardResult on success, false otherwise
719
-	 */
720
-	public function guessBaseDN() {
721
-		if(!$this->checkRequirements(array('ldapHost',
722
-										   'ldapPort',
723
-										   ))) {
724
-			return false;
725
-		}
726
-
727
-		//check whether a DN is given in the agent name (99.9% of all cases)
728
-		$base = null;
729
-		$i = stripos($this->configuration->ldapAgentName, 'dc=');
730
-		if($i !== false) {
731
-			$base = substr($this->configuration->ldapAgentName, $i);
732
-			if($this->testBaseDN($base)) {
733
-				$this->applyFind('ldap_base', $base);
734
-				return $this->result;
735
-			}
736
-		}
737
-
738
-		//this did not help :(
739
-		//Let's see whether we can parse the Host URL and convert the domain to
740
-		//a base DN
741
-		$helper = new Helper(\OC::$server->getConfig());
742
-		$domain = $helper->getDomainFromURL($this->configuration->ldapHost);
743
-		if(!$domain) {
744
-			return false;
745
-		}
746
-
747
-		$dparts = explode('.', $domain);
748
-		while(count($dparts) > 0) {
749
-			$base2 = 'dc=' . implode(',dc=', $dparts);
750
-			if ($base !== $base2 && $this->testBaseDN($base2)) {
751
-				$this->applyFind('ldap_base', $base2);
752
-				return $this->result;
753
-			}
754
-			array_shift($dparts);
755
-		}
756
-
757
-		return false;
758
-	}
759
-
760
-	/**
761
-	 * sets the found value for the configuration key in the WizardResult
762
-	 * as well as in the Configuration instance
763
-	 * @param string $key the configuration key
764
-	 * @param string $value the (detected) value
765
-	 *
766
-	 */
767
-	private function applyFind($key, $value) {
768
-		$this->result->addChange($key, $value);
769
-		$this->configuration->setConfiguration(array($key => $value));
770
-	}
771
-
772
-	/**
773
-	 * Checks, whether a port was entered in the Host configuration
774
-	 * field. In this case the port will be stripped off, but also stored as
775
-	 * setting.
776
-	 */
777
-	private function checkHost() {
778
-		$host = $this->configuration->ldapHost;
779
-		$hostInfo = parse_url($host);
780
-
781
-		//removes Port from Host
782
-		if(is_array($hostInfo) && isset($hostInfo['port'])) {
783
-			$port = $hostInfo['port'];
784
-			$host = str_replace(':'.$port, '', $host);
785
-			$this->applyFind('ldap_host', $host);
786
-			$this->applyFind('ldap_port', $port);
787
-		}
788
-	}
789
-
790
-	/**
791
-	 * tries to detect the group member association attribute which is
792
-	 * one of 'uniqueMember', 'memberUid', 'member', 'gidNumber'
793
-	 * @return string|false, string with the attribute name, false on error
794
-	 * @throws \Exception
795
-	 */
796
-	private function detectGroupMemberAssoc() {
797
-		$possibleAttrs = ['uniqueMember', 'memberUid', 'member', 'gidNumber'];
798
-		$filter = $this->configuration->ldapGroupFilter;
799
-		if(empty($filter)) {
800
-			return false;
801
-		}
802
-		$cr = $this->getConnection();
803
-		if(!$cr) {
804
-			throw new \Exception('Could not connect to LDAP');
805
-		}
806
-		$base = $this->configuration->ldapBaseGroups[0] ?: $this->configuration->ldapBase[0];
807
-		$rr = $this->ldap->search($cr, $base, $filter, $possibleAttrs, 0, 1000);
808
-		if(!$this->ldap->isResource($rr)) {
809
-			return false;
810
-		}
811
-		$er = $this->ldap->firstEntry($cr, $rr);
812
-		while(is_resource($er)) {
813
-			$this->ldap->getDN($cr, $er);
814
-			$attrs = $this->ldap->getAttributes($cr, $er);
815
-			$result = [];
816
-			$possibleAttrsCount = count($possibleAttrs);
817
-			for($i = 0; $i < $possibleAttrsCount; $i++) {
818
-				if(isset($attrs[$possibleAttrs[$i]])) {
819
-					$result[$possibleAttrs[$i]] = $attrs[$possibleAttrs[$i]]['count'];
820
-				}
821
-			}
822
-			if(!empty($result)) {
823
-				natsort($result);
824
-				return key($result);
825
-			}
826
-
827
-			$er = $this->ldap->nextEntry($cr, $er);
828
-		}
829
-
830
-		return false;
831
-	}
832
-
833
-	/**
834
-	 * Checks whether for a given BaseDN results will be returned
835
-	 * @param string $base the BaseDN to test
836
-	 * @return bool true on success, false otherwise
837
-	 * @throws \Exception
838
-	 */
839
-	private function testBaseDN($base) {
840
-		$cr = $this->getConnection();
841
-		if(!$cr) {
842
-			throw new \Exception('Could not connect to LDAP');
843
-		}
844
-
845
-		//base is there, let's validate it. If we search for anything, we should
846
-		//get a result set > 0 on a proper base
847
-		$rr = $this->ldap->search($cr, $base, 'objectClass=*', array('dn'), 0, 1);
848
-		if(!$this->ldap->isResource($rr)) {
849
-			$errorNo  = $this->ldap->errno($cr);
850
-			$errorMsg = $this->ldap->error($cr);
851
-			\OCP\Util::writeLog('user_ldap', 'Wiz: Could not search base '.$base.
852
-							' Error '.$errorNo.': '.$errorMsg, ILogger::INFO);
853
-			return false;
854
-		}
855
-		$entries = $this->ldap->countEntries($cr, $rr);
856
-		return ($entries !== false) && ($entries > 0);
857
-	}
858
-
859
-	/**
860
-	 * Checks whether the server supports memberOf in LDAP Filter.
861
-	 * Note: at least in OpenLDAP, availability of memberOf is dependent on
862
-	 * a configured objectClass. I.e. not necessarily for all available groups
863
-	 * memberOf does work.
864
-	 *
865
-	 * @return bool true if it does, false otherwise
866
-	 * @throws \Exception
867
-	 */
868
-	private function testMemberOf() {
869
-		$cr = $this->getConnection();
870
-		if(!$cr) {
871
-			throw new \Exception('Could not connect to LDAP');
872
-		}
873
-		$result = $this->access->countUsers('memberOf=*', array('memberOf'), 1);
874
-		if(is_int($result) &&  $result > 0) {
875
-			return true;
876
-		}
877
-		return false;
878
-	}
879
-
880
-	/**
881
-	 * creates an LDAP Filter from given configuration
882
-	 * @param integer $filterType int, for which use case the filter shall be created
883
-	 * can be any of self::LFILTER_USER_LIST, self::LFILTER_LOGIN or
884
-	 * self::LFILTER_GROUP_LIST
885
-	 * @return string|false string with the filter on success, false otherwise
886
-	 * @throws \Exception
887
-	 */
888
-	private function composeLdapFilter($filterType) {
889
-		$filter = '';
890
-		$parts = 0;
891
-		switch ($filterType) {
892
-			case self::LFILTER_USER_LIST:
893
-				$objcs = $this->configuration->ldapUserFilterObjectclass;
894
-				//glue objectclasses
895
-				if(is_array($objcs) && count($objcs) > 0) {
896
-					$filter .= '(|';
897
-					foreach($objcs as $objc) {
898
-						$filter .= '(objectclass=' . $objc . ')';
899
-					}
900
-					$filter .= ')';
901
-					$parts++;
902
-				}
903
-				//glue group memberships
904
-				if($this->configuration->hasMemberOfFilterSupport) {
905
-					$cns = $this->configuration->ldapUserFilterGroups;
906
-					if(is_array($cns) && count($cns) > 0) {
907
-						$filter .= '(|';
908
-						$cr = $this->getConnection();
909
-						if(!$cr) {
910
-							throw new \Exception('Could not connect to LDAP');
911
-						}
912
-						$base = $this->configuration->ldapBase[0];
913
-						foreach($cns as $cn) {
914
-							$rr = $this->ldap->search($cr, $base, 'cn=' . $cn, array('dn', 'primaryGroupToken'));
915
-							if(!$this->ldap->isResource($rr)) {
916
-								continue;
917
-							}
918
-							$er = $this->ldap->firstEntry($cr, $rr);
919
-							$attrs = $this->ldap->getAttributes($cr, $er);
920
-							$dn = $this->ldap->getDN($cr, $er);
921
-							if ($dn === false || $dn === '') {
922
-								continue;
923
-							}
924
-							$filterPart = '(memberof=' . $dn . ')';
925
-							if(isset($attrs['primaryGroupToken'])) {
926
-								$pgt = $attrs['primaryGroupToken'][0];
927
-								$primaryFilterPart = '(primaryGroupID=' . $pgt .')';
928
-								$filterPart = '(|' . $filterPart . $primaryFilterPart . ')';
929
-							}
930
-							$filter .= $filterPart;
931
-						}
932
-						$filter .= ')';
933
-					}
934
-					$parts++;
935
-				}
936
-				//wrap parts in AND condition
937
-				if($parts > 1) {
938
-					$filter = '(&' . $filter . ')';
939
-				}
940
-				if ($filter === '') {
941
-					$filter = '(objectclass=*)';
942
-				}
943
-				break;
944
-
945
-			case self::LFILTER_GROUP_LIST:
946
-				$objcs = $this->configuration->ldapGroupFilterObjectclass;
947
-				//glue objectclasses
948
-				if(is_array($objcs) && count($objcs) > 0) {
949
-					$filter .= '(|';
950
-					foreach($objcs as $objc) {
951
-						$filter .= '(objectclass=' . $objc . ')';
952
-					}
953
-					$filter .= ')';
954
-					$parts++;
955
-				}
956
-				//glue group memberships
957
-				$cns = $this->configuration->ldapGroupFilterGroups;
958
-				if(is_array($cns) && count($cns) > 0) {
959
-					$filter .= '(|';
960
-					foreach($cns as $cn) {
961
-						$filter .= '(cn=' . $cn . ')';
962
-					}
963
-					$filter .= ')';
964
-				}
965
-				$parts++;
966
-				//wrap parts in AND condition
967
-				if($parts > 1) {
968
-					$filter = '(&' . $filter . ')';
969
-				}
970
-				break;
971
-
972
-			case self::LFILTER_LOGIN:
973
-				$ulf = $this->configuration->ldapUserFilter;
974
-				$loginpart = '=%uid';
975
-				$filterUsername = '';
976
-				$userAttributes = $this->getUserAttributes();
977
-				$userAttributes = array_change_key_case(array_flip($userAttributes));
978
-				$parts = 0;
979
-
980
-				if($this->configuration->ldapLoginFilterUsername === '1') {
981
-					$attr = '';
982
-					if(isset($userAttributes['uid'])) {
983
-						$attr = 'uid';
984
-					} else if(isset($userAttributes['samaccountname'])) {
985
-						$attr = 'samaccountname';
986
-					} else if(isset($userAttributes['cn'])) {
987
-						//fallback
988
-						$attr = 'cn';
989
-					}
990
-					if ($attr !== '') {
991
-						$filterUsername = '(' . $attr . $loginpart . ')';
992
-						$parts++;
993
-					}
994
-				}
995
-
996
-				$filterEmail = '';
997
-				if($this->configuration->ldapLoginFilterEmail === '1') {
998
-					$filterEmail = '(|(mailPrimaryAddress=%uid)(mail=%uid))';
999
-					$parts++;
1000
-				}
1001
-
1002
-				$filterAttributes = '';
1003
-				$attrsToFilter = $this->configuration->ldapLoginFilterAttributes;
1004
-				if(is_array($attrsToFilter) && count($attrsToFilter) > 0) {
1005
-					$filterAttributes = '(|';
1006
-					foreach($attrsToFilter as $attribute) {
1007
-						$filterAttributes .= '(' . $attribute . $loginpart . ')';
1008
-					}
1009
-					$filterAttributes .= ')';
1010
-					$parts++;
1011
-				}
1012
-
1013
-				$filterLogin = '';
1014
-				if($parts > 1) {
1015
-					$filterLogin = '(|';
1016
-				}
1017
-				$filterLogin .= $filterUsername;
1018
-				$filterLogin .= $filterEmail;
1019
-				$filterLogin .= $filterAttributes;
1020
-				if($parts > 1) {
1021
-					$filterLogin .= ')';
1022
-				}
1023
-
1024
-				$filter = '(&'.$ulf.$filterLogin.')';
1025
-				break;
1026
-		}
1027
-
1028
-		\OCP\Util::writeLog('user_ldap', 'Wiz: Final filter '.$filter, ILogger::DEBUG);
1029
-
1030
-		return $filter;
1031
-	}
1032
-
1033
-	/**
1034
-	 * Connects and Binds to an LDAP Server
1035
-	 *
1036
-	 * @param int $port the port to connect with
1037
-	 * @param bool $tls whether startTLS is to be used
1038
-	 * @return bool
1039
-	 * @throws \Exception
1040
-	 */
1041
-	private function connectAndBind($port, $tls) {
1042
-		//connect, does not really trigger any server communication
1043
-		$host = $this->configuration->ldapHost;
1044
-		$hostInfo = parse_url($host);
1045
-		if(!$hostInfo) {
1046
-			throw new \Exception(self::$l->t('Invalid Host'));
1047
-		}
1048
-		\OCP\Util::writeLog('user_ldap', 'Wiz: Attempting to connect ', ILogger::DEBUG);
1049
-		$cr = $this->ldap->connect($host, $port);
1050
-		if(!is_resource($cr)) {
1051
-			throw new \Exception(self::$l->t('Invalid Host'));
1052
-		}
1053
-
1054
-		//set LDAP options
1055
-		$this->ldap->setOption($cr, LDAP_OPT_PROTOCOL_VERSION, 3);
1056
-		$this->ldap->setOption($cr, LDAP_OPT_REFERRALS, 0);
1057
-		$this->ldap->setOption($cr, LDAP_OPT_NETWORK_TIMEOUT, self::LDAP_NW_TIMEOUT);
1058
-
1059
-		try {
1060
-			if($tls) {
1061
-				$isTlsWorking = @$this->ldap->startTls($cr);
1062
-				if(!$isTlsWorking) {
1063
-					return false;
1064
-				}
1065
-			}
1066
-
1067
-			\OCP\Util::writeLog('user_ldap', 'Wiz: Attemping to Bind ', ILogger::DEBUG);
1068
-			//interesting part: do the bind!
1069
-			$login = $this->ldap->bind($cr,
1070
-				$this->configuration->ldapAgentName,
1071
-				$this->configuration->ldapAgentPassword
1072
-			);
1073
-			$errNo = $this->ldap->errno($cr);
1074
-			$error = ldap_error($cr);
1075
-			$this->ldap->unbind($cr);
1076
-		} catch(ServerNotAvailableException $e) {
1077
-			return false;
1078
-		}
1079
-
1080
-		if($login === true) {
1081
-			$this->ldap->unbind($cr);
1082
-			\OCP\Util::writeLog('user_ldap', 'Wiz: Bind successful to Port '. $port . ' TLS ' . (int)$tls, ILogger::DEBUG);
1083
-			return true;
1084
-		}
1085
-
1086
-		if($errNo === -1) {
1087
-			//host, port or TLS wrong
1088
-			return false;
1089
-		}
1090
-		throw new \Exception($error, $errNo);
1091
-	}
1092
-
1093
-	/**
1094
-	 * checks whether a valid combination of agent and password has been
1095
-	 * provided (either two values or nothing for anonymous connect)
1096
-	 * @return bool, true if everything is fine, false otherwise
1097
-	 */
1098
-	private function checkAgentRequirements() {
1099
-		$agent = $this->configuration->ldapAgentName;
1100
-		$pwd = $this->configuration->ldapAgentPassword;
1101
-
1102
-		return
1103
-			($agent !== '' && $pwd !== '')
1104
-			||  ($agent === '' && $pwd === '')
1105
-		;
1106
-	}
1107
-
1108
-	/**
1109
-	 * @param array $reqs
1110
-	 * @return bool
1111
-	 */
1112
-	private function checkRequirements($reqs) {
1113
-		$this->checkAgentRequirements();
1114
-		foreach($reqs as $option) {
1115
-			$value = $this->configuration->$option;
1116
-			if(empty($value)) {
1117
-				return false;
1118
-			}
1119
-		}
1120
-		return true;
1121
-	}
1122
-
1123
-	/**
1124
-	 * does a cumulativeSearch on LDAP to get different values of a
1125
-	 * specified attribute
1126
-	 * @param string[] $filters array, the filters that shall be used in the search
1127
-	 * @param string $attr the attribute of which a list of values shall be returned
1128
-	 * @param int $dnReadLimit the amount of how many DNs should be analyzed.
1129
-	 * The lower, the faster
1130
-	 * @param string $maxF string. if not null, this variable will have the filter that
1131
-	 * yields most result entries
1132
-	 * @return array|false an array with the values on success, false otherwise
1133
-	 */
1134
-	public function cumulativeSearchOnAttribute($filters, $attr, $dnReadLimit = 3, &$maxF = null) {
1135
-		$dnRead = array();
1136
-		$foundItems = array();
1137
-		$maxEntries = 0;
1138
-		if(!is_array($this->configuration->ldapBase)
1139
-		   || !isset($this->configuration->ldapBase[0])) {
1140
-			return false;
1141
-		}
1142
-		$base = $this->configuration->ldapBase[0];
1143
-		$cr = $this->getConnection();
1144
-		if(!$this->ldap->isResource($cr)) {
1145
-			return false;
1146
-		}
1147
-		$lastFilter = null;
1148
-		if(isset($filters[count($filters)-1])) {
1149
-			$lastFilter = $filters[count($filters)-1];
1150
-		}
1151
-		foreach($filters as $filter) {
1152
-			if($lastFilter === $filter && count($foundItems) > 0) {
1153
-				//skip when the filter is a wildcard and results were found
1154
-				continue;
1155
-			}
1156
-			// 20k limit for performance and reason
1157
-			$rr = $this->ldap->search($cr, $base, $filter, array($attr), 0, 20000);
1158
-			if(!$this->ldap->isResource($rr)) {
1159
-				continue;
1160
-			}
1161
-			$entries = $this->ldap->countEntries($cr, $rr);
1162
-			$getEntryFunc = 'firstEntry';
1163
-			if(($entries !== false) && ($entries > 0)) {
1164
-				if(!is_null($maxF) && $entries > $maxEntries) {
1165
-					$maxEntries = $entries;
1166
-					$maxF = $filter;
1167
-				}
1168
-				$dnReadCount = 0;
1169
-				do {
1170
-					$entry = $this->ldap->$getEntryFunc($cr, $rr);
1171
-					$getEntryFunc = 'nextEntry';
1172
-					if(!$this->ldap->isResource($entry)) {
1173
-						continue 2;
1174
-					}
1175
-					$rr = $entry; //will be expected by nextEntry next round
1176
-					$attributes = $this->ldap->getAttributes($cr, $entry);
1177
-					$dn = $this->ldap->getDN($cr, $entry);
1178
-					if($dn === false || in_array($dn, $dnRead)) {
1179
-						continue;
1180
-					}
1181
-					$newItems = array();
1182
-					$state = $this->getAttributeValuesFromEntry($attributes,
1183
-																$attr,
1184
-																$newItems);
1185
-					$dnReadCount++;
1186
-					$foundItems = array_merge($foundItems, $newItems);
1187
-					$this->resultCache[$dn][$attr] = $newItems;
1188
-					$dnRead[] = $dn;
1189
-				} while(($state === self::LRESULT_PROCESSED_SKIP
1190
-						|| $this->ldap->isResource($entry))
1191
-						&& ($dnReadLimit === 0 || $dnReadCount < $dnReadLimit));
1192
-			}
1193
-		}
1194
-
1195
-		return array_unique($foundItems);
1196
-	}
1197
-
1198
-	/**
1199
-	 * determines if and which $attr are available on the LDAP server
1200
-	 * @param string[] $objectclasses the objectclasses to use as search filter
1201
-	 * @param string $attr the attribute to look for
1202
-	 * @param string $dbkey the dbkey of the setting the feature is connected to
1203
-	 * @param string $confkey the confkey counterpart for the $dbkey as used in the
1204
-	 * Configuration class
1205
-	 * @param bool $po whether the objectClass with most result entries
1206
-	 * shall be pre-selected via the result
1207
-	 * @return array|false list of found items.
1208
-	 * @throws \Exception
1209
-	 */
1210
-	private function determineFeature($objectclasses, $attr, $dbkey, $confkey, $po = false) {
1211
-		$cr = $this->getConnection();
1212
-		if(!$cr) {
1213
-			throw new \Exception('Could not connect to LDAP');
1214
-		}
1215
-		$p = 'objectclass=';
1216
-		foreach($objectclasses as $key => $value) {
1217
-			$objectclasses[$key] = $p.$value;
1218
-		}
1219
-		$maxEntryObjC = '';
1220
-
1221
-		//how deep to dig?
1222
-		//When looking for objectclasses, testing few entries is sufficient,
1223
-		$dig = 3;
1224
-
1225
-		$availableFeatures =
1226
-			$this->cumulativeSearchOnAttribute($objectclasses, $attr,
1227
-											   $dig, $maxEntryObjC);
1228
-		if(is_array($availableFeatures)
1229
-		   && count($availableFeatures) > 0) {
1230
-			natcasesort($availableFeatures);
1231
-			//natcasesort keeps indices, but we must get rid of them for proper
1232
-			//sorting in the web UI. Therefore: array_values
1233
-			$this->result->addOptions($dbkey, array_values($availableFeatures));
1234
-		} else {
1235
-			throw new \Exception(self::$l->t('Could not find the desired feature'));
1236
-		}
1237
-
1238
-		$setFeatures = $this->configuration->$confkey;
1239
-		if(is_array($setFeatures) && !empty($setFeatures)) {
1240
-			//something is already configured? pre-select it.
1241
-			$this->result->addChange($dbkey, $setFeatures);
1242
-		} else if ($po && $maxEntryObjC !== '') {
1243
-			//pre-select objectclass with most result entries
1244
-			$maxEntryObjC = str_replace($p, '', $maxEntryObjC);
1245
-			$this->applyFind($dbkey, $maxEntryObjC);
1246
-			$this->result->addChange($dbkey, $maxEntryObjC);
1247
-		}
1248
-
1249
-		return $availableFeatures;
1250
-	}
1251
-
1252
-	/**
1253
-	 * appends a list of values fr
1254
-	 * @param resource $result the return value from ldap_get_attributes
1255
-	 * @param string $attribute the attribute values to look for
1256
-	 * @param array &$known new values will be appended here
1257
-	 * @return int, state on of the class constants LRESULT_PROCESSED_OK,
1258
-	 * LRESULT_PROCESSED_INVALID or LRESULT_PROCESSED_SKIP
1259
-	 */
1260
-	private function getAttributeValuesFromEntry($result, $attribute, &$known) {
1261
-		if(!is_array($result)
1262
-		   || !isset($result['count'])
1263
-		   || !$result['count'] > 0) {
1264
-			return self::LRESULT_PROCESSED_INVALID;
1265
-		}
1266
-
1267
-		// strtolower on all keys for proper comparison
1268
-		$result = \OCP\Util::mb_array_change_key_case($result);
1269
-		$attribute = strtolower($attribute);
1270
-		if(isset($result[$attribute])) {
1271
-			foreach($result[$attribute] as $key => $val) {
1272
-				if($key === 'count') {
1273
-					continue;
1274
-				}
1275
-				if(!in_array($val, $known)) {
1276
-					$known[] = $val;
1277
-				}
1278
-			}
1279
-			return self::LRESULT_PROCESSED_OK;
1280
-		} else {
1281
-			return self::LRESULT_PROCESSED_SKIP;
1282
-		}
1283
-	}
1284
-
1285
-	/**
1286
-	 * @return bool|mixed
1287
-	 */
1288
-	private function getConnection() {
1289
-		if(!is_null($this->cr)) {
1290
-			return $this->cr;
1291
-		}
1292
-
1293
-		$cr = $this->ldap->connect(
1294
-			$this->configuration->ldapHost,
1295
-			$this->configuration->ldapPort
1296
-		);
1297
-
1298
-		$this->ldap->setOption($cr, LDAP_OPT_PROTOCOL_VERSION, 3);
1299
-		$this->ldap->setOption($cr, LDAP_OPT_REFERRALS, 0);
1300
-		$this->ldap->setOption($cr, LDAP_OPT_NETWORK_TIMEOUT, self::LDAP_NW_TIMEOUT);
1301
-		if($this->configuration->ldapTLS === 1) {
1302
-			$this->ldap->startTls($cr);
1303
-		}
1304
-
1305
-		$lo = @$this->ldap->bind($cr,
1306
-								 $this->configuration->ldapAgentName,
1307
-								 $this->configuration->ldapAgentPassword);
1308
-		if($lo === true) {
1309
-			$this->$cr = $cr;
1310
-			return $cr;
1311
-		}
1312
-
1313
-		return false;
1314
-	}
1315
-
1316
-	/**
1317
-	 * @return array
1318
-	 */
1319
-	private function getDefaultLdapPortSettings() {
1320
-		static $settings = array(
1321
-								array('port' => 7636, 'tls' => false),
1322
-								array('port' =>  636, 'tls' => false),
1323
-								array('port' => 7389, 'tls' => true),
1324
-								array('port' =>  389, 'tls' => true),
1325
-								array('port' => 7389, 'tls' => false),
1326
-								array('port' =>  389, 'tls' => false),
1327
-						  );
1328
-		return $settings;
1329
-	}
1330
-
1331
-	/**
1332
-	 * @return array
1333
-	 */
1334
-	private function getPortSettingsToTry() {
1335
-		//389 ← LDAP / Unencrypted or StartTLS
1336
-		//636 ← LDAPS / SSL
1337
-		//7xxx ← UCS. need to be checked first, because both ports may be open
1338
-		$host = $this->configuration->ldapHost;
1339
-		$port = (int)$this->configuration->ldapPort;
1340
-		$portSettings = array();
1341
-
1342
-		//In case the port is already provided, we will check this first
1343
-		if($port > 0) {
1344
-			$hostInfo = parse_url($host);
1345
-			if(!(is_array($hostInfo)
1346
-				&& isset($hostInfo['scheme'])
1347
-				&& stripos($hostInfo['scheme'], 'ldaps') !== false)) {
1348
-				$portSettings[] = array('port' => $port, 'tls' => true);
1349
-			}
1350
-			$portSettings[] =array('port' => $port, 'tls' => false);
1351
-		}
1352
-
1353
-		//default ports
1354
-		$portSettings = array_merge($portSettings,
1355
-		                            $this->getDefaultLdapPortSettings());
1356
-
1357
-		return $portSettings;
1358
-	}
45
+    /** @var \OCP\IL10N */
46
+    static protected $l;
47
+    protected $access;
48
+    protected $cr;
49
+    protected $configuration;
50
+    protected $result;
51
+    protected $resultCache = array();
52
+
53
+    const LRESULT_PROCESSED_OK = 2;
54
+    const LRESULT_PROCESSED_INVALID = 3;
55
+    const LRESULT_PROCESSED_SKIP = 4;
56
+
57
+    const LFILTER_LOGIN      = 2;
58
+    const LFILTER_USER_LIST  = 3;
59
+    const LFILTER_GROUP_LIST = 4;
60
+
61
+    const LFILTER_MODE_ASSISTED = 2;
62
+    const LFILTER_MODE_RAW = 1;
63
+
64
+    const LDAP_NW_TIMEOUT = 4;
65
+
66
+    /**
67
+     * Constructor
68
+     * @param Configuration $configuration an instance of Configuration
69
+     * @param ILDAPWrapper $ldap an instance of ILDAPWrapper
70
+     * @param Access $access
71
+     */
72
+    public function __construct(Configuration $configuration, ILDAPWrapper $ldap, Access $access) {
73
+        parent::__construct($ldap);
74
+        $this->configuration = $configuration;
75
+        if(is_null(Wizard::$l)) {
76
+            Wizard::$l = \OC::$server->getL10N('user_ldap');
77
+        }
78
+        $this->access = $access;
79
+        $this->result = new WizardResult();
80
+    }
81
+
82
+    public function  __destruct() {
83
+        if($this->result->hasChanges()) {
84
+            $this->configuration->saveConfiguration();
85
+        }
86
+    }
87
+
88
+    /**
89
+     * counts entries in the LDAP directory
90
+     *
91
+     * @param string $filter the LDAP search filter
92
+     * @param string $type a string being either 'users' or 'groups';
93
+     * @return int
94
+     * @throws \Exception
95
+     */
96
+    public function countEntries(string $filter, string $type): int {
97
+        $reqs = ['ldapHost', 'ldapPort', 'ldapBase'];
98
+        if($type === 'users') {
99
+            $reqs[] = 'ldapUserFilter';
100
+        }
101
+        if(!$this->checkRequirements($reqs)) {
102
+            throw new \Exception('Requirements not met', 400);
103
+        }
104
+
105
+        $attr = ['dn']; // default
106
+        $limit = 1001;
107
+        if($type === 'groups') {
108
+            $result =  $this->access->countGroups($filter, $attr, $limit);
109
+        } else if($type === 'users') {
110
+            $result = $this->access->countUsers($filter, $attr, $limit);
111
+        } else if ($type === 'objects') {
112
+            $result = $this->access->countObjects($limit);
113
+        } else {
114
+            throw new \Exception('Internal error: Invalid object type', 500);
115
+        }
116
+
117
+        return (int)$result;
118
+    }
119
+
120
+    /**
121
+     * formats the return value of a count operation to the string to be
122
+     * inserted.
123
+     *
124
+     * @param int $count
125
+     * @return string
126
+     */
127
+    private function formatCountResult(int $count): string {
128
+        if($count > 1000) {
129
+            return '> 1000';
130
+        }
131
+        return (string)$count;
132
+    }
133
+
134
+    public function countGroups() {
135
+        $filter = $this->configuration->ldapGroupFilter;
136
+
137
+        if(empty($filter)) {
138
+            $output = self::$l->n('%s group found', '%s groups found', 0, array(0));
139
+            $this->result->addChange('ldap_group_count', $output);
140
+            return $this->result;
141
+        }
142
+
143
+        try {
144
+            $groupsTotal = $this->countEntries($filter, 'groups');
145
+        } catch (\Exception $e) {
146
+            //400 can be ignored, 500 is forwarded
147
+            if($e->getCode() === 500) {
148
+                throw $e;
149
+            }
150
+            return false;
151
+        }
152
+        $output = self::$l->n(
153
+            '%s group found',
154
+            '%s groups found',
155
+            $groupsTotal,
156
+            [$this->formatCountResult($groupsTotal)]
157
+        );
158
+        $this->result->addChange('ldap_group_count', $output);
159
+        return $this->result;
160
+    }
161
+
162
+    /**
163
+     * @return WizardResult
164
+     * @throws \Exception
165
+     */
166
+    public function countUsers() {
167
+        $filter = $this->access->getFilterForUserCount();
168
+
169
+        $usersTotal = $this->countEntries($filter, 'users');
170
+        $output = self::$l->n(
171
+            '%s user found',
172
+            '%s users found',
173
+            $usersTotal,
174
+            [$this->formatCountResult($usersTotal)]
175
+        );
176
+        $this->result->addChange('ldap_user_count', $output);
177
+        return $this->result;
178
+    }
179
+
180
+    /**
181
+     * counts any objects in the currently set base dn
182
+     *
183
+     * @return WizardResult
184
+     * @throws \Exception
185
+     */
186
+    public function countInBaseDN() {
187
+        // we don't need to provide a filter in this case
188
+        $total = $this->countEntries('', 'objects');
189
+        if($total === false) {
190
+            throw new \Exception('invalid results received');
191
+        }
192
+        $this->result->addChange('ldap_test_base', $total);
193
+        return $this->result;
194
+    }
195
+
196
+    /**
197
+     * counts users with a specified attribute
198
+     * @param string $attr
199
+     * @param bool $existsCheck
200
+     * @return int|bool
201
+     */
202
+    public function countUsersWithAttribute($attr, $existsCheck = false) {
203
+        if(!$this->checkRequirements(array('ldapHost',
204
+                                            'ldapPort',
205
+                                            'ldapBase',
206
+                                            'ldapUserFilter',
207
+                                            ))) {
208
+            return  false;
209
+        }
210
+
211
+        $filter = $this->access->combineFilterWithAnd(array(
212
+            $this->configuration->ldapUserFilter,
213
+            $attr . '=*'
214
+        ));
215
+
216
+        $limit = ($existsCheck === false) ? null : 1;
217
+
218
+        return $this->access->countUsers($filter, array('dn'), $limit);
219
+    }
220
+
221
+    /**
222
+     * detects the display name attribute. If a setting is already present that
223
+     * returns at least one hit, the detection will be canceled.
224
+     * @return WizardResult|bool
225
+     * @throws \Exception
226
+     */
227
+    public function detectUserDisplayNameAttribute() {
228
+        if(!$this->checkRequirements(array('ldapHost',
229
+                                        'ldapPort',
230
+                                        'ldapBase',
231
+                                        'ldapUserFilter',
232
+                                        ))) {
233
+            return  false;
234
+        }
235
+
236
+        $attr = $this->configuration->ldapUserDisplayName;
237
+        if ($attr !== '' && $attr !== 'displayName') {
238
+            // most likely not the default value with upper case N,
239
+            // verify it still produces a result
240
+            $count = (int)$this->countUsersWithAttribute($attr, true);
241
+            if($count > 0) {
242
+                //no change, but we sent it back to make sure the user interface
243
+                //is still correct, even if the ajax call was cancelled meanwhile
244
+                $this->result->addChange('ldap_display_name', $attr);
245
+                return $this->result;
246
+            }
247
+        }
248
+
249
+        // first attribute that has at least one result wins
250
+        $displayNameAttrs = array('displayname', 'cn');
251
+        foreach ($displayNameAttrs as $attr) {
252
+            $count = (int)$this->countUsersWithAttribute($attr, true);
253
+
254
+            if($count > 0) {
255
+                $this->applyFind('ldap_display_name', $attr);
256
+                return $this->result;
257
+            }
258
+        }
259
+
260
+        throw new \Exception(self::$l->t('Could not detect user display name attribute. Please specify it yourself in advanced LDAP settings.'));
261
+    }
262
+
263
+    /**
264
+     * detects the most often used email attribute for users applying to the
265
+     * user list filter. If a setting is already present that returns at least
266
+     * one hit, the detection will be canceled.
267
+     * @return WizardResult|bool
268
+     */
269
+    public function detectEmailAttribute() {
270
+        if(!$this->checkRequirements(array('ldapHost',
271
+                                            'ldapPort',
272
+                                            'ldapBase',
273
+                                            'ldapUserFilter',
274
+                                            ))) {
275
+            return  false;
276
+        }
277
+
278
+        $attr = $this->configuration->ldapEmailAttribute;
279
+        if ($attr !== '') {
280
+            $count = (int)$this->countUsersWithAttribute($attr, true);
281
+            if($count > 0) {
282
+                return false;
283
+            }
284
+            $writeLog = true;
285
+        } else {
286
+            $writeLog = false;
287
+        }
288
+
289
+        $emailAttributes = array('mail', 'mailPrimaryAddress');
290
+        $winner = '';
291
+        $maxUsers = 0;
292
+        foreach($emailAttributes as $attr) {
293
+            $count = $this->countUsersWithAttribute($attr);
294
+            if($count > $maxUsers) {
295
+                $maxUsers = $count;
296
+                $winner = $attr;
297
+            }
298
+        }
299
+
300
+        if($winner !== '') {
301
+            $this->applyFind('ldap_email_attr', $winner);
302
+            if($writeLog) {
303
+                \OCP\Util::writeLog('user_ldap', 'The mail attribute has ' .
304
+                    'automatically been reset, because the original value ' .
305
+                    'did not return any results.', ILogger::INFO);
306
+            }
307
+        }
308
+
309
+        return $this->result;
310
+    }
311
+
312
+    /**
313
+     * @return WizardResult
314
+     * @throws \Exception
315
+     */
316
+    public function determineAttributes() {
317
+        if(!$this->checkRequirements(array('ldapHost',
318
+                                            'ldapPort',
319
+                                            'ldapBase',
320
+                                            'ldapUserFilter',
321
+                                            ))) {
322
+            return  false;
323
+        }
324
+
325
+        $attributes = $this->getUserAttributes();
326
+
327
+        natcasesort($attributes);
328
+        $attributes = array_values($attributes);
329
+
330
+        $this->result->addOptions('ldap_loginfilter_attributes', $attributes);
331
+
332
+        $selected = $this->configuration->ldapLoginFilterAttributes;
333
+        if(is_array($selected) && !empty($selected)) {
334
+            $this->result->addChange('ldap_loginfilter_attributes', $selected);
335
+        }
336
+
337
+        return $this->result;
338
+    }
339
+
340
+    /**
341
+     * detects the available LDAP attributes
342
+     * @return array|false The instance's WizardResult instance
343
+     * @throws \Exception
344
+     */
345
+    private function getUserAttributes() {
346
+        if(!$this->checkRequirements(array('ldapHost',
347
+                                            'ldapPort',
348
+                                            'ldapBase',
349
+                                            'ldapUserFilter',
350
+                                            ))) {
351
+            return  false;
352
+        }
353
+        $cr = $this->getConnection();
354
+        if(!$cr) {
355
+            throw new \Exception('Could not connect to LDAP');
356
+        }
357
+
358
+        $base = $this->configuration->ldapBase[0];
359
+        $filter = $this->configuration->ldapUserFilter;
360
+        $rr = $this->ldap->search($cr, $base, $filter, array(), 1, 1);
361
+        if(!$this->ldap->isResource($rr)) {
362
+            return false;
363
+        }
364
+        $er = $this->ldap->firstEntry($cr, $rr);
365
+        $attributes = $this->ldap->getAttributes($cr, $er);
366
+        $pureAttributes = array();
367
+        for($i = 0; $i < $attributes['count']; $i++) {
368
+            $pureAttributes[] = $attributes[$i];
369
+        }
370
+
371
+        return $pureAttributes;
372
+    }
373
+
374
+    /**
375
+     * detects the available LDAP groups
376
+     * @return WizardResult|false the instance's WizardResult instance
377
+     */
378
+    public function determineGroupsForGroups() {
379
+        return $this->determineGroups('ldap_groupfilter_groups',
380
+                                        'ldapGroupFilterGroups',
381
+                                        false);
382
+    }
383
+
384
+    /**
385
+     * detects the available LDAP groups
386
+     * @return WizardResult|false the instance's WizardResult instance
387
+     */
388
+    public function determineGroupsForUsers() {
389
+        return $this->determineGroups('ldap_userfilter_groups',
390
+                                        'ldapUserFilterGroups');
391
+    }
392
+
393
+    /**
394
+     * detects the available LDAP groups
395
+     * @param string $dbKey
396
+     * @param string $confKey
397
+     * @param bool $testMemberOf
398
+     * @return WizardResult|false the instance's WizardResult instance
399
+     * @throws \Exception
400
+     */
401
+    private function determineGroups($dbKey, $confKey, $testMemberOf = true) {
402
+        if(!$this->checkRequirements(array('ldapHost',
403
+                                            'ldapPort',
404
+                                            'ldapBase',
405
+                                            ))) {
406
+            return  false;
407
+        }
408
+        $cr = $this->getConnection();
409
+        if(!$cr) {
410
+            throw new \Exception('Could not connect to LDAP');
411
+        }
412
+
413
+        $this->fetchGroups($dbKey, $confKey);
414
+
415
+        if($testMemberOf) {
416
+            $this->configuration->hasMemberOfFilterSupport = $this->testMemberOf();
417
+            $this->result->markChange();
418
+            if(!$this->configuration->hasMemberOfFilterSupport) {
419
+                throw new \Exception('memberOf is not supported by the server');
420
+            }
421
+        }
422
+
423
+        return $this->result;
424
+    }
425
+
426
+    /**
427
+     * fetches all groups from LDAP and adds them to the result object
428
+     *
429
+     * @param string $dbKey
430
+     * @param string $confKey
431
+     * @return array $groupEntries
432
+     * @throws \Exception
433
+     */
434
+    public function fetchGroups($dbKey, $confKey) {
435
+        $obclasses = array('posixGroup', 'group', 'zimbraDistributionList', 'groupOfNames', 'groupOfUniqueNames');
436
+
437
+        $filterParts = array();
438
+        foreach($obclasses as $obclass) {
439
+            $filterParts[] = 'objectclass='.$obclass;
440
+        }
441
+        //we filter for everything
442
+        //- that looks like a group and
443
+        //- has the group display name set
444
+        $filter = $this->access->combineFilterWithOr($filterParts);
445
+        $filter = $this->access->combineFilterWithAnd(array($filter, 'cn=*'));
446
+
447
+        $groupNames = array();
448
+        $groupEntries = array();
449
+        $limit = 400;
450
+        $offset = 0;
451
+        do {
452
+            // we need to request dn additionally here, otherwise memberOf
453
+            // detection will fail later
454
+            $result = $this->access->searchGroups($filter, array('cn', 'dn'), $limit, $offset);
455
+            foreach($result as $item) {
456
+                if(!isset($item['cn']) && !is_array($item['cn']) && !isset($item['cn'][0])) {
457
+                    // just in case - no issue known
458
+                    continue;
459
+                }
460
+                $groupNames[] = $item['cn'][0];
461
+                $groupEntries[] = $item;
462
+            }
463
+            $offset += $limit;
464
+        } while ($this->access->hasMoreResults());
465
+
466
+        if(count($groupNames) > 0) {
467
+            natsort($groupNames);
468
+            $this->result->addOptions($dbKey, array_values($groupNames));
469
+        } else {
470
+            throw new \Exception(self::$l->t('Could not find the desired feature'));
471
+        }
472
+
473
+        $setFeatures = $this->configuration->$confKey;
474
+        if(is_array($setFeatures) && !empty($setFeatures)) {
475
+            //something is already configured? pre-select it.
476
+            $this->result->addChange($dbKey, $setFeatures);
477
+        }
478
+        return $groupEntries;
479
+    }
480
+
481
+    public function determineGroupMemberAssoc() {
482
+        if(!$this->checkRequirements(array('ldapHost',
483
+                                            'ldapPort',
484
+                                            'ldapGroupFilter',
485
+                                            ))) {
486
+            return  false;
487
+        }
488
+        $attribute = $this->detectGroupMemberAssoc();
489
+        if($attribute === false) {
490
+            return false;
491
+        }
492
+        $this->configuration->setConfiguration(array('ldapGroupMemberAssocAttr' => $attribute));
493
+        $this->result->addChange('ldap_group_member_assoc_attribute', $attribute);
494
+
495
+        return $this->result;
496
+    }
497
+
498
+    /**
499
+     * Detects the available object classes
500
+     * @return WizardResult|false the instance's WizardResult instance
501
+     * @throws \Exception
502
+     */
503
+    public function determineGroupObjectClasses() {
504
+        if(!$this->checkRequirements(array('ldapHost',
505
+                                            'ldapPort',
506
+                                            'ldapBase',
507
+                                            ))) {
508
+            return  false;
509
+        }
510
+        $cr = $this->getConnection();
511
+        if(!$cr) {
512
+            throw new \Exception('Could not connect to LDAP');
513
+        }
514
+
515
+        $obclasses = array('groupOfNames', 'groupOfUniqueNames', 'group', 'posixGroup', '*');
516
+        $this->determineFeature($obclasses,
517
+                                'objectclass',
518
+                                'ldap_groupfilter_objectclass',
519
+                                'ldapGroupFilterObjectclass',
520
+                                false);
521
+
522
+        return $this->result;
523
+    }
524
+
525
+    /**
526
+     * detects the available object classes
527
+     * @return WizardResult
528
+     * @throws \Exception
529
+     */
530
+    public function determineUserObjectClasses() {
531
+        if(!$this->checkRequirements(array('ldapHost',
532
+                                            'ldapPort',
533
+                                            'ldapBase',
534
+                                            ))) {
535
+            return  false;
536
+        }
537
+        $cr = $this->getConnection();
538
+        if(!$cr) {
539
+            throw new \Exception('Could not connect to LDAP');
540
+        }
541
+
542
+        $obclasses = array('inetOrgPerson', 'person', 'organizationalPerson',
543
+                            'user', 'posixAccount', '*');
544
+        $filter = $this->configuration->ldapUserFilter;
545
+        //if filter is empty, it is probably the first time the wizard is called
546
+        //then, apply suggestions.
547
+        $this->determineFeature($obclasses,
548
+                                'objectclass',
549
+                                'ldap_userfilter_objectclass',
550
+                                'ldapUserFilterObjectclass',
551
+                                empty($filter));
552
+
553
+        return $this->result;
554
+    }
555
+
556
+    /**
557
+     * @return WizardResult|false
558
+     * @throws \Exception
559
+     */
560
+    public function getGroupFilter() {
561
+        if(!$this->checkRequirements(array('ldapHost',
562
+                                            'ldapPort',
563
+                                            'ldapBase',
564
+                                            ))) {
565
+            return false;
566
+        }
567
+        //make sure the use display name is set
568
+        $displayName = $this->configuration->ldapGroupDisplayName;
569
+        if ($displayName === '') {
570
+            $d = $this->configuration->getDefaults();
571
+            $this->applyFind('ldap_group_display_name',
572
+                                $d['ldap_group_display_name']);
573
+        }
574
+        $filter = $this->composeLdapFilter(self::LFILTER_GROUP_LIST);
575
+
576
+        $this->applyFind('ldap_group_filter', $filter);
577
+        return $this->result;
578
+    }
579
+
580
+    /**
581
+     * @return WizardResult|false
582
+     * @throws \Exception
583
+     */
584
+    public function getUserListFilter() {
585
+        if(!$this->checkRequirements(array('ldapHost',
586
+                                            'ldapPort',
587
+                                            'ldapBase',
588
+                                            ))) {
589
+            return false;
590
+        }
591
+        //make sure the use display name is set
592
+        $displayName = $this->configuration->ldapUserDisplayName;
593
+        if ($displayName === '') {
594
+            $d = $this->configuration->getDefaults();
595
+            $this->applyFind('ldap_display_name', $d['ldap_display_name']);
596
+        }
597
+        $filter = $this->composeLdapFilter(self::LFILTER_USER_LIST);
598
+        if(!$filter) {
599
+            throw new \Exception('Cannot create filter');
600
+        }
601
+
602
+        $this->applyFind('ldap_userlist_filter', $filter);
603
+        return $this->result;
604
+    }
605
+
606
+    /**
607
+     * @return bool|WizardResult
608
+     * @throws \Exception
609
+     */
610
+    public function getUserLoginFilter() {
611
+        if(!$this->checkRequirements(array('ldapHost',
612
+                                            'ldapPort',
613
+                                            'ldapBase',
614
+                                            'ldapUserFilter',
615
+                                            ))) {
616
+            return false;
617
+        }
618
+
619
+        $filter = $this->composeLdapFilter(self::LFILTER_LOGIN);
620
+        if(!$filter) {
621
+            throw new \Exception('Cannot create filter');
622
+        }
623
+
624
+        $this->applyFind('ldap_login_filter', $filter);
625
+        return $this->result;
626
+    }
627
+
628
+    /**
629
+     * @return bool|WizardResult
630
+     * @param string $loginName
631
+     * @throws \Exception
632
+     */
633
+    public function testLoginName($loginName) {
634
+        if(!$this->checkRequirements(array('ldapHost',
635
+            'ldapPort',
636
+            'ldapBase',
637
+            'ldapLoginFilter',
638
+        ))) {
639
+            return false;
640
+        }
641
+
642
+        $cr = $this->access->connection->getConnectionResource();
643
+        if(!$this->ldap->isResource($cr)) {
644
+            throw new \Exception('connection error');
645
+        }
646
+
647
+        if(mb_strpos($this->access->connection->ldapLoginFilter, '%uid', 0, 'UTF-8')
648
+            === false) {
649
+            throw new \Exception('missing placeholder');
650
+        }
651
+
652
+        $users = $this->access->countUsersByLoginName($loginName);
653
+        if($this->ldap->errno($cr) !== 0) {
654
+            throw new \Exception($this->ldap->error($cr));
655
+        }
656
+        $filter = str_replace('%uid', $loginName, $this->access->connection->ldapLoginFilter);
657
+        $this->result->addChange('ldap_test_loginname', $users);
658
+        $this->result->addChange('ldap_test_effective_filter', $filter);
659
+        return $this->result;
660
+    }
661
+
662
+    /**
663
+     * Tries to determine the port, requires given Host, User DN and Password
664
+     * @return WizardResult|false WizardResult on success, false otherwise
665
+     * @throws \Exception
666
+     */
667
+    public function guessPortAndTLS() {
668
+        if(!$this->checkRequirements(array('ldapHost',
669
+                                            ))) {
670
+            return false;
671
+        }
672
+        $this->checkHost();
673
+        $portSettings = $this->getPortSettingsToTry();
674
+
675
+        if(!is_array($portSettings)) {
676
+            throw new \Exception(print_r($portSettings, true));
677
+        }
678
+
679
+        //proceed from the best configuration and return on first success
680
+        foreach($portSettings as $setting) {
681
+            $p = $setting['port'];
682
+            $t = $setting['tls'];
683
+            \OCP\Util::writeLog('user_ldap', 'Wiz: trying port '. $p . ', TLS '. $t, ILogger::DEBUG);
684
+            //connectAndBind may throw Exception, it needs to be catched by the
685
+            //callee of this method
686
+
687
+            try {
688
+                $settingsFound = $this->connectAndBind($p, $t);
689
+            } catch (\Exception $e) {
690
+                // any reply other than -1 (= cannot connect) is already okay,
691
+                // because then we found the server
692
+                // unavailable startTLS returns -11
693
+                if($e->getCode() > 0) {
694
+                    $settingsFound = true;
695
+                } else {
696
+                    throw $e;
697
+                }
698
+            }
699
+
700
+            if ($settingsFound === true) {
701
+                $config = array(
702
+                    'ldapPort' => $p,
703
+                    'ldapTLS' => (int)$t
704
+                );
705
+                $this->configuration->setConfiguration($config);
706
+                \OCP\Util::writeLog('user_ldap', 'Wiz: detected Port ' . $p, ILogger::DEBUG);
707
+                $this->result->addChange('ldap_port', $p);
708
+                return $this->result;
709
+            }
710
+        }
711
+
712
+        //custom port, undetected (we do not brute force)
713
+        return false;
714
+    }
715
+
716
+    /**
717
+     * tries to determine a base dn from User DN or LDAP Host
718
+     * @return WizardResult|false WizardResult on success, false otherwise
719
+     */
720
+    public function guessBaseDN() {
721
+        if(!$this->checkRequirements(array('ldapHost',
722
+                                            'ldapPort',
723
+                                            ))) {
724
+            return false;
725
+        }
726
+
727
+        //check whether a DN is given in the agent name (99.9% of all cases)
728
+        $base = null;
729
+        $i = stripos($this->configuration->ldapAgentName, 'dc=');
730
+        if($i !== false) {
731
+            $base = substr($this->configuration->ldapAgentName, $i);
732
+            if($this->testBaseDN($base)) {
733
+                $this->applyFind('ldap_base', $base);
734
+                return $this->result;
735
+            }
736
+        }
737
+
738
+        //this did not help :(
739
+        //Let's see whether we can parse the Host URL and convert the domain to
740
+        //a base DN
741
+        $helper = new Helper(\OC::$server->getConfig());
742
+        $domain = $helper->getDomainFromURL($this->configuration->ldapHost);
743
+        if(!$domain) {
744
+            return false;
745
+        }
746
+
747
+        $dparts = explode('.', $domain);
748
+        while(count($dparts) > 0) {
749
+            $base2 = 'dc=' . implode(',dc=', $dparts);
750
+            if ($base !== $base2 && $this->testBaseDN($base2)) {
751
+                $this->applyFind('ldap_base', $base2);
752
+                return $this->result;
753
+            }
754
+            array_shift($dparts);
755
+        }
756
+
757
+        return false;
758
+    }
759
+
760
+    /**
761
+     * sets the found value for the configuration key in the WizardResult
762
+     * as well as in the Configuration instance
763
+     * @param string $key the configuration key
764
+     * @param string $value the (detected) value
765
+     *
766
+     */
767
+    private function applyFind($key, $value) {
768
+        $this->result->addChange($key, $value);
769
+        $this->configuration->setConfiguration(array($key => $value));
770
+    }
771
+
772
+    /**
773
+     * Checks, whether a port was entered in the Host configuration
774
+     * field. In this case the port will be stripped off, but also stored as
775
+     * setting.
776
+     */
777
+    private function checkHost() {
778
+        $host = $this->configuration->ldapHost;
779
+        $hostInfo = parse_url($host);
780
+
781
+        //removes Port from Host
782
+        if(is_array($hostInfo) && isset($hostInfo['port'])) {
783
+            $port = $hostInfo['port'];
784
+            $host = str_replace(':'.$port, '', $host);
785
+            $this->applyFind('ldap_host', $host);
786
+            $this->applyFind('ldap_port', $port);
787
+        }
788
+    }
789
+
790
+    /**
791
+     * tries to detect the group member association attribute which is
792
+     * one of 'uniqueMember', 'memberUid', 'member', 'gidNumber'
793
+     * @return string|false, string with the attribute name, false on error
794
+     * @throws \Exception
795
+     */
796
+    private function detectGroupMemberAssoc() {
797
+        $possibleAttrs = ['uniqueMember', 'memberUid', 'member', 'gidNumber'];
798
+        $filter = $this->configuration->ldapGroupFilter;
799
+        if(empty($filter)) {
800
+            return false;
801
+        }
802
+        $cr = $this->getConnection();
803
+        if(!$cr) {
804
+            throw new \Exception('Could not connect to LDAP');
805
+        }
806
+        $base = $this->configuration->ldapBaseGroups[0] ?: $this->configuration->ldapBase[0];
807
+        $rr = $this->ldap->search($cr, $base, $filter, $possibleAttrs, 0, 1000);
808
+        if(!$this->ldap->isResource($rr)) {
809
+            return false;
810
+        }
811
+        $er = $this->ldap->firstEntry($cr, $rr);
812
+        while(is_resource($er)) {
813
+            $this->ldap->getDN($cr, $er);
814
+            $attrs = $this->ldap->getAttributes($cr, $er);
815
+            $result = [];
816
+            $possibleAttrsCount = count($possibleAttrs);
817
+            for($i = 0; $i < $possibleAttrsCount; $i++) {
818
+                if(isset($attrs[$possibleAttrs[$i]])) {
819
+                    $result[$possibleAttrs[$i]] = $attrs[$possibleAttrs[$i]]['count'];
820
+                }
821
+            }
822
+            if(!empty($result)) {
823
+                natsort($result);
824
+                return key($result);
825
+            }
826
+
827
+            $er = $this->ldap->nextEntry($cr, $er);
828
+        }
829
+
830
+        return false;
831
+    }
832
+
833
+    /**
834
+     * Checks whether for a given BaseDN results will be returned
835
+     * @param string $base the BaseDN to test
836
+     * @return bool true on success, false otherwise
837
+     * @throws \Exception
838
+     */
839
+    private function testBaseDN($base) {
840
+        $cr = $this->getConnection();
841
+        if(!$cr) {
842
+            throw new \Exception('Could not connect to LDAP');
843
+        }
844
+
845
+        //base is there, let's validate it. If we search for anything, we should
846
+        //get a result set > 0 on a proper base
847
+        $rr = $this->ldap->search($cr, $base, 'objectClass=*', array('dn'), 0, 1);
848
+        if(!$this->ldap->isResource($rr)) {
849
+            $errorNo  = $this->ldap->errno($cr);
850
+            $errorMsg = $this->ldap->error($cr);
851
+            \OCP\Util::writeLog('user_ldap', 'Wiz: Could not search base '.$base.
852
+                            ' Error '.$errorNo.': '.$errorMsg, ILogger::INFO);
853
+            return false;
854
+        }
855
+        $entries = $this->ldap->countEntries($cr, $rr);
856
+        return ($entries !== false) && ($entries > 0);
857
+    }
858
+
859
+    /**
860
+     * Checks whether the server supports memberOf in LDAP Filter.
861
+     * Note: at least in OpenLDAP, availability of memberOf is dependent on
862
+     * a configured objectClass. I.e. not necessarily for all available groups
863
+     * memberOf does work.
864
+     *
865
+     * @return bool true if it does, false otherwise
866
+     * @throws \Exception
867
+     */
868
+    private function testMemberOf() {
869
+        $cr = $this->getConnection();
870
+        if(!$cr) {
871
+            throw new \Exception('Could not connect to LDAP');
872
+        }
873
+        $result = $this->access->countUsers('memberOf=*', array('memberOf'), 1);
874
+        if(is_int($result) &&  $result > 0) {
875
+            return true;
876
+        }
877
+        return false;
878
+    }
879
+
880
+    /**
881
+     * creates an LDAP Filter from given configuration
882
+     * @param integer $filterType int, for which use case the filter shall be created
883
+     * can be any of self::LFILTER_USER_LIST, self::LFILTER_LOGIN or
884
+     * self::LFILTER_GROUP_LIST
885
+     * @return string|false string with the filter on success, false otherwise
886
+     * @throws \Exception
887
+     */
888
+    private function composeLdapFilter($filterType) {
889
+        $filter = '';
890
+        $parts = 0;
891
+        switch ($filterType) {
892
+            case self::LFILTER_USER_LIST:
893
+                $objcs = $this->configuration->ldapUserFilterObjectclass;
894
+                //glue objectclasses
895
+                if(is_array($objcs) && count($objcs) > 0) {
896
+                    $filter .= '(|';
897
+                    foreach($objcs as $objc) {
898
+                        $filter .= '(objectclass=' . $objc . ')';
899
+                    }
900
+                    $filter .= ')';
901
+                    $parts++;
902
+                }
903
+                //glue group memberships
904
+                if($this->configuration->hasMemberOfFilterSupport) {
905
+                    $cns = $this->configuration->ldapUserFilterGroups;
906
+                    if(is_array($cns) && count($cns) > 0) {
907
+                        $filter .= '(|';
908
+                        $cr = $this->getConnection();
909
+                        if(!$cr) {
910
+                            throw new \Exception('Could not connect to LDAP');
911
+                        }
912
+                        $base = $this->configuration->ldapBase[0];
913
+                        foreach($cns as $cn) {
914
+                            $rr = $this->ldap->search($cr, $base, 'cn=' . $cn, array('dn', 'primaryGroupToken'));
915
+                            if(!$this->ldap->isResource($rr)) {
916
+                                continue;
917
+                            }
918
+                            $er = $this->ldap->firstEntry($cr, $rr);
919
+                            $attrs = $this->ldap->getAttributes($cr, $er);
920
+                            $dn = $this->ldap->getDN($cr, $er);
921
+                            if ($dn === false || $dn === '') {
922
+                                continue;
923
+                            }
924
+                            $filterPart = '(memberof=' . $dn . ')';
925
+                            if(isset($attrs['primaryGroupToken'])) {
926
+                                $pgt = $attrs['primaryGroupToken'][0];
927
+                                $primaryFilterPart = '(primaryGroupID=' . $pgt .')';
928
+                                $filterPart = '(|' . $filterPart . $primaryFilterPart . ')';
929
+                            }
930
+                            $filter .= $filterPart;
931
+                        }
932
+                        $filter .= ')';
933
+                    }
934
+                    $parts++;
935
+                }
936
+                //wrap parts in AND condition
937
+                if($parts > 1) {
938
+                    $filter = '(&' . $filter . ')';
939
+                }
940
+                if ($filter === '') {
941
+                    $filter = '(objectclass=*)';
942
+                }
943
+                break;
944
+
945
+            case self::LFILTER_GROUP_LIST:
946
+                $objcs = $this->configuration->ldapGroupFilterObjectclass;
947
+                //glue objectclasses
948
+                if(is_array($objcs) && count($objcs) > 0) {
949
+                    $filter .= '(|';
950
+                    foreach($objcs as $objc) {
951
+                        $filter .= '(objectclass=' . $objc . ')';
952
+                    }
953
+                    $filter .= ')';
954
+                    $parts++;
955
+                }
956
+                //glue group memberships
957
+                $cns = $this->configuration->ldapGroupFilterGroups;
958
+                if(is_array($cns) && count($cns) > 0) {
959
+                    $filter .= '(|';
960
+                    foreach($cns as $cn) {
961
+                        $filter .= '(cn=' . $cn . ')';
962
+                    }
963
+                    $filter .= ')';
964
+                }
965
+                $parts++;
966
+                //wrap parts in AND condition
967
+                if($parts > 1) {
968
+                    $filter = '(&' . $filter . ')';
969
+                }
970
+                break;
971
+
972
+            case self::LFILTER_LOGIN:
973
+                $ulf = $this->configuration->ldapUserFilter;
974
+                $loginpart = '=%uid';
975
+                $filterUsername = '';
976
+                $userAttributes = $this->getUserAttributes();
977
+                $userAttributes = array_change_key_case(array_flip($userAttributes));
978
+                $parts = 0;
979
+
980
+                if($this->configuration->ldapLoginFilterUsername === '1') {
981
+                    $attr = '';
982
+                    if(isset($userAttributes['uid'])) {
983
+                        $attr = 'uid';
984
+                    } else if(isset($userAttributes['samaccountname'])) {
985
+                        $attr = 'samaccountname';
986
+                    } else if(isset($userAttributes['cn'])) {
987
+                        //fallback
988
+                        $attr = 'cn';
989
+                    }
990
+                    if ($attr !== '') {
991
+                        $filterUsername = '(' . $attr . $loginpart . ')';
992
+                        $parts++;
993
+                    }
994
+                }
995
+
996
+                $filterEmail = '';
997
+                if($this->configuration->ldapLoginFilterEmail === '1') {
998
+                    $filterEmail = '(|(mailPrimaryAddress=%uid)(mail=%uid))';
999
+                    $parts++;
1000
+                }
1001
+
1002
+                $filterAttributes = '';
1003
+                $attrsToFilter = $this->configuration->ldapLoginFilterAttributes;
1004
+                if(is_array($attrsToFilter) && count($attrsToFilter) > 0) {
1005
+                    $filterAttributes = '(|';
1006
+                    foreach($attrsToFilter as $attribute) {
1007
+                        $filterAttributes .= '(' . $attribute . $loginpart . ')';
1008
+                    }
1009
+                    $filterAttributes .= ')';
1010
+                    $parts++;
1011
+                }
1012
+
1013
+                $filterLogin = '';
1014
+                if($parts > 1) {
1015
+                    $filterLogin = '(|';
1016
+                }
1017
+                $filterLogin .= $filterUsername;
1018
+                $filterLogin .= $filterEmail;
1019
+                $filterLogin .= $filterAttributes;
1020
+                if($parts > 1) {
1021
+                    $filterLogin .= ')';
1022
+                }
1023
+
1024
+                $filter = '(&'.$ulf.$filterLogin.')';
1025
+                break;
1026
+        }
1027
+
1028
+        \OCP\Util::writeLog('user_ldap', 'Wiz: Final filter '.$filter, ILogger::DEBUG);
1029
+
1030
+        return $filter;
1031
+    }
1032
+
1033
+    /**
1034
+     * Connects and Binds to an LDAP Server
1035
+     *
1036
+     * @param int $port the port to connect with
1037
+     * @param bool $tls whether startTLS is to be used
1038
+     * @return bool
1039
+     * @throws \Exception
1040
+     */
1041
+    private function connectAndBind($port, $tls) {
1042
+        //connect, does not really trigger any server communication
1043
+        $host = $this->configuration->ldapHost;
1044
+        $hostInfo = parse_url($host);
1045
+        if(!$hostInfo) {
1046
+            throw new \Exception(self::$l->t('Invalid Host'));
1047
+        }
1048
+        \OCP\Util::writeLog('user_ldap', 'Wiz: Attempting to connect ', ILogger::DEBUG);
1049
+        $cr = $this->ldap->connect($host, $port);
1050
+        if(!is_resource($cr)) {
1051
+            throw new \Exception(self::$l->t('Invalid Host'));
1052
+        }
1053
+
1054
+        //set LDAP options
1055
+        $this->ldap->setOption($cr, LDAP_OPT_PROTOCOL_VERSION, 3);
1056
+        $this->ldap->setOption($cr, LDAP_OPT_REFERRALS, 0);
1057
+        $this->ldap->setOption($cr, LDAP_OPT_NETWORK_TIMEOUT, self::LDAP_NW_TIMEOUT);
1058
+
1059
+        try {
1060
+            if($tls) {
1061
+                $isTlsWorking = @$this->ldap->startTls($cr);
1062
+                if(!$isTlsWorking) {
1063
+                    return false;
1064
+                }
1065
+            }
1066
+
1067
+            \OCP\Util::writeLog('user_ldap', 'Wiz: Attemping to Bind ', ILogger::DEBUG);
1068
+            //interesting part: do the bind!
1069
+            $login = $this->ldap->bind($cr,
1070
+                $this->configuration->ldapAgentName,
1071
+                $this->configuration->ldapAgentPassword
1072
+            );
1073
+            $errNo = $this->ldap->errno($cr);
1074
+            $error = ldap_error($cr);
1075
+            $this->ldap->unbind($cr);
1076
+        } catch(ServerNotAvailableException $e) {
1077
+            return false;
1078
+        }
1079
+
1080
+        if($login === true) {
1081
+            $this->ldap->unbind($cr);
1082
+            \OCP\Util::writeLog('user_ldap', 'Wiz: Bind successful to Port '. $port . ' TLS ' . (int)$tls, ILogger::DEBUG);
1083
+            return true;
1084
+        }
1085
+
1086
+        if($errNo === -1) {
1087
+            //host, port or TLS wrong
1088
+            return false;
1089
+        }
1090
+        throw new \Exception($error, $errNo);
1091
+    }
1092
+
1093
+    /**
1094
+     * checks whether a valid combination of agent and password has been
1095
+     * provided (either two values or nothing for anonymous connect)
1096
+     * @return bool, true if everything is fine, false otherwise
1097
+     */
1098
+    private function checkAgentRequirements() {
1099
+        $agent = $this->configuration->ldapAgentName;
1100
+        $pwd = $this->configuration->ldapAgentPassword;
1101
+
1102
+        return
1103
+            ($agent !== '' && $pwd !== '')
1104
+            ||  ($agent === '' && $pwd === '')
1105
+        ;
1106
+    }
1107
+
1108
+    /**
1109
+     * @param array $reqs
1110
+     * @return bool
1111
+     */
1112
+    private function checkRequirements($reqs) {
1113
+        $this->checkAgentRequirements();
1114
+        foreach($reqs as $option) {
1115
+            $value = $this->configuration->$option;
1116
+            if(empty($value)) {
1117
+                return false;
1118
+            }
1119
+        }
1120
+        return true;
1121
+    }
1122
+
1123
+    /**
1124
+     * does a cumulativeSearch on LDAP to get different values of a
1125
+     * specified attribute
1126
+     * @param string[] $filters array, the filters that shall be used in the search
1127
+     * @param string $attr the attribute of which a list of values shall be returned
1128
+     * @param int $dnReadLimit the amount of how many DNs should be analyzed.
1129
+     * The lower, the faster
1130
+     * @param string $maxF string. if not null, this variable will have the filter that
1131
+     * yields most result entries
1132
+     * @return array|false an array with the values on success, false otherwise
1133
+     */
1134
+    public function cumulativeSearchOnAttribute($filters, $attr, $dnReadLimit = 3, &$maxF = null) {
1135
+        $dnRead = array();
1136
+        $foundItems = array();
1137
+        $maxEntries = 0;
1138
+        if(!is_array($this->configuration->ldapBase)
1139
+           || !isset($this->configuration->ldapBase[0])) {
1140
+            return false;
1141
+        }
1142
+        $base = $this->configuration->ldapBase[0];
1143
+        $cr = $this->getConnection();
1144
+        if(!$this->ldap->isResource($cr)) {
1145
+            return false;
1146
+        }
1147
+        $lastFilter = null;
1148
+        if(isset($filters[count($filters)-1])) {
1149
+            $lastFilter = $filters[count($filters)-1];
1150
+        }
1151
+        foreach($filters as $filter) {
1152
+            if($lastFilter === $filter && count($foundItems) > 0) {
1153
+                //skip when the filter is a wildcard and results were found
1154
+                continue;
1155
+            }
1156
+            // 20k limit for performance and reason
1157
+            $rr = $this->ldap->search($cr, $base, $filter, array($attr), 0, 20000);
1158
+            if(!$this->ldap->isResource($rr)) {
1159
+                continue;
1160
+            }
1161
+            $entries = $this->ldap->countEntries($cr, $rr);
1162
+            $getEntryFunc = 'firstEntry';
1163
+            if(($entries !== false) && ($entries > 0)) {
1164
+                if(!is_null($maxF) && $entries > $maxEntries) {
1165
+                    $maxEntries = $entries;
1166
+                    $maxF = $filter;
1167
+                }
1168
+                $dnReadCount = 0;
1169
+                do {
1170
+                    $entry = $this->ldap->$getEntryFunc($cr, $rr);
1171
+                    $getEntryFunc = 'nextEntry';
1172
+                    if(!$this->ldap->isResource($entry)) {
1173
+                        continue 2;
1174
+                    }
1175
+                    $rr = $entry; //will be expected by nextEntry next round
1176
+                    $attributes = $this->ldap->getAttributes($cr, $entry);
1177
+                    $dn = $this->ldap->getDN($cr, $entry);
1178
+                    if($dn === false || in_array($dn, $dnRead)) {
1179
+                        continue;
1180
+                    }
1181
+                    $newItems = array();
1182
+                    $state = $this->getAttributeValuesFromEntry($attributes,
1183
+                                                                $attr,
1184
+                                                                $newItems);
1185
+                    $dnReadCount++;
1186
+                    $foundItems = array_merge($foundItems, $newItems);
1187
+                    $this->resultCache[$dn][$attr] = $newItems;
1188
+                    $dnRead[] = $dn;
1189
+                } while(($state === self::LRESULT_PROCESSED_SKIP
1190
+                        || $this->ldap->isResource($entry))
1191
+                        && ($dnReadLimit === 0 || $dnReadCount < $dnReadLimit));
1192
+            }
1193
+        }
1194
+
1195
+        return array_unique($foundItems);
1196
+    }
1197
+
1198
+    /**
1199
+     * determines if and which $attr are available on the LDAP server
1200
+     * @param string[] $objectclasses the objectclasses to use as search filter
1201
+     * @param string $attr the attribute to look for
1202
+     * @param string $dbkey the dbkey of the setting the feature is connected to
1203
+     * @param string $confkey the confkey counterpart for the $dbkey as used in the
1204
+     * Configuration class
1205
+     * @param bool $po whether the objectClass with most result entries
1206
+     * shall be pre-selected via the result
1207
+     * @return array|false list of found items.
1208
+     * @throws \Exception
1209
+     */
1210
+    private function determineFeature($objectclasses, $attr, $dbkey, $confkey, $po = false) {
1211
+        $cr = $this->getConnection();
1212
+        if(!$cr) {
1213
+            throw new \Exception('Could not connect to LDAP');
1214
+        }
1215
+        $p = 'objectclass=';
1216
+        foreach($objectclasses as $key => $value) {
1217
+            $objectclasses[$key] = $p.$value;
1218
+        }
1219
+        $maxEntryObjC = '';
1220
+
1221
+        //how deep to dig?
1222
+        //When looking for objectclasses, testing few entries is sufficient,
1223
+        $dig = 3;
1224
+
1225
+        $availableFeatures =
1226
+            $this->cumulativeSearchOnAttribute($objectclasses, $attr,
1227
+                                                $dig, $maxEntryObjC);
1228
+        if(is_array($availableFeatures)
1229
+           && count($availableFeatures) > 0) {
1230
+            natcasesort($availableFeatures);
1231
+            //natcasesort keeps indices, but we must get rid of them for proper
1232
+            //sorting in the web UI. Therefore: array_values
1233
+            $this->result->addOptions($dbkey, array_values($availableFeatures));
1234
+        } else {
1235
+            throw new \Exception(self::$l->t('Could not find the desired feature'));
1236
+        }
1237
+
1238
+        $setFeatures = $this->configuration->$confkey;
1239
+        if(is_array($setFeatures) && !empty($setFeatures)) {
1240
+            //something is already configured? pre-select it.
1241
+            $this->result->addChange($dbkey, $setFeatures);
1242
+        } else if ($po && $maxEntryObjC !== '') {
1243
+            //pre-select objectclass with most result entries
1244
+            $maxEntryObjC = str_replace($p, '', $maxEntryObjC);
1245
+            $this->applyFind($dbkey, $maxEntryObjC);
1246
+            $this->result->addChange($dbkey, $maxEntryObjC);
1247
+        }
1248
+
1249
+        return $availableFeatures;
1250
+    }
1251
+
1252
+    /**
1253
+     * appends a list of values fr
1254
+     * @param resource $result the return value from ldap_get_attributes
1255
+     * @param string $attribute the attribute values to look for
1256
+     * @param array &$known new values will be appended here
1257
+     * @return int, state on of the class constants LRESULT_PROCESSED_OK,
1258
+     * LRESULT_PROCESSED_INVALID or LRESULT_PROCESSED_SKIP
1259
+     */
1260
+    private function getAttributeValuesFromEntry($result, $attribute, &$known) {
1261
+        if(!is_array($result)
1262
+           || !isset($result['count'])
1263
+           || !$result['count'] > 0) {
1264
+            return self::LRESULT_PROCESSED_INVALID;
1265
+        }
1266
+
1267
+        // strtolower on all keys for proper comparison
1268
+        $result = \OCP\Util::mb_array_change_key_case($result);
1269
+        $attribute = strtolower($attribute);
1270
+        if(isset($result[$attribute])) {
1271
+            foreach($result[$attribute] as $key => $val) {
1272
+                if($key === 'count') {
1273
+                    continue;
1274
+                }
1275
+                if(!in_array($val, $known)) {
1276
+                    $known[] = $val;
1277
+                }
1278
+            }
1279
+            return self::LRESULT_PROCESSED_OK;
1280
+        } else {
1281
+            return self::LRESULT_PROCESSED_SKIP;
1282
+        }
1283
+    }
1284
+
1285
+    /**
1286
+     * @return bool|mixed
1287
+     */
1288
+    private function getConnection() {
1289
+        if(!is_null($this->cr)) {
1290
+            return $this->cr;
1291
+        }
1292
+
1293
+        $cr = $this->ldap->connect(
1294
+            $this->configuration->ldapHost,
1295
+            $this->configuration->ldapPort
1296
+        );
1297
+
1298
+        $this->ldap->setOption($cr, LDAP_OPT_PROTOCOL_VERSION, 3);
1299
+        $this->ldap->setOption($cr, LDAP_OPT_REFERRALS, 0);
1300
+        $this->ldap->setOption($cr, LDAP_OPT_NETWORK_TIMEOUT, self::LDAP_NW_TIMEOUT);
1301
+        if($this->configuration->ldapTLS === 1) {
1302
+            $this->ldap->startTls($cr);
1303
+        }
1304
+
1305
+        $lo = @$this->ldap->bind($cr,
1306
+                                    $this->configuration->ldapAgentName,
1307
+                                    $this->configuration->ldapAgentPassword);
1308
+        if($lo === true) {
1309
+            $this->$cr = $cr;
1310
+            return $cr;
1311
+        }
1312
+
1313
+        return false;
1314
+    }
1315
+
1316
+    /**
1317
+     * @return array
1318
+     */
1319
+    private function getDefaultLdapPortSettings() {
1320
+        static $settings = array(
1321
+                                array('port' => 7636, 'tls' => false),
1322
+                                array('port' =>  636, 'tls' => false),
1323
+                                array('port' => 7389, 'tls' => true),
1324
+                                array('port' =>  389, 'tls' => true),
1325
+                                array('port' => 7389, 'tls' => false),
1326
+                                array('port' =>  389, 'tls' => false),
1327
+                            );
1328
+        return $settings;
1329
+    }
1330
+
1331
+    /**
1332
+     * @return array
1333
+     */
1334
+    private function getPortSettingsToTry() {
1335
+        //389 ← LDAP / Unencrypted or StartTLS
1336
+        //636 ← LDAPS / SSL
1337
+        //7xxx ← UCS. need to be checked first, because both ports may be open
1338
+        $host = $this->configuration->ldapHost;
1339
+        $port = (int)$this->configuration->ldapPort;
1340
+        $portSettings = array();
1341
+
1342
+        //In case the port is already provided, we will check this first
1343
+        if($port > 0) {
1344
+            $hostInfo = parse_url($host);
1345
+            if(!(is_array($hostInfo)
1346
+                && isset($hostInfo['scheme'])
1347
+                && stripos($hostInfo['scheme'], 'ldaps') !== false)) {
1348
+                $portSettings[] = array('port' => $port, 'tls' => true);
1349
+            }
1350
+            $portSettings[] =array('port' => $port, 'tls' => false);
1351
+        }
1352
+
1353
+        //default ports
1354
+        $portSettings = array_merge($portSettings,
1355
+                                    $this->getDefaultLdapPortSettings());
1356
+
1357
+        return $portSettings;
1358
+    }
1359 1359
 
1360 1360
 
1361 1361
 }
Please login to merge, or discard this patch.
Spacing   +156 added lines, -156 removed lines patch added patch discarded remove patch
@@ -72,7 +72,7 @@  discard block
 block discarded – undo
72 72
 	public function __construct(Configuration $configuration, ILDAPWrapper $ldap, Access $access) {
73 73
 		parent::__construct($ldap);
74 74
 		$this->configuration = $configuration;
75
-		if(is_null(Wizard::$l)) {
75
+		if (is_null(Wizard::$l)) {
76 76
 			Wizard::$l = \OC::$server->getL10N('user_ldap');
77 77
 		}
78 78
 		$this->access = $access;
@@ -80,7 +80,7 @@  discard block
 block discarded – undo
80 80
 	}
81 81
 
82 82
 	public function  __destruct() {
83
-		if($this->result->hasChanges()) {
83
+		if ($this->result->hasChanges()) {
84 84
 			$this->configuration->saveConfiguration();
85 85
 		}
86 86
 	}
@@ -95,18 +95,18 @@  discard block
 block discarded – undo
95 95
 	 */
96 96
 	public function countEntries(string $filter, string $type): int {
97 97
 		$reqs = ['ldapHost', 'ldapPort', 'ldapBase'];
98
-		if($type === 'users') {
98
+		if ($type === 'users') {
99 99
 			$reqs[] = 'ldapUserFilter';
100 100
 		}
101
-		if(!$this->checkRequirements($reqs)) {
101
+		if (!$this->checkRequirements($reqs)) {
102 102
 			throw new \Exception('Requirements not met', 400);
103 103
 		}
104 104
 
105 105
 		$attr = ['dn']; // default
106 106
 		$limit = 1001;
107
-		if($type === 'groups') {
108
-			$result =  $this->access->countGroups($filter, $attr, $limit);
109
-		} else if($type === 'users') {
107
+		if ($type === 'groups') {
108
+			$result = $this->access->countGroups($filter, $attr, $limit);
109
+		} else if ($type === 'users') {
110 110
 			$result = $this->access->countUsers($filter, $attr, $limit);
111 111
 		} else if ($type === 'objects') {
112 112
 			$result = $this->access->countObjects($limit);
@@ -114,7 +114,7 @@  discard block
 block discarded – undo
114 114
 			throw new \Exception('Internal error: Invalid object type', 500);
115 115
 		}
116 116
 
117
-		return (int)$result;
117
+		return (int) $result;
118 118
 	}
119 119
 
120 120
 	/**
@@ -125,16 +125,16 @@  discard block
 block discarded – undo
125 125
 	 * @return string
126 126
 	 */
127 127
 	private function formatCountResult(int $count): string {
128
-		if($count > 1000) {
128
+		if ($count > 1000) {
129 129
 			return '> 1000';
130 130
 		}
131
-		return (string)$count;
131
+		return (string) $count;
132 132
 	}
133 133
 
134 134
 	public function countGroups() {
135 135
 		$filter = $this->configuration->ldapGroupFilter;
136 136
 
137
-		if(empty($filter)) {
137
+		if (empty($filter)) {
138 138
 			$output = self::$l->n('%s group found', '%s groups found', 0, array(0));
139 139
 			$this->result->addChange('ldap_group_count', $output);
140 140
 			return $this->result;
@@ -144,7 +144,7 @@  discard block
 block discarded – undo
144 144
 			$groupsTotal = $this->countEntries($filter, 'groups');
145 145
 		} catch (\Exception $e) {
146 146
 			//400 can be ignored, 500 is forwarded
147
-			if($e->getCode() === 500) {
147
+			if ($e->getCode() === 500) {
148 148
 				throw $e;
149 149
 			}
150 150
 			return false;
@@ -186,7 +186,7 @@  discard block
 block discarded – undo
186 186
 	public function countInBaseDN() {
187 187
 		// we don't need to provide a filter in this case
188 188
 		$total = $this->countEntries('', 'objects');
189
-		if($total === false) {
189
+		if ($total === false) {
190 190
 			throw new \Exception('invalid results received');
191 191
 		}
192 192
 		$this->result->addChange('ldap_test_base', $total);
@@ -200,7 +200,7 @@  discard block
 block discarded – undo
200 200
 	 * @return int|bool
201 201
 	 */
202 202
 	public function countUsersWithAttribute($attr, $existsCheck = false) {
203
-		if(!$this->checkRequirements(array('ldapHost',
203
+		if (!$this->checkRequirements(array('ldapHost',
204 204
 										   'ldapPort',
205 205
 										   'ldapBase',
206 206
 										   'ldapUserFilter',
@@ -210,7 +210,7 @@  discard block
 block discarded – undo
210 210
 
211 211
 		$filter = $this->access->combineFilterWithAnd(array(
212 212
 			$this->configuration->ldapUserFilter,
213
-			$attr . '=*'
213
+			$attr.'=*'
214 214
 		));
215 215
 
216 216
 		$limit = ($existsCheck === false) ? null : 1;
@@ -225,7 +225,7 @@  discard block
 block discarded – undo
225 225
 	 * @throws \Exception
226 226
 	 */
227 227
 	public function detectUserDisplayNameAttribute() {
228
-		if(!$this->checkRequirements(array('ldapHost',
228
+		if (!$this->checkRequirements(array('ldapHost',
229 229
 										'ldapPort',
230 230
 										'ldapBase',
231 231
 										'ldapUserFilter',
@@ -237,8 +237,8 @@  discard block
 block discarded – undo
237 237
 		if ($attr !== '' && $attr !== 'displayName') {
238 238
 			// most likely not the default value with upper case N,
239 239
 			// verify it still produces a result
240
-			$count = (int)$this->countUsersWithAttribute($attr, true);
241
-			if($count > 0) {
240
+			$count = (int) $this->countUsersWithAttribute($attr, true);
241
+			if ($count > 0) {
242 242
 				//no change, but we sent it back to make sure the user interface
243 243
 				//is still correct, even if the ajax call was cancelled meanwhile
244 244
 				$this->result->addChange('ldap_display_name', $attr);
@@ -249,9 +249,9 @@  discard block
 block discarded – undo
249 249
 		// first attribute that has at least one result wins
250 250
 		$displayNameAttrs = array('displayname', 'cn');
251 251
 		foreach ($displayNameAttrs as $attr) {
252
-			$count = (int)$this->countUsersWithAttribute($attr, true);
252
+			$count = (int) $this->countUsersWithAttribute($attr, true);
253 253
 
254
-			if($count > 0) {
254
+			if ($count > 0) {
255 255
 				$this->applyFind('ldap_display_name', $attr);
256 256
 				return $this->result;
257 257
 			}
@@ -267,7 +267,7 @@  discard block
 block discarded – undo
267 267
 	 * @return WizardResult|bool
268 268
 	 */
269 269
 	public function detectEmailAttribute() {
270
-		if(!$this->checkRequirements(array('ldapHost',
270
+		if (!$this->checkRequirements(array('ldapHost',
271 271
 										   'ldapPort',
272 272
 										   'ldapBase',
273 273
 										   'ldapUserFilter',
@@ -277,8 +277,8 @@  discard block
 block discarded – undo
277 277
 
278 278
 		$attr = $this->configuration->ldapEmailAttribute;
279 279
 		if ($attr !== '') {
280
-			$count = (int)$this->countUsersWithAttribute($attr, true);
281
-			if($count > 0) {
280
+			$count = (int) $this->countUsersWithAttribute($attr, true);
281
+			if ($count > 0) {
282 282
 				return false;
283 283
 			}
284 284
 			$writeLog = true;
@@ -289,19 +289,19 @@  discard block
 block discarded – undo
289 289
 		$emailAttributes = array('mail', 'mailPrimaryAddress');
290 290
 		$winner = '';
291 291
 		$maxUsers = 0;
292
-		foreach($emailAttributes as $attr) {
292
+		foreach ($emailAttributes as $attr) {
293 293
 			$count = $this->countUsersWithAttribute($attr);
294
-			if($count > $maxUsers) {
294
+			if ($count > $maxUsers) {
295 295
 				$maxUsers = $count;
296 296
 				$winner = $attr;
297 297
 			}
298 298
 		}
299 299
 
300
-		if($winner !== '') {
300
+		if ($winner !== '') {
301 301
 			$this->applyFind('ldap_email_attr', $winner);
302
-			if($writeLog) {
303
-				\OCP\Util::writeLog('user_ldap', 'The mail attribute has ' .
304
-					'automatically been reset, because the original value ' .
302
+			if ($writeLog) {
303
+				\OCP\Util::writeLog('user_ldap', 'The mail attribute has '.
304
+					'automatically been reset, because the original value '.
305 305
 					'did not return any results.', ILogger::INFO);
306 306
 			}
307 307
 		}
@@ -314,7 +314,7 @@  discard block
 block discarded – undo
314 314
 	 * @throws \Exception
315 315
 	 */
316 316
 	public function determineAttributes() {
317
-		if(!$this->checkRequirements(array('ldapHost',
317
+		if (!$this->checkRequirements(array('ldapHost',
318 318
 										   'ldapPort',
319 319
 										   'ldapBase',
320 320
 										   'ldapUserFilter',
@@ -330,7 +330,7 @@  discard block
 block discarded – undo
330 330
 		$this->result->addOptions('ldap_loginfilter_attributes', $attributes);
331 331
 
332 332
 		$selected = $this->configuration->ldapLoginFilterAttributes;
333
-		if(is_array($selected) && !empty($selected)) {
333
+		if (is_array($selected) && !empty($selected)) {
334 334
 			$this->result->addChange('ldap_loginfilter_attributes', $selected);
335 335
 		}
336 336
 
@@ -343,7 +343,7 @@  discard block
 block discarded – undo
343 343
 	 * @throws \Exception
344 344
 	 */
345 345
 	private function getUserAttributes() {
346
-		if(!$this->checkRequirements(array('ldapHost',
346
+		if (!$this->checkRequirements(array('ldapHost',
347 347
 										   'ldapPort',
348 348
 										   'ldapBase',
349 349
 										   'ldapUserFilter',
@@ -351,20 +351,20 @@  discard block
 block discarded – undo
351 351
 			return  false;
352 352
 		}
353 353
 		$cr = $this->getConnection();
354
-		if(!$cr) {
354
+		if (!$cr) {
355 355
 			throw new \Exception('Could not connect to LDAP');
356 356
 		}
357 357
 
358 358
 		$base = $this->configuration->ldapBase[0];
359 359
 		$filter = $this->configuration->ldapUserFilter;
360 360
 		$rr = $this->ldap->search($cr, $base, $filter, array(), 1, 1);
361
-		if(!$this->ldap->isResource($rr)) {
361
+		if (!$this->ldap->isResource($rr)) {
362 362
 			return false;
363 363
 		}
364 364
 		$er = $this->ldap->firstEntry($cr, $rr);
365 365
 		$attributes = $this->ldap->getAttributes($cr, $er);
366 366
 		$pureAttributes = array();
367
-		for($i = 0; $i < $attributes['count']; $i++) {
367
+		for ($i = 0; $i < $attributes['count']; $i++) {
368 368
 			$pureAttributes[] = $attributes[$i];
369 369
 		}
370 370
 
@@ -399,23 +399,23 @@  discard block
 block discarded – undo
399 399
 	 * @throws \Exception
400 400
 	 */
401 401
 	private function determineGroups($dbKey, $confKey, $testMemberOf = true) {
402
-		if(!$this->checkRequirements(array('ldapHost',
402
+		if (!$this->checkRequirements(array('ldapHost',
403 403
 										   'ldapPort',
404 404
 										   'ldapBase',
405 405
 										   ))) {
406 406
 			return  false;
407 407
 		}
408 408
 		$cr = $this->getConnection();
409
-		if(!$cr) {
409
+		if (!$cr) {
410 410
 			throw new \Exception('Could not connect to LDAP');
411 411
 		}
412 412
 
413 413
 		$this->fetchGroups($dbKey, $confKey);
414 414
 
415
-		if($testMemberOf) {
415
+		if ($testMemberOf) {
416 416
 			$this->configuration->hasMemberOfFilterSupport = $this->testMemberOf();
417 417
 			$this->result->markChange();
418
-			if(!$this->configuration->hasMemberOfFilterSupport) {
418
+			if (!$this->configuration->hasMemberOfFilterSupport) {
419 419
 				throw new \Exception('memberOf is not supported by the server');
420 420
 			}
421 421
 		}
@@ -435,7 +435,7 @@  discard block
 block discarded – undo
435 435
 		$obclasses = array('posixGroup', 'group', 'zimbraDistributionList', 'groupOfNames', 'groupOfUniqueNames');
436 436
 
437 437
 		$filterParts = array();
438
-		foreach($obclasses as $obclass) {
438
+		foreach ($obclasses as $obclass) {
439 439
 			$filterParts[] = 'objectclass='.$obclass;
440 440
 		}
441 441
 		//we filter for everything
@@ -452,8 +452,8 @@  discard block
 block discarded – undo
452 452
 			// we need to request dn additionally here, otherwise memberOf
453 453
 			// detection will fail later
454 454
 			$result = $this->access->searchGroups($filter, array('cn', 'dn'), $limit, $offset);
455
-			foreach($result as $item) {
456
-				if(!isset($item['cn']) && !is_array($item['cn']) && !isset($item['cn'][0])) {
455
+			foreach ($result as $item) {
456
+				if (!isset($item['cn']) && !is_array($item['cn']) && !isset($item['cn'][0])) {
457 457
 					// just in case - no issue known
458 458
 					continue;
459 459
 				}
@@ -463,7 +463,7 @@  discard block
 block discarded – undo
463 463
 			$offset += $limit;
464 464
 		} while ($this->access->hasMoreResults());
465 465
 
466
-		if(count($groupNames) > 0) {
466
+		if (count($groupNames) > 0) {
467 467
 			natsort($groupNames);
468 468
 			$this->result->addOptions($dbKey, array_values($groupNames));
469 469
 		} else {
@@ -471,7 +471,7 @@  discard block
 block discarded – undo
471 471
 		}
472 472
 
473 473
 		$setFeatures = $this->configuration->$confKey;
474
-		if(is_array($setFeatures) && !empty($setFeatures)) {
474
+		if (is_array($setFeatures) && !empty($setFeatures)) {
475 475
 			//something is already configured? pre-select it.
476 476
 			$this->result->addChange($dbKey, $setFeatures);
477 477
 		}
@@ -479,14 +479,14 @@  discard block
 block discarded – undo
479 479
 	}
480 480
 
481 481
 	public function determineGroupMemberAssoc() {
482
-		if(!$this->checkRequirements(array('ldapHost',
482
+		if (!$this->checkRequirements(array('ldapHost',
483 483
 										   'ldapPort',
484 484
 										   'ldapGroupFilter',
485 485
 										   ))) {
486 486
 			return  false;
487 487
 		}
488 488
 		$attribute = $this->detectGroupMemberAssoc();
489
-		if($attribute === false) {
489
+		if ($attribute === false) {
490 490
 			return false;
491 491
 		}
492 492
 		$this->configuration->setConfiguration(array('ldapGroupMemberAssocAttr' => $attribute));
@@ -501,14 +501,14 @@  discard block
 block discarded – undo
501 501
 	 * @throws \Exception
502 502
 	 */
503 503
 	public function determineGroupObjectClasses() {
504
-		if(!$this->checkRequirements(array('ldapHost',
504
+		if (!$this->checkRequirements(array('ldapHost',
505 505
 										   'ldapPort',
506 506
 										   'ldapBase',
507 507
 										   ))) {
508 508
 			return  false;
509 509
 		}
510 510
 		$cr = $this->getConnection();
511
-		if(!$cr) {
511
+		if (!$cr) {
512 512
 			throw new \Exception('Could not connect to LDAP');
513 513
 		}
514 514
 
@@ -528,14 +528,14 @@  discard block
 block discarded – undo
528 528
 	 * @throws \Exception
529 529
 	 */
530 530
 	public function determineUserObjectClasses() {
531
-		if(!$this->checkRequirements(array('ldapHost',
531
+		if (!$this->checkRequirements(array('ldapHost',
532 532
 										   'ldapPort',
533 533
 										   'ldapBase',
534 534
 										   ))) {
535 535
 			return  false;
536 536
 		}
537 537
 		$cr = $this->getConnection();
538
-		if(!$cr) {
538
+		if (!$cr) {
539 539
 			throw new \Exception('Could not connect to LDAP');
540 540
 		}
541 541
 
@@ -558,7 +558,7 @@  discard block
 block discarded – undo
558 558
 	 * @throws \Exception
559 559
 	 */
560 560
 	public function getGroupFilter() {
561
-		if(!$this->checkRequirements(array('ldapHost',
561
+		if (!$this->checkRequirements(array('ldapHost',
562 562
 										   'ldapPort',
563 563
 										   'ldapBase',
564 564
 										   ))) {
@@ -582,7 +582,7 @@  discard block
 block discarded – undo
582 582
 	 * @throws \Exception
583 583
 	 */
584 584
 	public function getUserListFilter() {
585
-		if(!$this->checkRequirements(array('ldapHost',
585
+		if (!$this->checkRequirements(array('ldapHost',
586 586
 										   'ldapPort',
587 587
 										   'ldapBase',
588 588
 										   ))) {
@@ -595,7 +595,7 @@  discard block
 block discarded – undo
595 595
 			$this->applyFind('ldap_display_name', $d['ldap_display_name']);
596 596
 		}
597 597
 		$filter = $this->composeLdapFilter(self::LFILTER_USER_LIST);
598
-		if(!$filter) {
598
+		if (!$filter) {
599 599
 			throw new \Exception('Cannot create filter');
600 600
 		}
601 601
 
@@ -608,7 +608,7 @@  discard block
 block discarded – undo
608 608
 	 * @throws \Exception
609 609
 	 */
610 610
 	public function getUserLoginFilter() {
611
-		if(!$this->checkRequirements(array('ldapHost',
611
+		if (!$this->checkRequirements(array('ldapHost',
612 612
 										   'ldapPort',
613 613
 										   'ldapBase',
614 614
 										   'ldapUserFilter',
@@ -617,7 +617,7 @@  discard block
 block discarded – undo
617 617
 		}
618 618
 
619 619
 		$filter = $this->composeLdapFilter(self::LFILTER_LOGIN);
620
-		if(!$filter) {
620
+		if (!$filter) {
621 621
 			throw new \Exception('Cannot create filter');
622 622
 		}
623 623
 
@@ -631,7 +631,7 @@  discard block
 block discarded – undo
631 631
 	 * @throws \Exception
632 632
 	 */
633 633
 	public function testLoginName($loginName) {
634
-		if(!$this->checkRequirements(array('ldapHost',
634
+		if (!$this->checkRequirements(array('ldapHost',
635 635
 			'ldapPort',
636 636
 			'ldapBase',
637 637
 			'ldapLoginFilter',
@@ -640,17 +640,17 @@  discard block
 block discarded – undo
640 640
 		}
641 641
 
642 642
 		$cr = $this->access->connection->getConnectionResource();
643
-		if(!$this->ldap->isResource($cr)) {
643
+		if (!$this->ldap->isResource($cr)) {
644 644
 			throw new \Exception('connection error');
645 645
 		}
646 646
 
647
-		if(mb_strpos($this->access->connection->ldapLoginFilter, '%uid', 0, 'UTF-8')
647
+		if (mb_strpos($this->access->connection->ldapLoginFilter, '%uid', 0, 'UTF-8')
648 648
 			=== false) {
649 649
 			throw new \Exception('missing placeholder');
650 650
 		}
651 651
 
652 652
 		$users = $this->access->countUsersByLoginName($loginName);
653
-		if($this->ldap->errno($cr) !== 0) {
653
+		if ($this->ldap->errno($cr) !== 0) {
654 654
 			throw new \Exception($this->ldap->error($cr));
655 655
 		}
656 656
 		$filter = str_replace('%uid', $loginName, $this->access->connection->ldapLoginFilter);
@@ -665,22 +665,22 @@  discard block
 block discarded – undo
665 665
 	 * @throws \Exception
666 666
 	 */
667 667
 	public function guessPortAndTLS() {
668
-		if(!$this->checkRequirements(array('ldapHost',
668
+		if (!$this->checkRequirements(array('ldapHost',
669 669
 										   ))) {
670 670
 			return false;
671 671
 		}
672 672
 		$this->checkHost();
673 673
 		$portSettings = $this->getPortSettingsToTry();
674 674
 
675
-		if(!is_array($portSettings)) {
675
+		if (!is_array($portSettings)) {
676 676
 			throw new \Exception(print_r($portSettings, true));
677 677
 		}
678 678
 
679 679
 		//proceed from the best configuration and return on first success
680
-		foreach($portSettings as $setting) {
680
+		foreach ($portSettings as $setting) {
681 681
 			$p = $setting['port'];
682 682
 			$t = $setting['tls'];
683
-			\OCP\Util::writeLog('user_ldap', 'Wiz: trying port '. $p . ', TLS '. $t, ILogger::DEBUG);
683
+			\OCP\Util::writeLog('user_ldap', 'Wiz: trying port '.$p.', TLS '.$t, ILogger::DEBUG);
684 684
 			//connectAndBind may throw Exception, it needs to be catched by the
685 685
 			//callee of this method
686 686
 
@@ -690,7 +690,7 @@  discard block
 block discarded – undo
690 690
 				// any reply other than -1 (= cannot connect) is already okay,
691 691
 				// because then we found the server
692 692
 				// unavailable startTLS returns -11
693
-				if($e->getCode() > 0) {
693
+				if ($e->getCode() > 0) {
694 694
 					$settingsFound = true;
695 695
 				} else {
696 696
 					throw $e;
@@ -700,10 +700,10 @@  discard block
 block discarded – undo
700 700
 			if ($settingsFound === true) {
701 701
 				$config = array(
702 702
 					'ldapPort' => $p,
703
-					'ldapTLS' => (int)$t
703
+					'ldapTLS' => (int) $t
704 704
 				);
705 705
 				$this->configuration->setConfiguration($config);
706
-				\OCP\Util::writeLog('user_ldap', 'Wiz: detected Port ' . $p, ILogger::DEBUG);
706
+				\OCP\Util::writeLog('user_ldap', 'Wiz: detected Port '.$p, ILogger::DEBUG);
707 707
 				$this->result->addChange('ldap_port', $p);
708 708
 				return $this->result;
709 709
 			}
@@ -718,7 +718,7 @@  discard block
 block discarded – undo
718 718
 	 * @return WizardResult|false WizardResult on success, false otherwise
719 719
 	 */
720 720
 	public function guessBaseDN() {
721
-		if(!$this->checkRequirements(array('ldapHost',
721
+		if (!$this->checkRequirements(array('ldapHost',
722 722
 										   'ldapPort',
723 723
 										   ))) {
724 724
 			return false;
@@ -727,9 +727,9 @@  discard block
 block discarded – undo
727 727
 		//check whether a DN is given in the agent name (99.9% of all cases)
728 728
 		$base = null;
729 729
 		$i = stripos($this->configuration->ldapAgentName, 'dc=');
730
-		if($i !== false) {
730
+		if ($i !== false) {
731 731
 			$base = substr($this->configuration->ldapAgentName, $i);
732
-			if($this->testBaseDN($base)) {
732
+			if ($this->testBaseDN($base)) {
733 733
 				$this->applyFind('ldap_base', $base);
734 734
 				return $this->result;
735 735
 			}
@@ -740,13 +740,13 @@  discard block
 block discarded – undo
740 740
 		//a base DN
741 741
 		$helper = new Helper(\OC::$server->getConfig());
742 742
 		$domain = $helper->getDomainFromURL($this->configuration->ldapHost);
743
-		if(!$domain) {
743
+		if (!$domain) {
744 744
 			return false;
745 745
 		}
746 746
 
747 747
 		$dparts = explode('.', $domain);
748
-		while(count($dparts) > 0) {
749
-			$base2 = 'dc=' . implode(',dc=', $dparts);
748
+		while (count($dparts) > 0) {
749
+			$base2 = 'dc='.implode(',dc=', $dparts);
750 750
 			if ($base !== $base2 && $this->testBaseDN($base2)) {
751 751
 				$this->applyFind('ldap_base', $base2);
752 752
 				return $this->result;
@@ -779,7 +779,7 @@  discard block
 block discarded – undo
779 779
 		$hostInfo = parse_url($host);
780 780
 
781 781
 		//removes Port from Host
782
-		if(is_array($hostInfo) && isset($hostInfo['port'])) {
782
+		if (is_array($hostInfo) && isset($hostInfo['port'])) {
783 783
 			$port = $hostInfo['port'];
784 784
 			$host = str_replace(':'.$port, '', $host);
785 785
 			$this->applyFind('ldap_host', $host);
@@ -796,30 +796,30 @@  discard block
 block discarded – undo
796 796
 	private function detectGroupMemberAssoc() {
797 797
 		$possibleAttrs = ['uniqueMember', 'memberUid', 'member', 'gidNumber'];
798 798
 		$filter = $this->configuration->ldapGroupFilter;
799
-		if(empty($filter)) {
799
+		if (empty($filter)) {
800 800
 			return false;
801 801
 		}
802 802
 		$cr = $this->getConnection();
803
-		if(!$cr) {
803
+		if (!$cr) {
804 804
 			throw new \Exception('Could not connect to LDAP');
805 805
 		}
806 806
 		$base = $this->configuration->ldapBaseGroups[0] ?: $this->configuration->ldapBase[0];
807 807
 		$rr = $this->ldap->search($cr, $base, $filter, $possibleAttrs, 0, 1000);
808
-		if(!$this->ldap->isResource($rr)) {
808
+		if (!$this->ldap->isResource($rr)) {
809 809
 			return false;
810 810
 		}
811 811
 		$er = $this->ldap->firstEntry($cr, $rr);
812
-		while(is_resource($er)) {
812
+		while (is_resource($er)) {
813 813
 			$this->ldap->getDN($cr, $er);
814 814
 			$attrs = $this->ldap->getAttributes($cr, $er);
815 815
 			$result = [];
816 816
 			$possibleAttrsCount = count($possibleAttrs);
817
-			for($i = 0; $i < $possibleAttrsCount; $i++) {
818
-				if(isset($attrs[$possibleAttrs[$i]])) {
817
+			for ($i = 0; $i < $possibleAttrsCount; $i++) {
818
+				if (isset($attrs[$possibleAttrs[$i]])) {
819 819
 					$result[$possibleAttrs[$i]] = $attrs[$possibleAttrs[$i]]['count'];
820 820
 				}
821 821
 			}
822
-			if(!empty($result)) {
822
+			if (!empty($result)) {
823 823
 				natsort($result);
824 824
 				return key($result);
825 825
 			}
@@ -838,14 +838,14 @@  discard block
 block discarded – undo
838 838
 	 */
839 839
 	private function testBaseDN($base) {
840 840
 		$cr = $this->getConnection();
841
-		if(!$cr) {
841
+		if (!$cr) {
842 842
 			throw new \Exception('Could not connect to LDAP');
843 843
 		}
844 844
 
845 845
 		//base is there, let's validate it. If we search for anything, we should
846 846
 		//get a result set > 0 on a proper base
847 847
 		$rr = $this->ldap->search($cr, $base, 'objectClass=*', array('dn'), 0, 1);
848
-		if(!$this->ldap->isResource($rr)) {
848
+		if (!$this->ldap->isResource($rr)) {
849 849
 			$errorNo  = $this->ldap->errno($cr);
850 850
 			$errorMsg = $this->ldap->error($cr);
851 851
 			\OCP\Util::writeLog('user_ldap', 'Wiz: Could not search base '.$base.
@@ -867,11 +867,11 @@  discard block
 block discarded – undo
867 867
 	 */
868 868
 	private function testMemberOf() {
869 869
 		$cr = $this->getConnection();
870
-		if(!$cr) {
870
+		if (!$cr) {
871 871
 			throw new \Exception('Could not connect to LDAP');
872 872
 		}
873 873
 		$result = $this->access->countUsers('memberOf=*', array('memberOf'), 1);
874
-		if(is_int($result) &&  $result > 0) {
874
+		if (is_int($result) && $result > 0) {
875 875
 			return true;
876 876
 		}
877 877
 		return false;
@@ -892,27 +892,27 @@  discard block
 block discarded – undo
892 892
 			case self::LFILTER_USER_LIST:
893 893
 				$objcs = $this->configuration->ldapUserFilterObjectclass;
894 894
 				//glue objectclasses
895
-				if(is_array($objcs) && count($objcs) > 0) {
895
+				if (is_array($objcs) && count($objcs) > 0) {
896 896
 					$filter .= '(|';
897
-					foreach($objcs as $objc) {
898
-						$filter .= '(objectclass=' . $objc . ')';
897
+					foreach ($objcs as $objc) {
898
+						$filter .= '(objectclass='.$objc.')';
899 899
 					}
900 900
 					$filter .= ')';
901 901
 					$parts++;
902 902
 				}
903 903
 				//glue group memberships
904
-				if($this->configuration->hasMemberOfFilterSupport) {
904
+				if ($this->configuration->hasMemberOfFilterSupport) {
905 905
 					$cns = $this->configuration->ldapUserFilterGroups;
906
-					if(is_array($cns) && count($cns) > 0) {
906
+					if (is_array($cns) && count($cns) > 0) {
907 907
 						$filter .= '(|';
908 908
 						$cr = $this->getConnection();
909
-						if(!$cr) {
909
+						if (!$cr) {
910 910
 							throw new \Exception('Could not connect to LDAP');
911 911
 						}
912 912
 						$base = $this->configuration->ldapBase[0];
913
-						foreach($cns as $cn) {
914
-							$rr = $this->ldap->search($cr, $base, 'cn=' . $cn, array('dn', 'primaryGroupToken'));
915
-							if(!$this->ldap->isResource($rr)) {
913
+						foreach ($cns as $cn) {
914
+							$rr = $this->ldap->search($cr, $base, 'cn='.$cn, array('dn', 'primaryGroupToken'));
915
+							if (!$this->ldap->isResource($rr)) {
916 916
 								continue;
917 917
 							}
918 918
 							$er = $this->ldap->firstEntry($cr, $rr);
@@ -921,11 +921,11 @@  discard block
 block discarded – undo
921 921
 							if ($dn === false || $dn === '') {
922 922
 								continue;
923 923
 							}
924
-							$filterPart = '(memberof=' . $dn . ')';
925
-							if(isset($attrs['primaryGroupToken'])) {
924
+							$filterPart = '(memberof='.$dn.')';
925
+							if (isset($attrs['primaryGroupToken'])) {
926 926
 								$pgt = $attrs['primaryGroupToken'][0];
927
-								$primaryFilterPart = '(primaryGroupID=' . $pgt .')';
928
-								$filterPart = '(|' . $filterPart . $primaryFilterPart . ')';
927
+								$primaryFilterPart = '(primaryGroupID='.$pgt.')';
928
+								$filterPart = '(|'.$filterPart.$primaryFilterPart.')';
929 929
 							}
930 930
 							$filter .= $filterPart;
931 931
 						}
@@ -934,8 +934,8 @@  discard block
 block discarded – undo
934 934
 					$parts++;
935 935
 				}
936 936
 				//wrap parts in AND condition
937
-				if($parts > 1) {
938
-					$filter = '(&' . $filter . ')';
937
+				if ($parts > 1) {
938
+					$filter = '(&'.$filter.')';
939 939
 				}
940 940
 				if ($filter === '') {
941 941
 					$filter = '(objectclass=*)';
@@ -945,27 +945,27 @@  discard block
 block discarded – undo
945 945
 			case self::LFILTER_GROUP_LIST:
946 946
 				$objcs = $this->configuration->ldapGroupFilterObjectclass;
947 947
 				//glue objectclasses
948
-				if(is_array($objcs) && count($objcs) > 0) {
948
+				if (is_array($objcs) && count($objcs) > 0) {
949 949
 					$filter .= '(|';
950
-					foreach($objcs as $objc) {
951
-						$filter .= '(objectclass=' . $objc . ')';
950
+					foreach ($objcs as $objc) {
951
+						$filter .= '(objectclass='.$objc.')';
952 952
 					}
953 953
 					$filter .= ')';
954 954
 					$parts++;
955 955
 				}
956 956
 				//glue group memberships
957 957
 				$cns = $this->configuration->ldapGroupFilterGroups;
958
-				if(is_array($cns) && count($cns) > 0) {
958
+				if (is_array($cns) && count($cns) > 0) {
959 959
 					$filter .= '(|';
960
-					foreach($cns as $cn) {
961
-						$filter .= '(cn=' . $cn . ')';
960
+					foreach ($cns as $cn) {
961
+						$filter .= '(cn='.$cn.')';
962 962
 					}
963 963
 					$filter .= ')';
964 964
 				}
965 965
 				$parts++;
966 966
 				//wrap parts in AND condition
967
-				if($parts > 1) {
968
-					$filter = '(&' . $filter . ')';
967
+				if ($parts > 1) {
968
+					$filter = '(&'.$filter.')';
969 969
 				}
970 970
 				break;
971 971
 
@@ -977,47 +977,47 @@  discard block
 block discarded – undo
977 977
 				$userAttributes = array_change_key_case(array_flip($userAttributes));
978 978
 				$parts = 0;
979 979
 
980
-				if($this->configuration->ldapLoginFilterUsername === '1') {
980
+				if ($this->configuration->ldapLoginFilterUsername === '1') {
981 981
 					$attr = '';
982
-					if(isset($userAttributes['uid'])) {
982
+					if (isset($userAttributes['uid'])) {
983 983
 						$attr = 'uid';
984
-					} else if(isset($userAttributes['samaccountname'])) {
984
+					} else if (isset($userAttributes['samaccountname'])) {
985 985
 						$attr = 'samaccountname';
986
-					} else if(isset($userAttributes['cn'])) {
986
+					} else if (isset($userAttributes['cn'])) {
987 987
 						//fallback
988 988
 						$attr = 'cn';
989 989
 					}
990 990
 					if ($attr !== '') {
991
-						$filterUsername = '(' . $attr . $loginpart . ')';
991
+						$filterUsername = '('.$attr.$loginpart.')';
992 992
 						$parts++;
993 993
 					}
994 994
 				}
995 995
 
996 996
 				$filterEmail = '';
997
-				if($this->configuration->ldapLoginFilterEmail === '1') {
997
+				if ($this->configuration->ldapLoginFilterEmail === '1') {
998 998
 					$filterEmail = '(|(mailPrimaryAddress=%uid)(mail=%uid))';
999 999
 					$parts++;
1000 1000
 				}
1001 1001
 
1002 1002
 				$filterAttributes = '';
1003 1003
 				$attrsToFilter = $this->configuration->ldapLoginFilterAttributes;
1004
-				if(is_array($attrsToFilter) && count($attrsToFilter) > 0) {
1004
+				if (is_array($attrsToFilter) && count($attrsToFilter) > 0) {
1005 1005
 					$filterAttributes = '(|';
1006
-					foreach($attrsToFilter as $attribute) {
1007
-						$filterAttributes .= '(' . $attribute . $loginpart . ')';
1006
+					foreach ($attrsToFilter as $attribute) {
1007
+						$filterAttributes .= '('.$attribute.$loginpart.')';
1008 1008
 					}
1009 1009
 					$filterAttributes .= ')';
1010 1010
 					$parts++;
1011 1011
 				}
1012 1012
 
1013 1013
 				$filterLogin = '';
1014
-				if($parts > 1) {
1014
+				if ($parts > 1) {
1015 1015
 					$filterLogin = '(|';
1016 1016
 				}
1017 1017
 				$filterLogin .= $filterUsername;
1018 1018
 				$filterLogin .= $filterEmail;
1019 1019
 				$filterLogin .= $filterAttributes;
1020
-				if($parts > 1) {
1020
+				if ($parts > 1) {
1021 1021
 					$filterLogin .= ')';
1022 1022
 				}
1023 1023
 
@@ -1042,12 +1042,12 @@  discard block
 block discarded – undo
1042 1042
 		//connect, does not really trigger any server communication
1043 1043
 		$host = $this->configuration->ldapHost;
1044 1044
 		$hostInfo = parse_url($host);
1045
-		if(!$hostInfo) {
1045
+		if (!$hostInfo) {
1046 1046
 			throw new \Exception(self::$l->t('Invalid Host'));
1047 1047
 		}
1048 1048
 		\OCP\Util::writeLog('user_ldap', 'Wiz: Attempting to connect ', ILogger::DEBUG);
1049 1049
 		$cr = $this->ldap->connect($host, $port);
1050
-		if(!is_resource($cr)) {
1050
+		if (!is_resource($cr)) {
1051 1051
 			throw new \Exception(self::$l->t('Invalid Host'));
1052 1052
 		}
1053 1053
 
@@ -1057,9 +1057,9 @@  discard block
 block discarded – undo
1057 1057
 		$this->ldap->setOption($cr, LDAP_OPT_NETWORK_TIMEOUT, self::LDAP_NW_TIMEOUT);
1058 1058
 
1059 1059
 		try {
1060
-			if($tls) {
1060
+			if ($tls) {
1061 1061
 				$isTlsWorking = @$this->ldap->startTls($cr);
1062
-				if(!$isTlsWorking) {
1062
+				if (!$isTlsWorking) {
1063 1063
 					return false;
1064 1064
 				}
1065 1065
 			}
@@ -1073,17 +1073,17 @@  discard block
 block discarded – undo
1073 1073
 			$errNo = $this->ldap->errno($cr);
1074 1074
 			$error = ldap_error($cr);
1075 1075
 			$this->ldap->unbind($cr);
1076
-		} catch(ServerNotAvailableException $e) {
1076
+		} catch (ServerNotAvailableException $e) {
1077 1077
 			return false;
1078 1078
 		}
1079 1079
 
1080
-		if($login === true) {
1080
+		if ($login === true) {
1081 1081
 			$this->ldap->unbind($cr);
1082
-			\OCP\Util::writeLog('user_ldap', 'Wiz: Bind successful to Port '. $port . ' TLS ' . (int)$tls, ILogger::DEBUG);
1082
+			\OCP\Util::writeLog('user_ldap', 'Wiz: Bind successful to Port '.$port.' TLS '.(int) $tls, ILogger::DEBUG);
1083 1083
 			return true;
1084 1084
 		}
1085 1085
 
1086
-		if($errNo === -1) {
1086
+		if ($errNo === -1) {
1087 1087
 			//host, port or TLS wrong
1088 1088
 			return false;
1089 1089
 		}
@@ -1111,9 +1111,9 @@  discard block
 block discarded – undo
1111 1111
 	 */
1112 1112
 	private function checkRequirements($reqs) {
1113 1113
 		$this->checkAgentRequirements();
1114
-		foreach($reqs as $option) {
1114
+		foreach ($reqs as $option) {
1115 1115
 			$value = $this->configuration->$option;
1116
-			if(empty($value)) {
1116
+			if (empty($value)) {
1117 1117
 				return false;
1118 1118
 			}
1119 1119
 		}
@@ -1135,33 +1135,33 @@  discard block
 block discarded – undo
1135 1135
 		$dnRead = array();
1136 1136
 		$foundItems = array();
1137 1137
 		$maxEntries = 0;
1138
-		if(!is_array($this->configuration->ldapBase)
1138
+		if (!is_array($this->configuration->ldapBase)
1139 1139
 		   || !isset($this->configuration->ldapBase[0])) {
1140 1140
 			return false;
1141 1141
 		}
1142 1142
 		$base = $this->configuration->ldapBase[0];
1143 1143
 		$cr = $this->getConnection();
1144
-		if(!$this->ldap->isResource($cr)) {
1144
+		if (!$this->ldap->isResource($cr)) {
1145 1145
 			return false;
1146 1146
 		}
1147 1147
 		$lastFilter = null;
1148
-		if(isset($filters[count($filters)-1])) {
1149
-			$lastFilter = $filters[count($filters)-1];
1148
+		if (isset($filters[count($filters) - 1])) {
1149
+			$lastFilter = $filters[count($filters) - 1];
1150 1150
 		}
1151
-		foreach($filters as $filter) {
1152
-			if($lastFilter === $filter && count($foundItems) > 0) {
1151
+		foreach ($filters as $filter) {
1152
+			if ($lastFilter === $filter && count($foundItems) > 0) {
1153 1153
 				//skip when the filter is a wildcard and results were found
1154 1154
 				continue;
1155 1155
 			}
1156 1156
 			// 20k limit for performance and reason
1157 1157
 			$rr = $this->ldap->search($cr, $base, $filter, array($attr), 0, 20000);
1158
-			if(!$this->ldap->isResource($rr)) {
1158
+			if (!$this->ldap->isResource($rr)) {
1159 1159
 				continue;
1160 1160
 			}
1161 1161
 			$entries = $this->ldap->countEntries($cr, $rr);
1162 1162
 			$getEntryFunc = 'firstEntry';
1163
-			if(($entries !== false) && ($entries > 0)) {
1164
-				if(!is_null($maxF) && $entries > $maxEntries) {
1163
+			if (($entries !== false) && ($entries > 0)) {
1164
+				if (!is_null($maxF) && $entries > $maxEntries) {
1165 1165
 					$maxEntries = $entries;
1166 1166
 					$maxF = $filter;
1167 1167
 				}
@@ -1169,13 +1169,13 @@  discard block
 block discarded – undo
1169 1169
 				do {
1170 1170
 					$entry = $this->ldap->$getEntryFunc($cr, $rr);
1171 1171
 					$getEntryFunc = 'nextEntry';
1172
-					if(!$this->ldap->isResource($entry)) {
1172
+					if (!$this->ldap->isResource($entry)) {
1173 1173
 						continue 2;
1174 1174
 					}
1175 1175
 					$rr = $entry; //will be expected by nextEntry next round
1176 1176
 					$attributes = $this->ldap->getAttributes($cr, $entry);
1177 1177
 					$dn = $this->ldap->getDN($cr, $entry);
1178
-					if($dn === false || in_array($dn, $dnRead)) {
1178
+					if ($dn === false || in_array($dn, $dnRead)) {
1179 1179
 						continue;
1180 1180
 					}
1181 1181
 					$newItems = array();
@@ -1186,7 +1186,7 @@  discard block
 block discarded – undo
1186 1186
 					$foundItems = array_merge($foundItems, $newItems);
1187 1187
 					$this->resultCache[$dn][$attr] = $newItems;
1188 1188
 					$dnRead[] = $dn;
1189
-				} while(($state === self::LRESULT_PROCESSED_SKIP
1189
+				} while (($state === self::LRESULT_PROCESSED_SKIP
1190 1190
 						|| $this->ldap->isResource($entry))
1191 1191
 						&& ($dnReadLimit === 0 || $dnReadCount < $dnReadLimit));
1192 1192
 			}
@@ -1209,11 +1209,11 @@  discard block
 block discarded – undo
1209 1209
 	 */
1210 1210
 	private function determineFeature($objectclasses, $attr, $dbkey, $confkey, $po = false) {
1211 1211
 		$cr = $this->getConnection();
1212
-		if(!$cr) {
1212
+		if (!$cr) {
1213 1213
 			throw new \Exception('Could not connect to LDAP');
1214 1214
 		}
1215 1215
 		$p = 'objectclass=';
1216
-		foreach($objectclasses as $key => $value) {
1216
+		foreach ($objectclasses as $key => $value) {
1217 1217
 			$objectclasses[$key] = $p.$value;
1218 1218
 		}
1219 1219
 		$maxEntryObjC = '';
@@ -1225,7 +1225,7 @@  discard block
 block discarded – undo
1225 1225
 		$availableFeatures =
1226 1226
 			$this->cumulativeSearchOnAttribute($objectclasses, $attr,
1227 1227
 											   $dig, $maxEntryObjC);
1228
-		if(is_array($availableFeatures)
1228
+		if (is_array($availableFeatures)
1229 1229
 		   && count($availableFeatures) > 0) {
1230 1230
 			natcasesort($availableFeatures);
1231 1231
 			//natcasesort keeps indices, but we must get rid of them for proper
@@ -1236,7 +1236,7 @@  discard block
 block discarded – undo
1236 1236
 		}
1237 1237
 
1238 1238
 		$setFeatures = $this->configuration->$confkey;
1239
-		if(is_array($setFeatures) && !empty($setFeatures)) {
1239
+		if (is_array($setFeatures) && !empty($setFeatures)) {
1240 1240
 			//something is already configured? pre-select it.
1241 1241
 			$this->result->addChange($dbkey, $setFeatures);
1242 1242
 		} else if ($po && $maxEntryObjC !== '') {
@@ -1258,7 +1258,7 @@  discard block
 block discarded – undo
1258 1258
 	 * LRESULT_PROCESSED_INVALID or LRESULT_PROCESSED_SKIP
1259 1259
 	 */
1260 1260
 	private function getAttributeValuesFromEntry($result, $attribute, &$known) {
1261
-		if(!is_array($result)
1261
+		if (!is_array($result)
1262 1262
 		   || !isset($result['count'])
1263 1263
 		   || !$result['count'] > 0) {
1264 1264
 			return self::LRESULT_PROCESSED_INVALID;
@@ -1267,12 +1267,12 @@  discard block
 block discarded – undo
1267 1267
 		// strtolower on all keys for proper comparison
1268 1268
 		$result = \OCP\Util::mb_array_change_key_case($result);
1269 1269
 		$attribute = strtolower($attribute);
1270
-		if(isset($result[$attribute])) {
1271
-			foreach($result[$attribute] as $key => $val) {
1272
-				if($key === 'count') {
1270
+		if (isset($result[$attribute])) {
1271
+			foreach ($result[$attribute] as $key => $val) {
1272
+				if ($key === 'count') {
1273 1273
 					continue;
1274 1274
 				}
1275
-				if(!in_array($val, $known)) {
1275
+				if (!in_array($val, $known)) {
1276 1276
 					$known[] = $val;
1277 1277
 				}
1278 1278
 			}
@@ -1286,7 +1286,7 @@  discard block
 block discarded – undo
1286 1286
 	 * @return bool|mixed
1287 1287
 	 */
1288 1288
 	private function getConnection() {
1289
-		if(!is_null($this->cr)) {
1289
+		if (!is_null($this->cr)) {
1290 1290
 			return $this->cr;
1291 1291
 		}
1292 1292
 
@@ -1298,14 +1298,14 @@  discard block
 block discarded – undo
1298 1298
 		$this->ldap->setOption($cr, LDAP_OPT_PROTOCOL_VERSION, 3);
1299 1299
 		$this->ldap->setOption($cr, LDAP_OPT_REFERRALS, 0);
1300 1300
 		$this->ldap->setOption($cr, LDAP_OPT_NETWORK_TIMEOUT, self::LDAP_NW_TIMEOUT);
1301
-		if($this->configuration->ldapTLS === 1) {
1301
+		if ($this->configuration->ldapTLS === 1) {
1302 1302
 			$this->ldap->startTls($cr);
1303 1303
 		}
1304 1304
 
1305 1305
 		$lo = @$this->ldap->bind($cr,
1306 1306
 								 $this->configuration->ldapAgentName,
1307 1307
 								 $this->configuration->ldapAgentPassword);
1308
-		if($lo === true) {
1308
+		if ($lo === true) {
1309 1309
 			$this->$cr = $cr;
1310 1310
 			return $cr;
1311 1311
 		}
@@ -1336,18 +1336,18 @@  discard block
 block discarded – undo
1336 1336
 		//636 ← LDAPS / SSL
1337 1337
 		//7xxx ← UCS. need to be checked first, because both ports may be open
1338 1338
 		$host = $this->configuration->ldapHost;
1339
-		$port = (int)$this->configuration->ldapPort;
1339
+		$port = (int) $this->configuration->ldapPort;
1340 1340
 		$portSettings = array();
1341 1341
 
1342 1342
 		//In case the port is already provided, we will check this first
1343
-		if($port > 0) {
1343
+		if ($port > 0) {
1344 1344
 			$hostInfo = parse_url($host);
1345
-			if(!(is_array($hostInfo)
1345
+			if (!(is_array($hostInfo)
1346 1346
 				&& isset($hostInfo['scheme'])
1347 1347
 				&& stripos($hostInfo['scheme'], 'ldaps') !== false)) {
1348 1348
 				$portSettings[] = array('port' => $port, 'tls' => true);
1349 1349
 			}
1350
-			$portSettings[] =array('port' => $port, 'tls' => false);
1350
+			$portSettings[] = array('port' => $port, 'tls' => false);
1351 1351
 		}
1352 1352
 
1353 1353
 		//default ports
Please login to merge, or discard this patch.
apps/user_ldap/lib/Configuration.php 1 patch
Indentation   +510 added lines, -510 removed lines patch added patch discarded remove patch
@@ -38,543 +38,543 @@
 block discarded – undo
38 38
  * @property string ldapUserAvatarRule
39 39
  */
40 40
 class Configuration {
41
-	const AVATAR_PREFIX_DEFAULT = 'default';
42
-	const AVATAR_PREFIX_NONE = 'none';
43
-	const AVATAR_PREFIX_DATA_ATTRIBUTE = 'data:';
41
+    const AVATAR_PREFIX_DEFAULT = 'default';
42
+    const AVATAR_PREFIX_NONE = 'none';
43
+    const AVATAR_PREFIX_DATA_ATTRIBUTE = 'data:';
44 44
 
45
-	protected $configPrefix = null;
46
-	protected $configRead = false;
47
-	/**
48
-	 * @var string[] pre-filled with one reference key so that at least one entry is written on save request and
49
-	 *               the config ID is registered
50
-	 */
51
-	protected $unsavedChanges = ['ldapConfigurationActive' => 'ldapConfigurationActive'];
45
+    protected $configPrefix = null;
46
+    protected $configRead = false;
47
+    /**
48
+     * @var string[] pre-filled with one reference key so that at least one entry is written on save request and
49
+     *               the config ID is registered
50
+     */
51
+    protected $unsavedChanges = ['ldapConfigurationActive' => 'ldapConfigurationActive'];
52 52
 
53
-	//settings
54
-	protected $config = array(
55
-		'ldapHost' => null,
56
-		'ldapPort' => null,
57
-		'ldapBackupHost' => null,
58
-		'ldapBackupPort' => null,
59
-		'ldapBase' => null,
60
-		'ldapBaseUsers' => null,
61
-		'ldapBaseGroups' => null,
62
-		'ldapAgentName' => null,
63
-		'ldapAgentPassword' => null,
64
-		'ldapTLS' => null,
65
-		'turnOffCertCheck' => null,
66
-		'ldapIgnoreNamingRules' => null,
67
-		'ldapUserDisplayName' => null,
68
-		'ldapUserDisplayName2' => null,
69
-		'ldapUserAvatarRule' => null,
70
-		'ldapGidNumber' => null,
71
-		'ldapUserFilterObjectclass' => null,
72
-		'ldapUserFilterGroups' => null,
73
-		'ldapUserFilter' => null,
74
-		'ldapUserFilterMode' => null,
75
-		'ldapGroupFilter' => null,
76
-		'ldapGroupFilterMode' => null,
77
-		'ldapGroupFilterObjectclass' => null,
78
-		'ldapGroupFilterGroups' => null,
79
-		'ldapGroupDisplayName' => null,
80
-		'ldapGroupMemberAssocAttr' => null,
81
-		'ldapLoginFilter' => null,
82
-		'ldapLoginFilterMode' => null,
83
-		'ldapLoginFilterEmail' => null,
84
-		'ldapLoginFilterUsername' => null,
85
-		'ldapLoginFilterAttributes' => null,
86
-		'ldapQuotaAttribute' => null,
87
-		'ldapQuotaDefault' => null,
88
-		'ldapEmailAttribute' => null,
89
-		'ldapCacheTTL' => null,
90
-		'ldapUuidUserAttribute' => 'auto',
91
-		'ldapUuidGroupAttribute' => 'auto',
92
-		'ldapOverrideMainServer' => false,
93
-		'ldapConfigurationActive' => false,
94
-		'ldapAttributesForUserSearch' => null,
95
-		'ldapAttributesForGroupSearch' => null,
96
-		'ldapExperiencedAdmin' => false,
97
-		'homeFolderNamingRule' => null,
98
-		'hasMemberOfFilterSupport' => false,
99
-		'useMemberOfToDetectMembership' => true,
100
-		'ldapExpertUsernameAttr' => null,
101
-		'ldapExpertUUIDUserAttr' => null,
102
-		'ldapExpertUUIDGroupAttr' => null,
103
-		'lastJpegPhotoLookup' => null,
104
-		'ldapNestedGroups' => false,
105
-		'ldapPagingSize' => null,
106
-		'turnOnPasswordChange' => false,
107
-		'ldapDynamicGroupMemberURL' => null,
108
-		'ldapDefaultPPolicyDN' => null,
109
-		'ldapExtStorageHomeAttribute' => null,
110
-	);
53
+    //settings
54
+    protected $config = array(
55
+        'ldapHost' => null,
56
+        'ldapPort' => null,
57
+        'ldapBackupHost' => null,
58
+        'ldapBackupPort' => null,
59
+        'ldapBase' => null,
60
+        'ldapBaseUsers' => null,
61
+        'ldapBaseGroups' => null,
62
+        'ldapAgentName' => null,
63
+        'ldapAgentPassword' => null,
64
+        'ldapTLS' => null,
65
+        'turnOffCertCheck' => null,
66
+        'ldapIgnoreNamingRules' => null,
67
+        'ldapUserDisplayName' => null,
68
+        'ldapUserDisplayName2' => null,
69
+        'ldapUserAvatarRule' => null,
70
+        'ldapGidNumber' => null,
71
+        'ldapUserFilterObjectclass' => null,
72
+        'ldapUserFilterGroups' => null,
73
+        'ldapUserFilter' => null,
74
+        'ldapUserFilterMode' => null,
75
+        'ldapGroupFilter' => null,
76
+        'ldapGroupFilterMode' => null,
77
+        'ldapGroupFilterObjectclass' => null,
78
+        'ldapGroupFilterGroups' => null,
79
+        'ldapGroupDisplayName' => null,
80
+        'ldapGroupMemberAssocAttr' => null,
81
+        'ldapLoginFilter' => null,
82
+        'ldapLoginFilterMode' => null,
83
+        'ldapLoginFilterEmail' => null,
84
+        'ldapLoginFilterUsername' => null,
85
+        'ldapLoginFilterAttributes' => null,
86
+        'ldapQuotaAttribute' => null,
87
+        'ldapQuotaDefault' => null,
88
+        'ldapEmailAttribute' => null,
89
+        'ldapCacheTTL' => null,
90
+        'ldapUuidUserAttribute' => 'auto',
91
+        'ldapUuidGroupAttribute' => 'auto',
92
+        'ldapOverrideMainServer' => false,
93
+        'ldapConfigurationActive' => false,
94
+        'ldapAttributesForUserSearch' => null,
95
+        'ldapAttributesForGroupSearch' => null,
96
+        'ldapExperiencedAdmin' => false,
97
+        'homeFolderNamingRule' => null,
98
+        'hasMemberOfFilterSupport' => false,
99
+        'useMemberOfToDetectMembership' => true,
100
+        'ldapExpertUsernameAttr' => null,
101
+        'ldapExpertUUIDUserAttr' => null,
102
+        'ldapExpertUUIDGroupAttr' => null,
103
+        'lastJpegPhotoLookup' => null,
104
+        'ldapNestedGroups' => false,
105
+        'ldapPagingSize' => null,
106
+        'turnOnPasswordChange' => false,
107
+        'ldapDynamicGroupMemberURL' => null,
108
+        'ldapDefaultPPolicyDN' => null,
109
+        'ldapExtStorageHomeAttribute' => null,
110
+    );
111 111
 
112
-	/**
113
-	 * @param string $configPrefix
114
-	 * @param bool $autoRead
115
-	 */
116
-	public function __construct($configPrefix, $autoRead = true) {
117
-		$this->configPrefix = $configPrefix;
118
-		if($autoRead) {
119
-			$this->readConfiguration();
120
-		}
121
-	}
112
+    /**
113
+     * @param string $configPrefix
114
+     * @param bool $autoRead
115
+     */
116
+    public function __construct($configPrefix, $autoRead = true) {
117
+        $this->configPrefix = $configPrefix;
118
+        if($autoRead) {
119
+            $this->readConfiguration();
120
+        }
121
+    }
122 122
 
123
-	/**
124
-	 * @param string $name
125
-	 * @return mixed|null
126
-	 */
127
-	public function __get($name) {
128
-		if(isset($this->config[$name])) {
129
-			return $this->config[$name];
130
-		}
131
-		return null;
132
-	}
123
+    /**
124
+     * @param string $name
125
+     * @return mixed|null
126
+     */
127
+    public function __get($name) {
128
+        if(isset($this->config[$name])) {
129
+            return $this->config[$name];
130
+        }
131
+        return null;
132
+    }
133 133
 
134
-	/**
135
-	 * @param string $name
136
-	 * @param mixed $value
137
-	 */
138
-	public function __set($name, $value) {
139
-		$this->setConfiguration(array($name => $value));
140
-	}
134
+    /**
135
+     * @param string $name
136
+     * @param mixed $value
137
+     */
138
+    public function __set($name, $value) {
139
+        $this->setConfiguration(array($name => $value));
140
+    }
141 141
 
142
-	/**
143
-	 * @return array
144
-	 */
145
-	public function getConfiguration() {
146
-		return $this->config;
147
-	}
142
+    /**
143
+     * @return array
144
+     */
145
+    public function getConfiguration() {
146
+        return $this->config;
147
+    }
148 148
 
149
-	/**
150
-	 * set LDAP configuration with values delivered by an array, not read
151
-	 * from configuration. It does not save the configuration! To do so, you
152
-	 * must call saveConfiguration afterwards.
153
-	 * @param array $config array that holds the config parameters in an associated
154
-	 * array
155
-	 * @param array &$applied optional; array where the set fields will be given to
156
-	 * @return false|null
157
-	 */
158
-	public function setConfiguration($config, &$applied = null) {
159
-		if(!is_array($config)) {
160
-			return false;
161
-		}
149
+    /**
150
+     * set LDAP configuration with values delivered by an array, not read
151
+     * from configuration. It does not save the configuration! To do so, you
152
+     * must call saveConfiguration afterwards.
153
+     * @param array $config array that holds the config parameters in an associated
154
+     * array
155
+     * @param array &$applied optional; array where the set fields will be given to
156
+     * @return false|null
157
+     */
158
+    public function setConfiguration($config, &$applied = null) {
159
+        if(!is_array($config)) {
160
+            return false;
161
+        }
162 162
 
163
-		$cta = $this->getConfigTranslationArray();
164
-		foreach($config as $inputKey => $val) {
165
-			if(strpos($inputKey, '_') !== false && array_key_exists($inputKey, $cta)) {
166
-				$key = $cta[$inputKey];
167
-			} elseif(array_key_exists($inputKey, $this->config)) {
168
-				$key = $inputKey;
169
-			} else {
170
-				continue;
171
-			}
163
+        $cta = $this->getConfigTranslationArray();
164
+        foreach($config as $inputKey => $val) {
165
+            if(strpos($inputKey, '_') !== false && array_key_exists($inputKey, $cta)) {
166
+                $key = $cta[$inputKey];
167
+            } elseif(array_key_exists($inputKey, $this->config)) {
168
+                $key = $inputKey;
169
+            } else {
170
+                continue;
171
+            }
172 172
 
173
-			$setMethod = 'setValue';
174
-			switch($key) {
175
-				case 'ldapAgentPassword':
176
-					$setMethod = 'setRawValue';
177
-					break;
178
-				case 'homeFolderNamingRule':
179
-					$trimmedVal = trim($val);
180
-					if ($trimmedVal !== '' && strpos($val, 'attr:') === false) {
181
-						$val = 'attr:'.$trimmedVal;
182
-					}
183
-					break;
184
-				case 'ldapBase':
185
-				case 'ldapBaseUsers':
186
-				case 'ldapBaseGroups':
187
-				case 'ldapAttributesForUserSearch':
188
-				case 'ldapAttributesForGroupSearch':
189
-				case 'ldapUserFilterObjectclass':
190
-				case 'ldapUserFilterGroups':
191
-				case 'ldapGroupFilterObjectclass':
192
-				case 'ldapGroupFilterGroups':
193
-				case 'ldapLoginFilterAttributes':
194
-					$setMethod = 'setMultiLine';
195
-					break;
196
-			}
197
-			$this->$setMethod($key, $val);
198
-			if(is_array($applied)) {
199
-				$applied[] = $inputKey;
200
-				// storing key as index avoids duplication, and as value for simplicity
201
-			}
202
-			$this->unsavedChanges[$key] = $key;
203
-		}
204
-		return null;
205
-	}
173
+            $setMethod = 'setValue';
174
+            switch($key) {
175
+                case 'ldapAgentPassword':
176
+                    $setMethod = 'setRawValue';
177
+                    break;
178
+                case 'homeFolderNamingRule':
179
+                    $trimmedVal = trim($val);
180
+                    if ($trimmedVal !== '' && strpos($val, 'attr:') === false) {
181
+                        $val = 'attr:'.$trimmedVal;
182
+                    }
183
+                    break;
184
+                case 'ldapBase':
185
+                case 'ldapBaseUsers':
186
+                case 'ldapBaseGroups':
187
+                case 'ldapAttributesForUserSearch':
188
+                case 'ldapAttributesForGroupSearch':
189
+                case 'ldapUserFilterObjectclass':
190
+                case 'ldapUserFilterGroups':
191
+                case 'ldapGroupFilterObjectclass':
192
+                case 'ldapGroupFilterGroups':
193
+                case 'ldapLoginFilterAttributes':
194
+                    $setMethod = 'setMultiLine';
195
+                    break;
196
+            }
197
+            $this->$setMethod($key, $val);
198
+            if(is_array($applied)) {
199
+                $applied[] = $inputKey;
200
+                // storing key as index avoids duplication, and as value for simplicity
201
+            }
202
+            $this->unsavedChanges[$key] = $key;
203
+        }
204
+        return null;
205
+    }
206 206
 
207
-	public function readConfiguration() {
208
-		if(!$this->configRead && !is_null($this->configPrefix)) {
209
-			$cta = array_flip($this->getConfigTranslationArray());
210
-			foreach($this->config as $key => $val) {
211
-				if(!isset($cta[$key])) {
212
-					//some are determined
213
-					continue;
214
-				}
215
-				$dbKey = $cta[$key];
216
-				switch($key) {
217
-					case 'ldapBase':
218
-					case 'ldapBaseUsers':
219
-					case 'ldapBaseGroups':
220
-					case 'ldapAttributesForUserSearch':
221
-					case 'ldapAttributesForGroupSearch':
222
-					case 'ldapUserFilterObjectclass':
223
-					case 'ldapUserFilterGroups':
224
-					case 'ldapGroupFilterObjectclass':
225
-					case 'ldapGroupFilterGroups':
226
-					case 'ldapLoginFilterAttributes':
227
-						$readMethod = 'getMultiLine';
228
-						break;
229
-					case 'ldapIgnoreNamingRules':
230
-						$readMethod = 'getSystemValue';
231
-						$dbKey = $key;
232
-						break;
233
-					case 'ldapAgentPassword':
234
-						$readMethod = 'getPwd';
235
-						break;
236
-					case 'ldapUserDisplayName2':
237
-					case 'ldapGroupDisplayName':
238
-						$readMethod = 'getLcValue';
239
-						break;
240
-					case 'ldapUserDisplayName':
241
-					default:
242
-						// user display name does not lower case because
243
-						// we rely on an upper case N as indicator whether to
244
-						// auto-detect it or not. FIXME
245
-						$readMethod = 'getValue';
246
-						break;
247
-				}
248
-				$this->config[$key] = $this->$readMethod($dbKey);
249
-			}
250
-			$this->configRead = true;
251
-		}
252
-	}
207
+    public function readConfiguration() {
208
+        if(!$this->configRead && !is_null($this->configPrefix)) {
209
+            $cta = array_flip($this->getConfigTranslationArray());
210
+            foreach($this->config as $key => $val) {
211
+                if(!isset($cta[$key])) {
212
+                    //some are determined
213
+                    continue;
214
+                }
215
+                $dbKey = $cta[$key];
216
+                switch($key) {
217
+                    case 'ldapBase':
218
+                    case 'ldapBaseUsers':
219
+                    case 'ldapBaseGroups':
220
+                    case 'ldapAttributesForUserSearch':
221
+                    case 'ldapAttributesForGroupSearch':
222
+                    case 'ldapUserFilterObjectclass':
223
+                    case 'ldapUserFilterGroups':
224
+                    case 'ldapGroupFilterObjectclass':
225
+                    case 'ldapGroupFilterGroups':
226
+                    case 'ldapLoginFilterAttributes':
227
+                        $readMethod = 'getMultiLine';
228
+                        break;
229
+                    case 'ldapIgnoreNamingRules':
230
+                        $readMethod = 'getSystemValue';
231
+                        $dbKey = $key;
232
+                        break;
233
+                    case 'ldapAgentPassword':
234
+                        $readMethod = 'getPwd';
235
+                        break;
236
+                    case 'ldapUserDisplayName2':
237
+                    case 'ldapGroupDisplayName':
238
+                        $readMethod = 'getLcValue';
239
+                        break;
240
+                    case 'ldapUserDisplayName':
241
+                    default:
242
+                        // user display name does not lower case because
243
+                        // we rely on an upper case N as indicator whether to
244
+                        // auto-detect it or not. FIXME
245
+                        $readMethod = 'getValue';
246
+                        break;
247
+                }
248
+                $this->config[$key] = $this->$readMethod($dbKey);
249
+            }
250
+            $this->configRead = true;
251
+        }
252
+    }
253 253
 
254
-	/**
255
-	 * saves the current config changes in the database
256
-	 */
257
-	public function saveConfiguration() {
258
-		$cta = array_flip($this->getConfigTranslationArray());
259
-		foreach($this->unsavedChanges as $key) {
260
-			$value = $this->config[$key];
261
-			switch ($key) {
262
-				case 'ldapAgentPassword':
263
-					$value = base64_encode($value);
264
-					break;
265
-				case 'ldapBase':
266
-				case 'ldapBaseUsers':
267
-				case 'ldapBaseGroups':
268
-				case 'ldapAttributesForUserSearch':
269
-				case 'ldapAttributesForGroupSearch':
270
-				case 'ldapUserFilterObjectclass':
271
-				case 'ldapUserFilterGroups':
272
-				case 'ldapGroupFilterObjectclass':
273
-				case 'ldapGroupFilterGroups':
274
-				case 'ldapLoginFilterAttributes':
275
-					if(is_array($value)) {
276
-						$value = implode("\n", $value);
277
-					}
278
-					break;
279
-				//following options are not stored but detected, skip them
280
-				case 'ldapIgnoreNamingRules':
281
-				case 'ldapUuidUserAttribute':
282
-				case 'ldapUuidGroupAttribute':
283
-					continue 2;
284
-			}
285
-			if(is_null($value)) {
286
-				$value = '';
287
-			}
288
-			$this->saveValue($cta[$key], $value);
289
-		}
290
-		$this->saveValue('_lastChange', time());
291
-		$this->unsavedChanges = [];
292
-	}
254
+    /**
255
+     * saves the current config changes in the database
256
+     */
257
+    public function saveConfiguration() {
258
+        $cta = array_flip($this->getConfigTranslationArray());
259
+        foreach($this->unsavedChanges as $key) {
260
+            $value = $this->config[$key];
261
+            switch ($key) {
262
+                case 'ldapAgentPassword':
263
+                    $value = base64_encode($value);
264
+                    break;
265
+                case 'ldapBase':
266
+                case 'ldapBaseUsers':
267
+                case 'ldapBaseGroups':
268
+                case 'ldapAttributesForUserSearch':
269
+                case 'ldapAttributesForGroupSearch':
270
+                case 'ldapUserFilterObjectclass':
271
+                case 'ldapUserFilterGroups':
272
+                case 'ldapGroupFilterObjectclass':
273
+                case 'ldapGroupFilterGroups':
274
+                case 'ldapLoginFilterAttributes':
275
+                    if(is_array($value)) {
276
+                        $value = implode("\n", $value);
277
+                    }
278
+                    break;
279
+                //following options are not stored but detected, skip them
280
+                case 'ldapIgnoreNamingRules':
281
+                case 'ldapUuidUserAttribute':
282
+                case 'ldapUuidGroupAttribute':
283
+                    continue 2;
284
+            }
285
+            if(is_null($value)) {
286
+                $value = '';
287
+            }
288
+            $this->saveValue($cta[$key], $value);
289
+        }
290
+        $this->saveValue('_lastChange', time());
291
+        $this->unsavedChanges = [];
292
+    }
293 293
 
294
-	/**
295
-	 * @param string $varName
296
-	 * @return array|string
297
-	 */
298
-	protected function getMultiLine($varName) {
299
-		$value = $this->getValue($varName);
300
-		if(empty($value)) {
301
-			$value = '';
302
-		} else {
303
-			$value = preg_split('/\r\n|\r|\n/', $value);
304
-		}
294
+    /**
295
+     * @param string $varName
296
+     * @return array|string
297
+     */
298
+    protected function getMultiLine($varName) {
299
+        $value = $this->getValue($varName);
300
+        if(empty($value)) {
301
+            $value = '';
302
+        } else {
303
+            $value = preg_split('/\r\n|\r|\n/', $value);
304
+        }
305 305
 
306
-		return $value;
307
-	}
306
+        return $value;
307
+    }
308 308
 
309
-	/**
310
-	 * Sets multi-line values as arrays
311
-	 * 
312
-	 * @param string $varName name of config-key
313
-	 * @param array|string $value to set
314
-	 */
315
-	protected function setMultiLine($varName, $value) {
316
-		if(empty($value)) {
317
-			$value = '';
318
-		} else if (!is_array($value)) {
319
-			$value = preg_split('/\r\n|\r|\n|;/', $value);
320
-			if($value === false) {
321
-				$value = '';
322
-			}
323
-		}
309
+    /**
310
+     * Sets multi-line values as arrays
311
+     * 
312
+     * @param string $varName name of config-key
313
+     * @param array|string $value to set
314
+     */
315
+    protected function setMultiLine($varName, $value) {
316
+        if(empty($value)) {
317
+            $value = '';
318
+        } else if (!is_array($value)) {
319
+            $value = preg_split('/\r\n|\r|\n|;/', $value);
320
+            if($value === false) {
321
+                $value = '';
322
+            }
323
+        }
324 324
 
325
-		if(!is_array($value)) {
326
-			$finalValue = trim($value);
327
-		} else {
328
-			$finalValue = [];
329
-			foreach($value as $key => $val) {
330
-				if(is_string($val)) {
331
-					$val = trim($val);
332
-					if ($val !== '') {
333
-						//accidental line breaks are not wanted and can cause
334
-						// odd behaviour. Thus, away with them.
335
-						$finalValue[] = $val;
336
-					}
337
-				} else {
338
-					$finalValue[] = $val;
339
-				}
340
-			}
341
-		}
325
+        if(!is_array($value)) {
326
+            $finalValue = trim($value);
327
+        } else {
328
+            $finalValue = [];
329
+            foreach($value as $key => $val) {
330
+                if(is_string($val)) {
331
+                    $val = trim($val);
332
+                    if ($val !== '') {
333
+                        //accidental line breaks are not wanted and can cause
334
+                        // odd behaviour. Thus, away with them.
335
+                        $finalValue[] = $val;
336
+                    }
337
+                } else {
338
+                    $finalValue[] = $val;
339
+                }
340
+            }
341
+        }
342 342
 
343
-		$this->setRawValue($varName, $finalValue);
344
-	}
343
+        $this->setRawValue($varName, $finalValue);
344
+    }
345 345
 
346
-	/**
347
-	 * @param string $varName
348
-	 * @return string
349
-	 */
350
-	protected function getPwd($varName) {
351
-		return base64_decode($this->getValue($varName));
352
-	}
346
+    /**
347
+     * @param string $varName
348
+     * @return string
349
+     */
350
+    protected function getPwd($varName) {
351
+        return base64_decode($this->getValue($varName));
352
+    }
353 353
 
354
-	/**
355
-	 * @param string $varName
356
-	 * @return string
357
-	 */
358
-	protected function getLcValue($varName) {
359
-		return mb_strtolower($this->getValue($varName), 'UTF-8');
360
-	}
354
+    /**
355
+     * @param string $varName
356
+     * @return string
357
+     */
358
+    protected function getLcValue($varName) {
359
+        return mb_strtolower($this->getValue($varName), 'UTF-8');
360
+    }
361 361
 
362
-	/**
363
-	 * @param string $varName
364
-	 * @return string
365
-	 */
366
-	protected function getSystemValue($varName) {
367
-		//FIXME: if another system value is added, softcode the default value
368
-		return \OC::$server->getConfig()->getSystemValue($varName, false);
369
-	}
362
+    /**
363
+     * @param string $varName
364
+     * @return string
365
+     */
366
+    protected function getSystemValue($varName) {
367
+        //FIXME: if another system value is added, softcode the default value
368
+        return \OC::$server->getConfig()->getSystemValue($varName, false);
369
+    }
370 370
 
371
-	/**
372
-	 * @param string $varName
373
-	 * @return string
374
-	 */
375
-	protected function getValue($varName) {
376
-		static $defaults;
377
-		if(is_null($defaults)) {
378
-			$defaults = $this->getDefaults();
379
-		}
380
-		return \OC::$server->getConfig()->getAppValue('user_ldap',
381
-										$this->configPrefix.$varName,
382
-										$defaults[$varName]);
383
-	}
371
+    /**
372
+     * @param string $varName
373
+     * @return string
374
+     */
375
+    protected function getValue($varName) {
376
+        static $defaults;
377
+        if(is_null($defaults)) {
378
+            $defaults = $this->getDefaults();
379
+        }
380
+        return \OC::$server->getConfig()->getAppValue('user_ldap',
381
+                                        $this->configPrefix.$varName,
382
+                                        $defaults[$varName]);
383
+    }
384 384
 
385
-	/**
386
-	 * Sets a scalar value.
387
-	 * 
388
-	 * @param string $varName name of config key
389
-	 * @param mixed $value to set
390
-	 */
391
-	protected function setValue($varName, $value) {
392
-		if(is_string($value)) {
393
-			$value = trim($value);
394
-		}
395
-		$this->config[$varName] = $value;
396
-	}
385
+    /**
386
+     * Sets a scalar value.
387
+     * 
388
+     * @param string $varName name of config key
389
+     * @param mixed $value to set
390
+     */
391
+    protected function setValue($varName, $value) {
392
+        if(is_string($value)) {
393
+            $value = trim($value);
394
+        }
395
+        $this->config[$varName] = $value;
396
+    }
397 397
 
398
-	/**
399
-	 * Sets a scalar value without trimming.
400
-	 *
401
-	 * @param string $varName name of config key
402
-	 * @param mixed $value to set
403
-	 */
404
-	protected function setRawValue($varName, $value) {
405
-		$this->config[$varName] = $value;
406
-	}
398
+    /**
399
+     * Sets a scalar value without trimming.
400
+     *
401
+     * @param string $varName name of config key
402
+     * @param mixed $value to set
403
+     */
404
+    protected function setRawValue($varName, $value) {
405
+        $this->config[$varName] = $value;
406
+    }
407 407
 
408
-	/**
409
-	 * @param string $varName
410
-	 * @param string $value
411
-	 * @return bool
412
-	 */
413
-	protected function saveValue($varName, $value) {
414
-		\OC::$server->getConfig()->setAppValue(
415
-			'user_ldap',
416
-			$this->configPrefix.$varName,
417
-			$value
418
-		);
419
-		return true;
420
-	}
408
+    /**
409
+     * @param string $varName
410
+     * @param string $value
411
+     * @return bool
412
+     */
413
+    protected function saveValue($varName, $value) {
414
+        \OC::$server->getConfig()->setAppValue(
415
+            'user_ldap',
416
+            $this->configPrefix.$varName,
417
+            $value
418
+        );
419
+        return true;
420
+    }
421 421
 
422
-	/**
423
-	 * @return array an associative array with the default values. Keys are correspond
424
-	 * to config-value entries in the database table
425
-	 */
426
-	public function getDefaults() {
427
-		return array(
428
-			'ldap_host'                         => '',
429
-			'ldap_port'                         => '',
430
-			'ldap_backup_host'                  => '',
431
-			'ldap_backup_port'                  => '',
432
-			'ldap_override_main_server'         => '',
433
-			'ldap_dn'                           => '',
434
-			'ldap_agent_password'               => '',
435
-			'ldap_base'                         => '',
436
-			'ldap_base_users'                   => '',
437
-			'ldap_base_groups'                  => '',
438
-			'ldap_userlist_filter'              => '',
439
-			'ldap_user_filter_mode'             => 0,
440
-			'ldap_userfilter_objectclass'       => '',
441
-			'ldap_userfilter_groups'            => '',
442
-			'ldap_login_filter'                 => '',
443
-			'ldap_login_filter_mode'            => 0,
444
-			'ldap_loginfilter_email'            => 0,
445
-			'ldap_loginfilter_username'         => 1,
446
-			'ldap_loginfilter_attributes'       => '',
447
-			'ldap_group_filter'                 => '',
448
-			'ldap_group_filter_mode'            => 0,
449
-			'ldap_groupfilter_objectclass'      => '',
450
-			'ldap_groupfilter_groups'           => '',
451
-			'ldap_gid_number'                   => 'gidNumber',
452
-			'ldap_display_name'                 => 'displayName',
453
-			'ldap_user_display_name_2'			=> '',
454
-			'ldap_group_display_name'           => 'cn',
455
-			'ldap_tls'                          => 0,
456
-			'ldap_quota_def'                    => '',
457
-			'ldap_quota_attr'                   => '',
458
-			'ldap_email_attr'                   => '',
459
-			'ldap_group_member_assoc_attribute' => '',
460
-			'ldap_cache_ttl'                    => 600,
461
-			'ldap_uuid_user_attribute'          => 'auto',
462
-			'ldap_uuid_group_attribute'         => 'auto',
463
-			'home_folder_naming_rule'           => '',
464
-			'ldap_turn_off_cert_check'          => 0,
465
-			'ldap_configuration_active'         => 0,
466
-			'ldap_attributes_for_user_search'   => '',
467
-			'ldap_attributes_for_group_search'  => '',
468
-			'ldap_expert_username_attr'         => '',
469
-			'ldap_expert_uuid_user_attr'        => '',
470
-			'ldap_expert_uuid_group_attr'       => '',
471
-			'has_memberof_filter_support'       => 0,
472
-			'use_memberof_to_detect_membership' => 1,
473
-			'last_jpegPhoto_lookup'             => 0,
474
-			'ldap_nested_groups'                => 0,
475
-			'ldap_paging_size'                  => 500,
476
-			'ldap_turn_on_pwd_change'           => 0,
477
-			'ldap_experienced_admin'            => 0,
478
-			'ldap_dynamic_group_member_url'     => '',
479
-			'ldap_default_ppolicy_dn'           => '',
480
-			'ldap_user_avatar_rule'             => 'default',
481
-			'ldap_ext_storage_home_attribute'   => '',
482
-		);
483
-	}
422
+    /**
423
+     * @return array an associative array with the default values. Keys are correspond
424
+     * to config-value entries in the database table
425
+     */
426
+    public function getDefaults() {
427
+        return array(
428
+            'ldap_host'                         => '',
429
+            'ldap_port'                         => '',
430
+            'ldap_backup_host'                  => '',
431
+            'ldap_backup_port'                  => '',
432
+            'ldap_override_main_server'         => '',
433
+            'ldap_dn'                           => '',
434
+            'ldap_agent_password'               => '',
435
+            'ldap_base'                         => '',
436
+            'ldap_base_users'                   => '',
437
+            'ldap_base_groups'                  => '',
438
+            'ldap_userlist_filter'              => '',
439
+            'ldap_user_filter_mode'             => 0,
440
+            'ldap_userfilter_objectclass'       => '',
441
+            'ldap_userfilter_groups'            => '',
442
+            'ldap_login_filter'                 => '',
443
+            'ldap_login_filter_mode'            => 0,
444
+            'ldap_loginfilter_email'            => 0,
445
+            'ldap_loginfilter_username'         => 1,
446
+            'ldap_loginfilter_attributes'       => '',
447
+            'ldap_group_filter'                 => '',
448
+            'ldap_group_filter_mode'            => 0,
449
+            'ldap_groupfilter_objectclass'      => '',
450
+            'ldap_groupfilter_groups'           => '',
451
+            'ldap_gid_number'                   => 'gidNumber',
452
+            'ldap_display_name'                 => 'displayName',
453
+            'ldap_user_display_name_2'			=> '',
454
+            'ldap_group_display_name'           => 'cn',
455
+            'ldap_tls'                          => 0,
456
+            'ldap_quota_def'                    => '',
457
+            'ldap_quota_attr'                   => '',
458
+            'ldap_email_attr'                   => '',
459
+            'ldap_group_member_assoc_attribute' => '',
460
+            'ldap_cache_ttl'                    => 600,
461
+            'ldap_uuid_user_attribute'          => 'auto',
462
+            'ldap_uuid_group_attribute'         => 'auto',
463
+            'home_folder_naming_rule'           => '',
464
+            'ldap_turn_off_cert_check'          => 0,
465
+            'ldap_configuration_active'         => 0,
466
+            'ldap_attributes_for_user_search'   => '',
467
+            'ldap_attributes_for_group_search'  => '',
468
+            'ldap_expert_username_attr'         => '',
469
+            'ldap_expert_uuid_user_attr'        => '',
470
+            'ldap_expert_uuid_group_attr'       => '',
471
+            'has_memberof_filter_support'       => 0,
472
+            'use_memberof_to_detect_membership' => 1,
473
+            'last_jpegPhoto_lookup'             => 0,
474
+            'ldap_nested_groups'                => 0,
475
+            'ldap_paging_size'                  => 500,
476
+            'ldap_turn_on_pwd_change'           => 0,
477
+            'ldap_experienced_admin'            => 0,
478
+            'ldap_dynamic_group_member_url'     => '',
479
+            'ldap_default_ppolicy_dn'           => '',
480
+            'ldap_user_avatar_rule'             => 'default',
481
+            'ldap_ext_storage_home_attribute'   => '',
482
+        );
483
+    }
484 484
 
485
-	/**
486
-	 * @return array that maps internal variable names to database fields
487
-	 */
488
-	public function getConfigTranslationArray() {
489
-		//TODO: merge them into one representation
490
-		static $array = array(
491
-			'ldap_host'                         => 'ldapHost',
492
-			'ldap_port'                         => 'ldapPort',
493
-			'ldap_backup_host'                  => 'ldapBackupHost',
494
-			'ldap_backup_port'                  => 'ldapBackupPort',
495
-			'ldap_override_main_server'         => 'ldapOverrideMainServer',
496
-			'ldap_dn'                           => 'ldapAgentName',
497
-			'ldap_agent_password'               => 'ldapAgentPassword',
498
-			'ldap_base'                         => 'ldapBase',
499
-			'ldap_base_users'                   => 'ldapBaseUsers',
500
-			'ldap_base_groups'                  => 'ldapBaseGroups',
501
-			'ldap_userfilter_objectclass'       => 'ldapUserFilterObjectclass',
502
-			'ldap_userfilter_groups'            => 'ldapUserFilterGroups',
503
-			'ldap_userlist_filter'              => 'ldapUserFilter',
504
-			'ldap_user_filter_mode'             => 'ldapUserFilterMode',
505
-			'ldap_user_avatar_rule'             => 'ldapUserAvatarRule',
506
-			'ldap_login_filter'                 => 'ldapLoginFilter',
507
-			'ldap_login_filter_mode'            => 'ldapLoginFilterMode',
508
-			'ldap_loginfilter_email'            => 'ldapLoginFilterEmail',
509
-			'ldap_loginfilter_username'         => 'ldapLoginFilterUsername',
510
-			'ldap_loginfilter_attributes'       => 'ldapLoginFilterAttributes',
511
-			'ldap_group_filter'                 => 'ldapGroupFilter',
512
-			'ldap_group_filter_mode'            => 'ldapGroupFilterMode',
513
-			'ldap_groupfilter_objectclass'      => 'ldapGroupFilterObjectclass',
514
-			'ldap_groupfilter_groups'           => 'ldapGroupFilterGroups',
515
-			'ldap_gid_number'                   => 'ldapGidNumber',
516
-			'ldap_display_name'                 => 'ldapUserDisplayName',
517
-			'ldap_user_display_name_2'			=> 'ldapUserDisplayName2',
518
-			'ldap_group_display_name'           => 'ldapGroupDisplayName',
519
-			'ldap_tls'                          => 'ldapTLS',
520
-			'ldap_quota_def'                    => 'ldapQuotaDefault',
521
-			'ldap_quota_attr'                   => 'ldapQuotaAttribute',
522
-			'ldap_email_attr'                   => 'ldapEmailAttribute',
523
-			'ldap_group_member_assoc_attribute' => 'ldapGroupMemberAssocAttr',
524
-			'ldap_cache_ttl'                    => 'ldapCacheTTL',
525
-			'home_folder_naming_rule'           => 'homeFolderNamingRule',
526
-			'ldap_turn_off_cert_check'          => 'turnOffCertCheck',
527
-			'ldap_configuration_active'         => 'ldapConfigurationActive',
528
-			'ldap_attributes_for_user_search'   => 'ldapAttributesForUserSearch',
529
-			'ldap_attributes_for_group_search'  => 'ldapAttributesForGroupSearch',
530
-			'ldap_expert_username_attr'         => 'ldapExpertUsernameAttr',
531
-			'ldap_expert_uuid_user_attr'        => 'ldapExpertUUIDUserAttr',
532
-			'ldap_expert_uuid_group_attr'       => 'ldapExpertUUIDGroupAttr',
533
-			'has_memberof_filter_support'       => 'hasMemberOfFilterSupport',
534
-			'use_memberof_to_detect_membership' => 'useMemberOfToDetectMembership',
535
-			'last_jpegPhoto_lookup'             => 'lastJpegPhotoLookup',
536
-			'ldap_nested_groups'                => 'ldapNestedGroups',
537
-			'ldap_paging_size'                  => 'ldapPagingSize',
538
-			'ldap_turn_on_pwd_change'           => 'turnOnPasswordChange',
539
-			'ldap_experienced_admin'            => 'ldapExperiencedAdmin',
540
-			'ldap_dynamic_group_member_url'     => 'ldapDynamicGroupMemberURL',
541
-			'ldap_default_ppolicy_dn'           => 'ldapDefaultPPolicyDN',
542
-			'ldap_ext_storage_home_attribute'   => 'ldapExtStorageHomeAttribute',
543
-			'ldapIgnoreNamingRules'             => 'ldapIgnoreNamingRules',	// sysconfig
544
-		);
545
-		return $array;
546
-	}
485
+    /**
486
+     * @return array that maps internal variable names to database fields
487
+     */
488
+    public function getConfigTranslationArray() {
489
+        //TODO: merge them into one representation
490
+        static $array = array(
491
+            'ldap_host'                         => 'ldapHost',
492
+            'ldap_port'                         => 'ldapPort',
493
+            'ldap_backup_host'                  => 'ldapBackupHost',
494
+            'ldap_backup_port'                  => 'ldapBackupPort',
495
+            'ldap_override_main_server'         => 'ldapOverrideMainServer',
496
+            'ldap_dn'                           => 'ldapAgentName',
497
+            'ldap_agent_password'               => 'ldapAgentPassword',
498
+            'ldap_base'                         => 'ldapBase',
499
+            'ldap_base_users'                   => 'ldapBaseUsers',
500
+            'ldap_base_groups'                  => 'ldapBaseGroups',
501
+            'ldap_userfilter_objectclass'       => 'ldapUserFilterObjectclass',
502
+            'ldap_userfilter_groups'            => 'ldapUserFilterGroups',
503
+            'ldap_userlist_filter'              => 'ldapUserFilter',
504
+            'ldap_user_filter_mode'             => 'ldapUserFilterMode',
505
+            'ldap_user_avatar_rule'             => 'ldapUserAvatarRule',
506
+            'ldap_login_filter'                 => 'ldapLoginFilter',
507
+            'ldap_login_filter_mode'            => 'ldapLoginFilterMode',
508
+            'ldap_loginfilter_email'            => 'ldapLoginFilterEmail',
509
+            'ldap_loginfilter_username'         => 'ldapLoginFilterUsername',
510
+            'ldap_loginfilter_attributes'       => 'ldapLoginFilterAttributes',
511
+            'ldap_group_filter'                 => 'ldapGroupFilter',
512
+            'ldap_group_filter_mode'            => 'ldapGroupFilterMode',
513
+            'ldap_groupfilter_objectclass'      => 'ldapGroupFilterObjectclass',
514
+            'ldap_groupfilter_groups'           => 'ldapGroupFilterGroups',
515
+            'ldap_gid_number'                   => 'ldapGidNumber',
516
+            'ldap_display_name'                 => 'ldapUserDisplayName',
517
+            'ldap_user_display_name_2'			=> 'ldapUserDisplayName2',
518
+            'ldap_group_display_name'           => 'ldapGroupDisplayName',
519
+            'ldap_tls'                          => 'ldapTLS',
520
+            'ldap_quota_def'                    => 'ldapQuotaDefault',
521
+            'ldap_quota_attr'                   => 'ldapQuotaAttribute',
522
+            'ldap_email_attr'                   => 'ldapEmailAttribute',
523
+            'ldap_group_member_assoc_attribute' => 'ldapGroupMemberAssocAttr',
524
+            'ldap_cache_ttl'                    => 'ldapCacheTTL',
525
+            'home_folder_naming_rule'           => 'homeFolderNamingRule',
526
+            'ldap_turn_off_cert_check'          => 'turnOffCertCheck',
527
+            'ldap_configuration_active'         => 'ldapConfigurationActive',
528
+            'ldap_attributes_for_user_search'   => 'ldapAttributesForUserSearch',
529
+            'ldap_attributes_for_group_search'  => 'ldapAttributesForGroupSearch',
530
+            'ldap_expert_username_attr'         => 'ldapExpertUsernameAttr',
531
+            'ldap_expert_uuid_user_attr'        => 'ldapExpertUUIDUserAttr',
532
+            'ldap_expert_uuid_group_attr'       => 'ldapExpertUUIDGroupAttr',
533
+            'has_memberof_filter_support'       => 'hasMemberOfFilterSupport',
534
+            'use_memberof_to_detect_membership' => 'useMemberOfToDetectMembership',
535
+            'last_jpegPhoto_lookup'             => 'lastJpegPhotoLookup',
536
+            'ldap_nested_groups'                => 'ldapNestedGroups',
537
+            'ldap_paging_size'                  => 'ldapPagingSize',
538
+            'ldap_turn_on_pwd_change'           => 'turnOnPasswordChange',
539
+            'ldap_experienced_admin'            => 'ldapExperiencedAdmin',
540
+            'ldap_dynamic_group_member_url'     => 'ldapDynamicGroupMemberURL',
541
+            'ldap_default_ppolicy_dn'           => 'ldapDefaultPPolicyDN',
542
+            'ldap_ext_storage_home_attribute'   => 'ldapExtStorageHomeAttribute',
543
+            'ldapIgnoreNamingRules'             => 'ldapIgnoreNamingRules',	// sysconfig
544
+        );
545
+        return $array;
546
+    }
547 547
 
548
-	/**
549
-	 * @param string $rule
550
-	 * @return array
551
-	 * @throws \RuntimeException
552
-	 */
553
-	public function resolveRule($rule) {
554
-		if($rule === 'avatar') {
555
-			return $this->getAvatarAttributes();
556
-		}
557
-		throw new \RuntimeException('Invalid rule');
558
-	}
548
+    /**
549
+     * @param string $rule
550
+     * @return array
551
+     * @throws \RuntimeException
552
+     */
553
+    public function resolveRule($rule) {
554
+        if($rule === 'avatar') {
555
+            return $this->getAvatarAttributes();
556
+        }
557
+        throw new \RuntimeException('Invalid rule');
558
+    }
559 559
 
560
-	public function getAvatarAttributes() {
561
-		$value = $this->ldapUserAvatarRule ?: self::AVATAR_PREFIX_DEFAULT;
562
-		$defaultAttributes = ['jpegphoto', 'thumbnailphoto'];
560
+    public function getAvatarAttributes() {
561
+        $value = $this->ldapUserAvatarRule ?: self::AVATAR_PREFIX_DEFAULT;
562
+        $defaultAttributes = ['jpegphoto', 'thumbnailphoto'];
563 563
 
564
-		if($value === self::AVATAR_PREFIX_NONE) {
565
-			return [];
566
-		}
567
-		if(strpos($value, self::AVATAR_PREFIX_DATA_ATTRIBUTE) === 0) {
568
-			$attribute = trim(substr($value, strlen(self::AVATAR_PREFIX_DATA_ATTRIBUTE)));
569
-			if($attribute === '') {
570
-				return $defaultAttributes;
571
-			}
572
-			return [strtolower($attribute)];
573
-		}
574
-		if($value !== self::AVATAR_PREFIX_DEFAULT) {
575
-			\OC::$server->getLogger()->warning('Invalid config value to ldapUserAvatarRule; falling back to default.');
576
-		}
577
-		return $defaultAttributes;
578
-	}
564
+        if($value === self::AVATAR_PREFIX_NONE) {
565
+            return [];
566
+        }
567
+        if(strpos($value, self::AVATAR_PREFIX_DATA_ATTRIBUTE) === 0) {
568
+            $attribute = trim(substr($value, strlen(self::AVATAR_PREFIX_DATA_ATTRIBUTE)));
569
+            if($attribute === '') {
570
+                return $defaultAttributes;
571
+            }
572
+            return [strtolower($attribute)];
573
+        }
574
+        if($value !== self::AVATAR_PREFIX_DEFAULT) {
575
+            \OC::$server->getLogger()->warning('Invalid config value to ldapUserAvatarRule; falling back to default.');
576
+        }
577
+        return $defaultAttributes;
578
+    }
579 579
 
580 580
 }
Please login to merge, or discard this patch.
apps/user_ldap/lib/LDAPProvider.php 1 patch
Indentation   +230 added lines, -230 removed lines patch added patch discarded remove patch
@@ -37,256 +37,256 @@
 block discarded – undo
37 37
  */
38 38
 class LDAPProvider implements ILDAPProvider, IDeletionFlagSupport {
39 39
 
40
-	private $userBackend;
41
-	private $groupBackend;
42
-	private $logger;
43
-	private $helper;
44
-	private $deletedUsersIndex;
40
+    private $userBackend;
41
+    private $groupBackend;
42
+    private $logger;
43
+    private $helper;
44
+    private $deletedUsersIndex;
45 45
 	
46
-	/**
47
-	 * Create new LDAPProvider
48
-	 * @param \OCP\IServerContainer $serverContainer
49
-	 * @param Helper $helper
50
-	 * @param DeletedUsersIndex $deletedUsersIndex
51
-	 * @throws \Exception if user_ldap app was not enabled
52
-	 */
53
-	public function __construct(IServerContainer $serverContainer, Helper $helper, DeletedUsersIndex $deletedUsersIndex) {
54
-		$this->logger = $serverContainer->getLogger();
55
-		$this->helper = $helper;
56
-		$this->deletedUsersIndex = $deletedUsersIndex;
57
-		$userBackendFound = false;
58
-		$groupBackendFound = false;
59
-		foreach ($serverContainer->getUserManager()->getBackends() as $backend){
60
-			$this->logger->debug('instance '.get_class($backend).' user backend.', ['app' => 'user_ldap']);
61
-			if ($backend instanceof IUserLDAP) {
62
-				$this->userBackend = $backend;
63
-				$userBackendFound = true;
64
-				break;
65
-			}
46
+    /**
47
+     * Create new LDAPProvider
48
+     * @param \OCP\IServerContainer $serverContainer
49
+     * @param Helper $helper
50
+     * @param DeletedUsersIndex $deletedUsersIndex
51
+     * @throws \Exception if user_ldap app was not enabled
52
+     */
53
+    public function __construct(IServerContainer $serverContainer, Helper $helper, DeletedUsersIndex $deletedUsersIndex) {
54
+        $this->logger = $serverContainer->getLogger();
55
+        $this->helper = $helper;
56
+        $this->deletedUsersIndex = $deletedUsersIndex;
57
+        $userBackendFound = false;
58
+        $groupBackendFound = false;
59
+        foreach ($serverContainer->getUserManager()->getBackends() as $backend){
60
+            $this->logger->debug('instance '.get_class($backend).' user backend.', ['app' => 'user_ldap']);
61
+            if ($backend instanceof IUserLDAP) {
62
+                $this->userBackend = $backend;
63
+                $userBackendFound = true;
64
+                break;
65
+            }
66
+        }
67
+        foreach ($serverContainer->getGroupManager()->getBackends() as $backend){
68
+            $this->logger->debug('instance '.get_class($backend).' group backend.', ['app' => 'user_ldap']);
69
+            if ($backend instanceof IGroupLDAP) {
70
+                $this->groupBackend = $backend;
71
+                $groupBackendFound = true;
72
+                break;
73
+            }
66 74
         }
67
-		foreach ($serverContainer->getGroupManager()->getBackends() as $backend){
68
-			$this->logger->debug('instance '.get_class($backend).' group backend.', ['app' => 'user_ldap']);
69
-			if ($backend instanceof IGroupLDAP) {
70
-				$this->groupBackend = $backend;
71
-				$groupBackendFound = true;
72
-				break;
73
-			}
74
-		}
75 75
 
76 76
         if (!$userBackendFound or !$groupBackendFound) {
77
-			throw new \Exception('To use the LDAPProvider, user_ldap app must be enabled');
78
-		}
79
-	}
77
+            throw new \Exception('To use the LDAPProvider, user_ldap app must be enabled');
78
+        }
79
+    }
80 80
 	
81
-	/**
82
-	 * Translate an user id to LDAP DN
83
-	 * @param string $uid user id
84
-	 * @return string with the LDAP DN
85
-	 * @throws \Exception if translation was unsuccessful
86
-	 */
87
-	public function getUserDN($uid) {
88
-		if(!$this->userBackend->userExists($uid)){
89
-			throw new \Exception('User id not found in LDAP');
90
-		}
91
-		$result = $this->userBackend->getLDAPAccess($uid)->username2dn($uid);
92
-		if(!$result){
93
-			throw new \Exception('Translation to LDAP DN unsuccessful');
94
-		}
95
-		return $result;
96
-	}
81
+    /**
82
+     * Translate an user id to LDAP DN
83
+     * @param string $uid user id
84
+     * @return string with the LDAP DN
85
+     * @throws \Exception if translation was unsuccessful
86
+     */
87
+    public function getUserDN($uid) {
88
+        if(!$this->userBackend->userExists($uid)){
89
+            throw new \Exception('User id not found in LDAP');
90
+        }
91
+        $result = $this->userBackend->getLDAPAccess($uid)->username2dn($uid);
92
+        if(!$result){
93
+            throw new \Exception('Translation to LDAP DN unsuccessful');
94
+        }
95
+        return $result;
96
+    }
97 97
 
98
-	/**
99
-	 * Translate a group id to LDAP DN.
100
-	 * @param string $gid group id
101
-	 * @return string
102
-	 * @throws \Exception
103
-	 */
104
-	public function getGroupDN($gid) {
105
-		if(!$this->groupBackend->groupExists($gid)){
106
-			throw new \Exception('Group id not found in LDAP');
107
-		}
108
-		$result = $this->groupBackend->getLDAPAccess($gid)->groupname2dn($gid);
109
-		if(!$result){
110
-			throw new \Exception('Translation to LDAP DN unsuccessful');
111
-		}
112
-		return $result;	
113
-	}
98
+    /**
99
+     * Translate a group id to LDAP DN.
100
+     * @param string $gid group id
101
+     * @return string
102
+     * @throws \Exception
103
+     */
104
+    public function getGroupDN($gid) {
105
+        if(!$this->groupBackend->groupExists($gid)){
106
+            throw new \Exception('Group id not found in LDAP');
107
+        }
108
+        $result = $this->groupBackend->getLDAPAccess($gid)->groupname2dn($gid);
109
+        if(!$result){
110
+            throw new \Exception('Translation to LDAP DN unsuccessful');
111
+        }
112
+        return $result;	
113
+    }
114 114
 
115
-	/**
116
-	 * Translate a LDAP DN to an internal user name. If there is no mapping between 
117
-	 * the DN and the user name, a new one will be created.
118
-	 * @param string $dn LDAP DN
119
-	 * @return string with the internal user name
120
-	 * @throws \Exception if translation was unsuccessful
121
-	 */
122
-	public function getUserName($dn) {
123
-		$result = $this->userBackend->dn2UserName($dn);
124
-		if(!$result){
125
-			throw new \Exception('Translation to internal user name unsuccessful');
126
-		}
127
-		return $result;
128
-	}
115
+    /**
116
+     * Translate a LDAP DN to an internal user name. If there is no mapping between 
117
+     * the DN and the user name, a new one will be created.
118
+     * @param string $dn LDAP DN
119
+     * @return string with the internal user name
120
+     * @throws \Exception if translation was unsuccessful
121
+     */
122
+    public function getUserName($dn) {
123
+        $result = $this->userBackend->dn2UserName($dn);
124
+        if(!$result){
125
+            throw new \Exception('Translation to internal user name unsuccessful');
126
+        }
127
+        return $result;
128
+    }
129 129
 	
130
-	/**
131
-	 * Convert a stored DN so it can be used as base parameter for LDAP queries.
132
-	 * @param string $dn the DN in question
133
-	 * @return string
134
-	 */
135
-	public function DNasBaseParameter($dn) {
136
-		return $this->helper->DNasBaseParameter($dn);
137
-	}
130
+    /**
131
+     * Convert a stored DN so it can be used as base parameter for LDAP queries.
132
+     * @param string $dn the DN in question
133
+     * @return string
134
+     */
135
+    public function DNasBaseParameter($dn) {
136
+        return $this->helper->DNasBaseParameter($dn);
137
+    }
138 138
 	
139
-	/**
140
-	 * Sanitize a DN received from the LDAP server.
141
-	 * @param array $dn the DN in question
142
-	 * @return array the sanitized DN
143
-	 */
144
-	public function sanitizeDN($dn) {
145
-		return $this->helper->sanitizeDN($dn);
146
-	}
139
+    /**
140
+     * Sanitize a DN received from the LDAP server.
141
+     * @param array $dn the DN in question
142
+     * @return array the sanitized DN
143
+     */
144
+    public function sanitizeDN($dn) {
145
+        return $this->helper->sanitizeDN($dn);
146
+    }
147 147
 	
148
-	/**
149
-	 * Return a new LDAP connection resource for the specified user. 
150
-	 * The connection must be closed manually.
151
-	 * @param string $uid user id
152
-	 * @return resource of the LDAP connection
153
-	 * @throws \Exception if user id was not found in LDAP
154
-	 */
155
-	public function getLDAPConnection($uid) {
156
-		if(!$this->userBackend->userExists($uid)){
157
-			throw new \Exception('User id not found in LDAP');
158
-		}
159
-		return $this->userBackend->getNewLDAPConnection($uid);
160
-	}
148
+    /**
149
+     * Return a new LDAP connection resource for the specified user. 
150
+     * The connection must be closed manually.
151
+     * @param string $uid user id
152
+     * @return resource of the LDAP connection
153
+     * @throws \Exception if user id was not found in LDAP
154
+     */
155
+    public function getLDAPConnection($uid) {
156
+        if(!$this->userBackend->userExists($uid)){
157
+            throw new \Exception('User id not found in LDAP');
158
+        }
159
+        return $this->userBackend->getNewLDAPConnection($uid);
160
+    }
161 161
 
162
-	/**
163
-	 * Return a new LDAP connection resource for the specified user.
164
-	 * The connection must be closed manually.
165
-	 * @param string $gid group id
166
-	 * @return resource of the LDAP connection
167
-	 * @throws \Exception if group id was not found in LDAP
168
-	 */
169
-	public function getGroupLDAPConnection($gid) {
170
-		if(!$this->groupBackend->groupExists($gid)){
171
-			throw new \Exception('Group id not found in LDAP');
172
-		}
173
-		return $this->groupBackend->getNewLDAPConnection($gid);
174
-	}
162
+    /**
163
+     * Return a new LDAP connection resource for the specified user.
164
+     * The connection must be closed manually.
165
+     * @param string $gid group id
166
+     * @return resource of the LDAP connection
167
+     * @throws \Exception if group id was not found in LDAP
168
+     */
169
+    public function getGroupLDAPConnection($gid) {
170
+        if(!$this->groupBackend->groupExists($gid)){
171
+            throw new \Exception('Group id not found in LDAP');
172
+        }
173
+        return $this->groupBackend->getNewLDAPConnection($gid);
174
+    }
175 175
 	
176
-	/**
177
-	 * Get the LDAP base for users.
178
-	 * @param string $uid user id
179
-	 * @return string the base for users
180
-	 * @throws \Exception if user id was not found in LDAP
181
-	 */
182
-	public function getLDAPBaseUsers($uid) {
183
-		if(!$this->userBackend->userExists($uid)){
184
-			throw new \Exception('User id not found in LDAP');
185
-		}	
186
-		return $this->userBackend->getLDAPAccess($uid)->getConnection()->getConfiguration()['ldap_base_users'];
187
-	}
176
+    /**
177
+     * Get the LDAP base for users.
178
+     * @param string $uid user id
179
+     * @return string the base for users
180
+     * @throws \Exception if user id was not found in LDAP
181
+     */
182
+    public function getLDAPBaseUsers($uid) {
183
+        if(!$this->userBackend->userExists($uid)){
184
+            throw new \Exception('User id not found in LDAP');
185
+        }	
186
+        return $this->userBackend->getLDAPAccess($uid)->getConnection()->getConfiguration()['ldap_base_users'];
187
+    }
188 188
 	
189
-	/**
190
-	 * Get the LDAP base for groups.
191
-	 * @param string $uid user id
192
-	 * @return string the base for groups
193
-	 * @throws \Exception if user id was not found in LDAP
194
-	 */
195
-	public function getLDAPBaseGroups($uid) {
196
-		if(!$this->userBackend->userExists($uid)){
197
-			throw new \Exception('User id not found in LDAP');
198
-		}
199
-		return $this->userBackend->getLDAPAccess($uid)->getConnection()->getConfiguration()['ldap_base_groups'];
200
-	}
189
+    /**
190
+     * Get the LDAP base for groups.
191
+     * @param string $uid user id
192
+     * @return string the base for groups
193
+     * @throws \Exception if user id was not found in LDAP
194
+     */
195
+    public function getLDAPBaseGroups($uid) {
196
+        if(!$this->userBackend->userExists($uid)){
197
+            throw new \Exception('User id not found in LDAP');
198
+        }
199
+        return $this->userBackend->getLDAPAccess($uid)->getConnection()->getConfiguration()['ldap_base_groups'];
200
+    }
201 201
 	
202
-	/**
203
-	 * Clear the cache if a cache is used, otherwise do nothing.
204
-	 * @param string $uid user id
205
-	 * @throws \Exception if user id was not found in LDAP
206
-	 */
207
-	public function clearCache($uid) {
208
-		if(!$this->userBackend->userExists($uid)){
209
-			throw new \Exception('User id not found in LDAP');
210
-		}
211
-		$this->userBackend->getLDAPAccess($uid)->getConnection()->clearCache();
212
-	}
202
+    /**
203
+     * Clear the cache if a cache is used, otherwise do nothing.
204
+     * @param string $uid user id
205
+     * @throws \Exception if user id was not found in LDAP
206
+     */
207
+    public function clearCache($uid) {
208
+        if(!$this->userBackend->userExists($uid)){
209
+            throw new \Exception('User id not found in LDAP');
210
+        }
211
+        $this->userBackend->getLDAPAccess($uid)->getConnection()->clearCache();
212
+    }
213 213
 
214
-	/**
215
-	 * Clear the cache if a cache is used, otherwise do nothing.
216
-	 * Acts on the LDAP connection of a group
217
-	 * @param string $gid group id
218
-	 * @throws \Exception if user id was not found in LDAP
219
-	 */
220
-	public function clearGroupCache($gid) {
221
-		if(!$this->groupBackend->groupExists($gid)){
222
-			throw new \Exception('Group id not found in LDAP');
223
-		}
224
-		$this->groupBackend->getLDAPAccess($gid)->getConnection()->clearCache();
225
-	}
214
+    /**
215
+     * Clear the cache if a cache is used, otherwise do nothing.
216
+     * Acts on the LDAP connection of a group
217
+     * @param string $gid group id
218
+     * @throws \Exception if user id was not found in LDAP
219
+     */
220
+    public function clearGroupCache($gid) {
221
+        if(!$this->groupBackend->groupExists($gid)){
222
+            throw new \Exception('Group id not found in LDAP');
223
+        }
224
+        $this->groupBackend->getLDAPAccess($gid)->getConnection()->clearCache();
225
+    }
226 226
 	
227
-	/**
228
-	 * Check whether a LDAP DN exists
229
-	 * @param string $dn LDAP DN
230
-	 * @return bool whether the DN exists
231
-	 */
232
-	public function dnExists($dn) {
233
-		$result = $this->userBackend->dn2UserName($dn);
234
-		return !$result ? false : true;
235
-	}
227
+    /**
228
+     * Check whether a LDAP DN exists
229
+     * @param string $dn LDAP DN
230
+     * @return bool whether the DN exists
231
+     */
232
+    public function dnExists($dn) {
233
+        $result = $this->userBackend->dn2UserName($dn);
234
+        return !$result ? false : true;
235
+    }
236 236
 	
237
-	/**
238
-	 * Flag record for deletion.
239
-	 * @param string $uid user id
240
-	 */
241
-	public function flagRecord($uid) {
242
-		$this->deletedUsersIndex->markUser($uid);
243
-	}
237
+    /**
238
+     * Flag record for deletion.
239
+     * @param string $uid user id
240
+     */
241
+    public function flagRecord($uid) {
242
+        $this->deletedUsersIndex->markUser($uid);
243
+    }
244 244
 	
245
-	/**
246
-	 * Unflag record for deletion.
247
-	 * @param string $uid user id
248
-	 */
249
-	public function unflagRecord($uid) {
250
-		//do nothing
251
-	}
245
+    /**
246
+     * Unflag record for deletion.
247
+     * @param string $uid user id
248
+     */
249
+    public function unflagRecord($uid) {
250
+        //do nothing
251
+    }
252 252
 
253
-	/**
254
-	 * Get the LDAP attribute name for the user's display name
255
-	 * @param string $uid user id
256
-	 * @return string the display name field
257
-	 * @throws \Exception if user id was not found in LDAP
258
-	 */
259
-	public function getLDAPDisplayNameField($uid) {
260
-		if(!$this->userBackend->userExists($uid)){
261
-			throw new \Exception('User id not found in LDAP');
262
-		}
263
-		return $this->userBackend->getLDAPAccess($uid)->getConnection()->getConfiguration()['ldap_display_name'];
264
-	}
253
+    /**
254
+     * Get the LDAP attribute name for the user's display name
255
+     * @param string $uid user id
256
+     * @return string the display name field
257
+     * @throws \Exception if user id was not found in LDAP
258
+     */
259
+    public function getLDAPDisplayNameField($uid) {
260
+        if(!$this->userBackend->userExists($uid)){
261
+            throw new \Exception('User id not found in LDAP');
262
+        }
263
+        return $this->userBackend->getLDAPAccess($uid)->getConnection()->getConfiguration()['ldap_display_name'];
264
+    }
265 265
 
266
-	/**
267
-	 * Get the LDAP attribute name for the email
268
-	 * @param string $uid user id
269
-	 * @return string the email field
270
-	 * @throws \Exception if user id was not found in LDAP
271
-	 */
272
-	public function getLDAPEmailField($uid) {
273
-		if(!$this->userBackend->userExists($uid)){
274
-			throw new \Exception('User id not found in LDAP');
275
-		}
276
-		return $this->userBackend->getLDAPAccess($uid)->getConnection()->getConfiguration()['ldap_email_attr'];
277
-	}
266
+    /**
267
+     * Get the LDAP attribute name for the email
268
+     * @param string $uid user id
269
+     * @return string the email field
270
+     * @throws \Exception if user id was not found in LDAP
271
+     */
272
+    public function getLDAPEmailField($uid) {
273
+        if(!$this->userBackend->userExists($uid)){
274
+            throw new \Exception('User id not found in LDAP');
275
+        }
276
+        return $this->userBackend->getLDAPAccess($uid)->getConnection()->getConfiguration()['ldap_email_attr'];
277
+    }
278 278
 
279
-	/**
280
-	 * Get the LDAP type of association between users and groups
281
-	 * @param string $gid group id
282
-	 * @return string the configuration, one of: 'memberUid', 'uniqueMember', 'member', 'gidNumber', ''
283
-	 * @throws \Exception if group id was not found in LDAP
284
-	 */
285
-	public function getLDAPGroupMemberAssoc($gid) {
286
-		if(!$this->groupBackend->groupExists($gid)){
287
-			throw new \Exception('Group id not found in LDAP');
288
-		}
289
-		return $this->groupBackend->getLDAPAccess($gid)->getConnection()->getConfiguration()['ldap_group_member_assoc_attribute'];
290
-	}
279
+    /**
280
+     * Get the LDAP type of association between users and groups
281
+     * @param string $gid group id
282
+     * @return string the configuration, one of: 'memberUid', 'uniqueMember', 'member', 'gidNumber', ''
283
+     * @throws \Exception if group id was not found in LDAP
284
+     */
285
+    public function getLDAPGroupMemberAssoc($gid) {
286
+        if(!$this->groupBackend->groupExists($gid)){
287
+            throw new \Exception('Group id not found in LDAP');
288
+        }
289
+        return $this->groupBackend->getLDAPAccess($gid)->getConnection()->getConfiguration()['ldap_group_member_assoc_attribute'];
290
+    }
291 291
 
292 292
 }
Please login to merge, or discard this patch.