Based on ideas from Linux trustees code by Vyacheslav Zavadsky .trustee.acl file format: # is a comment # define groups (line stats with +) +name_of_group:user[,user...] # define acls path[/file]:([user|+group|*]:[!][C|D|O][RWB])[:...] e.g.: # dpavlin is admin (grant all access to members of root group) +root:dpavlin # give read-only access to all users /:*:R # anyone can write in this file /public_write.txt:*:w # let just joe access secret file /secret:joe:!CRW group names are written with + before name * is wildcard for all users modifiers: ! trustee applies to all except user or group C clear the persmission (default is to set) D deny access (default is grant) O one level -- don't recurse into subdirectories permissions: R read (file) W write (file) B browse (directory) this file will be compiled into .trustee.php on demand. ***************** FIX: one level is not implemented. I can't find use for it! */ $fsScriptDir="/home/dpavlin/t/"; // FIX -- remove $trustee_conf="$fsScriptDir/.trustee.conf"; $trustee_php="$fsScriptDir/.trustee.php"; define(trmask_not,1 << 0); define(trmask_clear,1 << 1); define(trmask_deny,1 << 2); define(trmask_one_level,1 << 3); define(trmask_group,1 << 4); define(trperm_r,1 << 5); define(trperm_w,1 << 6); define(trperm_b,1 << 7); $trustee_a2n = array( '!' => trmask_not, 'C' => trmask_clear, 'D' => trmask_deny, 'O' => trmask_one_level, '+' => trmask_group, 'R' => trperm_r, 'W' => trperm_w, 'B' => trperm_b ); // debugging function function display_trustee($t) { global $trustee_a2n; $out=""; while (list ($c,$v) = each($trustee_a2n)) { if ($t & $v) $out.=$c; } return $out; } function init_trustee() { global $trustee_conf,$trustee_php,$trustee_a2n,$groups,$trustees; // do we need to re-create compiled trustees? if (! file_exists($trustee_conf)) { $error="$trustee_conf doesn't exits"; } elseif (file_exists($trustee_conf) && !is_readable($trustee_conf)) { $error="$trustee_conf exits, but is not readable"; } elseif (!is_writable(dirname($trustee_php))) { $error=dirname($trustee_php)." must be writable by web server user"; } elseif (!is_writable($trustee_php)) { $error="$trustee_php exits, but is not writable"; } elseif (1 || filemtime($trustee_conf) >= filemtime($trustee_php)) { $fp_php=@fopen($trustee_php,"w"); fputs($fp_php,"array("; $sep2=""; while ($user=array_shift($arr)) { print "$user"; $perm=0; if (substr($user,0,1) == "+") { $perm|=trmask_group; $user=substr($user,1,strlen($user)-1); } $perm_ascii=array_shift($arr); print "$perm_ascii <--
\n"; for ($i=0;$i\n"; } $tr_out.="$sep2\n\t\t'$user'=>$perm"; $sep2=","; } $tr_out.="\n\t)"; $sep1=","; } } $tr_out.="\n);\n"; fclose($fp_conf); // save groups $gr_out='$groups = array ('; $sep=""; while (list ($group, $members) = each ($groups_arr)) { $gr_out.="$sep\n\t'"; $gr_out.=substr($group,1,strlen($group)-1); $gr_out.="'=>array('".join("','",explode(",",$members))."')"; $sep=","; } $gr_out.="\n);\n"; print "
$gr_out\n$tr_out

\n"; fputs($fp_php,$gr_out); fputs($fp_php,$tr_out); fputs($fp_php,"?>\n"); fclose($fp_php); } if ($error) { print "$error"; // FIX } else { include("$trustee_php"); } }//init_trustee // global functions replacements for is_writable function in_group($user,$group) { return in_array($groups[$group],$user); } function docman_readable($user,$path) { global $trustees; global $t,$u,$perm_deny,$perm_allow; //FIX print "
";
	$perm_allow = 0;
	$perm_deny = 0;
	$path_arr=explode("/",$path);
	print $path_arr[1]."<--\n";
	$path = "/";
//------
global $t,$u,$perm_deny,$perm_allow;
function x($foo) {
	global $t,$u,$perm_deny,$perm_allow;
	print "$foo t: $t [".display_trustee($t)."] u: $u deny: $perm_deny allow: $perm_allow\n";
}
//------
	while (count($path_arr)) {
		if (substr($path,strlen($path)-1,1) != "/") $path.="/";
		$path.=array_shift($path_arr);
		print "\n## test: $path\n";
		if (isset($trustees[$path])) while (list($u,$t) = each($trustees[$path])) {
			x("new trustee...");
			x("resolv group!");
			if ($tr & trmask_group && in_group($user,$u)) {
				// resolv user
				$t = $t & ~trmask_group;
				$u = $user;
			}
			
			x("resolv user! u: '$u'");
			if ($u == "*") $u=$user;

			// check user
			x("have not? ".($t & trmask_not));
			if ($t & trmask_not && ($u==$user)) continue;
			if (!($t & trmask_not) && ($u!=$user)) continue;

			if ($t & trmask_deny) {
				if ($t & trmask_clear) {
					$perm_deny |= $t;
					x(1);
				} else {
					$perm_deny &= ~$t;
					x(2);
				}
			} elseif ($t & trmask_clear) {
				$perm_allow &= ~$t;
				x(3);
			} else {
				$perm_allow |= $t;
				x(4);
			}
		}
	}
	print "
"; return "deny: $perm_deny allow: $perm_allow"; } // FIX $user = "popov"; $path = "/secret/folder"; init_trustee(); print "
$user -- $path -- \n".docman_readable($user,$path)."\n
"; ?>