mirror of
https://github.com/pfsense/pfsense.git
synced 2025-10-26 11:38:35 +00:00
merge Ermal's CP locking changes
This commit is contained in:
parent
03ef91efda
commit
8751763c64
@ -46,6 +46,8 @@ $lockfile = "{$g['varrun_path']}/captiveportal.lock";
|
||||
function captiveportal_configure() {
|
||||
global $config, $g;
|
||||
|
||||
$captiveportallck = lock('captiveportal');
|
||||
|
||||
if (isset($config['captiveportal']['enable']) &&
|
||||
(($config['captiveportal']['interface'] == "lan") ||
|
||||
isset($config['interfaces'][$config['captiveportal']['interface']]['enable']))) {
|
||||
@ -81,7 +83,7 @@ function captiveportal_configure() {
|
||||
mwexec("kldload dummynet");
|
||||
|
||||
/* stop accounting on all clients */
|
||||
captiveportal_radius_stop_all();
|
||||
captiveportal_radius_stop_all(true);
|
||||
|
||||
/* initialize minicron interval value */
|
||||
$croninterval = $config['captiveportal']['croninterval'] ? $config['captiveportal']['croninterval'] : 60;
|
||||
@ -229,9 +231,9 @@ EOD;
|
||||
"/etc/rc.prunecaptiveportal");
|
||||
|
||||
/* generate passthru mac database */
|
||||
captiveportal_passthrumac_configure();
|
||||
captiveportal_passthrumac_configure(true);
|
||||
/* create allowed ip database and insert ipfw rules to make it so */
|
||||
captiveportal_allowedip_configure();
|
||||
captiveportal_allowedip_configure(true);
|
||||
|
||||
/* generate radius server database */
|
||||
if ($config['captiveportal']['radiusip'] && (!isset($config['captiveportal']['auth_method']) ||
|
||||
@ -277,7 +279,7 @@ EOD;
|
||||
killbypid("{$g['varrun_path']}/lighty-CaptivePortal.pid");
|
||||
killbypid("{$g['varrun_path']}/minicron.pid");
|
||||
|
||||
captiveportal_radius_stop_all();
|
||||
captiveportal_radius_stop_all(true);
|
||||
|
||||
mwexec("/sbin/sysctl net.link.ether.ipfw=0");
|
||||
|
||||
@ -298,8 +300,7 @@ EOD;
|
||||
mwexec("/sbin/ipfw -f delete set 3");
|
||||
}
|
||||
}
|
||||
|
||||
captiveportal_unlock();
|
||||
unlock($captiveportallck);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -458,7 +459,7 @@ function captiveportal_prune_old() {
|
||||
if (!$timeout && !$idletimeout && !isset($config['captiveportal']['reauthenticate']) && !isset($config['captiveportal']['radiussession_timeout']))
|
||||
return;
|
||||
|
||||
captiveportal_lock();
|
||||
$captiveportallck = lock('captiveportal');
|
||||
|
||||
/* read database */
|
||||
$cpdb = captiveportal_read_db();
|
||||
@ -585,7 +586,7 @@ function captiveportal_prune_old() {
|
||||
/* write database */
|
||||
captiveportal_write_db($cpdb);
|
||||
|
||||
captiveportal_unlock();
|
||||
unlock($captiveportallck);
|
||||
}
|
||||
|
||||
/* remove a single client according to the DB entry */
|
||||
@ -632,7 +633,7 @@ function captiveportal_disconnect_client($id,$term_cause = 1) {
|
||||
|
||||
global $g, $config;
|
||||
|
||||
captiveportal_lock();
|
||||
$captiveportallck = lock('captiveportal');
|
||||
|
||||
/* read database */
|
||||
$cpdb = captiveportal_read_db();
|
||||
@ -651,17 +652,19 @@ function captiveportal_disconnect_client($id,$term_cause = 1) {
|
||||
/* write database */
|
||||
captiveportal_write_db($cpdb);
|
||||
|
||||
captiveportal_unlock();
|
||||
unlock($captiveportallck);
|
||||
}
|
||||
|
||||
/* send RADIUS acct stop for all current clients */
|
||||
function captiveportal_radius_stop_all() {
|
||||
function captiveportal_radius_stop_all($lock = false) {
|
||||
global $g, $config;
|
||||
|
||||
if (!isset($config['captiveportal']['radacct_enable']))
|
||||
return;
|
||||
|
||||
captiveportal_lock();
|
||||
if (!$lock)
|
||||
$captiveportallck = lock('captiveportal');
|
||||
|
||||
$cpdb = captiveportal_read_db();
|
||||
|
||||
$radiusservers = captiveportal_get_radius_servers();
|
||||
@ -680,13 +683,15 @@ function captiveportal_radius_stop_all() {
|
||||
7); // Admin Reboot
|
||||
}
|
||||
}
|
||||
captiveportal_unlock();
|
||||
if (!$lock)
|
||||
unlock($captiveportallck);
|
||||
}
|
||||
|
||||
function captiveportal_passthrumac_configure() {
|
||||
function captiveportal_passthrumac_configure($lock = false) {
|
||||
global $config, $g;
|
||||
|
||||
captiveportal_lock();
|
||||
if (!$lock)
|
||||
$captiveportallck = lock('captiveportal');
|
||||
|
||||
/* clear out passthru macs, if necessary */
|
||||
unlink_if_exists("{$g['vardb_path']}/captiveportal_mac.db");
|
||||
@ -696,7 +701,8 @@ function captiveportal_passthrumac_configure() {
|
||||
$fd = @fopen("{$g['vardb_path']}/captiveportal_mac.db", "w");
|
||||
if (!$fd) {
|
||||
printf("Error: cannot open passthru mac DB file in captiveportal_passthrumac_configure().\n");
|
||||
captiveportal_unlock();
|
||||
if (!$lock)
|
||||
unlock($captiveportallck);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -725,16 +731,17 @@ function captiveportal_passthrumac_configure() {
|
||||
mwexec("/sbin/ipfw add 50 skipto 29900 ip from any to any MAC any {$ptm['mac']} keep-state");
|
||||
}
|
||||
}
|
||||
|
||||
captiveportal_unlock();
|
||||
if (!$lock)
|
||||
unlock($captiveportallck);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
function captiveportal_allowedip_configure() {
|
||||
function captiveportal_allowedip_configure($lock = false) {
|
||||
global $config, $g;
|
||||
|
||||
captiveportal_lock();
|
||||
if (!$lock)
|
||||
$captiveportallck = lock('captiveportal');
|
||||
|
||||
/* clear out existing allowed ips, if necessary */
|
||||
if (file_exists("{$g['vardb_path']}/captiveportal_ip.db")) {
|
||||
@ -763,7 +770,8 @@ function captiveportal_allowedip_configure() {
|
||||
$fd = @fopen("{$g['vardb_path']}/captiveportal_ip.db", "w");
|
||||
if (!$fd) {
|
||||
printf("Error: cannot open allowed ip DB file in captiveportal_allowedip_configure().\n");
|
||||
captiveportal_unlock();
|
||||
if (!$lock)
|
||||
unlock($captiveportallck);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -775,7 +783,8 @@ function captiveportal_allowedip_configure() {
|
||||
if (is_null($ruleno)) {
|
||||
printf("Error: system reached maximum login capacity, no free FW rulenos in captiveportal_allowedip_configure().\n");
|
||||
fclose($fd);
|
||||
captiveportal_unlock();
|
||||
if (!$lock)
|
||||
unlock($captiveportallck);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -796,7 +805,8 @@ function captiveportal_allowedip_configure() {
|
||||
fclose($fd);
|
||||
}
|
||||
|
||||
captiveportal_unlock();
|
||||
if (!$lock)
|
||||
unlock($captiveportallck);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -843,48 +853,6 @@ function captiveportal_get_radius_servers() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* lock captive portal information, decide that the lock file is stale after
|
||||
10 minutes and EXIT the process to not risk dataloss, issue warning in syslog every 1 minutes */
|
||||
function captiveportal_lock() {
|
||||
|
||||
global $lockfile;
|
||||
|
||||
$n = 1;
|
||||
while ($n) {
|
||||
/* open the lock file in append mode to avoid race condition */
|
||||
if ($fd = @fopen($lockfile, "x")) {
|
||||
/* succeeded */
|
||||
fclose($fd);
|
||||
if($n > 10) {
|
||||
captiveportal_syslog("LOCKINFO: Waiting for lock for $n seconds/s!");
|
||||
}
|
||||
return;
|
||||
} else {
|
||||
/* file locked, wait and try again */
|
||||
sleep(1);
|
||||
|
||||
if(($n % 60) == 0) {
|
||||
captiveportal_syslog("LOCKWARNING: waiting for lock for " . $n/60 . " minute/s!");
|
||||
if(($n % 600) == 0) {
|
||||
captiveportal_syslog("LOCKERROR: waiting for lock for 10 minute/s - EXITING PROCESS!");
|
||||
die("Can't get a lock");
|
||||
}
|
||||
}
|
||||
}
|
||||
$n++;
|
||||
}
|
||||
/* we never get here */
|
||||
}
|
||||
|
||||
/* unlock captive portal information file */
|
||||
function captiveportal_unlock() {
|
||||
|
||||
global $lockfile;
|
||||
|
||||
if (file_exists($lockfile))
|
||||
unlink($lockfile);
|
||||
}
|
||||
|
||||
/* log successful captive portal authentication to syslog */
|
||||
/* part of this code from php.net */
|
||||
function captiveportal_logportalauth($user,$mac,$ip,$status, $message = null) {
|
||||
@ -912,16 +880,17 @@ function radius($username,$password,$clientip,$clientmac,$type) {
|
||||
global $g, $config;
|
||||
|
||||
/* Start locking from the beginning of an authentication session */
|
||||
captiveportal_lock();
|
||||
$captiveportallck = lock('captiveportal');
|
||||
|
||||
$ruleno = captiveportal_get_next_ipfw_ruleno();
|
||||
|
||||
unlock($captiveportallck);
|
||||
|
||||
/* if the pool is empty, return apprioriate message and fail authentication */
|
||||
if (is_null($ruleno)) {
|
||||
$auth_list = array();
|
||||
$auth_list['auth_val'] = 1;
|
||||
$auth_list['error'] = "System reached maximum login capacity";
|
||||
captiveportal_unlock();
|
||||
return $auth_list;
|
||||
}
|
||||
|
||||
@ -934,6 +903,8 @@ function radius($username,$password,$clientip,$clientmac,$type) {
|
||||
$clientmac,
|
||||
$ruleno);
|
||||
|
||||
|
||||
$captiveportallck = lock('captiveportal');
|
||||
if ($auth_list['auth_val'] == 2) {
|
||||
captiveportal_logportalauth($username,$clientmac,$clientip,$type);
|
||||
$sessionid = portal_allow($clientip,
|
||||
@ -943,9 +914,8 @@ function radius($username,$password,$clientip,$clientmac,$type) {
|
||||
$auth_list,
|
||||
$ruleno);
|
||||
}
|
||||
else {
|
||||
captiveportal_unlock();
|
||||
}
|
||||
|
||||
unlock($captiveportallck);
|
||||
|
||||
return $auth_list;
|
||||
|
||||
@ -956,7 +926,7 @@ function captiveportal_read_db() {
|
||||
|
||||
global $g;
|
||||
|
||||
$cpdb = array();
|
||||
$cpdb = array();
|
||||
$fd = @fopen("{$g['vardb_path']}/captiveportal.db", "r");
|
||||
if ($fd) {
|
||||
while (!feof($fd)) {
|
||||
@ -1134,4 +1104,4 @@ function portal_mac_fixed($clientmac) {
|
||||
return FALSE ;
|
||||
}
|
||||
|
||||
?>
|
||||
?>
|
||||
|
||||
@ -343,6 +343,44 @@ function get_interface_list($mode = "active", $keyby = "physical", $vfaces = "")
|
||||
return $iflist;
|
||||
}
|
||||
|
||||
/* lock configuration file */
|
||||
function lock($lock) {
|
||||
global $g, $cfglckkeyconsumers;
|
||||
|
||||
if (!$lock)
|
||||
die("WARNING: You must give a name as parameter to lock() function.");
|
||||
if (!file_exists("{$g['tmp_path']}/{$lock}.lock"))
|
||||
@touch("{$g['tmp_path']}/{$lock}.lock");
|
||||
$config_lock_key = ftok("{$g['tmp_path']}/{$lock}.lock", 'a');
|
||||
$cfglckkey = sem_get($config_lock_key, 1);
|
||||
$cfglckkeyconsumers++;
|
||||
if (!sem_acquire($cfglckkey)) {
|
||||
log_error("WARNING: lock() - Could not acquire {$lock} lock!");
|
||||
sem_remove($cfglckkey);
|
||||
return NULL;
|
||||
} else if ($g['debug'])
|
||||
log_error("lock() - Got {$file} lock.");
|
||||
|
||||
return $cfglckkey;
|
||||
}
|
||||
|
||||
/* unlock configuration file */
|
||||
function unlock($cfglckkey = 0) {
|
||||
global $g, $cfglckkeyconsumers;
|
||||
|
||||
if (!$cfglckkey)
|
||||
return;
|
||||
|
||||
if (!sem_release($cfglckkey))
|
||||
log_error("WARNING: unlock() - Could not unlock lock.");
|
||||
else {
|
||||
if ($g['debug'])
|
||||
log_error("Released lock.");
|
||||
sem_remove($cfglckkey);
|
||||
}
|
||||
$cfglckkeyconsumers--;
|
||||
}
|
||||
|
||||
/* wrapper for exec() */
|
||||
function mwexec($command, $mute = true) {
|
||||
|
||||
|
||||
@ -219,8 +219,10 @@ function portal_allow($clientip,$clientmac,$username,$password = null, $attribut
|
||||
global $redirurl, $g, $config, $url_redirection, $type;
|
||||
|
||||
/* See if a ruleno is passed, if not start locking the sessions because this means there isn't one atm */
|
||||
$lockedcpnow = false;
|
||||
if ($ruleno == null) {
|
||||
captiveportal_lock();
|
||||
$cplock = lock('captiveportal');
|
||||
$lockedcpnow = true;
|
||||
$ruleno = captiveportal_get_next_ipfw_ruleno();
|
||||
}
|
||||
|
||||
@ -228,7 +230,8 @@ function portal_allow($clientip,$clientmac,$username,$password = null, $attribut
|
||||
if (is_null($ruleno)) {
|
||||
portal_reply_page($redirurl, "error", "System reached maximum login capacity");
|
||||
log_error("WARNING! Captive portal has reached maximum login capacity");
|
||||
captiveportal_unlock();
|
||||
if ($lockedcpnow == true)
|
||||
unlock($cplock);
|
||||
exit;
|
||||
}
|
||||
|
||||
@ -325,6 +328,8 @@ function portal_allow($clientip,$clientmac,$username,$password = null, $attribut
|
||||
/* rewrite information to database */
|
||||
captiveportal_write_db($cpdb);
|
||||
|
||||
if ($lockedcpnow == true)
|
||||
unlock($cplock);
|
||||
/* redirect user to desired destination */
|
||||
if ($url_redirection)
|
||||
$my_redirurl = $url_redirection;
|
||||
@ -373,11 +378,9 @@ document.location.href="{$my_redirurl}";
|
||||
|
||||
EOD;
|
||||
} else {
|
||||
captiveportal_unlock();
|
||||
header("Location: " . $my_redirurl);
|
||||
return $sessionid;
|
||||
}
|
||||
captiveportal_unlock();
|
||||
return $sessionid;
|
||||
}
|
||||
|
||||
@ -390,7 +393,8 @@ function disconnect_client($sessionid, $logoutReason = "LOGOUT", $term_cause = 1
|
||||
|
||||
global $g, $config;
|
||||
|
||||
captiveportal_lock();
|
||||
$cplock = lock('captiveportal');
|
||||
|
||||
/* read database */
|
||||
$cpdb = captiveportal_read_db();
|
||||
|
||||
@ -409,7 +413,7 @@ function disconnect_client($sessionid, $logoutReason = "LOGOUT", $term_cause = 1
|
||||
/* write database */
|
||||
captiveportal_write_db($cpdb);
|
||||
|
||||
captiveportal_unlock();
|
||||
unlock($cplock);
|
||||
}
|
||||
|
||||
?>
|
||||
?>
|
||||
|
||||
@ -57,37 +57,26 @@ function clientcmp($a, $b) {
|
||||
}
|
||||
|
||||
$cpdb = array();
|
||||
captiveportal_lock();
|
||||
$fp = @fopen("{$g['vardb_path']}/captiveportal.db","r");
|
||||
|
||||
if ($fp) {
|
||||
while (!feof($fp)) {
|
||||
$line = trim(fgets($fp));
|
||||
if ($line) {
|
||||
$cpent = explode(",", $line);
|
||||
if ($_GET['showact'])
|
||||
$cpent[5] = captiveportal_get_last_activity($cpent[1]);
|
||||
$cpdb[] = $cpent;
|
||||
}
|
||||
}
|
||||
|
||||
fclose($fp);
|
||||
|
||||
if ($_GET['order']) {
|
||||
if ($_GET['order'] == "ip")
|
||||
$order = 2;
|
||||
else if ($_GET['order'] == "mac")
|
||||
$order = 3;
|
||||
else if ($_GET['order'] == "user")
|
||||
$order = 4;
|
||||
else if ($_GET['order'] == "lastact")
|
||||
$order = 5;
|
||||
else
|
||||
$order = 0;
|
||||
usort($cpdb, "clientcmp");
|
||||
}
|
||||
$cpcontents = file("/var/db/captiveportal.db", FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
|
||||
foreach ($cpcontents as $cpcontent) {
|
||||
$cpent = explode(",", $cpcontent);
|
||||
if ($_GET['showact'])
|
||||
$cpent[5] = captiveportal_get_last_activity($cpent[1]);
|
||||
$cpdb[] = $cpent;
|
||||
}
|
||||
if ($_GET['order']) {
|
||||
if ($_GET['order'] == "ip")
|
||||
$order = 2;
|
||||
else if ($_GET['order'] == "mac")
|
||||
$order = 3;
|
||||
else if ($_GET['order'] == "user")
|
||||
$order = 4;
|
||||
else if ($_GET['order'] == "lastact")
|
||||
$order = 5;
|
||||
else
|
||||
$order = 0;
|
||||
usort($cpdb, "clientcmp");
|
||||
}
|
||||
captiveportal_unlock();
|
||||
?>
|
||||
<table class="sortable" width="100%" border="0" cellpadding="0" cellspacing="0">
|
||||
<tr>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user