Project

General

Profile

Download (8.62 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php
2
/*
3
 * priv.inc
4
 *
5
 * part of pfSense (https://www.pfsense.org)
6
 * Copyright (c) 2004-2016 Rubicon Communications, LLC (Netgate)
7
 * Copyright (c) 2005-2006 Bill Marquette <bill.marquette@gmail.com>
8
 * Copyright (c) 2006 Paul Taylor <paultaylor@winn-dixie.com>.
9
 * Copyright (c) 2008 Shrew Soft Inc
10
 * Copyright (c) 2003-2006 Manuel Kasper <mk@neon1.net>.
11
 * All rights reserved.
12
 *
13
 * Redistribution and use in source and binary forms, with or without
14
 * modification, are permitted provided that the following conditions are met:
15
 *
16
 * 1. Redistributions of source code must retain the above copyright notice,
17
 *    this list of conditions and the following disclaimer.
18
 *
19
 * 2. Redistributions in binary form must reproduce the above copyright
20
 *    notice, this list of conditions and the following disclaimer in
21
 *    the documentation and/or other materials provided with the
22
 *    distribution.
23
 *
24
 * 3. All advertising materials mentioning features or use of this software
25
 *    must display the following acknowledgment:
26
 *    "This product includes software developed by the pfSense Project
27
 *    for use in the pfSense® software distribution. (http://www.pfsense.org/).
28
 *
29
 * 4. The names "pfSense" and "pfSense Project" must not be used to
30
 *    endorse or promote products derived from this software without
31
 *    prior written permission. For written permission, please contact
32
 *    coreteam@pfsense.org.
33
 *
34
 * 5. Products derived from this software may not be called "pfSense"
35
 *    nor may "pfSense" appear in their names without prior written
36
 *    permission of the Electric Sheep Fencing, LLC.
37
 *
38
 * 6. Redistributions of any form whatsoever must retain the following
39
 *    acknowledgment:
40
 *
41
 * "This product includes software developed by the pfSense Project
42
 * for use in the pfSense software distribution (http://www.pfsense.org/).
43
 *
44
 * THIS SOFTWARE IS PROVIDED BY THE pfSense PROJECT ``AS IS'' AND ANY
45
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
46
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
47
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE pfSense PROJECT OR
48
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
49
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
50
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
51
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
52
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
53
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
54
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
55
 * OF THE POSSIBILITY OF SUCH DAMAGE.
56
 */
57

    
58
require_once("priv.defs.inc");
59

    
60
/* Load and process custom privs. */
61
function get_priv_files($directory) {
62
	$dir_array = array();
63
	if (!is_dir($directory)) {
64
		return;
65
	}
66
	if ($dh = opendir($directory)) {
67
		while (($file = readdir($dh)) !== false) {
68
			$canadd = 0;
69
			if ($file == ".") {
70
				$canadd = 1;
71
			}
72
			if ($file == "..") {
73
				$canadd = 1;
74
			}
75
			if ($canadd == 0) {
76
				array_push($dir_array, $file);
77
			}
78
		}
79
		closedir($dh);
80
	}
81
	if (!is_array($dir_array)) {
82
		return;
83
	}
84
	return $dir_array;
85
}
86

    
87
// Load and sort privs
88
$dir_array = get_priv_files("/etc/inc/priv");
89
foreach ($dir_array as $file) {
90
	if (!is_dir("/etc/inc/priv/{$file}") && substr($file, -4) == ".inc") {
91
		include_once("/etc/inc/priv/{$file}");
92
	}
93
}
94
if (is_dir("/usr/local/pkg/priv")) {
95
	$dir_array = get_priv_files("/usr/local/pkg/priv");
96
	foreach ($dir_array as $file) {
97
		if (!is_dir("/usr/local/pkg/priv/{$file}") &&
98
		    substr($file, -4) == ".inc") {
99
			include_once("/usr/local/pkg/priv/{$file}");
100
		}
101
	}
102
}
103

    
104
if (is_array($priv_list)) {
105
	sort_privs($priv_list);
106
}
107

    
108
function cmp_privkeys($a, $b) {
109
	/* user privs at the top */
110
	$auser = strncmp("user-", $a, 5);
111
	$buser = strncmp("user-", $b, 5);
112
	if ($auser != $buser) {
113
		return $auser - $buser;
114
	}
115

    
116
	/* name compare others */
117
	return strcasecmp($a, $b);
118
}
119

    
120
function sort_privs(& $privs) {
121
	uksort($privs, "cmp_privkeys");
122
}
123

    
124
function cmp_page_matches($page, & $matches, $fullwc = true) {
125

    
126
//	$dbg_matches = implode(",", $matches);
127
//	log_error("debug: checking page {$page} match with {$dbg_matches}");
128

    
129
	if (!is_array($matches)) {
130
		return false;
131
	}
132

    
133
	/* skip any leading fwdslash */
134
	$test = strpos($page, "/");
135
	if ($test !== false && $test == 0) {
136
		$page = substr($page, 1);
137
	}
138

    
139
	/* look for a match */
140
	foreach ($matches as $match) {
141

    
142
		/* possibly ignore full wildcard match */
143
		if (!$fullwc && !strcmp($match , "*")) {
144
			continue;
145
		}
146

    
147
		/* compare exact or wildcard match */
148
		$match = str_replace(array(".", "*", "?"), array("\.", ".*", "\?"), $match);
149
		$result = preg_match("@^/{$match}$@", "/{$page}");
150

    
151
		if ($result) {
152
			return true;
153
		}
154
	}
155

    
156
	return false;
157
}
158

    
159
function map_page_privname($page) {
160
	global $priv_list;
161

    
162
	foreach ($priv_list as $pname => $pdata) {
163
		if (strncmp($pname, "page-", 5)) {
164
			continue;
165
		}
166
		$fullwc = false;
167
		if (!strcasecmp($page, "any")||!strcmp($page, "*")) {
168
			$fullwc = true;
169
		}
170
		if (cmp_page_matches($page, $pdata['match'], $fullwc)) {
171
			return $pname;
172
		}
173
	}
174

    
175
	return false;
176
}
177

    
178
function get_user_privdesc(& $user) {
179
	global $priv_list;
180

    
181
	$privs = array();
182

    
183
	$user_privs = $user['priv'];
184
	if (!is_array($user_privs)) {
185
		$user_privs = array();
186
	}
187

    
188
	$names = local_user_get_groups($user, true);
189

    
190
	foreach ($names as $name) {
191
		$group = getGroupEntry($name);
192
		$group_privs = $group['priv'];
193
		if (!is_array($group_privs)) {
194
			continue;
195
		}
196
		foreach ($group_privs as $pname) {
197
			if (in_array($pname, $user_privs)) {
198
				continue;
199
			}
200
			if (!$priv_list[$pname]) {
201
				continue;
202
			}
203
			$priv = $priv_list[$pname];
204
			$priv['group'] = $group['name'];
205
			$privs[] = $priv;
206
		}
207
	}
208

    
209
	foreach ($user_privs as $pname) {
210
		if ($priv_list[$pname]) {
211
			$privs[] = $priv_list[$pname];
212
		}
213
	}
214

    
215
	return $privs;
216
}
217

    
218
function isAllowed($username, $page) {
219
	global $_SESSION;
220

    
221
	if (!isset($username)) {
222
		return false;
223
	}
224

    
225
	/* admin/root access check */
226
	$user = getUserEntry($username);
227
	if (isset($user)) {
228
		if (isset($user['uid'])) {
229
			if ($user['uid'] == 0) {
230
				return true;
231
			}
232
		}
233
	}
234

    
235
	/* user privilege access check */
236
	if (cmp_page_matches($page, $_SESSION['page-match'])) {
237
		return true;
238
	}
239

    
240
	return false;
241
}
242

    
243

    
244
function isAllowedPage($page) {
245
	global $_SESSION;
246

    
247

    
248
	$username = $_SESSION['Username'];
249

    
250
	if (!isset($username)) {
251
		return false;
252
	}
253

    
254
	/* admin/root access check */
255
	$user = getUserEntry($username);
256
	if (isset($user)) {
257
		if (isset($user['uid'])) {
258
			if ($user['uid'] == 0) {
259
				return true;
260
			}
261
		}
262
	}
263

    
264
	/* user privilege access check */
265
	return cmp_page_matches($page, $_SESSION['page-match']);
266
}
267

    
268
function getPrivPages(& $entry, & $allowed_pages) {
269
	global $priv_list;
270

    
271
	if (!is_array($entry['priv'])) {
272
		return;
273
	}
274

    
275
	foreach ($entry['priv'] as $pname) {
276
		if (strncmp($pname, "page-", 5)) {
277
			continue;
278
		}
279
		$priv = &$priv_list[$pname];
280
		if (!is_array($priv)) {
281
			continue;
282
		}
283
		$matches = &$priv['match'];
284
		if (!is_array($matches)) {
285
			continue;
286
		}
287
		foreach ($matches as $match) {
288
			$allowed_pages[] = $match;
289
		}
290
	}
291
}
292

    
293
function getAllowedPages($username, &$attributes = array()) {
294
	global $config, $_SESSION;
295

    
296
	if (!function_exists("ldap_connect")) {
297
		return;
298
	}
299

    
300
	$allowed_pages = array();
301
	$allowed_groups = array();
302

    
303
	if ($_SESSION['remoteauth']) {
304
		$authcfg = auth_get_authserver($config['system']['webgui']['authmode']);
305
		// obtain ldap groups if we are in ldap mode
306
		if ($authcfg['type'] == "ldap") {
307
			$allowed_groups = @ldap_get_groups($username, $authcfg);
308
		} elseif ($authcfg['type'] == "radius") {
309
			$allowed_groups = @radius_get_groups($attributes);
310
		}
311
	}
312
	if (!$allowed_groups) {
313
		// search for a local user by name
314
		$local_user = getUserEntry($username);
315

    
316
		// obtain local user pages and groups if we have a local user
317
		if ($local_user) {
318
			getPrivPages($local_user, $allowed_pages);
319
			$allowed_groups = local_user_get_groups($local_user);
320
		}
321
	}
322

    
323
	// build a list of allowed pages
324
	if (is_array($config['system']['group']) && is_array($allowed_groups)) {
325
		foreach ($config['system']['group'] as $group) {
326
			if (in_array($group['name'], $allowed_groups)) {
327
				getPrivPages($group, $allowed_pages);
328
			}
329
		}
330
	}
331

    
332
//	$dbg_pages = implode(",", $allowed_pages);
333
//	$dbg_groups = implode(",", $allowed_groups);
334
//	log_error("debug: user {$username} groups = {$dbg_groups}");
335
//	log_error("debug: user {$username} pages = {$dbg_pages}");
336

    
337
	$_SESSION['page-match'] = $allowed_pages;
338

    
339
	return $allowed_pages;
340
}
341

    
342
function sort_user_privs($privs) {
343
	// Privileges to place first, to redirect properly.
344
	$priority_privs = array("page-dashboard-all", "page-system-login-logout");
345

    
346
	$fprivs = array_intersect($privs, $priority_privs);
347
	$sprivs = array_diff($privs, $priority_privs);
348

    
349
	return array_merge($fprivs, $sprivs);
350
}
351
?>
(43-43/65)