Project

General

Profile

Download (7.57 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php
2
/*
3
	priv.inc
4
	Copyright (C) 2008 Shrew Soft Inc
5
	All rights reserved.
6

    
7
	Copyright (C) 2007, 2008 Scott Ullrich <sullrich@gmail.com>
8
	All rights reserved.
9

    
10
	Copyright (C) 2005-2006 Bill Marquette <bill.marquette@gmail.com>
11
	All rights reserved.
12

    
13
	Copyright (C) 2006 Paul Taylor <paultaylor@winn-dixie.com>.
14
	All rights reserved.
15

    
16
	Copyright (C) 2003-2006 Manuel Kasper <mk@neon1.net>.
17
	All rights reserved.
18

    
19
	Redistribution and use in source and binary forms, with or without
20
	modification, are permitted provided that the following conditions are met:
21

    
22
	1. Redistributions of source code must retain the above copyright notice,
23
	   this list of conditions and the following disclaimer.
24

    
25
	2. Redistributions in binary form must reproduce the above copyright
26
	   notice, this list of conditions and the following disclaimer in the
27
	   documentation and/or other materials provided with the distribution.
28

    
29
	THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
30
	INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
31
	AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
32
	AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
33
	OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
34
	SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
35
	INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
36
	CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
37
	ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
38
	POSSIBILITY OF SUCH DAMAGE.
39

    
40
*/
41

    
42
/*
43
	pfSense_MODULE:	auth
44
*/
45

    
46
require_once("priv.defs.inc");
47

    
48
/* Load and process custom privs. */
49
function get_priv_files($directory) {
50
	$dir_array = array();
51
	if (!is_dir($directory)) {
52
		return;
53
	}
54
	if ($dh = opendir($directory)) {
55
		while (($file = readdir($dh)) !== false) {
56
			$canadd = 0;
57
			if ($file == ".") {
58
				$canadd = 1;
59
			}
60
			if ($file == "..") {
61
				$canadd = 1;
62
			}
63
			if ($canadd == 0) {
64
				array_push($dir_array, $file);
65
			}
66
		}
67
		closedir($dh);
68
	}
69
	if (!is_array($dir_array)) {
70
		return;
71
	}
72
	return $dir_array;
73
}
74

    
75
// Load and sort privs
76
$dir_array = get_priv_files("/etc/inc/priv");
77
foreach ($dir_array as $file) {
78
	if (!is_dir("/etc/inc/priv/{$file}") && stristr($file, ".inc")) {
79
		include("/etc/inc/priv/{$file}");
80
	}
81
}
82
if (is_dir("/usr/local/pkg/priv")) {
83
	$dir_array = get_priv_files("/usr/local/pkg/priv");
84
	foreach ($dir_array as $file) {
85
		if (!is_dir("/usr/local/pkg/priv/{$file}") && stristr($file, ".inc")) {
86
			include("/usr/local/pkg/priv/{$file}");
87
		}
88
	}
89
}
90

    
91
if (is_array($priv_list)) {
92
	sort_privs($priv_list);
93
}
94

    
95
function cmp_privkeys($a, $b) {
96
	/* user privs at the top */
97
	$auser = strncmp("user-", $a, 5);
98
	$buser = strncmp("user-", $b, 5);
99
	if ($auser != $buser) {
100
		return $auser - $buser;
101
	}
102

    
103
	/* name compare others */
104
	return strcasecmp($a, $b);
105
}
106

    
107
function sort_privs(& $privs) {
108
	uksort($privs, "cmp_privkeys");
109
}
110

    
111
function cmp_page_matches($page, & $matches, $fullwc = true) {
112

    
113
//	$dbg_matches = implode(",", $matches);
114
//	log_error("debug: checking page {$page} match with {$dbg_matches}");
115

    
116
	if (!is_array($matches)) {
117
		return false;
118
	}
119

    
120
	/* skip any leading fwdslash */
121
	$test = strpos($page, "/");
122
	if ($test !== false && $test == 0) {
123
		$page = substr($page, 1);
124
	}
125

    
126
	/* look for a match */
127
	foreach ($matches as $match) {
128

    
129
		/* possibly ignore full wildcard match */
130
		if (!$fullwc && !strcmp($match , "*")) {
131
			continue;
132
		}
133

    
134
		/* compare exact or wildcard match */
135
		$match = str_replace(array(".", "*", "?"), array("\.", ".*", "\?"), $match);
136
		$result = preg_match("@^/{$match}$@", "/{$page}");
137

    
138
		if ($result) {
139
			return true;
140
		}
141
	}
142

    
143
	return false;
144
}
145

    
146
function map_page_privname($page) {
147
	global $priv_list;
148

    
149
	foreach ($priv_list as $pname => $pdata) {
150
		if (strncmp($pname, "page-", 5)) {
151
			continue;
152
		}
153
		$fullwc = false;
154
		if (!strcasecmp($page, "any")||!strcmp($page, "*")) {
155
			$fullwc = true;
156
		}
157
		if (cmp_page_matches($page, $pdata['match'], $fullwc)) {
158
			return $pname;
159
		}
160
	}
161

    
162
	return false;
163
}
164

    
165
function get_user_privdesc(& $user) {
166
	global $priv_list;
167

    
168
	$privs = array();
169

    
170
	$user_privs = $user['priv'];
171
	if (!is_array($user_privs)) {
172
		$user_privs = array();
173
	}
174

    
175
	$names = local_user_get_groups($user, true);
176

    
177
	foreach ($names as $name) {
178
		$group = getGroupEntry($name);
179
		$group_privs = $group['priv'];
180
		if (!is_array($group_privs)) {
181
			continue;
182
		}
183
		foreach ($group_privs as $pname) {
184
			if (in_array($pname, $user_privs)) {
185
				continue;
186
			}
187
			if (!$priv_list[$pname]) {
188
				continue;
189
			}
190
			$priv = $priv_list[$pname];
191
			$priv['group'] = $group['name'];
192
			$privs[] = $priv;
193
		}
194
	}
195

    
196
	foreach ($user_privs as $pname) {
197
		if ($priv_list[$pname]) {
198
			$privs[] = $priv_list[$pname];
199
		}
200
	}
201

    
202
	return $privs;
203
}
204

    
205
function isAllowed($username, $page) {
206
	global $_SESSION;
207

    
208
	if (!isset($username)) {
209
		return false;
210
	}
211

    
212
	/* admin/root access check */
213
	$user = getUserEntry($username);
214
	if (isset($user)) {
215
		if (isset($user['uid'])) {
216
			if ($user['uid'] == 0) {
217
				return true;
218
			}
219
		}
220
	}
221

    
222
	/* user privilege access check */
223
	if (cmp_page_matches($page, $_SESSION['page-match'])) {
224
		return true;
225
	}
226

    
227
	return false;
228
}
229

    
230

    
231
function isAllowedPage($page) {
232
	global $_SESSION;
233

    
234

    
235
	$username = $_SESSION['Username'];
236

    
237
	if (!isset($username)) {
238
		return false;
239
	}
240

    
241
	/* admin/root access check */
242
	$user = getUserEntry($username);
243
	if (isset($user)) {
244
		if (isset($user['uid'])) {
245
			if ($user['uid'] == 0) {
246
				return true;
247
			}
248
		}
249
	}
250

    
251
	/* user privilege access check */
252
	return cmp_page_matches($page, $_SESSION['page-match']);
253
}
254

    
255
function getPrivPages(& $entry, & $allowed_pages) {
256
	global $priv_list;
257

    
258
	if (!is_array($entry['priv'])) {
259
		return;
260
	}
261

    
262
	foreach ($entry['priv'] as $pname) {
263
		if (strncmp($pname, "page-", 5)) {
264
			continue;
265
		}
266
		$priv = &$priv_list[$pname];
267
		if (!is_array($priv)) {
268
			continue;
269
		}
270
		$matches = &$priv['match'];
271
		if (!is_array($matches)) {
272
			continue;
273
		}
274
		foreach ($matches as $match) {
275
			$allowed_pages[] = $match;
276
		}
277
	}
278
}
279

    
280
function getAllowedPages($username, &$attributes = array()) {
281
	global $config, $_SESSION;
282

    
283
	if (!function_exists("ldap_connect")) {
284
		return;
285
	}
286

    
287
	$allowed_pages = array();
288
	$allowed_groups = array();
289

    
290
	$authcfg = auth_get_authserver($config['system']['webgui']['authmode']);
291
	// obtain ldap groups if we are in ldap mode
292
	if ($authcfg['type'] == "ldap") {
293
		$allowed_groups = @ldap_get_groups($username, $authcfg);
294
	} elseif ($authcfg['type'] == "radius") {
295
		$allowed_groups = @radius_get_groups($attributes);
296
	}
297
	if (!$allowed_groups) {
298
		// search for a local user by name
299
		$local_user = getUserEntry($username);
300

    
301
		// obtain local user pages and groups if we have a local user
302
		if ($local_user) {
303
			getPrivPages($local_user, $allowed_pages);
304
			$allowed_groups = local_user_get_groups($local_user);
305
		}
306
	}
307

    
308
	// build a list of allowed pages
309
	if (is_array($config['system']['group']) && is_array($allowed_groups)) {
310
		foreach ($config['system']['group'] as $group) {
311
			if (in_array($group['name'], $allowed_groups)) {
312
				getPrivPages($group, $allowed_pages);
313
			}
314
		}
315
	}
316

    
317
//	$dbg_pages = implode(",", $allowed_pages);
318
//	$dbg_groups = implode(",", $allowed_groups);
319
//	log_error("debug: user {$username} groups = {$dbg_groups}");
320
//	log_error("debug: user {$username} pages = {$dbg_pages}");
321

    
322
	$_SESSION['page-match'] = $allowed_pages;
323

    
324
	return $allowed_pages;
325
}
326

    
327
function sort_user_privs($privs) {
328
	// Privileges to place first, to redirect properly.
329
	$priority_privs = array("page-dashboard-all", "page-system-login/logout");
330

    
331
	$fprivs = array_intersect($privs, $priority_privs);
332
	$sprivs = array_diff($privs, $priority_privs);
333

    
334
	return array_merge($fprivs, $sprivs);
335
}
336
?>
(44-44/67)