<?php
/**
*
* @author Benjamin Gillissen <hide@address.com>
*
* **************************************************************
Copyright (C) 2009 Benjamin Gillissen
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details at:
http://www.gnu.org/copyleft/gpl.html
* **************************************************************
*/
/**
*
* acces type : [a] userID,
* [b] group_member,
* [c] group_admin,
* [d] other
* [e] net mac
* [f] net ip
* [g] net netmask
[g] ip range
* [h] net domain name
*
*
function ip_in_range($ip, $ip_one, $ip_two=false){
if($ip_two===false){
if($ip_one==$ip){
$o=true;
}else{
$o=false;
}
}else{
if(ip2long($ip_one)<=ip2long($ip) && ip2long($ip_two)>=ip2long($ip)){
$o=true;
}else{
$o=false;
}
}
return $o;
}
//usage
echo in_ip_range('192.168.0.0','192.168.1.254');
*/
class acl_conf {
private static $CHK = Array('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h');
private static $ACT = Array('List', 'Read', 'Add', 'Edit', 'Delete', 'Manage', 'Chmod', 'Upload', 'Overwrite', 'Post');
private $realm, $conf, $chk;
public function __construct($realm){
$this->realm = $realm;
unset($realm);
$this->conf = configs::get('realm', 'realm', Array($this->realm, 'acl_opt'));
if ( FALSE === $this->conf ){
errors::raise("Realm $this->realm : missing 'acl_opt' option for conf acl engine", CORE_LOG_ALERT, 'REALM');
return;
}
$this->chk = configs::get('realm', 'realm', Array($this->realm, 'acl_checks'));
if ( FALSE === $this->chk ){
errors::raise("Realm $this->realm : missing 'acl_checks' option, using all", CORE_LOG_WARNING, 'REALM');
$this->chk = self::$CHK;
} elseif ( FALSE === is_array($this->chk) ){
//no overwrite possible...die...
errors::raise("Realm $this->realm : Invalid 'acl_checks' option, must be an array of chars !", CORE_LOG_ALERT, 'REALM');
return;
} else {
foreach($this->chk as $k => $char ){
if ( FALSE === array_search($char, self::$CHK) ){
errors::raise("Realm $this->realm : Invalid 'acl_checks' entry, $char is not valid !", CORE_LOG_WARNING, 'REALM');
unset($this->chk[$k]);
}
}
if ( count($this->chk) == 0 ){
errors::raise("Realm $this->realm : Invalid 'acl_checks' option, no entry left after cleaning !", CORE_LOG_ALERT, 'REALM');
return;
}
}
}
private function isvalid_checks($char){ return ( FALSE !== array_search($char, $this->chk) ); }
private function isvalid_actions($act){
return ( FALSE !== array_search($act, self::$ACT) );
}
public function ispublic($obj, $action, $objid=NULL){
$r = $this->getcount($obj, $action, $objid, '1', 'd', '');
//echo 'RESULT FOR : '.$obj.' - '.$action.' - '.$objid.' - 1 - d - "" => '.$r.'<br>';
return ($r != 0);
}
public function checks($obj, $action, $uid, $mbrship, $objid ){
//echo "acl_checks => $obj::$action::$objid<br>\n";
/*
if ( $obj != 'objects' ){
if ( FALSE === $this->get_acclevel('objects', $action, $uid, $mbrship, $obj) ){ return FALSE; }
} elseif( $objid != 'objects' ){
if ( FALSE === $this->get_acclevel('objects', $action, $uid, $mbrship, 'objects') ){ return FALSE; }
}
*/
if ( FALSE !== ($acc = $this->get_acclevel($obj, $action, $uid, $mbrship, $objid)) ){
//errors::raise('check OK acc=>'.$acc, CORE_LOG_WARNING, 'REALM');
return TRUE;
}
return FALSE;
}
public function get_acclevel($obj, $action, $uid, $mbrship, $objid){
if ( $this->getcount($obj, $action, $objid, '1', 'a', $uid) ){ return 'a'; }
foreach($mbrship as $lvl => $grps ){
if ($lvl == 'member' ){ $acc = 'b'; } else { $acc = 'c'; }
foreach($grps as $k => $grp){
if ( $this->getcount($obj, $action, $objid, '1', $acc, $grp) ){ return $acc; }
}
}
if ( $this->gotaccrules($obj, $action, $objid, 'f') ){
if ( $this->getcount($obj, $action, $objid, '1', 'f', client::host()) ){ return 'f'; }
}
if ( $this->gotaccrules($obj, $action, $objid, 'g') ){
//TODO NET MASK COMPUTATION, client::inetmask($mask);
//need to list rules to use value to client::inetmask($val);
}
if ( $this->gotaccrules($obj, $action, $objid, 'h') ){
$cns = gethostbyaddr(client::host());
//need to list rules to use value to pass an ereg, to allow *.example.org
if ( $this->getcount($obj, $action, $objid, '1', 'h', $cns) ){ return 'h'; }
unset($cns);
}
if ( $this->getcount($obj, $action, $objid, '1', 'd', '') ){ return 'd'; }
return FALSE;
}
private function gotaccrules($obj, $action, $objid, $acc){
$entries = configs::get($this->conf, $obj, Array($objid, $action) );
if ( FALSE === $entries ){ return FALSE; } //not defined for this object, objectID, action
foreach($entries as $k => $rule ){
if ( $acc == $rule[0] ){ return TRUE; }
}
return FALSE;
}
private function getcount($obj, $action, $objid, $bool, $acc, $val){
$entries = configs::get($this->conf, $obj, Array($objid, $action) );
if ( FALSE === $entries ){ return 0; } //not defined for this object, objectID, action
foreach($entries as $k => $rule ){
if ( $acc == $rule[0] AND $val == $rule[1] ){ return 1; }
}
return 0;
}
public function add($obj, $action, $objid, $bool, $acc, $val){
$arg=Array('obj'=>$obj,'action'=>$action, 'objid'=>$objid, 'bool'=>$bool, 'acc'=>$acc, 'val'=>$val);
return $this->dbquery($arg, __FUNCTION__);
}
public function delete($obj, $action, $objid, $bool, $acc, $val){
$arg=Array('obj'=>$obj,'action'=>$action, 'objid'=>$objid, 'bool'=>$bool, 'acc'=>$acc, 'val'=>$val);
return $this->dbquery($arg, __FUNCTION__);
}
public function del_byuid($uid){
$arg=Array('id'=>$uid);
return $this->dbquery($arg, __FUNCTION__);
}
public function del_bygid($gid){
$arg=Array('id'=>$gid);
return $this->dbquery($arg, __FUNCTION__);
}
public function del_byobjid($object, $objid){
$arg=Array('objid'=>$objid, 'obj'=>$object);
return $this->dbquery($arg, __FUNCTION__);
}
public function del_byobject($object){
$arg=Array('obj'=>$object);
return $this->dbquery($arg, __FUNCTION__);
}
public function list_rules($object, $objid){
$arg=Array('objid'=>$objid, 'obj'=>$object);
return $this->dbquery($arg, __FUNCTION__, 'aclid');
}
public function get_rule($aclid){
$arg=Array('aclid'=>$aclid);
return $this->dbquery($arg, __FUNCTION__);
}
}