Project

General

Profile

Download (30.7 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
if (!is_array($config['system']['authserver'])) {
105
	config_set_path('system/authserver', array());
106
}
107

    
108
$a_server = array_values(auth_get_authserver_list());
109

    
110
init_config_arr(array('ca'));
111
$a_ca = &$config['ca'];
112

    
113
$act = $_REQUEST['act'];
114

    
115
if ($act == 'dup') {
116
	$dup = true;
117
	$act = 'edit';
118
}
119

    
120
if ($_POST['act'] == "del") {
121

    
122
	if (!$a_server[$_POST['id']]) {
123
		pfSenseHeader("system_authservers.php");
124
		exit;
125
	}
126

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

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

    
139
	$savemsg = sprintf(gettext("Authentication Server %s deleted."), htmlspecialchars($serverdeleted));
140
	write_config($savemsg);
141
}
142

    
143
if ($act == "edit") {
144
	if (isset($id) && $a_server[$id]) {
145

    
146
		$pconfig['type'] = $a_server[$id]['type'];
147
		if (!$dup) {
148
			$pconfig['name'] = $a_server[$id]['name'];
149
		}
150

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

    
176
			if (!$pconfig['ldap_binddn'] || !$pconfig['ldap_bindpw']) {
177
				$pconfig['ldap_anon'] = true;
178
			}
179
		}
180

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

    
190
			if ($pconfig['radius_auth_port'] &&
191
				$pconfig['radius_acct_port']) {
192
				$pconfig['radius_srvcs'] = "both";
193
			}
194

    
195
			if ($pconfig['radius_auth_port'] &&
196
				!$pconfig['radius_acct_port']) {
197
				$pconfig['radius_srvcs'] = "auth";
198
				$pconfig['radius_acct_port'] = 1813;
199
			}
200

    
201
			if (!$pconfig['radius_auth_port'] &&
202
				$pconfig['radius_acct_port']) {
203
				$pconfig['radius_srvcs'] = "acct";
204
				$pconfig['radius_auth_port'] = 1812;
205
			}
206

    
207
		}
208
	}
209
}
210

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

    
220
if ($dup) {
221
	unset($id);
222
}
223

    
224
if ($_POST['save']) {
225
	unset($input_errors);
226
	$pconfig = $_POST;
227

    
228
	/* input validation */
229

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

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

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

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

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

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

    
278
		if (!isset($id)) {
279
			$reqdfields[] = "radius_secret";
280
			$reqdfieldsn[] = gettext("Shared Secret");
281
		}
282
	}
283

    
284
	do_input_validation($_POST, $reqdfields, $reqdfieldsn, $input_errors);
285

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

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

    
294
	if (isset($id) && $config['system']['authserver'][$id] &&
295
	   ($config['system']['authserver'][$id]['name'] != $pconfig['name'])) {
296
		$input_errors[] = gettext("The name of an authentication server cannot be changed.");
297
	}
298

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

    
306
	if (($pconfig['type'] == 'ldap') && isset($config['system']['webgui']['shellauth']) &&
307
	    ($config['system']['webgui']['authmode'] == $pconfig['name']) && empty($pconfig['ldap_pam_groupdn'])) {
308
		$input_errors[] = gettext("Shell Authentication Group DN must be specified if " . 
309
			"Shell Authentication is enabled for appliance.");
310
	}
311

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

    
319
		$server['type'] = $pconfig['type'];
320
		$server['name'] = $pconfig['name'];
321

    
322
		if ($server['type'] == "ldap") {
323

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

    
340
			$server['ldap_attr_groupobj'] = empty($pconfig['ldap_attr_groupobj']) ? "posixGroup" : $pconfig['ldap_attr_groupobj'];
341
			$server['ldap_pam_groupdn'] = $pconfig['ldap_pam_groupdn'];
342

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

    
369

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

    
378
			if ($pconfig['ldap_timeout']) {
379
				$server['ldap_timeout'] = $pconfig['ldap_timeout'];
380
			} else {
381
				$server['ldap_timeout'] = 25;
382
			}
383
		}
