Project

General

Profile

Download (7.14 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php
2
/*
3
 * priv.inc
4
 *
5
 * part of pfSense (https://www.pfsense.org)
6
 * Copyright (c) 2004-2018 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
 * 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
require_once("auth_func.inc");
28

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

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

    
73
if (is_array($priv_list)) {
74
	sort_privs($priv_list);
75
}
76

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

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

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

    
93
function map_page_privname($page) {
94
	global $priv_list;
95

    
96
	foreach ($priv_list as $pname => $pdata) {
97
		if (strncmp($pname, "page-", 5)) {
98
			continue;
99
		}
100
		$fullwc = false;
101
		if (!strcasecmp($page, "any")||!strcmp($page, "*")) {
102
			$fullwc = true;
103
		}
104
		if (cmp_page_matches($page, $pdata['match'], $fullwc)) {
105
			return $pname;
106
		}
107
	}
108

    
109
	return false;
110
}
111

    
112
function get_user_privdesc(& $user) {
113
	global $priv_list;
114

    
115
	$privs = array();
116

    
117
	$user_privs = $user['priv'];
118
	if (!is_array($user_privs)) {
119
		$user_privs = array();
120
	}
121

    
122
	$names = local_user_get_groups($user, true);
123

    
124
	foreach ($names as $name) {
125
		$group = getGroupEntry($name);
126
		$group_privs = $group['priv'];
127
		if (!is_array($group_privs)) {
128
			continue;
129
		}
130
		foreach ($group_privs as $pname) {
131
			if (in_array($pname, $user_privs)) {
132
				continue;
133
			}
134
			if (!$priv_list[$pname]) {
135
				continue;
136
			}
137
			$priv = $priv_list[$pname];
138
			$priv['group'] = $group['name'];
139
			$privs[] = $priv;
140
		}
141
	}
142

    
143
	foreach ($user_privs as $pname) {
144
		if ($priv_list[$pname]) {
145
			$privs[] = $priv_list[$pname];
146
		}
147
	}
148

    
149
	return $privs;
150
}
151

    
152
function isAdminUID($username) {
153
	global $_SESSION;
154

    
155
	if (!isset($username)) {
156
		return false;
157
	}
158

    
159
	/* admin/root access check */
160
	$user = getUserEntry($username);
161
	if (isset($user)) {
162
		if (isset($user['uid'])) {
163
			if ($user['uid'] == 0) {
164
				return true;
165
			}
166
		}
167
	}
168

    
169
	return false;
170
}
171

    
172
function isAllowed($username, $page) {
173
	global $_SESSION;
174

    
175
	if (!isset($username)) {
176
		return false;
177
	}
178

    
179
	if (isAdminUID($username)) {
180
		return true;
181
	}
182

    
183
	/* user privilege access check */
184
	if (cmp_page_matches($page, $_SESSION['page-match'])) {
185
		return true;
186
	}
187

    
188
	return false;
189
}
190

    
191
function isAllowedPage($page) {
192
	global $_SESSION;
193

    
194

    
195
	$username = $_SESSION['Username'];
196

    
197
	if (!isset($username)) {
198
		return false;
199
	}
200

    
201
	if (isAdminUID($username)) {
202
		return true;
203
	}
204

    
205
	/* user privilege access check */
206
	return cmp_page_matches($page, $_SESSION['page-match']);
207
}
208

    
209
function getPrivPages(& $entry, & $allowed_pages) {
210
	global $priv_list;
211

    
212
	if (!is_array($entry['priv'])) {
213
		return;
214
	}
215

    
216
	foreach ($entry['priv'] as $pname) {
217
		if (strncmp($pname, "page-", 5)) {
218
			continue;
219
		}
220
		$priv = &$priv_list[$pname];
221
		if (!is_array($priv)) {
222
			continue;
223
		}
224
		$matches = &$priv['match'];
225
		if (!is_array($matches)) {
226
			continue;
227
		}
228
		foreach ($matches as $match) {
229
			$allowed_pages[] = $match;
230
		}
231
	}
232
}
233

    
234
function getAllowedPages($username, &$attributes = array()) {
235
	global $config, $_SESSION;
236

    
237
	if (!function_exists("ldap_connect")) {
238
		return;
239
	}
240

    
241
	$allowed_pages = array();
242
	$allowed_groups = array();
243

    
244
 	phpsession_begin();
245
	if ($_SESSION['remoteauth']) {
246
		$authcfg = auth_get_authserver($config['system']['webgui']['authmode']);
247
		// cache auth results for a short time to ease load on auth services & logs
248
		if (isset($config['system']['webgui']['auth_refresh_time'])) {
249
			$recheck_time = $config['system']['webgui']['auth_refresh_time'];
250
		} else {
251
			$recheck_time = 30;
252
		}
253
		// obtain ldap groups if we are in ldap mode
254
		if ($authcfg['type'] == "ldap") {
255
			if (isset($_SESSION["ldap_allowed_groups"]) &&
256
			    (time() <= $_SESSION["auth_check_time"] + $recheck_time)) {
257
				$allowed_groups = $_SESSION["ldap_allowed_groups"];
258
			} else {
259
				$allowed_groups = @ldap_get_groups($username, $authcfg);
260
				$_SESSION["ldap_allowed_groups"] = $allowed_groups;
261
				$_SESSION["auth_check_time"] = time();
262
			}
263
		} elseif ($authcfg['type'] == "radius") {
264
			if (isset($_SESSION["radius_allowed_groups"]) &&
265
			    (time() <= $_SESSION["auth_check_time"] + $recheck_time)) {
266
				$allowed_groups = $_SESSION["radius_allowed_groups"];
267
			} else {
268
				$allowed_groups = @radius_get_groups($attributes);
269
				$_SESSION["radius_allowed_groups"] = $allowed_groups;
270
				$_SESSION["auth_check_time"] = time();
271
			}
272
		}
273

    
274
	}
275
	if (!$allowed_groups) {
276
		// search for a local user by name
277
		$local_user = getUserEntry($username);
278

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

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

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

    
300
	$_SESSION['page-match'] = $allowed_pages;
301
	phpsession_end(true);
302
	return $allowed_pages;
303
}
304

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

    
309
	$fprivs = array_intersect($privs, $priority_privs);
310
	$sprivs = array_diff($privs, $priority_privs);
311

    
312
	return array_merge($fprivs, $sprivs);
313
}
314
?>
(42-42/60)