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-2024 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 = $_REQUEST['id'];
103

    
104
config_init_path('system/authserver');
105

    
106
$a_server = array_values(auth_get_authserver_list());
107

    
108
config_init_path('ca');
109

    
110
$act = $_REQUEST['act'];
111

    
112
if ($act == 'dup') {
113
	$dup = true;
114
	$act = 'edit';
115
}
116

    
117
if ($_POST['act'] == "del") {
118

    
119
	if (!$a_server[$_POST['id']]) {
120
		pfSenseHeader("system_authservers.php");
121
		exit;
122
	}
123

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

    
132
	/* Remove server from temp list used later on this page. */
133
	unset($a_server[$_POST['id']]);
134
	$a_server = array_values($a_server);
135

    
136
	$savemsg = sprintf(gettext("Authentication Server %s deleted."), htmlspecialchars($serverdeleted));
137
	write_config($savemsg);
138
}
139

    
140
if ($act == "edit") {
141
	if (isset($id) && $a_server[$id]) {
142

    
143
		$pconfig['type'] = $a_server[$id]['type'];
144
		if (!$dup) {
145
			$pconfig['name'] = $a_server[$id]['name'];
146
		}
147

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

    
173
			if (!$pconfig['ldap_binddn'] || !$pconfig['ldap_bindpw']) {
174
				$pconfig['ldap_anon'] = true;
175
			}
176
		}
177

    
178
		if ($pconfig['type'] == "radius") {
179
			$pconfig['radius_protocol'] = $a_server[$id]['radius_protocol'];
180
			$pconfig['radius_host'] = $a_server[$id]['host'];
181
			$pconfig['radius_nasip_attribute'] = $a_server[$id]['radius_nasip_attribute'];
182
			$pconfig['radius_auth_port'] = $a_server[$id]['radius_auth_port'];
183
			$pconfig['radius_acct_port'] = $a_server[$id]['radius_acct_port'];
184
			$pconfig['radius_secret'] = $a_server[$id]['radius_secret'];
185
			$pconfig['radius_timeout'] = $a_server[$id]['radius_timeout'];
186

    
187
			if ($pconfig['radius_auth_port'] &&
188
				$pconfig['radius_acct_port']) {
189
				$pconfig['radius_srvcs'] = "both";
190
			}
191

    
192
			if ($pconfig['radius_auth_port'] &&
193
				!$pconfig['radius_acct_port']) {
194
				$pconfig['radius_srvcs'] = "auth";
195
				$pconfig['radius_acct_port'] = 1813;
196
			}
197

    
198
			if (!$pconfig['radius_auth_port'] &&
199
				$pconfig['radius_acct_port']) {
200
				$pconfig['radius_srvcs'] = "acct";
201
				$pconfig['radius_auth_port'] = 1812;
202
			}
203

    
204
		}
205
	}
206
}
207

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

    
217
if ($dup) {
218
	unset($id);
219
}
220

    
221
if ($_POST['save']) {
222
	unset($input_errors);
223
	$pconfig = $_POST;
224

    
225
	/* input validation */
226

    
227
	if ($pconfig['type'] == "ldap") {
228
		$reqdfields = explode(" ",
229
			"name type ldap_host ldap_port " .
230
			"ldap_urltype ldap_protver ldap_scope " .
231
			"ldap_attr_user ldap_attr_group ldap_attr_member ldapauthcontainers");
232

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

    
246
		if (!$pconfig['ldap_anon']) {
247
			$reqdfields[] = "ldap_binddn";
248
			$reqdfields[] = "ldap_bindpw";
249
			$reqdfieldsn[] = gettext("Bind user DN");
250
			$reqdfieldsn[] = gettext("Bind Password");
251
		}
252
	}
253

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

    
263
		if ($pconfig['radius_srvcs'] == "both" ||
264
			$pconfig['radius_srvcs'] == "auth") {
265
			$reqdfields[] = "radius_auth_port";
266
			$reqdfieldsn[] = gettext("Authentication port");
267
		}
268

    
269
		if ($pconfig['radius_srvcs'] == "both" ||
270
			$pconfig['radius_srvcs'] == "acct") {
271
			$reqdfields[] = "radius_acct_port";
272
			$reqdfieldsn[] = gettext("Accounting port");
273
		}
274

    
275
		if (!isset($id)) {
276
			$reqdfields[] = "radius_secret";
277
			$reqdfieldsn[] = gettext("Shared Secret");
278
		}
279
	}
280

    
281
	do_input_validation($_POST, $reqdfields, $reqdfieldsn, $input_errors);
282

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

    
287
	if (auth_get_authserver($pconfig['name']) && !isset($id)) {
288
		$input_errors[] = gettext("An authentication server with the same name already exists.");
289
	}
