Project

General

Profile

Download (16.6 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php
2
/* $Id$ */
3
/*
4
	system_usermanager.php
5
	part of m0n0wall (http://m0n0.ch/wall)
6

    
7
	part of pfSense
8
	Copyright (C) 2013-2015 Electric Sheep Fencing, LP
9
	All rights reserved.
10

    
11
	Copyright (C) 2008 Shrew Soft Inc.
12
	All rights reserved.
13

    
14
	Copyright (C) 2005 Paul Taylor <paultaylor@winn-dixie.com>.
15
	All rights reserved.
16

    
17
	Copyright (C) 2003-2005 Manuel Kasper <mk@neon1.net>.
18
	All rights reserved.
19

    
20
	Redistribution and use in source and binary forms, with or without
21
	modification, are permitted provided that the following conditions are met:
22

    
23
	1. Redistributions of source code must retain the above copyright notice,
24
	   this list of conditions and the following disclaimer.
25

    
26
	2. Redistributions in binary form must reproduce the above copyright
27
	   notice, this list of conditions and the following disclaimer in the
28
	   documentation and/or other materials provided with the distribution.
29

    
30
	THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
31
	INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
32
	AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
33
	AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
34
	OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
35
	SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
36
	INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
37
	CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
38
	ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39
	POSSIBILITY OF SUCH DAMAGE.
40
*/
41
/*
42
	pfSense_BUILDER_BINARIES:
43
	pfSense_MODULE:	auth
44
*/
45

    
46
##|+PRIV
47
##|*IDENT=page-system-usermanager
48
##|*NAME=System: User Manager page
49
##|*DESCR=Allow access to the 'System: User Manager' page.
50
##|*MATCH=system_usermanager.php*
51
##|-PRIV
52

    
53
require("certs.inc");
54
require("guiconfig.inc");
55

    
56
// start admin user code
57
$pgtitle = array(gettext("System"), gettext("User Manager"));
58

    
59
if (isset($_POST['userid']) && is_numericint($_POST['userid'])) {
60
	$id = $_POST['userid'];
61
}
62

    
63
if (!isset($config['system']['user']) || !is_array($config['system']['user'])) {
64
	$config['system']['user'] = array();
65
}
66

    
67
$a_user = &$config['system']['user'];
68

    
69
if (isset($_SERVER['HTTP_REFERER'])) {
70
	$referer = $_SERVER['HTTP_REFERER'];
71
} else {
72
	$referer = '/system_usermanager.php';
73
}
74

    
75
if (isset($id) && $a_user[$id]) {
76
	$pconfig['usernamefld'] = $a_user[$id]['name'];
77
	$pconfig['descr'] = $a_user[$id]['descr'];
78
	$pconfig['expires'] = $a_user[$id]['expires'];
79
	$pconfig['groups'] = local_user_get_groups($a_user[$id]);
80
	$pconfig['utype'] = $a_user[$id]['scope'];
81
	$pconfig['uid'] = $a_user[$id]['uid'];
82
	$pconfig['authorizedkeys'] = base64_decode($a_user[$id]['authorizedkeys']);
83
	$pconfig['priv'] = $a_user[$id]['priv'];
84
	$pconfig['ipsecpsk'] = $a_user[$id]['ipsecpsk'];
85
	$pconfig['disabled'] = isset($a_user[$id]['disabled']);
86
}
87

    
88
if ($_POST['act'] == "deluser") {
89

    
90
	if (!isset($_POST['username']) || !isset($a_user[$id]) || ($_POST['username'] != $a_user[$id]['name'])) {
91
		pfSenseHeader("system_usermanager.php");
92
		exit;
93
	}
94

    
95
	conf_mount_rw();
96
	local_user_del($a_user[$id]);
97
	conf_mount_ro();
98
	$userdeleted = $a_user[$id]['name'];
99
	unset($a_user[$id]);
100
	write_config();
101
	$savemsg = gettext("User")." {$userdeleted} ".
102
				gettext("successfully deleted")."<br />";
103
}
104
else if ($_GET['act'] == "new") {
105
	/*
106
	 * set this value cause the text field is read only
107
	 * and the user should not be able to mess with this
108
	 * setting.
109
	 */
110
	$pconfig['utype'] = "user";
111
	$pconfig['lifetime'] = 3650;
112
}
113

    
114
if (isset($_POST['dellall_x'])) {
115

    
116
	$del_users = $_POST['delete_check'];
117

    
118
	if (!empty($del_users)) {
119
		foreach ($del_users as $userid) {
120
			if (isset($a_user[$userid]) && $a_user[$userid]['scope'] != "system") {
121
				conf_mount_rw();
122
				local_user_del($a_user[$userid]);
123
				conf_mount_ro();
124
				unset($a_user[$userid]);
125
			}
126
		}
127
		$savemsg = gettext("Selected users removed successfully!");
128
		write_config($savemsg);
129
	}
130
}
131

    
132
if ($_POST['save']) {
133
	unset($input_errors);
134
	$pconfig = $_POST;
135

    
136
	/* input validation */
137
	if (isset($id) && ($a_user[$id])) {
138
		$reqdfields = explode(" ", "usernamefld");
139
		$reqdfieldsn = array(gettext("Username"));
140
	} else {
141
		if (empty($_POST['name'])) {
142
			$reqdfields = explode(" ", "usernamefld passwordfld1");
143
			$reqdfieldsn = array(
144
				gettext("Username"),
145
				gettext("Password"));
146
		} else {
147
			$reqdfields = explode(" ", "usernamefld passwordfld1 name caref keylen lifetime");
148
			$reqdfieldsn = array(
149
				gettext("Username"),
150
				gettext("Password"),
151
				gettext("Descriptive name"),
152
				gettext("Certificate authority"),
153
				gettext("Key length"),
154
				gettext("Lifetime"));
155
		}
156
	}
157

    
158
	do_input_validation($_POST, $reqdfields, $reqdfieldsn, $input_errors);
159

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

    
164
	if (strlen($_POST['usernamefld']) > 16) {
165
		$input_errors[] = gettext("The username is longer than 16 characters.");
166
	}
167

    
168
	if (($_POST['passwordfld1']) && ($_POST['passwordfld1'] != $_POST['passwordfld2'])) {
169
		$input_errors[] = gettext("The passwords do not match.");
170
	}
171

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

    
176
	if (isset($id) && $a_user[$id]) {
177
		$oldusername = $a_user[$id]['name'];
178
	} else {
179
		$oldusername = "";
180
	}
181
	/* make sure this user name is unique */
182
	if (!$input_errors) {
183
		foreach ($a_user as $userent) {
184
			if ($userent['name'] == $_POST['usernamefld'] && $oldusername != $_POST['usernamefld']) {
185
				$input_errors[] = gettext("Another entry with the same username already exists.");
186
				break;
187
			}
188
		}
189
	}
190
	/* also make sure it is not reserved */
191
	if (!$input_errors) {
192
		$system_users = explode("\n", file_get_contents("/etc/passwd"));
193
		foreach ($system_users as $s_user) {
194
			$ent = explode(":", $s_user);
195
			if ($ent[0] == $_POST['usernamefld'] && $oldusername != $_POST['usernamefld']) {
196
				$input_errors[] = gettext("That username is reserved by the system.");
197
				break;
198
			}
199
		}
200
	}
201

    
202
	/*
203
	 * Check for a valid expiration date if one is set at all (valid means,
204
	 * DateTime puts out a time stamp so any DateTime compatible time
205
	 * format may be used. to keep it simple for the enduser, we only
206
	 * claim to accept MM/DD/YYYY as inputs. Advanced users may use inputs
207
	 * like "+1 day", which will be converted to MM/DD/YYYY based on "now".
208
	 * Otherwise such an entry would lead to an invalid expiration data.
209
	 */
210
	if ($_POST['expires']) {
211
		try {
212
			$expdate = new DateTime($_POST['expires']);
213
			//convert from any DateTime compatible date to MM/DD/YYYY
214
			$_POST['expires'] = $expdate->format("m/d/Y");
215
		} catch (Exception $ex) {
216
			$input_errors[] = gettext("Invalid expiration date format; use MM/DD/YYYY instead.");
217
		}
218
	}
219

    
220
	if (!empty($_POST['name'])) {
221
		$ca = lookup_ca($_POST['caref']);
222
		if (!$ca) {
223
			$input_errors[] = gettext("Invalid internal Certificate Authority") . "\n";
224
		}
225
	}
226

    
227
	/* if this is an AJAX caller then handle via JSON */
228
	if (isAjax() && is_array($input_errors)) {
229
		input_errors2Ajax($input_errors);
230
		exit;
231
	}
232

    
233
	if (!$input_errors) {
234
		// This used to be a separate act=delpriv
235
		if ($a_user[$id] && !empty($_POST['privid'])) {
236
			foreach ($_POST['privid'] as $i)
237
				unset($a_user[$id]['priv'][$i]);
238
			local_user_set($a_user[$id]);
239
			write_config();
240
		}
241

    
242
		// This used to be a separate act=delcert
243
		if ($a_user[$id] && !empty($_POST['certid'])) {
244
			foreach ($_POST['certid'] as $i)
245
				unset($a_user[$id]['cert'][$i]);
246

    
247
			write_config();
248
		}
249

    
250
		conf_mount_rw();
251
		$userent = array();
252
		if (isset($id) && $a_user[$id]) {
253
			$userent = $a_user[$id];
254
		}
255

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

    
258
		/* the user name was modified */
259
		if (!empty($_POST['oldusername']) && ($_POST['usernamefld'] <> $_POST['oldusername'])) {
260
			$_SERVER['REMOTE_USER'] = $_POST['usernamefld'];
261
			local_user_del($userent);
262
		}
263

    
264
		/* the user password was modified */
265
		if ($_POST['passwordfld1']) {
266
			local_user_set_password($userent, $_POST['passwordfld1']);
267
		}
268

    
269
		$userent['name'] = $_POST['usernamefld'];
270
		$userent['descr'] = $_POST['descr'];
271
		$userent['expires'] = $_POST['expires'];
272
		$userent['authorizedkeys'] = base64_encode($_POST['authorizedkeys']);
273
		$userent['ipsecpsk'] = $_POST['ipsecpsk'];
274

    
275
		if ($_POST['disabled']) {
276
			$userent['disabled'] = true;
277
		} else {
278
			unset($userent['disabled']);
279
		}
280

    
281
		if (isset($id) && $a_user[$id]) {
282
			$a_user[$id] = $userent;
283
		} else {
284
			if (!empty($_POST['name'])) {
285
				$cert = array();
286
				$cert['refid'] = uniqid();
287
				$userent['cert'] = array();
288

    
289
				$cert['descr'] = $_POST['name'];
290

    
291
				$subject = cert_get_subject_array($ca['crt']);
292

    
293
				$dn = array(
294
					'countryName' => $subject[0]['v'],
295
					'stateOrProvinceName' => $subject[1]['v'],
296
					'localityName' => $subject[2]['v'],
297
					'organizationName' => $subject[3]['v'],
298
					'emailAddress' => $subject[4]['v'],
299
					'commonName' => $userent['name']);
300

    
301
				cert_create($cert, $_POST['caref'], $_POST['keylen'],
302
					(int)$_POST['lifetime'], $dn);
303

    
304
				if (!is_array($config['cert'])) {
305
					$config['cert'] = array();
306
				}
307
				$config['cert'][] = $cert;
308
				$userent['cert'][] = $cert['refid'];
309
			}
310
			$userent['uid'] = $config['system']['nextuid']++;
311
			/* Add the user to All Users group. */
312
			foreach ($config['system']['group'] as $gidx => $group) {
313
				if ($group['name'] == "all") {
314
					if (!is_array($config['system']['group'][$gidx]['member'])) {
315
						$config['system']['group'][$gidx]['member'] = array();
316
					}
317
					$config['system']['group'][$gidx]['member'][] = $userent['uid'];
318
					break;
319
				}
320
			}
321

    
322
			$a_user[] = $userent;
323
		}
324

    
325
		local_user_set($userent);
326
		local_user_set_groups($userent, $_POST['groups']);
327
		write_config();
328

    
329
		if (is_dir("/etc/inc/privhooks")) {
330
			run_plugins("/etc/inc/privhooks");
331
		}
332

    
333
		conf_mount_ro();
334

    
335
		pfSenseHeader("system_usermanager.php");
336
	}
337
}
338

    
339
$closehead = false;
340
include("head.inc");
341

    
342
if ($input_errors)
343
	print_input_errors($input_errors);
344
if ($savemsg)
345
	print_info_box($savemsg);
346

    
347
$tab_array = array();
348
$tab_array[] = array(gettext("Users"), true, "system_usermanager.php");
349
$tab_array[] = array(gettext("Groups"), false, "system_groupmanager.php");
350
$tab_array[] = array(gettext("Settings"), false, "system_usermanager_settings.php");
351
$tab_array[] = array(gettext("Servers"), false, "system_authservers.php");
352
display_top_tabs($tab_array);
353

    
354
if (!($_GET['act'] == "new" || $_GET['act'] == "edit" || $input_errors))
355
{
356
?>
357

    
358
<div class="table-responsive">
359
<table class="table table-striped table-hover">
360
	<thead>
361
		<tr>
362
			<th>&nbsp;</th>
363
			<th><?=gettext("Username")?></th>
364
			<th><?=gettext("Full name")?></th>
365
			<th><?=gettext("Disabled")?></th>
366
			<th><?=gettext("Groups")?></th>
367
		</tr>
368
	</thead>
369
	<tbody>
370
	</tbody>
371
	<tbody>
372
<?php
373
foreach($a_user as $i => $userent):
374
	?>
375
	<tr>
376
		<td>
377
			<input type="checkbox" id="frc<?=$i?>" name="delete_check[]" value="<?=$i?>" <?=($userent['scope'] == "system" ? 'disabled="disabled"' : '')?>/>
378
		</td>
379
		<td>
380
<?php
381
	if($userent['scope'] != "user")
382
		$usrimg = 'eye-open';
383
	else
384
		$usrimg = 'user';
385
?>
386
			<i class="icon icon-<?=$usrimg?>"></i>
387
			<?=htmlspecialchars($userent['name'])?>
388
		</td>
389
		<td><?=htmlspecialchars($userent['descr'])?></td>
390
		<td><?php if(isset($userent['disabled'])) echo "*"?></td>
391
		<td><?=implode(",",local_user_get_groups($userent))?></td>
392
		<td>
393
			<a href="?act=edit&amp;userid=<?=$i?>" class="btn btn-xs btn-primary">edit</a>
394
<?php if($userent['scope'] != "system"): ?>
395
			<a href="?act=del&amp;userid=<?=$i?>" class="btn btn-xs btn-danger">delete</a>
396
<?php endif; ?>
397
		</td>
398
	</tr>
399
<?php endforeach; ?>
400
	</tbody>
401
</table>
402
</div>
403
<nav class="action-buttons">
404
	<a href="?act=new" class="btn btn-success">add new</a>
405
</nav>
406
<p>
407
	<?=gettext("Additional users can be added here. User permissions for accessing " .
408
	"the webConfigurator can be assigned directly or inherited from group memberships. " .
409
	"An icon that appears grey indicates that it is a system defined object. " .
410
	"Some system object properties can be modified but they cannot be deleted.")?>
411
	<br /><br />
412
	<?=gettext("Accounts created here are also used for other parts of the system " .
413
	"such as OpenVPN, IPsec, and Captive Portal.")?>
414
</p>
415
<?php
416
	include("foot.inc");
417
	exit;
418
}
419

    
420
require('classes/Form.class.php');
421
$form = new Form;
422
$form->setAction('system_usermanager.php?act=edit');
423
$form->addGlobal(new Form_Input(
424
	'userid',
425
	null,
426
	'hidden',
427
	$id
428
));
429
$form->addGlobal(new Form_Input(
430
	'utype',
431
	null,
432
	'hidden',
433
	$pconfig['utype']
434
));
435
$form->addGlobal(new Form_Input(
436
	'oldusername',
437
	null,
438
	'hidden',
439
	$pconfig['usernamefld']
440
));
441

    
442
$section = new Form_Section('User Properties');
443

    
444
$section->addInput(new Form_StaticText(
445
	'Defined by',
446
	strtoupper($pconfig['utype'])
447
));
448

    
449
?>
450
<?php
451
$ro = false;
452
if ($pconfig['utype'] == "system")
453
	$ro = true;
454

    
455
$section->addInput(new Form_Checkbox(
456
	'disabled',
457
	'Disabled',
458
	'This user cannot login',
459
	$pconfig['disabled']
460
));
461

    
462
$section->addInput($input = new Form_Input(
463
	'usernamefld',
464
	'Username',
465
	'text',
466
	$pconfig['usernamefld']
467
));
468

    
469
if ($ro)
470
	$input->setDisabled();
471

    
472
$group = new Form_Group('Password');
473
$group->add(new Form_Input(
474
	'passwordfld1',
475
	'Password',
476
	'password'
477
));
478
$group->add(new Form_Input(
479
	'passwordfld2',
480
	'Confirm Password',
481
	'password'
482
));
483

    
484
$section->add($group);
485

    
486
$section->addInput($input = new Form_Input(
487
	'descr',
488
	'Full name',
489
	'text',
490
	htmlspecialchars($pconfig['descr'])
491
))->setHelp('User\'s full name, for your own information only');
492

    
493
if ($ro)
494
	$input->setDisabled();
495

    
496
$section->addInput(new Form_Input(
497
	'expires',
498
	'Expiration date',
499
	'date',
500
	$pconfig['expires']
501
))->setHelp('Leave blank if the account shouldn\'t expire, otherwise enter '.
502
	'the expiration date');
503

    
504
$systemGroups = array();
505
foreach ($config['system']['group'] as $group)
506
	$systemGroups[ $group['name'] ] = $group['name'];
507

    
508
$section->addInput(new Form_Select(
509
	'groups',
510
	'Group Memberships',
511
	array_combine((array)$pconfig['groups'], (array)$pconfig['groups']),
512
	$systemGroups,
513
	true
514
))->setHelp('Hold down CTRL (pc)/COMMAND (mac) key to select multiple items');
515

    
516
$form->add($section);
517

    
518
if (isset($pconfig['uid']))
519
{
520
	$section = new Form_Section('Effective Privileges');
521

    
522
	foreach (get_user_privdesc($a_user[$id]) as $i => $priv)
523
	{
524
		// We reverse name and action for readability of longer names
525
		$input = new Form_Checkbox(
526
			'privid[]',
527
			null,
528
			$priv['name'],
529
			false,
530
			$i
531
		);
532

    
533
		if ($priv['group'])
534
		{
535
			$group = new Form_Group('Inherited from '. $priv['group']);
536
			$input->setDisabled();
537
		}
538
		else
539
			$group = new Form_Group('Revoke privilege');
540

    
541
		$group->add($input);
542
		$section->add($group);
543
	}
544

    
545
	$section->addInput(new Form_StaticText(
546
		null,
547
		new Form_Button(null, 'grant more privileges', 'system_usermanager_addprivs.php?userid='. $id)
548
	));
549

    
550
	$form->add($section);
551

    
552
	$section = new Form_Section('User Certificates');
553

    
554
	foreach ((array)$a_user[$id]['cert'] as $i => $certref)
555
	{
556
		$cert = lookup_cert($certref);
557
		$ca = lookup_ca($cert['caref']);
558

    
559
		// We reverse name and action for readability of longer names
560
		$section->addInput(new Form_Checkbox(
561
			'certid[]',
562
			'Delete certificate',
563
			$cert['descr']. (is_cert_revoked($cert) ? ' <b>revoked</b>' : ''),
564
			false,
565
			$i
566
		));
567
	}
568

    
569
	#FIXME; old ui supplied direct export links to each certificate
570

    
571
	$section->addInput(new Form_StaticText(
572
		null,
573
		new Form_Button(null, 'add certificate', 'system_certmanager.php?act=new&userid='. $id).
574
		new Form_Button(null, 'export certificates', 'system_certmanager.php')
575
	));
576
}
577
else
578
{
579
	if (is_array($config['ca']) && count($config['ca']) > 0)
580
	{
581
		$section = new Form_Section('Create certificate for user');
582

    
583
		$nonPrvCas = array();
584
		foreach( $config['ca'] as $ca)
585
		{
586
			if (!$ca['prv'])
587
				continue;
588

    
589
			$nonPrvCas[ $ca['refid'] ] = $ca['descr'];
590
		}
591

    
592
		if (!empty($nonPrvCas))
593
		{
594
			$section->addInput(new Form_Input(
595
				'name',
596
				'Descriptive name',
597
				'text',
598
				$pconfig['name']
599
			));
600

    
601
			$section->addInput(new Form_Select(
602
				'caref',
603
				'Certificate authority',
604
				null,
605
				$nonPrvCas
606
			));
607

    
608
			$section->addInput(new Form_Select(
609
				'keylen',
610
				'Key length',
611
				2048,
612
				array(
613
					512 => '512 bits',
614
					1024 => '1024 bits',
615
					2048 => '2049 bits',
616
					4096 => '4096 bits',
617
				)
618
			));
619

    
620
			$section->addInput(new Form_Input(
621
				'lifetime',
622
				'Lifetime',
623
				'number',
624
				$pconfig['lifetime']
625
			));
626
		}
627

    
628
		$form->add($section);
629
	}
630
}
631

    
632
$section = new Form_Section('Keys');
633

    
634
$section->addInput(new Form_Textarea(
635
	'authorizedkeys',
636
	'Authorized keys',
637
	'text',
638
	$pconfig['authorizedkeys']
639
))->setHelp('Paste an authorized keys file here.');
640

    
641
$section->addInput(new Form_Input(
642
	'ipsecpsk',
643
	'IPsec Pre-Shared Key',
644
	'text',
645
	$pconfig['ipsecpsk']
646
));
647

    
648
$form->add($section);
649
print $form;
650

    
651
include('foot.inc');
(211-211/237)