Project

General

Profile

Download (28.4 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
##|*MATCH=system_usermanager.php*
33
##|-PRIV
34

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
273
	if (!$input_errors) {
274

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
414
		/* 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. */
415
		local_user_set_groups($userent, $_POST['groups']);
416
		local_user_set($userent);
417
		/* 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. */
418
		local_user_set_groups($userent, $_POST['groups']);
419
		write_config();
420

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

    
425

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

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

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

    
445
	$i = 0;
446

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

    
453
		$privhtml .=		'<tr>';
454
		$privhtml .=			'<td>' . htmlspecialchars($priv['group']) . '</td>';
455
		$privhtml .=			'<td>' . htmlspecialchars($priv['name']) . '</td>';
456
		$privhtml .=			'<td>' . htmlspecialchars($priv['descr']) . '</td>';
457
		$privhtml .=			'<td>';
458
		if (!$group) {
459
			$privhtml .=			'<a class="fa fa-trash no-confirm icon-pointer" title="' . gettext('Delete Privilege') . '" id="delprivid' . $i . '"></a>';
460
		}
461

    
462
		$privhtml .=			'</td>';
463
		$privhtml .=		'</tr>';
464

    
465
		if (!$group) {
466
			$i++;
467
		}
468
	}
469

    
470
	$privhtml .=		'</tbody>';
471
	$privhtml .=	'</table>';
472
	$privhtml .= '</div>';
473

    
474
	$privhtml .= '<nav class="action-buttons">';
475
	$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>';
476
	$privhtml .= '</nav>';
477

    
478
	return($privhtml);
479
}
480

    
481
function build_cert_table() {
482
	global $a_user, $id;
483

    
484
	$certhtml = '<div class="table-responsive">';
485
	$certhtml .=	'<table class="table table-striped table-hover table-condensed">';
486
	$certhtml .=		'<thead>';
487
	$certhtml .=			'<tr>';
488
	$certhtml .=				'<th>' . gettext('Name') . '</th>';
489
	$certhtml .=				'<th>' . gettext('CA') . '</th>';
490
	$certhtml .=				'<th></th>';
491
	$certhtml .=			'</tr>';
492
	$certhtml .=		'</thead>';
493
	$certhtml .=		'<tbody>';
494

    
495
	$a_cert = $a_user[$id]['cert'];
496
	if (is_array($a_cert)) {
497
		$i = 0;
498
		foreach ($a_cert as $certref) {
499
			$cert = lookup_cert($certref);
500
			$ca = lookup_ca($cert['caref']);
501
			$revokedstr =	is_cert_revoked($cert) ? '<b> Revoked</b>':'';
502

    
503
			$certhtml .=	'<tr>';
504
			$certhtml .=		'<td>' . htmlspecialchars($cert['descr']) . $revokedstr . '</td>';
505
			$certhtml .=		'<td>' . htmlspecialchars($ca['descr']) . '</td>';
506
			$certhtml .=		'<td>';
507
			$certhtml .=			'<a id="delcert' . $i .'" class="fa fa-trash no-confirm icon-pointer" title="';
508
			$certhtml .=			gettext('Remove this certificate association? (Certificate will not be deleted)') . '"></a>';
509
			$certhtml .=		'</td>';
510
			$certhtml .=	'</tr>';
511
			$i++;
512
		}
513

    
514
	}
515

    
516
	$certhtml .=		'</tbody>';
517
	$certhtml .=	'</table>';
518
	$certhtml .= '</div>';
519

    
520
	$certhtml .= '<nav class="action-buttons">';
521
	$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>';
522
	$certhtml .= '</nav>';
523

    
524
	return($certhtml);
525
}
526

    
527
$pgtitle = array(gettext("System"), gettext("User Manager"), gettext("Users"));
528

    
529
if ($act == "new" || $act == "edit" || $input_errors) {
530
	$pgtitle[] = gettext('Edit');
531
}
532
include("head.inc");
533

    
534
if ($delete_errors) {
535
	print_input_errors($delete_errors);
536
}
537

    
538
if ($input_errors) {
539
	print_input_errors($input_errors);
540
}
541

    
542
if ($savemsg) {
543
	print_info_box($savemsg, 'success');
544
}
545

    
546
$tab_array = array();
547
$tab_array[] = array(gettext("Users"), true, "system_usermanager.php");
548
$tab_array[] = array(gettext("Groups"), false, "system_groupmanager.php");
549
$tab_array[] = array(gettext("Settings"), false, "system_usermanager_settings.php");
550
$tab_array[] = array(gettext("Authentication Servers"), false, "system_authservers.php");
551
display_top_tabs($tab_array);
552

    
553
if (!($act == "new" || $act == "edit" || $input_errors)) {
554
?>
555
<form method="post">
556
<div class="panel panel-default">
557
	<div class="panel-heading"><h2 class="panel-title"><?=gettext('Users')?></h2></div>
558
	<div class="panel-body">
559
		<div class="table-responsive">
560
			<table class="table table-striped table-hover table-condensed sortable-theme-bootstrap table-rowdblclickedit" data-sortable>
561
				<thead>
562
					<tr>
563
						<th>&nbsp;</th>
564
						<th><?=gettext("Username")?></th>
565
						<th><?=gettext("Full name")?></th>
566
						<th><?=gettext("Disabled")?></th>
567
						<th><?=gettext("Groups")?></th>
568
						<th><?=gettext("Actions")?></th>
569
					</tr>
570
				</thead>
571
				<tbody>
572
<?php
573
foreach ($a_user as $i => $userent):
574
	?>
575
					<tr>
576
						<td>
577
							<input type="checkbox" id="frc<?=$i?>" name="delete_check[]" value="<?=$i?>" <?=((($userent['scope'] == "system") || ($userent['name'] == $_SESSION['Username'])) ? 'disabled' : '')?>/>
578
						</td>
579
						<td>
580
<?php
581
	if ($userent['scope'] != "user") {
582
		$usrimg = 'eye-open';
583
	} else {
584
		$usrimg = 'user';
585
	}
586
?>
587
							<i class="fa fa-<?=$usrimg?>"></i>
588
							<?=htmlspecialchars($userent['name'])?>
589
						</td>
590
						<td><?=htmlspecialchars($userent['descr'])?></td>
591
						<td><?php if (isset($userent['disabled'])) echo "*"?></td>
592
						<td><?=implode(",", local_user_get_groups($userent))?></td>
593
						<td>
594
							<a class="fa fa-pencil" title="<?=gettext("Edit user"); ?>" href="?act=edit&amp;userid=<?=$i?>"></a>
595
<?php if (($userent['scope'] != "system") && ($userent['name'] != $_SESSION['Username'])): ?>
596
							<a class="fa fa-trash"	title="<?=gettext("Delete user")?>" href="?act=deluser&amp;userid=<?=$i?>&amp;username=<?=$userent['name']?>"></a>
597
<?php endif; ?>
598
						</td>
599
					</tr>
600
<?php endforeach; ?>
601
				</tbody>
602
			</table>
603
		</div>
604
	</div>
605
</div>
606
<nav class="action-buttons">
607
	<a href="?act=new" class="btn btn-sm btn-success">
608
		<i class="fa fa-plus icon-embed-btn"></i>
609
		<?=gettext("Add")?>
610
	</a>
611

    
612
	<button type="submit" class="btn btn-sm btn-danger" name="dellall" value="dellall" title="<?=gettext('Delete selected users')?>">
613
		<i class="fa fa-trash icon-embed-btn"></i>
614
		<?=gettext("Delete")?>
615
	</button>
616
</nav>
617
</form>
618
<div class="infoblock">
619
<?php
620
	print_callout('<p>' . gettext("Additional users can be added here. User permissions for accessing " .
621
		"the webConfigurator can be assigned directly or inherited from group memberships. " .
622
		"Some system object properties can be modified but they cannot be deleted.") . '</p>' .
623
		'<p>' . gettext("Accounts added here are also used for other parts of the system " .
624
		"such as OpenVPN, IPsec, and Captive Portal.") . '</p>'
625
	);
626
?></div><?php
627
	include("foot.inc");
628
	exit;
629
}
630

    
631
$form = new Form;
632

    
633
if ($act == "new" || $act == "edit" || $input_errors):
634

    
635
	$form->addGlobal(new Form_Input(
636
		'act',
637
		null,
638
		'hidden',
639
		''
640
	));
