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