384

    
385
		if ($server['type'] == "radius") {
386

    
387
			$server['radius_protocol'] = $pconfig['radius_protocol'];
388
			$server['host'] = $pconfig['radius_host'];
389
			$server['radius_nasip_attribute'] = $pconfig['radius_nasip_attribute'];
390

    
391
			if ($pconfig['radius_secret']) {
392
				$server['radius_secret'] = $pconfig['radius_secret'];
393
			}
394

    
395
			if ($pconfig['radius_timeout']) {
396
				$server['radius_timeout'] = $pconfig['radius_timeout'];
397
			} else {
398
				$server['radius_timeout'] = 5;
399
			}
400

    
401
			if ($pconfig['radius_srvcs'] == "both") {
402
				$server['radius_auth_port'] = $pconfig['radius_auth_port'];
403
				$server['radius_acct_port'] = $pconfig['radius_acct_port'];
404
			}
405

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

    
411
			if ($pconfig['radius_srvcs'] == "acct") {
412
				$server['radius_acct_port'] = $pconfig['radius_acct_port'];
413
				unset($server['radius_auth_port']);
414
			}
415
		}
416

    
417
		if (isset($id) && $config['system']['authserver'][$id]) {
418
			$config['system']['authserver'][$id] = $server;
419
		} else {
420
			$config['system']['authserver'][] = $server;
421
		}
422

    
423
		if (isset($config['system']['webgui']['shellauth']) &&
424
		    ($config['system']['webgui']['authmode'] == $pconfig['name'])) {
425
			set_pam_auth();
426
		}
427

    
428
		write_config("Authentication Servers settings saved");
429

    
430
		pfSenseHeader("system_authservers.php");
431
	}
432
}
433

    
434
function build_radiusnas_list() {
435
	global $config;
436
	$list = array();
437

    
438
	$iflist = get_configured_interface_with_descr();
439
	foreach ($iflist as $ifdesc => $ifdescr) {
440
		$ipaddr = get_interface_ip($ifdesc);
441
		if (is_ipaddr($ipaddr)) {
442
			$list[$ifdesc] = $ifdescr . ' - ' . $ipaddr;
443
		}
444
	}
445

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

    
452
			for ($i = 0; $i <= $len; $i++) {
453
				$snip = long2ip32($start+$i);
454
				$list[$snip] = $sn['descr'] . ' - ' . $snip;
455
			}
456
		} else {
457
			$list[$sn['subnet']] = $sn['descr'] . ' - ' . $sn['subnet'];
458
		}
459
	}
460

    
461

    
462
	return($list);
463
}
464

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

    
472
$pgtitle = array(gettext("System"), gettext("User Manager"), gettext("Authentication Servers"));
473
$pglinks = array("", "system_usermanager.php", "system_authservers.php");
474

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

    
482
if ($input_errors) {
483
	print_input_errors($input_errors);
484
}
485

    
486
if ($savemsg) {
487
	print_info_box($savemsg, 'success');
488
}
489

    
490
$tab_array = array();
491
if (!isAllowedPage("system_usermanager.php")) {
492
       $tab_array[] = array(gettext("User Password"), false, "system_usermanager_passwordmg.php");
493
} else {
494
       $tab_array[] = array(gettext("Users"), false, "system_usermanager.php");
495
}
496
$tab_array[] = array(gettext("Groups"), false, "system_groupmanager.php");
497
$tab_array[] = array(gettext("Settings"), false, "system_usermanager_settings.php");
498
$tab_array[] = array(gettext("Authentication Servers"), true, "system_authservers.php");
499
display_top_tabs($tab_array);
500

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

    
537
<nav class="action-buttons">
538
	<a href="?act=new" class="btn btn-success btn-sm">
539
		<i class="fa-solid fa-plus icon-embed-btn"></i>
