Project

General

Profile

Download (19.8 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php
2
/*
3
    $Id$
4
    part of m0n0wall (http://m0n0.ch/wall)
5

    
6
    Copyrigth (C) 2009	    Ermal Lu?i
7
    Copyright (C) 2003-2006 Manuel Kasper <mk@neon1.net>.
8
    All rights reserved.
9

    
10
    Redistribution and use in source and binary forms, with or without
11
    modification, are permitted provided that the following conditions are met:
12

    
13
    1. Redistributions of source code must retain the above copyright notice,
14
       this list of conditions and the following disclaimer.
15

    
16
    2. Redistributions in binary form must reproduce the above copyright
17
       notice, this list of conditions and the following disclaimer in the
18
       documentation and/or other materials provided with the distribution.
19

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

    
36
require_once("auth.inc");
37
require_once("functions.inc");
38
require_once("captiveportal.inc");
39

    
40
header("Expires: 0");
41
header("Cache-Control: no-store, no-cache, must-revalidate");
42
header("Cache-Control: post-check=0, pre-check=0", false);
43
header("Pragma: no-cache");
44

    
45
$orig_host = $_ENV['HTTP_HOST'];
46
$orig_request = $_REQUEST['redirurl'];
47
$clientip = $_SERVER['REMOTE_ADDR'];
48

    
49
if (!$clientip) {
50
    /* not good - bail out */
51
    echo "An error occurred.  Please check the system logs for more information.";
52
    log_error("Captive portal could not determine client's IP address.");
53
    exit;
54
}
55

    
56
if (isset($config['captiveportal']['httpslogin']))
57
    $ourhostname = $config['captiveportal']['httpsname'] . ":8001";
58
else {
59
    $ifip = portal_ip_from_client_ip($clientip);
60
    if (!$ifip)
61
    	$ourhostname = $config['system']['hostname'] . ":8000";
62
    else
63
    	$ourhostname = "{$ifip}:8000";
64
}
65

    
66
if ($orig_host != $ourhostname) {
67
    /* the client thinks it's connected to the desired web server, but instead
68
       it's connected to us. Issue a redirect... */
69

    
70
    if (isset($config['captiveportal']['httpslogin']))
71
        header("Location: https://{$ourhostname}/index.php?redirurl=" . urlencode("http://{$orig_host}{$orig_request}"));
72
    else
73
        header("Location: http://{$ourhostname}/index.php?redirurl=" . urlencode("http://{$orig_host}{$orig_request}"));
74

    
75
    exit;
76
}
77

    
78
if (preg_match("/redirurl=(.*)/", $orig_request, $matches))
79
    $redirurl = urldecode($matches[1]);
80
if ($_POST['redirurl'])
81
    $redirurl = $_POST['redirurl'];
