Project

General

Profile

Download (30.6 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
 * Redistribution and use in source and binary forms, with or without
16
 * modification, are permitted provided that the following conditions are met:
17
 *
18
 * 1. Redistributions of source code must retain the above copyright notice,
19
 *    this list of conditions and the following disclaimer.
20
 *
21
 * 2. Redistributions in binary form must reproduce the above copyright
22
 *    notice, this list of conditions and the following disclaimer in
23
 *    the documentation and/or other materials provided with the
24
 *    distribution.
25
 *
26
 * 3. All advertising materials mentioning features or use of this software
27
 *    must display the following acknowledgment:
28
 *    "This product includes software developed by the pfSense Project
29
 *    for use in the pfSense® software distribution. (http://www.pfsense.org/).
30
 *
31
 * 4. The names "pfSense" and "pfSense Project" must not be used to
32
 *    endorse or promote products derived from this software without
33
 *    prior written permission. For written permission, please contact
34
 *    coreteam@pfsense.org.
35
 *
36
 * 5. Products derived from this software may not be called "pfSense"
37
 *    nor may "pfSense" appear in their names without prior written
38
 *    permission of the Electric Sheep Fencing, LLC.
39
 *
40
 * 6. Redistributions of any form whatsoever must retain the following
41
 *    acknowledgment:
42
 *
43
 * "This product includes software developed by the pfSense Project
44
 * for use in the pfSense software distribution (http://www.pfsense.org/).
45
 *
46
 * THIS SOFTWARE IS PROVIDED BY THE pfSense PROJECT ``AS IS'' AND ANY
47
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
48
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
49
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE pfSense PROJECT OR
50
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
51
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
52
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
53
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
54
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
55
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
56
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
57
 * OF THE POSSIBILITY OF SUCH DAMAGE.
58
 */
59

    
60
##|+PRIV
61
##|*IDENT=page-system-usermanager
62
##|*NAME=System: User Manager
63
##|*DESCR=Allow access to the 'System: User Manager' page.
64
##|*MATCH=system_usermanager.php*
65
##|-PRIV
66

    
67
require_once("certs.inc");
68
require_once("guiconfig.inc");
69

    
70
// start admin user code
71
if (isset($_POST['userid']) && is_numericint($_POST['userid'])) {
72
	$id = $_POST['userid'];
73
}
74

    
75
if (isset($_GET['userid']) && is_numericint($_GET['userid'])) {
76
	$id = $_GET['userid'];
77
}
78

    
79
if (!isset($config['system']['user']) || !is_array($config['system']['user'])) {
80
	$config['system']['user'] = array();
81
}
82

    
83
$a_user = &$config['system']['user'];
84
$act = $_GET['act'];
85

    
86
if (isset($_SERVER['HTTP_REFERER'])) {
87
	$referer = $_SERVER['HTTP_REFERER'];
88
} else {
89
	$referer = '/system_usermanager.php';
90
}
91

    
92
if (isset($id) && $a_user[$id]) {
93
	$pconfig['usernamefld'] = $a_user[$id]['name'];
94
	$pconfig['descr'] = $a_user[$id]['descr'];
95
	$pconfig['expires'] = $a_user[$id]['expires'];
96
	$pconfig['customsettings'] = isset($a_user[$id]['customsettings']);
97
	$pconfig['webguicss'] = $a_user[$id]['webguicss'];
98
	$pconfig['webguifixedmenu'] = $a_user[$id]['webguifixedmenu'];
99
	$pconfig['webguihostnamemenu'] = $a_user[$id]['webguihostnamemenu'];
100
	$pconfig['dashboardcolumns'] = $a_user[$id]['dashboardcolumns'];
101
	$pconfig['dashboardavailablewidgetspanel'] = isset($a_user[$id]['dashboardavailablewidgetspanel']);
102
	$pconfig['systemlogsfilterpanel'] = isset($a_user[$id]['systemlogsfilterpanel']);
103
	$pconfig['systemlogsmanagelogpanel'] = isset($a_user[$id]['systemlogsmanagelogpanel']);
104
	$pconfig['statusmonitoringsettingspanel'] = isset($a_user[$id]['statusmonitoringsettingspanel']);
105
	$pconfig['webguileftcolumnhyper'] = isset($a_user[$id]['webguileftcolumnhyper']);
106
	$pconfig['pagenamefirst'] = isset($a_user[$id]['pagenamefirst']);
107
	$pconfig['groups'] = local_user_get_groups($a_user[$id]);
108
	$pconfig['utype'] = $a_user[$id]['scope'];
109
	$pconfig['uid'] = $a_user[$id]['uid'];
110
	$pconfig['authorizedkeys'] = base64_decode($a_user[$id]['authorizedkeys']);
111
	$pconfig['priv'] = $a_user[$id]['priv'];
112
	$pconfig['ipsecpsk'] = $a_user[$id]['ipsecpsk'];
113
	$pconfig['disabled'] = isset($a_user[$id]['disabled']);
114
}
115

    
116
if ($_GET['act'] == "deluser") {
117

    
118
	if (!isset($_GET['username']) || !isset($a_user[$id]) || ($_GET['username'] != $a_user[$id]['name'])) {
119
		pfSenseHeader("system_usermanager.php");
120
		exit;
121
	}
122

    
123
	if ($_GET['username'] == $_SESSION['Username']) {
124
		$delete_errors[] = sprintf(gettext("Cannot delete user %s because you are currently logged in as that user."), $_GET['username']);
125
	} else {
126
		conf_mount_rw();
127
		local_user_del($a_user[$id]);
128
		conf_mount_ro();
129
		$userdeleted = $a_user[$id]['name'];
130
		unset($a_user[$id]);
131
		write_config();
132
		$savemsg = sprintf(gettext("User %s successfully deleted."), $userdeleted);
133
	}
134
} else if ($act == "new") {
135
	/*
136
	 * set this value cause the text field is read only
137
	 * and the user should not be able to mess with this
138
	 * setting.
139
	 */
140
	$pconfig['utype'] = "user";
141
	$pconfig['lifetime'] = 3650;
142
}
143

    
144
if (isset($_POST['dellall'])) {
145

    
146
	$del_users = $_POST['delete_check'];
147
	$deleted_users = "";
148
	$deleted_count = 0;
149
	$comma = "";
150

    
151
	if (!empty($del_users)) {
152
		foreach ($del_users as $userid) {
153
			if (isset($a_user[$userid]) && $a_user[$userid]['scope'] != "system") {
154
				if ($a_user[$userid]['name'] == $_SESSION['Username']) {
155
					$delete_errors[] = sprintf(gettext("Cannot delete user %s because you are currently logged in as that user."), $a_user[$userid]['name']);
156
				} else {
157
					conf_mount_rw();
158
					$deleted_users = $deleted_users . $comma . $a_user[$userid]['name'];
159
					$comma = ", ";
160
					$deleted_count++;
161
					local_user_del($a_user[$userid]);
162
					conf_mount_ro();
163
					unset($a_user[$userid]);
164
				}
165
			} else {
166
				$delete_errors[] = sprintf(gettext("Cannot delete user %s because it is a system user."), $a_user[$userid]['name']);
167
			}
168
		}
169

    
170
		if ($deleted_count > 0) {
171
			if ($deleted_count == 1) {
172
				$savemsg = sprintf(gettext("User %s successfully deleted."), $deleted_users);
173
			} else {
174
				$savemsg = sprintf(gettext("Users %s successfully deleted."), $deleted_users);
175
			}
176
			write_config($savemsg);
177
		}
178
	}
179
}
180

    
181
if ($_POST['act'] == "delcert") {
182

    
183
	if (!$a_user[$id]) {
184
		pfSenseHeader("system_usermanager.php");
185
		exit;
186
	}
187

    
188
	$certdeleted = lookup_cert($a_user[$id]['cert'][$_POST['certid']]);
189
	$certdeleted = $certdeleted['descr'];
190
	unset($a_user[$id]['cert'][$_POST['certid']]);
191
	write_config();
192
	$_POST['act'] = "edit";
193
	$savemsg = sprintf(gettext("Certificate %s association removed."), $certdeleted);
194
}
195

    
196
if ($_POST['act'] == "delprivid") {
197
	$privdeleted = $priv_list[$a_user[$id]['priv'][$_POST['privid']]]['name'];
198
	unset($a_user[$id]['priv'][$_POST['privid']]);
199
	local_user_set($a_user[$id]);
200
	write_config();
201
	$_POST['act'] = "edit";
202
	$savemsg = sprintf(gettext("Privilege %s removed."), $privdeleted);
203
}
204

    
205
if ($_POST['save']) {
206
	unset($input_errors);
207
	$pconfig = $_POST;
208

    
209
	/* input validation */
210
	if (isset($id) && ($a_user[$id])) {
211
		$reqdfields = explode(" ", "usernamefld");
212
		$reqdfieldsn = array(gettext("Username"));
213
	} else {
214
		if (empty($_POST['name'])) {
215
			$reqdfields = explode(" ", "usernamefld passwordfld1");
216
			$reqdfieldsn = array(
217
				gettext("Username"),
218
				gettext("Password"));
219
		} else {
220
			$reqdfields = explode(" ", "usernamefld passwordfld1 name caref keylen lifetime");
221
			$reqdfieldsn = array(
222
				gettext("Username"),
223
				gettext("Password"),
224
				gettext("Descriptive name"),
225
				gettext("Certificate authority"),
226
				gettext("Key length"),
227
				gettext("Lifetime"));
228
		}
229
	}
230

    
231
	do_input_validation($_POST, $reqdfields, $reqdfieldsn, $input_errors);
232

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

    
237
	if (strlen($_POST['usernamefld']) > 16) {
238
		$input_errors[] = gettext("The username is longer than 16 characters.");
239
	}
240

    
241
	if (($_POST['passwordfld1']) && ($_POST['passwordfld1'] != $_POST['passwordfld2'])) {
242
		$input_errors[] = gettext("The passwords do not match.");
243
	}
244

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

    
249
	/* Check the POSTed groups to ensure they are valid and exist */
250
	if (is_array($_POST['groups'])) {
251
		foreach ($_POST['groups'] as $newgroup) {
252
			if (empty(getGroupEntry($newgroup))) {
253
				$input_errors[] = gettext("One or more invalid groups was submitted.");
254
			}
255
		}
256
	}
257

    
258
	if (isset($id) && $a_user[$id]) {
259
		$oldusername = $a_user[$id]['name'];
260
	} else {
261
		$oldusername = "";
262
	}
263
	/* make sure this user name is unique */
264
	if (!$input_errors) {
265
		foreach ($a_user as $userent) {
266
			if ($userent['name'] == $_POST['usernamefld'] && $oldusername != $_POST['usernamefld']) {
267
				$input_errors[] = gettext("Another entry with the same username already exists.");
268
				break;
269
			}
270
		}
271
	}
272
	/* also make sure it is not reserved */
273
	if (!$input_errors) {
274
		$system_users = explode("\n", file_get_contents("/etc/passwd"));
275
		foreach ($system_users as $s_user) {
276
			$ent = explode(":", $s_user);
277
			if ($ent[0] == $_POST['usernamefld'] && $oldusername != $_POST['usernamefld']) {
278
				$input_errors[] = gettext("That username is reserved by the system.");
279
				break;
280
			}
281
		}
282
	}
283

    
284
	/*
285
	 * Check for a valid expiration date if one is set at all (valid means,
286
	 * DateTime puts out a time stamp so any DateTime compatible time
287
	 * format may be used. to keep it simple for the enduser, we only
288
	 * claim to accept MM/DD/YYYY as inputs. Advanced users may use inputs
289
	 * like "+1 day", which will be converted to MM/DD/YYYY based on "now".
290
	 * Otherwise such an entry would lead to an invalid expiration data.
291
	 */
292
	if ($_POST['expires']) {
293
		try {
294
			$expdate = new DateTime($_POST['expires']);
295
			//convert from any DateTime compatible date to MM/DD/YYYY
296
			$_POST['expires'] = $expdate->format("m/d/Y");
297
		} catch (Exception $ex) {
298
			$input_errors[] = gettext("Invalid expiration date format; use MM/DD/YYYY instead.");
299
		}
300
	}
301

    
302
	if (!empty($_POST['name'])) {
303
		$ca = lookup_ca($_POST['caref']);
304
		if (!$ca) {
305
			$input_errors[] = gettext("Invalid internal Certificate Authority") . "\n";
306
		}
307
	}
308

    
309
	if (!$input_errors) {
310

    
311
		conf_mount_rw();
312
		$userent = array();
313
		if (isset($id) && $a_user[$id]) {
314
			$userent = $a_user[$id];
315
		}
316

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

    
319
		/* the user name was modified */
320
		if (!empty($_POST['oldusername']) && ($_POST['usernamefld'] <> $_POST['oldusername'])) {
321
			$_SERVER['REMOTE_USER'] = $_POST['usernamefld'];
322
			local_user_del($userent);
323
		}
324

    
325
		/* the user password was modified */
326
		if ($_POST['passwordfld1']) {
327
			local_user_set_password($userent, $_POST['passwordfld1']);
328
		}
329

    
330
		/* only change description if sent */
331
		if (isset($_POST['descr'])) {
332
			$userent['descr'] = $_POST['descr'];
333
		}
334

    
335
		$userent['name'] = $_POST['usernamefld'];
336
		$userent['expires'] = $_POST['expires'];
337
		$userent['dashboardcolumns'] = $_POST['dashboardcolumns'];
338
		$userent['authorizedkeys'] = base64_encode($_POST['authorizedkeys']);
339
		$userent['ipsecpsk'] = $_POST['ipsecpsk'];
340

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

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

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

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

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

    
371
		if ($_POST['dashboardavailablewidgetspanel']) {
372
			$userent['dashboardavailablewidgetspanel'] = true;
373
		} else {
374
			unset($userent['dashboardavailablewidgetspanel']);
375
		}
376

    
377
		if ($_POST['systemlogsfilterpanel']) {
378
			$userent['systemlogsfilterpanel'] = true;
379
		} else {
380
			unset($userent['systemlogsfilterpanel']);
381
		}
382

    
383
		if ($_POST['systemlogsmanagelogpanel']) {
384
			$userent['systemlogsmanagelogpanel'] = true;
385
		} else {
386
			unset($userent['systemlogsmanagelogpanel']);
387
		}
388

    
389
		if ($_POST['statusmonitoringsettingspanel']) {
390
			$userent['statusmonitoringsettingspanel'] = true;
391
		} else {
392
			unset($userent['statusmonitoringsettingspanel']);
393
		}
394

    
395
		if ($_POST['webguileftcolumnhyper']) {
396
			$userent['webguileftcolumnhyper'] = true;
397
		} else {
398
			unset($userent['webguileftcolumnhyper']);
399
		}
400

    
401
		if ($_POST['pagenamefirst']) {
402
			$userent['pagenamefirst'] = true;
403
		} else {
404
			unset($userent['pagenamefirst']);
405
		}
406

    
407
		if (isset($id) && $a_user[$id]) {
408
			$a_user[$id] = $userent;
409
		} else {
410
			if (!empty($_POST['name'])) {
411
				$cert = array();
412
				$cert['refid'] = uniqid();
413
				$userent['cert'] = array();
414

    
415
				$cert['descr'] = $_POST['name'];
416

    
417
				$subject = cert_get_subject_array($ca['crt']);
418

    
419
				$dn = array(
420
					'countryName' => $subject[0]['v'],
421
					'stateOrProvinceName' => $subject[1]['v'],
422
					'localityName' => $subject[2]['v'],
423
					'organizationName' => $subject[3]['v'],
424
					'emailAddress' => $subject[4]['v'],
425
					'commonName' => $userent['name']);
426

    
427
				cert_create($cert, $_POST['caref'], $_POST['keylen'],
428
					(int)$_POST['lifetime'], $dn);
429

    
430
				if (!is_array($config['cert'])) {
431
					$config['cert'] = array();
432
				}
433
				$config['cert'][] = $cert;
434
				$userent['cert'][] = $cert['refid'];
435
			}
436
			$userent['uid'] = $config['system']['nextuid']++;
437
			/* Add the user to All Users group. */
438
			foreach ($config['system']['group'] as $gidx => $group) {
439
				if ($group['name'] == "all") {
440
					if (!is_array($config['system']['group'][$gidx]['member'])) {
441
						$config['system']['group'][$gidx]['member'] = array();
442
					}
443
					$config['system']['group'][$gidx]['member'][] = $userent['uid'];
444
					break;
445
				}
446
			}
447

    
448
			$a_user[] = $userent;
449
		}
450

    
451
		/* 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. */
452
		local_user_set_groups($userent, $_POST['groups']);
453
		local_user_set($userent);
454
		/* 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. */
455
		local_user_set_groups($userent, $_POST['groups']);
456
		write_config();
457

    
458
		if (is_dir("/etc/inc/privhooks")) {
459
			run_plugins("/etc/inc/privhooks");
460
		}
461

    
462
		conf_mount_ro();
463

    
464
		pfSenseHeader("system_usermanager.php");
465
	}
466
}
467

    
468
function build_priv_table() {
469
	global $a_user, $id;
470

    
471
	$privhtml = '<div class="table-responsive">';
472
	$privhtml .=	'<table class="table table-striped table-hover table-condensed">';
473
	$privhtml .=		'<thead>';
474
	$privhtml .=			'<tr>';
475
	$privhtml .=				'<th>' . gettext('Inherited from') . '</th>';
476
	$privhtml .=				'<th>' . gettext('Name') . '</th>';
477
	$privhtml .=				'<th>' . gettext('Description') . '</th>';
478
	$privhtml .=				'<th>' . gettext('Action') . '</th>';
479
	$privhtml .=			'</tr>';
480
	$privhtml .=		'</thead>';
481
	$privhtml .=		'<tbody>';
482

    
483
	$i = 0;
484

    
485
	foreach (get_user_privdesc($a_user[$id]) as $priv) {
486
		$group = false;
487
		if ($priv['group']) {
488
			$group = $priv['group'];
489
		}
490

    
491
		$privhtml .=		'<tr>';
492
		$privhtml .=			'<td>' . htmlspecialchars($priv['group']) . '</td>';
493
		$privhtml .=			'<td>' . htmlspecialchars($priv['name']) . '</td>';
494
		$privhtml .=			'<td>' . htmlspecialchars($priv['descr']) . '</td>';
495
		$privhtml .=			'<td>';
496
		if (!$group) {
497
			$privhtml .=			'<a class="fa fa-trash no-confirm icon-pointer" title="' . gettext('Delete Privilege') . '" id="delprivid' . $i . '"></a>';
498
		}
499

    
500
		$privhtml .=			'</td>';
501
		$privhtml .=		'</tr>';
502

    
503
		if (!$group) {
504
			$i++;
505
		}
506
	}
507

    
508
	$privhtml .=		'</tbody>';
509
	$privhtml .=	'</table>';
510
	$privhtml .= '</div>';
511

    
512
	$privhtml .= '<nav class="action-buttons">';
513
	$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>';
514
	$privhtml .= '</nav>';
515

    
516
	return($privhtml);
517
}
518

    
519
function build_cert_table() {
520
	global $a_user, $id;
521

    
522
	$certhtml = '<div class="table-responsive">';
523
	$certhtml .=	'<table class="table table-striped table-hover table-condensed">';
524
	$certhtml .=		'<thead>';
525
	$certhtml .=			'<tr>';
526
	$certhtml .=				'<th>' . gettext('Name') . '</th>';
527
	$certhtml .=				'<th>' . gettext('CA') . '</th>';
528
	$certhtml .=				'<th></th>';
529
	$certhtml .=			'</tr>';
530
	$certhtml .=		'</thead>';
531
	$certhtml .=		'<tbody>';
532

    
533
	$a_cert = $a_user[$id]['cert'];
534
	if (is_array($a_cert)) {
535
		$i = 0;
536
		foreach ($a_cert as $certref) {
537
			$cert = lookup_cert($certref);
538
			$ca = lookup_ca($cert['caref']);
539
			$revokedstr =	is_cert_revoked($cert) ? '<b> Revoked</b>':'';
540

    
541
			$certhtml .=	'<tr>';
542
			$certhtml .=		'<td>' . htmlspecialchars($cert['descr']) . $revokedstr . '</td>';
543
			$certhtml .=		'<td>' . htmlspecialchars($ca['descr']) . '</td>';
544
			$certhtml .=		'<td>';
545
			$certhtml .=			'<a id="delcert' . $i .'" class="fa fa-trash no-confirm icon-pointer" title="';
546
			$certhtml .=			gettext('Remove this certificate association? (Certificate will not be deleted)') . '"></a>';
547
			$certhtml .=		'</td>';
548
			$certhtml .=	'</tr>';
549
			$i++;
550
		}
551

    
552
	}
553

    
554
	$certhtml .=		'</tbody>';
555
	$certhtml .=	'</table>';
556
	$certhtml .= '</div>';
557

    
558
	$certhtml .= '<nav class="action-buttons">';
559
	$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>';
560
	$certhtml .= '</nav>';
561

    
562
	return($certhtml);
563
}
564

    
565
$pgtitle = array(gettext("System"), gettext("User Manager"), gettext("Users"));
566
$pglinks = array("", "system_usermanager.php", "system_usermanager.php");
567

    
568
if ($act == "new" || $act == "edit" || $input_errors) {
569
	$pgtitle[] = gettext('Edit');
570
	$pglinks[] = "@self";
571
}
572
include("head.inc");
573

    
574
if ($delete_errors) {
575
	print_input_errors($delete_errors);
576
}
577

    
578
if ($input_errors) {
579
	print_input_errors($input_errors);
580
}
581

    
582
if ($savemsg) {
583
	print_info_box($savemsg, 'success');
584
}
585

    
586
$tab_array = array();
587
$tab_array[] = array(gettext("Users"), true, "system_usermanager.php");
588
$tab_array[] = array(gettext("Groups"), false, "system_groupmanager.php");
589
$tab_array[] = array(gettext("Settings"), false, "system_usermanager_settings.php");
590
$tab_array[] = array(gettext("Authentication Servers"), false, "system_authservers.php");
591
display_top_tabs($tab_array);
592

    
593
if (!($act == "new" || $act == "edit" || $input_errors)) {
594
?>
595
<form method="post">
596
<div class="panel panel-default">
597
	<div class="panel-heading"><h2 class="panel-title"><?=gettext('Users')?></h2></div>
598
	<div class="panel-body">
599
		<div class="table-responsive">
600
			<table class="table table-striped table-hover table-condensed sortable-theme-bootstrap table-rowdblclickedit" data-sortable>
601
				<thead>
602
					<tr>
603
						<th>&nbsp;</th>
604
						<th><?=gettext("Username")?></th>
605
						<th><?=gettext("Full name")?></th>
606
						<th><?=gettext("Status")?></th>
607
						<th><?=gettext("Groups")?></th>
608
						<th><?=gettext("Actions")?></th>
609
					</tr>
610
				</thead>
611
				<tbody>
612
<?php
613
foreach ($a_user as $i => $userent):
614
	?>
615
					<tr>
616
						<td>
617
							<input type="checkbox" id="frc<?=$i?>" name="delete_check[]" value="<?=$i?>" <?=((($userent['scope'] == "system") || ($userent['name'] == $_SESSION['Username'])) ? 'disabled' : '')?>/>
618
						</td>
619
						<td>
620
<?php
621
	if ($userent['scope'] != "user") {
622
		$usrimg = 'eye-open';
623
	} else {
624
		$usrimg = 'user';
625
	}
626
?>
627
							<i class="fa fa-<?=$usrimg?>"></i>
628
							<?=htmlspecialchars($userent['name'])?>
629
						</td>
630
						<td><?=htmlspecialchars($userent['descr'])?></td>
631
						<td><i class="fa fa-<?= (isset($userent['disabled'])) ? 'ban" title="' . gettext("Disabled") . '"' : 'check" title="' . gettext("Enabled") . '"' ; ?>><span style='display: none'><?= (isset($userent['disabled'])) ? gettext("Disabled") : gettext("Enabled") ; ?></span></i></td>
632
						<td><?=implode(",", local_user_get_groups($userent))?></td>
633
						<td>
634
							<a class="fa fa-pencil" title="<?=gettext("Edit user"); ?>" href="?act=edit&amp;userid=<?=$i?>"></a>
635
<?php if (($userent['scope'] != "system") && ($userent['name'] != $_SESSION['Username'])): ?>
636
							<a class="fa fa-trash"	title="<?=gettext("Delete user")?>" href="?act=deluser&amp;userid=<?=$i?>&amp;username=<?=$userent['name']?>"></a>
637
<?php endif; ?>
638
						</td>
639
					</tr>
640
<?php endforeach; ?>
641
				</tbody>
642
			</table>
643
		</div>
644
	</div>
645
</div>
646
<nav class="action-buttons">
647
	<a href="?act=new" class="btn btn-sm btn-success">
648
		<i class="fa fa-plus icon-embed-btn"></i>
649
		<?=gettext("Add")?>
650
	</a>
651

    
652
	<button type="submit" class="btn btn-sm btn-danger" name="dellall" value="dellall" title="<?=gettext('Delete selected users')?>">
653
		<i class="fa fa-trash icon-embed-btn"></i>
654
		<?=gettext("Delete")?>
655
	</button>
656
</nav>
657
</form>
658
<div class="infoblock">
659
<?php
660
	print_callout('<p>' . gettext("Additional users can be added here. User permissions for accessing " .
661
		"the webConfigurator can be assigned directly or inherited from group memberships. " .
662
		"Some system object properties can be modified but they cannot be deleted.") . '</p>' .
663
		'<p>' . gettext("Accounts added here are also used for other parts of the system " .
664
		"such as OpenVPN, IPsec, and Captive Portal.") . '</p>'
665
	);
666
?></div><?php
667
	include("foot.inc");
668
	exit;
669
}
670

    
671
$form = new Form;
672

    
673
if ($act == "new" || $act == "edit" || $input_errors):
674

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

    
682
	$form->addGlobal(new Form_Input(
683
		'userid',
684
		null,
685
		'hidden',
686
		isset($id) ? $id:''
687
	));
688

    
689
	$form->addGlobal(new Form_Input(
690
		'privid',
691
		null,
692
		'hidden',
693
		''
694
	));
695

    
696
	$form->addGlobal(new Form_Input(
697
		'certid',
698
		null,
699
		'hidden',
700
		''
701
	));
702

    
703
	$ro = "";
704
	if ($pconfig['utype'] == "system") {
705
		$ro = "readonly";
706
	}
707

    
708
	$section = new Form_Section('User Properties');
709

    
710
	$section->addInput(new Form_StaticText(
711
		'Defined by',
712
		strtoupper($pconfig['utype'])
713
	));
714

    
715
	$form->addGlobal(new Form_Input(
716
		'utype',
717
		null,
718
		'hidden',
719
		$pconfig['utype']
720
	));
721

    
722
	$section->addInput(new Form_Checkbox(
723
		'disabled',
724
		'Disabled',
725
		'This user cannot login',
726
		$pconfig['disabled']
727
	));
728

    
729
	$section->addInput($input = new Form_Input(
730
		'usernamefld',
731
		'*Username',
732
		'text',
733
		$pconfig['usernamefld']
734
	));
735

    
736
	if ($ro) {
737
		$input->setReadonly();
738
	}
739

    
740
	$form->addGlobal(new Form_Input(
741
		'oldusername',
742
		null,
743
		'hidden',
744
		$pconfig['usernamefld']
745
	));
746

    
747
	if ($act == "edit") {
748
		$pwd_required = "";
749
	} else {
750
		$pwd_required = "*";
751
	}
752

    
753
	$group = new Form_Group($pwd_required . 'Password');
754
	$group->add(new Form_Input(
755
		'passwordfld1',
756
		'Password',
757
		'password'
758
	));
759
	$group->add(new Form_Input(
760
		'passwordfld2',
761
		'Confirm Password',
762
		'password'
763
	));
764

    
765
	$section->add($group);
766

    
767
	$section->addInput($input = new Form_Input(
768
		'descr',
769
		'Full name',
770
		'text',
771
		htmlspecialchars($pconfig['descr'])
772
	))->setHelp('User\'s full name, for administrative information only');
773

    
774
	if ($ro) {
775
		$input->setDisabled();
776
	}
777

    
778
	$section->addInput(new Form_Input(
779
		'expires',
780
		'Expiration date',
781
		'text',
782
		$pconfig['expires']
783
	))->setHelp('Leave blank if the account shouldn\'t expire, otherwise enter '.
784
		'the expiration date as MM/DD/YYYY');
785

    
786
	$section->addInput(new Form_Checkbox(
787
		'customsettings',
788
		'Custom Settings',
789
		'Use individual customized GUI options and dashboard layout for this user.',
790
		$pconfig['customsettings']
791
	));
792

    
793
	gen_user_settings_fields($section, $pconfig);
794

    
795
	// ==== Group membership ==================================================
796
	$group = new Form_Group('Group membership');
797

    
798
	// Make a list of all the groups configured on the system, and a list of
799
	// those which this user is a member of
800
	$systemGroups = array();
801
	$usersGroups = array();
802

    
803
	$usergid = [$pconfig['usernamefld']];
804

    
805
	foreach ($config['system']['group'] as $Ggroup) {
806
		if ($Ggroup['name'] != "all") {
807
			if (($act == 'edit') && $Ggroup['member'] && in_array($pconfig['uid'], $Ggroup['member'])) {
808
				$usersGroups[ $Ggroup['name'] ] = $Ggroup['name'];	// Add it to the user's list
809
			} else {
810
				$systemGroups[ $Ggroup['name'] ] = $Ggroup['name']; // Add it to the 'not a member of' list
811
			}
812
		}
813
	}
814

    
815
	$group->add(new Form_Select(
816
		'sysgroups',
817
		null,
818
		array_combine((array)$pconfig['groups'], (array)$pconfig['groups']),
819
		$systemGroups,
820
		true
821
	))->setHelp('Not member of');
822

    
823
	$group->add(new Form_Select(
824
		'groups',
825
		null,
826
		array_combine((array)$pconfig['groups'], (array)$pconfig['groups']),
827
		$usersGroups,
828
		true
829
	))->setHelp('Member of');
830

    
831
	$section->add($group);
832

    
833
	$group = new Form_Group('');
834

    
835
	$group->add(new Form_Button(
836
		'movetoenabled',
837
		'Move to "Member of" list',
838
		null,
839
		'fa-angle-double-right'
840
	))->setAttribute('type','button')->removeClass('btn-primary')->addClass('btn-info btn-sm');
841

    
842
	$group->add(new Form_Button(
843
		'movetodisabled',
844
		'Move to "Not member of" list',
845
		null,
846
		'fa-angle-double-left'
847
	))->setAttribute('type','button')->removeClass('btn-primary')->addClass('btn-info btn-sm');
848

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

    
852
	// ==== Button for adding user certificate ================================
853
	if ($act == 'new') {
854
		$section->addInput(new Form_Checkbox(
855
			'showcert',
856
			'Certificate',
857
			'Click to create a user certificate',
858
			false
859
		));
860
	}
861

    
862
	$form->add($section);
863

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

    
869
		$section = new Form_Section('Effective Privileges');
870

    
871
		$section->addInput(new Form_StaticText(
872
			null,
873
			build_priv_table()
874
		));
875

    
876
		$form->add($section);
877

    
878
		// ==== Certificate table section =====================================
879
		$section = new Form_Section('User Certificates');
880

    
881
		$section->addInput(new Form_StaticText(
882
			null,
883
			build_cert_table()
884
		));
885

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

    
889
	// ==== Add user certificate for a new user
890
	if (is_array($config['ca']) && count($config['ca']) > 0) {
891
		$section = new Form_Section('Create Certificate for User');
892
		$section->addClass('cert-options');
893

    
894
		$nonPrvCas = array();
895
		foreach ($config['ca'] as $ca) {
896
			if (!$ca['prv']) {
897
				continue;
898
			}
899

    
900
			$nonPrvCas[ $ca['refid'] ] = $ca['descr'];
901
		}
902

    
903
		if (!empty($nonPrvCas)) {
904
			$section->addInput(new Form_Input(
905
				'name',
906
				'Descriptive name',
907
				'text',
908
				$pconfig['name']
909
			));
910

    
911
			$section->addInput(new Form_Select(
912
				'caref',
913
				'Certificate authority',
914
				null,
915
				$nonPrvCas
916
			));
917

    
918
			$section->addInput(new Form_Select(
919
				'keylen',
920
				'Key length',
921
				2048,
922
				array(
923
					512 => '512 bits',
924
					1024 => '1024 bits',
925
					2048 => '2048 bits',
926
					3072 => '3072 bits',
927
					4096 => '4096 bits',
928
					7680 => '7680 bits',
929
					8192 => '8192 bits',
930
					15360 => '15360 bits',
931
					16384 => '16384 bits'
932
				)
933
			))->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;.');
934

    
935
			$section->addInput(new Form_Input(
936
				'lifetime',
937
				'Lifetime',
938
				'number',
939
				$pconfig['lifetime']
940
			));
941
		}
942

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

    
946
endif;
947
// ==== Paste a key for the new user
948
$section = new Form_Section('Keys');
949

    
950
$section->addInput(new Form_Checkbox(
951
	'showkey',
952
	'Authorized keys',
953
	'Click to paste an authorized key',
954
	false
955
));
956

    
957
$section->addInput(new Form_Textarea(
958
	'authorizedkeys',
959
	'Authorized SSH Keys',
960
	$pconfig['authorizedkeys']
961
))->setHelp('Enter authorized SSH keys for this user');
962

    
963
$section->addInput(new Form_Input(
964
	'ipsecpsk',
965
	'IPsec Pre-Shared Key',
966
	'text',
967
	$pconfig['ipsecpsk']
968
));
969

    
970
$form->add($section);
971

    
972
print $form;
973

    
974
$csswarning = sprintf(gettext("%sUser-created themes are unsupported, use at your own risk."), "<br />");
975
?>
976
<script type="text/javascript">
977
//<![CDATA[
978
events.push(function() {
979

    
980
	function setcustomoptions() {
981
		var adv = $('#customsettings').prop('checked');
982

    
983
		hideInput('webguicss', !adv);
984
		hideInput('webguifixedmenu', !adv);
985
		hideInput('webguihostnamemenu', !adv);
986
		hideInput('dashboardcolumns', !adv);
987
		hideCheckbox('dashboardavailablewidgetspanel', !adv);
988
		hideCheckbox('systemlogsfilterpanel', !adv);
989
		hideCheckbox('systemlogsmanagelogpanel', !adv);
990
		hideCheckbox('statusmonitoringsettingspanel', !adv);
991
		hideCheckbox('webguileftcolumnhyper', !adv);
992
		hideCheckbox('pagenamefirst', !adv);
993
	}
994

    
995
	// Handle displaying a warning message if a user-created theme is selected.
996
	function setThemeWarning() {
997
		if ($('#webguicss').val().startsWith("pfSense")) {
998
			$('#csstxt').html("").addClass("text-default");
999
		} else {
1000
			$('#csstxt').html("<?=$csswarning?>").addClass("text-danger");
1001
		}
1002
	}
1003

    
1004
	$('#webguicss').change(function() {
1005
		setThemeWarning();
1006
	});
1007

    
1008
	setThemeWarning();
1009

    
1010
	// On click . .
1011
	$('#customsettings').click(function () {
1012
		setcustomoptions();
1013
	});
1014

    
1015
	$("#movetodisabled").click(function() {
1016
		moveOptions($('[name="groups[]"] option'), $('[name="sysgroups[]"]'));
1017
	});
1018

    
1019
	$("#movetoenabled").click(function() {
1020
		moveOptions($('[name="sysgroups[]"] option'), $('[name="groups[]"]'));
1021
	});
1022

    
1023
	$("#showcert").click(function() {
1024
		hideClass('cert-options', !this.checked);
1025
	});
1026

    
1027
	$("#showkey").click(function() {
1028
		hideInput('authorizedkeys', false);
1029
		hideCheckbox('showkey', true);
1030
	});
1031

    
1032
	$('[id^=delcert]').click(function(event) {
1033
		if (confirm(event.target.title)) {
1034
			$('#certid').val(event.target.id.match(/\d+$/)[0]);
1035
			$('#userid').val('<?=$id;?>');
1036
			$('#act').val('delcert');
1037
			$('form').submit();
1038
		}
1039
	});
1040

    
1041
	$('[id^=delprivid]').click(function(event) {
1042
		if (confirm(event.target.title)) {
1043
			$('#privid').val(event.target.id.match(/\d+$/)[0]);
1044
			$('#userid').val('<?=$id;?>');
1045
			$('#act').val('delprivid');
1046
			$('form').submit();
1047
		}
1048
	});
1049

    
1050
	$('#expires').datepicker();
1051

    
1052
	// ---------- On initial page load ------------------------------------------------------------
1053

    
1054
	hideClass('cert-options', true);
1055
	//hideInput('authorizedkeys', true);
1056
	hideCheckbox('showkey', true);
1057
	setcustomoptions();
1058

    
1059
	// On submit mark all the user's groups as "selected"
1060
	$('form').submit(function() {
1061
		AllServers($('[name="groups[]"] option'), true);
1062
	});
1063
});
1064
//]]>
1065
</script>
1066
<?php
1067
include('foot.inc');
1068
?>
(206-206/225)