540
		<?=gettext("Add")?>
541
	</a>
542
</nav>
543
<?php
544
	include("foot.inc");
545
	exit;
546
}
547

    
548
$form = new Form;
549
$form->setAction('system_authservers.php?act=edit');
550

    
551
$form->addGlobal(new Form_Input(
552
	'userid',
553
	null,
554
	'hidden',
555
	$id
556
));
557

    
558
$section = new Form_Section('Server Settings');
559

    
560
$section->addInput($input = new Form_Input(
561
	'name',
562
	'*Descriptive name',
563
	'text',
564
	$pconfig['name']
565
));
566

    
567
$section->addInput($input = new Form_Select(
568
	'type',
569
	'*Type',
570
	$pconfig['type'],
571
	$auth_server_types
572
))->toggles();
573

    
574
$form->add($section);
575

    
576
// ==== LDAP settings =========================================================
577
$section = new Form_Section('LDAP Server Settings');
578
$section->addClass('toggle-ldap collapse');
579

    
580
if (!isset($pconfig['type']) || $pconfig['type'] == 'ldap')
581
	$section->addClass('in');
582

    
583
$section->addInput(new Form_Input(
584
	'ldap_host',
585
	'*Hostname or IP address',
586
	'text',
587
	$pconfig['ldap_host']
588
))->setHelp('NOTE: When using SSL/TLS or STARTTLS, this hostname MUST match a Subject '.
589
	'Alternative Name (SAN) or the Common Name (CN) of the LDAP server SSL/TLS Certificate.');
590

    
591
$section->addInput(new Form_Input(
592
	'ldap_port',
593
	'*Port value',
594
	'number',
595
	$pconfig['ldap_port']
596
));
597

    
598
$section->addInput(new Form_Select(
599
	'ldap_urltype',
600
	'*Transport',
601
	$pconfig['ldap_urltype'],
602
	array_combine(array_keys($ldap_urltypes), array_keys($ldap_urltypes))
603
));
604

    
605
$ldapCaRef = array('global' => 'Global Root CA List');
606
foreach ($a_ca as $ca) {
607
	$ldapCaRef[$ca['refid']] = $ca['descr'];
608
}
609

    
610
$section->addInput(new Form_Select(
611
	'ldap_caref',
612
	'Peer Certificate Authority',
613
	$pconfig['ldap_caref'],
614
	$ldapCaRef
615
))->setHelp('This CA is used to validate the LDAP server certificate when '.
616
	'\'SSL/TLS Encrypted\' or \'STARTTLS Encrypted\' Transport is active. '.
617
	'This CA must match the CA used by the LDAP server.');