641

    
642
	$form->addGlobal(new Form_Input(
643
		'userid',
644
		null,
645
		'hidden',
646
		isset($id) ? $id:''
647
	));
648

    
649
	$form->addGlobal(new Form_Input(
650
		'privid',
651
		null,
652
		'hidden',
653
		''
654
	));
655

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

    
663
	$ro = "";
664
	if ($pconfig['utype'] == "system") {
665
		$ro = "readonly";
666
	}
667

    
668
	$section = new Form_Section('User Properties');
669

    
670
	$section->addInput(new Form_StaticText(
671
		'Defined by',
672
		strtoupper($pconfig['utype'])
673
	));
674

    
675
	$form->addGlobal(new Form_Input(
676
		'utype',
677
		null,
678
		'hidden',
679
		$pconfig['utype']
680
	));
681

    
682
	$section->addInput(new Form_Checkbox(
683
		'disabled',
684
		'Disabled',
685
		'This user cannot login',
686
		$pconfig['disabled']
687
	));
688

    
689
	$section->addInput($input = new Form_Input(
690
		'usernamefld',
691
		'Username',
692
		'text',
693
		$pconfig['usernamefld']
694
	));
695

    
696
	if ($ro) {
697
		$input->setReadonly();
698
	}
699

    
700
	$form->addGlobal(new Form_Input(
701
		'oldusername',
702
		null,
703
		'hidden',
704
		$pconfig['usernamefld']
705
	));
