Project

General

Profile

Download (14.4 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php
2
/*
3
 * system_groupmanager.php
4
 *
5
 * part of pfSense (https://www.pfsense.org)
6
 * Copyright (c) 2004-2016 Rubicon Communications, LLC (Netgate)
7
 * Copyright (c) 2005 Paul Taylor <paultaylor@winn-dixie.com>
8
 * Copyright (c) 2008 Shrew Soft Inc
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-groupmanager
62
##|*NAME=System: Group Manager
63
##|*DESCR=Allow access to the 'System: Group Manager' page.
64
##|*MATCH=system_groupmanager.php*
65
##|-PRIV
66

    
67
require_once("guiconfig.inc");
68

    
69
if (!is_array($config['system']['group'])) {
70
	$config['system']['group'] = array();
71
}
72

    
73
$a_group = &$config['system']['group'];
74

    
75
unset($id);
76

    
77
if (isset($_POST['groupid']) && is_numericint($_POST['groupid'])) {
78
	$id = $_POST['groupid'];
79
}
80

    
81
if (isset($_GET['groupid']) && is_numericint($_GET['groupid'])) {
82
	$id = $_GET['groupid'];
83
}
84

    
85
$act = (isset($_GET['act']) ? $_GET['act'] : '');
86

    
87
function cpusercmp($a, $b) {
88
	return strcasecmp($a['name'], $b['name']);
89
}
90

    
91
function admin_groups_sort() {
92
	global $a_group;
93

    
94
	if (!is_array($a_group)) {
95
		return;
96
	}
97

    
98
	usort($a_group, "cpusercmp");
99
}
100

    
101
if ($act == "delgroup") {
102

    
103
	if (!isset($id) || !isset($_GET['groupname']) || !isset($a_group[$id]) || ($_GET['groupname'] != $a_group[$id]['name'])) {
104
		pfSenseHeader("system_groupmanager.php");
105
		exit;
106
	}
107

    
108
	conf_mount_rw();
109
	local_group_del($a_group[$id]);
110
	conf_mount_ro();
111
	$groupdeleted = $a_group[$id]['name'];
112
	unset($a_group[$id]);
113
	write_config();
114
	$savemsg = sprintf(gettext("Group %s successfully deleted."), $groupdeleted);
115
}
116

    
117
if ($act == "delpriv") {
118

    
119
	if (!isset($id) || !isset($a_group[$id])) {
120
		pfSenseHeader("system_groupmanager.php");
121
		exit;
122
	}
123

    
124
	$privdeleted = $priv_list[$a_group[$id]['priv'][$_POST['privid']]]['name'];
125
	unset($a_group[$id]['priv'][$_GET['privid']]);
126

    
127
	if (is_array($a_group[$id]['member'])) {
128
		foreach ($a_group[$id]['member'] as $uid) {
129
			$user = getUserEntryByUID($uid);
130
			if ($user) {
131
				local_user_set($user);
132
			}
133
		}
134
	}
135

    
136
	write_config();
137
	$act = "edit";
138
	$savemsg = sprintf(gettext("Privilege %s successfully deleted."), $privdeleted);
139
}
140

    
141
if ($act == "edit") {
142
	if (isset($id) && isset($a_group[$id])) {
143
		$pconfig['name'] = $a_group[$id]['name'];
144
		$pconfig['gid'] = $a_group[$id]['gid'];
145
		$pconfig['gtype'] = empty($a_group[$id]['scope']) ? "local" : $a_group[$id]['scope'];
146
		$pconfig['description'] = $a_group[$id]['description'];
147
		$pconfig['members'] = $a_group[$id]['member'];
148
		$pconfig['priv'] = $a_group[$id]['priv'];
149
	}
150
}
151

    
152
if (isset($_GET['dellall_x'])) {
153

    
154
	$del_groups = $_GET['delete_check'];
155

    
156
	if (!empty($del_groups)) {
157
		foreach ($del_groups as $groupid) {
158
			if (isset($a_group[$groupid]) && $a_group[$groupid]['scope'] != "system") {
159
				conf_mount_rw();
160
				local_group_del($a_group[$groupid]);
161
				conf_mount_ro();
162
				unset($a_group[$groupid]);
163
			}
164
		}
165
		$savemsg = gettext("Selected groups removed successfully.");
166
		write_config($savemsg);
167
	}
168
}
169

    
170
if (isset($_POST['save'])) {
171
	unset($input_errors);
172
	$pconfig = $_POST;
173

    
174
	/* input validation */
175
	$reqdfields = explode(" ", "groupname");
176
	$reqdfieldsn = array(gettext("Group Name"));
177

    
178
	do_input_validation($_POST, $reqdfields, $reqdfieldsn, $input_errors);
179

    
180
	if ($_POST['gtype'] != "remote") {
181
		if (preg_match("/[^a-zA-Z0-9\.\-_]/", $_POST['groupname'])) {
182
			$input_errors[] = sprintf(gettext("The (%s) group name contains invalid characters."), $_POST['gtype']);
183
		}
184
	} else {
185
		if (preg_match("/[^a-zA-Z0-9\.\- _]/", $_POST['groupname'])) {
186
			$input_errors[] = sprintf(gettext("The (%s) group name contains invalid characters."), $_POST['gtype']);
187
		}
188
	}
189

    
190
	if (strlen($_POST['groupname']) > 16) {
191
		$input_errors[] = gettext("The group name is longer than 16 characters.");
192
	}
193

    
194
	/* Check the POSTed members to ensure they are valid and exist */
195
	if (is_array($_POST['members'])) {
196
		foreach ($_POST['members'] as $newmember) {
197
			if (!is_numeric($newmember) || empty(getUserEntryByUID($newmember))) {
198
				$input_errors[] = gettext("One or more invalid group members was submitted.");
199
			}
200
		}
201
	}
202

    
203
	if (!$input_errors && !(isset($id) && $a_group[$id])) {
204
		/* make sure there are no dupes */
205
		foreach ($a_group as $group) {
206
			if ($group['name'] == $_POST['groupname']) {
207
				$input_errors[] = gettext("Another entry with the same group name already exists.");
208
				break;
209
			}
210
		}
211
	}
212

    
213
	if (!$input_errors) {
214
		$group = array();
215
		if (isset($id) && $a_group[$id]) {
216
			$group = $a_group[$id];
217
		}
218

    
219
		$group['name'] = $_POST['groupname'];
220
		$group['description'] = $_POST['description'];
221
		$group['scope'] = $_POST['gtype'];
222

    
223
		if (empty($_POST['members'])) {
224
			unset($group['member']);
225
		} else if ($group['gid'] != 1998) { // all group
226
			$group['member'] = $_POST['members'];
227
		}
228

    
229
		if (isset($id) && $a_group[$id]) {
230
			$a_group[$id] = $group;
231
		} else {
232
			$group['gid'] = $config['system']['nextgid']++;
233
			$a_group[] = $group;
234
		}
235

    
236
		admin_groups_sort();
237

    
238
		conf_mount_rw();
239
		local_group_set($group);
240
		conf_mount_ro();
241

    
242
		/* Refresh users in this group since their privileges may have changed. */
243
		if (is_array($group['member'])) {
244
			$a_user = &$config['system']['user'];
245
			foreach ($a_user as & $user) {
246
				if (in_array($user['uid'], $group['member'])) {
247
					local_user_set($user);
248
				}
249
			}
250
		}
251

    
252
		write_config();
253

    
254
		header("Location: system_groupmanager.php");
255
		exit;
256
	}
257

    
258
	$pconfig['name'] = $_POST['groupname'];
259
}
260

    
261
function build_priv_table() {
262
	global $a_group, $id;
263

    
264
	$privhtml = '<div class="table-responsive">';
265
	$privhtml .=	'<table class="table table-striped table-hover table-condensed">';
266
	$privhtml .=		'<thead>';
267
	$privhtml .=			'<tr>';
268
	$privhtml .=				'<th>' . gettext('Name') . '</th>';
269
	$privhtml .=				'<th>' . gettext('Description') . '</th>';
270
	$privhtml .=				'<th>' . gettext('Action') . '</th>';
271
	$privhtml .=			'</tr>';
272
	$privhtml .=		'</thead>';
273
	$privhtml .=		'<tbody>';
274

    
275
	foreach (get_user_privdesc($a_group[$id]) as $i => $priv) {
276
		$privhtml .=		'<tr>';
277
		$privhtml .=			'<td>' . htmlspecialchars($priv['name']) . '</td>';
278
		$privhtml .=			'<td>' . htmlspecialchars($priv['descr']) . '</td>';
279
		$privhtml .=			'<td><a class="fa fa-trash" title="' . gettext('Delete Privilege') . '"	href="system_groupmanager.php?act=delpriv&amp;groupid=' . $id . '&amp;privid=' . $i . '"></a></td>';
280
		$privhtml .=		'</tr>';
281

    
282
	}
283

    
284
	$privhtml .=		'</tbody>';
285
	$privhtml .=	'</table>';
286
	$privhtml .= '</div>';
287

    
288
	$privhtml .= '<nav class="action-buttons">';
289
	$privhtml .=	'<a href="system_groupmanager_addprivs.php?groupid=' . $id . '" class="btn btn-success"><i class="fa fa-plus icon-embed-btn"></i>' . gettext("Add") . '</a>';
290
	$privhtml .= '</nav>';
291

    
292
	return($privhtml);
293
}
294

    
295
$pgtitle = array(gettext("System"), gettext("User Manager"), gettext("Groups"));
296
$pglinks = array("", "system_usermanager.php", "system_groupmanager.php");
297

    
298
if ($act == "new" || $act == "edit") {
299
	$pgtitle[] = gettext('Edit');
300
	$pglinks[] = "@self";
301
}
302

    
303
include("head.inc");
304

    
305
if ($input_errors) {
306
	print_input_errors($input_errors);
307
}
308

    
309
if ($savemsg) {
310
	print_info_box($savemsg, 'success');
311
}
312

    
313
$tab_array = array();
314
$tab_array[] = array(gettext("Users"), false, "system_usermanager.php");
315
$tab_array[] = array(gettext("Groups"), true, "system_groupmanager.php");
316
$tab_array[] = array(gettext("Settings"), false, "system_usermanager_settings.php");
317
$tab_array[] = array(gettext("Authentication Servers"), false, "system_authservers.php");
318
display_top_tabs($tab_array);
319

    
320
if (!($_GET['act'] == "new" || $_GET['act'] == "edit")) {
321
?>
322
<div class="panel panel-default">
323
	<div class="panel-heading"><h2 class="panel-title"><?=gettext('Groups')?></h2></div>
324
	<div class="panel-body">
325
		<div class="table-responsive">
326
			<table class="table table-striped table-hover table-condensed sortable-theme-bootstrap table-rowdblclickedit" data-sortable>
327
				<thead>
328
					<tr>
329
						<th><?=gettext("Group name")?></th>
330
						<th><?=gettext("Description")?></th>
331
						<th><?=gettext("Member Count")?></th>
332
						<th><?=gettext("Actions")?></th>
333
					</tr>
334
				</thead>
335
				<tbody>
336
<?php
337
	foreach ($a_group as $i => $group):
338
		if ($group["name"] == "all") {
339
			$groupcount = count($config['system']['user']);
340
		} else {
341
			$groupcount = count($group['member']);
342
		}
343
?>
344
					<tr>
345
						<td>
346
							<?=htmlspecialchars($group['name'])?>
347
						</td>
348
						<td>
349
							<?=htmlspecialchars($group['description'])?>
350
						</td>
351
						<td>
352
							<?=$groupcount?>
353
						</td>
354
						<td>
355
							<a class="fa fa-pencil" title="<?=gettext("Edit group"); ?>" href="?act=edit&amp;groupid=<?=$i?>"></a>
356
							<?php if ($group['scope'] != "system"): ?>
357
								<a class="fa fa-trash"	title="<?=gettext("Delete group")?>" href="?act=delgroup&amp;groupid=<?=$i?>&amp;groupname=<?=$group['name']?>"></a>
358
							<?php endif;?>
359
						</td>
360
					</tr>
361
<?php
362
	endforeach;
363
?>
364
				</tbody>
365
			</table>
366
		</div>
367
	</div>
368
</div>
369

    
370
<nav class="action-buttons">
371
	<a href="?act=new" class="btn btn-success btn-sm">
372
		<i class="fa fa-plus icon-embed-btn"></i>
373
		<?=gettext("Add")?>
374
	</a>
375
</nav>
376
<?php
377
	include('foot.inc');
378
	exit;
379
}
380

    
381
$form = new Form;
382
$form->setAction('system_groupmanager.php?act=edit');
383
$form->addGlobal(new Form_Input(
384
	'groupid',
385
	null,
386
	'hidden',
387
	$id
388
));
389

    
390
if (isset($id) && $a_group[$id]) {
391
	$form->addGlobal(new Form_Input(
392
		'id',
393
		null,
394
		'hidden',
395
		$id
396
	));
397

    
398
	$form->addGlobal(new Form_Input(
399
		'gid',
400
		null,
401
		'hidden',
402
		$pconfig['gid']
403
	));
404
}
405

    
406
$section = new Form_Section('Group Properties');
407

    
408
$section->addInput($input = new Form_Input(
409
	'groupname',
410
	'*Group name',
411
	'text',
412
	$pconfig['name']
413
));
414

    
415
if ($pconfig['gtype'] == "system") {
416
	$input->setReadonly();
417

    
418
	$section->addInput(new Form_Input(
419
		'gtype',
420
		'*Scope',
421
		'text',
422
		$pconfig['gtype']
423
	))->setReadonly();
424
} else {
425
	$section->addInput(new Form_Select(
426
		'gtype',
427
		'*Scope',
428
		$pconfig['gtype'],
429
		["local" => gettext("Local"), "remote" => gettext("Remote")]
430
	));
431
}
432

    
433
$section->addInput(new Form_Input(
434
	'description',
435
	'Description',
436
	'text',
437
	$pconfig['description']
438
))->setHelp('Group description, for administrative information only');
439

    
440

    
441
$form->add($section);
442
if ($pconfig['gid'] != 1998) { // all users group
443

    
444
	// ==== Group membership ==================================================
445
	$group = new Form_Group('Group membership');
446

    
447
	// Make a list of all the groups configured on the system, and a list of
448
	// those which this user is a member of
449
	$systemGroups = array();
450
	$usersGroups = array();
451

    
452
	foreach ($config['system']['user'] as $user) {
453
		if (is_array($pconfig['members']) && in_array($user['uid'], $pconfig['members'])) {
454
			$usersGroups[ $user['uid'] ] = $user['name'];	// Add it to the user's list
455
		} else {
456
			$systemGroups[ $user['uid'] ] = $user['name']; // Add it to the 'not a member of' list
457
		}
458
	}
459

    
460
	$group->add(new Form_Select(
461
		'notmembers',
462
		null,
463
		array_combine((array)$pconfig['groups'], (array)$pconfig['groups']),
464
		$systemGroups,
465
		true
466
	))->setHelp('Not members');
467

    
468
	$group->add(new Form_Select(
469
		'members',
470
		null,
471
		array_combine((array)$pconfig['groups'], (array)$pconfig['groups']),
472
		$usersGroups,
473
		true
474
	))->setHelp('Members');
475

    
476
	$section->add($group);
477

    
478
	$group = new Form_Group('');
479

    
480
	$group->add(new Form_Button(
481
		'movetoenabled',
482
		'Move to "Members"',
483
		null,
484
		'fa-angle-double-right'
485
	))->setAttribute('type','button')->removeClass('btn-primary')->addClass('btn-info btn-sm');
486

    
487
	$group->add(new Form_Button(
488
		'movetodisabled',
489
		'Move to "Not members',
490
		null,
491
		'fa-angle-double-left'
492
	))->setAttribute('type','button')->removeClass('btn-primary')->addClass('btn-info btn-sm');
493

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

    
497
}
498

    
499
if ($_GET['act'] != "new") {
500
	$section = new Form_Section('Assigned Privileges');
501

    
502
	$section->addInput(new Form_StaticText(
503
		null,
504
		build_priv_table()
505
	));
506

    
507

    
508
	$form->add($section);
509
}
510

    
511
print $form;
512
?>
513
<script type="text/javascript">
514
//<![CDATA[
515
events.push(function() {
516

    
517
	// On click . .
518
	$("#movetodisabled").click(function() {
519
		moveOptions($('[name="members[]"] option'), $('[name="notmembers[]"]'));
520
	});
521

    
522
	$("#movetoenabled").click(function() {
523
		moveOptions($('[name="notmembers[]"] option'), $('[name="members[]"]'));
524
	});
525

    
526
	// On submit mark all the user's groups as "selected"
527
	$('form').submit(function() {
528
		AllServers($('[name="members[]"] option'), true);
529
	});
530
});
531
//]]>
532
</script>
533
<?php
534
include('foot.inc');
(199-199/225)