Project

General

Profile

Download (6.88 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 Electric Sheep Fencing, LLC
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
 * Licensed under the Apache License, Version 2.0 (the "License");
14
 * you may not use this file except in compliance with the License.
15
 * You may obtain a copy of the License at
16
 *
17
 * http://www.apache.org/licenses/LICENSE-2.0
18
 *
19
 * Unless required by applicable law or agreed to in writing, software
20
 * distributed under the License is distributed on an "AS IS" BASIS,
21
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22
 * See the License for the specific language governing permissions and
23
 * limitations under the License.
24
 */
25

    
26
require_once("priv.defs.inc");
27

    
28
/* Load and process custom privs. */
29
function get_priv_files($directory) {
30
	$dir_array = array();
31
	if (!is_dir($directory)) {
32
		return;
33
	}
34
	if ($dh = opendir($directory)) {
35
		while (($file = readdir($dh)) !== false) {
36
			$canadd = 0;
37
			if ($file == ".") {
38
				$canadd = 1;
39
			}
40
			if ($file == "..") {
41
				$canadd = 1;
42
			}
43
			if ($canadd == 0) {
44
				array_push($dir_array, $file);
45
			}
46
		}
47
		closedir($dh);
48
	}
49
	if (!is_array($dir_array)) {
50
		return;
51
	}
52
	return $dir_array;
53
}
54

    
55
// Load and sort privs
56
$dir_array = get_priv_files("/etc/inc/priv");
57
foreach ($dir_array as $file) {
58
	if (!is_dir("/etc/inc/priv/{$file}") && stristr($file, ".inc")) {
59
		include_once("/etc/inc/priv/{$file}");
60
	}
61
}
62
if (is_dir("/usr/local/pkg/priv")) {
63
	$dir_array = get_priv_files("/usr/local/pkg/priv");
64
	foreach ($dir_array as $file) {
65
		if (!is_dir("/usr/local/pkg/priv/{$file}") && stristr($file, ".inc")) {
66
			include_once("/usr/local/pkg/priv/{$file}");
67
		}
68
	}
69
}
70

    
71
if (is_array($priv_list)) {
72
	sort_privs($priv_list);
73
}
74

    
75
function cmp_privkeys($a, $b) {
76
	/* user privs at the top */
77
	$auser = strncmp("user-", $a, 5);
78
	$buser = strncmp("user-", $b, 5);
79
	if ($auser != $buser) {
80
		return $auser - $buser;
81
	}
82

    
83
	/* name compare others */
84
	return strcasecmp($a, $b);
85
}
86

    
87
function sort_privs(& $privs) {
88
	uksort($privs, "cmp_privkeys");
89
}
90

    
91
function cmp_page_matches($page, & $matches, $fullwc = true) {
92

    
93
//	$dbg_matches = implode(",", $matches);
94
//	log_error("debug: checking page {$page} match with {$dbg_matches}");
95

    
96
	if (!is_array($matches)) {
97
		return false;
98
	}
99

    
100
	/* skip any leading fwdslash */
101
	$test = strpos($page, "/");
102
	if ($test !== false && $test == 0) {
103
		$page = substr($page, 1);
104
	}
105

    
106
	/* look for a match */
107
	foreach ($matches as $match) {
108

    
109
		/* possibly ignore full wildcard match */
110
		if (!$fullwc && !strcmp($match , "*")) {
111
			continue;
112
		}
113

    
114
		/* compare exact or wildcard match */
115
		$match = str_replace(array(".", "*", "?"), array("\.", ".*", "\?"), $match);
116
		$result = preg_match("@^/{$match}$@", "/{$page}");
117

    
118
		if ($result) {
119
			return true;
120
		}
121
	}
122

    
123
	return false;
124
}
125

    
126
function map_page_privname($page) {
127
	global $priv_list;
128

    
129
	foreach ($priv_list as $pname => $pdata) {
130
		if (strncmp($pname, "page-", 5)) {
131
			continue;
132
		}
133
		$fullwc = false;
134
		if (!strcasecmp($page, "any")||!strcmp($page, "*")) {
135
			$fullwc = true;
136
		}
137
		if (cmp_page_matches($page, $pdata['match'], $fullwc)) {
138
			return $pname;
139
		}
140
	}
141

    
142
	return false;
143
}
144

    
145
function get_user_privdesc(& $user) {
146
	global $priv_list;
147

    
148
	$privs = array();
149

    
150
	$user_privs = $user['priv'];
151
	if (!is_array($user_privs)) {
152
		$user_privs = array();
153
	}
154

    
155
	$names = local_user_get_groups($user, true);
156

    
157
	foreach ($names as $name) {
158
		$group = getGroupEntry($name);
159
		$group_privs = $group['priv'];
160
		if (!is_array($group_privs)) {
161
			continue;
162
		}
163
		foreach ($group_privs as $pname) {
164
			if (in_array($pname, $user_privs)) {
165
				continue;
166
			}
167
			if (!$priv_list[$pname]) {
168
				continue;
169
			}
170
			$priv = $priv_list[$pname];
171
			$priv['group'] = $group['name'];
172
			$privs[] = $priv;
173
		}
174
	}
175

    
176
	foreach ($user_privs as $pname) {
177
		if ($priv_list[$pname]) {
178
			$privs[] = $priv_list[$pname];
179
		}
180
	}
181

    
182
	return $privs;
183
}
184

    
185
function isAllowed($username, $page) {
186
	global $_SESSION;
187

    
188
	if (!isset($username)) {
189
		return false;
190
	}
191

    
192
	/* admin/root access check */
193
	$user = getUserEntry($username);
194
	if (isset($user)) {
195
		if (isset($user['uid'])) {
196
			if ($user['uid'] == 0) {
197
				return true;
198
			}
199
		}
200
	}
201

    
202
	/* user privilege access check */
203
	if (cmp_page_matches($page, $_SESSION['page-match'])) {
204
		return true;
205
	}
206

    
207
	return false;
208
}
209

    
210

    
211
function isAllowedPage($page) {
212
	global $_SESSION;
213

    
214

    
215
	$username = $_SESSION['Username'];
216

    
217
	if (!isset($username)) {
218
		return false;
219
	}
220

    
221
	/* admin/root access check */
222
	$user = getUserEntry($username);
223
	if (isset($user)) {
224
		if (isset($user['uid'])) {
225
			if ($user['uid'] == 0) {
226
				return true;
227
			}
228
		}
229
	}
230

    
231
	/* user privilege access check */
232
	return cmp_page_matches($page, $_SESSION['page-match']);
233
}
234

    
235
function getPrivPages(& $entry, & $allowed_pages) {
236
	global $priv_list;
237

    
238
	if (!is_array($entry['priv'])) {
239
		return;
240
	}
241

    
242
	foreach ($entry['priv'] as $pname) {
243
		if (strncmp($pname, "page-", 5)) {
244
			continue;
245
		}
246
		$priv = &$priv_list[$pname];
247
		if (!is_array($priv)) {
248
			continue;
249
		}
250
		$matches = &$priv['match'];
251
		if (!is_array($matches)) {
252
			continue;
253
		}
254
		foreach ($matches as $match) {
255
			$allowed_pages[] = $match;
256
		}
257
	}
258
}
259

    
260
function getAllowedPages($username, &$attributes = array()) {
261
	global $config, $_SESSION;
262

    
263
	if (!function_exists("ldap_connect")) {
264
		return;
265
	}
266

    
267
	$allowed_pages = array();
268
	$allowed_groups = array();
269

    
270
	$authcfg = auth_get_authserver($config['system']['webgui']['authmode']);
271
	// obtain ldap groups if we are in ldap mode
272
	if ($authcfg['type'] == "ldap") {
273
		$allowed_groups = @ldap_get_groups($username, $authcfg);
274
	} elseif ($authcfg['type'] == "radius") {
275
		$allowed_groups = @radius_get_groups($attributes);
276
	}
277
	if (!$allowed_groups) {
278
		// search for a local user by name
279
		$local_user = getUserEntry($username);
280

    
281
		// obtain local user pages and groups if we have a local user
282
		if ($local_user) {
283
			getPrivPages($local_user, $allowed_pages);
284
			$allowed_groups = local_user_get_groups($local_user);
285
		}
286
	}
287

    
288
	// build a list of allowed pages
289
	if (is_array($config['system']['group']) && is_array($allowed_groups)) {
290
		foreach ($config['system']['group'] as $group) {
291
			if (in_array($group['name'], $allowed_groups)) {
292
				getPrivPages($group, $allowed_pages);
293
			}
294
		}
295
	}
296

    
297
//	$dbg_pages = implode(",", $allowed_pages);
298
//	$dbg_groups = implode(",", $allowed_groups);
299
//	log_error("debug: user {$username} groups = {$dbg_groups}");
300
//	log_error("debug: user {$username} pages = {$dbg_pages}");
301

    
302
	$_SESSION['page-match'] = $allowed_pages;
303

    
304
	return $allowed_pages;
305
}
306

    
307
function sort_user_privs($privs) {
308
	// Privileges to place first, to redirect properly.
309
	$priority_privs = array("page-dashboard-all", "page-system-login-logout");
310

    
311
	$fprivs = array_intersect($privs, $priority_privs);
312
	$sprivs = array_diff($privs, $priority_privs);
313

    
314
	return array_merge($fprivs, $sprivs);
315
}
316
?>
(43-43/65)