706

    
707
	$group = new Form_Group('Password');
708
	$group->add(new Form_Input(
709
		'passwordfld1',
710
		'Password',
711
		'password'
712
	));
713
	$group->add(new Form_Input(
714
		'passwordfld2',
715
		'Confirm Password',
716
		'password'
717
	));
718

    
719
	$section->add($group);
720

    
721
	$section->addInput($input = new Form_Input(
722
		'descr',
723
		'Full name',
724
		'text',
725
		htmlspecialchars($pconfig['descr'])
726
	))->setHelp('User\'s full name, for administrative information only');
727

    
728
	if ($ro) {
729
		$input->setDisabled();
730
	}
731

    
732
	$section->addInput(new Form_Input(
733
		'expires',
734
		'Expiration date',
735
		'text',
736
		$pconfig['expires']
737
	))->setHelp('Leave blank if the account shouldn\'t expire, otherwise enter '.
738
		'the expiration date as MM/DD/YYYY');
739

    
740
	$section->addInput(new Form_Checkbox(
741
		'customsettings',
742
		'Custom Settings',
743
		'Use individual customized GUI options and dashboard layout for this user.',
744
		$pconfig['customsettings']
745
	));
746

    
747
	gen_user_settings_fields($section, $pconfig);
748

    
749
	// ==== Group membership ==================================================
750
	$group = new Form_Group('Group membership');
751

    
752
	// Make a list of all the groups configured on the system, and a list of
753
	// those which this user is a member of
754
	$systemGroups = array();
755
	$usersGroups = array();
756

    
757
	$usergid = [$pconfig['usernamefld']];
758

    
759
	foreach ($config['system']['group'] as $Ggroup) {
760
		if ($Ggroup['name'] != "all") {
761
			if (($act == 'edit') && $Ggroup['member'] && in_array($pconfig['uid'], $Ggroup['member'])) {
762
				$usersGroups[ $Ggroup['name'] ] = $Ggroup['name'];	// Add it to the user's list
763
			} else {
764
				$systemGroups[ $Ggroup['name'] ] = $Ggroup['name']; // Add it to the 'not a member of' list
765
			}
766
		}
767
	}
