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

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

    
407
$section = new Form_Section('User Properties');
408

    
409
$section->addInput(new Form_StaticText(
410
	'Defined by',
411
	strtoupper($pconfig['utype'])
412
));
413

    
414
?>
415
<?php
416
$ro = false;
417
if ($pconfig['utype'] == "system")
418
	$ro = true;
419

    
420
$section->addInput(new Form_Checkbox(
421
	'disabled',
422
	'Disabled',
423
	'This user cannot login',
424
	$pconfig['disabled']
425
));
426

    
427
$section->addInput($input = new Form_Input(
428
	'usernamefld',
429
	'Username',
430
	'text',
431
	$pconfig['usernamefld']
432
));
433

    
434
if ($ro)
435
	$input->setAttribute('disabled', 'disabled');
436

    
437
$group = new Form_Group('Password');
438
$group->add(new Form_Input(
439
	'passwordfld1',
440
	'Password',
441
	'password'
442
));
443
$group->add(new Form_Input(
444
	'passwordfld2',
445
	'Confirm Password',
446
	'password'
447
));
448

    
449
$section->add($group);
450

    
451
$section->addInput($input = new Form_Input(
452
	'descr',
453
	'Full name',
454
	'text',
455
	htmlspecialchars($pconfig['descr'])
456
))->setHelp('User\'s full name, for your own information only');
457

    
458
if ($ro)
459
	$input->setAttribute('disabled', 'disabled');
460

    
461
$section->addInput(new Form_Input(
462
	'expires',
463
	'Expiration date',
464
	'date',
465
	$pconfig['expires']
466
))->setHelp('Leave blank if the account shouldn\'t expire, otherwise enter '.
467
	'the expiration date');
468

    
469
$systemGroups = array();
470
foreach ($config['system']['group'] as $group)
471
	$systemGroups[ $group['name'] ] = $group['name'];
472

    
473
$section->addInput(new Form_Select(
474
	'groups',
475
	'Group Memberships',
476
	array_combine((array)$pconfig['groups'], (array)$pconfig['groups']),
477
	$systemGroups,
478
	true
479
))->setHelp('Hold down CTRL (pc)/COMMAND (mac) key to select multiple items');
480

    
481
$form->add($section);
482

    
483
if (isset($pconfig['uid']))
484
{
485
	$section = new Form_Section('Effective Privileges');
486

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

    
498
		if ($priv['group'])
499
		{
500
			$group = new Form_Group('Inherited from '. $priv['group']);
501
			$input->setAttribute('disabled', 'disabled');
502
		}
503
		else
504
			$group = new Form_Group('Revoke privilege');
505

    
506
		$group->add($input);
507
		$section->add($group);
508
	}
509

    
510
	$section->addInput(new Form_StaticText(
511
		null,
512
		new Form_Button(null, 'grant more privileges', 'system_usermanager_addprivs.php?userid='. $id)
513
	));
514

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

    
517
	$section = new Form_Section('User Certificates');
518

    
519
	foreach ((array)$a_user[$id]['cert'] as $i => $certref)
520
	{
521
		$cert = lookup_cert($certref);
522
		$ca = lookup_ca($cert['caref']);
523

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

    
534
	#FIXME; old ui supplied direct export links to each certificate
535

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

    
548
		$nonPrvCas = array();
549
		foreach( $config['ca'] as $ca)
550
		{
551
			if (!$ca['prv'])
552
				continue;
553

    
554
			$nonPrvCas[ $ca['refid'] ] = $ca['descr'];
555
		}
556

    
557
		if (!empty($nonPrvCas))
558
		{
559
			$section->addInput(new Form_Input(
560
				'name',
561
				'Descriptive name',
562
				'text',
563
				$pconfig['name']
564
			));
565

    
566
			$section->addInput(new Form_Select(
567
				'caref',
568
				'Certificate authority',
569
				null,
570
				$nonPrvCas
571
			));
572

    
573
			$section->addInput(new Form_Select(
574
				'keylen',
575
				'Key length',
576
				2048,
577
				array(
578
					512 => '512 bits',
579
					1024 => '1024 bits',
580
					2048 => '2049 bits',
581
					4096 => '4096 bits',
582
				)
583
			));
584

    
585
			$section->addInput(new Form_Input(
586
				'lifetime',
587
				'Lifetime',
588
				'number',
589
				$pconfig['lifetime']
590
			));
591
		}
592

    
593
		$form->add($section);
594
	}
595
}
596

    
597
$section = new Form_Section('Keys');
598

    
599
$section->addInput(new Form_Textarea(
600
	'authorizedkeys',
601
	'Authorized keys',
602
	'text',
603
	$pconfig['authorizedkeys']
604
))->setHelp('Paste an authorized keys file here.');
605

    
606
$section->addInput(new Form_Input(
607
	'ipsecpsk',
608
	'IPsec Pre-Shared Key',
609
	'text',
610
	$pconfig['ipsecpsk']
611
));
612

    
613
$form->add($section);
614
print $form;
615

    
616
include('foot.inc');
(226-226/252)