Passed
Push — master ( 415e68...b16c98 )
by Blizzz
15:44 queued 12s
created
apps/user_ldap/lib/Configuration.php 2 patches
Indentation   +495 added lines, -495 removed lines patch added patch discarded remove patch
@@ -39,527 +39,527 @@
 block discarded – undo
39 39
  * @property string ldapUserAvatarRule
40 40
  */
41 41
 class Configuration {
42
-	public const AVATAR_PREFIX_DEFAULT = 'default';
43
-	public const AVATAR_PREFIX_NONE = 'none';
44
-	public const AVATAR_PREFIX_DATA_ATTRIBUTE = 'data:';
42
+    public const AVATAR_PREFIX_DEFAULT = 'default';
43
+    public const AVATAR_PREFIX_NONE = 'none';
44
+    public const AVATAR_PREFIX_DATA_ATTRIBUTE = 'data:';
45 45
 
46
-	public const LDAP_SERVER_FEATURE_UNKNOWN = 'unknown';
47
-	public const LDAP_SERVER_FEATURE_AVAILABLE = 'available';
48
-	public const LDAP_SERVER_FEATURE_UNAVAILABLE = 'unavailable';
46
+    public const LDAP_SERVER_FEATURE_UNKNOWN = 'unknown';
47
+    public const LDAP_SERVER_FEATURE_AVAILABLE = 'available';
48
+    public const LDAP_SERVER_FEATURE_UNAVAILABLE = 'unavailable';
49 49
 
50
-	/**
51
-	 * @var string
52
-	 */
53
-	protected $configPrefix;
54
-	/**
55
-	 * @var bool
56
-	 */
57
-	protected $configRead = false;
58
-	/**
59
-	 * @var string[]
60
-	 */
61
-	protected array $unsavedChanges = [];
50
+    /**
51
+     * @var string
52
+     */
53
+    protected $configPrefix;
54
+    /**
55
+     * @var bool
56
+     */
57
+    protected $configRead = false;
58
+    /**
59
+     * @var string[]
60
+     */
61
+    protected array $unsavedChanges = [];
62 62
 
63
-	/**
64
-	 * @var array<string, mixed> settings
65
-	 */
66
-	protected $config = [
67
-		'ldapHost' => null,
68
-		'ldapPort' => null,
69
-		'ldapBackupHost' => null,
70
-		'ldapBackupPort' => null,
71
-		'ldapBase' => null,
72
-		'ldapBaseUsers' => null,
73
-		'ldapBaseGroups' => null,
74
-		'ldapAgentName' => null,
75
-		'ldapAgentPassword' => null,
76
-		'ldapTLS' => null,
77
-		'turnOffCertCheck' => null,
78
-		'ldapIgnoreNamingRules' => null,
79
-		'ldapUserDisplayName' => null,
80
-		'ldapUserDisplayName2' => null,
81
-		'ldapUserAvatarRule' => null,
82
-		'ldapGidNumber' => null,
83
-		'ldapUserFilterObjectclass' => null,
84
-		'ldapUserFilterGroups' => null,
85
-		'ldapUserFilter' => null,
86
-		'ldapUserFilterMode' => null,
87
-		'ldapGroupFilter' => null,
88
-		'ldapGroupFilterMode' => null,
89
-		'ldapGroupFilterObjectclass' => null,
90
-		'ldapGroupFilterGroups' => null,
91
-		'ldapGroupDisplayName' => null,
92
-		'ldapGroupMemberAssocAttr' => null,
93
-		'ldapLoginFilter' => null,
94
-		'ldapLoginFilterMode' => null,
95
-		'ldapLoginFilterEmail' => null,
96
-		'ldapLoginFilterUsername' => null,
97
-		'ldapLoginFilterAttributes' => null,
98
-		'ldapQuotaAttribute' => null,
99
-		'ldapQuotaDefault' => null,
100
-		'ldapEmailAttribute' => null,
101
-		'ldapCacheTTL' => null,
102
-		'ldapUuidUserAttribute' => 'auto',
103
-		'ldapUuidGroupAttribute' => 'auto',
104
-		'ldapOverrideMainServer' => false,
105
-		'ldapConfigurationActive' => false,
106
-		'ldapAttributesForUserSearch' => null,
107
-		'ldapAttributesForGroupSearch' => null,
108
-		'ldapExperiencedAdmin' => false,
109
-		'homeFolderNamingRule' => null,
110
-		'hasMemberOfFilterSupport' => false,
111
-		'useMemberOfToDetectMembership' => true,
112
-		'ldapExpertUsernameAttr' => null,
113
-		'ldapExpertUUIDUserAttr' => null,
114
-		'ldapExpertUUIDGroupAttr' => null,
115
-		'lastJpegPhotoLookup' => null,
116
-		'ldapNestedGroups' => false,
117
-		'ldapPagingSize' => null,
118
-		'turnOnPasswordChange' => false,
119
-		'ldapDynamicGroupMemberURL' => null,
120
-		'ldapDefaultPPolicyDN' => null,
121
-		'ldapExtStorageHomeAttribute' => null,
122
-		'ldapMatchingRuleInChainState' => self::LDAP_SERVER_FEATURE_UNKNOWN,
123
-		'ldapConnectionTimeout' => 15,
124
-	];
63
+    /**
64
+     * @var array<string, mixed> settings
65
+     */
66
+    protected $config = [
67
+        'ldapHost' => null,
68
+        'ldapPort' => null,
69
+        'ldapBackupHost' => null,
70
+        'ldapBackupPort' => null,
71
+        'ldapBase' => null,
72
+        'ldapBaseUsers' => null,
73
+        'ldapBaseGroups' => null,
74
+        'ldapAgentName' => null,
75
+        'ldapAgentPassword' => null,
76
+        'ldapTLS' => null,
77
+        'turnOffCertCheck' => null,
78
+        'ldapIgnoreNamingRules' => null,
79
+        'ldapUserDisplayName' => null,
80
+        'ldapUserDisplayName2' => null,
81
+        'ldapUserAvatarRule' => null,
82
+        'ldapGidNumber' => null,
83
+        'ldapUserFilterObjectclass' => null,
84
+        'ldapUserFilterGroups' => null,
85
+        'ldapUserFilter' => null,
86
+        'ldapUserFilterMode' => null,
87
+        'ldapGroupFilter' => null,
88
+        'ldapGroupFilterMode' => null,
89
+        'ldapGroupFilterObjectclass' => null,
90
+        'ldapGroupFilterGroups' => null,
91
+        'ldapGroupDisplayName' => null,
92
+        'ldapGroupMemberAssocAttr' => null,
93
+        'ldapLoginFilter' => null,
94
+        'ldapLoginFilterMode' => null,
95
+        'ldapLoginFilterEmail' => null,
96
+        'ldapLoginFilterUsername' => null,
97
+        'ldapLoginFilterAttributes' => null,
98
+        'ldapQuotaAttribute' => null,
99
+        'ldapQuotaDefault' => null,
100
+        'ldapEmailAttribute' => null,
101
+        'ldapCacheTTL' => null,
102
+        'ldapUuidUserAttribute' => 'auto',
103
+        'ldapUuidGroupAttribute' => 'auto',
104
+        'ldapOverrideMainServer' => false,
105
+        'ldapConfigurationActive' => false,
106
+        'ldapAttributesForUserSearch' => null,
107
+        'ldapAttributesForGroupSearch' => null,
108
+        'ldapExperiencedAdmin' => false,
109
+        'homeFolderNamingRule' => null,
110
+        'hasMemberOfFilterSupport' => false,
111
+        'useMemberOfToDetectMembership' => true,
112
+        'ldapExpertUsernameAttr' => null,
113
+        'ldapExpertUUIDUserAttr' => null,
114
+        'ldapExpertUUIDGroupAttr' => null,
115
+        'lastJpegPhotoLookup' => null,
116
+        'ldapNestedGroups' => false,
117
+        'ldapPagingSize' => null,
118
+        'turnOnPasswordChange' => false,
119
+        'ldapDynamicGroupMemberURL' => null,
120
+        'ldapDefaultPPolicyDN' => null,
121
+        'ldapExtStorageHomeAttribute' => null,
122
+        'ldapMatchingRuleInChainState' => self::LDAP_SERVER_FEATURE_UNKNOWN,
123
+        'ldapConnectionTimeout' => 15,
124
+    ];
125 125
 
126
-	public function __construct(string $configPrefix, bool $autoRead = true) {
127
-		$this->configPrefix = $configPrefix;
128
-		if ($autoRead) {
129
-			$this->readConfiguration();
130
-		}
131
-	}
126
+    public function __construct(string $configPrefix, bool $autoRead = true) {
127
+        $this->configPrefix = $configPrefix;
128
+        if ($autoRead) {
129
+            $this->readConfiguration();
130
+        }
131
+    }
132 132
 
133
-	/**
134
-	 * @param string $name
135
-	 * @return mixed|null
136
-	 */
137
-	public function __get($name) {
138
-		if (isset($this->config[$name])) {
139
-			return $this->config[$name];
140
-		}
141
-		return null;
142
-	}
133
+    /**
134
+     * @param string $name
135
+     * @return mixed|null
136
+     */
137
+    public function __get($name) {
138
+        if (isset($this->config[$name])) {
139
+            return $this->config[$name];
140
+        }
141
+        return null;
142
+    }
143 143
 
144
-	/**
145
-	 * @param string $name
146
-	 * @param mixed $value
147
-	 */
148
-	public function __set($name, $value) {
149
-		$this->setConfiguration([$name => $value]);
150
-	}
144
+    /**
145
+     * @param string $name
146
+     * @param mixed $value
147
+     */
148
+    public function __set($name, $value) {
149
+        $this->setConfiguration([$name => $value]);
150
+    }
151 151
 
152
-	public function getConfiguration(): array {
153
-		return $this->config;
154
-	}
152
+    public function getConfiguration(): array {
153
+        return $this->config;
154
+    }
155 155
 
156
-	/**
157
-	 * set LDAP configuration with values delivered by an array, not read
158
-	 * from configuration. It does not save the configuration! To do so, you
159
-	 * must call saveConfiguration afterwards.
160
-	 * @param array $config array that holds the config parameters in an associated
161
-	 * array
162
-	 * @param array &$applied optional; array where the set fields will be given to
163
-	 */
164
-	public function setConfiguration(array $config, array &$applied = null): void {
165
-		$cta = $this->getConfigTranslationArray();
166
-		foreach ($config as $inputKey => $val) {
167
-			if (strpos($inputKey, '_') !== false && array_key_exists($inputKey, $cta)) {
168
-				$key = $cta[$inputKey];
169
-			} elseif (array_key_exists($inputKey, $this->config)) {
170
-				$key = $inputKey;
171
-			} else {
172
-				continue;
173
-			}
156
+    /**
157
+     * set LDAP configuration with values delivered by an array, not read
158
+     * from configuration. It does not save the configuration! To do so, you
159
+     * must call saveConfiguration afterwards.
160
+     * @param array $config array that holds the config parameters in an associated
161
+     * array
162
+     * @param array &$applied optional; array where the set fields will be given to
163
+     */
164
+    public function setConfiguration(array $config, array &$applied = null): void {
165
+        $cta = $this->getConfigTranslationArray();
166
+        foreach ($config as $inputKey => $val) {
167
+            if (strpos($inputKey, '_') !== false && array_key_exists($inputKey, $cta)) {
168
+                $key = $cta[$inputKey];
169
+            } elseif (array_key_exists($inputKey, $this->config)) {
170
+                $key = $inputKey;
171
+            } else {
172
+                continue;
173
+            }
174 174
 
175
-			$setMethod = 'setValue';
176
-			switch ($key) {
177
-				case 'ldapAgentPassword':
178
-					$setMethod = 'setRawValue';
179
-					break;
180
-				case 'homeFolderNamingRule':
181
-					$trimmedVal = trim($val);
182
-					if ($trimmedVal !== '' && strpos($val, 'attr:') === false) {
183
-						$val = 'attr:'.$trimmedVal;
184
-					}
185
-					break;
186
-				case 'ldapBase':
187
-				case 'ldapBaseUsers':
188
-				case 'ldapBaseGroups':
189
-				case 'ldapAttributesForUserSearch':
190
-				case 'ldapAttributesForGroupSearch':
191
-				case 'ldapUserFilterObjectclass':
192
-				case 'ldapUserFilterGroups':
193
-				case 'ldapGroupFilterObjectclass':
194
-				case 'ldapGroupFilterGroups':
195
-				case 'ldapLoginFilterAttributes':
196
-					$setMethod = 'setMultiLine';
197
-					break;
198
-			}
199
-			$this->$setMethod($key, $val);
200
-			if (is_array($applied)) {
201
-				$applied[] = $inputKey;
202
-				// storing key as index avoids duplication, and as value for simplicity
203
-			}
204
-			$this->unsavedChanges[$key] = $key;
205
-		}
206
-	}
175
+            $setMethod = 'setValue';
176
+            switch ($key) {
177
+                case 'ldapAgentPassword':
178
+                    $setMethod = 'setRawValue';
179
+                    break;
180
+                case 'homeFolderNamingRule':
181
+                    $trimmedVal = trim($val);
182
+                    if ($trimmedVal !== '' && strpos($val, 'attr:') === false) {
183
+                        $val = 'attr:'.$trimmedVal;
184
+                    }
185
+                    break;
186
+                case 'ldapBase':
187
+                case 'ldapBaseUsers':
188
+                case 'ldapBaseGroups':
189
+                case 'ldapAttributesForUserSearch':
190
+                case 'ldapAttributesForGroupSearch':
191
+                case 'ldapUserFilterObjectclass':
192
+                case 'ldapUserFilterGroups':
193
+                case 'ldapGroupFilterObjectclass':
194
+                case 'ldapGroupFilterGroups':
195
+                case 'ldapLoginFilterAttributes':
196
+                    $setMethod = 'setMultiLine';
197
+                    break;
198
+            }
199
+            $this->$setMethod($key, $val);
200
+            if (is_array($applied)) {
201
+                $applied[] = $inputKey;
202
+                // storing key as index avoids duplication, and as value for simplicity
203
+            }
204
+            $this->unsavedChanges[$key] = $key;
205
+        }
206
+    }
207 207
 
208
-	public function readConfiguration(): void {
209
-		if (!$this->configRead) {
210
-			$cta = array_flip($this->getConfigTranslationArray());
211
-			foreach ($this->config as $key => $val) {
212
-				if (!isset($cta[$key])) {
213
-					//some are determined
214
-					continue;
215
-				}
216
-				$dbKey = $cta[$key];
217
-				switch ($key) {
218
-					case 'ldapBase':
219
-					case 'ldapBaseUsers':
220
-					case 'ldapBaseGroups':
221
-					case 'ldapAttributesForUserSearch':
222
-					case 'ldapAttributesForGroupSearch':
223
-					case 'ldapUserFilterObjectclass':
224
-					case 'ldapUserFilterGroups':
225
-					case 'ldapGroupFilterObjectclass':
226
-					case 'ldapGroupFilterGroups':
227
-					case 'ldapLoginFilterAttributes':
228
-						$readMethod = 'getMultiLine';
229
-						break;
230
-					case 'ldapIgnoreNamingRules':
231
-						$readMethod = 'getSystemValue';
232
-						$dbKey = $key;
233
-						break;
234
-					case 'ldapAgentPassword':
235
-						$readMethod = 'getPwd';
236
-						break;
237
-					case 'ldapUserDisplayName2':
238
-					case 'ldapGroupDisplayName':
239
-						$readMethod = 'getLcValue';
240
-						break;
241
-					case 'ldapUserDisplayName':
242
-					default:
243
-						// user display name does not lower case because
244
-						// we rely on an upper case N as indicator whether to
245
-						// auto-detect it or not. FIXME
246
-						$readMethod = 'getValue';
247
-						break;
248
-				}
249
-				$this->config[$key] = $this->$readMethod($dbKey);
250
-			}
251
-			$this->configRead = true;
252
-		}
253
-	}
208
+    public function readConfiguration(): void {
209
+        if (!$this->configRead) {
210
+            $cta = array_flip($this->getConfigTranslationArray());
211
+            foreach ($this->config as $key => $val) {
212
+                if (!isset($cta[$key])) {
213
+                    //some are determined
214
+                    continue;
215
+                }
216
+                $dbKey = $cta[$key];
217
+                switch ($key) {
218
+                    case 'ldapBase':
219
+                    case 'ldapBaseUsers':
220
+                    case 'ldapBaseGroups':
221
+                    case 'ldapAttributesForUserSearch':
222
+                    case 'ldapAttributesForGroupSearch':
223
+                    case 'ldapUserFilterObjectclass':
224
+                    case 'ldapUserFilterGroups':
225
+                    case 'ldapGroupFilterObjectclass':
226
+                    case 'ldapGroupFilterGroups':
227
+                    case 'ldapLoginFilterAttributes':
228
+                        $readMethod = 'getMultiLine';
229
+                        break;
230
+                    case 'ldapIgnoreNamingRules':
231
+                        $readMethod = 'getSystemValue';
232
+                        $dbKey = $key;
233
+                        break;
234
+                    case 'ldapAgentPassword':
235
+                        $readMethod = 'getPwd';
236
+                        break;
237
+                    case 'ldapUserDisplayName2':
238
+                    case 'ldapGroupDisplayName':
239
+                        $readMethod = 'getLcValue';
240
+                        break;
241
+                    case 'ldapUserDisplayName':
242
+                    default:
243
+                        // user display name does not lower case because
244
+                        // we rely on an upper case N as indicator whether to
245
+                        // auto-detect it or not. FIXME
246
+                        $readMethod = 'getValue';
247
+                        break;
248
+                }
249
+                $this->config[$key] = $this->$readMethod($dbKey);
250
+            }
251
+            $this->configRead = true;
252
+        }
253
+    }
254 254
 
255
-	/**
256
-	 * saves the current config changes in the database
257
-	 */
258
-	public function saveConfiguration(): void {
259
-		$cta = array_flip($this->getConfigTranslationArray());
260
-		$changed = false;
261
-		foreach ($this->unsavedChanges as $key) {
262
-			$value = $this->config[$key];
263
-			switch ($key) {
264
-				case 'ldapAgentPassword':
265
-					$value = base64_encode($value);
266
-					break;
267
-				case 'ldapBase':
268
-				case 'ldapBaseUsers':
269
-				case 'ldapBaseGroups':
270
-				case 'ldapAttributesForUserSearch':
271
-				case 'ldapAttributesForGroupSearch':
272
-				case 'ldapUserFilterObjectclass':
273
-				case 'ldapUserFilterGroups':
274
-				case 'ldapGroupFilterObjectclass':
275
-				case 'ldapGroupFilterGroups':
276
-				case 'ldapLoginFilterAttributes':
277
-					if (is_array($value)) {
278
-						$value = implode("\n", $value);
279
-					}
280
-					break;
281
-				//following options are not stored but detected, skip them
282
-				case 'ldapIgnoreNamingRules':
283
-				case 'ldapUuidUserAttribute':
284
-				case 'ldapUuidGroupAttribute':
285
-					continue 2;
286
-			}
287
-			if (is_null($value)) {
288
-				$value = '';
289
-			}
290
-			$changed = true;
291
-			$this->saveValue($cta[$key], $value);
292
-		}
293
-		if ($changed) {
294
-			$this->saveValue('_lastChange', (string)time());
295
-		}
296
-		$this->unsavedChanges = [];
297
-	}
255
+    /**
256
+     * saves the current config changes in the database
257
+     */
258
+    public function saveConfiguration(): void {
259
+        $cta = array_flip($this->getConfigTranslationArray());
260
+        $changed = false;
261
+        foreach ($this->unsavedChanges as $key) {
262
+            $value = $this->config[$key];
263
+            switch ($key) {
264
+                case 'ldapAgentPassword':
265
+                    $value = base64_encode($value);
266
+                    break;
267
+                case 'ldapBase':
268
+                case 'ldapBaseUsers':
269
+                case 'ldapBaseGroups':
270
+                case 'ldapAttributesForUserSearch':
271
+                case 'ldapAttributesForGroupSearch':
272
+                case 'ldapUserFilterObjectclass':
273
+                case 'ldapUserFilterGroups':
274
+                case 'ldapGroupFilterObjectclass':
275
+                case 'ldapGroupFilterGroups':
276
+                case 'ldapLoginFilterAttributes':
277
+                    if (is_array($value)) {
278
+                        $value = implode("\n", $value);
279
+                    }
280
+                    break;
281
+                //following options are not stored but detected, skip them
282
+                case 'ldapIgnoreNamingRules':
283
+                case 'ldapUuidUserAttribute':
284
+                case 'ldapUuidGroupAttribute':
285
+                    continue 2;
286
+            }
287
+            if (is_null($value)) {
288
+                $value = '';
289
+            }
290
+            $changed = true;
291
+            $this->saveValue($cta[$key], $value);
292
+        }
293
+        if ($changed) {
294
+            $this->saveValue('_lastChange', (string)time());
295
+        }
296
+        $this->unsavedChanges = [];
297
+    }
298 298
 
299
-	/**
300
-	 * @param string $varName
301
-	 * @return array|string
302
-	 */
303
-	protected function getMultiLine($varName) {
304
-		$value = $this->getValue($varName);
305
-		if (empty($value)) {
306
-			$value = '';
307
-		} else {
308
-			$value = preg_split('/\r\n|\r|\n/', $value);
309
-		}
299
+    /**
300
+     * @param string $varName
301
+     * @return array|string
302
+     */
303
+    protected function getMultiLine($varName) {
304
+        $value = $this->getValue($varName);
305
+        if (empty($value)) {
306
+            $value = '';
307
+        } else {
308
+            $value = preg_split('/\r\n|\r|\n/', $value);
309
+        }
310 310
 
311
-		return $value;
312
-	}
311
+        return $value;
312
+    }
313 313
 
314
-	/**
315
-	 * Sets multi-line values as arrays
316
-	 *
317
-	 * @param string $varName name of config-key
318
-	 * @param array|string $value to set
319
-	 */
320
-	protected function setMultiLine(string $varName, $value): void {
321
-		if (empty($value)) {
322
-			$value = '';
323
-		} elseif (!is_array($value)) {
324
-			$value = preg_split('/\r\n|\r|\n|;/', $value);
325
-			if ($value === false) {
326
-				$value = '';
327
-			}
328
-		}
314
+    /**
315
+     * Sets multi-line values as arrays
316
+     *
317
+     * @param string $varName name of config-key
318
+     * @param array|string $value to set
319
+     */
320
+    protected function setMultiLine(string $varName, $value): void {
321
+        if (empty($value)) {
322
+            $value = '';
323
+        } elseif (!is_array($value)) {
324
+            $value = preg_split('/\r\n|\r|\n|;/', $value);
325
+            if ($value === false) {
326
+                $value = '';
327
+            }
328
+        }
329 329
 
330
-		if (!is_array($value)) {
331
-			$finalValue = trim($value);
332
-		} else {
333
-			$finalValue = [];
334
-			foreach ($value as $key => $val) {
335
-				if (is_string($val)) {
336
-					$val = trim($val);
337
-					if ($val !== '') {
338
-						//accidental line breaks are not wanted and can cause
339
-						// odd behaviour. Thus, away with them.
340
-						$finalValue[] = $val;
341
-					}
342
-				} else {
343
-					$finalValue[] = $val;
344
-				}
345
-			}
346
-		}
330
+        if (!is_array($value)) {
331
+            $finalValue = trim($value);
332
+        } else {
333
+            $finalValue = [];
334
+            foreach ($value as $key => $val) {
335
+                if (is_string($val)) {
336
+                    $val = trim($val);
337
+                    if ($val !== '') {
338
+                        //accidental line breaks are not wanted and can cause
339
+                        // odd behaviour. Thus, away with them.
340
+                        $finalValue[] = $val;
341
+                    }
342
+                } else {
343
+                    $finalValue[] = $val;
344
+                }
345
+            }
346
+        }
347 347
 
348
-		$this->setRawValue($varName, $finalValue);
349
-	}
348
+        $this->setRawValue($varName, $finalValue);
349
+    }
350 350
 
351
-	protected function getPwd(string $varName): string {
352
-		return base64_decode($this->getValue($varName));
353
-	}
351
+    protected function getPwd(string $varName): string {
352
+        return base64_decode($this->getValue($varName));
353
+    }
354 354
 
355
-	protected function getLcValue(string $varName): string {
356
-		return mb_strtolower($this->getValue($varName), 'UTF-8');
357
-	}
355
+    protected function getLcValue(string $varName): string {
356
+        return mb_strtolower($this->getValue($varName), 'UTF-8');
357
+    }
358 358
 
359
-	protected function getSystemValue(string $varName): string {
360
-		//FIXME: if another system value is added, softcode the default value
361
-		return \OC::$server->getConfig()->getSystemValue($varName, false);
362
-	}
359
+    protected function getSystemValue(string $varName): string {
360
+        //FIXME: if another system value is added, softcode the default value
361
+        return \OC::$server->getConfig()->getSystemValue($varName, false);
362
+    }
363 363
 
364
-	protected function getValue(string $varName): string {
365
-		static $defaults;
366
-		if (is_null($defaults)) {
367
-			$defaults = $this->getDefaults();
368
-		}
369
-		return \OC::$server->getConfig()->getAppValue('user_ldap',
370
-										$this->configPrefix.$varName,
371
-										$defaults[$varName]);
372
-	}
364
+    protected function getValue(string $varName): string {
365
+        static $defaults;
366
+        if (is_null($defaults)) {
367
+            $defaults = $this->getDefaults();
368
+        }
369
+        return \OC::$server->getConfig()->getAppValue('user_ldap',
370
+                                        $this->configPrefix.$varName,
371
+                                        $defaults[$varName]);
372
+    }
373 373
 
374
-	/**
375
-	 * Sets a scalar value.
376
-	 *
377
-	 * @param string $varName name of config key
378
-	 * @param mixed $value to set
379
-	 */
380
-	protected function setValue(string $varName, $value): void {
381
-		if (is_string($value)) {
382
-			$value = trim($value);
383
-		}
384
-		$this->config[$varName] = $value;
385
-	}
374
+    /**
375
+     * Sets a scalar value.
376
+     *
377
+     * @param string $varName name of config key
378
+     * @param mixed $value to set
379
+     */
380
+    protected function setValue(string $varName, $value): void {
381
+        if (is_string($value)) {
382
+            $value = trim($value);
383
+        }
384
+        $this->config[$varName] = $value;
385
+    }
386 386
 
387
-	/**
388
-	 * Sets a scalar value without trimming.
389
-	 *
390
-	 * @param string $varName name of config key
391
-	 * @param mixed $value to set
392
-	 */
393
-	protected function setRawValue(string $varName, $value): void {
394
-		$this->config[$varName] = $value;
395
-	}
387
+    /**
388
+     * Sets a scalar value without trimming.
389
+     *
390
+     * @param string $varName name of config key
391
+     * @param mixed $value to set
392
+     */
393
+    protected function setRawValue(string $varName, $value): void {
394
+        $this->config[$varName] = $value;
395
+    }
396 396
 
397
-	protected function saveValue(string $varName, string $value): bool {
398
-		\OC::$server->getConfig()->setAppValue(
399
-			'user_ldap',
400
-			$this->configPrefix.$varName,
401
-			$value
402
-		);
403
-		return true;
404
-	}
397
+    protected function saveValue(string $varName, string $value): bool {
398
+        \OC::$server->getConfig()->setAppValue(
399
+            'user_ldap',
400
+            $this->configPrefix.$varName,
401
+            $value
402
+        );
403
+        return true;
404
+    }
405 405
 
406
-	/**
407
-	 * @return array an associative array with the default values. Keys are correspond
408
-	 * to config-value entries in the database table
409
-	 */
410
-	public function getDefaults(): array {
411
-		return [
412
-			'ldap_host' => '',
413
-			'ldap_port' => '',
414
-			'ldap_backup_host' => '',
415
-			'ldap_backup_port' => '',
416
-			'ldap_override_main_server' => '',
417
-			'ldap_dn' => '',
418
-			'ldap_agent_password' => '',
419
-			'ldap_base' => '',
420
-			'ldap_base_users' => '',
421
-			'ldap_base_groups' => '',
422
-			'ldap_userlist_filter' => '',
423
-			'ldap_user_filter_mode' => 0,
424
-			'ldap_userfilter_objectclass' => '',
425
-			'ldap_userfilter_groups' => '',
426
-			'ldap_login_filter' => '',
427
-			'ldap_login_filter_mode' => 0,
428
-			'ldap_loginfilter_email' => 0,
429
-			'ldap_loginfilter_username' => 1,
430
-			'ldap_loginfilter_attributes' => '',
431
-			'ldap_group_filter' => '',
432
-			'ldap_group_filter_mode' => 0,
433
-			'ldap_groupfilter_objectclass' => '',
434
-			'ldap_groupfilter_groups' => '',
435
-			'ldap_gid_number' => 'gidNumber',
436
-			'ldap_display_name' => 'displayName',
437
-			'ldap_user_display_name_2' => '',
438
-			'ldap_group_display_name' => 'cn',
439
-			'ldap_tls' => 0,
440
-			'ldap_quota_def' => '',
441
-			'ldap_quota_attr' => '',
442
-			'ldap_email_attr' => '',
443
-			'ldap_group_member_assoc_attribute' => '',
444
-			'ldap_cache_ttl' => 600,
445
-			'ldap_uuid_user_attribute' => 'auto',
446
-			'ldap_uuid_group_attribute' => 'auto',
447
-			'home_folder_naming_rule' => '',
448
-			'ldap_turn_off_cert_check' => 0,
449
-			'ldap_configuration_active' => 0,
450
-			'ldap_attributes_for_user_search' => '',
451
-			'ldap_attributes_for_group_search' => '',
452
-			'ldap_expert_username_attr' => '',
453
-			'ldap_expert_uuid_user_attr' => '',
454
-			'ldap_expert_uuid_group_attr' => '',
455
-			'has_memberof_filter_support' => 0,
456
-			'use_memberof_to_detect_membership' => 1,
457
-			'last_jpegPhoto_lookup' => 0,
458
-			'ldap_nested_groups' => 0,
459
-			'ldap_paging_size' => 500,
460
-			'ldap_turn_on_pwd_change' => 0,
461
-			'ldap_experienced_admin' => 0,
462
-			'ldap_dynamic_group_member_url' => '',
463
-			'ldap_default_ppolicy_dn' => '',
464
-			'ldap_user_avatar_rule' => 'default',
465
-			'ldap_ext_storage_home_attribute' => '',
466
-			'ldap_matching_rule_in_chain_state' => self::LDAP_SERVER_FEATURE_UNKNOWN,
467
-			'ldap_connection_timeout' => 15,
468
-		];
469
-	}
406
+    /**
407
+     * @return array an associative array with the default values. Keys are correspond
408
+     * to config-value entries in the database table
409
+     */
410
+    public function getDefaults(): array {
411
+        return [
412
+            'ldap_host' => '',
413
+            'ldap_port' => '',
414
+            'ldap_backup_host' => '',
415
+            'ldap_backup_port' => '',
416
+            'ldap_override_main_server' => '',
417
+            'ldap_dn' => '',
418
+            'ldap_agent_password' => '',
419
+            'ldap_base' => '',
420
+            'ldap_base_users' => '',
421
+            'ldap_base_groups' => '',
422
+            'ldap_userlist_filter' => '',
423
+            'ldap_user_filter_mode' => 0,
424
+            'ldap_userfilter_objectclass' => '',
425
+            'ldap_userfilter_groups' => '',
426
+            'ldap_login_filter' => '',
427
+            'ldap_login_filter_mode' => 0,
428
+            'ldap_loginfilter_email' => 0,
429
+            'ldap_loginfilter_username' => 1,
430
+            'ldap_loginfilter_attributes' => '',
431
+            'ldap_group_filter' => '',
432
+            'ldap_group_filter_mode' => 0,
433
+            'ldap_groupfilter_objectclass' => '',
434
+            'ldap_groupfilter_groups' => '',
435
+            'ldap_gid_number' => 'gidNumber',
436
+            'ldap_display_name' => 'displayName',
437
+            'ldap_user_display_name_2' => '',
438
+            'ldap_group_display_name' => 'cn',
439
+            'ldap_tls' => 0,
440
+            'ldap_quota_def' => '',
441
+            'ldap_quota_attr' => '',
442
+            'ldap_email_attr' => '',
443
+            'ldap_group_member_assoc_attribute' => '',
444
+            'ldap_cache_ttl' => 600,
445
+            'ldap_uuid_user_attribute' => 'auto',
446
+            'ldap_uuid_group_attribute' => 'auto',
447
+            'home_folder_naming_rule' => '',
448
+            'ldap_turn_off_cert_check' => 0,
449
+            'ldap_configuration_active' => 0,
450
+            'ldap_attributes_for_user_search' => '',
451
+            'ldap_attributes_for_group_search' => '',
452
+            'ldap_expert_username_attr' => '',
453
+            'ldap_expert_uuid_user_attr' => '',
454
+            'ldap_expert_uuid_group_attr' => '',
455
+            'has_memberof_filter_support' => 0,
456
+            'use_memberof_to_detect_membership' => 1,
457
+            'last_jpegPhoto_lookup' => 0,
458
+            'ldap_nested_groups' => 0,
459
+            'ldap_paging_size' => 500,
460
+            'ldap_turn_on_pwd_change' => 0,
461
+            'ldap_experienced_admin' => 0,
462
+            'ldap_dynamic_group_member_url' => '',
463
+            'ldap_default_ppolicy_dn' => '',
464
+            'ldap_user_avatar_rule' => 'default',
465
+            'ldap_ext_storage_home_attribute' => '',
466
+            'ldap_matching_rule_in_chain_state' => self::LDAP_SERVER_FEATURE_UNKNOWN,
467
+            'ldap_connection_timeout' => 15,
468
+        ];
469
+    }
470 470
 
471
-	/**
472
-	 * @return array that maps internal variable names to database fields
473
-	 */
474
-	public function getConfigTranslationArray(): array {
475
-		//TODO: merge them into one representation
476
-		static $array = [
477
-			'ldap_host' => 'ldapHost',
478
-			'ldap_port' => 'ldapPort',
479
-			'ldap_backup_host' => 'ldapBackupHost',
480
-			'ldap_backup_port' => 'ldapBackupPort',
481
-			'ldap_override_main_server' => 'ldapOverrideMainServer',
482
-			'ldap_dn' => 'ldapAgentName',
483
-			'ldap_agent_password' => 'ldapAgentPassword',
484
-			'ldap_base' => 'ldapBase',
485
-			'ldap_base_users' => 'ldapBaseUsers',
486
-			'ldap_base_groups' => 'ldapBaseGroups',
487
-			'ldap_userfilter_objectclass' => 'ldapUserFilterObjectclass',
488
-			'ldap_userfilter_groups' => 'ldapUserFilterGroups',
489
-			'ldap_userlist_filter' => 'ldapUserFilter',
490
-			'ldap_user_filter_mode' => 'ldapUserFilterMode',
491
-			'ldap_user_avatar_rule' => 'ldapUserAvatarRule',
492
-			'ldap_login_filter' => 'ldapLoginFilter',
493
-			'ldap_login_filter_mode' => 'ldapLoginFilterMode',
494
-			'ldap_loginfilter_email' => 'ldapLoginFilterEmail',
495
-			'ldap_loginfilter_username' => 'ldapLoginFilterUsername',
496
-			'ldap_loginfilter_attributes' => 'ldapLoginFilterAttributes',
497
-			'ldap_group_filter' => 'ldapGroupFilter',
498
-			'ldap_group_filter_mode' => 'ldapGroupFilterMode',
499
-			'ldap_groupfilter_objectclass' => 'ldapGroupFilterObjectclass',
500
-			'ldap_groupfilter_groups' => 'ldapGroupFilterGroups',
501
-			'ldap_gid_number' => 'ldapGidNumber',
502
-			'ldap_display_name' => 'ldapUserDisplayName',
503
-			'ldap_user_display_name_2' => 'ldapUserDisplayName2',
504
-			'ldap_group_display_name' => 'ldapGroupDisplayName',
505
-			'ldap_tls' => 'ldapTLS',
506
-			'ldap_quota_def' => 'ldapQuotaDefault',
507
-			'ldap_quota_attr' => 'ldapQuotaAttribute',
508
-			'ldap_email_attr' => 'ldapEmailAttribute',
509
-			'ldap_group_member_assoc_attribute' => 'ldapGroupMemberAssocAttr',
510
-			'ldap_cache_ttl' => 'ldapCacheTTL',
511
-			'home_folder_naming_rule' => 'homeFolderNamingRule',
512
-			'ldap_turn_off_cert_check' => 'turnOffCertCheck',
513
-			'ldap_configuration_active' => 'ldapConfigurationActive',
514
-			'ldap_attributes_for_user_search' => 'ldapAttributesForUserSearch',
515
-			'ldap_attributes_for_group_search' => 'ldapAttributesForGroupSearch',
516
-			'ldap_expert_username_attr' => 'ldapExpertUsernameAttr',
517
-			'ldap_expert_uuid_user_attr' => 'ldapExpertUUIDUserAttr',
518
-			'ldap_expert_uuid_group_attr' => 'ldapExpertUUIDGroupAttr',
519
-			'has_memberof_filter_support' => 'hasMemberOfFilterSupport',
520
-			'use_memberof_to_detect_membership' => 'useMemberOfToDetectMembership',
521
-			'last_jpegPhoto_lookup' => 'lastJpegPhotoLookup',
522
-			'ldap_nested_groups' => 'ldapNestedGroups',
523
-			'ldap_paging_size' => 'ldapPagingSize',
524
-			'ldap_turn_on_pwd_change' => 'turnOnPasswordChange',
525
-			'ldap_experienced_admin' => 'ldapExperiencedAdmin',
526
-			'ldap_dynamic_group_member_url' => 'ldapDynamicGroupMemberURL',
527
-			'ldap_default_ppolicy_dn' => 'ldapDefaultPPolicyDN',
528
-			'ldap_ext_storage_home_attribute' => 'ldapExtStorageHomeAttribute',
529
-			'ldap_matching_rule_in_chain_state' => 'ldapMatchingRuleInChainState',
530
-			'ldapIgnoreNamingRules' => 'ldapIgnoreNamingRules',	// sysconfig
531
-			'ldap_connection_timeout' => 'ldapConnectionTimeout',
532
-		];
533
-		return $array;
534
-	}
471
+    /**
472
+     * @return array that maps internal variable names to database fields
473
+     */
474
+    public function getConfigTranslationArray(): array {
475
+        //TODO: merge them into one representation
476
+        static $array = [
477
+            'ldap_host' => 'ldapHost',
478
+            'ldap_port' => 'ldapPort',
479
+            'ldap_backup_host' => 'ldapBackupHost',
480
+            'ldap_backup_port' => 'ldapBackupPort',
481
+            'ldap_override_main_server' => 'ldapOverrideMainServer',
482
+            'ldap_dn' => 'ldapAgentName',
483
+            'ldap_agent_password' => 'ldapAgentPassword',
484
+            'ldap_base' => 'ldapBase',
485
+            'ldap_base_users' => 'ldapBaseUsers',
486
+            'ldap_base_groups' => 'ldapBaseGroups',
487
+            'ldap_userfilter_objectclass' => 'ldapUserFilterObjectclass',
488
+            'ldap_userfilter_groups' => 'ldapUserFilterGroups',
489
+            'ldap_userlist_filter' => 'ldapUserFilter',
490
+            'ldap_user_filter_mode' => 'ldapUserFilterMode',
491
+            'ldap_user_avatar_rule' => 'ldapUserAvatarRule',
492
+            'ldap_login_filter' => 'ldapLoginFilter',
493
+            'ldap_login_filter_mode' => 'ldapLoginFilterMode',
494
+            'ldap_loginfilter_email' => 'ldapLoginFilterEmail',
495
+            'ldap_loginfilter_username' => 'ldapLoginFilterUsername',
496
+            'ldap_loginfilter_attributes' => 'ldapLoginFilterAttributes',
497
+            'ldap_group_filter' => 'ldapGroupFilter',
498
+            'ldap_group_filter_mode' => 'ldapGroupFilterMode',
499
+            'ldap_groupfilter_objectclass' => 'ldapGroupFilterObjectclass',
500
+            'ldap_groupfilter_groups' => 'ldapGroupFilterGroups',
501
+            'ldap_gid_number' => 'ldapGidNumber',
502
+            'ldap_display_name' => 'ldapUserDisplayName',
503
+            'ldap_user_display_name_2' => 'ldapUserDisplayName2',
504
+            'ldap_group_display_name' => 'ldapGroupDisplayName',
505
+            'ldap_tls' => 'ldapTLS',
506
+            'ldap_quota_def' => 'ldapQuotaDefault',
507
+            'ldap_quota_attr' => 'ldapQuotaAttribute',
508
+            'ldap_email_attr' => 'ldapEmailAttribute',
509
+            'ldap_group_member_assoc_attribute' => 'ldapGroupMemberAssocAttr',
510
+            'ldap_cache_ttl' => 'ldapCacheTTL',
511
+            'home_folder_naming_rule' => 'homeFolderNamingRule',
512
+            'ldap_turn_off_cert_check' => 'turnOffCertCheck',
513
+            'ldap_configuration_active' => 'ldapConfigurationActive',
514
+            'ldap_attributes_for_user_search' => 'ldapAttributesForUserSearch',
515
+            'ldap_attributes_for_group_search' => 'ldapAttributesForGroupSearch',
516
+            'ldap_expert_username_attr' => 'ldapExpertUsernameAttr',
517
+            'ldap_expert_uuid_user_attr' => 'ldapExpertUUIDUserAttr',
518
+            'ldap_expert_uuid_group_attr' => 'ldapExpertUUIDGroupAttr',
519
+            'has_memberof_filter_support' => 'hasMemberOfFilterSupport',
520
+            'use_memberof_to_detect_membership' => 'useMemberOfToDetectMembership',
521
+            'last_jpegPhoto_lookup' => 'lastJpegPhotoLookup',
522
+            'ldap_nested_groups' => 'ldapNestedGroups',
523
+            'ldap_paging_size' => 'ldapPagingSize',
524
+            'ldap_turn_on_pwd_change' => 'turnOnPasswordChange',
525
+            'ldap_experienced_admin' => 'ldapExperiencedAdmin',
526
+            'ldap_dynamic_group_member_url' => 'ldapDynamicGroupMemberURL',
527
+            'ldap_default_ppolicy_dn' => 'ldapDefaultPPolicyDN',
528
+            'ldap_ext_storage_home_attribute' => 'ldapExtStorageHomeAttribute',
529
+            'ldap_matching_rule_in_chain_state' => 'ldapMatchingRuleInChainState',
530
+            'ldapIgnoreNamingRules' => 'ldapIgnoreNamingRules',	// sysconfig
531
+            'ldap_connection_timeout' => 'ldapConnectionTimeout',
532
+        ];
533
+        return $array;
534
+    }
535 535
 
536
-	/**
537
-	 * @throws \RuntimeException
538
-	 */
539
-	public function resolveRule(string $rule): array {
540
-		if ($rule === 'avatar') {
541
-			return $this->getAvatarAttributes();
542
-		}
543
-		throw new \RuntimeException('Invalid rule');
544
-	}
536
+    /**
537
+     * @throws \RuntimeException
538
+     */
539
+    public function resolveRule(string $rule): array {
540
+        if ($rule === 'avatar') {
541
+            return $this->getAvatarAttributes();
542
+        }
543
+        throw new \RuntimeException('Invalid rule');
544
+    }
545 545
 
546
-	public function getAvatarAttributes(): array {
547
-		$value = $this->ldapUserAvatarRule ?: self::AVATAR_PREFIX_DEFAULT;
548
-		$defaultAttributes = ['jpegphoto', 'thumbnailphoto'];
546
+    public function getAvatarAttributes(): array {
547
+        $value = $this->ldapUserAvatarRule ?: self::AVATAR_PREFIX_DEFAULT;
548
+        $defaultAttributes = ['jpegphoto', 'thumbnailphoto'];
549 549
 
550
-		if ($value === self::AVATAR_PREFIX_NONE) {
551
-			return [];
552
-		}
553
-		if (strpos($value, self::AVATAR_PREFIX_DATA_ATTRIBUTE) === 0) {
554
-			$attribute = trim(substr($value, strlen(self::AVATAR_PREFIX_DATA_ATTRIBUTE)));
555
-			if ($attribute === '') {
556
-				return $defaultAttributes;
557
-			}
558
-			return [strtolower($attribute)];
559
-		}
560
-		if ($value !== self::AVATAR_PREFIX_DEFAULT) {
561
-			\OC::$server->getLogger()->warning('Invalid config value to ldapUserAvatarRule; falling back to default.');
562
-		}
563
-		return $defaultAttributes;
564
-	}
550
+        if ($value === self::AVATAR_PREFIX_NONE) {
551
+            return [];
552
+        }
553
+        if (strpos($value, self::AVATAR_PREFIX_DATA_ATTRIBUTE) === 0) {
554
+            $attribute = trim(substr($value, strlen(self::AVATAR_PREFIX_DATA_ATTRIBUTE)));
555
+            if ($attribute === '') {
556
+                return $defaultAttributes;
557
+            }
558
+            return [strtolower($attribute)];
559
+        }
560
+        if ($value !== self::AVATAR_PREFIX_DEFAULT) {
561
+            \OC::$server->getLogger()->warning('Invalid config value to ldapUserAvatarRule; falling back to default.');
562
+        }
563
+        return $defaultAttributes;
564
+    }
565 565
 }