768

    
769
	$group->add(new Form_Select(
770
		'sysgroups',
771
		null,
772
		array_combine((array)$pconfig['groups'], (array)$pconfig['groups']),
773
		$systemGroups,
774
		true
775
	))->setHelp('Not member of');
776

    
777
	$group->add(new Form_Select(
778
		'groups',
779
		null,
780
		array_combine((array)$pconfig['groups'], (array)$pconfig['groups']),
781
		$usersGroups,
782
		true
783
	))->setHelp('Member of');
784

    
785
	$section->add($group);
786

    
787
	$group = new Form_Group('');
788

    
789
	$group->add(new Form_Button(
790
		'movetoenabled',
791
		'Move to "Member of" list',
792
		null,
793
		'fa-angle-double-right'
794
	))->setAttribute('type','button')->removeClass('btn-primary')->addClass('btn-info btn-sm');
795

    
796
	$group->add(new Form_Button(
797
		'movetodisabled',
798
		'Move to "Not member of" list',
799
		null,
800
		'fa-angle-double-left'
801
	))->setAttribute('type','button')->removeClass('btn-primary')->addClass('btn-info btn-sm');
802

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

    
806
	// ==== Button for adding user certificate ================================
807
	if ($act == 'new') {
808
		$section->addInput(new Form_Checkbox(
809
			'showcert',
810
			'Certificate',
811
			'Click to create a user certificate',
812
			false
813
		));
814
	}
815

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

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

    
823
		$section = new Form_Section('Effective Privileges');
824

    
825
		$section->addInput(new Form_StaticText(
826
			null,
827
			build_priv_table()
828
		));
829

    
830
		$form->add($section);
831

    
832
		// ==== Certificate table section =====================================
833
		$section = new Form_Section('User Certificates');
834

    
835
		$section->addInput(new Form_StaticText(
836
			null,
837
			build_cert_table()
838
		));
839

    
840
		$form->add($section);
841
	}
842

    
843
	// ==== Add user certificate for a new user
844
	if (is_array($config['ca']) && count($config['ca']) > 0) {
845
		$section = new Form_Section('Create Certificate for User');
846
		$section->addClass('cert-options');
847

    
848
		$nonPrvCas = array();
849
		foreach ($config['ca'] as $ca) {
850
			if (!$ca['prv']) {
851
				continue;
852
			}
853

    
854
			$nonPrvCas[ $ca['refid'] ] = $ca['descr'];
855
		}
856

    
857
		if (!empty($nonPrvCas)) {
858
			$section->addInput(new Form_Input(
859
				'name',
860
				'Descriptive name',
861
				'text',
862
				$pconfig['name']
863
			));
864

    
865
			$section->addInput(new Form_Select(
866
				'caref',
867
				'Certificate authority',
868
				null,
869
				$nonPrvCas
870
			));
871

    
872
			$section->addInput(new Form_Select(
873
				'keylen',
874
				'Key length',
875
				2048,
876
				array(
877
					512 => '512 bits',
878
					1024 => '1024 bits',
879
					2048 => '2048 bits',
880
					3072 => '3072 bits',
881
					4096 => '4096 bits',
882
					7680 => '7680 bits',
883
					8192 => '8192 bits',
884
					15360 => '15360 bits',
885
					16384 => '16384 bits'
886
				)
887
			))->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;.');
888

    
889
			$section->addInput(new Form_Input(
890
				'lifetime',
891
				'Lifetime',
892
				'number',
893
				$pconfig['lifetime']
894
			));
895
		}
896

    
897
		$form->add($section);
898
	}
