Project

General

Profile

Download (22.4 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($_GET['userid']) && is_numericint($_GET['userid'])) {
64
	$id = $_GET['userid'];
65
}
66

    
67
if (!isset($config['system']['user']) || !is_array($config['system']['user'])) {
68
	$config['system']['user'] = array();
69
}
70

    
71
$a_user = &$config['system']['user'];
72
$act = $_GET['act'];
73

    
74
if (isset($_SERVER['HTTP_REFERER'])) {
75
	$referer = $_SERVER['HTTP_REFERER'];
76
} else {
77
	$referer = '/system_usermanager.php';
78
}
79

    
80
if (isset($id) && $a_user[$id]) {
81
	$pconfig['usernamefld'] = $a_user[$id]['name'];
82
	$pconfig['descr'] = $a_user[$id]['descr'];
83
	$pconfig['expires'] = $a_user[$id]['expires'];
84
	$pconfig['groups'] = local_user_get_groups($a_user[$id]);
85
	$pconfig['utype'] = $a_user[$id]['scope'];
86
	$pconfig['uid'] = $a_user[$id]['uid'];
87
	$pconfig['authorizedkeys'] = base64_decode($a_user[$id]['authorizedkeys']);
88
	$pconfig['priv'] = $a_user[$id]['priv'];
89
	$pconfig['ipsecpsk'] = $a_user[$id]['ipsecpsk'];
90
	$pconfig['disabled'] = isset($a_user[$id]['disabled']);
91
}
92

    
93
if ($_POST['act'] == "deluser") {
94

    
95
	if (!isset($_POST['username']) || !isset($a_user[$id]) || ($_POST['username'] != $a_user[$id]['name'])) {
96
		pfSenseHeader("system_usermanager.php");
97
		exit;
98
	}
99

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

    
119
if (isset($_POST['dellall_x'])) {
120

    
121
	$del_users = $_POST['delete_check'];
122

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

    
137
if ($_POST['save']) {
138
	unset($input_errors);
139
	$pconfig = $_POST;
140

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

    
163
	do_input_validation($_POST, $reqdfields, $reqdfieldsn, $input_errors);
164

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

    
169
	if (strlen($_POST['usernamefld']) > 16) {
170
		$input_errors[] = gettext("The username is longer than 16 characters.");
171
	}
172

    
173
	if (($_POST['passwordfld1']) && ($_POST['passwordfld1'] != $_POST['passwordfld2'])) {
174
		$input_errors[] = gettext("The passwords do not match.");
175
	}
176

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

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

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

    
225
	if (!empty($_POST['name'])) {
226
		$ca = lookup_ca($_POST['caref']);
227
		if (!$ca) {
228
			$input_errors[] = gettext("Invalid internal Certificate Authority") . "\n";
229
		}
230
	}
231

    
232
	/* if this is an AJAX caller then handle via JSON */
233
	if (isAjax() && is_array($input_errors)) {
234
		input_errors2Ajax($input_errors);
235
		exit;
236
	}
237

    
238
	if (!$input_errors) {
239
		// This used to be a separate act=delpriv
240
		if ($a_user[$id] && !empty($_POST['privid'])) {
241
			foreach ($_POST['privid'] as $i)
242
				unset($a_user[$id]['priv'][$i]);
243
			local_user_set($a_user[$id]);
244
			write_config();
245
		}
246

    
247
		// This used to be a separate act=delcert
248
		if ($a_user[$id] && !empty($_POST['certid'])) {
249
			foreach ($_POST['certid'] as $i)
250
				unset($a_user[$id]['cert'][$i]);
251

    
252
			write_config();
253
		}
254

    
255
		conf_mount_rw();
256
		$userent = array();
257
		if (isset($id) && $a_user[$id]) {
258
			$userent = $a_user[$id];
259
		}
260

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

    
263
		/* the user name was modified */
264
		if (!empty($_POST['oldusername']) && ($_POST['usernamefld'] <> $_POST['oldusername'])) {
265
			$_SERVER['REMOTE_USER'] = $_POST['usernamefld'];
266
			local_user_del($userent);
267
		}
268

    
269
		/* the user password was modified */
270
		if ($_POST['passwordfld1']) {
271
			local_user_set_password($userent, $_POST['passwordfld1']);
272
		}
273

    
274
		$userent['name'] = $_POST['usernamefld'];
275
		$userent['descr'] = $_POST['descr'];
276
		$userent['expires'] = $_POST['expires'];
277
		$userent['authorizedkeys'] = base64_encode($_POST['authorizedkeys']);
278
		$userent['ipsecpsk'] = $_POST['ipsecpsk'];
279

    
280
		if ($_POST['disabled']) {
281
			$userent['disabled'] = true;
282
		} else {
283
			unset($userent['disabled']);
284
		}
285

    
286
		if (isset($id) && $a_user[$id]) {
287
			$a_user[$id] = $userent;
288
		} else {
289
			if (!empty($_POST['name'])) {
290
				$cert = array();
291
				$cert['refid'] = uniqid();
292
				$userent['cert'] = array();
293

    
294
				$cert['descr'] = $_POST['name'];
295

    
296
				$subject = cert_get_subject_array($ca['crt']);
297

    
298
				$dn = array(
299
					'countryName' => $subject[0]['v'],
300
					'stateOrProvinceName' => $subject[1]['v'],
301
					'localityName' => $subject[2]['v'],
302
					'organizationName' => $subject[3]['v'],
303
					'emailAddress' => $subject[4]['v'],
304
					'commonName' => $userent['name']);
305

    
306
				cert_create($cert, $_POST['caref'], $_POST['keylen'],
307
					(int)$_POST['lifetime'], $dn);
308

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

    
327
			$a_user[] = $userent;
328
		}
329

    
330
		local_user_set($userent);
331
		local_user_set_groups($userent, $_POST['groups']);
332
		write_config();
333

    
334
		if (is_dir("/etc/inc/privhooks")) {
335
			run_plugins("/etc/inc/privhooks");
336
		}
337

    
338
		conf_mount_ro();
339

    
340
		pfSenseHeader("system_usermanager.php");
341
	}
342
}
343

    
344
function build_priv_table() {
345
	global $a_user, $id;
346

    
347
	$privhtml = '<div class="table-responsive">';
348
	$privhtml .=	'<table class="table table-striped table-hover table-condensed">';
349
	$privhtml .=		'<thead>';
350
	$privhtml .=			'<th>' . gettext('Inherited from') . '</th>';
351
	$privhtml .=			'<th>' . gettext('Name') . '</th>';
352
	$privhtml .=			'<th>' . gettext('Description') . '</th>';
353
	$privhtml .=		'</thead>';
354
	$privhtml .=		'<tbody>';
355

    
356
	foreach (get_user_privdesc($a_user[$id]) as $i => $priv) {
357
		$privhtml .=		'<tr>';
358
		$privhtml .=			'<td>' . htmlspecialchars($priv['group']) . '</td>';
359
		$privhtml .=			'<td>' . htmlspecialchars($priv['name']) . '</td>';
360
		$privhtml .=			'<td>' . htmlspecialchars($priv['descr']) . '</td>';
361
		$privhtml .=		'</tr>';
362
	}
363

    
364
	$privhtml .=		'</tbody>';
365
	$privhtml .=	'</table>';
366
	$privhtml .= '</div>';
367

    
368
	$privhtml .= '<nav class="action-buttons">';
369
	$privhtml .=	'<a href="system_usermanager_addprivs.php?userid=' . $id . '" class="btn btn-success">' . gettext("Add") . '</a>';
370
	$privhtml .= '</nav>';
371

    
372
	return($privhtml);
373
}
374

    
375
function build_cert_table() {
376
	global $a_user, $id;
377

    
378
	$certhtml = '<div class="table-responsive">';
379
	$certhtml .=	'<table class="table table-striped table-hover table-condensed">';
380
	$certhtml .=		'<thead>';
381
	$certhtml .=			'<th>' . gettext('Name') . '</th>';
382
	$certhtml .=			'<th>' . gettext('CA') . '</th>';
383
	$certhtml .=		'</thead>';
384
	$certhtml .=		'<tbody>';
385

    
386
	$a_cert = $a_user[$id]['cert'];
387
	if (is_array($a_cert)) {
388
		$i = 0;
389
		foreach ($a_cert as $certref) {
390
			$certhtml .=	'<tr>';
391
			$certhtml .=		'<td>' . htmlspecialchars($cert['descr']) . is_cert_revoked($cert) ? '<b> Revoked</b>':'' . '</td>';
392
			$certhtml .=		'<td>' . htmlspecialchars($ca['descr']) . '</td>';
393
			$certhtml .=	'</tr>';
394
		}
395
	}
396

    
397
	$certhtml .=		'</tbody>';
398
	$certhtml .=	'</table>';
399
	$certhtml .= '</div>';
400

    
401
	$certhtml .= '<nav class="action-buttons">';
402
	$certhtml .=	'<a href="system_certmanager.php?act=new&amp;userid=' . $id . '" class="btn btn-success">' . gettext("Add") . '</a>';
403
	$certhtml .= '</nav>';
404

    
405
	return($certhtml);
406
}
407

    
408
$closehead = false;
409
include("head.inc");
410

    
411
if ($input_errors)
412
	print_input_errors($input_errors);
413
if ($savemsg)
414
	print_info_box($savemsg);
415

    
416
$tab_array = array();
417
$tab_array[] = array(gettext("Users"), true, "system_usermanager.php");
418
$tab_array[] = array(gettext("Groups"), false, "system_groupmanager.php");
419
$tab_array[] = array(gettext("Settings"), false, "system_usermanager_settings.php");
420
$tab_array[] = array(gettext("Servers"), false, "system_authservers.php");
421
display_top_tabs($tab_array);
422

    
423
if (!($act == "new" || $act == "edit" || $input_errors)) {
424
?>
425

    
426
<div class="table-responsive">
427
	<table class="table table-striped table-hover">
428
		<thead>
429
			<tr>
430
				<th>&nbsp;</th>
431
				<th><?=gettext("Username")?></th>
432
				<th><?=gettext("Full name")?></th>
433
				<th><?=gettext("Disabled")?></th>
434
				<th><?=gettext("Groups")?></th>
435
			</tr>
436
		</thead>
437
		<tbody>
438
		</tbody>
439
		<tbody>
440
<?php
441
foreach($a_user as $i => $userent):
442
	?>
443
			<tr>
444
				<td>
445
					<input type="checkbox" id="frc<?=$i?>" name="delete_check[]" value="<?=$i?>" <?=($userent['scope'] == "system" ? 'disabled="disabled"' : '')?>/>
446
				</td>
447
				<td>
448
<?php
449
	if($userent['scope'] != "user")
450
		$usrimg = 'eye-open';
451
	else
452
		$usrimg = 'user';
453
?>
454
					<i class="icon icon-<?=$usrimg?>"></i>
455
					<?=htmlspecialchars($userent['name'])?>
456
				</td>
457
				<td><?=htmlspecialchars($userent['descr'])?></td>
458
				<td><?php if(isset($userent['disabled'])) echo "*"?></td>
459
				<td><?=implode(",",local_user_get_groups($userent))?></td>
460
				<td>
461
					<a href="?act=edit&amp;userid=<?=$i?>" class="btn btn-xs btn-primary">edit</a>
462
<?php if($userent['scope'] != "system"): ?>
463
					<a href="?act=del&amp;userid=<?=$i?>" class="btn btn-xs btn-danger">delete</a>
464
<?php endif; ?>
465
				</td>
466
			</tr>
467
<?php endforeach; ?>
468
		</tbody>
469
	</table>
470
</div>
471
<nav class="action-buttons">
472
	<a href="?act=new" class="btn btn-success">add new</a>
473
</nav>
474
<p>
475
	<?=gettext("Additional users can be added here. User permissions for accessing " .
476
	"the webConfigurator can be assigned directly or inherited from group memberships. " .
477
	"An icon that appears grey indicates that it is a system defined object. " .
478
	"Some system object properties can be modified but they cannot be deleted.")?>
479
	<br /><br />
480
	<?=gettext("Accounts created here are also used for other parts of the system " .
481
	"such as OpenVPN, IPsec, and Captive Portal.")?>
482
</p>
483
<?php
484
	include("foot.inc");
485
	exit;
486
}
487

    
488
require('classes/Form.class.php');
489
$form = new Form;
490

    
491
if ($act == "new" || $act == "edit" || $input_errors):
492

    
493

    
494
	$form->addGlobal(new Form_Input(
495
		'act',
496
		null,
497
		'hidden',
498
		''
499
	));
500

    
501
	$form->addGlobal(new Form_Input(
502
		'userid',
503
		null,
504
		'hidden',
505
		isset($id) ? $id:''
506
	));
507

    
508
	$form->addGlobal(new Form_Input(
509
		'privid',
510
		null,
511
		'hidden',
512
		''
513
	));
514

    
515
	$form->addGlobal(new Form_Input(
516
		'certid',
517
		null,
518
		'hidden',
519
		''
520
	));
521

    
522
	$ro = "";
523
	if ($pconfig['utype'] == "system") {
524
		$ro = "readonly=\"readonly\"";
525
	}
526

    
527
	$section = new Form_Section('User Properties');
528

    
529
	$section->addInput(new Form_StaticText(
530
		'Defined by',
531
		strtoupper($pconfig['utype'])
532
	));
533

    
534
	$form->addGlobal(new Form_Input(
535
		'utype',
536
		null,
537
		'hidden',
538
		$pconfig['utype']
539
	));
540

    
541
	$section->addInput(new Form_Checkbox(
542
		'disabled',
543
		'Disabled',
544
		'This user cannot login',
545
		$pconfig['disabled']
546
	));
547

    
548
	$section->addInput($input = new Form_Input(
549
		'usernamefld',
550
		'Username',
551
		'text',
552
		$pconfig['usernamefld']
553
	));
554

    
555
	if ($ro)
556
		$input->setDisabled();
557

    
558
	$form->addGlobal(new Form_Input(
559
		'oldusername',
560
		null,
561
		'hidden',
562
		$pconfig['usernamefld']
563
	));
564

    
565
	$group = new Form_Group('Password');
566
	$group->add(new Form_Input(
567
		'passwordfld1',
568
		'Password',
569
		'password'
570
	));
571
	$group->add(new Form_Input(
572
		'passwordfld2',
573
		'Confirm Password',
574
		'password'
575
	));
576

    
577
	$section->add($group);
578

    
579
	$section->addInput($input = new Form_Input(
580
		'descr',
581
		'Full name',
582
		'text',
583
		htmlspecialchars($pconfig['descr'])
584
	))->setHelp('User\'s full name, for your own information only');
585

    
586
	if ($ro)
587
		$input->setDisabled();
588

    
589
	$section->addInput(new Form_Input(
590
		'expires',
591
		'Expiration date',
592
		'date',
593
		$pconfig['expires']
594
	))->setHelp('Leave blank if the account shouldn\'t expire, otherwise enter '.
595
		'the expiration date');
596

    
597
	// ==== Group membership ==================================================
598
	$group = new Form_Group('Group membership');
599

    
600
	// Make a list of all the groups configured on the system, and a list of 
601
	// those which this user is a member of
602
	$systemGroups = array();
603
	$usersGroups = array();
604

    
605
	$usergid = [$pconfig['usernamefld']];
606

    
607
	foreach ($config['system']['group'] as $Ggroup) {
608
		if(($act == 'edit') && $Ggroup['member'] && in_array($pconfig['uid'], $Ggroup['member']))
609
			$usersGroups[ $Ggroup['name'] ] = $Ggroup['name'];	// Add it to the user's list
610
		else
611
			$systemGroups[ $Ggroup['name'] ] = $Ggroup['name']; // Add it to the 'not a member of' list
612
	}
613

    
614
	$group->add(new Form_Select(
615
		'sysgroups',
616
		null,
617
		array_combine((array)$pconfig['groups'], (array)$pconfig['groups']),
618
		$systemGroups,
619
		true
620
	))->setHelp('Not member of');
621

    
622
	$group->add(new Form_Select(
623
		'groups',
624
		null,
625
		array_combine((array)$pconfig['groups'], (array)$pconfig['groups']),
626
		$usersGroups,
627
		true
628
	))->setHelp('Member of');
629

    
630
	$section->add($group);
631

    
632
	$group = new Form_Group('');
633

    
634
	$group->add(new Form_Button(
635
		'movetoenabled',
636
		'Move to "Member of" list >'
637
	))->removeClass('btn-primary')->addClass('btn-default btn-sm');
638

    
639
	$group->add(new Form_Button(
640
		'movetodisabled',
641
		'< Move to "Not member of" list'
642
	))->removeClass('btn-primary')->addClass('btn-default btn-sm');
643

    
644
	$group->setHelp('Hold down CTRL (pc)/COMMAND (mac) key to select multiple items');
645
	$section->add($group);
646

    
647
	// ==== Button for adding user certificate ================================
648
	if($act == 'new') {
649
		$section->addInput(new Form_Checkbox(
650
			'showcert',
651
			'Certificate',
652
			'Click to create a user certificate',
653
			false
654
		));
655
	}
656

    
657
	$form->add($section);
658

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

    
664
		$section = new Form_Section('Effective Privileges');
665

    
666
		$section->addInput(new Form_StaticText(
667
			null,
668
			build_priv_table()
669
		));
670

    
671
		$form->add($section);
672

    
673
		// ==== Certificate table section =====================================
674
		$section = new Form_Section('User certificates');
675

    
676
		$section->addInput(new Form_StaticText(
677
			null,
678
			build_cert_table()
679
		));
680

    
681
		$form->add($section);
682
	}
683
else;
684
		$section = new Form_Section('User Certificates');
685

    
686
		foreach ((array)$a_user[$id]['cert'] as $i => $certref) {
687
			$cert = lookup_cert($certref);
688
			$ca = lookup_ca($cert['caref']);
689

    
690
			// We reverse name and action for readability of longer names
691
			$section->addInput(new Form_Checkbox(
692
				'certid[]',
693
				'Delete certificate',
694
				$cert['descr']. (is_cert_revoked($cert) ? ' <b>revoked</b>' : ''),
695
				false,
696
				$i
697
			));
698
		}
699

    
700
		#FIXME; old ui supplied direct export links to each certificate
701

    
702
		$section->addInput(new Form_StaticText(
703
			null,
704
			new Form_Button(null, 'add certificate', 'system_certmanager.php?act=new&userid='. $id).
705
			new Form_Button(null, 'export certificates', 'system_certmanager.php')
706
		));
707

    
708
		// ==== Add user certificate for a new user
709
		if (is_array($config['ca']) && count($config['ca']) > 0) {
710
			$section = new Form_Section('Create certificate for user');
711
			$section->addClass('cert-options');
712

    
713
			$nonPrvCas = array();
714
			foreach( $config['ca'] as $ca) {
715
				if (!$ca['prv'])
716
					continue;
717

    
718
				$nonPrvCas[ $ca['refid'] ] = $ca['descr'];
719
			}
720

    
721
			if (!empty($nonPrvCas)) {
722
				$section->addInput(new Form_Input(
723
					'name',
724
					'Descriptive name',
725
					'text',
726
					$pconfig['name']
727
				));
728

    
729
				$section->addInput(new Form_Select(
730
					'caref',
731
					'Certificate authority',
732
					null,
733
					$nonPrvCas
734
				));
735

    
736
				$section->addInput(new Form_Select(
737
					'keylen',
738
					'Key length',
739
					2048,
740
					array(
741
						512 => '512 bits',
742
						1024 => '1024 bits',
743
						2048 => '2049 bits',
744
						4096 => '4096 bits',
745
					)
746
				));
747

    
748
				$section->addInput(new Form_Input(
749
					'lifetime',
750
					'Lifetime',
751
					'number',
752
					$pconfig['lifetime']
753
				));
754
			}
755

    
756
			$form->add($section);
757
		}
758

    
759
endif;
760
// ==== Paste a key for the new user
761
$section = new Form_Section('Keys');
762

    
763
$section->addInput(new Form_Textarea(
764
	'authorizedkeys',
765
	'Authorized keys',
766
	$pconfig['authorizedkeys']
767
))->setHelp('Paste an authorized keys file here.');
768

    
769
$group = new Form_Group('IPsec Pre-Shared Key');
770

    
771
$group->add(new Form_Input(
772
	'ipsecpsk',
773
	'IPsec Pre-Shared Key',
774
	'text',
775
	$pconfig['ipsecpsk']
776
));
777

    
778
$group->add(new Form_Checkbox(
779
	'showkey',
780
	'Authorized keys',
781
	'Click to paste an authorized key',
782
	false
783
));
784

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

    
788
print $form;
789
?>
790
<script>
791
//<![CDATA[
792
events.push(function(){
793
	// Hides all elements of the specified class.
794
	function hideClass(s_class, hide) {
795
		if(hide)
796
			$('.' + s_class).hide();
797
		else
798
			$('.' + s_class).show();
799
	}
800

    
801
	// Hides the <div> in which the specified input element lives so that the input, its label and help text are hidden
802
	function hideInput(id, hide) {
803
		if(hide)
804
			$('#' + id).parent().parent('div').addClass('hidden');
805
		else
806
			$('#' + id).parent().parent('div').removeClass('hidden');
807
	}
808

    
809
	// Select every option in the specified multiselect
810
	function AllServers(id, selectAll) {
811
	   for (i = 0; i < id.length; i++)	   {
812
		   id.eq(i).prop('selected', selectAll);
813
	   }
814
	}
815

    
816
	// Move all selected options from one multiselect to another
817
	function moveOptions(From, To)	{
818
		var len = From.length;
819
		var option;
820

    
821
		if(len > 1) {
822
			for(i=0; i<len; i++) {
823
				if(From.eq(i).is(':selected')) {
824
					option = From.eq(i).val();
825
					To.append(new Option(option, option));
826
					From.eq(i).remove();
827
				}
828
			}
829
		}
830
	}
831

    
832
	// Make buttons plain buttons, not submit
833
	$("#movetodisabled").prop('type','button');
834
	$("#movetoenabled").prop('type','button');
835

    
836

    
837
	// On click . .
838
	$("#movetodisabled").click(function() {
839
		moveOptions($('[name="groups[]"] option'), $('[name="sysgroups[]"]'));
840
	});
841

    
842
	$("#movetoenabled").click(function() {
843
		moveOptions($('[name="sysgroups[]"] option'), $('[name="groups[]"]'));
844
	});
845

    
846
	$("#showcert").click(function() {
847
		hideClass('cert-options', !this.checked);
848
	});
849

    
850
	$("#showkey").click(function() {
851
		hideInput('authorizedkeys', !this.checked);
852
	});
853

    
854
	// On page load . .
855
   hideClass('cert-options', true);
856
   hideInput('authorizedkeys', true);
857

    
858
	// On submit mark all the user's groups as "selected"
859
	$('form').submit(function(){
860
		AllServers($('[name="groups[]"] option'), true);
861
	});
862
});
863
//]]>
864
</script>
865
<?php
866

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