Please login to merge, or discard this patch.
Spacing   +2 added lines, -2 removed lines patch added patch discarded remove patch
@@ -291,7 +291,7 @@  discard block
 block discarded – undo
291 291
 			$this->saveValue($cta[$key], $value);
292 292
 		}
293 293
 		if ($changed) {
294
-			$this->saveValue('_lastChange', (string)time());
294
+			$this->saveValue('_lastChange', (string) time());
295 295
 		}
296 296
 		$this->unsavedChanges = [];
297 297
 	}
@@ -527,7 +527,7 @@  discard block
 block discarded – undo
527 527
 			'ldap_default_ppolicy_dn' => 'ldapDefaultPPolicyDN',
528 528
 			'ldap_ext_storage_home_attribute' => 'ldapExtStorageHomeAttribute',
529 529
 			'ldap_matching_rule_in_chain_state' => 'ldapMatchingRuleInChainState',
530
-			'ldapIgnoreNamingRules' => 'ldapIgnoreNamingRules',	// sysconfig
530
+			'ldapIgnoreNamingRules' => 'ldapIgnoreNamingRules', // sysconfig
531 531
 			'ldap_connection_timeout' => 'ldapConnectionTimeout',
532 532
 		];
533 533
 		return $array;
Please login to merge, or discard this patch.
apps/user_ldap/lib/Connection.php 1 patch
Indentation   +645 added lines, -645 removed lines patch added patch discarded remove patch
@@ -74,649 +74,649 @@
 block discarded – undo