290

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

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

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

    
309
	if (!$input_errors) {
310
		$server = array();
311
		$server['refid'] = uniqid();
312
		if (isset($id) && $a_server[$id]) {
313
			$server = $a_server[$id];
314
		}
315

    
316
		$server['type'] = $pconfig['type'];
317
		$server['name'] = $pconfig['name'];
318

    
319
		if ($server['type'] == "ldap") {
320

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

    
337
			$server['ldap_attr_groupobj'] = empty($pconfig['ldap_attr_groupobj']) ? "posixGroup" : $pconfig['ldap_attr_groupobj'];
338
			$server['ldap_pam_groupdn'] = $pconfig['ldap_pam_groupdn'];
339

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

    
366

    
367
			if (!$pconfig['ldap_anon']) {
368
				$server['ldap_binddn'] = $pconfig['ldap_binddn'];
369
				$server['ldap_bindpw'] = $pconfig['ldap_bindpw'];
370
			} else {
371
				unset($server['ldap_binddn']);
372
				unset($server['ldap_bindpw']);
373
			}
374

    
375
			if ($pconfig['ldap_timeout']) {
376
				$server['ldap_timeout'] = $pconfig['ldap_timeout'];
377
			} else {
378
				$server['ldap_timeout'] = 25;
379
			}
380
		}
381

    
382
		if ($server['type'] == "radius") {
383

    
384
			$server['radius_protocol'] = $pconfig['radius_protocol'];
385
			$server['host'] = $pconfig['radius_host'];
386
			$server['radius_nasip_attribute'] = $pconfig['radius_nasip_attribute'];
387

    
388
			if ($pconfig['radius_secret']) {
389
				$server['radius_secret'] = $pconfig['radius_secret'];
390
			}
391

    
392
			if ($pconfig['radius_timeout']) {
393
				$server['radius_timeout'] = $pconfig['radius_timeout'];
394
			} else {
395
				$server['radius_timeout'] = 5;
396
			}
397

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

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

    
408
			if ($pconfig['radius_srvcs'] == "acct") {
409
				$server['radius_acct_port'] = $pconfig['radius_acct_port'];
410
				unset($server['radius_auth_port']);
411
			}
412
		}
413

    
414
		if (isset($id) && config_get_path("system/authserver/{$id}")) {
415
			config_set_path("system/authserver/{$id}", $server);
416
		} else {
417
			config_set_path('system/authserver/', $server);
418
		}
419

    
420
		if (config_path_enabled('system/webgui', 'shellauth') &&
421
		    (config_get_path('system/webgui/authmode') == $pconfig['name'])) {
422
			set_pam_auth();
423
		}
424

    
425
		write_config("Authentication Servers settings saved");
426

    
427
		pfSenseHeader("system_authservers.php");
428
	}
429
}
430

    
431
function build_radiusnas_list() {
432
	$list = array();
433

    
434
	$iflist = get_configured_interface_with_descr();
435
	foreach ($iflist as $ifdesc => $ifdescr) {
436
		$ipaddr = get_interface_ip($ifdesc);
437
		if (is_ipaddr($ipaddr)) {
438
			$list[$ifdesc] = $ifdescr . ' - ' . $ipaddr;
439
		}
440
	}
441

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

    
448
			for ($i = 0; $i <= $len; $i++) {
449
				$snip = long2ip32($start+$i);
450
				$list[$snip] = $sn['descr'] . ' - ' . $snip;
451
			}
452
		} else {
453
			$list[$sn['subnet']] = $sn['descr'] . ' - ' . $sn['subnet'];
454
		}
455
	}
456

    
457

    
458
	return($list);
459
}
460

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

    
468
$pgtitle = array(gettext("System"), gettext("User Manager"), gettext("Authentication Servers"));
469
$pglinks = array("", "system_usermanager.php", "system_authservers.php");
470

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

    
478
if ($input_errors) {
479
	print_input_errors($input_errors);
480
}
481

    
482
if ($savemsg) {
483
	print_info_box($savemsg, 'success');
484
}
485

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

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

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

    
541
$form = new Form;
542
$form->setAction('system_authservers.php?act=edit');
543

    
544
$form->addGlobal(new Form_Input(
545
	'userid',
546
	null,
547
	'hidden',
548
	$id
549
));
550

    
551
$section = new Form_Section('Server Settings');
552

    
553
$section->addInput($input = new Form_Input(
554
	'name',
555
	'*Descriptive name',
556
	'text',
557
	$pconfig['name']
558
));
559

    
560
$section->addInput($input = new Form_Select(
561
	'type',
562
	'*Type',
563
	$pconfig['type'],
564
	$auth_server_types
565
))->toggles();
566

    
567
$form->add($section);
568

    
569
// ==== LDAP settings =========================================================
570
$section = new Form_Section('LDAP Server Settings');
571
$section->addClass('toggle-ldap collapse');
572

    
573
if (!isset($pconfig['type']) || $pconfig['type'] == 'ldap')
574
	$section->addClass('in');
