Project

General

Profile

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

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

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

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

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

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

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

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

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

    
41
*/
42

    
43
/*
44
	pfSense_MODULE:	auth
45
*/
46

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
144
	return false;
145
}
146

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

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

    
163
	return false;
164
}
165

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

    
169
	$privs = array();
170

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

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

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

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

    
203
	return $privs;
204
}
205

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

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

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

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

    
228
	return false;
229
}
230

    
231

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

    
235

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
325
	return $allowed_pages;
326
}
327

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

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

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