74 74
  * @property string ldapMatchingRuleInChainState
75 75
  */
76 76
 class Connection extends LDAPUtility {
77
-	/**
78
-	 * @var resource|\LDAP\Connection|null
79
-	 */
80
-	private $ldapConnectionRes = null;
81
-
82
-	/**
83
-	 * @var string
84
-	 */
85
-	private $configPrefix;
86
-
87
-	/**
88
-	 * @var ?string
89
-	 */
90
-	private $configID;
91
-
92
-	/**
93
-	 * @var bool
94
-	 */
95
-	private $configured = false;
96
-
97
-	/**
98
-	 * @var bool whether connection should be kept on __destruct
99
-	 */
100
-	private $dontDestruct = false;
101
-
102
-	/**
103
-	 * @var bool runtime flag that indicates whether supported primary groups are available
104
-	 */
105
-	public $hasPrimaryGroups = true;
106
-
107
-	/**
108
-	 * @var bool runtime flag that indicates whether supported POSIX gidNumber are available
109
-	 */
110
-	public $hasGidNumber = true;
111
-
112
-	/**
113
-	 * @var \OCP\ICache|null
114
-	 */
115
-	protected $cache = null;
116
-
117
-	/** @var Configuration settings handler **/
118
-	protected $configuration;
119
-
120
-	/**
121
-	 * @var bool
122
-	 */
123
-	protected $doNotValidate = false;
124
-
125
-	/**
126
-	 * @var bool
127
-	 */
128
-	protected $ignoreValidation = false;
129
-
130
-	/**
131
-	 * @var array{sum?: string, result?: bool}
132
-	 */
133
-	protected $bindResult = [];
134
-
135
-	/** @var LoggerInterface */
136
-	protected $logger;
137
-
138
-	/**
139
-	 * Constructor
140
-	 * @param string $configPrefix a string with the prefix for the configkey column (appconfig table)
141
-	 * @param string|null $configID a string with the value for the appid column (appconfig table) or null for on-the-fly connections
142
-	 */
143
-	public function __construct(ILDAPWrapper $ldap, string $configPrefix = '', ?string $configID = 'user_ldap') {
144
-		parent::__construct($ldap);
145
-		$this->configPrefix = $configPrefix;
146
-		$this->configID = $configID;
147
-		$this->configuration = new Configuration($configPrefix, !is_null($configID));
148
-		$memcache = \OC::$server->getMemCacheFactory();
149
-		if ($memcache->isAvailable()) {
150
-			$this->cache = $memcache->createDistributed();
151
-		}
152
-		$helper = new Helper(\OC::$server->getConfig(), \OC::$server->getDatabaseConnection());
153
-		$this->doNotValidate = !in_array($this->configPrefix,
154
-			$helper->getServerConfigurationPrefixes());
155
-		$this->logger = \OC::$server->get(LoggerInterface::class);
156
-	}
157
-
158
-	public function __destruct() {
159
-		if (!$this->dontDestruct && $this->ldap->isResource($this->ldapConnectionRes)) {
160
-			@$this->ldap->unbind($this->ldapConnectionRes);
161
-			$this->bindResult = [];
162
-		}
163
-	}
164
-
165
-	/**
166
-	 * defines behaviour when the instance is cloned
167
-	 */
168
-	public function __clone() {
169
-		$this->configuration = new Configuration($this->configPrefix,
170
-			!is_null($this->configID));
171
-		if (count($this->bindResult) !== 0 && $this->bindResult['result'] === true) {
172
-			$this->bindResult = [];
173
-		}
174
-		$this->ldapConnectionRes = null;
175
-		$this->dontDestruct = true;
176
-	}
177
-
178
-	public function __get(string $name) {
179
-		if (!$this->configured) {
180
-			$this->readConfiguration();
181
-		}
182
-
183
-		return $this->configuration->$name;
184
-	}
185
-
186
-	/**
187
-	 * @param string $name
188
-	 * @param mixed $value
189
-	 */
190
-	public function __set($name, $value) {
191
-		$this->doNotValidate = false;
192
-		$before = $this->configuration->$name;
193
-		$this->configuration->$name = $value;
194
-		$after = $this->configuration->$name;
195
-		if ($before !== $after) {
196
-			if ($this->configID !== '' && $this->configID !== null) {
197
-				$this->configuration->saveConfiguration();
198
-			}
199
-			$this->validateConfiguration();
200
-		}
201
-	}
202
-
203
-	/**
204
-	 * @param string $rule
205
-	 * @return array
206
-	 * @throws \RuntimeException
207
-	 */
208
-	public function resolveRule($rule) {
209
-		return $this->configuration->resolveRule($rule);
210
-	}
211
-
212
-	/**
213
-	 * sets whether the result of the configuration validation shall
214
-	 * be ignored when establishing the connection. Used by the Wizard
215
-	 * in early configuration state.
216
-	 * @param bool $state
217
-	 */
218
-	public function setIgnoreValidation($state) {
219
-		$this->ignoreValidation = (bool)$state;
220
-	}
221
-
222
-	/**
223
-	 * initializes the LDAP backend
224
-	 * @param bool $force read the config settings no matter what
225
-	 */
226
-	public function init($force = false) {
227
-		$this->readConfiguration($force);
228
-		$this->establishConnection();
229
-	}
230
-
231
-	/**
232
-	 * @return resource|\LDAP\Connection The LDAP resource
233
-	 */
234
-	public function getConnectionResource() {
235
-		if (!$this->ldapConnectionRes) {
236
-			$this->init();
237
-		} elseif (!$this->ldap->isResource($this->ldapConnectionRes)) {
238
-			$this->ldapConnectionRes = null;
239
-			$this->establishConnection();
240
-		}
241
-		if (is_null($this->ldapConnectionRes)) {
242
-			$this->logger->error(
243
-				'No LDAP Connection to server ' . $this->configuration->ldapHost,
244
-				['app' => 'user_ldap']
245
-			);
246
-			throw new ServerNotAvailableException('Connection to LDAP server could not be established');
247
-		}
248
-		return $this->ldapConnectionRes;
249
-	}
250
-
251
-	/**
252
-	 * resets the connection resource
253
-	 */
254
-	public function resetConnectionResource() {
255
-		if (!is_null($this->ldapConnectionRes)) {
256
-			@$this->ldap->unbind($this->ldapConnectionRes);
257
-			$this->ldapConnectionRes = null;
258
-			$this->bindResult = [];
259
-		}
260
-	}
261
-
262
-	/**
263
-	 * @param string|null $key
264
-	 * @return string
265
-	 */
266
-	private function getCacheKey($key) {
267
-		$prefix = 'LDAP-'.$this->configID.'-'.$this->configPrefix.'-';
268
-		if (is_null($key)) {
269
-			return $prefix;
270
-		}
271
-		return $prefix.hash('sha256', $key);
272
-	}
273
-
274
-	/**
275
-	 * @param string $key
276
-	 * @return mixed|null
277
-	 */
278
-	public function getFromCache($key) {
279
-		if (!$this->configured) {
280
-			$this->readConfiguration();
281
-		}
282
-		if (is_null($this->cache) || !$this->configuration->ldapCacheTTL) {
283
-			return null;
284
-		}
285
-		$key = $this->getCacheKey($key);
286
-
287
-		return json_decode(base64_decode($this->cache->get($key) ?? ''), true);
288
-	}
289
-
290
-	/**
291
-	 * @param string $key
292
-	 * @param mixed $value
293
-	 */
294
-	public function writeToCache($key, $value): void {
295
-		if (!$this->configured) {
296
-			$this->readConfiguration();
297
-		}
298
-		if (is_null($this->cache)
299
-			|| !$this->configuration->ldapCacheTTL
300
-			|| !$this->configuration->ldapConfigurationActive) {
301
-			return;
302
-		}
303
-		$key = $this->getCacheKey($key);
304
-		$value = base64_encode(json_encode($value));
305
-		$this->cache->set($key, $value, $this->configuration->ldapCacheTTL);
306
-	}
307
-
308
-	public function clearCache() {
309
-		if (!is_null($this->cache)) {
310
-			$this->cache->clear($this->getCacheKey(null));
311
-		}
312
-	}
313
-
314
-	/**
315
-	 * Caches the general LDAP configuration.
316
-	 * @param bool $force optional. true, if the re-read should be forced. defaults
317
-	 * to false.
318
-	 * @return null
319
-	 */
320
-	private function readConfiguration($force = false) {
321
-		if ((!$this->configured || $force) && !is_null($this->configID)) {
322
-			$this->configuration->readConfiguration();
323
-			$this->configured = $this->validateConfiguration();
324
-		}
325
-	}
326
-
327
-	/**
328
-	 * set LDAP configuration with values delivered by an array, not read from configuration
329
-	 * @param array $config array that holds the config parameters in an associated array
330
-	 * @param array &$setParameters optional; array where the set fields will be given to
331
-	 * @return bool true if config validates, false otherwise. Check with $setParameters for detailed success on single parameters
332
-	 */
333
-	public function setConfiguration($config, &$setParameters = null): bool {
334
-		if (is_null($setParameters)) {
335
-			$setParameters = [];
336
-		}
337
-		$this->doNotValidate = false;
338
-		$this->configuration->setConfiguration($config, $setParameters);
339
-		if (count($setParameters) > 0) {
340
-			$this->configured = $this->validateConfiguration();
341
-		}
342
-
343
-
344
-		return $this->configured;
345
-	}
346
-
347
-	/**
348
-	 * saves the current Configuration in the database and empties the
349
-	 * cache
350
-	 * @return null
351
-	 */
352
-	public function saveConfiguration() {
353
-		$this->configuration->saveConfiguration();
354
-		$this->clearCache();
355
-	}
356
-
357
-	/**
358
-	 * get the current LDAP configuration
359
-	 * @return array
360
-	 */
361
-	public function getConfiguration() {
362
-		$this->readConfiguration();
363
-		$config = $this->configuration->getConfiguration();
364
-		$cta = $this->configuration->getConfigTranslationArray();
365
-		$result = [];
366
-		foreach ($cta as $dbkey => $configkey) {
367
-			switch ($configkey) {
368
-				case 'homeFolderNamingRule':
369
-					if (strpos($config[$configkey], 'attr:') === 0) {
370
-						$result[$dbkey] = substr($config[$configkey], 5);
371
-					} else {
372
-						$result[$dbkey] = '';
373
-					}
374
-					break;
375
-				case 'ldapBase':
376
-				case 'ldapBaseUsers':
377
-				case 'ldapBaseGroups':
378
-				case 'ldapAttributesForUserSearch':
379
-				case 'ldapAttributesForGroupSearch':
380
-					if (is_array($config[$configkey])) {
381
-						$result[$dbkey] = implode("\n", $config[$configkey]);
382
-						break;
383
-					} //else follows default
384
-					// no break
385
-				default:
386
-					$result[$dbkey] = $config[$configkey];
387
-			}
388
-		}
389
-		return $result;
390
-	}
391
-
392
-	private function doSoftValidation() {
393
-		//if User or Group Base are not set, take over Base DN setting
394
-		foreach (['ldapBaseUsers', 'ldapBaseGroups'] as $keyBase) {
395
-			$val = $this->configuration->$keyBase;
396
-			if (empty($val)) {
397
-				$this->configuration->$keyBase = $this->configuration->ldapBase;
398
-			}
399
-		}
400
-
401
-		foreach (['ldapExpertUUIDUserAttr' => 'ldapUuidUserAttribute',
402
-			'ldapExpertUUIDGroupAttr' => 'ldapUuidGroupAttribute']
403
-				as $expertSetting => $effectiveSetting) {
404
-			$uuidOverride = $this->configuration->$expertSetting;
405
-			if (!empty($uuidOverride)) {
406
-				$this->configuration->$effectiveSetting = $uuidOverride;
407
-			} else {
408
-				$uuidAttributes = Access::UUID_ATTRIBUTES;
409
-				array_unshift($uuidAttributes, 'auto');
410
-				if (!in_array($this->configuration->$effectiveSetting, $uuidAttributes)
411
-					&& !is_null($this->configID)) {
412
-					$this->configuration->$effectiveSetting = 'auto';
413
-					$this->configuration->saveConfiguration();
414
-					$this->logger->info(
415
-						'Illegal value for the '.$effectiveSetting.', reset to autodetect.',
416
-						['app' => 'user_ldap']
417
-					);
418
-				}
419
-			}
420
-		}
421
-
422
-		$backupPort = (int)$this->configuration->ldapBackupPort;
423
-		if ($backupPort <= 0) {
424
-			$this->configuration->backupPort = $this->configuration->ldapPort;
425
-		}
426
-
427
-		//make sure empty search attributes are saved as simple, empty array
428
-		$saKeys = ['ldapAttributesForUserSearch',
429
-			'ldapAttributesForGroupSearch'];
430
-		foreach ($saKeys as $key) {
431
-			$val = $this->configuration->$key;
432
-			if (is_array($val) && count($val) === 1 && empty($val[0])) {
433
-				$this->configuration->$key = [];
434
-			}
435
-		}
436
-
437
-		if ((stripos((string)$this->configuration->ldapHost, 'ldaps://') === 0)
438
-			&& $this->configuration->ldapTLS) {
439
-			$this->configuration->ldapTLS = false;
440
-			$this->logger->info(
441
-				'LDAPS (already using secure connection) and TLS do not work together. Switched off TLS.',
442
-				['app' => 'user_ldap']
443
-			);
444
-		}
445
-	}
446
-
447
-	/**
448
-	 * @return bool
449
-	 */
450
-	private function doCriticalValidation() {
451
-		$configurationOK = true;
452
-		$errorStr = 'Configuration Error (prefix '.
453
-			(string)$this->configPrefix .'): ';
454
-
455
-		//options that shall not be empty
456
-		$options = ['ldapHost', 'ldapPort', 'ldapUserDisplayName',
457
-			'ldapGroupDisplayName', 'ldapLoginFilter'];
458
-		foreach ($options as $key) {
459
-			$val = $this->configuration->$key;
460
-			if (empty($val)) {
461
-				switch ($key) {
462
-					case 'ldapHost':
463
-						$subj = 'LDAP Host';
464
-						break;
465
-					case 'ldapPort':
466
-						$subj = 'LDAP Port';
467
-						break;
468
-					case 'ldapUserDisplayName':
469
-						$subj = 'LDAP User Display Name';
470
-						break;
471
-					case 'ldapGroupDisplayName':
472
-						$subj = 'LDAP Group Display Name';
473
-						break;
474
-					case 'ldapLoginFilter':
475
-						$subj = 'LDAP Login Filter';
476
-						break;
477
-					default:
478
-						$subj = $key;
479
-						break;
480
-				}
481
-				$configurationOK = false;
482
-				$this->logger->warning(
483
-					$errorStr.'No '.$subj.' given!',
484
-					['app' => 'user_ldap']
485
-				);
486
-			}
487
-		}
488
-
489
-		//combinations
490
-		$agent = $this->configuration->ldapAgentName;
491
-		$pwd = $this->configuration->ldapAgentPassword;
492
-		if (
493
-			($agent === '' && $pwd !== '')
494
-			|| ($agent !== '' && $pwd === '')
495
-		) {
496
-			$this->logger->warning(
497
-				$errorStr.'either no password is given for the user ' .
498
-					'agent or a password is given, but not an LDAP agent.',
499
-				['app' => 'user_ldap']
500
-			);
501
-			$configurationOK = false;
502
-		}
503
-
504
-		$base = $this->configuration->ldapBase;
505
-		$baseUsers = $this->configuration->ldapBaseUsers;
506
-		$baseGroups = $this->configuration->ldapBaseGroups;
507
-
508
-		if (empty($base) && empty($baseUsers) && empty($baseGroups)) {
509
-			$this->logger->warning(
510
-				$errorStr.'Not a single Base DN given.',
511
-				['app' => 'user_ldap']
512
-			);
513
-			$configurationOK = false;
514
-		}
515
-
516
-		if (mb_strpos((string)$this->configuration->ldapLoginFilter, '%uid', 0, 'UTF-8')
517
-		   === false) {
518
-			$this->logger->warning(
519
-				$errorStr.'login filter does not contain %uid place holder.',
520
-				['app' => 'user_ldap']
521
-			);
522
-			$configurationOK = false;
523
-		}
524
-
525
-		return $configurationOK;
526
-	}
527
-
528
-	/**
529
-	 * Validates the user specified configuration
530
-	 * @return bool true if configuration seems OK, false otherwise
531
-	 */
532
-	private function validateConfiguration() {
533
-		if ($this->doNotValidate) {
534
-			//don't do a validation if it is a new configuration with pure
535
-			//default values. Will be allowed on changes via __set or
536
-			//setConfiguration
537
-			return false;
538
-		}
539
-
540
-		// first step: "soft" checks: settings that are not really
541
-		// necessary, but advisable. If left empty, give an info message
542
-		$this->doSoftValidation();
543
-
544
-		//second step: critical checks. If left empty or filled wrong, mark as
545
-		//not configured and give a warning.
546
-		return $this->doCriticalValidation();
547
-	}
548
-
549
-
550
-	/**
551
-	 * Connects and Binds to LDAP
552
-	 *
553
-	 * @throws ServerNotAvailableException
554
-	 */
555
-	private function establishConnection() {
556
-		if (!$this->configuration->ldapConfigurationActive) {
557
-			return null;
558
-		}
559
-		static $phpLDAPinstalled = true;
560
-		if (!$phpLDAPinstalled) {
561
-			return false;
562
-		}
563
-		if (!$this->ignoreValidation && !$this->configured) {
564
-			$this->logger->warning(
565
-				'Configuration is invalid, cannot connect',
566
-				['app' => 'user_ldap']
567
-			);
568
-			return false;
569
-		}
570
-		if (!$this->ldapConnectionRes) {
571
-			if (!$this->ldap->areLDAPFunctionsAvailable()) {
572
-				$phpLDAPinstalled = false;
573
-				$this->logger->error(
574
-					'function ldap_connect is not available. Make sure that the PHP ldap module is installed.',
575
-					['app' => 'user_ldap']
576
-				);
577
-
578
-				return false;
579
-			}
580
-			if ($this->configuration->turnOffCertCheck) {
581
-				if (putenv('LDAPTLS_REQCERT=never')) {
582
-					$this->logger->debug(
583
-						'Turned off SSL certificate validation successfully.',
584
-						['app' => 'user_ldap']
585
-					);
586
-				} else {
587
-					$this->logger->warning(
588
-						'Could not turn off SSL certificate validation.',
589
-						['app' => 'user_ldap']
590
-					);
591
-				}
592
-			}
593
-
594
-			$isOverrideMainServer = ($this->configuration->ldapOverrideMainServer
595
-				|| $this->getFromCache('overrideMainServer'));
596
-			$isBackupHost = (trim($this->configuration->ldapBackupHost) !== "");
597
-			$bindStatus = false;
598
-			try {
599
-				if (!$isOverrideMainServer) {
600
-					$this->doConnect($this->configuration->ldapHost,
601
-						$this->configuration->ldapPort);
602
-					return $this->bind();
603
-				}
604
-			} catch (ServerNotAvailableException $e) {
605
-				if (!$isBackupHost) {
606
-					throw $e;
607
-				}
608
-				$this->logger->warning(
609
-					'Main LDAP not reachable, connecting to backup',
610
-					[
611
-						'app' => 'user_ldap'
612
-					]
613
-				);
614
-			}
615
-
616
-			//if LDAP server is not reachable, try the Backup (Replica!) Server
617
-			if ($isBackupHost || $isOverrideMainServer) {
618
-				$this->doConnect($this->configuration->ldapBackupHost,
619
-					$this->configuration->ldapBackupPort);
620
-				$this->bindResult = [];
621
-				$bindStatus = $this->bind();
622
-				$error = $this->ldap->isResource($this->ldapConnectionRes) ?
623
-					$this->ldap->errno($this->ldapConnectionRes) : -1;
624
-				if ($bindStatus && $error === 0 && !$this->getFromCache('overrideMainServer')) {
625
-					//when bind to backup server succeeded and failed to main server,
626
-					//skip contacting him until next cache refresh
627
-					$this->writeToCache('overrideMainServer', true);
628
-				}
629
-			}
630
-
631
-			return $bindStatus;
632
-		}
633
-		return null;
634
-	}
635
-
636
-	/**
637
-	 * @param string $host
638
-	 * @param string $port
639
-	 * @return bool
640
-	 * @throws \OC\ServerNotAvailableException
641
-	 */
642
-	private function doConnect($host, $port) {
643
-		if ($host === '') {
644
-			return false;
645
-		}
646
-
647
-		$this->ldapConnectionRes = $this->ldap->connect($host, $port);
648
-
649
-		if (!$this->ldap->setOption($this->ldapConnectionRes, LDAP_OPT_PROTOCOL_VERSION, 3)) {
650
-			throw new ServerNotAvailableException('Could not set required LDAP Protocol version.');
651
-		}
652
-
653
-		if (!$this->ldap->setOption($this->ldapConnectionRes, LDAP_OPT_REFERRALS, 0)) {
654
-			throw new ServerNotAvailableException('Could not disable LDAP referrals.');
655
-		}
656
-
657
-		if (!$this->ldap->setOption($this->ldapConnectionRes, LDAP_OPT_NETWORK_TIMEOUT, $this->configuration->ldapConnectionTimeout)) {
658
-			throw new ServerNotAvailableException('Could not set network timeout');
659
-		}
660
-
661
-		if ($this->configuration->ldapTLS) {
662
-			if (!$this->ldap->startTls($this->ldapConnectionRes)) {
663
-				throw new ServerNotAvailableException('Start TLS failed, when connecting to LDAP host ' . $host . '.');
664
-			}
665
-		}
666
-
667
-		return true;
668
-	}
669
-
670
-	/**
671
-	 * Binds to LDAP
672
-	 */
673
-	public function bind() {
674
-		if (!$this->configuration->ldapConfigurationActive) {
675
-			return false;
676
-		}
677
-		$cr = $this->ldapConnectionRes;
678
-		if (!$this->ldap->isResource($cr)) {
679
-			$cr = $this->getConnectionResource();
680
-		}
681
-
682
-		if (
683
-			count($this->bindResult) !== 0
684
-			&& $this->bindResult['sum'] === md5($this->configuration->ldapAgentName . $this->configPrefix . $this->configuration->ldapAgentPassword)
685
-		) {
686
-			// don't attempt to bind again with the same data as before
687
-			// bind might have been invoked via getConnectionResource(),
688
-			// but we need results specifically for e.g. user login
689
-			return $this->bindResult['result'];
690
-		}
691
-
692
-		$ldapLogin = @$this->ldap->bind($cr,
693
-			$this->configuration->ldapAgentName,
694
-			$this->configuration->ldapAgentPassword);
695
-
696
-		$this->bindResult = [
697
-			'sum' => md5($this->configuration->ldapAgentName . $this->configPrefix . $this->configuration->ldapAgentPassword),
698
-			'result' => $ldapLogin,
699
-		];
700
-
701
-		if (!$ldapLogin) {
702
-			$errno = $this->ldap->errno($cr);
703
-
704
-			$this->logger->warning(
705
-				'Bind failed: ' . $errno . ': ' . $this->ldap->error($cr),
706
-				['app' => 'user_ldap']
707
-			);
708
-
709
-			// Set to failure mode, if LDAP error code is not one of
710
-			// - LDAP_SUCCESS (0)
711
-			// - LDAP_INVALID_CREDENTIALS (49)
712
-			// - LDAP_INSUFFICIENT_ACCESS (50, spotted Apple Open Directory)
713
-			// - LDAP_UNWILLING_TO_PERFORM (53, spotted eDirectory)
714
-			if (!in_array($errno, [0, 49, 50, 53], true)) {
715
-				$this->ldapConnectionRes = null;
716
-			}
717
-
718
-			return false;
719
-		}
720
-		return true;
721
-	}
77
+    /**
78
+     * @var resource|\LDAP\Connection|null
79
+     */
80
+    private $ldapConnectionRes = null;
81
+
82
+    /**
83
+     * @var string
84
+     */
85
+    private $configPrefix;
86
+
87
+    /**
88
+     * @var ?string
89
+     */
90
+    private $configID;
91
+
92
+    /**
93
+     * @var bool
94
+     */
95
+    private $configured = false;
96
+
97
+    /**
98
+     * @var bool whether connection should be kept on __destruct
99
+     */
100
+    private $dontDestruct = false;
101
+
102
+    /**
103
+     * @var bool runtime flag that indicates whether supported primary groups are available
104
+     */
105
+    public $hasPrimaryGroups = true;
106
+
107
+    /**
108
+     * @var bool runtime flag that indicates whether supported POSIX gidNumber are available
109
+     */
110
+    public $hasGidNumber = true;
111
+
112
+    /**
113
+     * @var \OCP\ICache|null
114
+     */
115
+    protected $cache = null;
116
+
117
+    /** @var Configuration settings handler **/
118
+    protected $configuration;
119
+
120
+    /**
121
+     * @var bool
122
+     */
123
+    protected $doNotValidate = false;
124
+
125
+    /**
126
+     * @var bool
127
+     */
128
+    protected $ignoreValidation = false;
129
+
130
+    /**
131
+     * @var array{sum?: string, result?: bool}
132
+     */
133
+    protected $bindResult = [];
134
+
135
+    /** @var LoggerInterface */
136
+    protected $logger;
137
+
138
+    /**
139
+     * Constructor
140
+     * @param string $configPrefix a string with the prefix for the configkey column (appconfig table)
141
+     * @param string|null $configID a string with the value for the appid column (appconfig table) or null for on-the-fly connections
142
+     */
143
+    public function __construct(ILDAPWrapper $ldap, string $configPrefix = '', ?string $configID = 'user_ldap') {
144
+        parent::__construct($ldap);
145
+        $this->configPrefix = $configPrefix;
146
+        $this->configID = $configID;
147
+        $this->configuration = new Configuration($configPrefix, !is_null($configID));
148
+        $memcache = \OC::$server->getMemCacheFactory();
149
+        if ($memcache->isAvailable()) {
150
+            $this->cache = $memcache->createDistributed();
151
+        }
152
+        $helper = new Helper(\OC::$server->getConfig(), \OC::$server->getDatabaseConnection());
153
+        $this->doNotValidate = !in_array($this->configPrefix,
154
+            $helper->getServerConfigurationPrefixes());
155
+        $this->logger = \OC::$server->get(LoggerInterface::class);
156
+    }
157
+
158
+    public function __destruct() {
159
+        if (!$this->dontDestruct && $this->ldap->isResource($this->ldapConnectionRes)) {
160
+            @$this->ldap->unbind($this->ldapConnectionRes);
161
+            $this->bindResult = [];
162
+        }
163
+    }
164
+
165
+    /**
166
+     * defines behaviour when the instance is cloned
167
+     */
168
+    public function __clone() {
169
+        $this->configuration = new Configuration($this->configPrefix,
170
+            !is_null($this->configID));
171
+        if (count($this->bindResult) !== 0 && $this->bindResult['result'] === true) {
172
+            $this->bindResult = [];
173
+        }
174
+        $this->ldapConnectionRes = null;
175
+        $this->dontDestruct = true;
176
+    }
177
+
178
+    public function __get(string $name) {
179
+        if (!$this->configured) {
180
+            $this->readConfiguration();
181
+        }
182
+
183
+        return $this->configuration->$name;
184
+    }
185
+
186
+    /**
187
+     * @param string $name
188
+     * @param mixed $value
189
+     */
190
+    public function __set($name, $value) {
191
+        $this->doNotValidate = false;
192
+        $before = $this->configuration->$name;
193
+        $this->configuration->$name = $value;
194
+        $after = $this->configuration->$name;
195
+        if ($before !== $after) {
196
+            if ($this->configID !== '' && $this->configID !== null) {
197
+                $this->configuration->saveConfiguration();
198
+            }
199
+            $this->validateConfiguration();
200
+        }
201
+    }
202
+
203
+    /**
204
+     * @param string $rule
205
+     * @return array
206
+     * @throws \RuntimeException
207
+     */
208
+    public function resolveRule($rule) {
209
+        return $this->configuration->resolveRule($rule);
210
+    }
211
+
212
+    /**
213
+     * sets whether the result of the configuration validation shall
214
+     * be ignored when establishing the connection. Used by the Wizard
215
+     * in early configuration state.
216
+     * @param bool $state
217
+     */
218
+    public function setIgnoreValidation($state) {
219
+        $this->ignoreValidation = (bool)$state;
220
+    }
221
+
222
+    /**
223
+     * initializes the LDAP backend
224
+     * @param bool $force read the config settings no matter what
225
+     */
226
+    public function init($force = false) {
227
+        $this->readConfiguration($force);
228
+        $this->establishConnection();
229
+    }
230
+
231
+    /**
232
+     * @return resource|\LDAP\Connection The LDAP resource
233
+     */
234
+    public function getConnectionResource() {
235
+        if (!$this->ldapConnectionRes) {
236
+            $this->init();
237
+        } elseif (!$this->ldap->isResource($this->ldapConnectionRes)) {
238
+            $this->ldapConnectionRes = null;
239
+            $this->establishConnection();
240
+        }
241
+        if (is_null($this->ldapConnectionRes)) {
242
+            $this->logger->error(
243
+                'No LDAP Connection to server ' . $this->configuration->ldapHost,
244
+                ['app' => 'user_ldap']
245
+            );
246
+            throw new ServerNotAvailableException('Connection to LDAP server could not be established');
247
+        }
248
+        return $this->ldapConnectionRes;
249
+    }
250
+
251
+    /**
252
+     * resets the connection resource
253
+     */
254
+    public function resetConnectionResource() {
255
+        if (!is_null($this->ldapConnectionRes)) {
256
+            @$this->ldap->unbind($this->ldapConnectionRes);
257
+            $this->ldapConnectionRes = null;
258
+            $this->bindResult = [];
259
+        }
260
+    }
261
+
262
+    /**
263
+     * @param string|null $key
264
+     * @return string
265
+     */
266
+    private function getCacheKey($key) {
267
+        $prefix = 'LDAP-'.$this->configID.'-'.$this->configPrefix.'-';
268
+        if (is_null($key)) {
269
+            return $prefix;
270
+        }
271
+        return $prefix.hash('sha256', $key);
272
+    }
273
+
274
+    /**
275
+     * @param string $key
276
+     * @return mixed|null
277
+     */
278
+    public function getFromCache($key) {
279
+        if (!$this->configured) {
280
+            $this->readConfiguration();
281
+        }
282
+        if (is_null($this->cache) || !$this->configuration->ldapCacheTTL) {
283
+            return null;
284
+        }
285
+        $key = $this->getCacheKey($key);
286
+
287
+        return json_decode(base64_decode($this->cache->get($key) ?? ''), true);
288
+    }
289
+
290
+    /**
291
+     * @param string $key
292
+     * @param mixed $value
293
+     */
294
+    public function writeToCache($key, $value): void {
295
+        if (!$this->configured) {
296
+            $this->readConfiguration();
297
+        }
298
+        if (is_null($this->cache)
299
+            || !$this->configuration->ldapCacheTTL
300
+            || !$this->configuration->ldapConfigurationActive) {
301
+            return;
302
+        }
303
+        $key = $this->getCacheKey($key);
304
+        $value = base64_encode(json_encode($value));
305
+        $this->cache->set($key, $value, $this->configuration->ldapCacheTTL);
306
+    }
307
+
308
+    public function clearCache() {
309
+        if (!is_null($this->cache)) {
310
+            $this->cache->clear($this->getCacheKey(null));
311
+        }
312
+    }
313
+
314
+    /**
315
+     * Caches the general LDAP configuration.
316
+     * @param bool $force optional. true, if the re-read should be forced. defaults
317
+     * to false.
318
+     * @return null
319
+     */
320
+    private function readConfiguration($force = false) {
321
+        if ((!$this->configured || $force) && !is_null($this->configID)) {
322
+            $this->configuration->readConfiguration();
323
+            $this->configured = $this->validateConfiguration();
324
+        }
325
+    }
326
+
327
+    /**
328
+     * set LDAP configuration with values delivered by an array, not read from configuration
329
+     * @param array $config array that holds the config parameters in an associated array
330
+     * @param array &$setParameters optional; array where the set fields will be given to
331
+     * @return bool true if config validates, false otherwise. Check with $setParameters for detailed success on single parameters
332
+     */
333
+    public function setConfiguration($config, &$setParameters = null): bool {
334
+        if (is_null($setParameters)) {
335
+            $setParameters = [];
336
+        }
337
+        $this->doNotValidate = false;
338
+        $this->configuration->setConfiguration($config, $setParameters);
339
+        if (count($setParameters) > 0) {
340
+            $this->configured = $this->validateConfiguration();
341
+        }
342
+
343
+
344
+        return $this->configured;
345
+    }
346
+
347
+    /**
348
+     * saves the current Configuration in the database and empties the
349
+     * cache
350
+     * @return null
351
+     */
352
+    public function saveConfiguration() {
353
+        $this->configuration->saveConfiguration();
354
+        $this->clearCache();
355
+    }
356
+
357
+    /**
358
+     * get the current LDAP configuration
359
+     * @return array
360
+     */
361
+    public function getConfiguration() {
362
+        $this->readConfiguration();
363
+        $config = $this->configuration->getConfiguration();
364
+        $cta = $this->configuration->getConfigTranslationArray();
365
+        $result = [];
366
+        foreach ($cta as $dbkey => $configkey) {
367
+            switch ($configkey) {
368
+                case 'homeFolderNamingRule':
369
+                    if (strpos($config[$configkey], 'attr:') === 0) {
370
+                        $result[$dbkey] = substr($config[$configkey], 5);
371
+                    } else {
372
+                        $result[$dbkey] = '';
373
+                    }
374
+                    break;
375
+                case 'ldapBase':
376
+                case 'ldapBaseUsers':
377
+                case 'ldapBaseGroups':
378
+                case 'ldapAttributesForUserSearch':
379
+                case 'ldapAttributesForGroupSearch':
380
+                    if (is_array($config[$configkey])) {
381
+                        $result[$dbkey] = implode("\n", $config[$configkey]);
382
+                        break;
383
+                    } //else follows default
384
+                    // no break
385
+                default:
386
+                    $result[$dbkey] = $config[$configkey];
387
+            }
388
+        }
389
+        return $result;
390
+    }
391
+
392
+    private function doSoftValidation() {
393
+        //if User or Group Base are not set, take over Base DN setting
394
+        foreach (['ldapBaseUsers', 'ldapBaseGroups'] as $keyBase) {
395
+            $val = $this->configuration->$keyBase;
396
+            if (empty($val)) {
397
+                $this->configuration->$keyBase = $this->configuration->ldapBase;
398
+            }
399
+        }
400
+
401
+        foreach (['ldapExpertUUIDUserAttr' => 'ldapUuidUserAttribute',
402
+            'ldapExpertUUIDGroupAttr' => 'ldapUuidGroupAttribute']
403
+                as $expertSetting => $effectiveSetting) {
404
+            $uuidOverride = $this->configuration->$expertSetting;
405
+            if (!empty($uuidOverride)) {
406
+                $this->configuration->$effectiveSetting = $uuidOverride;
407
+            } else {
408
+                $uuidAttributes = Access::UUID_ATTRIBUTES;
409
+                array_unshift($uuidAttributes, 'auto');
410
+                if (!in_array($this->configuration->$effectiveSetting, $uuidAttributes)
411
+                    && !is_null($this->configID)) {
412
+                    $this->configuration->$effectiveSetting = 'auto';
413
+                    $this->configuration->saveConfiguration();
414
+                    $this->logger->info(
415
+                        'Illegal value for the '.$effectiveSetting.', reset to autodetect.',
416
+                        ['app' => 'user_ldap']
417
+                    );
418
+                }
419
+            }
420
+        }
421
+
422
+        $backupPort = (int)$this->configuration->ldapBackupPort;
423
+        if ($backupPort <= 0) {
424
+            $this->configuration->backupPort = $this->configuration->ldapPort;
425
+        }
426
+
427
+        //make sure empty search attributes are saved as simple, empty array
428
+        $saKeys = ['ldapAttributesForUserSearch',
429
+            'ldapAttributesForGroupSearch'];
430
+        foreach ($saKeys as $key) {
431
+            $val = $this->configuration->$key;
432
+            if (is_array($val) && count($val) === 1 && empty($val[0])) {
433
+                $this->configuration->$key = [];
434
+            }
435
+        }
436
+
437
+        if ((stripos((string)$this->configuration->ldapHost, 'ldaps://') === 0)
438
+            && $this->configuration->ldapTLS) {
439
+            $this->configuration->ldapTLS = false;
440
+            $this->logger->info(
441
+                'LDAPS (already using secure connection) and TLS do not work together. Switched off TLS.',
442
+                ['app' => 'user_ldap']
443
+            );
444
+        }
445
+    }
446
+
447
+    /**
448
+     * @return bool
449
+     */
450
+    private function doCriticalValidation() {
451
+        $configurationOK = true;
452
+        $errorStr = 'Configuration Error (prefix '.
453
+            (string)$this->configPrefix .'): ';
454
+
455
+        //options that shall not be empty
456
+        $options = ['ldapHost', 'ldapPort', 'ldapUserDisplayName',
457
+            'ldapGroupDisplayName', 'ldapLoginFilter'];
458
+        foreach ($options as $key) {
459
+            $val = $this->configuration->$key;
460
+            if (empty($val)) {
461
+                switch ($key) {
462
+                    case 'ldapHost':
463
+                        $subj = 'LDAP Host';
464
+                        break;
465
+                    case 'ldapPort':
466
+                        $subj = 'LDAP Port';
467
+                        break;
468
+                    case 'ldapUserDisplayName':
469
+                        $subj = 'LDAP User Display Name';
470
+                        break;
471
+                    case 'ldapGroupDisplayName':
472
+                        $subj = 'LDAP Group Display Name';
473
+                        break;
474
+                    case 'ldapLoginFilter':
475
+                        $subj = 'LDAP Login Filter';
476
+                        break;
477
+                    default:
478
+                        $subj = $key;
479
+                        break;
480
+                }
481
+                $configurationOK = false;
482
+                $this->logger->warning(
483
+                    $errorStr.'No '.$subj.' given!',
484
+                    ['app' => 'user_ldap']
485
+                );
486
+            }
487
+        }
488
+
489
+        //combinations
490
+        $agent = $this->configuration->ldapAgentName;
491
+        $pwd = $this->configuration->ldapAgentPassword;
492
+        if (
493
+            ($agent === '' && $pwd !== '')
494
+            || ($agent !== '' && $pwd === '')
495
+        ) {
496
+            $this->logger->warning(
497
+                $errorStr.'either no password is given for the user ' .
498
+                    'agent or a password is given, but not an LDAP agent.',
499
+                ['app' => 'user_ldap']
500
+            );
501
+            $configurationOK = false;
502
+        }
503
+
504
+        $base = $this->configuration->ldapBase;
505
+        $baseUsers = $this->configuration->ldapBaseUsers;
506
+        $baseGroups = $this->configuration->ldapBaseGroups;
507
+
508
+        if (empty($base) && empty($baseUsers) && empty($baseGroups)) {
509
+            $this->logger->warning(
510
+                $errorStr.'Not a single Base DN given.',
511
+                ['app' => 'user_ldap']
512
+            );
513
+            $configurationOK = false;
514
+        }
515
+
516
+        if (mb_strpos((string)$this->configuration->ldapLoginFilter, '%uid', 0, 'UTF-8')
517
+            === false) {
518
+            $this->logger->warning(
519
+                $errorStr.'login filter does not contain %uid place holder.',
520
+                ['app' => 'user_ldap']
521
+            );
522
+            $configurationOK = false;
523
+        }
524
+
525
+        return $configurationOK;
526
+    }
527
+
528
+    /**
529
+     * Validates the user specified configuration
530
+     * @return bool true if configuration seems OK, false otherwise
531
+     */
532
+    private function validateConfiguration() {
533
+        if ($this->doNotValidate) {
534
+            //don't do a validation if it is a new configuration with pure
535
+            //default values. Will be allowed on changes via __set or
536
+            //setConfiguration
537
+            return false;
538
+        }
539
+
540
+        // first step: "soft" checks: settings that are not really
541
+        // necessary, but advisable. If left empty, give an info message
542
+        $this->doSoftValidation();
543
+
544
+        //second step: critical checks. If left empty or filled wrong, mark as
545
+        //not configured and give a warning.
546
+        return $this->doCriticalValidation();
547
+    }
548
+
549
+
550
+    /**
551
+     * Connects and Binds to LDAP
552
+     *
553
+     * @throws ServerNotAvailableException
554
+     */
555
+    private function establishConnection() {
556
+        if (!$this->configuration->ldapConfigurationActive) {
557
+            return null;
558
+        }
559
+        static $phpLDAPinstalled = true;
560
+        if (!$phpLDAPinstalled) {
561
+            return false;
562
+        }
563
+        if (!$this->ignoreValidation && !$this->configured) {
564
+            $this->logger->warning(
565
+                'Configuration is invalid, cannot connect',
566
+                ['app' => 'user_ldap']
567
+            );
568
+            return false;
569
+        }
570
+        if (!$this->ldapConnectionRes) {
571
+            if (!$this->ldap->areLDAPFunctionsAvailable()) {
572
+                $phpLDAPinstalled = false;
573
+                $this->logger->error(
574
+                    'function ldap_connect is not available. Make sure that the PHP ldap module is installed.',
575
+                    ['app' => 'user_ldap']
576
+                );
577
+
578
+                return false;
579
+            }
580
+            if ($this->configuration->turnOffCertCheck) {
581
+                if (putenv('LDAPTLS_REQCERT=never')) {
582
+                    $this->logger->debug(
583
+                        'Turned off SSL certificate validation successfully.',
584
+                        ['app' => 'user_ldap']
585
+                    );
586
+                } else {
587
+                    $this->logger->warning(
588
+                        'Could not turn off SSL certificate validation.',
589
+                        ['app' => 'user_ldap']
590
+                    );
591
+                }
592
+            }
593
+
594
+            $isOverrideMainServer = ($this->configuration->ldapOverrideMainServer
595
+                || $this->getFromCache('overrideMainServer'));
596
+            $isBackupHost = (trim($this->configuration->ldapBackupHost) !== "");
597
+            $bindStatus = false;
598
+            try {
599
+                if (!$isOverrideMainServer) {
600
+                    $this->doConnect($this->configuration->ldapHost,
601
+                        $this->configuration->ldapPort);
602
+                    return $this->bind();
603
+                }
604
+            } catch (ServerNotAvailableException $e) {
605
+                if (!$isBackupHost) {
606
+                    throw $e;
607
+                }
608
+                $this->logger->warning(
609
+                    'Main LDAP not reachable, connecting to backup',
610
+                    [
611
+                        'app' => 'user_ldap'
612
+                    ]
613
+                );
614
+            }
615
+
616
+            //if LDAP server is not reachable, try the Backup (Replica!) Server
617
+            if ($isBackupHost || $isOverrideMainServer) {
618
+                $this->doConnect($this->configuration->ldapBackupHost,
619
+                    $this->configuration->ldapBackupPort);
620
+                $this->bindResult = [];
621
+                $bindStatus = $this->bind();
622
+                $error = $this->ldap->isResource($this->ldapConnectionRes) ?
623
+                    $this->ldap->errno($this->ldapConnectionRes) : -1;
624
+                if ($bindStatus && $error === 0 && !$this->getFromCache('overrideMainServer')) {
625
+                    //when bind to backup server succeeded and failed to main server,
626
+                    //skip contacting him until next cache refresh
627
+                    $this->writeToCache('overrideMainServer', true);
628
+                }
629
+            }
630
+
631
+            return $bindStatus;
632
+        }
633
+        return null;
634
+    }
635
+
636
+    /**
637
+     * @param string $host
638
+     * @param string $port
639
+     * @return bool
640
+     * @throws \OC\ServerNotAvailableException
641
+     */
642
+    private function doConnect($host, $port) {
643
+        if ($host === '') {
644
+            return false;
645
+        }
646
+
647
+        $this->ldapConnectionRes = $this->ldap->connect($host, $port);
648
+
649
+        if (!$this->ldap->setOption($this->ldapConnectionRes, LDAP_OPT_PROTOCOL_VERSION, 3)) {
650
+            throw new ServerNotAvailableException('Could not set required LDAP Protocol version.');
651
+        }
652
+
653
+        if (!$this->ldap->setOption($this->ldapConnectionRes, LDAP_OPT_REFERRALS, 0)) {
654
+            throw new ServerNotAvailableException('Could not disable LDAP referrals.');
655
+        }
656
+
657
+        if (!$this->ldap->setOption($this->ldapConnectionRes, LDAP_OPT_NETWORK_TIMEOUT, $this->configuration->ldapConnectionTimeout)) {
658
+            throw new ServerNotAvailableException('Could not set network timeout');
659
+        }
660
+
661
+        if ($this->configuration->ldapTLS) {
662
+            if (!$this->ldap->startTls($this->ldapConnectionRes)) {
663
+                throw new ServerNotAvailableException('Start TLS failed, when connecting to LDAP host ' . $host . '.');
664
+            }
665
+        }
666
+
667
+        return true;
668
+    }
669
+
670
+    /**
671
+     * Binds to LDAP
672
+     */
673
+    public function bind() {
674
+        if (!$this->configuration->ldapConfigurationActive) {
675
+            return false;
676
+        }
677
+        $cr = $this->ldapConnectionRes;
678
+        if (!$this->ldap->isResource($cr)) {
679
+            $cr = $this->getConnectionResource();
680
+        }
681
+
682
+        if (
683
+            count($this->bindResult) !== 0
684
+            && $this->bindResult['sum'] === md5($this->configuration->ldapAgentName . $this->configPrefix . $this->configuration->ldapAgentPassword)
685
+        ) {
686
+            // don't attempt to bind again with the same data as before
687
+            // bind might have been invoked via getConnectionResource(),
688
+            // but we need results specifically for e.g. user login
689
+            return $this->bindResult['result'];
690
+        }
691
+
692
+        $ldapLogin = @$this->ldap->bind($cr,
693
+            $this->configuration->ldapAgentName,
694
+            $this->configuration->ldapAgentPassword);
695
+
696
+        $this->bindResult = [
697
+            'sum' => md5($this->configuration->ldapAgentName . $this->configPrefix . $this->configuration->ldapAgentPassword),
698
+            'result' => $ldapLogin,
699
+        ];
700
+
701
+        if (!$ldapLogin) {
702
+            $errno = $this->ldap->errno($cr);
703
+
704
+            $this->logger->warning(
705
+                'Bind failed: ' . $errno . ': ' . $this->ldap->error($cr),
706
+                ['app' => 'user_ldap']
707
+            );
708
+
709
+            // Set to failure mode, if LDAP error code is not one of
710
+            // - LDAP_SUCCESS (0)
711
+            // - LDAP_INVALID_CREDENTIALS (49)
712
+            // - LDAP_INSUFFICIENT_ACCESS (50, spotted Apple Open Directory)
713
+            // - LDAP_UNWILLING_TO_PERFORM (53, spotted eDirectory)
714
+            if (!in_array($errno, [0, 49, 50, 53], true)) {
715
+                $this->ldapConnectionRes = null;
716
+            }
717
+
718
+            return false;
719
+        }
720
+        return true;
721
+    }
722 722
 }
Please login to merge, or discard this patch.