--- docman.php 2002/07/28 12:14:18 1.14 +++ docman.php 2002/07/28 17:51:20 1.20 @@ -20,7 +20,7 @@ ////////////////////////////////////////////////////////////////// // CONFIGURATION OPTIONS -// error_reporting(4) ; // how verbose ? + error_reporting(E_ALL) ; // how verbose ? // from where to include auth_*.php modules? $gblIncDir = "/data/docman2"; @@ -84,14 +84,14 @@ LoadLanguage($HTTP_SERVER_VARS["HTTP_ACCEPT_LANGUAGE"]); // for security and configuration - $realm=$HTTP_SERVER_VARS[HTTP_HOST]; + $realm=$HTTP_SERVER_VARS["HTTP_HOST"]; - $fsDocumentRoot = dirname($HTTP_SERVER_VARS[SCRIPT_FILENAME]); + $fsDocumentRoot = dirname($HTTP_SERVER_VARS["SCRIPT_FILENAME"]); if ($fsDocumentRoot == "") Error("Configuration error","Can't get SCRIPT_FILENAME from your web server. Please set \$fsDocumentRoot in \$",1); // globals for later - $gblLogin = $HTTP_SERVER_VARS[PHP_AUTH_USER]; - $gblPasswd = $HTTP_SERVER_VARS[PHP_AUTH_PW]; + $gblLogin = $HTTP_SERVER_VARS["PHP_AUTH_USER"]; + $gblPasswd = $HTTP_SERVER_VARS["PHP_AUTH_PW"]; ////////////////////////////////////////////////////////////////// @@ -109,9 +109,8 @@ function StartHTML($title,$text="") { - global $html,$fsDocumentRoot,$HTTP_SERVER_VARS; + global $html,$fsDocumentRoot,$gblTitle,$HTTP_SERVER_VARS; - $title = $gblTitle." ".$title ; $host = $HTTP_SERVER_VARS["HTTP_HOST"] ; $self = $HTTP_SERVER_VARS["PHP_SELF"] ; @@ -138,7 +137,9 @@ } else { $url .= md5($gblLogin.$gblPasswd); } - if (isset($gblLogin) && $gblLogin != "" && ($gblPasswd == "" || !isset($gblPasswd))) { + if ( ( (isset($gblLogin) && $gblLogin != "") || + (!isset($gblLogin) || $gblLogin == "") + ) && ($gblPasswd == "" || !isset($gblPasswd))) { $url_title="login"; $url .= "&force_login=1"; } else { @@ -577,19 +578,30 @@ global $gblEditable, $gblIcon, $gblModDays, $webRoot, $gblHide, $gblIgnoreUnknownFileType, $gblRepositoryDir, + $gblLogin, $fsRealmDir, $realm, $realm_sep, - $HTTP_GET_VARS, $html, $realm_config; + $html, $realm_config, + $HTTP_GET_VARS, $HTTP_SERVER_VARS; $self = $HTTP_SERVER_VARS["PHP_SELF"] ; - if ($relDir == "") $relDir = "/"; + $relDir = chopsl($relDir)."/"; + $fsDir = $fsRoot.$relDir; // current directory - $fsDir = $fsRoot.$relDir."/"; // current directory + if (!is_dir($fsDir)) Error("Dir not found","Directory $relDir not found on filesystem at $fsDir",1) ; - if (!is_dir($fsDir)) Error("Dir not found",$relDir,1) ; + global $debug; + $debug .= "[$gblLogin|$relDir] before >"; + + if (! check_perm($relDir,trperm_b)) + Error("Access denied","User $gblLogin tried to access $relDir without valid trustee.",1); + $debug .= "< afeter"; $hide_items=",$gblHide,"; + $dirList = array(); + $fileList = array(); + // read directory contents if ( !($dir = @opendir($fsDir)) ) Error("Read Access denied",$relDir,1) ; @@ -614,7 +626,7 @@ closedir($dir) ; // scan deleted files - if ( $HTTP_GET_VARS["show_deleted"] == 1 && ($dir = @opendir("$fsDir/.del")) ) { + if ( HTTP_GET_VAR("show_deleted") == 1 && ($dir = @opendir("$fsDir/.del")) ) { while ($item = readdir($dir)) { if ( substr($item,0,1) == "." || strstr($hide_items,",$item,") || !check_perm($relDir.$item,trperm_w) ) continue ; $fileList[$item] = ".del/$item" ; @@ -629,7 +641,7 @@ // start navigation page $text = "Use this page to add, delete"; - if (! isset($HTTP_GET_VARS[show_deleted])) { + if (! isset($HTTP_GET_VARS["show_deleted"])) { $text .= ", undelete"; } $text .= " or revise files on this web site." ; @@ -655,8 +667,7 @@ return $out; } - $dsort = $HTTP_GET_VARS[dsort]; - if (! isset($dsort)) $dsort = "name"; // default directory sort + if (! HTTP_GET_VAR("dsort")) $dsort = "name"; // default directory sort $dsort_arr = array( "name" => array ("rname", "note"), @@ -665,8 +676,7 @@ "rnote" => array ("name", "note") ); - $fsort = $HTTP_GET_VARS[fsort]; - if (! isset($fsort)) $fsort = "name"; // default directory sort + if (! HTTP_GET_VAR("fsort")) $fsort = "name"; // default directory sort $fsort_arr = array( "name" => array ("rname", "note", "date", "size"), @@ -682,6 +692,7 @@ $D="D=".urlencode($relDir); function self_args($arr = array()) { + global $self; $arg = implode("&",$arr); if ($arg) { return $self."?".$arg; @@ -904,8 +915,6 @@ global $html, $HTTP_SERVER_VARS; $self = $HTTP_SERVER_VARS["PHP_SELF"] ; - if ($relDir == "") $relDir = "/" ; - include("$html/UploadPage.html"); } // end function UploadPage @@ -1232,16 +1241,16 @@ by Vyacheslav Zavadsky */ -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); -define(trperm_n,1 << 8); +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); +define('trperm_n',1 << 8); $trustee_a2n = array( '!' => trmask_not, @@ -1289,7 +1298,7 @@ $error="".dirname($trustee_php)." must be writable by web server user"; } elseif (file_exists($trustee_php) && !is_writable($trustee_php)) { $error="trustees cache file $trustee_php exists, but is not writable by web server"; -} elseif (1 || filemtime($trustee_conf) >= filemtime($trustee_php)) { +} elseif (@filemtime($trustee_conf) >= @filemtime($trustee_php)) { $fp_php=@fopen($trustee_php,"w"); fputs($fp_php,"\n"; } } - $tr_arr[$path][$user] |= $perm; + if (isset($tr_arr[$path][$user])) { + $tr_arr[$path][$user] |= $perm; + } else { + $tr_arr[$path][$user] = $perm; + } } } } @@ -1364,10 +1377,10 @@ fclose($fp_php); } -if ($error) { +if (isset($error)) { Error("Trustee error",$error,1); } else { - include("$trustee_php"); + include_once("$trustee_php"); } return 1; @@ -1375,39 +1388,53 @@ }//init_trustee function in_group($user,$group) { - return in_array($groups[$group],$user); + global $groups; + return in_array($user,$groups[$group]); } // helper function function unroll_perm($u,$t,$user,$perm) { - // check user + + // check user FIX 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; + $perm['deny'] &= ~$t; } else { - $perm[deny] |= $t; + $perm['deny'] |= $t; } } elseif ($t & trmask_clear) { - $perm[allow] &= ~$t; + $perm['allow'] &= ~$t; } else { - $perm[allow] |= $t; + $perm['allow'] |= $t; } return $perm; }// end of helper function function check_trustee($user,$path) { global $trustees; - $perm[allow] = 0; - $perm[deny] = 0; + $perm['allow'] = 0; + $perm['deny'] = 0; + + if (! isset($trustees)) Error("Trustees not found","Can't find in-memory trustee structure \$trustees. Probably bug in code. Contact dpavlin@rot13.org",1); + +global $debug; +$debug .= "
check_trustee $path ... "; + $path_arr=explode("/",$path); - $path = "/"; + $tmppath = "/"; while (count($path_arr)) { - if (substr($path,strlen($path)-1,1) != "/") $path.="/"; - $path.=array_shift($path_arr); - $tr = $trustees[$path]; + $tmppath.=array_shift($path_arr); +$debug.= ">> $tmppath "; + + # clear one level flag + $perm['allow'] &= ~trmask_one_level; + $perm['deny'] &= ~trmask_one_level; + + if (! isset($trustees[$tmppath])) continue; + $tr = $trustees[$tmppath]; if (isset($tr)) { // first apply trustee for all @@ -1416,26 +1443,25 @@ unset($tr['*']); } // then apply group policies - foreach ($tr as $u=>$t) { - if ($t & trmask_group && in_group($user,$u)) { + foreach ($tr as $g=>$t) { + if ($t & trmask_group && in_group($user,$g)) { // resolv user $t = $t & ~trmask_group; - $u = $user; - $perm = unroll_perm($u,$t,$user, $perm); - unset($tr[$u]); + $perm = unroll_perm($user,$t,$user, $perm); + unset($tr[$g]); } } - // then apply use policy + // then apply user policy if (isset($tr[$user])) { $perm = unroll_perm($user,$tr[$user],$user, $perm); unset($tr[$user]); } - } +$debug.="d(".display_trustee($perm['deny']).") a(".display_trustee($perm['allow']).") "; } -#print "
user: $user path: $path perm: "; -#print "d: $perm[deny] (".display_trustee($perm[deny]).") a: $perm[allow] (".display_trustee($perm[allow]).")
\n"; +$debug.="
check_trustee: user: $user path: $path==$tmppath perm: "; +$debug.="d: ".$perm['deny']." (".display_trustee($perm['deny']).") a: ".$perm['allow']." (".display_trustee($perm['allow']).")
\n"; return $perm; } @@ -1445,13 +1471,14 @@ global $gblLogin,$HAVE_TRUSTEE; global $debug; -$debug.="
check_perm: $path test perm ".display_trustee($perm)."
\n"; +$debug.="
check_perm: on $path for perm ".display_trustee($trperm)."
\n"; + $return = ! $HAVE_TRUSTEE; if ($HAVE_TRUSTEE) { $perm = check_trustee($gblLogin,$path); -$debug.=" d: $perm[deny] (".display_trustee($perm[deny]).") a: $perm[allow] (".display_trustee($perm[allow]).") perm: $trperm"; - if ($perm[deny] & $trperm) $return=0; - elseif ($perm[allow] & $trperm) $return=1; +$debug.=" d: ".$perm['deny']." (".display_trustee($perm['deny']).") a: ".$perm['allow']." (".display_trustee($perm['allow']).") perm to have: $trperm (".display_trustee($trperm).")"; + if ($perm['deny'] & $trperm) $return=0; + elseif (($perm['allow'] & $trperm) == $trperm) $return=1; } $debug.=" return: $return
\n"; return($return); @@ -1496,13 +1523,38 @@ } ////////////////////////////////////////////////////////////////// + +// functions to move HTTP server variables to global namespace +// [replacement for register_globals in php.ini] + +function HTTP_GET_VAR($var) { + global $HTTP_GET_VARS, $GLOBALS; + if (isset($HTTP_GET_VARS[$var])) { + $GLOBALS[$var] = stripSlashes($HTTP_GET_VARS[$var]); + return $GLOBALS[$var]; + } +} + +function HTTP_POST_VAR($var) { + global $HTTP_GET_VARS, $GLOBALS; + if (isset($HTTP_GET_VARS[$var])) { + $GLOBALS[$var] = stripSlashes($HTTP_GET_VARS[$var]); + return $GLOBALS[$var]; + } +} + +////////////////////////////////////////////////////////////////// + +function Warn($text) { +} + +////////////////////////////////////////////////////////////////// // MAIN PROGRAM $gblFilePerms = 0640 ; // default for new files $gblDirPerms = 0750 ; // default for new dirs - $STYLE = $HTTP_GET_VARS[STYLE]; - if (isset($STYLE) && $STYLE == "get") { + if (isset($HTTP_GET_VARS["STYLE"]) && $HTTP_GET_VARS["STYLE"] == "get") { include("$html/docman.css"); exit; } @@ -1522,8 +1574,8 @@ } // try to add dir to script name to realm var - if (is_dir("$fsRealmDir/$realm/".dirname($HTTP_SERVER_VARS[SCRIPT_NAME]))) { - $realm .= dirname($HTTP_SERVER_VARS[SCRIPT_NAME]); + if (is_dir("$fsRealmDir/$realm/".dirname($HTTP_SERVER_VARS["SCRIPT_NAME"]))) { + $realm .= dirname($HTTP_SERVER_VARS["SCRIPT_NAME"]); $realm_sep = "/"; } else { $realm_sep = "."; @@ -1547,6 +1599,10 @@ Error("Configuration error","Can't find user handling module at $gblIncDir/htusers/$gblUsers.php ! Please fix $realm_config"); } + // take additional login vars + HTTP_GET_VAR("relogin"); + HTTP_GET_VAR("force_login"); + // if no password, or empty password logout if ( isset($gblLogin) && ( @@ -1571,11 +1627,12 @@ // get ACL informations $HAVE_TRUSTEE = init_trustee(); - if (strtolower($gblLogin) == "anonymous" || !isset($gblPasswd)) { - $perm = check_trustee($gblLogin,$path); + if (strtolower($gblLogin) == "anonymous" || !isset($gblLogin)) { + $perm = check_trustee("anonymous","/"); // browsing must be explicitly allowed for root directory // of repository for anonymous user to work! - if ($perm[allow] & trperm_b) { + if ($perm['allow'] & trperm_b) { + $gblLogin = $gblPasswd = "anonymous"; $secHash = md5($gblLogin.$gblPasswd); $gblUserName = "Anonymous user"; } @@ -1595,32 +1652,32 @@ if ($HTTP_SERVER_VARS["REQUEST_METHOD"] == "POST") { // take variables from server - $FN=stripSlashes($HTTP_POST_VARS["FN"]); - $DIR=stripSlashes($HTTP_POST_VARS["DIR"]); - $RELPATH=stripSlashes($HTTP_POST_VARS["RELPATH"]); - $T=stripSlashes($HTTP_POST_VARS["T"]); - $CONFIRM=stripSlashes($HTTP_POST_VARS["CONFIRM"]); - - check_filename($FN); - check_dirname($DIR); - check_dirname($RELPATH); + if (HTTP_POST_VAR("FN")) check_filename($FN); + if (HTTP_POST_VAR("DIR")) { + check_dirname($DIR); + $relDir = $DIR; + } else { + trigger_error("Can't get DIR",E_USER_WARNING); + } + if (HTTP_POST_VAR("RELPATH")) check_dirname($RELPATH); + HTTP_POST_VAR("T"); + HTTP_POST_VAR("CONFIRM"); - $relDir = $DIR; } else { // get - $A=stripSlashes($HTTP_GET_VARS["A"]); - $D=stripSlashes(urldecode($HTTP_GET_VARS["D"])); - $F=stripSlashes($HTTP_GET_VARS["F"]); - - check_filename($F); - check_dirname($D); - - $relDir = $D; + HTTP_GET_VAR("A"); + if (HTTP_GET_VAR("D")) { + check_dirname($D); + $D=urldecode($D); + $relDir = $D; + } else { + //trigger_error("Can't get D",E_USER_WARNING); + $relDir = "/"; + } + if (HTTP_GET_VAR("F")) check_filename($F); } - if ($relDir == "/") $relDir = "" ; - - $relScriptDir = dirname($SCRIPT_NAME) ; + $relScriptDir = dirname($HTTP_SERVER_VARS["SCRIPT_NAME"]) ; // i.e. /docman // start on server root @@ -1628,7 +1685,9 @@ // i.e. /home/httpd/repository $fsDir = $gblFsRoot . $relDir ; // current directory - if ( !is_dir($fsDir) ) Error("Dir not found",$relDir,1) ; + if ( !is_dir($fsDir) ) Error("Dir not found","Can't find $relDir which points to $fsDir",1) ; + + if ($relDir == "") $relDir="/"; if (isset($HTTP_SERVER_VARS["HTTPS"]) && $HTTP_SERVER_VARS["HTTPS"] == "on") { $webRoot = "https://"; @@ -1637,7 +1696,7 @@ } $webRoot .= $HTTP_SERVER_VARS["HTTP_HOST"] . $relScriptDir; - switch ($HTTP_POST_VARS["POSTACTION"]) { + if (HTTP_POST_VAR("POSTACTION")) switch ($POSTACTION) { case "UPLOAD" : $FN_name=stripSlashes($HTTP_POST_FILES["FN"]["tmp_name"]); $FN=stripSlashes($HTTP_POST_FILES["FN"]["name"]); @@ -1805,7 +1864,7 @@ } // common to all POSTs : redirect to directory view ($relDir) - if ( $POSTACTION != "" ) { + if (isset($POSTACTION)) { $tstr = $PHP_SELF . "?D=" . urlencode($relDir) ; header("Location: " . $tstr) ; exit ; @@ -1821,11 +1880,13 @@ // $A=I : include file .$F.php from [$gblIncDir|realm]/include_php // default : display directory $D - switch ($A) { + if (isset($A)) switch ($A) { case "U" : // upload to $relDir + if (! check_perm($relDir, trperm_w)) + Error("Write access denied","You don't have permission to write in $relDir"); if (!is_writeable($gblFsRoot . $relDir)) - Error("Write access denied",$relDir) ; + Error("Write access denied","User $gblLogin has permission on $relDir, but directory is not writable",1); $text = "Use this page to upload a single " ; $text .= "file to $realm." ; StartHTML("(Upload Page)", $text) ; @@ -1875,15 +1936,12 @@ case "I" : if (! isset($F) || $F == "") Error("Can't find file to include","Your request didn't specify file to include which should be in variable F like $HTTP_SERVER_VARS[REQUEST_URI]&F=include_php_file",1); - if (file_exists("$gblIncDir/include_php/$F.php")) { - $inc_file="$gblIncDir/include_php/${F}.php"; - } elseif (file_exists("$fsRealmDir/$realm/$F.php")) { - $inc_file="$fsRealmDir/$realm/${F}.php"; - } else { - Error("Can't find file to include","Can't find include file $F.php in $gblIncDir/include_php/ nor $fsRealmDir/$realm/",1); + $inc_file="$fsRealmDir/$realm".$realm_sep.$F.".php"; + if (! file_exists($inc_file)) { + Error("Can't find file to include","Can't find include file $F.php in $fsRealmDir/$realm/. Meybe you should copy $gblIncDir/include_php/$F.php to $inc_file ?",1); } if (!is_readable($inc_file)) - Error("Read access to include file denied","Can't read PHP include file $inc_file. Fix permissions on it."); + Error("Read access to include file denied","Can't read PHP include file $inc_file. Fix permissions on it.",1); $text = "Your include file should define \$text variable which holds this text and \$title variable which is page title"; $title = "You should define \$title variable with page title"; include($inc_file);