Project

General

Profile

Download (29.1 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php
2
/*
3
 * system_usermanager.php
4
 *
5
 * part of pfSense (https://www.pfsense.org)
6
 * Copyright (c) 2004-2016 Rubicon Communications, LLC (Netgate)
7
 * Copyright (c) 2008 Shrew Soft Inc.
8
 * Copyright (c) 2005 Paul Taylor <paultaylor@winn-dixie.com>
9
 * All rights reserved.
10
 *
11
 * originally based on m0n0wall (http://m0n0.ch/wall)
12
 * Copyright (c) 2003-2004 Manuel Kasper <mk@neon1.net>.
13
 * All rights reserved.
14
 *
15
 * Licensed under the Apache License, Version 2.0 (the "License");
16
 * you may not use this file except in compliance with the License.
17
 * You may obtain a copy of the License at
18
 *
19
 * http://www.apache.org/licenses/LICENSE-2.0
20
 *
21
 * Unless required by applicable law or agreed to in writing, software
22
 * distributed under the License is distributed on an "AS IS" BASIS,
23
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
24
 * See the License for the specific language governing permissions and
25
 * limitations under the License.
26
 */
27

    
28
##|+PRIV
29
##|*IDENT=page-system-usermanager
30
##|*NAME=System: User Manager
31
##|*DESCR=Allow access to the 'System: User Manager' page.
32
##|*WARN=standard-warning-root
33
##|*MATCH=system_usermanager.php*
34
##|-PRIV
35

    
36
require_once("certs.inc");
37
require_once("guiconfig.inc");
38

    
39
// start admin user code
40
if (isset($_POST['userid']) && is_numericint($_POST['userid'])) {
41
	$id = $_POST['userid'];
42
}
43

    
44
if (isset($_GET['userid']) && is_numericint($_GET['userid'])) {
45
	$id = $_GET['userid'];
46
}
47

    
48
if (!isset($config['system']['user']) || !is_array($config['system']['user'])) {
49
	$config['system']['user'] = array();
50
}
51

    
52
$a_user = &$config['system']['user'];
53
$act = $_GET['act'];
54

    
55
if (isset($_SERVER['HTTP_REFERER'])) {
56
	$referer = $_SERVER['HTTP_REFERER'];
57
} else {
58
	$referer = '/system_usermanager.php';
59
}
60

    
61
if (isset($id) && $a_user[$id]) {
62
	$pconfig['usernamefld'] = $a_user[$id]['name'];
63
	$pconfig['descr'] = $a_user[$id]['descr'];
64
	$pconfig['expires'] = $a_user[$id]['expires'];
65
	$pconfig['customsettings'] = isset($a_user[$id]['customsettings']);
66
	$pconfig['webguicss'] = $a_user[$id]['webguicss'];
67
	$pconfig['webguifixedmenu'] = $a_user[$id]['webguifixedmenu'];
68
	$pconfig['webguihostnamemenu'] = $a_user[$id]['webguihostnamemenu'];
69
	$pconfig['dashboardcolumns'] = $a_user[$id]['dashboardcolumns'];
70
	$pconfig['dashboardavailablewidgetspanel'] = isset($a_user[$id]['dashboardavailablewidgetspanel']);
71
	$pconfig['systemlogsfilterpanel'] = isset($a_user[$id]['systemlogsfilterpanel']);
72
	$pconfig['systemlogsmanagelogpanel'] = isset($a_user[$id]['systemlogsmanagelogpanel']);
73
	$pconfig['statusmonitoringsettingspanel'] = isset($a_user[$id]['statusmonitoringsettingspanel']);
74
	$pconfig['webguileftcolumnhyper'] = isset($a_user[$id]['webguileftcolumnhyper']);
75
	$pconfig['pagenamefirst'] = isset($a_user[$id]['pagenamefirst']);
76
	$pconfig['groups'] = local_user_get_groups($a_user[$id]);
77
	$pconfig['utype'] = $a_user[$id]['scope'];
78
	$pconfig['uid'] = $a_user[$id]['uid'];
79
	$pconfig['authorizedkeys'] = base64_decode($a_user[$id]['authorizedkeys']);
80
	$pconfig['priv'] = $a_user[$id]['priv'];
81
	$pconfig['ipsecpsk'] = $a_user[$id]['ipsecpsk'];
82
	$pconfig['disabled'] = isset($a_user[$id]['disabled']);
83
}
84

    
85
if ($_GET['act'] == "deluser") {
86

    
87
	if (!isset($_GET['username']) || !isset($a_user[$id]) || ($_GET['username'] != $a_user[$id]['name'])) {
88
		pfSenseHeader("system_usermanager.php");
89
		exit;
90
	}
91

    
92
	if ($_GET['username'] == $_SESSION['Username']) {
93
		$delete_errors[] = sprintf(gettext("Cannot delete user %s because you are currently logged in as that user."), $_GET['username']);
94
	} else {
95
		local_user_del($a_user[$id]);
96
		$userdeleted = $a_user[$id]['name'];
97
		unset($a_user[$id]);
98
		write_config();
99
		$savemsg = sprintf(gettext("User %s successfully deleted."), $userdeleted);
100
	}
101
} else if ($act == "new") {
102
	/*
103
	 * set this value cause the text field is read only
104
	 * and the user should not be able to mess with this
105
	 * setting.
106
	 */
107
	$pconfig['utype'] = "user";
108
	$pconfig['lifetime'] = 3650;
109
}
110

    
111
if (isset($_POST['dellall'])) {
112

    
113
	$del_users = $_POST['delete_check'];
114
	$deleted_users = "";
115
	$deleted_count = 0;
116
	$comma = "";
117

    
118
	if (!empty($del_users)) {
119
		foreach ($del_users as $userid) {
120
			if (isset($a_user[$userid]) && $a_user[$userid]['scope'] != "system") {
121
				if ($a_user[$userid]['name'] == $_SESSION['Username']) {
122
					$delete_errors[] = sprintf(gettext("Cannot delete user %s because you are currently logged in as that user."), $a_user[$userid]['name']);
123
				} else {
124
					$deleted_users = $deleted_users . $comma . $a_user[$userid]['name'];
125
					$comma = ", ";
126
					$deleted_count++;
127
					local_user_del($a_user[$userid]);
128
					unset($a_user[$userid]);
129
				}
130
			} else {
131
				$delete_errors[] = sprintf(gettext("Cannot delete user %s because it is a system user."), $a_user[$userid]['name']);
132
			}
133
		}
134

    
135
		if ($deleted_count > 0) {
136
			if ($deleted_count == 1) {
137
				$savemsg = sprintf(gettext("User %s successfully deleted."), $deleted_users);
138
			} else {
139
				$savemsg = sprintf(gettext("Users %s successfully deleted."), $deleted_users);
140
			}
141
			write_config($savemsg);
142
		}
143
	}
144
}
145

    
146
if ($_POST['act'] == "delcert") {
147

    
148
	if (!$a_user[$id]) {
149
		pfSenseHeader("system_usermanager.php");
150
		exit;
151
	}
152

    
153
	$certdeleted = lookup_cert($a_user[$id]['cert'][$_POST['certid']]);
154
	$certdeleted = $certdeleted['descr'];
155
	unset($a_user[$id]['cert'][$_POST['certid']]);
156
	write_config();
157
	$_POST['act'] = "edit";
158
	$savemsg = sprintf(gettext("Certificate %s association removed."), $certdeleted);
159
}
160

    
161
if ($_POST['act'] == "delprivid") {
162
	$privdeleted = $priv_list[$a_user[$id]['priv'][$_POST['privid']]]['name'];
163
	unset($a_user[$id]['priv'][$_POST['privid']]);
164
	local_user_set($a_user[$id]);
165
	write_config();
166
	$_POST['act'] = "edit";
167
	$savemsg = sprintf(gettext("Privilege %s removed."), $privdeleted);
168
}
169

    
170
if ($_POST['save']) {
171
	unset($input_errors);
172
	$pconfig = $_POST;
173

    
174
	/* input validation */
175
	if (isset($id) && ($a_user[$id])) {
176
		$reqdfields = explode(" ", "usernamefld");
177
		$reqdfieldsn = array(gettext("Username"));
178
	} else {
179
		if (empty($_POST['name'])) {
180
			$reqdfields = explode(" ", "usernamefld passwordfld1");
181
			$reqdfieldsn = array(
182
				gettext("Username"),
183
				gettext("Password"));
184
		} else {
185
			$reqdfields = explode(" ", "usernamefld passwordfld1 name caref keylen lifetime");
186
			$reqdfieldsn = array(
187
				gettext("Username"),
188
				gettext("Password"),
189
				gettext("Descriptive name"),
190
				gettext("Certificate authority"),
191
				gettext("Key length"),
192
				gettext("Lifetime"));
193
		}
194
	}
195

    
196
	do_input_validation($_POST, $reqdfields, $reqdfieldsn, $input_errors);
197

    
198
	if (preg_match("/[^a-zA-Z0-9\.\-_]/", $_POST['usernamefld'])) {
199
		$input_errors[] = gettext("The username contains invalid characters.");
200
	}
201

    
202
	if (strlen($_POST['usernamefld']) > 16) {
203
		$input_errors[] = gettext("The username is longer than 16 characters.");
204
	}
205

    
206
	if (($_POST['passwordfld1']) && ($_POST['passwordfld1'] != $_POST['passwordfld2'])) {
207
		$input_errors[] = gettext("The passwords do not match.");
208
	}
209

    
210
	if (isset($_POST['ipsecpsk']) && !preg_match('/^[[:ascii:]]*$/', $_POST['ipsecpsk'])) {
211
		$input_errors[] = gettext("IPsec Pre-Shared Key contains invalid characters.");
212
	}
213

    
214
	/* Check the POSTed groups to ensure they are valid and exist */
215
	if (is_array($_POST['groups'])) {
216
		foreach ($_POST['groups'] as $newgroup) {
217
			if (empty(getGroupEntry($newgroup))) {
218
				$input_errors[] = gettext("One or more invalid groups was submitted.");
219
			}
220
		}
221
	}
222

    
223
	if (isset($id) && $a_user[$id]) {
224
		$oldusername = $a_user[$id]['name'];
225
	} else {
226
		$oldusername = "";
227
	}
228
	/* make sure this user name is unique */
229
	if (!$input_errors) {
230
		foreach ($a_user as $userent) {
231
			if ($userent['name'] == $_POST['usernamefld'] && $oldusername != $_POST['usernamefld']) {
232
				$input_errors[] = gettext("Another entry with the same username already exists.");
233
				break;
234
			}
235
		}
236
	}
237
	/* also make sure it is not reserved */
238
	if (!$input_errors) {
239
		$system_users = explode("\n", file_get_contents("/etc/passwd"));
240
		foreach ($system_users as $s_user) {
241
			$ent = explode(":", $s_user);
242
			if ($ent[0] == $_POST['usernamefld'] && $oldusername != $_POST['usernamefld']) {
243
				$input_errors[] = gettext("That username is reserved by the system.");
244
				break;
245
			}
246
		}
247
	}
248

    
249
	/*
250
	 * Check for a valid expiration date if one is set at all (valid means,
251
	 * DateTime puts out a time stamp so any DateTime compatible time
252
	 * format may be used. to keep it simple for the enduser, we only
253
	 * claim to accept MM/DD/YYYY as inputs. Advanced users may use inputs
254
	 * like "+1 day", which will be converted to MM/DD/YYYY based on "now".
255
	 * Otherwise such an entry would lead to an invalid expiration data.
256
	 */
257
	if ($_POST['expires']) {
258
		try {
259
			$expdate = new DateTime($_POST['expires']);
260
			//convert from any DateTime compatible date to MM/DD/YYYY
261
			$_POST['expires'] = $expdate->format("m/d/Y");
262
		} catch (Exception $ex) {
263
			$input_errors[] = gettext("Invalid expiration date format; use MM/DD/YYYY instead.");
264
		}
265
	}
266

    
267
	if (!empty($_POST['name'])) {
268
		$ca = lookup_ca($_POST['caref']);
269
		if (!$ca) {
270
			$input_errors[] = gettext("Invalid internal Certificate Authority") . "\n";
271
		}
272
	}
273

    
274
	if (!$input_errors) {
275

    
276
		$userent = array();
277
		if (isset($id) && $a_user[$id]) {
278
			$userent = $a_user[$id];
279
		}
280

    
281
		isset($_POST['utype']) ? $userent['scope'] = $_POST['utype'] : $userent['scope'] = "system";
282

    
283
		/* the user name was modified */
284
		if (!empty($_POST['oldusername']) && ($_POST['usernamefld'] <> $_POST['oldusername'])) {
285
			$_SERVER['REMOTE_USER'] = $_POST['usernamefld'];
286
			local_user_del($userent);
287
		}
288

    
289
		/* the user password was modified */
290
		if ($_POST['passwordfld1']) {
291
			local_user_set_password($userent, $_POST['passwordfld1']);
292
		}
293

    
294
		/* only change description if sent */
295
		if (isset($_POST['descr'])) {
296
			$userent['descr'] = $_POST['descr'];
297
		}
298

    
299
		$userent['name'] = $_POST['usernamefld'];
300
		$userent['expires'] = $_POST['expires'];
301
		$userent['dashboardcolumns'] = $_POST['dashboardcolumns'];
302
		$userent['authorizedkeys'] = base64_encode($_POST['authorizedkeys']);
303
		$userent['ipsecpsk'] = $_POST['ipsecpsk'];
304

    
305
		if ($_POST['disabled']) {
306
			$userent['disabled'] = true;
307
		} else {
308
			unset($userent['disabled']);
309
		}
310

    
311
		if ($_POST['customsettings']) {
312
			$userent['customsettings'] = true;
313
		} else {
314
			unset($userent['customsettings']);
315
		}
316

    
317
		if ($_POST['webguicss']) {
318
			$userent['webguicss'] = $_POST['webguicss'];
319
		} else {
320
			unset($userent['webguicss']);
321
		}
322

    
323
		if ($_POST['webguifixedmenu']) {
324
			$userent['webguifixedmenu'] = $_POST['webguifixedmenu'];
325
		} else {
326
			unset($userent['webguifixedmenu']);
327
		}
328

    
329
		if ($_POST['webguihostnamemenu']) {
330
			$userent['webguihostnamemenu'] = $_POST['webguihostnamemenu'];
331
		} else {
332
			unset($userent['webguihostnamemenu']);
333
		}
334

    
335
		if ($_POST['dashboardavailablewidgetspanel']) {
336
			$userent['dashboardavailablewidgetspanel'] = true;
337
		} else {
338
			unset($userent['dashboardavailablewidgetspanel']);
339
		}
340

    
341
		if ($_POST['systemlogsfilterpanel']) {
342
			$userent['systemlogsfilterpanel'] = true;
343
		} else {
344
			unset($userent['systemlogsfilterpanel']);
345
		}
346

    
347
		if ($_POST['systemlogsmanagelogpanel']) {
348
			$userent['systemlogsmanagelogpanel'] = true;
349
		} else {
350
			unset($userent['systemlogsmanagelogpanel']);
351
		}
352

    
353
		if ($_POST['statusmonitoringsettingspanel']) {
354
			$userent['statusmonitoringsettingspanel'] = true;
355
		} else {
356
			unset($userent['statusmonitoringsettingspanel']);
357
		}
358

    
359
		if ($_POST['webguileftcolumnhyper']) {
360
			$userent['webguileftcolumnhyper'] = true;
361
		} else {
362
			unset($userent['webguileftcolumnhyper']);
363
		}
364

    
365
		if ($_POST['pagenamefirst']) {
366
			$userent['pagenamefirst'] = true;
367
		} else {
368
			unset($userent['pagenamefirst']);
369
		}
370

    
371
		if (isset($id) && $a_user[$id]) {
372
			$a_user[$id] = $userent;
373
		} else {
374
			if (!empty($_POST['name'])) {
375
				$cert = array();
376
				$cert['refid'] = uniqid();
377
				$userent['cert'] = array();
378

    
379
				$cert['descr'] = $_POST['name'];
380

    
381
				$subject = cert_get_subject_array($ca['crt']);
382

    
383
				$dn = array(
384
					'countryName' => $subject[0]['v'],
385
					'stateOrProvinceName' => $subject[1]['v'],
386
					'localityName' => $subject[2]['v'],
387
					'organizationName' => $subject[3]['v'],
388
					'emailAddress' => $subject[4]['v'],
389
					'commonName' => $userent['name']);
390

    
391
				cert_create($cert, $_POST['caref'], $_POST['keylen'],
392
					(int)$_POST['lifetime'], $dn);
393

    
394
				if (!is_array($config['cert'])) {
395
					$config['cert'] = array();
396
				}
397
				$config['cert'][] = $cert;
398
				$userent['cert'][] = $cert['refid'];
399
			}
400
			$userent['uid'] = $config['system']['nextuid']++;
401
			/* Add the user to All Users group. */
402
			foreach ($config['system']['group'] as $gidx => $group) {
403
				if ($group['name'] == "all") {
404
					if (!is_array($config['system']['group'][$gidx]['member'])) {
405
						$config['system']['group'][$gidx]['member'] = array();
406
					}
407
					$config['system']['group'][$gidx]['member'][] = $userent['uid'];
408
					break;
409
				}
410
			}
411

    
412
			$a_user[] = $userent;
413
		}
414

    
415
		/* Add user to groups so PHP can see the memberships properly or else the user's shell account does not get proper permissions (if applicable) See #5152. */
416
		local_user_set_groups($userent, $_POST['groups']);
417
		local_user_set($userent);
418
		/* Add user to groups again to ensure they are set everywhere, otherwise the user may not appear to be a member of the group. See commit:5372d26d9d25d751d16865ed9d46869d3b0ec5e1. */
419
		local_user_set_groups($userent, $_POST['groups']);
420
		write_config();
421

    
422
		if (is_dir("/etc/inc/privhooks")) {
423
			run_plugins("/etc/inc/privhooks");
424
		}
425

    
426

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

    
431
function build_priv_table() {
432
	global $a_user, $id;
433

    
434
	$privhtml = '<div class="table-responsive">';
435
	$privhtml .=	'<table class="table table-striped table-hover table-condensed">';
436
	$privhtml .=		'<thead>';
437
	$privhtml .=			'<tr>';
438
	$privhtml .=				'<th>' . gettext('Inherited from') . '</th>';
439
	$privhtml .=				'<th>' . gettext('Name') . '</th>';
440
	$privhtml .=				'<th>' . gettext('Description') . '</th>';
441
	$privhtml .=				'<th>' . gettext('Action') . '</th>';
442
	$privhtml .=			'</tr>';
443
	$privhtml .=		'</thead>';
444
	$privhtml .=		'<tbody>';
445

    
446
	$i = 0;
447
	$user_has_root_priv = false;
448

    
449
	foreach (get_user_privdesc($a_user[$id]) as $priv) {
450
		$group = false;
451
		if ($priv['group']) {
452
			$group = $priv['group'];
453
		}
454

    
455
		$privhtml .=		'<tr>';
456
		$privhtml .=			'<td>' . htmlspecialchars($priv['group']) . '</td>';
457
		$privhtml .=			'<td>' . htmlspecialchars($priv['name']) . '</td>';
458
		$privhtml .=			'<td>' . htmlspecialchars($priv['descr']);
459
		if (isset($priv['warn']) && ($priv['warn'] == 'standard-warning-root')) {
460
			$privhtml .=			' ' . gettext('(admin privilege)');
461
			$user_has_root_priv = true;
462
		}
463
		$privhtml .=			'</td>';
464
		$privhtml .=			'<td>';
465
		if (!$group) {
466
			$privhtml .=			'<a class="fa fa-trash no-confirm icon-pointer" title="' . gettext('Delete Privilege') . '" id="delprivid' . $i . '"></a>';
467
		}
468

    
469
		$privhtml .=			'</td>';
470
		$privhtml .=		'</tr>';
471

    
472
		if (!$group) {
473
			$i++;
474
		}
475
	}
476

    
477
	if ($user_has_root_priv) {
478
		$privhtml .=		'<tr>';
479
		$privhtml .=			'<td colspan="3">';
480
		$privhtml .=				'<b>' . gettext('Security notice: This user effectively has administrator-level access') . '</b>';
481
		$privhtml .=			'</td>';
482
		$privhtml .=			'<td>';
483
		$privhtml .=			'</td>';
484
		$privhtml .=		'</tr>';
485
		
486
	}
487

    
488
	$privhtml .=		'</tbody>';
489
	$privhtml .=	'</table>';
490
	$privhtml .= '</div>';
491

    
492
	$privhtml .= '<nav class="action-buttons">';
493
	$privhtml .=	'<a href="system_usermanager_addprivs.php?userid=' . $id . '" class="btn btn-success"><i class="fa fa-plus icon-embed-btn"></i>' . gettext("Add") . '</a>';
494
	$privhtml .= '</nav>';
495

    
496
	return($privhtml);
497
}
498

    
499
function build_cert_table() {
500
	global $a_user, $id;
501

    
502
	$certhtml = '<div class="table-responsive">';
503
	$certhtml .=	'<table class="table table-striped table-hover table-condensed">';
504
	$certhtml .=		'<thead>';
505
	$certhtml .=			'<tr>';
506
	$certhtml .=				'<th>' . gettext('Name') . '</th>';
507
	$certhtml .=				'<th>' . gettext('CA') . '</th>';
508
	$certhtml .=				'<th></th>';
509
	$certhtml .=			'</tr>';
510
	$certhtml .=		'</thead>';
511
	$certhtml .=		'<tbody>';
512

    
513
	$a_cert = $a_user[$id]['cert'];
514
	if (is_array($a_cert)) {
515
		$i = 0;
516
		foreach ($a_cert as $certref) {
517
			$cert = lookup_cert($certref);
518
			$ca = lookup_ca($cert['caref']);
519
			$revokedstr =	is_cert_revoked($cert) ? '<b> Revoked</b>':'';
520

    
521
			$certhtml .=	'<tr>';
522
			$certhtml .=		'<td>' . htmlspecialchars($cert['descr']) . $revokedstr . '</td>';
523
			$certhtml .=		'<td>' . htmlspecialchars($ca['descr']) . '</td>';
524
			$certhtml .=		'<td>';
525
			$certhtml .=			'<a id="delcert' . $i .'" class="fa fa-trash no-confirm icon-pointer" title="';
526
			$certhtml .=			gettext('Remove this certificate association? (Certificate will not be deleted)') . '"></a>';
527
			$certhtml .=		'</td>';
528
			$certhtml .=	'</tr>';
529
			$i++;
530
		}
531

    
532
	}
533

    
534
	$certhtml .=		'</tbody>';
535
	$certhtml .=	'</table>';
536
	$certhtml .= '</div>';
537

    
538
	$certhtml .= '<nav class="action-buttons">';
539
	$certhtml .=	'<a href="system_certmanager.php?act=new&amp;userid=' . $id . '" class="btn btn-success"><i class="fa fa-plus icon-embed-btn"></i>' . gettext("Add") . '</a>';
540
	$certhtml .= '</nav>';
541

    
542
	return($certhtml);
543
}
544

    
545
$pgtitle = array(gettext("System"), gettext("User Manager"), gettext("Users"));
546
$pglinks = array("", "system_usermanager.php", "system_usermanager.php");
547

    
548
if ($act == "new" || $act == "edit" || $input_errors) {
549
	$pgtitle[] = gettext('Edit');
550
	$pglinks[] = "@self";
551
}
552
include("head.inc");
553

    
554
if ($delete_errors) {
555
	print_input_errors($delete_errors);
556
}
557

    
558
if ($input_errors) {
559
	print_input_errors($input_errors);
560
}
561

    
562
if ($savemsg) {
563
	print_info_box($savemsg, 'success');
564
}
565

    
566
$tab_array = array();
567
$tab_array[] = array(gettext("Users"), true, "system_usermanager.php");
568
$tab_array[] = array(gettext("Groups"), false, "system_groupmanager.php");
569
$tab_array[] = array(gettext("Settings"), false, "system_usermanager_settings.php");
570
$tab_array[] = array(gettext("Authentication Servers"), false, "system_authservers.php");
571
display_top_tabs($tab_array);
572

    
573
if (!($act == "new" || $act == "edit" || $input_errors)) {
574
?>
575
<form method="post">
576
<div class="panel panel-default">
577
	<div class="panel-heading"><h2 class="panel-title"><?=gettext('Users')?></h2></div>
578
	<div class="panel-body">
579
		<div class="table-responsive">
580
			<table class="table table-striped table-hover table-condensed sortable-theme-bootstrap table-rowdblclickedit" data-sortable>
581
				<thead>
582
					<tr>
583
						<th>&nbsp;</th>
584
						<th><?=gettext("Username")?></th>
585
						<th><?=gettext("Full name")?></th>
586
						<th><?=gettext("Disabled")?></th>
587
						<th><?=gettext("Groups")?></th>
588
						<th><?=gettext("Actions")?></th>
589
					</tr>
590
				</thead>
591
				<tbody>
592
<?php
593
foreach ($a_user as $i => $userent):
594
	?>
595
					<tr>
596
						<td>
597
							<input type="checkbox" id="frc<?=$i?>" name="delete_check[]" value="<?=$i?>" <?=((($userent['scope'] == "system") || ($userent['name'] == $_SESSION['Username'])) ? 'disabled' : '')?>/>
598
						</td>
599
						<td>
600
<?php
601
	if ($userent['scope'] != "user") {
602
		$usrimg = 'eye-open';
603
	} else {
604
		$usrimg = 'user';
605
	}
606
?>
607
							<i class="fa fa-<?=$usrimg?>"></i>
608
							<?=htmlspecialchars($userent['name'])?>
609
						</td>
610
						<td><?=htmlspecialchars($userent['descr'])?></td>
611
						<td><?php if (isset($userent['disabled'])) echo "*"?></td>
612
						<td><?=implode(",", local_user_get_groups($userent))?></td>
613
						<td>
614
							<a class="fa fa-pencil" title="<?=gettext("Edit user"); ?>" href="?act=edit&amp;userid=<?=$i?>"></a>
615
<?php if (($userent['scope'] != "system") && ($userent['name'] != $_SESSION['Username'])): ?>
616
							<a class="fa fa-trash"	title="<?=gettext("Delete user")?>" href="?act=deluser&amp;userid=<?=$i?>&amp;username=<?=$userent['name']?>"></a>
617
<?php endif; ?>
618
						</td>
619
					</tr>
620
<?php endforeach; ?>
621
				</tbody>
622
			</table>
623
		</div>
624
	</div>
625
</div>
626
<nav class="action-buttons">
627
	<a href="?act=new" class="btn btn-sm btn-success">
628
		<i class="fa fa-plus icon-embed-btn"></i>
629
		<?=gettext("Add")?>
630
	</a>
631

    
632
	<button type="submit" class="btn btn-sm btn-danger" name="dellall" value="dellall" title="<?=gettext('Delete selected users')?>">
633
		<i class="fa fa-trash icon-embed-btn"></i>
634
		<?=gettext("Delete")?>
635
	</button>
636
</nav>
637
</form>
638
<div class="infoblock">
639
<?php
640
	print_callout('<p>' . gettext("Additional users can be added here. User permissions for accessing " .
641
		"the webConfigurator can be assigned directly or inherited from group memberships. " .
642
		"Some system object properties can be modified but they cannot be deleted.") . '</p>' .
643
		'<p>' . gettext("Accounts added here are also used for other parts of the system " .
644
		"such as OpenVPN, IPsec, and Captive Portal.") . '</p>'
645
	);
646
?></div><?php
647
	include("foot.inc");
648
	exit;
649
}
650

    
651
$form = new Form;
652

    
653
if ($act == "new" || $act == "edit" || $input_errors):
654

    
655
	$form->addGlobal(new Form_Input(
656
		'act',
657
		null,
658
		'hidden',
659
		''
660
	));
661

    
662
	$form->addGlobal(new Form_Input(
663
		'userid',
664
		null,
665
		'hidden',
666
		isset($id) ? $id:''
667
	));
668

    
669
	$form->addGlobal(new Form_Input(
670
		'privid',
671
		null,
672
		'hidden',
673
		''
674
	));
675

    
676
	$form->addGlobal(new Form_Input(
677
		'certid',
678
		null,
679
		'hidden',
680
		''
681
	));
682

    
683
	$ro = "";
684
	if ($pconfig['utype'] == "system") {
685
		$ro = "readonly";
686
	}
687

    
688
	$section = new Form_Section('User Properties');
689

    
690
	$section->addInput(new Form_StaticText(
691
		'Defined by',
692
		strtoupper($pconfig['utype'])
693
	));
694

    
695
	$form->addGlobal(new Form_Input(
696
		'utype',
697
		null,
698
		'hidden',
699
		$pconfig['utype']
700
	));
701

    
702
	$section->addInput(new Form_Checkbox(
703
		'disabled',
704
		'Disabled',
705
		'This user cannot login',
706
		$pconfig['disabled']
707
	));
708

    
709
	$section->addInput($input = new Form_Input(
710
		'usernamefld',
711
		'Username',
712
		'text',
713
		$pconfig['usernamefld']
714
	));
715

    
716
	if ($ro) {
717
		$input->setReadonly();
718
	}
719

    
720
	$form->addGlobal(new Form_Input(
721
		'oldusername',
722
		null,
723
		'hidden',
724
		$pconfig['usernamefld']
725
	));
726

    
727
	$group = new Form_Group('Password');
728
	$group->add(new Form_Input(
729
		'passwordfld1',
730
		'Password',
731
		'password'
732
	));
733
	$group->add(new Form_Input(
734
		'passwordfld2',
735
		'Confirm Password',
736
		'password'
737
	));
738

    
739
	$section->add($group);
740

    
741
	$section->addInput($input = new Form_Input(
742
		'descr',
743
		'Full name',
744
		'text',
745
		htmlspecialchars($pconfig['descr'])
746
	))->setHelp('User\'s full name, for administrative information only');
747

    
748
	if ($ro) {
749
		$input->setDisabled();
750
	}
751

    
752
	$section->addInput(new Form_Input(
753
		'expires',
754
		'Expiration date',
755
		'text',
756
		$pconfig['expires']
757
	))->setHelp('Leave blank if the account shouldn\'t expire, otherwise enter '.
758
		'the expiration date as MM/DD/YYYY');
759

    
760
	$section->addInput(new Form_Checkbox(
761
		'customsettings',
762
		'Custom Settings',
763
		'Use individual customized GUI options and dashboard layout for this user.',
764
		$pconfig['customsettings']
765
	));
766

    
767
	gen_user_settings_fields($section, $pconfig);
768

    
769
	// ==== Group membership ==================================================
770
	$group = new Form_Group('Group membership');
771

    
772
	// Make a list of all the groups configured on the system, and a list of
773
	// those which this user is a member of
774
	$systemGroups = array();
775
	$usersGroups = array();
776

    
777
	$usergid = [$pconfig['usernamefld']];
778

    
779
	foreach ($config['system']['group'] as $Ggroup) {
780
		if ($Ggroup['name'] != "all") {
781
			if (($act == 'edit') && $Ggroup['member'] && in_array($pconfig['uid'], $Ggroup['member'])) {
782
				$usersGroups[ $Ggroup['name'] ] = $Ggroup['name'];	// Add it to the user's list
783
			} else {
784
				$systemGroups[ $Ggroup['name'] ] = $Ggroup['name']; // Add it to the 'not a member of' list
785
			}
786
		}
787
	}
788

    
789
	$group->add(new Form_Select(
790
		'sysgroups',
791
		null,
792
		array_combine((array)$pconfig['groups'], (array)$pconfig['groups']),
793
		$systemGroups,
794
		true
795
	))->setHelp('Not member of');
796

    
797
	$group->add(new Form_Select(
798
		'groups',
799
		null,
800
		array_combine((array)$pconfig['groups'], (array)$pconfig['groups']),
801
		$usersGroups,
802
		true
803
	))->setHelp('Member of');
804

    
805
	$section->add($group);
806

    
807
	$group = new Form_Group('');
808

    
809
	$group->add(new Form_Button(
810
		'movetoenabled',
811
		'Move to "Member of" list',
812
		null,
813
		'fa-angle-double-right'
814
	))->setAttribute('type','button')->removeClass('btn-primary')->addClass('btn-info btn-sm');
815

    
816
	$group->add(new Form_Button(
817
		'movetodisabled',
818
		'Move to "Not member of" list',
819
		null,
820
		'fa-angle-double-left'
821
	))->setAttribute('type','button')->removeClass('btn-primary')->addClass('btn-info btn-sm');
822

    
823
	$group->setHelp('Hold down CTRL (PC)/COMMAND (Mac) key to select multiple items.');
824
	$section->add($group);
825

    
826
	// ==== Button for adding user certificate ================================
827
	if ($act == 'new') {
828
		$section->addInput(new Form_Checkbox(
829
			'showcert',
830
			'Certificate',
831
			'Click to create a user certificate',
832
			false
833
		));
834
	}
835

    
836
	$form->add($section);
837

    
838
	// ==== Effective privileges section ======================================
839
	if (isset($pconfig['uid'])) {
840
		// We are going to build an HTML table and add it to an Input_StaticText. It may be ugly, but it
841
		// is the best way to make the display we need.
842

    
843
		$section = new Form_Section('Effective Privileges');
844

    
845
		$section->addInput(new Form_StaticText(
846
			null,
847
			build_priv_table()
848
		));
849

    
850
		$form->add($section);
851

    
852
		// ==== Certificate table section =====================================
853
		$section = new Form_Section('User Certificates');
854

    
855
		$section->addInput(new Form_StaticText(
856
			null,
857
			build_cert_table()
858
		));
859

    
860
		$form->add($section);
861
	}
862

    
863
	// ==== Add user certificate for a new user
864
	if (is_array($config['ca']) && count($config['ca']) > 0) {
865
		$section = new Form_Section('Create Certificate for User');
866
		$section->addClass('cert-options');
867

    
868
		$nonPrvCas = array();
869
		foreach ($config['ca'] as $ca) {
870
			if (!$ca['prv']) {
871
				continue;
872
			}
873

    
874
			$nonPrvCas[ $ca['refid'] ] = $ca['descr'];
875
		}
876

    
877
		if (!empty($nonPrvCas)) {
878
			$section->addInput(new Form_Input(
879
				'name',
880
				'Descriptive name',
881
				'text',
882
				$pconfig['name']
883
			));
884

    
885
			$section->addInput(new Form_Select(
886
				'caref',
887
				'Certificate authority',
888
				null,
889
				$nonPrvCas
890
			));
891

    
892
			$section->addInput(new Form_Select(
893
				'keylen',
894
				'Key length',
895
				2048,
896
				array(
897
					512 => '512 bits',
898
					1024 => '1024 bits',
899
					2048 => '2048 bits',
900
					3072 => '3072 bits',
901
					4096 => '4096 bits',
902
					7680 => '7680 bits',
903
					8192 => '8192 bits',
904
					15360 => '15360 bits',
905
					16384 => '16384 bits'
906
				)
907
			))->setHelp('The larger the key, the more security it offers, but larger keys take considerably more time to generate, and take slightly longer to validate leading to a slight slowdown in setting up new sessions (not always noticeable). As of 2016, 2048 bit is the minimum and most common selection and 4096 is the maximum in common use. For more information see &lt;a href="https://keylength.com"&gt;keylength.com&lt;/a&gt;.');
908

    
909
			$section->addInput(new Form_Input(
910
				'lifetime',
911
				'Lifetime',
912
				'number',
913
				$pconfig['lifetime']
914
			));
915
		}
916

    
917
		$form->add($section);
918
	}
919

    
920
endif;
921
// ==== Paste a key for the new user
922
$section = new Form_Section('Keys');
923

    
924
$section->addInput(new Form_Checkbox(
925
	'showkey',
926
	'Authorized keys',
927
	'Click to paste an authorized key',
928
	false
929
));
930

    
931
$section->addInput(new Form_Textarea(
932
	'authorizedkeys',
933
	'Authorized SSH Keys',
934
	$pconfig['authorizedkeys']
935
))->setHelp('Enter authorized SSH keys for this user');
936

    
937
$section->addInput(new Form_Input(
938
	'ipsecpsk',
939
	'IPsec Pre-Shared Key',
940
	'text',
941
	$pconfig['ipsecpsk']
942
));
943

    
944
$form->add($section);
945

    
946
print $form;
947

    
948
$csswarning = sprintf(gettext("%sUser-created themes are unsupported, use at your own risk."), "<br />");
949
?>
950
<script type="text/javascript">
951
//<![CDATA[
952
events.push(function() {
953

    
954
	function setcustomoptions() {
955
		var adv = $('#customsettings').prop('checked');
956

    
957
		hideInput('webguicss', !adv);
958
		hideInput('webguifixedmenu', !adv);
959
		hideInput('webguihostnamemenu', !adv);
960
		hideInput('dashboardcolumns', !adv);
961
		hideCheckbox('dashboardavailablewidgetspanel', !adv);
962
		hideCheckbox('systemlogsfilterpanel', !adv);
963
		hideCheckbox('systemlogsmanagelogpanel', !adv);
964
		hideCheckbox('statusmonitoringsettingspanel', !adv);
965
		hideCheckbox('webguileftcolumnhyper', !adv);
966
		hideCheckbox('pagenamefirst', !adv);
967
	}
968

    
969
	// Handle displaying a warning message if a user-created theme is selected.
970
	function setThemeWarning() {
971
		if ($('#webguicss').val().startsWith("pfSense")) {
972
			$('#csstxt').html("").addClass("text-default");
973
		} else {
974
			$('#csstxt').html("<?=$csswarning?>").addClass("text-danger");
975
		}
976
	}
977

    
978
	$('#webguicss').change(function() {
979
		setThemeWarning();
980
	});
981

    
982
	setThemeWarning();
983

    
984
	// On click . .
985
	$('#customsettings').click(function () {
986
		setcustomoptions();
987
	});
988

    
989
	$("#movetodisabled").click(function() {
990
		moveOptions($('[name="groups[]"] option'), $('[name="sysgroups[]"]'));
991
	});
992

    
993
	$("#movetoenabled").click(function() {
994
		moveOptions($('[name="sysgroups[]"] option'), $('[name="groups[]"]'));
995
	});
996

    
997
	$("#showcert").click(function() {
998
		hideClass('cert-options', !this.checked);
999
	});
1000

    
1001
	$("#showkey").click(function() {
1002
		hideInput('authorizedkeys', false);
1003
		hideCheckbox('showkey', true);
1004
	});
1005

    
1006
	$('[id^=delcert]').click(function(event) {
1007
		if (confirm(event.target.title)) {
1008
			$('#certid').val(event.target.id.match(/\d+$/)[0]);
1009
			$('#userid').val('<?=$id;?>');
1010
			$('#act').val('delcert');
1011
			$('form').submit();
1012
		}
1013
	});
1014

    
1015
	$('[id^=delprivid]').click(function(event) {
1016
		if (confirm(event.target.title)) {
1017
			$('#privid').val(event.target.id.match(/\d+$/)[0]);
1018
			$('#userid').val('<?=$id;?>');
1019
			$('#act').val('delprivid');
1020
			$('form').submit();
1021
		}
1022
	});
1023

    
1024
	$('#expires').datepicker();
1025

    
1026
	// ---------- On initial page load ------------------------------------------------------------
1027

    
1028
	hideClass('cert-options', true);
1029
	//hideInput('authorizedkeys', true);
1030
	hideCheckbox('showkey', true);
1031
	setcustomoptions();
1032

    
1033
	// On submit mark all the user's groups as "selected"
1034
	$('form').submit(function() {
1035
		AllServers($('[name="groups[]"] option'), true);
1036
	});
1037
});
1038
//]]>
1039
</script>
1040
<?php
1041
include('foot.inc');
1042
?>
(206-206/225)