618

    
619
$section->addInput(new Form_Select(
620
	'ldap_protver',
621
	'*Protocol version',
622
	$pconfig['ldap_protver'],
623
	array_combine($ldap_protvers, $ldap_protvers)
624
));
625

    
626
$section->addInput(new Form_Input(
627
	'ldap_timeout',
628
	'Server Timeout',
629
	'number',
630
	$pconfig['ldap_timeout'],
631
	['placeholder' => 25]
632
))->setHelp('Timeout for LDAP operations (seconds)');
633

    
634
$group = new Form_Group('Search scope');
635

    
636
$SSF = new Form_Select(
637
	'ldap_scope',
638
	'*Level',
639
	$pconfig['ldap_scope'],
640
	$ldap_scopes
641
);
642

    
643
$SSB = new Form_Input(
644
	'ldap_basedn',
645
	'Base DN',
646
	'text',
647
	$pconfig['ldap_basedn']
648
);
649

    
650

    
651
$section->addInput(new Form_StaticText(
652
	'Search scope',
653
	'Level ' . $SSF . '<br />' . 'Base DN' . $SSB
654
));
655

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

    
666
$group->add(new Form_Button(
667
	'Select',
668
	'Select a container',
669
	null,
670
	'fa-solid fa-search'
671
))->setAttribute('type','button')->addClass('btn-info');
672

    
673
$section->add($group);
674

    
675
$section->addInput(new Form_Checkbox(
676
	'ldap_extended_enabled',
677
	'Extended query',
678
	'Enable extended query',
679
	$pconfig['ldap_extended_enabled']
680
));
681

    
682
$group = new Form_Group('Query');
683
$group->addClass('extended');
684

    
685
$group->add(new Form_Input(
686
	'ldap_extended_query',
687
	'Query',
688
	'text',
689
	$pconfig['ldap_extended_query']
690
))->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=*))');
691

    
692
$section->add($group);
693

    
694
$section->addInput(new Form_Checkbox(
695
	'ldap_anon',
696
	'Bind anonymous',
697
	'Use anonymous binds to resolve distinguished names',
698
	$pconfig['ldap_anon']
699
));
700

    
701
$group = new Form_Group('*Bind credentials');
702
$group->addClass('ldapanon');
703

    
704
$group->add(new Form_Input(
705
	'ldap_binddn',
706
	'User DN:',
707
	'text',
708
	$pconfig['ldap_binddn']
709
));
710

    
711
$group->add(new Form_Input(
712
	'ldap_bindpw',
713
	'Password',
714
	'password',
715
	$pconfig['ldap_bindpw']
716
));
717
$section->add($group);
718

    
719
if (!isset($id)) {
720
	$template_list = array();
721

    
722
	foreach ($ldap_templates as $option => $template) {
723
		$template_list[$option] = $template['desc'];
724
	}
725

    
726
	$section->addInput(new Form_Select(
727
		'ldap_tmpltype',
728
		'Initial Template',
729
		$pconfig['ldap_template'],
730
		$template_list
731
	));
732
}
733

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

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

    
748
$section->addInput(new Form_Input(
749
	'ldap_attr_member',
750
	'*Group member attribute',
751
	'text',
752
	$pconfig['ldap_attr_member']
753
));
754

    
755
$section->addInput(new Form_Checkbox(
756
	'ldap_rfc2307',
757
	'RFC 2307 Groups',
758
	'LDAP Server uses RFC 2307 style group membership',
759
	$pconfig['ldap_rfc2307']
760
))->setHelp('RFC 2307 style group membership has members listed on the group '.
761
	'object rather than using groups listed on user object. Leave unchecked '.
762
	'for Active Directory style group membership (RFC 2307bis).');
763

    
764
$group = new Form_Group('RFC 2307 User DN');
765
$group->addClass('ldap_rfc2307_userdn');
766

    
767
$group->add(new Form_Checkbox(
768
	'ldap_rfc2307_userdn',
769
	'RFC 2307 user DN',
770
	'RFC 2307 Use DN for username search.',
771
	$pconfig['ldap_rfc2307_userdn']
772
))->setHelp('Use DN for username search, i.e. "(member=CN=Username,CN=Users,DC=example,DC=com)".');
773

    
774
$section->add($group);
775

    
776
$section->addInput(new Form_Input(
777
	'ldap_attr_groupobj',
778
	'Group Object Class',
779
	'text',
780
	$pconfig['ldap_attr_groupobj'],
781
	['placeholder' => 'posixGroup']
782
))->setHelp('Object class used for groups in RFC2307 mode. '.
783
	'Typically "posixGroup" or "group".');
784

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

    
794
$section->addInput(new Form_Checkbox(
795
	'ldap_utf8',
796
	'UTF8 Encode',
797
	'UTF8 encode LDAP parameters before sending them to the server.',
798
	$pconfig['ldap_utf8']
799
))->setHelp('Required to support international characters, but may not be '.
800
	'supported by every LDAP server.');
