--- docman.php 2002/07/21 18:15:47 1.1.1.1 +++ docman.php 2002/07/29 09:36:22 1.24 @@ -20,13 +20,13 @@ ////////////////////////////////////////////////////////////////// // CONFIGURATION OPTIONS -// error_reporting(4) ; // how verbose ? + error_reporting(E_ALL) ; // how verbose ? // from where to include auth_*.php modules? $gblIncDir = "/data/docman2"; - // force download (so it won't open in associated application) - $gblForceDownload = 1; + // force download on view (so it won't open in associated application) + $gblForceDownload = 0; // date format $gblDateFmt="Y-m-d"; @@ -84,14 +84,14 @@ LoadLanguage($HTTP_SERVER_VARS["HTTP_ACCEPT_LANGUAGE"]); // for security and configuration - $realm="$HTTP_HOST"; // FIX + $realm=$HTTP_SERVER_VARS["HTTP_HOST"]; - $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 \$"); + $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 = $PHP_AUTH_USER; - $gblPasswd = $PHP_AUTH_PW; + $gblLogin = HTTP_SERVER_VAR("PHP_AUTH_USER"); + $gblPasswd = HTTP_SERVER_VAR("PHP_AUTH_PW"); ////////////////////////////////////////////////////////////////// @@ -109,16 +109,15 @@ function StartHTML($title,$text="") { - global $html,$fsDocumentRoot; + global $html,$fsDocumentRoot,$gblTitle,$HTTP_SERVER_VARS; - $title = $gblTitle." ".$title ; - $host = $GLOBALS["HTTP_HOST"] ; - $self = $GLOBALS["PHP_SELF"] ; + $host = $HTTP_SERVER_VARS["HTTP_HOST"] ; + $self = $HTTP_SERVER_VARS["PHP_SELF"] ; if (file_exists("$fsDocumentRoot/docman.css")) { $css=dirname($self)."/docman.css"; } else { - $css=$self."?STYLE=get&css=$css"; + $css=$self."?STYLE=get"; } include("$html/head.html"); @@ -138,22 +137,29 @@ } 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 { $url_title="relogin"; } include("$html/footer.html"); - //phpinfo(); + + global $debug; + if ($debug) print $debug; } // end function EndHTML ////////////////////////////////////////////////////////////////// function DetailPage($fsRoot,$relDir,$fn) { - global $gblEditable, $gblImages, $webRoot, $html ; - $self = $GLOBALS["PHP_SELF"] ; + global $gblEditable, $gblImages, + $gblDateFmt, $gblTimeFmt, + $webRoot, $html, + $HTTP_SERVER_VARS ; + $self = $HTTP_SERVER_VARS["PHP_SELF"] ; $relPath = $relDir . "/" . $fn ; $fsPath = $fsRoot . $relPath ; @@ -161,14 +167,16 @@ $exists = file_exists($fsPath) ; $ext = strtolower(strrchr($relPath,".")) ; - $editable = ( $ext=="" || strstr(join(" ",$gblEditable),$ext)) ; - $writable = is_writeable($fsPath) ; + $editable = ( $ext=="" || strstr(join(" ",$gblEditable),$ext)) && + check_perm($relPath,trperm_w); + $writable = is_writeable($fsPath) && check_perm($relPath,trperm_w) ; + $writable_dir = is_writeable($fsDir) && check_perm($relDir,trperm_w) ; $file_lock = CheckLock($fsPath); if (!$editable && !$exists) - Error(_("Creation unsupported for type"),$relPath) ; - if (!exists && !is_writeable($fsDir) ) - Error(_("Creation denied"),$relDir) ; + Error("Creation denied","Can't create $relPath") ; + if (!$exists && !$writable_dir ) + Error("Creation denied","Can't write in directory $relDir while creating $relPathfor which user has permissions.",1); $text = _("Use this page to view, modify or ") ; if (is_dir($fsPath)) { @@ -183,8 +191,8 @@ echo "

" . $relDir . "/" . $fn . "

