Project

General

Profile

Download (16.1 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

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

    
60
if (isset($_POST['userid']) && is_numericint($_POST['userid']))
61
	$id = $_POST['userid'];
62
else if (isset($_GET['userid']) && is_numericint($_GET['userid']))
63
	$id = $_GET['userid'];
64

    
65
if (!isset($config['system']['user']) || !is_array($config['system']['user']))
66
	$config['system']['user'] = array();
67

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

    
70
if (isset($_SERVER['HTTP_REFERER']))
71
	$referer = $_SERVER['HTTP_REFERER'];
72
else
73
	$referer = '/system_usermanager.php';
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 ($_POST['save']) {
115
	unset($input_errors);
116
	$pconfig = $_POST;
117

    
118
	/* input validation */
119
	if (isset($id) && ($a_user[$id])) {
120
		$reqdfields = explode(" ", "usernamefld");
121
		$reqdfieldsn = array(gettext("Username"));
122
	} else {
123
		if (empty($_POST['name'])) {
124
			$reqdfields = explode(" ", "usernamefld passwordfld1");
125
			$reqdfieldsn = array(
126
				gettext("Username"),
127
				gettext("Password"));
128
		} else {
129
			$reqdfields = explode(" ", "usernamefld passwordfld1 name caref keylen lifetime");
130
			$reqdfieldsn = array(
131
				gettext("Username"),
132
				gettext("Password"),
133
				gettext("Descriptive name"),
134
				gettext("Certificate authority"),
135
				gettext("Key length"),
136
				gettext("Lifetime"));
137
		}
138
	}
139

    
140
	do_input_validation($_POST, $reqdfields, $reqdfieldsn, $input_errors);
141

    
142
	if (preg_match("/[^a-zA-Z0-9\.\-_]/", $_POST['usernamefld']))
143
		$input_errors[] = gettext("The username contains invalid characters.");
144

    
145
	if (strlen($_POST['usernamefld']) > 16)
146
		$input_errors[] = gettext("The username is longer than 16 characters.");
147

    
148
	if (($_POST['passwordfld1']) && ($_POST['passwordfld1'] != $_POST['passwordfld2']))
149
		$input_errors[] = gettext("The passwords do not match.");
150

    
151
	if (isset($_POST['ipsecpsk']) && !preg_match('/^[[:ascii:]]*$/', $_POST['ipsecpsk']))
152
		$input_errors[] = gettext("IPsec Pre-Shared Key contains invalid characters.");
153

    
154
	if (isset($id) && $a_user[$id])
155
		$oldusername = $a_user[$id]['name'];
156
	else
157
		$oldusername = "";
158
	/* make sure this user name is unique */
159
	if (!$input_errors) {
160
		foreach ($a_user as $userent) {
161
			if ($userent['name'] == $_POST['usernamefld'] && $oldusername != $_POST['usernamefld']) {
162
				$input_errors[] = gettext("Another entry with the same username already exists.");
163
				break;
164
			}
165
		}
166
	}
167
	/* also make sure it is not reserved */
168
	if (!$input_errors) {
169
		$system_users = explode("\n", file_get_contents("/etc/passwd"));
170
		foreach ($system_users as $s_user) {
171
			$ent = explode(":", $s_user);
172
			if ($ent[0] == $_POST['usernamefld'] && $oldusername != $_POST['usernamefld']) {
173
				$input_errors[] = gettext("That username is reserved by the system.");
174
				break;
175
			}
176
		}
177
	}
178

    
179
	/*
180
	 * Check for a valid expiration date if one is set at all (valid means,
181
	 * DateTime puts out a time stamp so any DateTime compatible time
182
	 * format may be used. to keep it simple for the enduser, we only
183
	 * claim to accept MM/DD/YYYY as inputs. Advanced users may use inputs
184
	 * like "+1 day", which will be converted to MM/DD/YYYY based on "now".
185
	 * Otherwise such an entry would lead to an invalid expiration data.
186
	 */
187
	if ($_POST['expires']){
188
		try {
189
			$expdate = new DateTime($_POST['expires']);
190
			//convert from any DateTime compatible date to MM/DD/YYYY
191
			$_POST['expires'] = $expdate->format("m/d/Y");
192
		} catch ( Exception $ex ) {
193
			$input_errors[] = gettext("Invalid expiration date format; use MM/DD/YYYY instead.");
194
		}
195
	}
196

    
197
	if (!empty($_POST['name'])) {
198
		$ca = lookup_ca($_POST['caref']);
199
		if (!$ca)
200
			$input_errors[] = gettext("Invalid internal Certificate Authority") . "\n";
201
	}
202

    
203
	/* if this is an AJAX caller then handle via JSON */
204
	if (isAjax() && is_array($input_errors)) {
205
		input_errors2Ajax($input_errors);
206
		exit;
207
	}
208

    
209
	if (!$input_errors) {
210
		// This used to be a separate act=delpriv
211
		if ($a_user[$id] && !empty($_POST['privid'])) {
212
			foreach ($_POST['privid'] as $i)
213
				unset($a_user[$id]['priv'][$i]);
214
			local_user_set($a_user[$id]);
215
			write_config();
216
		}
217

    
218
		// This used to be a separate act=delcert
219
		if ($a_user[$id] && !empty($_POST['certid'])) {
220
			foreach ($_POST['certid'] as $i)
221
				unset($a_user[$id]['cert'][$i]);
222

    
223
			write_config();
224
		}
225

    
226
		conf_mount_rw();
227
		$userent = array();
228
		if (isset($id) && $a_user[$id])
229
			$userent = $a_user[$id];
230

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

    
233
		/* the user name was modified */
234
		if (!empty($_POST['oldusername']) && ($_POST['usernamefld'] <> $_POST['oldusername'])) {
235
			$_SERVER['REMOTE_USER'] = $_POST['usernamefld'];
236
			local_user_del($userent);
237
		}
238

    
239
		/* the user password was modified */
240
		if ($_POST['passwordfld1'])
241
			local_user_set_password($userent, $_POST['passwordfld1']);
242

    
243
		$userent['name'] = $_POST['usernamefld'];
244
		$userent['descr'] = $_POST['descr'];
245
		$userent['expires'] = $_POST['expires'];
246
		$userent['authorizedkeys'] = base64_encode($_POST['authorizedkeys']);
247
		$userent['ipsecpsk'] = $_POST['ipsecpsk'];
248

    
249
		if($_POST['disabled'])
250
			$userent['disabled'] = true;
251
		else
252
			unset($userent['disabled']);
253

    
254
		if (isset($id) && $a_user[$id])
255
			$a_user[$id] = $userent;
256
		else {
257
			if (!empty($_POST['name'])) {
258
				$cert = array();
259
				$cert['refid'] = uniqid();
260
				$userent['cert'] = array();
261

    
262
				$cert['descr'] = $_POST['name'];
263

    
264
				$subject = cert_get_subject_array($ca['crt']);
265

    
266
				$dn = array(
267
					'countryName' => $subject[0]['v'],
268
					'stateOrProvinceName' => $subject[1]['v'],
269
					'localityName' => $subject[2]['v'],
270
					'organizationName' => $subject[3]['v'],
271
					'emailAddress' => $subject[4]['v'],
272
					'commonName' => $userent['name']);
273

    
274
				cert_create($cert, $_POST['caref'], $_POST['keylen'],
275
					(int)$_POST['lifetime'], $dn);
276

    
277
				if (!is_array($config['cert']))
278
					$config['cert'] = array();
279
				$config['cert'][] = $cert;
280
				$userent['cert'][] = $cert['refid'];
281
			}
282
			$userent['uid'] = $config['system']['nextuid']++;
283
			/* Add the user to All Users group. */
284
			foreach ($config['system']['group'] as $gidx => $group) {
285
				if ($group['name'] == "all") {
286
					if (!is_array($config['system']['group'][$gidx]['member']))
287
						$config['system']['group'][$gidx]['member'] = array();
288
					$config['system']['group'][$gidx]['member'][] = $userent['uid'];
289
					break;
290
				}
291
			}
292

    
293
			$a_user[] = $userent;
294
		}
295

    
296
		local_user_set($userent);
297
		local_user_set_groups($userent,$_POST['groups']);
298
		write_config();
299

    
300
		if(is_dir("/etc/inc/privhooks"))
301
			run_plugins("/etc/inc/privhooks");
302

    
303
		conf_mount_ro();
304

    
305
		pfSenseHeader("system_usermanager.php");
306
	}
307
}
308

    
309
$closehead = false;
310
include("head.inc");
311

    
312
if ($input_errors)
313
	print_input_errors($input_errors);
314
if ($savemsg)
315
	print_info_box($savemsg);
316

    
317
$tab_array = array();
318
$tab_array[] = array(gettext("Users"), true, "system_usermanager.php");
319
$tab_array[] = array(gettext("Groups"), false, "system_groupmanager.php");
320
$tab_array[] = array(gettext("Settings"), false, "system_usermanager_settings.php");
321
$tab_array[] = array(gettext("Servers"), false, "system_authservers.php");
322
display_top_tabs($tab_array);
323

    
324
if (!($_GET['act'] == "new" || $_GET['act'] == "edit" || $input_errors))
325
{
326
?>
327

    
328
<div class="table-responsive">
329
<table class="table table-striped table-hover">
330
	<thead>
331
		<tr>
332
			<th>&nbsp;</th>
333
			<th><?=gettext("Username")?></th>
334
			<th><?=gettext("Full name")?></th>
335
			<th><?=gettext("Disabled")?></th>
336
			<th><?=gettext("Groups")?></th>
337
		</tr>
338
	</thead>
339
	<tbody>
340
	</tbody>
341
	<tbody>
342
<?php
343
foreach($a_user as $i => $userent):
344
	?>
345
	<tr>
346
		<td>
347
			<input type="checkbox" id="frc<?=$i?>" name="delete_check[]" value="<?=$i?>" <?=($userent['scope'] == "system" ? 'disabled="disabled"' : '')?>/>
348
		</td>
349
		<td>
350
<?php
351
	if($userent['scope'] != "user")
352
		$usrimg = 'eye-open';
353
	else
354
		$usrimg = 'user';
355
?>
356
			<i class="icon icon-<?=$usrimg?>"></i>
357
			<?=htmlspecialchars($userent['name'])?>
358
		</td>
359
		<td><?=htmlspecialchars($userent['descr'])?></td>
360
		<td><?php if(isset($userent['disabled'])) echo "*"?></td>
361
		<td><?=implode(",",local_user_get_groups($userent))?></td>
362
		<td>
363
			<a href="?act=edit&amp;userid=<?=$i?>" class="btn btn-xs btn-primary">edit</a>
364
<?php if($userent['scope'] != "system"): ?>
365
			<a href="?act=del&amp;userid=<?=$i?>" class="btn btn-xs btn-danger">delete</a>
366
<?php endif; ?>
367
		</td>
368
	</tr>
369
<?php endforeach; ?>
370
	</tbody>
371
</table>
372
</div>
373
<nav class="action-buttons">
374
	<a href="?act=new" class="btn btn-success">add new</a>
375
</nav>
376
<p>
377
	<?=gettext("Additional users can be added here. User permissions for accessing " .
378
	"the webConfigurator can be assigned directly or inherited from group memberships. " .
379
	"An icon that appears grey indicates that it is a system defined object. " .
380
	"Some system object properties can be modified but they cannot be deleted.")?>
381
	<br /><br />
382
	<?=gettext("Accounts created here are also used for other parts of the system " .
383
	"such as OpenVPN, IPsec, and Captive Portal.")?>
384
</p>
385
<?php
386
	include("foot.inc");
387
	exit;
388
}
389

    
390
require('classes/Form.class.php');
391
$form = new Form;
392
$form->setAction('system_usermanager.php?act=edit');
393
$form->addGlobal(new Form_Input(
394
	'userid',
395
	null,
396
	'hidden',
397
	$id
398
));
399
$form->addGlobal(new Form_Input(
400
	'utype',
401
	null,
402
	'hidden',
403
	$pconfig['utype']
404
));
405
$form->addGlobal(new Form_Input(
406
	'oldusername',
407
	null,
408
	'hidden',
409
	$pconfig['usernamefld']
410
));
411

    
412
$section = new Form_Section('User Properties');
413

    
414
$section->addInput(new Form_StaticText(
415
	'Defined by',
416
	strtoupper($pconfig['utype'])
417
));
418

    
419
?>
420
<?php
421
$ro = false;
422
if ($pconfig['utype'] == "system")
423
	$ro = true;
424

    
425
$section->addInput(new Form_Checkbox(
426
	'disabled',
427
	'Disabled',
428
	'This user cannot login',
429
	$pconfig['disabled']
430
));
431

    
432
$section->addInput($input = new Form_Input(
433
	'usernamefld',
434
	'Username',
435
	'text',
436
	$pconfig['usernamefld']
437
));
438

    
439
if ($ro)
440
	$input->setDisabled();
441

    
442
$group = new Form_Group('Password');
443
$group->add(new Form_Input(
444
	'passwordfld1',
445
	'Password',
446
	'password'
447
));
448
$group->add(new Form_Input(
449
	'passwordfld2',
450
	'Confirm Password',
451
	'password'
452
));
453

    
454
$section->add($group);
455

    
456
$section->addInput($input = new Form_Input(
457
	'descr',
458
	'Full name',
459
	'text',
460
	htmlspecialchars($pconfig['descr'])
461
))->setHelp('User\'s full name, for your own information only');
462

    
463
if ($ro)
464
	$input->setDisabled();
465

    
466
$section->addInput(new Form_Input(
467
	'expires',
468
	'Expiration date',
469
	'date',
470
	$pconfig['expires']
471
))->setHelp('Leave blank if the account shouldn\'t expire, otherwise enter '.
472
	'the expiration date');
473

    
474
$systemGroups = array();
475
foreach ($config['system']['group'] as $group)
476
	$systemGroups[ $group['name'] ] = $group['name'];
477

    
478
$section->addInput(new Form_Select(
479
	'groups',
480
	'Group Memberships',
481
	array_combine((array)$pconfig['groups'], (array)$pconfig['groups']),
482
	$systemGroups,
483
	true
484
))->setHelp('Hold down CTRL (pc)/COMMAND (mac) key to select multiple items');
485

    
486
$form->add($section);
487

    
488
if (isset($pconfig['uid']))
489
{
490
	$section = new Form_Section('Effective Privileges');
491

    
492
	foreach (get_user_privdesc($a_user[$id]) as $i => $priv)
493
	{
494
		// We reverse name and action for readability of longer names
495
		$input = new Form_Checkbox(
496
			'privid[]',
497
			null,
498
			$priv['name'],
499
			false,
500
			$i
501
		);
502

    
503
		if ($priv['group'])
504
		{
505
			$group = new Form_Group('Inherited from '. $priv['group']);
506
			$input->setDisabled();
507
		}
508
		else
509
			$group = new Form_Group('Revoke privilege');
510

    
511
		$group->add($input);
512
		$section->add($group);
513
	}
514

    
515
	$section->addInput(new Form_StaticText(
516
		null,
517
		new Form_Button(null, 'grant more privileges', 'system_usermanager_addprivs.php?userid='. $id)
518
	));
519

    
520
	$form->add($section);
521

    
522
	$section = new Form_Section('User Certificates');
523

    
524
	foreach ((array)$a_user[$id]['cert'] as $i => $certref)
525
	{
526
		$cert = lookup_cert($certref);
527
		$ca = lookup_ca($cert['caref']);
528

    
529
		// We reverse name and action for readability of longer names
530
		$section->addInput(new Form_Checkbox(
531
			'certid[]',
532
			'Delete certificate',
533
			$cert['descr']. (is_cert_revoked($cert) ? ' <b>revoked</b>' : ''),
534
			false,
535
			$i
536
		));
537
	}
538

    
539
	#FIXME; old ui supplied direct export links to each certificate
540

    
541
	$section->addInput(new Form_StaticText(
542
		null,
543
		new Form_Button(null, 'add certificate', 'system_certmanager.php?act=new&userid='. $id).
544
		new Form_Button(null, 'export certificates', 'system_certmanager.php')
545
	));
546
}
547
else
548
{
549
	if (is_array($config['ca']) && count($config['ca']) > 0)
550
	{
551
		$section = new Form_Section('Create certificate for user');
552

    
553
		$nonPrvCas = array();
554
		foreach( $config['ca'] as $ca)
555
		{
556
			if (!$ca['prv'])
557
				continue;
558

    
559
			$nonPrvCas[ $ca['refid'] ] = $ca['descr'];
560
		}
561

    
562
		if (!empty($nonPrvCas))
563
		{
564
			$section->addInput(new Form_Input(
565
				'name',
566
				'Descriptive name',
567
				'text',
568
				$pconfig['name']
569
			));
570

    
571
			$section->addInput(new Form_Select(
572
				'caref',
573
				'Certificate authority',
574
				null,
575
				$nonPrvCas
576
			));
577

    
578
			$section->addInput(new Form_Select(
579
				'keylen',
580
				'Key length',
581
				2048,
582
				array(
583
					512 => '512 bits',
584
					1024 => '1024 bits',
585
					2048 => '2049 bits',
586
					4096 => '4096 bits',
587
				)
588
			));
589

    
590
			$section->addInput(new Form_Input(
591
				'lifetime',
592
				'Lifetime',
593
				'number',
594
				$pconfig['lifetime']
595
			));
596
		}
597

    
598
		$form->add($section);
599
	}
600
}
601

    
602
$section = new Form_Section('Keys');
603

    
604
$section->addInput(new Form_Textarea(
605
	'authorizedkeys',
606
	'Authorized keys',
607
	'text',
608
	$pconfig['authorizedkeys']
609
))->setHelp('Paste an authorized keys file here.');
610

    
611
$section->addInput(new Form_Input(
612
	'ipsecpsk',
613
	'IPsec Pre-Shared Key',
614
	'text',
615
	$pconfig['ipsecpsk']
616
));
617

    
618
$form->add($section);
619
print $form;
620

    
621
include('foot.inc');
(215-215/241)