801

    
802
$section->addInput(new Form_Checkbox(
803
	'ldap_nostrip_at',
804
	'Username Alterations',
805
	'Do not strip away parts of the username after the @ symbol',
806
	$pconfig['ldap_nostrip_at']
807
))->setHelp('e.g. user@host becomes user when unchecked.');
808

    
809
$section->addInput(new Form_Checkbox(
810
	'ldap_allow_unauthenticated',
811
	'Allow unauthenticated bind',
812
	'Allow unauthenticated bind',
813
	$pconfig['ldap_allow_unauthenticated']
814
))->setHelp('Unauthenticated binds are bind with an existing login but with an empty password. '.
815
         'Some LDAP servers (Microsoft AD) allow this type of bind without any possibility to disable it.');
816

    
817
$form->add($section);
818

    
819
// ==== RADIUS section ========================================================
820
$section = new Form_Section('RADIUS Server Settings');
821
$section->addClass('toggle-radius collapse');
822

    
823
$section->addInput(new Form_Select(
824
	'radius_protocol',
825
	'*Protocol',
826
	$pconfig['radius_protocol'],
827
	$radius_protocol
828
));
829

    
830
$section->addInput(new Form_Input(
831
	'radius_host',
832
	'*Hostname or IP address',
833
	'text',
834
	$pconfig['radius_host']
835
));
836

    
837
$section->addInput(new Form_Input(
838
	'radius_secret',
839
	'*Shared Secret',
840
	'password',
841
	$pconfig['radius_secret']
842
));
843

    
844
$section->addInput(new Form_Select(
845
	'radius_srvcs',
846
	'*Services offered',
847
	$pconfig['radius_srvcs'],
848
	$radius_srvcs
849
));
850

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

    
858
$section->addInput(new Form_Input(
859
	'radius_acct_port',
860
	'Accounting port',
861
	'number',
862
	$pconfig['radius_acct_port']
863
));
864

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

    
876
$section->addInput(new Form_Select(
877
	'radius_nasip_attribute',
878
	'RADIUS NAS IP Attribute',
879
	$pconfig['radius_nasip_attribute'],
880
	build_radiusnas_list()
881
))->setHelp('Enter the IP to use for the "NAS-IP-Address" attribute during RADIUS Access-Requests.<br />'.
882
			'Please note that this choice won\'t change the interface used for contacting the RADIUS server.');
