Project

General

Profile

Download (7.3 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php
2
/*
3
 * priv.inc
4
 *
5
 * part of pfSense (https://www.pfsense.org)
6
 * Copyright (c) 2004-2013 BSD Perimeter
7
 * Copyright (c) 2013-2016 Electric Sheep Fencing
8
 * Copyright (c) 2014-2022 Rubicon Communications, LLC (Netgate)
9
 * Copyright (c) 2005-2006 Bill Marquette <bill.marquette@gmail.com>
10
 * Copyright (c) 2006 Paul Taylor <paultaylor@winn-dixie.com>.
11
 * Copyright (c) 2008 Shrew Soft Inc
12
 * Copyright (c) 2003-2006 Manuel Kasper <mk@neon1.net>.
13
 * All rights reserved.
14
 *
15
 * Licensed under the Apache License, Version 2.0 (the "License");
16
 * you may not use this file except in compliance with the License.
17
 * You may obtain a copy of the License at
18
 *
19
 * http://www.apache.org/licenses/LICENSE-2.0
20
 *
21
 * Unless required by applicable law or agreed to in writing, software
22
 * distributed under the License is distributed on an "AS IS" BASIS,
23
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
24
 * See the License for the specific language governing permissions and
25
 * limitations under the License.
26
 */
27

    
28
require_once("priv.defs.inc");
29
require_once("auth_func.inc");
30

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

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

    
75
if (is_array($priv_list)) {
76
	sort_privs($priv_list);
77
}
78

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

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

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

    
95
function map_page_privname($page) {
96
	global $priv_list;
97

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

    
111
	return false;
112
}
113

    
114
function get_user_privdesc(& $user) {
115
	global $priv_list;
116

    
117
	$privs = array();
118

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

    
124
	$names = local_user_get_groups($user, true);
125

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

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

    
151
	return $privs;
152
}
153

    
154
function isAdminUID($username) {
155
	global $_SESSION;
156

    
157
	if (!isset($username)) {
158
		return false;
159
	}
160

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

    
171
	return false;
172
}
173

    
174
function isAllowed($username, $page) {
175
	global $_SESSION;
176

    
177
	if (!isset($username)) {
178
		return false;
179
	}
180

    
181
	if (isAdminUID($username)) {
182
		return true;
183
	}
184

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

    
190
	return false;
191
}
192

    
193
function isAllowedPage($page) {
194
	global $_SESSION;
195

    
196

    
197
	$username = $_SESSION['Username'];
198

    
199
	if (!isset($username)) {
200
		return false;
201
	}
202

    
203
	if (isAdminUID($username)) {
204
		return true;
205
	}
206

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

    
211
function getPrivPages(& $entry, & $allowed_pages) {
212
	global $priv_list;
213

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

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

    
230
function getAllowedPages($username, &$attributes = array()) {
231
	global $config, $_SESSION;
232

    
233
	if (!function_exists("ldap_connect")) {
234
		return;
235
	}
236

    
237
	$allowed_pages = array();
238
	$allowed_groups = array();
239

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

    
270
	}
271
	if (!$allowed_groups) {
272
		// search for a local user by name
273
		$local_user = getUserEntry($username);
274

    
275
		// obtain local user pages and groups if we have a local user
276
		if ($local_user) {
277
			getPrivPages($local_user, $allowed_pages);
278
			$allowed_groups = local_user_get_groups($local_user);
279
		}
280
	}
281

    
282
	if (!is_array($allowed_groups)) {
283
		$allowed_groups = array('all');
284
	} else {
285
		$allowed_groups[] = 'all';
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
	phpsession_end(true);
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
?>
(42-42/61)