82

    
83
$macfilter = !isset($config['captiveportal']['nomacfilter']);
84
$passthrumac = isset($config['captiveportal']['passthrumacadd']);
85

    
86
/* find MAC address for client */
87
$clientmac = arp_get_mac_by_ip($clientip);
88
if (!$clientmac && ($macfilter || $passthrumac)) {
89
    /* unable to find MAC address - shouldn't happen! - bail out */
90
    captiveportal_logportalauth("unauthenticated","noclientmac",$clientip,"ERROR");
91
    echo "An error occurred.  Please check the system logs for more information.";
92
    log_error("Captive portal could not determine client's MAC address.  Disable MAC address filtering in captive portal if you do not need this functionality.");
93
    exit;
94
}
95

    
96
/* find out if we need RADIUS + RADIUSMAC or not */
97
if (file_exists("{$g['vardb_path']}/captiveportal_radius.db")) {
98
    $radius_enable = TRUE;
99
    if (isset($config['captiveportal']['radmac_enable']))
100
        $radmac_enable = TRUE;
101
}
102

    
103
if ($_POST['logout_id']) {
104
    disconnect_client($_POST['logout_id']);
105
    echo <<<EOD
106
<HTML>
107
<HEAD><TITLE>Disconnecting...</TITLE></HEAD>
108
<BODY BGCOLOR="#435370">
109
<SPAN STYLE="color: #ffffff; font-family: Tahoma, Verdana, Arial, Helvetica, sans-serif; font-size: 11px;">
110
<B>You have been disconnected.</B>
111
</SPAN>
112
<SCRIPT LANGUAGE="JavaScript">
113
<!--
114
setTimeout('window.close();',5000) ;
115
-->
116
</SCRIPT>
117
</BODY>
118
</HTML>
119

    
120
EOD;
121
exit;
122
} else if ($clientmac && $radmac_enable && portal_mac_radius($clientmac,$clientip)) {
123
    /* radius functions handle everything so we exit here since we're done */
124
    exit;
125

    
126
} else if ($_POST['accept'] && $_POST['auth_voucher']) {
127

    
128
    $voucher = trim($_POST['auth_voucher']);
129
    $timecredit = voucher_auth($voucher);
130
    // $timecredit contains either a credit in minutes or an error message
131
    if ($timecredit > 0) {  // voucher is valid. Remaining minutes returned
132
        // if multiple vouchers given, use the first as username
133
        $a_vouchers = split("[\t\n\r ]+",$voucher);
134
        $voucher = $a_vouchers[0];
135
        $attr = array( 'voucher' => 1,
136
                'session_timeout' => $timecredit*60,
137
                'session_terminate_time' => 0);
138
        if (portal_allow($clientip, $clientmac,$voucher,null,$attr)) {
139

    
140
            // YES: user is good for $timecredit minutes.
141
            captiveportal_logportalauth($voucher,$clientmac,$clientip,"Voucher login good for $timecredit min.");
142
        } else {
143
            portal_reply_page($redirurl, "error", $config['voucher']['msgexpired']);
144
        }
145
    } else if (-1 == $timecredit) {  // valid but expired
146
        captiveportal_logportalauth($voucher,$clientmac,$clientip,"FAILURE","voucher expired");
147
        portal_reply_page($redirurl, "error", $config['voucher']['msgexpired']);
148
    } else {
149
        captiveportal_logportalauth($voucher,$clientmac,$clientip,"FAILURE");
150
        portal_reply_page($redirurl, "error", $config['voucher']['msgnoaccess']);
151
    }
152

    
153
} else if ($_POST['accept'] && $radius_enable) {
154

    
155
    if ($_POST['auth_user'] && $_POST['auth_pass']) {
156
        $auth_list = radius($_POST['auth_user'],$_POST['auth_pass'],$clientip,$clientmac,"USER LOGIN");
157
	$type = "error";
158
	if (!empty($auth_list['url_redirection'])) {
159
		$redirurl = $auth_list['url_redirection'];
160
		$type = "redir";
161
	}
162

    
163
        if ($auth_list['auth_val'] == 1) {
164
            captiveportal_logportalauth($_POST['auth_user'],$clientmac,$clientip,"ERROR",$auth_list['error']);
165
 	    portal_reply_page($redirurl, $type, $auth_list['error']);
166
        }
167
        else if ($auth_list['auth_val'] == 3) {
168
            captiveportal_logportalauth($_POST['auth_user'],$clientmac,$clientip,"FAILURE",$auth_list['reply_message']);
169
            portal_reply_page($redirurl, $type, $auth_list['reply_message']);
170
        }
171
    } else {
172
        captiveportal_logportalauth($_POST['auth_user'],$clientmac,$clientip,"ERROR");
173
        portal_reply_page($redirurl, "error", "Invalid username/password specified.");
174
    }
175

    
176
} else if ($_POST['accept'] && $config['captiveportal']['auth_method'] == "local") {
177

    
178
	//check against local user manager
179
	$loginok = local_backed($_POST['auth_user'], $_POST['auth_pass']);
180
    if ($loginok){
181
        captiveportal_logportalauth($_POST['auth_user'],$clientmac,$clientip,"LOGIN");
182
        portal_allow($clientip, $clientmac,$_POST['auth_user']);
183
    } else {
184
        captiveportal_logportalauth($_POST['auth_user'],$clientmac,$clientip,"FAILURE");
185
        portal_reply_page($redirurl, "error");
186
    }
187
} else if ($_POST['accept'] && $clientip) {
188
    captiveportal_logportalauth("unauthenticated",$clientmac,$clientip,"ACCEPT");
189
    portal_allow($clientip, $clientmac, "unauthenticated");
190
} else {
191
    /* display captive portal page */
192
    portal_reply_page($redirurl, "login",null,$clientmac,$clientip);
193
}
194

    
195
exit;
196

    
197
function portal_reply_page($redirurl, $type = null, $message = null, $clientmac = null, $clientip = null, $username = null, $password = null) {
198
    global $g, $config;
199

    
200
    /* Get captive portal layout */
201
    if ($type == "redir") {
202
	header("Location: {$redirurl}");
203
	return;
204
    } else if ($type == "login")
205
        $htmltext = get_include_contents("{$g['varetc_path']}/captiveportal.html");
206
    else
207
        $htmltext = get_include_contents("{$g['varetc_path']}/captiveportal-error.html");
208

    
209
    /* substitute other variables */
210
    if (isset($config['captiveportal']['httpslogin'])) {
211
        $htmltext = str_replace("\$PORTAL_ACTION\$", "https://{$config['captiveportal']['httpsname']}:8001/", $htmltext);
212
        $htmltext = str_replace("#PORTAL_ACTION#", "https://{$config['captiveportal']['httpsname']}:8001/", $htmltext);
213
    } else {
214
		$ifip = portal_ip_from_client_ip($clientip);
215
    	if (!$ifip)
216
        	$ourhostname = $config['system']['hostname'] . ":8000";
217
    	else
218
        	$ourhostname = "{$ifip}:8000";
219
        $htmltext = str_replace("\$PORTAL_ACTION\$", "http://{$ourhostname}/", $htmltext);
220
        $htmltext = str_replace("#PORTAL_ACTION#", "http://{$ourhostname}/", $htmltext);
221
    }
222

    
223
    $htmltext = str_replace("\$PORTAL_REDIRURL\$", htmlspecialchars($redirurl), $htmltext);
224
    $htmltext = str_replace("\$PORTAL_MESSAGE\$", htmlspecialchars($message), $htmltext);
225
    $htmltext = str_replace("\$CLIENT_MAC\$", htmlspecialchars($clientmac), $htmltext);
226
    $htmltext = str_replace("\$CLIENT_IP\$", htmlspecialchars($clientip), $htmltext);
227

    
228
	// Special handling case for captive portal master page so that it can be ran 
229
	// through the PHP interpreter using the include method above.  We convert the
230
	// $VARIABLE$ case to #VARIABLE# in /etc/inc/captiveportal.inc before writing out.
231
	$htmltext = str_replace("#PORTAL_REDIRURL#", htmlspecialchars($redirurl), $htmltext);
232
	$htmltext = str_replace("#PORTAL_MESSAGE#", htmlspecialchars($message), $htmltext);
233
	$htmltext = str_replace("#CLIENT_MAC#", htmlspecialchars($clientmac), $htmltext);
234
	$htmltext = str_replace("#CLIENT_IP#", htmlspecialchars($clientip), $htmltext);
235
	$htmltext = str_replace("#USERNAME#", htmlspecialchars($username), $htmltext);
236
	$htmltext = str_replace("#PASSWORD#", htmlspecialchars($password), $htmltext);
237

    
238
    echo $htmltext;
239
}
240

    
241
function portal_mac_radius($clientmac,$clientip) {
242
    global $config ;
243

    
244
    $radmac_secret = $config['captiveportal']['radmac_secret'];
245

    
246
    /* authentication against the radius server */
247
    $username = mac_format($clientmac);
248
    $auth_list = radius($username,$radmac_secret,$clientip,$clientmac,"MACHINE LOGIN");
249
    if ($auth_list['auth_val'] == 2)
250
        return TRUE;
251
    if (!empty($auth_list['url_redirection']))
252
	portal_reply_page($auth_list['url_redirection'], "redir");
253

    
254
    return FALSE;
255
}
256

    
257
function portal_allow($clientip,$clientmac,$username,$password = null, $attributes = null, $ruleno = null)  {
258

    
259
	global $redirurl, $g, $config, $type, $passthrumac, $_POST;
260

    
261
	/* See if a ruleno is passed, if not start locking the sessions because this means there isn't one atm */
262
	$captiveshouldunlock = false;
263
	if ($ruleno == null) {
264
		$cplock = lock('captiveportal');
265
		$captiveshouldunlock = true;
266
		$ruleno = captiveportal_get_next_ipfw_ruleno();
267
	}
268

    
269
	/* if the pool is empty, return appropriate message and exit */
270
	if (is_null($ruleno)) {
271
		portal_reply_page($redirurl, "error", "System reached maximum login capacity");
272
		log_error("WARNING!  Captive portal has reached maximum login capacity");
273
		if ($captiveshouldunlock == true)
274
		unlock($cplock);
275
		exit;
276
	}
277

    
278
	// Ensure we create an array if we are missing attributes
279
	if (!is_array($attributes))
280
		$attributes = array();
281

    
282
	/* read in client database */
283
	$cpdb = captiveportal_read_db();
284

    
285
	$radiusservers = captiveportal_get_radius_servers();
286

    
287
	if ($attributes['voucher'])
288
		$remaining_time = $attributes['session_timeout'];
289

    
290
	$writecfg = false;
291
	/* Find an existing session */
292
	if ((isset($config['captiveportal']['noconcurrentlogins'])) && $passthrumac) {
293
		if (isset($config['captiveportal']['passthrumacadd'])) {
294
			$mac = captiveportal_passthrumac_findbyname($username);
295
			if (!empty($mac)) {
296
				if ($_POST['replacemacpassthru']) {
297
					foreach ($config['captiveportal']['passthrumac'] as $idx => $macent) {
298
						if ($macent['mac'] == $mac['mac']) {
299
							$macrules = "";
300
							$ruleno = captiveportal_get_ipfw_passthru_ruleno($mac['mac']);
301
                                			if ($ruleno) {
302
								captiveportal_free_ipfw_ruleno($ruleno, true);
303
                                        			$macrules .= "delete {$ruleno}\n";
304
								++$ruleno;
305
                                        			$macrules .= "delete {$ruleno}\n";
306
                                			}
307
							unset($config['captiveportal']['passthrumac'][$idx]);
308
							$mac['mac'] = $clientmac;
309
							$config['captiveportal']['passthrumac'][] = $mac;
310
							$macrules .= captiveportal_passthrumac_configure_entry($mac);
311
							file_put_contents("{$g['tmp_path']}/macentry.rules.tmp", $macrules);
312
							mwexec("/sbin/ipfw -q {$g['tmp_path']}/macentry.rules.tmp");
313
							$writecfg = true;
314
							$sessionid = true;
315
							break;
316
						}
317
					}
318
                                } else {
319
					portal_reply_page($redirurl, "error", "Username: {$username} is known with another mac address.",
320
						$clientmac, $clientip, $username, $password);
321
					exit;
322
				}
323
			}
324
		}
325
	}
326

    
327
	$nousers = count($cpdb);
328
	for ($i = 0; $i < $nousers; $i++) {
329
		/* on the same ip */
330
		if($cpdb[$i][2] == $clientip) {
331
			captiveportal_logportalauth($cpdb[$i][4],$cpdb[$i][3],$cpdb[$i][2],"CONCURRENT LOGIN - REUSING OLD SESSION");
332
			$sessionid = $cpdb[$i][5];
333
			break;
334
		}
335
		elseif (($attributes['voucher']) && ($username != 'unauthenticated') && ($cpdb[$i][4] == $username)) {
336
			// user logged in with an active voucher. Check for how long and calculate 
337
			// how much time we can give him (voucher credit - used time)
338
			$remaining_time = $cpdb[$i][0] + $cpdb[$i][7] - time();
339
			if ($remaining_time < 0)    // just in case. 
340
				$remaining_time = 0;
341

    
342
			/* This user was already logged in so we disconnect the old one */
343
			captiveportal_disconnect($cpdb[$i],$radiusservers,13);
344
			captiveportal_logportalauth($cpdb[$i][4],$cpdb[$i][3],$cpdb[$i][2],"CONCURRENT LOGIN - TERMINATING OLD SESSION");
345
			unset($cpdb[$i]);
346
			break;
347
		}
348
		elseif ((isset($config['captiveportal']['noconcurrentlogins'])) && ($username != 'unauthenticated')) {
349
			/* on the same username */
350
			if (strcasecmp($cpdb[$i][4], $username) == 0) {
351
				/* This user was already logged in so we disconnect the old one */
352
				captiveportal_disconnect($cpdb[$i],$radiusservers,13);
353
				captiveportal_logportalauth($cpdb[$i][4],$cpdb[$i][3],$cpdb[$i][2],"CONCURRENT LOGIN - TERMINATING OLD SESSION");
354
				unset($cpdb[$i]);
355
				break;
356
			}
357
		}
358
	}
359

    
360
	if ($attributes['voucher'] && $remaining_time <= 0) {
361
		unlock($cplock);
362
		return 0;       // voucher already used and no time left
363
	}
364

    
365
	if (!isset($sessionid)) {
366

    
367
		/* generate unique session ID */
368
		$tod = gettimeofday();
369
		$sessionid = substr(md5(mt_rand() . $tod['sec'] . $tod['usec'] . $clientip . $clientmac), 0, 16);
370

    
371
		/* Add rules for traffic shaping
372
		 * We don't need to add extra rules since traffic will pass due to the following kernel option
373
		 * net.inet.ip.fw.one_pass: 1
374
		 */
375
		$peruserbw = isset($config['captiveportal']['peruserbw']);
376

    
377
		$bw_up = isset($attributes['bw_up']) ? trim($attributes['bw_up']) : $config['captiveportal']['bwdefaultup'];
378
		$bw_down = isset($attributes['bw_down']) ? trim($attributes['bw_down']) : $config['captiveportal']['bwdefaultdn'];
379

    
380
		if ($passthrumac) {
381
			$mac = array();
382
			$mac['mac'] = $clientmac;
383
			if (isset($config['captiveportal']['passthrumacaddusername']))
384
				$mac['username'] = $username;
385
			$mac['descr'] =  "Auto added pass-through MAC for user {$username}";
386
			if (!empty($bw_up))
387
				$mac['bw_up'] = $bw_up;
388
			if (!empty($bw_down))
389
				$mac['bw_down'] = $bw_down;
390
			if (!is_array($config['captiveportal']['passthrumac']))
391
				$config['captiveportal']['passthrumac'] = array();
392
			$config['captiveportal']['passthrumac'][] = $mac;
393
			$macrules = captiveportal_passthrumac_configure_entry($mac);
394
			file_put_contents("{$g['tmp_path']}/macentry.rules.tmp", $macrules);
395
			mwexec("/sbin/ipfw -q {$g['tmp_path']}/macentry.rules.tmp");
396
			$writecfg = true;
397
		} else {
398

    
399
			if ($peruserbw && !empty($bw_up) && is_numeric($bw_up)) {
400
				$bw_up_pipeno = $ruleno + 20000;
401
				//$bw_up /= 1000; // Scale to Kbit/s
402
				mwexec("/sbin/ipfw pipe {$bw_up_pipeno} config bw {$bw_up}Kbit/s queue 100");
403

    
404
				if (!isset($config['captiveportal']['nomacfilter']))
405
					mwexec("/sbin/ipfw table 1 add {$clientip} mac {$clientmac} {$bw_up_pipeno}");
406
				else
407
					mwexec("/sbin/ipfw table 1 add {$clientip} {$bw_up_pipeno}");
408
			} else {
409
				if (!isset($config['captiveportal']['nomacfilter']))
410
					mwexec("/sbin/ipfw table 1 add {$clientip} mac {$clientmac}");
411
				else
412
					mwexec("/sbin/ipfw table 1 add {$clientip}");
413
			}
414
			if ($peruserbw && !empty($bw_down) && is_numeric($bw_down)) {
415
				$bw_down_pipeno = $ruleno + 20001;
416
				//$bw_down /= 1000; // Scale to Kbit/s
417
				mwexec("/sbin/ipfw pipe {$bw_down_pipeno} config bw {$bw_down}Kbit/s queue 100");
418

    
419
				if (!isset($config['captiveportal']['nomacfilter']))
420
					mwexec("/sbin/ipfw table 2 add {$clientip} mac {$clientmac} {$bw_down_pipeno}");
421
				else
422
					mwexec("/sbin/ipfw table 2 add {$clientip} {$bw_down_pipeno}");
423
			} else {
424
				if (!isset($config['captiveportal']['nomacfilter']))
425
					mwexec("/sbin/ipfw table 2 add {$clientip} mac {$clientmac}");
426
				else
427
					mwexec("/sbin/ipfw table 2 add {$clientip}");
428
			}
429

    
430
			if ($attributes['voucher'])
431
				$attributes['session_timeout'] = $remaining_time;
432

    
433
			/* encode password in Base64 just in case it contains commas */
434
			$bpassword = base64_encode($password);
435
			$cpdb[] = array(time(), $ruleno, $clientip, $clientmac, $username, $sessionid, $bpassword,
436
				$attributes['session_timeout'], $attributes['idle_timeout'], $attributes['session_terminate_time']);
437

    
438
			if (isset($config['captiveportal']['radacct_enable']) && !empty($radiusservers)) {
439
				$acct_val = RADIUS_ACCOUNTING_START($ruleno,
440
                                		$username, $sessionid, $radiusservers, $clientip, $clientmac);
441

    
442
				if ($acct_val == 1)
443
					captiveportal_logportalauth($username,$clientmac,$clientip,$type,"RADIUS ACCOUNTING FAILED");
444
			}
445

    
446
			/* rewrite information to database */
447
			captiveportal_write_db($cpdb);
448
		}
449
	}
450

    
451
	if ($captiveshouldunlock == true)
452
		unlock($cplock);
453

    
454
	if ($writecfg == true)
455
		write_config();
456

    
457
	/* redirect user to desired destination */
458
	if (!empty($attributes['url_redirection']))
459
		$my_redirurl = $attributes['url_redirection'];
460
	else if ($config['captiveportal']['redirurl'])
461
		$my_redirurl = $config['captiveportal']['redirurl'];
462
	else
463
		$my_redirurl = $redirurl;
464

    
465
	if(isset($config['captiveportal']['logoutwin_enable']) && !$passthrumac) {
466

    
467
		if (isset($config['captiveportal']['httpslogin']))
468
			$logouturl = "https://{$config['captiveportal']['httpsname']}:8001/";
469
		else {
470
			$ifip = portal_ip_from_client_ip($clientip);
471
			if (!$ifip)
472
				$ourhostname = $config['system']['hostname'] . ":8000";
473
			else
474
				$ourhostname = "{$ifip}:8000";
475
			$logouturl = "http://{$ourhostname}/";
476
		}
477

    
478
		include("{$g['varetc_path']}/captiveportal-logout.html");
479

    
480
	} else {
481
		if($_POST['ORIGINAL_PORTAL_IP'] && $_SERVER['SERVER_NAME'] != $_POST['ORIGINAL_PORTAL_IP']) {
482
 			header ('HTTP/1.1 301 Moved Permanently');
483
			header("Location: " . $_POST['ORIGINAL_PORTAL_IP']);
484
		} else {
485
			header("Location: " . $my_redirurl);
486
		}
487
	}
488

    
489
	return $sessionid;
490
}
491

    
492

    
493

    
494
/* remove a single client by session ID
495
   by Dinesh Nair
496
 */
497
function disconnect_client($sessionid, $logoutReason = "LOGOUT", $term_cause = 1) {
498

    
499
    global $g, $config;
500

    
501
    $cplock = lock('captiveportal');
502
    /* read database */
503
    $cpdb = captiveportal_read_db();
504

    
505
    $radiusservers = captiveportal_get_radius_servers();
506

    
507
    /* find entry */
508
    $dbcount = count($cpdb);
509
    for ($i = 0; $i < $dbcount; $i++) {
510
        if ($cpdb[$i][5] == $sessionid) {
511
            captiveportal_disconnect($cpdb[$i],$radiusservers, $term_cause);
512
            captiveportal_logportalauth($cpdb[$i][4],$cpdb[$i][3],$cpdb[$i][2],$logoutReason);
513
            unset($cpdb[$i]);
514
            break;
515
        }
516
    }
517

    
518
    /* write database */
519
    captiveportal_write_db($cpdb);
520

    
521
    unlock($cplock);
522
}
523

    
524
?>
(1-1/3)