899

    
900
endif;
901
// ==== Paste a key for the new user
902
$section = new Form_Section('Keys');
903

    
904
$section->addInput(new Form_Checkbox(
905
	'showkey',
906
	'Authorized keys',
907
	'Click to paste an authorized key',
908
	false
909
));
910

    
911
$section->addInput(new Form_Textarea(
912
	'authorizedkeys',
913
	'Authorized SSH Keys',
914
	$pconfig['authorizedkeys']
915
))->setHelp('Enter authorized SSH keys for this user');
916

    
917
$section->addInput(new Form_Input(
918
	'ipsecpsk',
919
	'IPsec Pre-Shared Key',
920
	'text',
921
	$pconfig['ipsecpsk']
922
));
923

    
924
$form->add($section);
925

    
926
print $form;
927

    
928
$csswarning = sprintf(gettext("%sUser-created themes are unsupported, use at your own risk."), "<br />");
929
?>
930
<script type="text/javascript">
931
//<![CDATA[
932
events.push(function() {
933

    
934
	function setcustomoptions() {
935
		var adv = $('#customsettings').prop('checked');
936

    
937
		hideInput('webguicss', !adv);
938
		hideInput('webguifixedmenu', !adv);
939
		hideInput('webguihostnamemenu', !adv);
940
		hideInput('dashboardcolumns', !adv);
941
		hideCheckbox('dashboardavailablewidgetspanel', !adv);
942
		hideCheckbox('systemlogsfilterpanel', !adv);
943
		hideCheckbox('systemlogsmanagelogpanel', !adv);
944
		hideCheckbox('statusmonitoringsettingspanel', !adv);
945
		hideCheckbox('webguileftcolumnhyper', !adv);
946
		hideCheckbox('pagenamefirst', !adv);
947
	}
948

    
949
	// Handle displaying a warning message if a user-created theme is selected.
950
	function setThemeWarning() {
951
		if ($('#webguicss').val().startsWith("pfSense")) {
952
			$('#csstxt').html("").addClass("text-default");
953
		} else {
954
			$('#csstxt').html("<?=$csswarning?>").addClass("text-danger");
955
		}
956
	}
957

    
958
	$('#webguicss').change(function() {
959
		setThemeWarning();
960
	});
961

    
962
	setThemeWarning();
963

    
964
	// On click . .
965
	$('#customsettings').click(function () {
966
		setcustomoptions();
967
	});
968

    
969
	$("#movetodisabled").click(function() {
970
		moveOptions($('[name="groups[]"] option'), $('[name="sysgroups[]"]'));
971
	});
972

    
973
	$("#movetoenabled").click(function() {
974
		moveOptions($('[name="sysgroups[]"] option'), $('[name="groups[]"]'));
975
	});
976

    
977
	$("#showcert").click(function() {
978
		hideClass('cert-options', !this.checked);
979
	});
980

    
981
	$("#showkey").click(function() {
982
		hideInput('authorizedkeys', false);
983
		hideCheckbox('showkey', true);
984
	});
985

    
986
	$('[id^=delcert]').click(function(event) {
987
		if (confirm(event.target.title)) {
988
			$('#certid').val(event.target.id.match(/\d+$/)[0]);
989
			$('#userid').val('<?=$id;?>');
990
			$('#act').val('delcert');
991
			$('form').submit();
992
		}
993
	});
994

    
995
	$('[id^=delprivid]').click(function(event) {
996
		if (confirm(event.target.title)) {
997
			$('#privid').val(event.target.id.match(/\d+$/)[0]);
998
			$('#userid').val('<?=$id;?>');
999
			$('#act').val('delprivid');
1000
			$('form').submit();
1001
		}
1002
	});
1003

    
1004
	$('#expires').datepicker();
1005

    
1006
	// ---------- On initial page load ------------------------------------------------------------
1007

    
1008
	hideClass('cert-options', true);
1009
	//hideInput('authorizedkeys', true);
1010
	hideCheckbox('showkey', true);
1011
	setcustomoptions();
1012

    
1013
	// On submit mark all the user's groups as "selected"
1014
	$('form').submit(function() {
1015
		AllServers($('[name="groups[]"] option'), true);
1016
	});
1017
});
1018
//]]>
1019
</script>
1020
<?php
1021
include('foot.inc');
1022
?>
(206-206/225)