575

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

    
584
$section->addInput(new Form_Input(
585
	'ldap_port',
586
	'*Port value',
587
	'number',
588
	$pconfig['ldap_port']
589
));
590

    
591
$section->addInput(new Form_Select(
592
	'ldap_urltype',
593
	'*Transport',
594
	$pconfig['ldap_urltype'],
595
	array_combine(array_keys($ldap_urltypes), array_keys($ldap_urltypes))
596
));
597

    
598
$ldapCaRef = array('global' => 'Global Root CA List');
599
foreach (config_get_path('ca', []) as $ca) {
600
	$ldapCaRef[$ca['refid']] = $ca['descr'];
601
}
602

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

    
612
$section->addInput(new Form_Select(
613
	'ldap_protver',
614
	'*Protocol version',
615
	$pconfig['ldap_protver'],
616
	array_combine($ldap_protvers, $ldap_protvers)
617
));
618

    
619
$section->addInput(new Form_Input(
620
	'ldap_timeout',
621
	'Server Timeout',
622
	'number',
623
	$pconfig['ldap_timeout'],
624
	['placeholder' => 25]
625
))->setHelp('Timeout for LDAP operations (seconds)');
626

    
627
$group = new Form_Group('Search scope');
628

    
629
$SSF = new Form_Select(
630
	'ldap_scope',
631
	'*Level',
632
	$pconfig['ldap_scope'],
633
	$ldap_scopes
634
);
635

    
636
$SSB = new Form_Input(
637
	'ldap_basedn',
638
	'Base DN',
639
	'text',
640
	$pconfig['ldap_basedn']
641
);
642

    
643

    
644
$section->addInput(new Form_StaticText(
645
	'Search scope',
646
	'Level ' . $SSF . '<br />' . 'Base DN' . $SSB
647
));
648

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

    
659
$group->add(new Form_Button(
660
	'Select',
661
	'Select a container',
662
	null,
663
	'fa-solid fa-search'
664
))->setAttribute('type','button')->addClass('btn-info');
665

    
666
$section->add($group);
667

    
668
$section->addInput(new Form_Checkbox(
669
	'ldap_extended_enabled',
670
	'Extended query',
671
	'Enable extended query',
672
	$pconfig['ldap_extended_enabled']
673
));
674

    
675
$group = new Form_Group('Query');
676
$group->addClass('extended');
677

    
678
$group->add(new Form_Input(
679
	'ldap_extended_query',
680
	'Query',
681
	'text',
682
	$pconfig['ldap_extended_query']
683
))->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=*))');
684

    
685
$section->add($group);
686

    
687
$section->addInput(new Form_Checkbox(
688
	'ldap_anon',
689
	'Bind anonymous',
690
	'Use anonymous binds to resolve distinguished names',
691
	$pconfig['ldap_anon']
692
));
693

    
694
$group = new Form_Group('*Bind credentials');
695
$group->addClass('ldapanon');
696

    
697
$group->add(new Form_Input(
698
	'ldap_binddn',
699
	'User DN:',
700
	'text',
701
	$pconfig['ldap_binddn']
702
));
703

    
704
$group->add(new Form_Input(
705
	'ldap_bindpw',
706
	'Password',
707
	'password',
708
	$pconfig['ldap_bindpw']
709
));
710
$section->add($group);
711

    
712
if (!isset($id)) {
713
	$template_list = array();
714

    
715
	foreach ($ldap_templates as $option => $template) {
716
		$template_list[$option] = $template['desc'];
717
	}
718

    
719
	$section->addInput(new Form_Select(
720
		'ldap_tmpltype',
721
		'Initial Template',
722
		$pconfig['ldap_template'],
723
		$template_list
724
	));
725
}
726

    
727
$section->addInput(new Form_Input(
728
	'ldap_attr_user',
729
	'*User naming attribute',
730
	'text',
731
	$pconfig['ldap_attr_user']
732
));
733

    
734
$section->addInput(new Form_Input(
735
	'ldap_attr_group',
736
	'*Group naming attribute',
737
	'text',
738
	$pconfig['ldap_attr_group']
739
));
740

    
741
$section->addInput(new Form_Input(
742
	'ldap_attr_member',
743
	'*Group member attribute',
744
	'text',
745
	$pconfig['ldap_attr_member']
746
));
747

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

    
757
$group = new Form_Group('RFC 2307 User DN');
758
$group->addClass('ldap_rfc2307_userdn');
759

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

    
767
$section->add($group);
768

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

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

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

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

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

    
810
$form->add($section);
811

    
812
// ==== RADIUS section ========================================================
813
$section = new Form_Section('RADIUS Server Settings');
814
$section->addClass('toggle-radius collapse');
815

    
816
$section->addInput(new Form_Select(
817
	'radius_protocol',
818
	'*Protocol',
819
	$pconfig['radius_protocol'],
820
	$radius_protocol
821
));
822

    
823
$section->addInput(new Form_Input(
824
	'radius_host',
825
	'*Hostname or IP address',
826
	'text',
827
	$pconfig['radius_host']
828
));
829

    
830
$section->addInput(new Form_Input(
831
	'radius_secret',
832
	'*Shared Secret',
833
	'password',
834
	$pconfig['radius_secret']
835
));
836

    
837
$section->addInput(new Form_Select(
838
	'radius_srvcs',
839
	'*Services offered',
840
	$pconfig['radius_srvcs'],
841
	$radius_srvcs
842
));
843

    
844
$section->addInput(new Form_Input(
845
	'radius_auth_port',
846
	'Authentication port',
847
	'number',
848
	$pconfig['radius_auth_port']
849
));
850

    
851
$section->addInput(new Form_Input(
852
	'radius_acct_port',
853
	'Accounting port',
854
	'number',
855
	$pconfig['radius_acct_port']
856
));
857

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

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

    
877
if (isset($id) && $a_server[$id])
878
{
879
	$form->addGlobal(new Form_Input(
880
		'id',
881
		null,
882
		'hidden',
883
		$id
884
	));
885
}
886

    
887
$form->add($section);
888

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

    
892
$form->add($modal);
893

    
894
print $form;
895
?>
896
<script type="text/javascript">
897
//<![CDATA[
898
events.push(function() {
899

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

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

    
919
		var ajaxRequest;
920
		var authserver = $('#authmode').val();
921
		var cert;
922

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

    
954
		// Deal with the results of the above ajax call
955
		ajaxRequest.done(function (response, textStatus, jqXHR) {
956
			$('#containers').replaceWith(response);
957

    
958
			$('#containers').modal('show');
959

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

    
965
			$('#svcontbtn').click(function () {
966
				var ous = $('[id^=ou]').length;
967
				var i;
968

    
969
				$('#ldapauthcontainers').val("");
970

    
971
				for (i = 0; i < ous; i++) {
972
					if ($('#ou' + i).prop("checked")) {
973
						if ($('#ldapauthcontainers').val() != "") {
974
							$('#ldapauthcontainers').val($('#ldapauthcontainers').val() +";");
975
						}
976

    
977
						$('#ldapauthcontainers').val($('#ldapauthcontainers').val() + $('#ou' + i).val());
978
					}
979
				}
980

    
981
				$('#containers').modal('hide');
982
			});
983
		});
984

    
985
	}
986

    
987
	function set_ldap_port() {
988
		if ($('#ldap_urltype').find(":selected").index() == 2)
989
			$('#ldap_port').val('636');
990
		else
991
			$('#ldap_port').val('389');
992
	}
993

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

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

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

    
1034
	// ---------- On initial page load ------------------------------------------------------------
1035

    
1036
<?php if ($act != 'edit') : ?>
1037
	ldap_tmplchange();
1038
<?php endif; ?>
1039

    
1040
	hideClass('ldapanon', $('#ldap_anon').prop('checked'));
1041
	hideClass('extended', !$('#ldap_extended_enabled').prop('checked'));
1042
	hideClass('ldap_rfc2307_userdn', !$('#ldap_rfc2307').prop('checked'));
1043
	set_required_port_fields();
1044

    
1045
	if ($('#ldap_port').val() == "")
1046
		set_ldap_port();
1047

    
1048
<?php
1049
	if ($act == 'edit') {
1050
?>
1051
		$('#type option:not(:selected)').each(function(){
1052
			$(this).attr('disabled', 'disabled');
1053
		});
1054

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

    
1065
	$('#ldap_tmpltype').on('change', function() {
1066
		ldap_tmplchange();
1067
	});
1068

    
1069
	$('#ldap_anon').click(function () {
1070
		hideClass('ldapanon', this.checked);
1071
	});
1072

    
1073
	$('#ldap_urltype').on('change', function() {
1074
		set_ldap_port();
1075
	});
1076

    
1077
	$('#Select').click(function () {
1078
		select_clicked();
1079
	});
1080

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

    
1085
	$('#ldap_rfc2307').click(function () {
1086
		hideClass('ldap_rfc2307_userdn', !this.checked);
1087
	});
1088

    
1089
	$('#radius_srvcs').on('change', function() {
1090
		set_required_port_fields();
1091
	});
1092

    
1093
});
1094
//]]>
1095
</script>
1096
<?php
1097
include("foot.inc");
(195-195/232)