Project

General

Profile

Download (30.6 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php
2
/*
3
 * system_authservers.php
4
 *
5
 * part of pfSense (https://www.pfsense.org)
6
 * Copyright (c) 2004-2013 BSD Perimeter
7
 * Copyright (c) 2013-2016 Electric Sheep Fencing
8
 * Copyright (c) 2014-2025 Rubicon Communications, LLC (Netgate)
9
 * Copyright (c) 2008 Shrew Soft Inc
10
 * All rights reserved.
11
 *
12
 * Licensed under the Apache License, Version 2.0 (the "License");
13
 * you may not use this file except in compliance with the License.
14
 * You may obtain a copy of the License at
15
 *
16
 * http://www.apache.org/licenses/LICENSE-2.0
17
 *
18
 * Unless required by applicable law or agreed to in writing, software
19
 * distributed under the License is distributed on an "AS IS" BASIS,
20
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21
 * See the License for the specific language governing permissions and
22
 * limitations under the License.
23
 */
24

    
25
##|+PRIV
26
##|*IDENT=page-system-authservers
27
##|*NAME=System: Authentication Servers
28
##|*DESCR=Allow access to the 'System: Authentication Servers' page.
29
##|*WARN=standard-warning-root
30
##|*MATCH=system_authservers.php*
31
##|-PRIV
32

    
33
require_once("guiconfig.inc");
34
require_once("auth.inc");
35
require_once("pfsense-utils.inc");
36

    
37
// Have we been called to populate the "Select a container" modal?
38
if ($_REQUEST['ajax']) {
39

    
40
	$ous = array();
41
	$authcfg = array();
42

    
43
	$authcfg['ldap_port'] = $_REQUEST['port'];
44
	$authcfg['ldap_basedn'] = $_REQUEST['basedn'];
45
	$authcfg['host'] = $_REQUEST['host'];
46
	$authcfg['ldap_scope'] = $_REQUEST['scope'];
47
	$authcfg['ldap_binddn'] = $_REQUEST['binddn'];
48
	$authcfg['ldap_bindpw'] = $_REQUEST['bindpw'];
49
	$authcfg['ldap_urltype'] = $_REQUEST['urltype'];
50
	$authcfg['ldap_protver'] = $_REQUEST['proto'];
51
	$authcfg['ldap_authcn'] = explode(";", $_REQUEST['authcn']);
52
	$authcfg['ldap_caref'] = $_REQUEST['cert'];
53

    
54
	$ous = ldap_get_user_ous(true, $authcfg);
55

    
56
	if (empty($ous)) {
57
		print('<span class="text-danger">Could not connect to the LDAP server. Please check the LDAP configuration.</span>');
58
	} else {
59
		$modal = new Modal("Select LDAP containers for authentication", "containers", true);
60
		$group = new Form_MultiCheckboxGroup('Containers');
61

    
62
		if (is_array($ous)) {
63
			$idx = 0;
64

    
65
			foreach ($ous as $ou) {
66
				$group->add(new Form_MultiCheckbox(
67
					'ou' . $idx,
68
					'',
69
					$ou,
70
					in_array($ou, $authcfg['ldap_authcn']),
71
					$ou
72
				));
73

    
74
				$idx++;
75
			}
76
		}
77

    
78
		$modal->add($group);
79

    
80
		// Create a "Save button"
81

    
82
		$btnsv = new Form_Button(
83
			'svcontbtn',
84
			'Save',
85
			null,
86
			'fa-solid fa-save'
87
		);
88

    
89
		$btnsv->removeClass("btn-default)")->addClass("btn-primary");
90

    
91
		$modal->addInput(new Form_StaticText(
92
			'',
93
			$btnsv
94
		));
95

    
96
		print($modal);
97
	}
98

    
99
	exit;
100
}
101

    
102
$id = is_numericint($_REQUEST['id']) ? $_REQUEST['id'] : null;
103

    
104
$a_server = array_values(auth_get_authserver_list());
105

    
106
$act = $_REQUEST['act'];
107

    
108
if ($act == 'dup') {
109
	$dup = true;
110
	$act = 'edit';
111
}
112

    
113
if ($_POST['act'] == "del") {
114

    
115
	if (!$a_server[$_POST['id']]) {
116
		pfSenseHeader("system_authservers.php");
117
		exit;
118
	}
119

    
120
	/* Remove server from main list. */
121
	$serverdeleted = $a_server[$_POST['id']]['name'];
122
	foreach (config_get_path('system/authserver', []) as $k => $as) {
123
		if ($as['name'] == $serverdeleted) {
124
			config_del_path("system/authserver/{$k}");
125
		}
126
	}
127

    
128
	/* Remove server from temp list used later on this page. */
129
	unset($a_server[$_POST['id']]);
130
	$a_server = array_values($a_server);
131

    
132
	$savemsg = sprintf(gettext("Authentication Server %s deleted."), htmlspecialchars($serverdeleted));
133
	write_config($savemsg);
134
}
135

    
136
if ($act == "edit") {
137
	if (isset($id) && $a_server[$id]) {
138

    
139
		$pconfig['type'] = $a_server[$id]['type'];
140
		if (!$dup) {
141
			$pconfig['name'] = $a_server[$id]['name'];
142
		}
143

    
144
		if ($pconfig['type'] == "ldap") {
145
			$pconfig['ldap_caref'] = $a_server[$id]['ldap_caref'];
146
			$pconfig['ldap_host'] = $a_server[$id]['host'];
147
			$pconfig['ldap_port'] = $a_server[$id]['ldap_port'];
148
			$pconfig['ldap_timeout'] = $a_server[$id]['ldap_timeout'];
149
			$pconfig['ldap_urltype'] = $a_server[$id]['ldap_urltype'];
150
			$pconfig['ldap_protver'] = $a_server[$id]['ldap_protver'];
151
			$pconfig['ldap_scope'] = $a_server[$id]['ldap_scope'];
152
			$pconfig['ldap_basedn'] = $a_server[$id]['ldap_basedn'];
153
			$pconfig['ldap_authcn'] = $a_server[$id]['ldap_authcn'];
154
			$pconfig['ldap_extended_enabled'] = $a_server[$id]['ldap_extended_enabled'];
155
			$pconfig['ldap_extended_query'] = $a_server[$id]['ldap_extended_query'];
156
			$pconfig['ldap_binddn'] = $a_server[$id]['ldap_binddn'];
157
			$pconfig['ldap_bindpw'] = $a_server[$id]['ldap_bindpw'];
158
			$pconfig['ldap_attr_user'] = $a_server[$id]['ldap_attr_user'];
159
			$pconfig['ldap_attr_group'] = $a_server[$id]['ldap_attr_group'];
160
			$pconfig['ldap_attr_member'] = $a_server[$id]['ldap_attr_member'];
161
			$pconfig['ldap_attr_groupobj'] = $a_server[$id]['ldap_attr_groupobj'];
162
			$pconfig['ldap_pam_groupdn'] = $a_server[$id]['ldap_pam_groupdn'];
163
			$pconfig['ldap_utf8'] = isset($a_server[$id]['ldap_utf8']);
164
			$pconfig['ldap_nostrip_at'] = isset($a_server[$id]['ldap_nostrip_at']);
165
			$pconfig['ldap_allow_unauthenticated'] = isset($a_server[$id]['ldap_allow_unauthenticated']);
166
			$pconfig['ldap_rfc2307'] = isset($a_server[$id]['ldap_rfc2307']);
167
			$pconfig['ldap_rfc2307_userdn'] = isset($a_server[$id]['ldap_rfc2307_userdn']);
168

    
169
			if (!$pconfig['ldap_binddn'] || !$pconfig['ldap_bindpw']) {
170
				$pconfig['ldap_anon'] = true;
171
			}
172
		}
173

    
174
		if ($pconfig['type'] == "radius") {
175
			$pconfig['radius_protocol'] = $a_server[$id]['radius_protocol'];
176
			$pconfig['radius_host'] = $a_server[$id]['host'];
177
			$pconfig['radius_nasip_attribute'] = $a_server[$id]['radius_nasip_attribute'];
178
			$pconfig['radius_auth_port'] = $a_server[$id]['radius_auth_port'];
179
			$pconfig['radius_acct_port'] = $a_server[$id]['radius_acct_port'];
180
			$pconfig['radius_secret'] = $a_server[$id]['radius_secret'];
181
			$pconfig['radius_timeout'] = $a_server[$id]['radius_timeout'];
182

    
183
			if ($pconfig['radius_auth_port'] &&
184
				$pconfig['radius_acct_port']) {
185
				$pconfig['radius_srvcs'] = "both";
186
			}
187

    
188
			if ($pconfig['radius_auth_port'] &&
189
				!$pconfig['radius_acct_port']) {
190
				$pconfig['radius_srvcs'] = "auth";
191
				$pconfig['radius_acct_port'] = 1813;
192
			}
193

    
194
			if (!$pconfig['radius_auth_port'] &&
195
				$pconfig['radius_acct_port']) {
196
				$pconfig['radius_srvcs'] = "acct";
197
				$pconfig['radius_auth_port'] = 1812;
198
			}
199

    
200
		}
201
	}
202
}
203

    
204
if ($act == "new") {
205
	$pconfig['ldap_protver'] = 3;
206
	$pconfig['ldap_anon'] = true;
207
	$pconfig['radius_protocol'] = "MSCHAPv2";
208
	$pconfig['radius_srvcs'] = "both";
209
	$pconfig['radius_auth_port'] = "1812";
210
	$pconfig['radius_acct_port'] = "1813";
211
}
212

    
213
if ($dup) {
214
	unset($id);
215
}
216

    
217
if ($_POST['save']) {
218
	unset($input_errors);
219
	$pconfig = $_POST;
220

    
221
	/* input validation */
222

    
223
	if ($pconfig['type'] == "ldap") {
224
		$reqdfields = explode(" ",
225
			"name type ldap_host ldap_port " .
226
			"ldap_urltype ldap_protver ldap_scope " .
227
			"ldap_attr_user ldap_attr_group ldap_attr_member ldapauthcontainers");
228

    
229
		$reqdfieldsn = array(
230
			gettext("Descriptive name"),
231
			gettext("Type"),
232
			gettext("Hostname or IP"),
233
			gettext("Port value"),
234
			gettext("Transport"),
235
			gettext("Protocol version"),
236
			gettext("Search level"),
237
			gettext("User naming Attribute"),
238
			gettext("Group naming Attribute"),
239
			gettext("Group member attribute"),
240
			gettext("Authentication container"));
241

    
242
		if (!$pconfig['ldap_anon']) {
243
			$reqdfields[] = "ldap_binddn";
244
			$reqdfields[] = "ldap_bindpw";
245
			$reqdfieldsn[] = gettext("Bind user DN");
246
			$reqdfieldsn[] = gettext("Bind Password");
247
		}
248
	}
249

    
250
	if ($pconfig['type'] == "radius") {
251
		$reqdfields = explode(" ", "name type radius_protocol radius_host radius_srvcs");
252
		$reqdfieldsn = array(
253
			gettext("Descriptive name"),
254
			gettext("Type"),
255
			gettext("Radius Protocol"),
256
			gettext("Hostname or IP"),
257
			gettext("Services"));
258

    
259
		if ($pconfig['radius_srvcs'] == "both" ||
260
			$pconfig['radius_srvcs'] == "auth") {
261
			$reqdfields[] = "radius_auth_port";
262
			$reqdfieldsn[] = gettext("Authentication port");
263
		}
264

    
265
		if ($pconfig['radius_srvcs'] == "both" ||
266
			$pconfig['radius_srvcs'] == "acct") {
267
			$reqdfields[] = "radius_acct_port";
268
			$reqdfieldsn[] = gettext("Accounting port");
269
		}
270

    
271
		if (!isset($id)) {
272
			$reqdfields[] = "radius_secret";
273
			$reqdfieldsn[] = gettext("Shared Secret");
274
		}
275
	}
276

    
277
	do_input_validation($_POST, $reqdfields, $reqdfieldsn, $input_errors);
278

    
279
	if (preg_match("/[^a-zA-Z0-9\.\-_]/", $_POST['host'])) {
280
		$input_errors[] = gettext("The host name contains invalid characters.");
281
	}
282

    
283
	if (auth_get_authserver($pconfig['name']) && !isset($id)) {
284
		$input_errors[] = gettext("An authentication server with the same name already exists.");
285
	}
286

    
287
	if (isset($id) && config_get_path("system/authserver/{$id}") &&
288
	   (config_get_path("system/authserver/{$id}/name") != $pconfig['name'])) {
289
		$input_errors[] = gettext("The name of an authentication server cannot be changed.");
290
	}
291

    
292
	if (($pconfig['type'] == "ldap") || ($pconfig['type'] == "radius")) {
293
		$to_field = "{$pconfig['type']}_timeout";
294
		if (isset($_POST[$to_field]) && !empty($_POST[$to_field]) && (!is_numeric($_POST[$to_field]) || (is_numeric($_POST[$to_field]) && ($_POST[$to_field] <= 0)))) {
295
			$input_errors[] = sprintf(gettext("%s Timeout value must be numeric and positive."), strtoupper($pconfig['type']));
296
		}
297
	}
298

    
299
	if (($pconfig['type'] == 'ldap') && config_path_enabled('system/webgui', 'shellauth') &&
300
	    (config_get_path('system/webgui/authmode') == $pconfig['name']) && empty($pconfig['ldap_pam_groupdn'])) {
301
		$input_errors[] = gettext("Shell Authentication Group DN must be specified if " . 
302
			"Shell Authentication is enabled for appliance.");
303
	}
304

    
305
	if (!$input_errors) {
306
		$server = array();
307
		$server['refid'] = uniqid();
308
		if (isset($id) && $a_server[$id]) {
309
			$server = $a_server[$id];
310
		}
311

    
312
		$server['type'] = $pconfig['type'];
313
		$server['name'] = $pconfig['name'];
314

    
315
		if ($server['type'] == "ldap") {
316

    
317
			if (!empty($pconfig['ldap_caref'])) {
318
				$server['ldap_caref'] = $pconfig['ldap_caref'];
319
			}
320
			$server['host'] = $pconfig['ldap_host'];
321
			$server['ldap_port'] = $pconfig['ldap_port'];
322
			$server['ldap_urltype'] = $pconfig['ldap_urltype'];
323
			$server['ldap_protver'] = $pconfig['ldap_protver'];
324
			$server['ldap_scope'] = $pconfig['ldap_scope'];
325
			$server['ldap_basedn'] = $pconfig['ldap_basedn'];
326
			$server['ldap_authcn'] = $pconfig['ldapauthcontainers'];
327
			$server['ldap_extended_enabled'] = $pconfig['ldap_extended_enabled'];
328
			$server['ldap_extended_query'] = $pconfig['ldap_extended_query'];
329
			$server['ldap_attr_user'] = $pconfig['ldap_attr_user'];
330
			$server['ldap_attr_group'] = $pconfig['ldap_attr_group'];
331
			$server['ldap_attr_member'] = $pconfig['ldap_attr_member'];
332

    
333
			$server['ldap_attr_groupobj'] = empty($pconfig['ldap_attr_groupobj']) ? "posixGroup" : $pconfig['ldap_attr_groupobj'];
334
			$server['ldap_pam_groupdn'] = $pconfig['ldap_pam_groupdn'];
335

    
336
			if ($pconfig['ldap_utf8'] == "yes") {
337
				$server['ldap_utf8'] = true;
338
			} else {
339
				unset($server['ldap_utf8']);
340
			}
341
			if ($pconfig['ldap_nostrip_at'] == "yes") {
342
				$server['ldap_nostrip_at'] = true;
343
			} else {
344
				unset($server['ldap_nostrip_at']);
345
			}
346
			if ($pconfig['ldap_allow_unauthenticated'] == "yes") {
347
				$server['ldap_allow_unauthenticated'] = true;
348
			} else {
349
				unset($server['ldap_allow_unauthenticated']);
350
			}
351
			if ($pconfig['ldap_rfc2307'] == "yes") {
352
				$server['ldap_rfc2307'] = true;
353
			} else {
354
				unset($server['ldap_rfc2307']);
355
			}
356
			if ($pconfig['ldap_rfc2307_userdn'] == "yes") {
357
				$server['ldap_rfc2307_userdn'] = true;
358
			} else {
359
				unset($server['ldap_rfc2307_userdn']);
360
			}
361

    
362

    
363
			if (!$pconfig['ldap_anon']) {
364
				$server['ldap_binddn'] = $pconfig['ldap_binddn'];
365
				$server['ldap_bindpw'] = $pconfig['ldap_bindpw'];
366
			} else {
367
				unset($server['ldap_binddn']);
368
				unset($server['ldap_bindpw']);
369
			}
370

    
371
			if ($pconfig['ldap_timeout']) {
372
				$server['ldap_timeout'] = $pconfig['ldap_timeout'];
373
			} else {
374
				$server['ldap_timeout'] = 25;
375
			}
376
		}
377

    
378
		if ($server['type'] == "radius") {
379

    
380
			$server['radius_protocol'] = $pconfig['radius_protocol'];
381
			$server['host'] = $pconfig['radius_host'];
382
			$server['radius_nasip_attribute'] = $pconfig['radius_nasip_attribute'];
383

    
384
			if ($pconfig['radius_secret']) {
385
				$server['radius_secret'] = $pconfig['radius_secret'];
386
			}
387

    
388
			if ($pconfig['radius_timeout']) {
389
				$server['radius_timeout'] = $pconfig['radius_timeout'];
390
			} else {
391
				$server['radius_timeout'] = 5;
392
			}
393

    
394
			if ($pconfig['radius_srvcs'] == "both") {
395
				$server['radius_auth_port'] = $pconfig['radius_auth_port'];
396
				$server['radius_acct_port'] = $pconfig['radius_acct_port'];
397
			}
398

    
399
			if ($pconfig['radius_srvcs'] == "auth") {
400
				$server['radius_auth_port'] = $pconfig['radius_auth_port'];
401
				unset($server['radius_acct_port']);
402
			}
403

    
404
			if ($pconfig['radius_srvcs'] == "acct") {
405
				$server['radius_acct_port'] = $pconfig['radius_acct_port'];
406
				unset($server['radius_auth_port']);
407
			}
408
		}
409

    
410
		if (isset($id) && config_get_path("system/authserver/{$id}")) {
411
			config_set_path("system/authserver/{$id}", $server);
412
		} else {
413
			config_set_path('system/authserver/', $server);
414
		}
415

    
416
		if (config_path_enabled('system/webgui', 'shellauth') &&
417
		    (config_get_path('system/webgui/authmode') == $pconfig['name'])) {
418
			set_pam_auth();
419
		}
420

    
421
		write_config("Authentication Servers settings saved");
422

    
423
		pfSenseHeader("system_authservers.php");
424
	}
425
}
426

    
427
function build_radiusnas_list() {
428
	$list = array();
429

    
430
	$iflist = get_configured_interface_with_descr();
431
	foreach ($iflist as $ifdesc => $ifdescr) {
432
		$ipaddr = get_interface_ip($ifdesc);
433
		if (is_ipaddr($ipaddr)) {
434
			$list[$ifdesc] = $ifdescr . ' - ' . $ipaddr;
435
		}
436
	}
437

    
438
	foreach (config_get_path('virtualip/vip', []) as $sn) {
439
		if ($sn['mode'] == "proxyarp" && $sn['type'] == "network") {
440
			$start = ip2long32(gen_subnet($sn['subnet'], $sn['subnet_bits']));
441
			$end = ip2long32(gen_subnet_max($sn['subnet'], $sn['subnet_bits']));
442
			$len = $end - $start;
443

    
444
			for ($i = 0; $i <= $len; $i++) {
445
				$snip = long2ip32($start+$i);
446
				$list[$snip] = $sn['descr'] . ' - ' . $snip;
447
			}
448
		} else {
449
			$list[$sn['subnet']] = $sn['descr'] . ' - ' . $sn['subnet'];
450
		}
451
	}
452

    
453

    
454
	return($list);
455
}
456

    
457
// On error, restore the form contents so the user doesn't have to re-enter too much
458
if ($_POST && $input_errors) {
459
	$pconfig = $_POST;
460
	$pconfig['ldap_authcn'] = $_POST['ldapauthcontainers'];
461
	$pconfig['ldap_template'] = $_POST['ldap_tmpltype'];
462
}
463

    
464
$pgtitle = array(gettext("System"), gettext("User Manager"), gettext("Authentication Servers"));
465
$pglinks = array("", "system_usermanager.php", "system_authservers.php");
466

    
467
if ($act == "new" || $act == "edit" || $input_errors) {
468
	$pgtitle[] = gettext('Edit');
469
	$pglinks[] = "@self";
470
}
471
$shortcut_section = "authentication";
472
include("head.inc");
473

    
474
if ($input_errors) {
475
	print_input_errors($input_errors);
476
}
477

    
478
if ($savemsg) {
479
	print_info_box($savemsg, 'success');
480
}
481

    
482
$tab_array = array();
483
$tab_array[] = array(gettext("Users"), false, "system_usermanager.php");
484
$tab_array[] = array(gettext("Groups"), false, "system_groupmanager.php");
485
$tab_array[] = array(gettext("Settings"), false, "system_usermanager_settings.php");
486
$tab_array[] = array(gettext("Change Password"), false, "system_usermanager_passwordmg.php");
487
$tab_array[] = array(gettext("Authentication Servers"), true, "system_authservers.php");
488
display_top_tabs($tab_array);
489

    
490
if (!($act == "new" || $act == "edit" || $input_errors)) {
491
?>
492
<div class="panel panel-default">
493
	<div class="panel-heading"><h2 class="panel-title"><?=gettext('Authentication Servers')?></h2></div>
494
	<div class="panel-body">
495
		<div class="table-responsive">
496
			<table class="table table-striped table-hover table-condensed sortable-theme-bootstrap table-rowdblclickedit" data-sortable>
497
				<thead>
498
					<tr>
499
						<th><?=gettext("Server Name")?></th>
500
						<th><?=gettext("Type")?></th>
501
						<th><?=gettext("Host Name")?></th>
502
						<th><?=gettext("Actions")?></th>
503
					</tr>
504
				</thead>
505
				<tbody>
506
			<?php foreach ($a_server as $i => $server): ?>
507
					<tr>
508
						<td><?=htmlspecialchars($server['name'])?></td>
509
						<td><?=htmlspecialchars($auth_server_types[$server['type']])?></td>
510
						<td><?=htmlspecialchars($server['host'])?></td>
511
						<td>
512
						<?php if ($i < (count($a_server) - 1)): ?>
513
							<a class="fa-solid fa-pencil" title="<?=gettext("Edit server"); ?>" href="system_authservers.php?act=edit&amp;id=<?=$i?>"></a>
514
							<a class="fa-regular fa-clone" title="<?=gettext("Copy server"); ?>" href="system_authservers.php?act=dup&amp;id=<?=$i?>"></a>
515
							<a class="fa-solid fa-trash-can"  title="<?=gettext("Delete server")?>" href="system_authservers.php?act=del&amp;id=<?=$i?>" usepost></a>
516
						<?php endif?>
517
						</td>
518
					</tr>
519
			<?php endforeach; ?>
520
				</tbody>
521
			</table>
522
		</div>
523
	</div>
524
</div>
525

    
526
<nav class="action-buttons">
527
	<a href="?act=new" class="btn btn-success btn-sm">
528
		<i class="fa-solid fa-plus icon-embed-btn"></i>
529
		<?=gettext("Add")?>
530
	</a>
531
</nav>
532
<?php
533
	include("foot.inc");
534
	exit;
535
}
536

    
537
$form = new Form;
538
$form->setAction('system_authservers.php?act=edit');
539

    
540
$form->addGlobal(new Form_Input(
541
	'userid',
542
	null,
543
	'hidden',
544
	$id
545
));
546

    
547
$section = new Form_Section('Server Settings');
548

    
549
$section->addInput($input = new Form_Input(
550
	'name',
551
	'*Descriptive name',
552
	'text',
553
	$pconfig['name']
554
));
555

    
556
$section->addInput($input = new Form_Select(
557
	'type',
558
	'*Type',
559
	$pconfig['type'],
560
	$auth_server_types
561
))->toggles();
562

    
563
$form->add($section);
564

    
565
// ==== LDAP settings =========================================================
566
$section = new Form_Section('LDAP Server Settings');
567
$section->addClass('toggle-ldap collapse');
568

    
569
if (!isset($pconfig['type']) || $pconfig['type'] == 'ldap')
570
	$section->addClass('in');
571

    
572
$section->addInput(new Form_Input(
573
	'ldap_host',
574
	'*Hostname or IP address',
575
	'text',
576
	$pconfig['ldap_host']
577
))->setHelp('NOTE: When using SSL/TLS or STARTTLS, this hostname MUST match a Subject '.
578
	'Alternative Name (SAN) or the Common Name (CN) of the LDAP server SSL/TLS Certificate.');
579

    
580
$section->addInput(new Form_Input(
581
	'ldap_port',
582
	'*Port value',
583
	'number',
584
	$pconfig['ldap_port']
585
));
586

    
587
$section->addInput(new Form_Select(
588
	'ldap_urltype',
589
	'*Transport',
590
	$pconfig['ldap_urltype'],
591
	array_combine(array_keys($ldap_urltypes), array_keys($ldap_urltypes))
592
));
593

    
594
$ldapCaRef = array('global' => 'Global Root CA List');
595
foreach (config_get_path('ca', []) as $ca) {
596
	$ldapCaRef[$ca['refid']] = $ca['descr'];
597
}
598

    
599
$section->addInput(new Form_Select(
600
	'ldap_caref',
601
	'Peer Certificate Authority',
602
	$pconfig['ldap_caref'],
603
	$ldapCaRef
604
))->setHelp('This CA is used to validate the LDAP server certificate when '.
605
	'\'SSL/TLS Encrypted\' or \'STARTTLS Encrypted\' Transport is active. '.
606
	'This CA must match the CA used by the LDAP server.');
607

    
608
$section->addInput(new Form_Select(
609
	'ldap_protver',
610
	'*Protocol version',
611
	$pconfig['ldap_protver'],
612
	array_combine($ldap_protvers, $ldap_protvers)
613
));
614

    
615
$section->addInput(new Form_Input(
616
	'ldap_timeout',
617
	'Server Timeout',
618
	'number',
619
	$pconfig['ldap_timeout'],
620
	['placeholder' => 25]
621
))->setHelp('Timeout for LDAP operations (seconds)');
622

    
623
$group = new Form_Group('Search scope');
624

    
625
$SSF = new Form_Select(
626
	'ldap_scope',
627
	'*Level',
628
	$pconfig['ldap_scope'],
629
	$ldap_scopes
630
);
631

    
632
$SSB = new Form_Input(
633
	'ldap_basedn',
634
	'Base DN',
635
	'text',
636
	$pconfig['ldap_basedn']
637
);
638

    
639

    
640
$section->addInput(new Form_StaticText(
641
	'Search scope',
642
	'Level ' . $SSF . '<br />' . 'Base DN' . $SSB
643
));
644

    
645
$group = new Form_Group('*Authentication containers');
646
$group->add(new Form_Input(
647
	'ldapauthcontainers',
648
	'Containers',
649
	'text',
650
	$pconfig['ldap_authcn']
651
))->setHelp('Note: Semi-Colon separated. This will be prepended to the search '.
652
	'base dn above or the full container path can be specified containing a dc= '.
653
	'component.%1$sExample: CN=Users;DC=example,DC=com or OU=Staff;OU=Freelancers', '<br/>');
654

    
655
$group->add(new Form_Button(
656
	'Select',
657
	'Select a container',
658
	null,
659
	'fa-solid fa-search'
660
))->setAttribute('type','button')->addClass('btn-info');
661

    
662
$section->add($group);
663

    
664
$section->addInput(new Form_Checkbox(
665
	'ldap_extended_enabled',
666
	'Extended query',
667
	'Enable extended query',
668
	$pconfig['ldap_extended_enabled']
669
));
670

    
671
$group = new Form_Group('Query');
672
$group->addClass('extended');
673

    
674
$group->add(new Form_Input(
675
	'ldap_extended_query',
676
	'Query',
677
	'text',
678
	$pconfig['ldap_extended_query']
679
))->setHelp('Example (MSAD): memberOf=CN=Groupname,OU=MyGroups,DC=example,DC=com<br>Example (2307): |(&(objectClass=posixGroup)(cn=Groupname)(memberUid=*))(&(objectClass=posixGroup)(cn=anotherGroup)(memberUid=*))');
680

    
681
$section->add($group);
682

    
683
$section->addInput(new Form_Checkbox(
684
	'ldap_anon',
685
	'Bind anonymous',
686
	'Use anonymous binds to resolve distinguished names',
687
	$pconfig['ldap_anon']
688
));
689

    
690
$group = new Form_Group('*Bind credentials');
691
$group->addClass('ldapanon');
692

    
693
$group->add(new Form_Input(
694
	'ldap_binddn',
695
	'User DN:',
696
	'text',
697
	$pconfig['ldap_binddn']
698
));
699

    
700
$group->add(new Form_Input(
701
	'ldap_bindpw',
702
	'Password',
703
	'password',
704
	$pconfig['ldap_bindpw']
705
));
706
$section->add($group);
707

    
708
if (!isset($id)) {
709
	$template_list = array();
710

    
711
	foreach ($ldap_templates as $option => $template) {
712
		$template_list[$option] = $template['desc'];
713
	}
714

    
715
	$section->addInput(new Form_Select(
716
		'ldap_tmpltype',
717
		'Initial Template',
718
		$pconfig['ldap_template'],
719
		$template_list
720
	));
721
}
722

    
723
$section->addInput(new Form_Input(
724
	'ldap_attr_user',
725
	'*User naming attribute',
726
	'text',
727
	$pconfig['ldap_attr_user']
728
));
729

    
730
$section->addInput(new Form_Input(
731
	'ldap_attr_group',
732
	'*Group naming attribute',
733
	'text',
734
	$pconfig['ldap_attr_group']
735
));
736

    
737
$section->addInput(new Form_Input(
738
	'ldap_attr_member',
739
	'*Group member attribute',
740
	'text',
741
	$pconfig['ldap_attr_member']
742
));
743

    
744
$section->addInput(new Form_Checkbox(
745
	'ldap_rfc2307',
746
	'RFC 2307 Groups',
747
	'LDAP Server uses RFC 2307 style group membership',
748
	$pconfig['ldap_rfc2307']
749
))->setHelp('RFC 2307 style group membership has members listed on the group '.
750
	'object rather than using groups listed on user object. Leave unchecked '.
751
	'for Active Directory style group membership (RFC 2307bis).');
752

    
753
$group = new Form_Group('RFC 2307 User DN');
754
$group->addClass('ldap_rfc2307_userdn');
755

    
756
$group->add(new Form_Checkbox(
757
	'ldap_rfc2307_userdn',
758
	'RFC 2307 user DN',
759
	'RFC 2307 Use DN for username search.',
760
	$pconfig['ldap_rfc2307_userdn']
761
))->setHelp('Use DN for username search, i.e. "(member=CN=Username,CN=Users,DC=example,DC=com)".');
762

    
763
$section->add($group);
764

    
765
$section->addInput(new Form_Input(
766
	'ldap_attr_groupobj',
767
	'Group Object Class',
768
	'text',
769
	$pconfig['ldap_attr_groupobj'],
770
	['placeholder' => 'posixGroup']
771
))->setHelp('Object class used for groups in RFC2307 mode. '.
772
	'Typically "posixGroup" or "group".');
773

    
774
$section->addInput(new Form_Input(
775
	'ldap_pam_groupdn',
776
	'Shell Authentication Group DN',
777
	'text',
778
	$pconfig['ldap_pam_groupdn']
779
))->setHelp('If LDAP server is used for shell authentication, user must be a member ' .
780
	    'of this group and have a valid posixAccount attributes to be able to login.%s Example: CN=Remoteshellusers,CN=Users,DC=example,DC=com',
781
	    '<br/>');
782

    
783
$section->addInput(new Form_Checkbox(
784
	'ldap_utf8',
785
	'UTF8 Encode',
786
	'UTF8 encode LDAP parameters before sending them to the server.',
787
	$pconfig['ldap_utf8']
788
))->setHelp('Required to support international characters, but may not be '.
789
	'supported by every LDAP server.');
790

    
791
$section->addInput(new Form_Checkbox(
792
	'ldap_nostrip_at',
793
	'Username Alterations',
794
	'Do not strip away parts of the username after the @ symbol',
795
	$pconfig['ldap_nostrip_at']
796
))->setHelp('e.g. user@host becomes user when unchecked.');
797

    
798
$section->addInput(new Form_Checkbox(
799
	'ldap_allow_unauthenticated',
800
	'Allow unauthenticated bind',
801
	'Allow unauthenticated bind',
802
	$pconfig['ldap_allow_unauthenticated']
803
))->setHelp('Unauthenticated binds are bind with an existing login but with an empty password. '.
804
         'Some LDAP servers (Microsoft AD) allow this type of bind without any possibility to disable it.');
805

    
806
$form->add($section);
807

    
808
// ==== RADIUS section ========================================================
809
$section = new Form_Section('RADIUS Server Settings');
810
$section->addClass('toggle-radius collapse');
811

    
812
$section->addInput(new Form_Select(
813
	'radius_protocol',
814
	'*Protocol',
815
	$pconfig['radius_protocol'],
816
	$radius_protocol
817
));
818

    
819
$section->addInput(new Form_Input(
820
	'radius_host',
821
	'*Hostname or IP address',
822
	'text',
823
	$pconfig['radius_host']
824
));
825

    
826
$section->addInput(new Form_Input(
827
	'radius_secret',
828
	'*Shared Secret',
829
	'password',
830
	$pconfig['radius_secret']
831
));
832

    
833
$section->addInput(new Form_Select(
834
	'radius_srvcs',
835
	'*Services offered',
836
	$pconfig['radius_srvcs'],
837
	$radius_srvcs
838
));
839

    
840
$section->addInput(new Form_Input(
841
	'radius_auth_port',
842
	'Authentication port',
843
	'number',
844
	$pconfig['radius_auth_port']
845
));
846

    
847
$section->addInput(new Form_Input(
848
	'radius_acct_port',
849
	'Accounting port',
850
	'number',
851
	$pconfig['radius_acct_port']
852
));
853

    
854
$section->addInput(new Form_Input(
855
	'radius_timeout',
856
	'Authentication Timeout',
857
	'number',
858
	$pconfig['radius_timeout']
859
))->setHelp('This value controls how long, in seconds, that the RADIUS '.
860
	'server may take to respond to an authentication request. If left blank, the '.
861
	'default value is 5 seconds. NOTE: If using an interactive two-factor '.
862
	'authentication system, increase this timeout to account for how long it will '.
863
	'take the user to receive and enter a token.');
864

    
865
$section->addInput(new Form_Select(
866
	'radius_nasip_attribute',
867
	'RADIUS NAS IP Attribute',
868
	$pconfig['radius_nasip_attribute'],
869
	build_radiusnas_list()
870
))->setHelp('Enter the IP to use for the "NAS-IP-Address" attribute during RADIUS Access-Requests.<br />'.
871
			'Please note that this choice won\'t change the interface used for contacting the RADIUS server.');
872

    
873
if (isset($id) && $a_server[$id])
874
{
875
	$form->addGlobal(new Form_Input(
876
		'id',
877
		null,
878
		'hidden',
879
		$id
880
	));
881
}
882

    
883
$form->add($section);
884

    
885
// Create a largely empty modal to show the available containers. We will populate it via AJAX later
886
$modal = new Modal("LDAP containers", "containers", true);
887

    
888
$form->add($modal);
889

    
890
print $form;
891
?>
892
<script type="text/javascript">
893
//<![CDATA[
894
events.push(function() {
895

    
896
	// Create an AJAX request (to this page) to get the container list and controls
897
	function select_clicked() {
898
		if (document.getElementById("ldap_port").value == '' ||
899
			document.getElementById("ldap_host").value == '' ||
900
			document.getElementById("ldap_scope").value == '' ||
901
			document.getElementById("ldap_basedn").value == '' ||
902
			document.getElementById("ldapauthcontainers").value == '') {
903
			alert("<?=gettext("Please fill the required values.");?>");
904
			return;
905
		}
906

    
907
		if (!document.getElementById("ldap_anon").checked) {
908
			if (document.getElementById("ldap_binddn").value == '' ||
909
				document.getElementById("ldap_bindpw").value == '') {
910
				alert("<?=gettext("Please fill the bind username/password.");?>");
911
				return;
912
			}
913
		}
914

    
915
		var ajaxRequest;
916
		var authserver = $('#authmode').val();
917
		var cert;
918

    
919
<?php if (count(config_get_path('ca', [])) > 0): ?>
920
			cert = $('#ldap_caref').val();
921
<?php else: ?>
922
			cert = '';
923
<?php endif; ?>
924
/*
925
		$('#containers').modal('show');
926
		$('#serverlist').parent('div').prev('label').remove();
927
		$('#serverlist').parent('div').removeClass("col-sm-10");
928
		$('#serverlist').parent('div').addClass("col-sm-12");
929
*/
930
		ajaxRequest = $.ajax(
931
			{
932
				url: "/system_authservers.php",
933
				type: "post",
934
				data: {
935
					ajax: 	"ajax",
936
					port: 	$('#ldap_port').val(),
937
					host: 	$('#ldap_host').val(),
938
					scope: 	$('#ldap_scope').val(),
939
					basedn: $('#ldap_basedn').val(),
940
					binddn: $('#ldap_binddn').val(),
941
					bindpw: $('#ldap_bindpw').val(),
942
					urltype:$('#ldap_urltype').val(),
943
					proto:  $('#ldap_protver').val(),
944
					authcn: $('#ldapauthcontainers').val(),
945
					cert:   cert
946
				}
947
			}
948
		);
949

    
950
		// Deal with the results of the above ajax call
951
		ajaxRequest.done(function (response, textStatus, jqXHR) {
952
			$('#containers').replaceWith(response);
953

    
954
			$('#containers').modal('show');
955

    
956
			// The button handler needs to be here because until the modal has been populated
957
			// the controls we need to attach handlers to do not exist
958
			$('#svcontbtn').prop("type", "button");
959
			$('#svcontbtn').removeAttr("href");
960

    
961
			$('#svcontbtn').click(function () {
962
				var ous = $('[id^=ou]').length;
963
				var i;
964

    
965
				$('#ldapauthcontainers').val("");
966

    
967
				for (i = 0; i < ous; i++) {
968
					if ($('#ou' + i).prop("checked")) {
969
						if ($('#ldapauthcontainers').val() != "") {
970
							$('#ldapauthcontainers').val($('#ldapauthcontainers').val() +";");
971
						}
972

    
973
						$('#ldapauthcontainers').val($('#ldapauthcontainers').val() + $('#ou' + i).val());
974
					}
975
				}
976

    
977
				$('#containers').modal('hide');
978
			});
979
		});
980

    
981
	}
982

    
983
	function set_ldap_port() {
984
		if ($('#ldap_urltype').find(":selected").index() == 2)
985
			$('#ldap_port').val('636');
986
		else
987
			$('#ldap_port').val('389');
988
	}
989

    
990
	function set_required_port_fields() {
991
		if (document.getElementById("radius_srvcs").value == 'auth') {
992
			setRequired('radius_auth_port', true);
993
			setRequired('radius_acct_port', false);
994
		} else if (document.getElementById("radius_srvcs").value == 'acct') {
995
			setRequired('radius_auth_port', false);
996
			setRequired('radius_acct_port', true);
997
		} else { // both
998
			setRequired('radius_auth_port', true);
999
			setRequired('radius_acct_port', true);
1000
		}
1001
	}
1002

    
1003
	// Hides all elements of the specified class. This will usually be a section
1004
	function hideClass(s_class, hide) {
1005
		if (hide)
1006
			$('.' + s_class).hide();
1007
		else
1008
			$('.' + s_class).show();
1009
	}
1010

    
1011
	function ldap_tmplchange() {
1012
		switch ($('#ldap_tmpltype').find(":selected").index()) {
1013
<?php
1014
		$index = 0;
1015
		foreach ($ldap_templates as $tmpldata):
1016
?>
1017
			case <?=$index;?>:
1018
				$('#ldap_attr_user').val("<?=$tmpldata['attr_user'];?>");
1019
				$('#ldap_attr_group').val("<?=$tmpldata['attr_group'];?>");
1020
				$('#ldap_attr_member').val("<?=$tmpldata['attr_member'];?>");
1021
				$("#ldap_allow_unauthenticated").attr("checked", <?=$tmpldata['allow_unauthenticated'];?>);
1022
				break;
1023
<?php
1024
			$index++;
1025
		endforeach;
1026
?>
1027
		}
1028
	}
1029

    
1030
	// ---------- On initial page load ------------------------------------------------------------
1031

    
1032
<?php if ($act != 'edit') : ?>
1033
	ldap_tmplchange();
1034
<?php endif; ?>
1035

    
1036
	hideClass('ldapanon', $('#ldap_anon').prop('checked'));
1037
	hideClass('extended', !$('#ldap_extended_enabled').prop('checked'));
1038
	hideClass('ldap_rfc2307_userdn', !$('#ldap_rfc2307').prop('checked'));
1039
	set_required_port_fields();
1040

    
1041
	if ($('#ldap_port').val() == "")
1042
		set_ldap_port();
1043

    
1044
<?php
1045
	if ($act == 'edit') {
1046
?>
1047
		$('#type option:not(:selected)').each(function(){
1048
			$(this).attr('disabled', 'disabled');
1049
		});
1050

    
1051
<?php
1052
		if (!$input_errors && !$dup) {
1053
?>
1054
		$('#name').prop("readonly", true);
1055
<?php
1056
		}
1057
	}
1058
?>
1059
	// ---------- Click checkbox handlers ---------------------------------------------------------
1060

    
1061
	$('#ldap_tmpltype').on('change', function() {
1062
		ldap_tmplchange();
1063
	});
1064

    
1065
	$('#ldap_anon').click(function () {
1066
		hideClass('ldapanon', this.checked);
1067
	});
1068

    
1069
	$('#ldap_urltype').on('change', function() {
1070
		set_ldap_port();
1071
	});
1072

    
1073
	$('#Select').click(function () {
1074
		select_clicked();
1075
	});
1076

    
1077
	$('#ldap_extended_enabled').click(function () {
1078
		hideClass('extended', !this.checked);
1079
	});
1080

    
1081
	$('#ldap_rfc2307').click(function () {
1082
		hideClass('ldap_rfc2307_userdn', !this.checked);
1083
	});
1084

    
1085
	$('#radius_srvcs').on('change', function() {
1086
		set_required_port_fields();
1087
	});
1088

    
1089
});
1090
//]]>
1091
</script>
1092
<?php
1093
include("foot.inc");
(196-196/233)