Completed
Pull Request — master (#7531)
by Blizzz
43:38 queued 27:41
created
apps/user_ldap/lib/Connection.php 2 patches
Indentation   +577 added lines, -577 removed lines patch added patch discarded remove patch
@@ -58,582 +58,582 @@
 block discarded – undo
58 58
  * @property string ldapExpertUUIDGroupAttr
59 59
  */
60 60
 class Connection extends LDAPUtility {
61
-	private $ldapConnectionRes = null;
62
-	private $configPrefix;
63
-	private $configID;
64
-	private $configured = false;
65
-	private $hasPagedResultSupport = true;
66
-	//whether connection should be kept on __destruct
67
-	private $dontDestruct = false;
68
-
69
-	/**
70
-	 * @var bool runtime flag that indicates whether supported primary groups are available
71
-	 */
72
-	public $hasPrimaryGroups = true;
73
-
74
-	/**
75
-	 * @var bool runtime flag that indicates whether supported POSIX gidNumber are available
76
-	 */
77
-	public $hasGidNumber = true;
78
-
79
-	//cache handler
80
-	protected $cache;
81
-
82
-	/** @var Configuration settings handler **/
83
-	protected $configuration;
84
-
85
-	protected $doNotValidate = false;
86
-
87
-	protected $ignoreValidation = false;
88
-
89
-	/**
90
-	 * Constructor
91
-	 * @param ILDAPWrapper $ldap
92
-	 * @param string $configPrefix a string with the prefix for the configkey column (appconfig table)
93
-	 * @param string|null $configID a string with the value for the appid column (appconfig table) or null for on-the-fly connections
94
-	 */
95
-	public function __construct(ILDAPWrapper $ldap, $configPrefix = '', $configID = 'user_ldap') {
96
-		parent::__construct($ldap);
97
-		$this->configPrefix = $configPrefix;
98
-		$this->configID = $configID;
99
-		$this->configuration = new Configuration($configPrefix,
100
-												 !is_null($configID));
101
-		$memcache = \OC::$server->getMemCacheFactory();
102
-		if($memcache->isAvailable()) {
103
-			$this->cache = $memcache->createDistributed();
104
-		}
105
-		$helper = new Helper(\OC::$server->getConfig());
106
-		$this->doNotValidate = !in_array($this->configPrefix,
107
-			$helper->getServerConfigurationPrefixes());
108
-		$this->hasPagedResultSupport =
109
-			intval($this->configuration->ldapPagingSize) !== 0
110
-			|| $this->ldap->hasPagedResultSupport();
111
-	}
112
-
113
-	public function __destruct() {
114
-		if(!$this->dontDestruct && $this->ldap->isResource($this->ldapConnectionRes)) {
115
-			@$this->ldap->unbind($this->ldapConnectionRes);
116
-		};
117
-	}
118
-
119
-	/**
120
-	 * defines behaviour when the instance is cloned
121
-	 */
122
-	public function __clone() {
123
-		$this->configuration = new Configuration($this->configPrefix,
124
-												 !is_null($this->configID));
125
-		$this->ldapConnectionRes = null;
126
-		$this->dontDestruct = true;
127
-	}
128
-
129
-	/**
130
-	 * @param string $name
131
-	 * @return bool|mixed
132
-	 */
133
-	public function __get($name) {
134
-		if(!$this->configured) {
135
-			$this->readConfiguration();
136
-		}
137
-
138
-		if($name === 'hasPagedResultSupport') {
139
-			return $this->hasPagedResultSupport;
140
-		}
141
-
142
-		return $this->configuration->$name;
143
-	}
144
-
145
-	/**
146
-	 * @param string $name
147
-	 * @param mixed $value
148
-	 */
149
-	public function __set($name, $value) {
150
-		$this->doNotValidate = false;
151
-		$before = $this->configuration->$name;
152
-		$this->configuration->$name = $value;
153
-		$after = $this->configuration->$name;
154
-		if($before !== $after) {
155
-			if ($this->configID !== '' && $this->configID !== null) {
156
-				$this->configuration->saveConfiguration();
157
-			}
158
-			$this->validateConfiguration();
159
-		}
160
-	}
161
-
162
-	/**
163
-	 * sets whether the result of the configuration validation shall
164
-	 * be ignored when establishing the connection. Used by the Wizard
165
-	 * in early configuration state.
166
-	 * @param bool $state
167
-	 */
168
-	public function setIgnoreValidation($state) {
169
-		$this->ignoreValidation = (bool)$state;
170
-	}
171
-
172
-	/**
173
-	 * initializes the LDAP backend
174
-	 * @param bool $force read the config settings no matter what
175
-	 */
176
-	public function init($force = false) {
177
-		$this->readConfiguration($force);
178
-		$this->establishConnection();
179
-	}
180
-
181
-	/**
182
-	 * Returns the LDAP handler
183
-	 */
184
-	public function getConnectionResource() {
185
-		if(!$this->ldapConnectionRes) {
186
-			$this->init();
187
-		} else if(!$this->ldap->isResource($this->ldapConnectionRes)) {
188
-			$this->ldapConnectionRes = null;
189
-			$this->establishConnection();
190
-		}
191
-		if(is_null($this->ldapConnectionRes)) {
192
-			\OCP\Util::writeLog('user_ldap', 'No LDAP Connection to server ' . $this->configuration->ldapHost, \OCP\Util::ERROR);
193
-			throw new ServerNotAvailableException('Connection to LDAP server could not be established');
194
-		}
195
-		return $this->ldapConnectionRes;
196
-	}
197
-
198
-	/**
199
-	 * resets the connection resource
200
-	 */
201
-	public function resetConnectionResource() {
202
-		if(!is_null($this->ldapConnectionRes)) {
203
-			@$this->ldap->unbind($this->ldapConnectionRes);
204
-			$this->ldapConnectionRes = null;
205
-		}
206
-	}
207
-
208
-	/**
209
-	 * @param string|null $key
210
-	 * @return string
211
-	 */
212
-	private function getCacheKey($key) {
213
-		$prefix = 'LDAP-'.$this->configID.'-'.$this->configPrefix.'-';
214
-		if(is_null($key)) {
215
-			return $prefix;
216
-		}
217
-		return $prefix.md5($key);
218
-	}
219
-
220
-	/**
221
-	 * @param string $key
222
-	 * @return mixed|null
223
-	 */
224
-	public function getFromCache($key) {
225
-		if(!$this->configured) {
226
-			$this->readConfiguration();
227
-		}
228
-		if(is_null($this->cache) || !$this->configuration->ldapCacheTTL) {
229
-			return null;
230
-		}
231
-		$key = $this->getCacheKey($key);
232
-
233
-		return json_decode(base64_decode($this->cache->get($key)), true);
234
-	}
235
-
236
-	/**
237
-	 * @param string $key
238
-	 * @param mixed $value
239
-	 *
240
-	 * @return string
241
-	 */
242
-	public function writeToCache($key, $value) {
243
-		if(!$this->configured) {
244
-			$this->readConfiguration();
245
-		}
246
-		if(is_null($this->cache)
247
-			|| !$this->configuration->ldapCacheTTL
248
-			|| !$this->configuration->ldapConfigurationActive) {
249
-			return null;
250
-		}
251
-		$key   = $this->getCacheKey($key);
252
-		$value = base64_encode(json_encode($value));
253
-		$this->cache->set($key, $value, $this->configuration->ldapCacheTTL);
254
-	}
255
-
256
-	public function clearCache() {
257
-		if(!is_null($this->cache)) {
258
-			$this->cache->clear($this->getCacheKey(null));
259
-		}
260
-	}
261
-
262
-	/**
263
-	 * Caches the general LDAP configuration.
264
-	 * @param bool $force optional. true, if the re-read should be forced. defaults
265
-	 * to false.
266
-	 * @return null
267
-	 */
268
-	private function readConfiguration($force = false) {
269
-		if((!$this->configured || $force) && !is_null($this->configID)) {
270
-			$this->configuration->readConfiguration();
271
-			$this->configured = $this->validateConfiguration();
272
-		}
273
-	}
274
-
275
-	/**
276
-	 * set LDAP configuration with values delivered by an array, not read from configuration
277
-	 * @param array $config array that holds the config parameters in an associated array
278
-	 * @param array &$setParameters optional; array where the set fields will be given to
279
-	 * @return boolean true if config validates, false otherwise. Check with $setParameters for detailed success on single parameters
280
-	 */
281
-	public function setConfiguration($config, &$setParameters = null) {
282
-		if(is_null($setParameters)) {
283
-			$setParameters = array();
284
-		}
285
-		$this->doNotValidate = false;
286
-		$this->configuration->setConfiguration($config, $setParameters);
287
-		if(count($setParameters) > 0) {
288
-			$this->configured = $this->validateConfiguration();
289
-		}
290
-
291
-
292
-		return $this->configured;
293
-	}
294
-
295
-	/**
296
-	 * saves the current Configuration in the database and empties the
297
-	 * cache
298
-	 * @return null
299
-	 */
300
-	public function saveConfiguration() {
301
-		$this->configuration->saveConfiguration();
302
-		$this->clearCache();
303
-	}
304
-
305
-	/**
306
-	 * get the current LDAP configuration
307
-	 * @return array
308
-	 */
309
-	public function getConfiguration() {
310
-		$this->readConfiguration();
311
-		$config = $this->configuration->getConfiguration();
312
-		$cta = $this->configuration->getConfigTranslationArray();
313
-		$result = array();
314
-		foreach($cta as $dbkey => $configkey) {
315
-			switch($configkey) {
316
-				case 'homeFolderNamingRule':
317
-					if(strpos($config[$configkey], 'attr:') === 0) {
318
-						$result[$dbkey] = substr($config[$configkey], 5);
319
-					} else {
320
-						$result[$dbkey] = '';
321
-					}
322
-					break;
323
-				case 'ldapBase':
324
-				case 'ldapBaseUsers':
325
-				case 'ldapBaseGroups':
326
-				case 'ldapAttributesForUserSearch':
327
-				case 'ldapAttributesForGroupSearch':
328
-					if(is_array($config[$configkey])) {
329
-						$result[$dbkey] = implode("\n", $config[$configkey]);
330
-						break;
331
-					} //else follows default
332
-				default:
333
-					$result[$dbkey] = $config[$configkey];
334
-			}
335
-		}
336
-		return $result;
337
-	}
338
-
339
-	private function doSoftValidation() {
340
-		//if User or Group Base are not set, take over Base DN setting
341
-		foreach(array('ldapBaseUsers', 'ldapBaseGroups') as $keyBase) {
342
-			$val = $this->configuration->$keyBase;
343
-			if(empty($val)) {
344
-				$this->configuration->$keyBase = $this->configuration->ldapBase;
345
-			}
346
-		}
347
-
348
-		foreach(array('ldapExpertUUIDUserAttr'  => 'ldapUuidUserAttribute',
349
-					  'ldapExpertUUIDGroupAttr' => 'ldapUuidGroupAttribute')
350
-				as $expertSetting => $effectiveSetting) {
351
-			$uuidOverride = $this->configuration->$expertSetting;
352
-			if(!empty($uuidOverride)) {
353
-				$this->configuration->$effectiveSetting = $uuidOverride;
354
-			} else {
355
-				$uuidAttributes = Access::UUID_ATTRIBUTES;
356
-				array_unshift($uuidAttributes, 'auto');
357
-				if(!in_array($this->configuration->$effectiveSetting,
358
-							$uuidAttributes)
359
-					&& (!is_null($this->configID))) {
360
-					$this->configuration->$effectiveSetting = 'auto';
361
-					$this->configuration->saveConfiguration();
362
-					\OCP\Util::writeLog('user_ldap',
363
-										'Illegal value for the '.
364
-										$effectiveSetting.', '.'reset to '.
365
-										'autodetect.', \OCP\Util::INFO);
366
-				}
367
-
368
-			}
369
-		}
370
-
371
-		$backupPort = intval($this->configuration->ldapBackupPort);
372
-		if ($backupPort <= 0) {
373
-			$this->configuration->backupPort = $this->configuration->ldapPort;
374
-		}
375
-
376
-		//make sure empty search attributes are saved as simple, empty array
377
-		$saKeys = array('ldapAttributesForUserSearch',
378
-						'ldapAttributesForGroupSearch');
379
-		foreach($saKeys as $key) {
380
-			$val = $this->configuration->$key;
381
-			if(is_array($val) && count($val) === 1 && empty($val[0])) {
382
-				$this->configuration->$key = array();
383
-			}
384
-		}
385
-
386
-		if((stripos($this->configuration->ldapHost, 'ldaps://') === 0)
387
-			&& $this->configuration->ldapTLS) {
388
-			$this->configuration->ldapTLS = false;
389
-			\OCP\Util::writeLog('user_ldap',
390
-								'LDAPS (already using secure connection) and '.
391
-								'TLS do not work together. Switched off TLS.',
392
-								\OCP\Util::INFO);
393
-		}
394
-	}
395
-
396
-	/**
397
-	 * @return bool
398
-	 */
399
-	private function doCriticalValidation() {
400
-		$configurationOK = true;
401
-		$errorStr = 'Configuration Error (prefix '.
402
-					strval($this->configPrefix).'): ';
403
-
404
-		//options that shall not be empty
405
-		$options = array('ldapHost', 'ldapPort', 'ldapUserDisplayName',
406
-						 'ldapGroupDisplayName', 'ldapLoginFilter');
407
-		foreach($options as $key) {
408
-			$val = $this->configuration->$key;
409
-			if(empty($val)) {
410
-				switch($key) {
411
-					case 'ldapHost':
412
-						$subj = 'LDAP Host';
413
-						break;
414
-					case 'ldapPort':
415
-						$subj = 'LDAP Port';
416
-						break;
417
-					case 'ldapUserDisplayName':
418
-						$subj = 'LDAP User Display Name';
419
-						break;
420
-					case 'ldapGroupDisplayName':
421
-						$subj = 'LDAP Group Display Name';
422
-						break;
423
-					case 'ldapLoginFilter':
424
-						$subj = 'LDAP Login Filter';
425
-						break;
426
-					default:
427
-						$subj = $key;
428
-						break;
429
-				}
430
-				$configurationOK = false;
431
-				\OCP\Util::writeLog('user_ldap',
432
-									$errorStr.'No '.$subj.' given!',
433
-									\OCP\Util::WARN);
434
-			}
435
-		}
436
-
437
-		//combinations
438
-		$agent = $this->configuration->ldapAgentName;
439
-		$pwd = $this->configuration->ldapAgentPassword;
440
-		if (
441
-			($agent === ''  && $pwd !== '')
442
-			|| ($agent !== '' && $pwd === '')
443
-		) {
444
-			\OCP\Util::writeLog('user_ldap',
445
-								$errorStr.'either no password is given for the '.
446
-								'user agent or a password is given, but not an '.
447
-								'LDAP agent.',
448
-				\OCP\Util::WARN);
449
-			$configurationOK = false;
450
-		}
451
-
452
-		$base = $this->configuration->ldapBase;
453
-		$baseUsers = $this->configuration->ldapBaseUsers;
454
-		$baseGroups = $this->configuration->ldapBaseGroups;
455
-
456
-		if(empty($base) && empty($baseUsers) && empty($baseGroups)) {
457
-			\OCP\Util::writeLog('user_ldap',
458
-								$errorStr.'Not a single Base DN given.',
459
-								\OCP\Util::WARN);
460
-			$configurationOK = false;
461
-		}
462
-
463
-		if(mb_strpos($this->configuration->ldapLoginFilter, '%uid', 0, 'UTF-8')
464
-		   === false) {
465
-			\OCP\Util::writeLog('user_ldap',
466
-								$errorStr.'login filter does not contain %uid '.
467
-								'place holder.',
468
-								\OCP\Util::WARN);
469
-			$configurationOK = false;
470
-		}
471
-
472
-		return $configurationOK;
473
-	}
474
-
475
-	/**
476
-	 * Validates the user specified configuration
477
-	 * @return bool true if configuration seems OK, false otherwise
478
-	 */
479
-	private function validateConfiguration() {
480
-
481
-		if($this->doNotValidate) {
482
-			//don't do a validation if it is a new configuration with pure
483
-			//default values. Will be allowed on changes via __set or
484
-			//setConfiguration
485
-			return false;
486
-		}
487
-
488
-		// first step: "soft" checks: settings that are not really
489
-		// necessary, but advisable. If left empty, give an info message
490
-		$this->doSoftValidation();
491
-
492
-		//second step: critical checks. If left empty or filled wrong, mark as
493
-		//not configured and give a warning.
494
-		return $this->doCriticalValidation();
495
-	}
496
-
497
-
498
-	/**
499
-	 * Connects and Binds to LDAP
500
-	 */
501
-	private function establishConnection() {
502
-		if(!$this->configuration->ldapConfigurationActive) {
503
-			return null;
504
-		}
505
-		static $phpLDAPinstalled = true;
506
-		if(!$phpLDAPinstalled) {
507
-			return false;
508
-		}
509
-		if(!$this->ignoreValidation && !$this->configured) {
510
-			\OCP\Util::writeLog('user_ldap',
511
-								'Configuration is invalid, cannot connect',
512
-								\OCP\Util::WARN);
513
-			return false;
514
-		}
515
-		if(!$this->ldapConnectionRes) {
516
-			if(!$this->ldap->areLDAPFunctionsAvailable()) {
517
-				$phpLDAPinstalled = false;
518
-				\OCP\Util::writeLog('user_ldap',
519
-									'function ldap_connect is not available. Make '.
520
-									'sure that the PHP ldap module is installed.',
521
-									\OCP\Util::ERROR);
522
-
523
-				return false;
524
-			}
525
-			if($this->configuration->turnOffCertCheck) {
526
-				if(putenv('LDAPTLS_REQCERT=never')) {
527
-					\OCP\Util::writeLog('user_ldap',
528
-						'Turned off SSL certificate validation successfully.',
529
-						\OCP\Util::DEBUG);
530
-				} else {
531
-					\OCP\Util::writeLog('user_ldap',
532
-										'Could not turn off SSL certificate validation.',
533
-										\OCP\Util::WARN);
534
-				}
535
-			}
536
-
537
-			$isOverrideMainServer = ($this->configuration->ldapOverrideMainServer
538
-				|| $this->getFromCache('overrideMainServer'));
539
-			$isBackupHost = (trim($this->configuration->ldapBackupHost) !== "");
540
-			$bindStatus = false;
541
-			$error = -1;
542
-			try {
543
-				if (!$isOverrideMainServer) {
544
-					$this->doConnect($this->configuration->ldapHost,
545
-						$this->configuration->ldapPort);
546
-					$bindStatus = $this->bind();
547
-					$error = $this->ldap->isResource($this->ldapConnectionRes) ?
548
-						$this->ldap->errno($this->ldapConnectionRes) : -1;
549
-				}
550
-				if($bindStatus === true) {
551
-					return $bindStatus;
552
-				}
553
-			} catch (ServerNotAvailableException $e) {
554
-				if(!$isBackupHost) {
555
-					throw $e;
556
-				}
557
-			}
558
-
559
-			//if LDAP server is not reachable, try the Backup (Replica!) Server
560
-			if($isBackupHost && ($error !== 0 || $isOverrideMainServer)) {
561
-				$this->doConnect($this->configuration->ldapBackupHost,
562
-								 $this->configuration->ldapBackupPort);
563
-				$bindStatus = $this->bind();
564
-				$error = $this->ldap->isResource($this->ldapConnectionRes) ?
565
-					$this->ldap->errno($this->ldapConnectionRes) : -1;
566
-				if($bindStatus && $error === 0 && !$this->getFromCache('overrideMainServer')) {
567
-					//when bind to backup server succeeded and failed to main server,
568
-					//skip contacting him until next cache refresh
569
-					$this->writeToCache('overrideMainServer', true);
570
-				}
571
-			}
572
-
573
-			return $bindStatus;
574
-		}
575
-		return null;
576
-	}
577
-
578
-	/**
579
-	 * @param string $host
580
-	 * @param string $port
581
-	 * @return bool
582
-	 * @throws \OC\ServerNotAvailableException
583
-	 */
584
-	private function doConnect($host, $port) {
585
-		if ($host === '') {
586
-			return false;
587
-		}
588
-
589
-		$this->ldapConnectionRes = $this->ldap->connect($host, $port);
590
-
591
-		if(!$this->ldap->setOption($this->ldapConnectionRes, LDAP_OPT_PROTOCOL_VERSION, 3)) {
592
-			throw new ServerNotAvailableException('Could not set required LDAP Protocol version.');
593
-		}
594
-
595
-		if(!$this->ldap->setOption($this->ldapConnectionRes, LDAP_OPT_REFERRALS, 0)) {
596
-			throw new ServerNotAvailableException('Could not disable LDAP referrals.');
597
-		}
598
-
599
-		if($this->configuration->ldapTLS) {
600
-			if(!$this->ldap->startTls($this->ldapConnectionRes)) {
601
-				throw new ServerNotAvailableException('Start TLS failed, when connecting to LDAP host ' . $host . '.');
602
-			}
603
-		}
604
-
605
-		return true;
606
-	}
607
-
608
-	/**
609
-	 * Binds to LDAP
610
-	 */
611
-	public function bind() {
612
-		if(!$this->configuration->ldapConfigurationActive) {
613
-			return false;
614
-		}
615
-		$cr = $this->getConnectionResource();
616
-		if(!$this->ldap->isResource($cr)) {
617
-			return false;
618
-		}
619
-		$ldapLogin = @$this->ldap->bind($cr,
620
-										$this->configuration->ldapAgentName,
621
-										$this->configuration->ldapAgentPassword);
622
-		if(!$ldapLogin) {
623
-			$errno = $this->ldap->errno($cr);
624
-
625
-			\OCP\Util::writeLog('user_ldap',
626
-				'Bind failed: ' . $errno . ': ' . $this->ldap->error($cr),
627
-				\OCP\Util::WARN);
628
-
629
-			// Set to failure mode, if LDAP error code is not LDAP_SUCCESS or LDAP_INVALID_CREDENTIALS
630
-			if($errno !== 0x00 && $errno !== 0x31) {
631
-				$this->ldapConnectionRes = null;
632
-			}
633
-
634
-			return false;
635
-		}
636
-		return true;
637
-	}
61
+    private $ldapConnectionRes = null;
62
+    private $configPrefix;
63
+    private $configID;
64
+    private $configured = false;
65
+    private $hasPagedResultSupport = true;
66
+    //whether connection should be kept on __destruct
67
+    private $dontDestruct = false;
68
+
69
+    /**
70
+     * @var bool runtime flag that indicates whether supported primary groups are available
71
+     */
72
+    public $hasPrimaryGroups = true;
73
+
74
+    /**
75
+     * @var bool runtime flag that indicates whether supported POSIX gidNumber are available
76
+     */
77
+    public $hasGidNumber = true;
78
+
79
+    //cache handler
80
+    protected $cache;
81
+
82
+    /** @var Configuration settings handler **/
83
+    protected $configuration;
84
+
85
+    protected $doNotValidate = false;
86
+
87
+    protected $ignoreValidation = false;
88
+
89
+    /**
90
+     * Constructor
91
+     * @param ILDAPWrapper $ldap
92
+     * @param string $configPrefix a string with the prefix for the configkey column (appconfig table)
93
+     * @param string|null $configID a string with the value for the appid column (appconfig table) or null for on-the-fly connections
94
+     */
95
+    public function __construct(ILDAPWrapper $ldap, $configPrefix = '', $configID = 'user_ldap') {
96
+        parent::__construct($ldap);
97
+        $this->configPrefix = $configPrefix;
98
+        $this->configID = $configID;
99
+        $this->configuration = new Configuration($configPrefix,
100
+                                                    !is_null($configID));
101
+        $memcache = \OC::$server->getMemCacheFactory();
102
+        if($memcache->isAvailable()) {
103
+            $this->cache = $memcache->createDistributed();
104
+        }
105
+        $helper = new Helper(\OC::$server->getConfig());
106
+        $this->doNotValidate = !in_array($this->configPrefix,
107
+            $helper->getServerConfigurationPrefixes());
108
+        $this->hasPagedResultSupport =
109
+            intval($this->configuration->ldapPagingSize) !== 0
110
+            || $this->ldap->hasPagedResultSupport();
111
+    }
112
+
113
+    public function __destruct() {
114
+        if(!$this->dontDestruct && $this->ldap->isResource($this->ldapConnectionRes)) {
115
+            @$this->ldap->unbind($this->ldapConnectionRes);
116
+        };
117
+    }
118
+
119
+    /**
120
+     * defines behaviour when the instance is cloned
121
+     */
122
+    public function __clone() {
123
+        $this->configuration = new Configuration($this->configPrefix,
124
+                                                    !is_null($this->configID));
125
+        $this->ldapConnectionRes = null;
126
+        $this->dontDestruct = true;
127
+    }
128
+
129
+    /**
130
+     * @param string $name
131
+     * @return bool|mixed
132
+     */
133
+    public function __get($name) {
134
+        if(!$this->configured) {
135
+            $this->readConfiguration();
136
+        }
137
+
138
+        if($name === 'hasPagedResultSupport') {
139
+            return $this->hasPagedResultSupport;
140
+        }
141
+
142
+        return $this->configuration->$name;
143
+    }
144
+
145
+    /**
146
+     * @param string $name
147
+     * @param mixed $value
148
+     */
149
+    public function __set($name, $value) {
150
+        $this->doNotValidate = false;
151
+        $before = $this->configuration->$name;
152
+        $this->configuration->$name = $value;
153
+        $after = $this->configuration->$name;
154
+        if($before !== $after) {
155
+            if ($this->configID !== '' && $this->configID !== null) {
156
+                $this->configuration->saveConfiguration();
157
+            }
158
+            $this->validateConfiguration();
159
+        }
160
+    }
161
+
162
+    /**
163
+     * sets whether the result of the configuration validation shall
164
+     * be ignored when establishing the connection. Used by the Wizard
165
+     * in early configuration state.
166
+     * @param bool $state
167
+     */
168
+    public function setIgnoreValidation($state) {
169
+        $this->ignoreValidation = (bool)$state;
170
+    }
171
+
172
+    /**
173
+     * initializes the LDAP backend
174
+     * @param bool $force read the config settings no matter what
175
+     */
176
+    public function init($force = false) {
177
+        $this->readConfiguration($force);
178
+        $this->establishConnection();
179
+    }
180
+
181
+    /**
182
+     * Returns the LDAP handler
183
+     */
184
+    public function getConnectionResource() {
185
+        if(!$this->ldapConnectionRes) {
186
+            $this->init();
187
+        } else if(!$this->ldap->isResource($this->ldapConnectionRes)) {
188
+            $this->ldapConnectionRes = null;
189
+            $this->establishConnection();
190
+        }
191
+        if(is_null($this->ldapConnectionRes)) {
192
+            \OCP\Util::writeLog('user_ldap', 'No LDAP Connection to server ' . $this->configuration->ldapHost, \OCP\Util::ERROR);
193
+            throw new ServerNotAvailableException('Connection to LDAP server could not be established');
194
+        }
195
+        return $this->ldapConnectionRes;
196
+    }
197
+
198
+    /**
199
+     * resets the connection resource
200
+     */
201
+    public function resetConnectionResource() {
202
+        if(!is_null($this->ldapConnectionRes)) {
203
+            @$this->ldap->unbind($this->ldapConnectionRes);
204
+            $this->ldapConnectionRes = null;
205
+        }
206
+    }
207
+
208
+    /**
209
+     * @param string|null $key
210
+     * @return string
211
+     */
212
+    private function getCacheKey($key) {
213
+        $prefix = 'LDAP-'.$this->configID.'-'.$this->configPrefix.'-';
214
+        if(is_null($key)) {
215
+            return $prefix;
216
+        }
217
+        return $prefix.md5($key);
218
+    }
219
+
220
+    /**
221
+     * @param string $key
222
+     * @return mixed|null
223
+     */
224
+    public function getFromCache($key) {
225
+        if(!$this->configured) {
226
+            $this->readConfiguration();
227
+        }
228
+        if(is_null($this->cache) || !$this->configuration->ldapCacheTTL) {
229
+            return null;
230
+        }
231
+        $key = $this->getCacheKey($key);
232
+
233
+        return json_decode(base64_decode($this->cache->get($key)), true);
234
+    }
235
+
236
+    /**
237
+     * @param string $key
238
+     * @param mixed $value
239
+     *
240
+     * @return string
241
+     */
242
+    public function writeToCache($key, $value) {
243
+        if(!$this->configured) {
244
+            $this->readConfiguration();
245
+        }
246
+        if(is_null($this->cache)
247
+            || !$this->configuration->ldapCacheTTL
248
+            || !$this->configuration->ldapConfigurationActive) {
249
+            return null;
250
+        }
251
+        $key   = $this->getCacheKey($key);
252
+        $value = base64_encode(json_encode($value));
253
+        $this->cache->set($key, $value, $this->configuration->ldapCacheTTL);
254
+    }
255
+
256
+    public function clearCache() {
257
+        if(!is_null($this->cache)) {
258
+            $this->cache->clear($this->getCacheKey(null));
259
+        }
260
+    }
261
+
262
+    /**
263
+     * Caches the general LDAP configuration.
264
+     * @param bool $force optional. true, if the re-read should be forced. defaults
265
+     * to false.
266
+     * @return null
267
+     */
268
+    private function readConfiguration($force = false) {
269
+        if((!$this->configured || $force) && !is_null($this->configID)) {
270
+            $this->configuration->readConfiguration();
271
+            $this->configured = $this->validateConfiguration();
272
+        }
273
+    }
274
+
275
+    /**
276
+     * set LDAP configuration with values delivered by an array, not read from configuration
277
+     * @param array $config array that holds the config parameters in an associated array
278
+     * @param array &$setParameters optional; array where the set fields will be given to
279
+     * @return boolean true if config validates, false otherwise. Check with $setParameters for detailed success on single parameters
280
+     */
281
+    public function setConfiguration($config, &$setParameters = null) {
282
+        if(is_null($setParameters)) {
283
+            $setParameters = array();
284
+        }
285
+        $this->doNotValidate = false;
286
+        $this->configuration->setConfiguration($config, $setParameters);
287
+        if(count($setParameters) > 0) {
288
+            $this->configured = $this->validateConfiguration();
289
+        }
290
+
291
+
292
+        return $this->configured;
293
+    }
294
+
295
+    /**
296
+     * saves the current Configuration in the database and empties the
297
+     * cache
298
+     * @return null
299
+     */
300
+    public function saveConfiguration() {
301
+        $this->configuration->saveConfiguration();
302
+        $this->clearCache();
303
+    }
304
+
305
+    /**
306
+     * get the current LDAP configuration
307
+     * @return array
308
+     */
309
+    public function getConfiguration() {
310
+        $this->readConfiguration();
311
+        $config = $this->configuration->getConfiguration();
312
+        $cta = $this->configuration->getConfigTranslationArray();
313
+        $result = array();
314
+        foreach($cta as $dbkey => $configkey) {
315
+            switch($configkey) {
316
+                case 'homeFolderNamingRule':
317
+                    if(strpos($config[$configkey], 'attr:') === 0) {
318
+                        $result[$dbkey] = substr($config[$configkey], 5);
319
+                    } else {
320
+                        $result[$dbkey] = '';
321
+                    }
322
+                    break;
323
+                case 'ldapBase':
324
+                case 'ldapBaseUsers':
325
+                case 'ldapBaseGroups':
326
+                case 'ldapAttributesForUserSearch':
327
+                case 'ldapAttributesForGroupSearch':
328
+                    if(is_array($config[$configkey])) {
329
+                        $result[$dbkey] = implode("\n", $config[$configkey]);
330
+                        break;
331
+                    } //else follows default
332
+                default:
333
+                    $result[$dbkey] = $config[$configkey];
334
+            }
335
+        }
336
+        return $result;
337
+    }
338
+
339
+    private function doSoftValidation() {
340
+        //if User or Group Base are not set, take over Base DN setting
341
+        foreach(array('ldapBaseUsers', 'ldapBaseGroups') as $keyBase) {
342
+            $val = $this->configuration->$keyBase;
343
+            if(empty($val)) {
344
+                $this->configuration->$keyBase = $this->configuration->ldapBase;
345
+            }
346
+        }
347
+
348
+        foreach(array('ldapExpertUUIDUserAttr'  => 'ldapUuidUserAttribute',
349
+                        'ldapExpertUUIDGroupAttr' => 'ldapUuidGroupAttribute')
350
+                as $expertSetting => $effectiveSetting) {
351
+            $uuidOverride = $this->configuration->$expertSetting;
352
+            if(!empty($uuidOverride)) {
353
+                $this->configuration->$effectiveSetting = $uuidOverride;
354
+            } else {
355
+                $uuidAttributes = Access::UUID_ATTRIBUTES;
356
+                array_unshift($uuidAttributes, 'auto');
357
+                if(!in_array($this->configuration->$effectiveSetting,
358
+                            $uuidAttributes)
359
+                    && (!is_null($this->configID))) {
360
+                    $this->configuration->$effectiveSetting = 'auto';
361
+                    $this->configuration->saveConfiguration();
362
+                    \OCP\Util::writeLog('user_ldap',
363
+                                        'Illegal value for the '.
364
+                                        $effectiveSetting.', '.'reset to '.
365
+                                        'autodetect.', \OCP\Util::INFO);
366
+                }
367
+
368
+            }
369
+        }
370
+
371
+        $backupPort = intval($this->configuration->ldapBackupPort);
372
+        if ($backupPort <= 0) {
373
+            $this->configuration->backupPort = $this->configuration->ldapPort;
374
+        }
375
+
376
+        //make sure empty search attributes are saved as simple, empty array
377
+        $saKeys = array('ldapAttributesForUserSearch',
378
+                        'ldapAttributesForGroupSearch');
379
+        foreach($saKeys as $key) {
380
+            $val = $this->configuration->$key;
381
+            if(is_array($val) && count($val) === 1 && empty($val[0])) {
382
+                $this->configuration->$key = array();
383
+            }
384
+        }
385
+
386
+        if((stripos($this->configuration->ldapHost, 'ldaps://') === 0)
387
+            && $this->configuration->ldapTLS) {
388
+            $this->configuration->ldapTLS = false;
389
+            \OCP\Util::writeLog('user_ldap',
390
+                                'LDAPS (already using secure connection) and '.
391
+                                'TLS do not work together. Switched off TLS.',
392
+                                \OCP\Util::INFO);
393
+        }
394
+    }
395
+
396
+    /**
397
+     * @return bool
398
+     */
399
+    private function doCriticalValidation() {
400
+        $configurationOK = true;
401
+        $errorStr = 'Configuration Error (prefix '.
402
+                    strval($this->configPrefix).'): ';
403
+
404
+        //options that shall not be empty
405
+        $options = array('ldapHost', 'ldapPort', 'ldapUserDisplayName',
406
+                            'ldapGroupDisplayName', 'ldapLoginFilter');
407
+        foreach($options as $key) {
408
+            $val = $this->configuration->$key;
409
+            if(empty($val)) {
410
+                switch($key) {
411
+                    case 'ldapHost':
412
+                        $subj = 'LDAP Host';
413
+                        break;
414
+                    case 'ldapPort':
415
+                        $subj = 'LDAP Port';
416
+                        break;
417
+                    case 'ldapUserDisplayName':
418
+                        $subj = 'LDAP User Display Name';
419
+                        break;
420
+                    case 'ldapGroupDisplayName':
421
+                        $subj = 'LDAP Group Display Name';
422
+                        break;
423
+                    case 'ldapLoginFilter':
424
+                        $subj = 'LDAP Login Filter';
425
+                        break;
426
+                    default:
427
+                        $subj = $key;
428
+                        break;
429
+                }
430
+                $configurationOK = false;
431
+                \OCP\Util::writeLog('user_ldap',
432
+                                    $errorStr.'No '.$subj.' given!',
433
+                                    \OCP\Util::WARN);
434
+            }
435
+        }
436
+
437
+        //combinations
438
+        $agent = $this->configuration->ldapAgentName;
439
+        $pwd = $this->configuration->ldapAgentPassword;
440
+        if (
441
+            ($agent === ''  && $pwd !== '')
442
+            || ($agent !== '' && $pwd === '')
443
+        ) {
444
+            \OCP\Util::writeLog('user_ldap',
445
+                                $errorStr.'either no password is given for the '.
446
+                                'user agent or a password is given, but not an '.
447
+                                'LDAP agent.',
448
+                \OCP\Util::WARN);
449
+            $configurationOK = false;
450
+        }
451
+
452
+        $base = $this->configuration->ldapBase;
453
+        $baseUsers = $this->configuration->ldapBaseUsers;
454
+        $baseGroups = $this->configuration->ldapBaseGroups;
455
+
456
+        if(empty($base) && empty($baseUsers) && empty($baseGroups)) {
457
+            \OCP\Util::writeLog('user_ldap',
458
+                                $errorStr.'Not a single Base DN given.',
459
+                                \OCP\Util::WARN);
460
+            $configurationOK = false;
461
+        }
462
+
463
+        if(mb_strpos($this->configuration->ldapLoginFilter, '%uid', 0, 'UTF-8')
464
+            === false) {
465
+            \OCP\Util::writeLog('user_ldap',
466
+                                $errorStr.'login filter does not contain %uid '.
467
+                                'place holder.',
468
+                                \OCP\Util::WARN);
469
+            $configurationOK = false;
470
+        }
471
+
472
+        return $configurationOK;
473
+    }
474
+
475
+    /**
476
+     * Validates the user specified configuration
477
+     * @return bool true if configuration seems OK, false otherwise
478
+     */
479
+    private function validateConfiguration() {
480
+
481
+        if($this->doNotValidate) {
482
+            //don't do a validation if it is a new configuration with pure
483
+            //default values. Will be allowed on changes via __set or
484
+            //setConfiguration
485
+            return false;
486
+        }
487
+
488
+        // first step: "soft" checks: settings that are not really
489
+        // necessary, but advisable. If left empty, give an info message
490
+        $this->doSoftValidation();
491
+
492
+        //second step: critical checks. If left empty or filled wrong, mark as
493
+        //not configured and give a warning.
494
+        return $this->doCriticalValidation();
495
+    }
496
+
497
+
498
+    /**
499
+     * Connects and Binds to LDAP
500
+     */
501
+    private function establishConnection() {
502
+        if(!$this->configuration->ldapConfigurationActive) {
503
+            return null;
504
+        }
505
+        static $phpLDAPinstalled = true;
506
+        if(!$phpLDAPinstalled) {
507
+            return false;
508
+        }
509
+        if(!$this->ignoreValidation && !$this->configured) {
510
+            \OCP\Util::writeLog('user_ldap',
511
+                                'Configuration is invalid, cannot connect',
512
+                                \OCP\Util::WARN);
513
+            return false;
514
+        }
515
+        if(!$this->ldapConnectionRes) {
516
+            if(!$this->ldap->areLDAPFunctionsAvailable()) {
517
+                $phpLDAPinstalled = false;
518
+                \OCP\Util::writeLog('user_ldap',
519
+                                    'function ldap_connect is not available. Make '.
520
+                                    'sure that the PHP ldap module is installed.',
521
+                                    \OCP\Util::ERROR);
522
+
523
+                return false;
524
+            }
525
+            if($this->configuration->turnOffCertCheck) {
526
+                if(putenv('LDAPTLS_REQCERT=never')) {
527
+                    \OCP\Util::writeLog('user_ldap',
528
+                        'Turned off SSL certificate validation successfully.',
529
+                        \OCP\Util::DEBUG);
530
+                } else {
531
+                    \OCP\Util::writeLog('user_ldap',
532
+                                        'Could not turn off SSL certificate validation.',
533
+                                        \OCP\Util::WARN);
534
+                }
535
+            }
536
+
537
+            $isOverrideMainServer = ($this->configuration->ldapOverrideMainServer
538
+                || $this->getFromCache('overrideMainServer'));
539
+            $isBackupHost = (trim($this->configuration->ldapBackupHost) !== "");
540
+            $bindStatus = false;
541
+            $error = -1;
542
+            try {
543
+                if (!$isOverrideMainServer) {
544
+                    $this->doConnect($this->configuration->ldapHost,
545
+                        $this->configuration->ldapPort);
546
+                    $bindStatus = $this->bind();
547
+                    $error = $this->ldap->isResource($this->ldapConnectionRes) ?
548
+                        $this->ldap->errno($this->ldapConnectionRes) : -1;
549
+                }
550
+                if($bindStatus === true) {
551
+                    return $bindStatus;
552
+                }
553
+            } catch (ServerNotAvailableException $e) {
554
+                if(!$isBackupHost) {
555
+                    throw $e;
556
+                }
557
+            }
558
+
559
+            //if LDAP server is not reachable, try the Backup (Replica!) Server
560
+            if($isBackupHost && ($error !== 0 || $isOverrideMainServer)) {
561
+                $this->doConnect($this->configuration->ldapBackupHost,
562
+                                    $this->configuration->ldapBackupPort);
563
+                $bindStatus = $this->bind();
564
+                $error = $this->ldap->isResource($this->ldapConnectionRes) ?
565
+                    $this->ldap->errno($this->ldapConnectionRes) : -1;
566
+                if($bindStatus && $error === 0 && !$this->getFromCache('overrideMainServer')) {
567
+                    //when bind to backup server succeeded and failed to main server,
568
+                    //skip contacting him until next cache refresh
569
+                    $this->writeToCache('overrideMainServer', true);
570
+                }
571
+            }
572
+
573
+            return $bindStatus;
574
+        }
575
+        return null;
576
+    }
577
+
578
+    /**
579
+     * @param string $host
580
+     * @param string $port
581
+     * @return bool
582
+     * @throws \OC\ServerNotAvailableException
583
+     */
584
+    private function doConnect($host, $port) {
585
+        if ($host === '') {
586
+            return false;
587
+        }
588
+
589
+        $this->ldapConnectionRes = $this->ldap->connect($host, $port);
590
+
591
+        if(!$this->ldap->setOption($this->ldapConnectionRes, LDAP_OPT_PROTOCOL_VERSION, 3)) {
592
+            throw new ServerNotAvailableException('Could not set required LDAP Protocol version.');
593
+        }
594
+
595
+        if(!$this->ldap->setOption($this->ldapConnectionRes, LDAP_OPT_REFERRALS, 0)) {
596
+            throw new ServerNotAvailableException('Could not disable LDAP referrals.');
597
+        }
598
+
599
+        if($this->configuration->ldapTLS) {
600
+            if(!$this->ldap->startTls($this->ldapConnectionRes)) {
601
+                throw new ServerNotAvailableException('Start TLS failed, when connecting to LDAP host ' . $host . '.');
602
+            }
603
+        }
604
+
605
+        return true;
606
+    }
607
+
608
+    /**
609
+     * Binds to LDAP
610
+     */
611
+    public function bind() {
612
+        if(!$this->configuration->ldapConfigurationActive) {
613
+            return false;
614
+        }
615
+        $cr = $this->getConnectionResource();
616
+        if(!$this->ldap->isResource($cr)) {
617
+            return false;
618
+        }
619
+        $ldapLogin = @$this->ldap->bind($cr,
620
+                                        $this->configuration->ldapAgentName,
621
+                                        $this->configuration->ldapAgentPassword);
622
+        if(!$ldapLogin) {
623
+            $errno = $this->ldap->errno($cr);
624
+
625
+            \OCP\Util::writeLog('user_ldap',
626
+                'Bind failed: ' . $errno . ': ' . $this->ldap->error($cr),
627
+                \OCP\Util::WARN);
628
+
629
+            // Set to failure mode, if LDAP error code is not LDAP_SUCCESS or LDAP_INVALID_CREDENTIALS
630
+            if($errno !== 0x00 && $errno !== 0x31) {
631
+                $this->ldapConnectionRes = null;
632
+            }
633
+
634
+            return false;
635
+        }
636
+        return true;
637
+    }
638 638
 
639 639
 }
Please login to merge, or discard this patch.
Spacing   +60 added lines, -60 removed lines patch added patch discarded remove patch
@@ -99,7 +99,7 @@  discard block
 block discarded – undo
99 99
 		$this->configuration = new Configuration($configPrefix,
100 100
 												 !is_null($configID));
101 101
 		$memcache = \OC::$server->getMemCacheFactory();
102
-		if($memcache->isAvailable()) {
102
+		if ($memcache->isAvailable()) {
103 103
 			$this->cache = $memcache->createDistributed();
104 104
 		}
105 105
 		$helper = new Helper(\OC::$server->getConfig());
@@ -111,7 +111,7 @@  discard block
 block discarded – undo
111 111
 	}
112 112
 
113 113
 	public function __destruct() {
114
-		if(!$this->dontDestruct && $this->ldap->isResource($this->ldapConnectionRes)) {
114
+		if (!$this->dontDestruct && $this->ldap->isResource($this->ldapConnectionRes)) {
115 115
 			@$this->ldap->unbind($this->ldapConnectionRes);
116 116
 		};
117 117
 	}
@@ -131,11 +131,11 @@  discard block
 block discarded – undo
131 131
 	 * @return bool|mixed
132 132
 	 */
133 133
 	public function __get($name) {
134
-		if(!$this->configured) {
134
+		if (!$this->configured) {
135 135
 			$this->readConfiguration();
136 136
 		}
137 137
 
138
-		if($name === 'hasPagedResultSupport') {
138
+		if ($name === 'hasPagedResultSupport') {
139 139
 			return $this->hasPagedResultSupport;
140 140
 		}
141 141
 
@@ -151,7 +151,7 @@  discard block
 block discarded – undo
151 151
 		$before = $this->configuration->$name;
152 152
 		$this->configuration->$name = $value;
153 153
 		$after = $this->configuration->$name;
154
-		if($before !== $after) {
154
+		if ($before !== $after) {
155 155
 			if ($this->configID !== '' && $this->configID !== null) {
156 156
 				$this->configuration->saveConfiguration();
157 157
 			}
@@ -166,7 +166,7 @@  discard block
 block discarded – undo
166 166
 	 * @param bool $state
167 167
 	 */
168 168
 	public function setIgnoreValidation($state) {
169
-		$this->ignoreValidation = (bool)$state;
169
+		$this->ignoreValidation = (bool) $state;
170 170
 	}
171 171
 
172 172
 	/**
@@ -182,14 +182,14 @@  discard block
 block discarded – undo
182 182
 	 * Returns the LDAP handler
183 183
 	 */
184 184
 	public function getConnectionResource() {
185
-		if(!$this->ldapConnectionRes) {
185
+		if (!$this->ldapConnectionRes) {
186 186
 			$this->init();
187
-		} else if(!$this->ldap->isResource($this->ldapConnectionRes)) {
187
+		} else if (!$this->ldap->isResource($this->ldapConnectionRes)) {
188 188
 			$this->ldapConnectionRes = null;
189 189
 			$this->establishConnection();
190 190
 		}
191
-		if(is_null($this->ldapConnectionRes)) {
192
-			\OCP\Util::writeLog('user_ldap', 'No LDAP Connection to server ' . $this->configuration->ldapHost, \OCP\Util::ERROR);
191
+		if (is_null($this->ldapConnectionRes)) {
192
+			\OCP\Util::writeLog('user_ldap', 'No LDAP Connection to server '.$this->configuration->ldapHost, \OCP\Util::ERROR);
193 193
 			throw new ServerNotAvailableException('Connection to LDAP server could not be established');
194 194
 		}
195 195
 		return $this->ldapConnectionRes;
@@ -199,7 +199,7 @@  discard block
 block discarded – undo
199 199
 	 * resets the connection resource
200 200
 	 */
201 201
 	public function resetConnectionResource() {
202
-		if(!is_null($this->ldapConnectionRes)) {
202
+		if (!is_null($this->ldapConnectionRes)) {
203 203
 			@$this->ldap->unbind($this->ldapConnectionRes);
204 204
 			$this->ldapConnectionRes = null;
205 205
 		}
@@ -211,7 +211,7 @@  discard block
 block discarded – undo
211 211
 	 */
212 212
 	private function getCacheKey($key) {
213 213
 		$prefix = 'LDAP-'.$this->configID.'-'.$this->configPrefix.'-';
214
-		if(is_null($key)) {
214
+		if (is_null($key)) {
215 215
 			return $prefix;
216 216
 		}
217 217
 		return $prefix.md5($key);
@@ -222,10 +222,10 @@  discard block
 block discarded – undo
222 222
 	 * @return mixed|null
223 223
 	 */
224 224
 	public function getFromCache($key) {
225
-		if(!$this->configured) {
225
+		if (!$this->configured) {
226 226
 			$this->readConfiguration();
227 227
 		}
228
-		if(is_null($this->cache) || !$this->configuration->ldapCacheTTL) {
228
+		if (is_null($this->cache) || !$this->configuration->ldapCacheTTL) {
229 229
 			return null;
230 230
 		}
231 231
 		$key = $this->getCacheKey($key);
@@ -240,10 +240,10 @@  discard block
 block discarded – undo
240 240
 	 * @return string
241 241
 	 */
242 242
 	public function writeToCache($key, $value) {
243
-		if(!$this->configured) {
243
+		if (!$this->configured) {
244 244
 			$this->readConfiguration();
245 245
 		}
246
-		if(is_null($this->cache)
246
+		if (is_null($this->cache)
247 247
 			|| !$this->configuration->ldapCacheTTL
248 248
 			|| !$this->configuration->ldapConfigurationActive) {
249 249
 			return null;
@@ -254,7 +254,7 @@  discard block
 block discarded – undo
254 254
 	}
255 255
 
256 256
 	public function clearCache() {
257
-		if(!is_null($this->cache)) {
257
+		if (!is_null($this->cache)) {
258 258
 			$this->cache->clear($this->getCacheKey(null));
259 259
 		}
260 260
 	}
@@ -266,7 +266,7 @@  discard block
 block discarded – undo
266 266
 	 * @return null
267 267
 	 */
268 268
 	private function readConfiguration($force = false) {
269
-		if((!$this->configured || $force) && !is_null($this->configID)) {
269
+		if ((!$this->configured || $force) && !is_null($this->configID)) {
270 270
 			$this->configuration->readConfiguration();
271 271
 			$this->configured = $this->validateConfiguration();
272 272
 		}
@@ -279,12 +279,12 @@  discard block
 block discarded – undo
279 279
 	 * @return boolean true if config validates, false otherwise. Check with $setParameters for detailed success on single parameters
280 280
 	 */
281 281
 	public function setConfiguration($config, &$setParameters = null) {
282
-		if(is_null($setParameters)) {
282
+		if (is_null($setParameters)) {
283 283
 			$setParameters = array();
284 284
 		}
285 285
 		$this->doNotValidate = false;
286 286
 		$this->configuration->setConfiguration($config, $setParameters);
287
-		if(count($setParameters) > 0) {
287
+		if (count($setParameters) > 0) {
288 288
 			$this->configured = $this->validateConfiguration();
289 289
 		}
290 290
 
@@ -311,10 +311,10 @@  discard block
 block discarded – undo
311 311
 		$config = $this->configuration->getConfiguration();
312 312
 		$cta = $this->configuration->getConfigTranslationArray();
313 313
 		$result = array();
314
-		foreach($cta as $dbkey => $configkey) {
315
-			switch($configkey) {
314
+		foreach ($cta as $dbkey => $configkey) {
315
+			switch ($configkey) {
316 316
 				case 'homeFolderNamingRule':
317
-					if(strpos($config[$configkey], 'attr:') === 0) {
317
+					if (strpos($config[$configkey], 'attr:') === 0) {
318 318
 						$result[$dbkey] = substr($config[$configkey], 5);
319 319
 					} else {
320 320
 						$result[$dbkey] = '';
@@ -325,7 +325,7 @@  discard block
 block discarded – undo
325 325
 				case 'ldapBaseGroups':
326 326
 				case 'ldapAttributesForUserSearch':
327 327
 				case 'ldapAttributesForGroupSearch':
328
-					if(is_array($config[$configkey])) {
328
+					if (is_array($config[$configkey])) {
329 329
 						$result[$dbkey] = implode("\n", $config[$configkey]);
330 330
 						break;
331 331
 					} //else follows default
@@ -338,23 +338,23 @@  discard block
 block discarded – undo
338 338
 
339 339
 	private function doSoftValidation() {
340 340
 		//if User or Group Base are not set, take over Base DN setting
341
-		foreach(array('ldapBaseUsers', 'ldapBaseGroups') as $keyBase) {
341
+		foreach (array('ldapBaseUsers', 'ldapBaseGroups') as $keyBase) {
342 342
 			$val = $this->configuration->$keyBase;
343
-			if(empty($val)) {
343
+			if (empty($val)) {
344 344
 				$this->configuration->$keyBase = $this->configuration->ldapBase;
345 345
 			}
346 346
 		}
347 347
 
348
-		foreach(array('ldapExpertUUIDUserAttr'  => 'ldapUuidUserAttribute',
348
+		foreach (array('ldapExpertUUIDUserAttr'  => 'ldapUuidUserAttribute',
349 349
 					  'ldapExpertUUIDGroupAttr' => 'ldapUuidGroupAttribute')
350 350
 				as $expertSetting => $effectiveSetting) {
351 351
 			$uuidOverride = $this->configuration->$expertSetting;
352
-			if(!empty($uuidOverride)) {
352
+			if (!empty($uuidOverride)) {
353 353
 				$this->configuration->$effectiveSetting = $uuidOverride;
354 354
 			} else {
355 355
 				$uuidAttributes = Access::UUID_ATTRIBUTES;
356 356
 				array_unshift($uuidAttributes, 'auto');
357
-				if(!in_array($this->configuration->$effectiveSetting,
357
+				if (!in_array($this->configuration->$effectiveSetting,
358 358
 							$uuidAttributes)
359 359
 					&& (!is_null($this->configID))) {
360 360
 					$this->configuration->$effectiveSetting = 'auto';
@@ -376,14 +376,14 @@  discard block
 block discarded – undo
376 376
 		//make sure empty search attributes are saved as simple, empty array
377 377
 		$saKeys = array('ldapAttributesForUserSearch',
378 378
 						'ldapAttributesForGroupSearch');
379
-		foreach($saKeys as $key) {
379
+		foreach ($saKeys as $key) {
380 380
 			$val = $this->configuration->$key;
381
-			if(is_array($val) && count($val) === 1 && empty($val[0])) {
381
+			if (is_array($val) && count($val) === 1 && empty($val[0])) {
382 382
 				$this->configuration->$key = array();
383 383
 			}
384 384
 		}
385 385
 
386
-		if((stripos($this->configuration->ldapHost, 'ldaps://') === 0)
386
+		if ((stripos($this->configuration->ldapHost, 'ldaps://') === 0)
387 387
 			&& $this->configuration->ldapTLS) {
388 388
 			$this->configuration->ldapTLS = false;
389 389
 			\OCP\Util::writeLog('user_ldap',
@@ -404,10 +404,10 @@  discard block
 block discarded – undo
404 404
 		//options that shall not be empty
405 405
 		$options = array('ldapHost', 'ldapPort', 'ldapUserDisplayName',
406 406
 						 'ldapGroupDisplayName', 'ldapLoginFilter');
407
-		foreach($options as $key) {
407
+		foreach ($options as $key) {
408 408
 			$val = $this->configuration->$key;
409
-			if(empty($val)) {
410
-				switch($key) {
409
+			if (empty($val)) {
410
+				switch ($key) {
411 411
 					case 'ldapHost':
412 412
 						$subj = 'LDAP Host';
413 413
 						break;
@@ -438,7 +438,7 @@  discard block
 block discarded – undo
438 438
 		$agent = $this->configuration->ldapAgentName;
439 439
 		$pwd = $this->configuration->ldapAgentPassword;
440 440
 		if (
441
-			($agent === ''  && $pwd !== '')
441
+			($agent === '' && $pwd !== '')
442 442
 			|| ($agent !== '' && $pwd === '')
443 443
 		) {
444 444
 			\OCP\Util::writeLog('user_ldap',
@@ -453,14 +453,14 @@  discard block
 block discarded – undo
453 453
 		$baseUsers = $this->configuration->ldapBaseUsers;
454 454
 		$baseGroups = $this->configuration->ldapBaseGroups;
455 455
 
456
-		if(empty($base) && empty($baseUsers) && empty($baseGroups)) {
456
+		if (empty($base) && empty($baseUsers) && empty($baseGroups)) {
457 457
 			\OCP\Util::writeLog('user_ldap',
458 458
 								$errorStr.'Not a single Base DN given.',
459 459
 								\OCP\Util::WARN);
460 460
 			$configurationOK = false;
461 461
 		}
462 462
 
463
-		if(mb_strpos($this->configuration->ldapLoginFilter, '%uid', 0, 'UTF-8')
463
+		if (mb_strpos($this->configuration->ldapLoginFilter, '%uid', 0, 'UTF-8')
464 464
 		   === false) {
465 465
 			\OCP\Util::writeLog('user_ldap',
466 466
 								$errorStr.'login filter does not contain %uid '.
@@ -478,7 +478,7 @@  discard block
 block discarded – undo
478 478
 	 */
479 479
 	private function validateConfiguration() {
480 480
 
481
-		if($this->doNotValidate) {
481
+		if ($this->doNotValidate) {
482 482
 			//don't do a validation if it is a new configuration with pure
483 483
 			//default values. Will be allowed on changes via __set or
484 484
 			//setConfiguration
@@ -499,21 +499,21 @@  discard block
 block discarded – undo
499 499
 	 * Connects and Binds to LDAP
500 500
 	 */
501 501
 	private function establishConnection() {
502
-		if(!$this->configuration->ldapConfigurationActive) {
502
+		if (!$this->configuration->ldapConfigurationActive) {
503 503
 			return null;
504 504
 		}
505 505
 		static $phpLDAPinstalled = true;
506
-		if(!$phpLDAPinstalled) {
506
+		if (!$phpLDAPinstalled) {
507 507
 			return false;
508 508
 		}
509
-		if(!$this->ignoreValidation && !$this->configured) {
509
+		if (!$this->ignoreValidation && !$this->configured) {
510 510
 			\OCP\Util::writeLog('user_ldap',
511 511
 								'Configuration is invalid, cannot connect',
512 512
 								\OCP\Util::WARN);
513 513
 			return false;
514 514
 		}
515
-		if(!$this->ldapConnectionRes) {
516
-			if(!$this->ldap->areLDAPFunctionsAvailable()) {
515
+		if (!$this->ldapConnectionRes) {
516
+			if (!$this->ldap->areLDAPFunctionsAvailable()) {
517 517
 				$phpLDAPinstalled = false;
518 518
 				\OCP\Util::writeLog('user_ldap',
519 519
 									'function ldap_connect is not available. Make '.
@@ -522,8 +522,8 @@  discard block
 block discarded – undo
522 522
 
523 523
 				return false;
524 524
 			}
525
-			if($this->configuration->turnOffCertCheck) {
526
-				if(putenv('LDAPTLS_REQCERT=never')) {
525
+			if ($this->configuration->turnOffCertCheck) {
526
+				if (putenv('LDAPTLS_REQCERT=never')) {
527 527
 					\OCP\Util::writeLog('user_ldap',
528 528
 						'Turned off SSL certificate validation successfully.',
529 529
 						\OCP\Util::DEBUG);
@@ -547,23 +547,23 @@  discard block
 block discarded – undo
547 547
 					$error = $this->ldap->isResource($this->ldapConnectionRes) ?
548 548
 						$this->ldap->errno($this->ldapConnectionRes) : -1;
549 549
 				}
550
-				if($bindStatus === true) {
550
+				if ($bindStatus === true) {
551 551
 					return $bindStatus;
552 552
 				}
553 553
 			} catch (ServerNotAvailableException $e) {
554
-				if(!$isBackupHost) {
554
+				if (!$isBackupHost) {
555 555
 					throw $e;
556 556
 				}
557 557
 			}
558 558
 
559 559
 			//if LDAP server is not reachable, try the Backup (Replica!) Server
560
-			if($isBackupHost && ($error !== 0 || $isOverrideMainServer)) {
560
+			if ($isBackupHost && ($error !== 0 || $isOverrideMainServer)) {
561 561
 				$this->doConnect($this->configuration->ldapBackupHost,
562 562
 								 $this->configuration->ldapBackupPort);
563 563
 				$bindStatus = $this->bind();
564 564
 				$error = $this->ldap->isResource($this->ldapConnectionRes) ?
565 565
 					$this->ldap->errno($this->ldapConnectionRes) : -1;
566
-				if($bindStatus && $error === 0 && !$this->getFromCache('overrideMainServer')) {
566
+				if ($bindStatus && $error === 0 && !$this->getFromCache('overrideMainServer')) {
567 567
 					//when bind to backup server succeeded and failed to main server,
568 568
 					//skip contacting him until next cache refresh
569 569
 					$this->writeToCache('overrideMainServer', true);
@@ -588,17 +588,17 @@  discard block
 block discarded – undo
588 588
 
589 589
 		$this->ldapConnectionRes = $this->ldap->connect($host, $port);
590 590
 
591
-		if(!$this->ldap->setOption($this->ldapConnectionRes, LDAP_OPT_PROTOCOL_VERSION, 3)) {
591
+		if (!$this->ldap->setOption($this->ldapConnectionRes, LDAP_OPT_PROTOCOL_VERSION, 3)) {
592 592
 			throw new ServerNotAvailableException('Could not set required LDAP Protocol version.');
593 593
 		}
594 594
 
595
-		if(!$this->ldap->setOption($this->ldapConnectionRes, LDAP_OPT_REFERRALS, 0)) {
595
+		if (!$this->ldap->setOption($this->ldapConnectionRes, LDAP_OPT_REFERRALS, 0)) {
596 596
 			throw new ServerNotAvailableException('Could not disable LDAP referrals.');
597 597
 		}
598 598
 
599
-		if($this->configuration->ldapTLS) {
600
-			if(!$this->ldap->startTls($this->ldapConnectionRes)) {
601
-				throw new ServerNotAvailableException('Start TLS failed, when connecting to LDAP host ' . $host . '.');
599
+		if ($this->configuration->ldapTLS) {
600
+			if (!$this->ldap->startTls($this->ldapConnectionRes)) {
601
+				throw new ServerNotAvailableException('Start TLS failed, when connecting to LDAP host '.$host.'.');
602 602
 			}
603 603
 		}
604 604
 
@@ -609,25 +609,25 @@  discard block
 block discarded – undo
609 609
 	 * Binds to LDAP
610 610
 	 */
611 611
 	public function bind() {
612
-		if(!$this->configuration->ldapConfigurationActive) {
612
+		if (!$this->configuration->ldapConfigurationActive) {
613 613
 			return false;
614 614
 		}
615 615
 		$cr = $this->getConnectionResource();
616
-		if(!$this->ldap->isResource($cr)) {
616
+		if (!$this->ldap->isResource($cr)) {
617 617
 			return false;
618 618
 		}
619 619
 		$ldapLogin = @$this->ldap->bind($cr,
620 620
 										$this->configuration->ldapAgentName,
621 621
 										$this->configuration->ldapAgentPassword);
622
-		if(!$ldapLogin) {
622
+		if (!$ldapLogin) {
623 623
 			$errno = $this->ldap->errno($cr);
624 624
 
625 625
 			\OCP\Util::writeLog('user_ldap',
626
-				'Bind failed: ' . $errno . ': ' . $this->ldap->error($cr),
626
+				'Bind failed: '.$errno.': '.$this->ldap->error($cr),
627 627
 				\OCP\Util::WARN);
628 628
 
629 629
 			// Set to failure mode, if LDAP error code is not LDAP_SUCCESS or LDAP_INVALID_CREDENTIALS
630
-			if($errno !== 0x00 && $errno !== 0x31) {
630
+			if ($errno !== 0x00 && $errno !== 0x31) {
631 631
 				$this->ldapConnectionRes = null;
632 632
 			}
633 633
 
Please login to merge, or discard this patch.