883

    
884
if (isset($id) && $a_server[$id])
885
{
886
	$form->addGlobal(new Form_Input(
887
		'id',
888
		null,
889
		'hidden',
890
		$id
891
	));
892
}
893

    
894
$form->add($section);
895

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

    
899
$form->add($modal);
900

    
901
print $form;
902
?>
903
<script type="text/javascript">
904
//<![CDATA[
905
events.push(function() {
906

    
907
	// Create an AJAX request (to this page) to get the container list and controls
908
	function select_clicked() {
909
		if (document.getElementById("ldap_port").value == '' ||
910
			document.getElementById("ldap_host").value == '' ||
911
			document.getElementById("ldap_scope").value == '' ||
912
			document.getElementById("ldap_basedn").value == '' ||
913
			document.getElementById("ldapauthcontainers").value == '') {
914
			alert("<?=gettext("Please fill the required values.");?>");
915
			return;
916
		}
917

    
918
		if (!document.getElementById("ldap_anon").checked) {
919
			if (document.getElementById("ldap_binddn").value == '' ||
920
				document.getElementById("ldap_bindpw").value == '') {
921
				alert("<?=gettext("Please fill the bind username/password.");?>");
922
				return;
923
			}
924
		}
925

    
926
		var ajaxRequest;
927
		var authserver = $('#authmode').val();
928
		var cert;
929

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

    
961
		// Deal with the results of the above ajax call
962
		ajaxRequest.done(function (response, textStatus, jqXHR) {
963
			$('#containers').replaceWith(response);
964

    
965
			$('#containers').modal('show');
966

    
967
			// The button handler needs to be here because until the modal has been populated
968
			// the controls we need to attach handlers to do not exist
969
			$('#svcontbtn').prop("type", "button");
970
			$('#svcontbtn').removeAttr("href");
971

    
972
			$('#svcontbtn').click(function () {
973
				var ous = $('[id^=ou]').length;
974
				var i;
975

    
976
				$('#ldapauthcontainers').val("");
977

    
978
				for (i = 0; i < ous; i++) {
979
					if ($('#ou' + i).prop("checked")) {
980
						if ($('#ldapauthcontainers').val() != "") {
981
							$('#ldapauthcontainers').val($('#ldapauthcontainers').val() +";");
982
						}
983

    
984
						$('#ldapauthcontainers').val($('#ldapauthcontainers').val() + $('#ou' + i).val());
985
					}
986
				}
987

    
988
				$('#containers').modal('hide');
989
			});
990
		});
991

    
992
	}
993

    
994
	function set_ldap_port() {
995
		if ($('#ldap_urltype').find(":selected").index() == 2)
996
			$('#ldap_port').val('636');
997
		else
998
			$('#ldap_port').val('389');
999
	}
1000

    
1001
	function set_required_port_fields() {
1002
		if (document.getElementById("radius_srvcs").value == 'auth') {
1003
			setRequired('radius_auth_port', true);
1004
			setRequired('radius_acct_port', false);
1005
		} else if (document.getElementById("radius_srvcs").value == 'acct') {
1006
			setRequired('radius_auth_port', false);
1007
			setRequired('radius_acct_port', true);
1008
		} else { // both
1009
			setRequired('radius_auth_port', true);
1010
			setRequired('radius_acct_port', true);
1011
		}
1012
	}
1013

    
1014
	// Hides all elements of the specified class. This will usually be a section
1015
	function hideClass(s_class, hide) {
1016
		if (hide)
1017
			$('.' + s_class).hide();
1018
		else
1019
			$('.' + s_class).show();
1020
	}
1021

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

    
1041
	// ---------- On initial page load ------------------------------------------------------------
1042

    
1043
<?php if ($act != 'edit') : ?>
1044
	ldap_tmplchange();
1045
<?php endif; ?>
1046

    
1047
	hideClass('ldapanon', $('#ldap_anon').prop('checked'));
1048
	hideClass('extended', !$('#ldap_extended_enabled').prop('checked'));
1049
	hideClass('ldap_rfc2307_userdn', !$('#ldap_rfc2307').prop('checked'));
1050
	set_required_port_fields();
1051

    
1052
	if ($('#ldap_port').val() == "")
1053
		set_ldap_port();
1054

    
1055
<?php
1056
	if ($act == 'edit') {
1057
?>
1058
		$('#type option:not(:selected)').each(function(){
1059
			$(this).attr('disabled', 'disabled');
1060
		});
1061

    
1062
<?php
1063
		if (!$input_errors && !$dup) {
1064
?>
1065
		$('#name').prop("readonly", true);
1066
<?php
1067
		}
1068
	}
1069
?>
1070
	// ---------- Click checkbox handlers ---------------------------------------------------------
1071

    
1072
	$('#ldap_tmpltype').on('change', function() {
1073
		ldap_tmplchange();
1074
	});
1075

    
1076
	$('#ldap_anon').click(function () {
1077
		hideClass('ldapanon', this.checked);
1078
	});
1079

    
1080
	$('#ldap_urltype').on('change', function() {
1081
		set_ldap_port();
1082
	});
1083

    
1084
	$('#Select').click(function () {
1085
		select_clicked();
1086
	});
1087

    
1088
	$('#ldap_extended_enabled').click(function () {
1089
		hideClass('extended', !this.checked);
1090
	});
1091

    
1092
	$('#ldap_rfc2307').click(function () {
1093
		hideClass('ldap_rfc2307_userdn', !this.checked);
1094
	});
1095

    
1096
	$('#radius_srvcs').on('change', function() {
1097
		set_required_port_fields();
1098
	});
1099

    
1100
});
1101
//]]>
1102
</script>
1103
<?php
1104
include("foot.inc");
(191-191/228)