" ; if ($exists) { // get file info $fsize = filesize($fsPath) ; - $fmodified = date("$GLOBALS[gblDateFmt] $GLOBALS[gblTimeFmt]", filemtime($fsPath)) ; - $faccessed = date("$GLOBALS[gblDateFmt] $GLOBALS[gblTimeFmt]", fileatime($fsPath)) ; + $fmodified = date("$gblDateFmt $gblTimeFmt", filemtime($fsPath)) ; + $faccessed = date("$gblDateFmt $gblTimeFmt", fileatime($fsPath)) ; $fuid=fileowner($fsPath); $fgid=filegroup($fsPath); $userinfo = posix_getpwuid($fuid); @@ -201,7 +209,7 @@ $fstr = htmlentities( $fstr ) ; ?> -
+ DOCUMENT CONTENTS
@@ -572,46 +580,56 @@ function Navigate($fsRoot,$relDir) { global $gblEditable, $gblIcon, $gblModDays, $webRoot, $gblHide, - $HTTP_GET_VARS, $html; + $gblIgnoreUnknownFileType, $gblRepositoryDir, + $gblLogin, $gblUserName, $gblDateFmt, $gblTimeFmt, + $fsRealmDir, $realm, $realm_sep, + $html, $realm_config, + $HTTP_GET_VARS, $HTTP_SERVER_VARS; + + $self = $HTTP_SERVER_VARS["PHP_SELF"] ; - $self = $GLOBALS["PHP_SELF"] ; + $relDir = chopsl($relDir)."/"; + $fsDir = $fsRoot.$relDir; // current directory - if ($relDir == "") $relDir = "/"; + if (!is_dir($fsDir)) Error("Dir not found","Directory $relDir not found on filesystem at $fsDir",1) ; - $fsDir = $fsRoot.$relDir."/"; // current directory + global $debug; + $debug .= "[$gblLogin|$relDir] before >"; - if (!is_dir($fsDir)) Error("Dir not found",$relDir) ; + if (! check_perm($relDir,trperm_b)) + Error("Access denied","User $gblLogin tried to access $relDir without valid trustee.",1); + $debug .= "< afeter"; $hide_items=",$gblHide,"; -#display_all_trustee(); -print "-- $fsDir --"; + $dirList = array(); + $fileList = array(); // read directory contents if ( !($dir = @opendir($fsDir)) ) - Error("Read Access denied",$relDir) ; + Error("Read Access denied",$relDir,1) ; while ($item = readdir($dir)) { -print "$item, "; if ( substr($item,0,1) == "." || strstr($hide_items,",$item,") ) continue ; - if ((is_dir($fsDir.$item) || is_link ($fsDir.$item)) && check_perm($relDir.$item,trperm_b)) { - $dirList[$item] = $item ; - $dirNote[$item] = ReadNote($fsDir.$item); - } else if ( is_file($fsDir.$item) && check_perm($relDir.$item,trperm_r) ) { - $fileList[$item] = $item ; - $fileDate[$item] = filemtime($fsDir.$item) ; - $fileSize[$item] = filesize($fsDir.$item) ; - $fileNote[$item] = ReadNote($fsDir.$item); + if (is_dir($fsDir.$item) || is_link ($fsDir.$item)) { + if (check_perm($relDir.$item,trperm_b)) { + $dirList[$item] = $item ; + $dirNote[$item] = ReadNote($fsDir.$item); + } + } else if (is_file($fsDir.$item)) { + if (check_perm($relDir.$item,trperm_r)) { + $fileList[$item] = $item ; + $fileDate[$item] = filemtime($fsDir.$item) ; + $fileSize[$item] = filesize($fsDir.$item) ; + $fileNote[$item] = ReadNote($fsDir.$item); + } } else { - // unknown file type - // $text = "Could not determine file type of " ; - // Error("File Error", $text.$relDir."/".$item) ; - // exit ; + if (! $gblIgnoreUnknownFileType) Error("File Type Error", "Item ".$fsDir.$item." is not file, directory or link. If you want to ignore errors like this, set \$gblIgnoreUnknownFileType = 1 in $realm_config.",1); } } closedir($dir) ; // scan deleted files - if ( $GLOBALS[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" ; @@ -626,7 +644,7 @@ // start navigation page $text = "Use this page to add, delete"; - if (! isset($show_deleted)) { + if (! isset($HTTP_GET_VARS["show_deleted"])) { $text .= ", undelete"; } $text .= " or revise files on this web site." ; @@ -636,7 +654,7 @@ echo "" ; - // updir bar + // updir (parent) bar if (chopsl($fsDir) != chopsl($fsRoot)) { $parent = dirname($relDir) ; if ($parent == "") $parent = "/" ; @@ -652,8 +670,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"), @@ -662,8 +679,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"), @@ -679,6 +695,7 @@ $D="D=".urlencode($relDir); function self_args($arr = array()) { + global $self; $arg = implode("&",$arr); if ($arg) { return $self."?".$arg; @@ -715,8 +732,8 @@ $dir = $dirList[$key]; - $info_url=self_args(array("A" => "A=E", "F" => "F=".urlencode($dir))); - $dir_url=$self."?D=".urlencode($relDir.$dir); + $info_url=self_args(array("A"=>"A=E", "F"=>"F=".urlencode($dir), "D"=>$D)); + $dir_url=$self."?D=".urlencode(chopsl($relDir)."/".$dir); include("$html/Navigate-dirEntry.html"); } // iterate over dirs @@ -788,8 +805,7 @@ $file_lock=CheckLock($path); - $file_url_html="" ; if (substr($file,0,5) != ".del/") { @@ -803,9 +819,8 @@ $ext = strtolower(strrchr($file,".")) ; if ($file_lock) { - if ($file_lock == $GLOBALS[gblUserName]) { - $b.="" ; $file_url_html=$b; $b.=$gblIcon("checkin")."" ; @@ -819,14 +834,12 @@ $file_url_html = "$file $a"; } } else { - $b.="" ; - $b.=$gblIcon("checkout")."" ; + $b.=$gblIcon("checkout").""; if ( $ext=="" || strstr(join(" ",$gblEditable),$ext) ) { - $b.="" ; $b.=$gblIcon("view")."" ; } else { @@ -834,7 +847,7 @@ } } - $mod = date("$GLOBALS[gblDateFmt] $GLOBALS[gblTimeFmt]",$mod); + $mod = date("$gblDateFmt $gblTimeFmt",$mod); include("$html/Navigate-fileEntry.html"); @@ -866,12 +879,18 @@ "; +} elseif (file_exists("$gblRepositoryDir/.info.inc")) { print " - "; + include("$gblRepositoryDir/.info.inc"); + print ""; } + + ?> @@ -896,62 +915,74 @@ function UploadPage($fsRoot, $relDir, $filename="") { - $self = $GLOBALS["PHP_SELF"] ; - if ($relDir == "") $relDir = "/" ; -?> + global $html, $HTTP_SERVER_VARS; -


"; + include("$fsRealmDir/$realm".$realm_sep."info.inc"); + print "

"; - include(".info.inc"); - print "


-
- -DESTINATION DIRECTORY: - -
DESTINATION FILE: - - -

PATHNAME OF LOCAL FILE
- - -

-

-

If the [BROWSE...] button is not displayed,
-you must upgrade to an RFC1867-compliant browser.

-

Your browser:

- -
-
-
- -
-

+ $self = $HTTP_SERVER_VARS["PHP_SELF"] ; + include("$html/UploadPage.html"); -Hit your Browser's Back Button.

" ; - EndHTML() ; +// Error with sysadmin flag are reported to error_log or hidden from +// users + +function Error($title,$text="",$sysadmin=0,$no_404=0) { + global $gblSeparateAdminMessages, + $gblMailAdminMessages,$realm, + $HTTP_SERVER_VARS; + if (! headers_sent() && ! $no_404) header("HTTP/1.0 404 Not Found"); + if ($sysadmin) { + if ($gblSeparateAdminMessages) { + $user="Your administrator "; + if ($gblMailAdminMessages) { + mail($HTTP_SERVER_VARS["SERVER_ADMIN"], "docman $realm error message: $title", strip_tags($text)); + $user.="".$HTTP_SERVER_VARS["SERVER_ADMIN"]." "; + } + $user.="has been notified about error" ; + StartHTML("($title)",$user); + echo "

Hit your Browser's Back Button.

" ; + EndHTML(); + error_log("docman $realm: ".strip_tags($text)); + } else { + StartHTML("ADMIN: ".$title,$text) ; + echo "

Hit your Browser's Back Button.

" ; + EndHTML(); + } + } else { + StartHTML("(".$title.")",$text) ; + echo "

Hit your Browser's Back Button.

" ; + EndHTML() ; + } exit ; } // end function Error -////////////////////////////////////////////////////////////////// +function LogIt($target,$msg, $changelog=0) { -function LogIt($target,$msg) { + global $gblDateFmt, $gblTimeFmt, $gblUserName, $gblFsRoot; $dir=dirname($target); if (! file_exists($dir."/.log")) { - if (! @mkdir($dir."/.log",0700)) Error("docman installation problem","can't create log directory $dir/.log"); + if (! @mkdir($dir."/.log",0700)) Error("docman installation problem","can't create log directory $dir/.log",1); } $file=basename($target); $log=fopen("$dir/.log/$file","a+"); - fputs($log,date("$GLOBALS[gblDateFmt]\t$GLOBALS[gblTimeFmt]"). - "\t$GLOBALS[gblUserName]\t$msg\n"); + fputs($log,date("$gblDateFmt\t$gblTimeFmt"). + "\t$gblUserName\t$msg\n"); + fclose($log); + + if (! $changelog) return; + + $log=fopen("$gblFsRoot/.changelog","a+"); + if (substr($target,0,strlen($gblFsRoot)) == $gblFsRoot) + $target=substr($target,strlen($gblFsRoot),strlen($target)-strlen($gblFsRoot)); + $msg=str_replace("\t"," ",$msg); + fputs($log,time()."\t$target\t$gblUserName\t$msg\n"); fclose($log); + // FIX: implement e-mail notification based on $changelog + // permission } @@ -970,7 +1001,7 @@ fputs($note,"$msg\n"); fclose($note); - Logit($target,"added note $msg"); + LogIt($target,"added note $msg"); } @@ -1007,6 +1038,8 @@ function Lock($target) { + global $gblUserName; + $target=stripSlashes($target); $dir=dirname($target); if (! file_exists($dir."/.lock")) { @@ -1015,13 +1048,13 @@ $file=basename($target); if (file_exists("$dir/.lock/$file")) { - Logit($target,"attempt to locked allready locked file!"); + LogIt($target,"attempt to locked allready locked file!"); } else { $lock=fopen("$dir/.lock/$file","w"); - fputs($lock,"$GLOBALS[gblUserName]\n"); + fputs($lock,"$gblUserName\n"); fclose($lock); - Logit($target,"file locked"); + LogIt($target,"file locked"); } } @@ -1048,9 +1081,9 @@ $file=basename($target); if (file_exists($dir."/.lock/$file")) { unlink("$dir/.lock/$file"); - Logit($target,"file unlocked"); + LogIt($target,"file unlocked"); } else { - Logit($target,"attempt to unlocked non-locked file!"); + LogIt($target,"attempt to unlocked non-locked file!"); } } @@ -1067,16 +1100,21 @@ ////////////////////////////////////////////////////////////////// function safe_rename($fromdir,$fromfile,$tofile) { + + global $gblNumBackups; + function try_rename($from,$to) { # print "$from -> $to\n"; if (file_exists($from) && is_writeable(dirname($to))) { - rename($from,$to); + return rename($from,$to); + } else { + return 0; } } function try_dir($todir) { if (! file_exists($todir)) { - mkdir($todir,0700); + @mkdir($todir,0700); } } @@ -1086,7 +1124,7 @@ # print "
$fromdir / $fromfile -> $todir / $tofile\n\n";
 
-	try_rename("$fromdir/$fromfile","$todir/$tofile");
+	if (! try_rename("$fromdir/$fromfile","$todir/$tofile")) Error("Rename error","Can't rename file $fromfile to $tofile",1);
 	try_dir("$todir/.log");
 	try_rename("$fromdir/.log/$fromfile","$todir/.log/$tofile");
 	try_dir("$todir/.note");
@@ -1094,7 +1132,7 @@
 	try_dir("$todir/.lock");
 	try_rename("$fromdir/.lock/$fromfile","$todir/.lock/$tofile");
 	try_dir("$todir/.bak");
-	for($i=0;$i<=$GLOBALS[gblNumBackups];$i++) {
+	for($i=0;$i<=$gblNumBackups;$i++) {
 		try_rename("$fromdir/.bak/$i/$fromfile","$todir/.bak/$i/$tofile");
 	}
 }
@@ -1120,21 +1158,13 @@
 
 //////////////////////////////////////////////////////////////////
 
-function ChangeLog($target,$msg) {
-
-	global $gblFsRoot;
-	$log=fopen("$gblFsRoot/.changelog","a+");
-	if (substr($target,0,strlen($gblFsRoot)) == $gblFsRoot)
-		$target=substr($target,strlen($gblFsRoot),strlen($target)-strlen($gblFsRoot));
-	$msg=str_replace("\t"," ",$msg);
-	fputs($log,time()."\t$target\t$GLOBALS[gblUserName]\t$msg\n");
-	fclose($log);
+function DisplayChangeLog($day) {
 
-}
+	global $gblFsRoot, $gblDateFmt, $gblTimeFmt,
+		$HTTP_SERVER_VARS;
 
-function DisplayChangeLog($day) {
+	$self  = $HTTP_SERVER_VARS["PHP_SELF"];
 
-	global $gblFsRoot;
 	if (!file_exists("$gblFsRoot/.changelog")) return;
 	$log=fopen("$gblFsRoot/.changelog","r");
 	$logarr = array();
@@ -1152,32 +1182,54 @@
 	print "\n";
 	while ($e = array_shift($logarr)) {
 		$cl=$cl1; $cl1=$cl2; $cl2=$cl;
-		$date = date("$GLOBALS[gblDateFmt]", $e[0]);
-		$time = date("$GLOBALS[gblTimeFmt]", $e[0]);
+		$date = date($gblDateFmt, $e[0]);
+		$time = date($gblTimeFmt, $e[0]);
 		$dir = dirname($e[1]);
 		$file = basename($e[1]);
-		print "$date$time$dir/$file$e[2]$e[3]\n";
+		print "$date$time$dir/$file$e[2]$e[3]\n";
 	}
 	print "
"; - print "

".GifIcon(up)." Back to front page.

"; + print "

".GifIcon("up")." Back to front page.

"; } ////////////////////////////////////////////////////////////////// -function Download($path) { - global $HTTP_USER_AGENT; - $file=basename($path); +function Download($path,$force=0) { + global $HTTP_SERVER_VARS,$mime_type; + + // default transfer-encoding + $encoding = "binary"; + + // known transfer encodings + $encoding_ext = array( + "gz" => "x-gzip", + "Z" => "x-compress", + ); + + $file = basename($path); $size = filesize($path); - //header("Content-Type: application/octet-stream"); - header("Content-Type: application/force-download"); - header("Content-Length: $size"); + + $ext_arr = explode(".",$file); + $ext = array_pop($ext_arr); + if ($encoding_ext[$ext]) { + $encoding = $encoding_ext[$ext]; + $ext = array_pop($ext_arr); + } + + if ($force || !isset($mime_type[$ext])) { + header("Content-Type: application/force-download"); + } else { + header("Content-Type: $mime_type[$ext]"); + } + // IE5.5 just downloads index.php if we don't do this - if(preg_match("/MSIE 5.5/", $HTTP_USER_AGENT)) { + if(preg_match("/MSIE 5.5/", $HTTP_SERVER_VARS[HTTP_USER_AGENT])) { header("Content-Disposition: filename=$file"); } else { header("Content-Disposition: attachment; filename=$file"); } - header("Content-Transfer-Encoding: binary"); + + header("Content-Transfer-Encoding: $encoding"); $fh = fopen($path, "r"); fpassthru($fh); } @@ -1186,8 +1238,8 @@ ////////////////////////////////////////////////////////////////// function chopsl($path) { - if (substr($path,strlen($path)-1,1) == "/") $path=substr($path,0,strlen($path)-1); $path=str_replace("//","/",$path); + if (substr($path,strlen($path)-1,1) == "/") $path=substr($path,0,strlen($path)-1); return $path; } @@ -1201,16 +1253,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, @@ -1258,7 +1310,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; + } } } } @@ -1335,10 +1389,10 @@ fclose($fp_php); } -if ($error) { - Error("Trustee error",$error); +if (isset($error)) { + Error("Trustee error",$error,1); } else { - include("$trustee_php"); + include_once("$trustee_php"); } return 1; @@ -1346,67 +1400,85 @@ }//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 - if ($t & trmask_not && ($u==$user)) continue; - if (!($t & trmask_not) && ($u!=$user)) continue; +function unroll_perm($u,$t,$perm,$one_level) { + + if ($t & trmask_one_level && !$one_level) return $perm; 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; + global $trustees,$HAVE_TRUSTEE; + $perm['allow'] = 0; + $perm['deny'] = 0; + + // do we use trustees? + if (! $HAVE_TRUSTEE) return $perm; + + 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 "; + + if (! isset($trustees[$tmppath])) continue; + $tr = $trustees[$tmppath]; + + $one_level = (!count($path_arr)); +$debug.=" O($one_level) "; if (isset($tr)) { // first apply trustee for all if (isset($tr['*'])) { - $perm = unroll_perm($user,$tr['*'],$user, $perm); + $perm = unroll_perm($user,$tr['*'],$perm, $one_level); unset($tr['*']); } - // then apply group policies - foreach ($tr as $u=>$t) { - if ($t & trmask_group && in_group($user,$u)) { + // then apply not and group policies + foreach ($tr as $g=>$t) { + if ($t & trmask_not && $g != $user) { + $t = $t & ~trmask_not; + $perm = unroll_perm($user,$t,$perm, $one_level); + unset($tr[$g]); + + } elseif ($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,$perm, $one_level); + unset($tr[$g]); } } - // then apply use policy + // then apply user policy if (isset($tr[$user])) { - $perm = unroll_perm($user,$tr[$user],$user, $perm); + $perm = unroll_perm($user,$tr[$user],$perm,$one_level); 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; } @@ -1414,18 +1486,92 @@ function check_perm($path,$trperm) { global $gblLogin,$HAVE_TRUSTEE; -print "
check_perm: $path test perm ".display_trustee($perm)."
\n"; + + global $debug; +$debug.="
check_perm: on $path for perm ".display_trustee($trperm)."
\n"; + $return = ! $HAVE_TRUSTEE; if ($HAVE_TRUSTEE) { $perm = check_trustee($gblLogin,$path); -print " 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; } -print " return: $return
\n"; +$debug.=" return: $return
\n"; return($return); } +////////////////////////////////////////////////////////////////// + +function readMime() { + global $mime_type; + + if (! isset($gblMimeTypes)) { + $gblMimeTypes = "/etc/mime.types"; + } + + $mime = @fopen($gblMimeTypes,"r"); + + if (! $mime) Error("Can't read MIME types","$gblMimeTypes file not found. You can setup other mime.types file using \$gblMimeTypes in $realm_config"); + + while($line = fgets($mime,80)) { + if (substr($line,0,1) == "#") continue; // skip comment + $arr = preg_split("/[\s\t]+/",$line); + $type = array_shift($arr); + while ($ext = array_shift($arr)) { + $mime_type[$ext] = $type; + } + } + + fclose($mime); +} + +////////////////////////////////////////////////////////////////// + +// check for invalid characters in filename and dirname (.. and /) + +function check_dirname($file) { + if (strstr($file,"..")) Error("Security violation","No parent dir .. allowed in directory name $file",1); +} + +function check_filename($file) { + if (strstr($file,"..")) Error("Security violation","No parent dir .. allowed in file name $file",1); + if (strstr($file,"/")) Error("Security violation","No slashes / allowed in file name $file",1); +} + +////////////////////////////////////////////////////////////////// + +// 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, ${$var}; + if (isset($HTTP_GET_VARS[$var])) { + $$var = stripSlashes($HTTP_GET_VARS[$var]); + return $$var; + } +} + +function HTTP_POST_VAR($var) { + global $HTTP_POST_VARS, ${$var}; + if (isset($HTTP_POST_VARS[$var])) { + $$var = $HTTP_POST_VARS[$var]; + return $$var; + } +} + +function HTTP_SERVER_VAR($var) { + global $HTTP_SERVER_VARS, ${$var}; + if (isset($HTTP_SERVER_VARS[$var])) { + $$var = $HTTP_SERVER_VARS[$var]; + return $$var; + } +} + +////////////////////////////////////////////////////////////////// + +function Warn($text) { +} ////////////////////////////////////////////////////////////////// // MAIN PROGRAM @@ -1433,7 +1579,7 @@ $gblFilePerms = 0640 ; // default for new files $gblDirPerms = 0750 ; // default for new dirs - if (isset($STYLE) && $STYLE == "get") { + if (isset($HTTP_GET_VARS["STYLE"]) && $HTTP_GET_VARS["STYLE"] == "get") { include("$html/docman.css"); exit; } @@ -1441,7 +1587,7 @@ // location of master docman configuration file $docman_conf = "/etc/docman.conf"; if (! file_exists($docman_conf)) { - $error = "Can't find master configuration file $docman_conf. See docman2/doc/upgrade.html#docman_conf for more informations"; + $error = "Can't find master configuration file $docman_conf. See docman2/doc/upgrade.html#docman_conf for more informations"; error_log("docman: $error"); Error("docman not installed completly",$error); @@ -1451,7 +1597,16 @@ if (! isset($fsRealmDir)) { $fsRealmDir = "$gblIncDir/realm"; } - $realm_config = "$fsRealmDir/$realm.conf"; + + // 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"]); + $realm_sep = "/"; + } else { + $realm_sep = "."; + } + + $realm_config = $fsRealmDir."/".$realm.$realm_sep."conf"; // read user-defined configuration if (file_exists($realm_config)) { @@ -1469,6 +1624,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) && ( @@ -1484,18 +1643,21 @@ exit ; } + if (!is_dir($gblRepositoryDir)) Error("Repository dir not found","Can't find repository directory $gblRepositoryDir. Please fix that in $realm_config variable \$gblRepositoryDir.",1); + // trustee (ACL) file configuration - $trustee_conf="$gblIncDir/realm/$realm.trustee"; + $trustee_conf="$fsRealmDir/$realm".$realm_sep."trustee"; // compiled version of trustee file $trustee_php="$gblRepositoryDir/.trustee.php"; // 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"; } @@ -1506,60 +1668,77 @@ isset($relogin) && $secHash == $relogin) { header("WWW-authenticate: basic realm=\"$realm\"") ; header("HTTP/1.0 401 Unauthorized") ; - Error("401 Unauthorized","No trespassing !"); - exit ; + Error("401 Unauthorized","No trespassing !",0,1); } - // get current directory relative to $gblFsRoot - $relDir = $DIR ; // from POST - if ($relDir == "") { // not defined in POST ? - $relDir = urldecode($D) ; // then use GET - } - - $relDir=stripSlashes($relDir); - if ($relDir == "/") $relDir = "" ; - // default : website root = "" + // read mime.types + readMime(); - if (strstr($relDir,"..")) Error("No updirs allowed"); +HTTP_POST_VAR("FN"); - // full paths contain "fs" or "Fs". Paths realitve to root of - // website contain "rel" or "Rel". The script won't let you - // edit anything above directory equal to http://server.com - // i.e. below $gblFsRoot. + if ($HTTP_SERVER_VARS["REQUEST_METHOD"] == "POST") { + // take variables from server + 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); + $relDir = "/"; + } + if (HTTP_POST_VAR("RELPATH")) check_dirname($RELPATH); + HTTP_POST_VAR("T"); + HTTP_POST_VAR("CONFIRM"); + } else { + // get + 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); + } - $relScriptDir = dirname($SCRIPT_NAME) ; + $relScriptDir = dirname($HTTP_SERVER_VARS["SCRIPT_NAME"]) ; // i.e. /docman // start on server root $gblFsRoot = $gblRepositoryDir; - // i.e. /home/httpd/html + // i.e. /home/httpd/repository $fsDir = $gblFsRoot . $relDir ; // current directory - if ( !is_dir($fsDir) ) Error("Dir not found",$relDir) ; + if ( !is_dir($fsDir) ) Error("Dir not found","Can't find $relDir which points to $fsDir",1) ; - if (isset($GLOBALS["HTTPS"]) && $GLOBALS["HTTPS"] == "on") { + if ($relDir == "") $relDir="/"; + + if (isset($HTTP_SERVER_VARS["HTTPS"]) && $HTTP_SERVER_VARS["HTTPS"] == "on") { $webRoot = "https://"; } else { $webRoot = "http://"; } - $webRoot .= $GLOBALS["HTTP_HOST"] . $relScriptDir; - - $FN=stripSlashes($FN); + $webRoot .= $HTTP_SERVER_VARS["HTTP_HOST"] . $relScriptDir; - switch ($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"]); if (!is_writeable($fsDir)) Error("Write denied",$relDir) ; - if (strstr($FN_name,"/")) - Error("Non-conforming filename") ; - // TODO : should rather check for escapeshellcmds - // but maybe RFC 18xx asserts safe filenames .... - $source = $FN ; + + $source = $FN_name ; if (! file_exists($source)) { Error("You must select file with browse to upload it!"); } + + if (HTTP_POST_VAR("FILENAME")) check_filename($FILENAME); + if (! isset($FILENAME)) { // from update file - $target = "$fsDir/$FN_name" ; + $target = "$fsDir/".basename($FN); } else { $target = "$fsDir/$FILENAME"; } @@ -1569,11 +1748,11 @@ if (! file_exists($dir."/.bak")) { mkdir($dir."/.bak",0700); } - if (! file_exists($dir."/.bak/$GLOBALS[gblNumBackups]")) { - mkdir($dir."/.bak/$GLOBALS[gblNumBackups]",0700); + if (! file_exists($dir."/.bak/$gblNumBackups")) { + mkdir($dir."/.bak/$gblNumBackups",0700); } $file=basename($target); - for($i=$GLOBALS[gblNumBackups]-1;$i>0;$i--) { + for($i=$gblNumBackups-1;$i>0;$i--) { MoveTo("$dir/.bak/$i/$file","$dir/.bak/".($i+1)."/"); } MoveTo($target,$dir."/.bak/1/"); @@ -1581,11 +1760,12 @@ copy($source,$target) ; chmod($target,$gblFilePerms) ; clearstatcache() ; - Logit($target,"uploaded"); if (isset($FILENAME)) { + LogIt($target,"check-in",trperm_r | trperm_w); Unlock($target); + } else { + LogIt($target,"uploaded",trperm_r | trperm_w); } - ChangeLog($target,"updated"); break ; case "SAVE" : @@ -1598,17 +1778,20 @@ if (!($writable || (!$exists && $legaldir))) Error("Write denied",$RELPATH) ; $fh = fopen($path, "w") ; - $FILEDATA=stripSlashes($FILEDATA); + HTTP_POST_VAR("FILEDATA"); fwrite($fh,$FILEDATA) ; fclose($fh) ; clearstatcache() ; - Logit($path,"saved changes"); - ChangeLog($path,"saved changes"); + LogIt($path,"saved changes",trperm_r); break ; case "CREATE" : // we know $fsDir exists - if ($FN == "") break; // no filename! + if (! check_perm($relDir, trperm_w)) + Error("Write access denied","You don't have permission to write in $relDir"); + if ($T == "D") $type = "directory"; + else $type ="file"; + if ($FN == "") Error("Can't create $type","You must enter name of $type to create it."); if (!is_writeable($fsDir)) Error("Write denied",$relDir) ; $path = $fsDir . "/" . $FN ; // file or dir to create $relPath = $relDir . "/" . $FN ; @@ -1616,6 +1799,8 @@ case "D" : // create a directory if ( ! @mkdir($path,$gblDirPerms) ) Error("Mkdir failed",$relPath) ; // eg. if it exists + else + LogIt($path."/","dir created",trperm_w); clearstatcache() ; break ; case "F" : // create a new file @@ -1628,13 +1813,12 @@ if ($fh) { fputs($fh,"\n"); fclose($fh) ; - LogIt($path,"file created"); + LogIt($path,"file created",trperm_r | trperm_w); } else { Error("Creation of file $relPath failed -- $path"); } - $tstr = "$PHP_SELF?A=E&D=".urlencode($relDir)."&F=".urlencode($FN) ; + $tstr = $HTTP_SERVER_VARS["PHP_SELF"]."?A=E&D=".urlencode($relDir)."&F=".urlencode($FN) ; header("Location: " . $tstr) ; - ChangeLog($target,"created"); exit ; } break ; @@ -1656,23 +1840,21 @@ // if ( ! @unlink($path) ) { if ( ! rename($path,"$dir/.del/$file") ) { + LogIt($path,"file delete failed"); Error("File delete failed", $tstr . $path) ; - Logit($path,"file delete failed"); - exit ; } else { - Logit($path,"file deleted"); + LogIt($path,"file deleted",trperm_w); MoveTo("$dir/.log/$file","$dir/.del/.log/"); MoveTo("$dir/.note/$file","$dir/.del/.note/"); MoveTo("$dir/.lock/$file","$dir/.del/.lock/"); } - } - else { // delete directory - if ( ! @rrmdir($fsDir) ) { - Error("Rmdir failed", $tstr . $fsDir) ; - } - else { - $relDir = dirname($relDir) ; // move up - } + } else { // delete directory + if ( ! @rrmdir($fsDir) ) { + Error("Rmdir failed", $tstr . $fsDir) ; + } else { + LogIt($path,"dir deleted",trperm_w); + $relDir = dirname($relDir) ; // move up + } } break ; @@ -1682,7 +1864,7 @@ if (substr($FN,0,4) != ".del") break ; $file=substr($FN,4,strlen($FN)-4); - Logit("$fsDir/.del/$file","undeleted"); + LogIt("$fsDir/.del/$file","undeleted",trperm_w); MoveTo("$fsDir/.del/$file","$fsDir/"); MoveTo("$fsDir/.del/.log/$file","$fsDir/.log/"); MoveTo("$fsDir/.del/.note/$file","$fsDir/.note/"); @@ -1693,11 +1875,13 @@ case "RENAME" : if ( $CONFIRM != "on" ) break ; - Logit("$fsDir/$FN","renamed $FN to $NEWNAME"); + $NEWNAME=stripSlashes($HTTP_POST_VARS["NEWNAME"]); + LogIt("$fsDir/$FN","renamed $FN to $NEWNAME",trperm_r); safe_rename($fsDir,$FN,$NEWNAME); break ; case "NOTE" : + $NOTE=stripSlashes($HTTP_POST_VARS["NOTE"]); WriteNote("$fsDir/$FN","$NOTE"); break ; @@ -1711,9 +1895,9 @@ } // common to all POSTs : redirect to directory view ($relDir) - if ( $POSTACTION != "" ) { - $tstr = $PHP_SELF . "?D=" . urlencode($relDir) ; - header("Location: " . $tstr) ; + if (isset($POSTACTION)) { + $tstr = $HTTP_SERVER_VARS["PHP_SELF"]."?D=".urlencode($relDir); + header("Location: ".$tstr) ; exit ; } @@ -1724,22 +1908,23 @@ // $A=Co : checkout file $D/$F // $A=Ci : checkin file $D/$F // $A=V : view file (do nothing except log) - // $A=I : include file .$F.php from $gblFsRoot + // $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 $HTTP_HOST." ; + $text .= "file to $realm." ; StartHTML("(Upload Page)", $text) ; UploadPage($gblFsRoot, $relDir) ; EndHTML() ; exit ; case "E" : - $F=stripSlashes($F); // detail of $relDir/$F if (is_file("$gblFsRoot/$relDir/$F") || is_dir("$gblFsRoot/$relDir/$F")) DetailPage($gblFsRoot, $relDir, $F) ; exit ; @@ -1751,7 +1936,7 @@ case "Co" : // checkout Lock("$gblFsRoot/$relDir/$F"); - Download("$gblFsRoot/$relDir/$F"); + Download("$gblFsRoot/$relDir/$F",1); exit; case "Ci" : $F=stripSlashes($F); @@ -1759,7 +1944,7 @@ if (!is_writeable($gblFsRoot . $relDir)) Error("Write access denied",$relDir) ; $text = "Use this page to update a single " ; - $text .= "file to $HTTP_HOST." ; + $text .= "file to $realm." ; StartHTML("(Update file Page)", $text) ; UploadPage($gblFsRoot, $relDir, $F) ; EndHTML() ; @@ -1767,12 +1952,7 @@ case "V" : // view LogIt("$gblFsRoot/$relDir/$F","viewed"); - if ($gblForceDownload) { - Download("$gblFsRoot/$relDir/$F"); - } else { - header("Content-Disposition: attachment; filename=$F" ); - Header("Location: $webRoot".urlpath("$relDir/$F")); - } + Download("$gblFsRoot/$relDir/$F",$gblForceDownload); exit; case "Ch" : StartHTML("(File changes)","All changes chronologicaly..."); @@ -1785,16 +1965,19 @@ EndHTML() ; exit; case "I" : - $F=stripSlashes($F); - $inc_file="${gblFsRoot}/.${F}.php"; - if (!isset($F) || $F == "" || !file_exists($inc_file)) Error("Fatal error $inc_file"); // can't find file to include + 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); + $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",".${F}.php"); + 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); StartHTML($title, $text) ; - print "

".GifIcon(up)." Back to front page.

"; + print "

".GifIcon(up)." Back to front page.

"; EndHTML() ; exit ; } @@ -1803,5 +1986,5 @@ Navigate($gblFsRoot,$relDir) ; exit ; - Error("Whooah!","By cartesian logic, this never happens") ; + Error("Whooah!","By cartesian logic, this never happens",1) ; ?>