1<?php 2if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../../../../../../../../').'/'); 3$CONF_DIR = DOKU_INC.'conf'; 4if(file_exists($CONF_DIR)) { 5 if(!defined('DOKU_CONF')) define('DOKU_CONF',DOKU_INC.'conf/'); 6} 7else { 8 require_once(DOKU_INC. 'inc/preload.php'); 9 } 10require_once DOKU_INC.'inc/utf8.php'; 11 12// some ACL level defines 13 define('AUTH_NONE',0); 14 define('AUTH_READ',1); 15 define('AUTH_EDIT',2); 16 define('AUTH_CREATE',4); 17 define('AUTH_UPLOAD',8); 18 define('AUTH_DELETE',16); 19 define('AUTH_ADMIN',255); 20 global $AUTH_ACL; 21 22 global $cache_authname; $cache_authname = array(); 23 global $config_cascade; 24 global $Dwfck_conf_values; 25 $AUTH_ACL = array(); 26 27 //load ACL into a global array XXX 28 $auth_file = DOKU_CONF. '/acl.auth.php'; 29 if(isset( $_COOKIE['FCK_animal_inc'] )) { 30 $animal_inc = $_COOKIE['FCK_animal_inc']; 31 $auth_file = $animal_inc.'conf/acl.auth.php'; 32} 33 34 $AUTH_ACL = file($auth_file); 35 36/** 37 * Returns the maximum rights a user has for 38 * the given ID or its namespace 39 * 40 * @author Andreas Gohr <andi@splitbrain.org> 41 * 42 * @param string $id page ID 43 * @param string $user Username 44 * @param array $groups Array of groups the user is in 45 * @return int permission level 46 */ 47function auth_aclcheck($id,$user,$groups, $_auth=1){ 48 49 global $AUTH_ACL; 50 $AUTH_ACL = auth_loadACL($AUTH_ACL); 51 if($_auth == 255) { 52 return 255; 53 } 54 elseif(isset($_SESSION['dwfck_acl']) && $_SESSION['dwfck_acl'] == 255) { 55 return 255; 56 } 57 //make sure groups is an array 58 if(!is_array($groups)) $groups = array(); 59 60 if(!auth_isCaseSensitive()) { 61 $user = utf8_strtolower($user); 62 $groups = array_map('utf8_strtolower', $groups); 63 } 64 $user = auth_cleanUser($user); 65 $groups = array_map('auth_cleanGroup', (array) $groups); 66 $user = auth_nameencode($user); 67 68 //prepend groups with @ and nameencode 69 $cnt = count($groups); 70 for($i = 0; $i < $cnt; $i++) { 71 $groups[$i] = '@'.auth_nameencode($groups[$i]); 72 } 73 74 $ns = getNS($id); 75 $perm = -1; 76 77 if($user || count($groups)) { 78 //add ALL group 79 $groups[] = '@ALL'; 80 //add User 81 if($user) $groups[] = $user; 82 } else { 83 $groups[] = '@ALL'; 84 } 85 86 //check exact match first 87 $matches = preg_grep('/^'.preg_quote($id, '/').'[ \t]+([^ \t]+)[ \t]+/', $AUTH_ACL); 88 if(count($matches)) { 89 foreach($matches as $match) { 90 $match = preg_replace('/#.*$/', '', $match); //ignore comments 91 $acl = preg_split('/[ \t]+/', $match); 92 if(!auth_isCaseSensitive() && $acl[1] !== '@ALL') { 93 $acl[1] = utf8_strtolower($acl[1]); 94 } 95 if(!in_array($acl[1], $groups)) { 96 continue; 97 } 98 if($acl[2] > AUTH_DELETE) $acl[2] = AUTH_DELETE; //no admins in the ACL! 99 if($acl[2] > $perm) { 100 $perm = $acl[2]; 101 } 102 } 103 if($perm > -1) { 104 //we had a match - return it 105 return (int) $perm; 106 } 107 } 108 109 //still here? do the namespace checks 110 if($ns) { 111 $path = $ns.':*'; 112 } else { 113 $path = '*'; //root document 114 } 115 116 do { 117 $matches = preg_grep('/^'.preg_quote($path, '/').'[ \t]+([^ \t]+)[ \t]+/', $AUTH_ACL); 118 if(count($matches)) { 119 foreach($matches as $match) { 120 $match = preg_replace('/#.*$/', '', $match); //ignore comments 121 $acl = preg_split('/[ \t]+/', $match); 122 if(!auth_isCaseSensitive() && $acl[1] !== '@ALL') { 123 $acl[1] = utf8_strtolower($acl[1]); 124 } 125 if(!in_array($acl[1], $groups)) { 126 continue; 127 } 128 if($acl[2] > AUTH_DELETE) $acl[2] = AUTH_DELETE; //no admins in the ACL! 129 if($acl[2] > $perm) { 130 $perm = $acl[2]; 131 } 132 } 133 //we had a match - return it 134 if($perm != -1) { 135 return (int) $perm; 136 } 137 } 138 //get next higher namespace 139 $ns = getNS($ns); 140 141 if($path != '*') { 142 $path = $ns.':*'; 143 if($path == ':*') $path = '*'; 144 } else { 145 //we did this already 146 //looks like there is something wrong with the ACL 147 //break here 148 149 return AUTH_NONE; 150 } 151 } while(1); //this should never loop endless 152 return AUTH_NONE; 153} 154 155function auth_isCaseSensitive() { 156 global $Dwfck_conf_values; 157 if(!isset($Dwfck_conf_values['plugin'])) return false; 158 $ckgdoku = $Dwfck_conf_values['plugin']['ckgdoku']; 159 if(isset($ckgdoku['auth_ci']) && $ckgdoku['auth_ci']) { 160 return false; 161 } 162 return true; 163} 164 165function auth_nameencode($name,$skip_group=false){ 166 global $cache_authname; 167 $cache =& $cache_authname; 168 $name = (string) $name; 169 170 // never encode wildcard FS#1955 171 if($name == '%USER%') return $name; 172 if($name == '%GROUP%') return $name; 173 174 if (!isset($cache[$name][$skip_group])) { 175 if($skip_group && $name{0} =='@'){ 176 $cache[$name][$skip_group] = '@'.preg_replace_callback( 177 '/([\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f])/', 178 'auth_nameencode_callback', substr($name, 1) 179 ); 180 }else{ 181 $cache[$name][$skip_group] = preg_replace_callback( 182 '/([\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f])/', 183 'auth_nameencode_callback', $name 184 ); 185 } 186 } 187 188 return $cache[$name][$skip_group]; 189} 190 191/** 192 * callback encodes the matches 193 * 194 * @param array $matches first complete match, next matching subpatterms 195 * @return string 196 */ 197function auth_nameencode_callback($matches) { 198 return '%'.dechex(ord(substr($matches[1],-1))); 199} 200 201 202function getNS($id){ 203 $pos = strrpos((string)$id,':'); 204 if($pos!==false){ 205 return substr((string)$id,0,$pos); 206 } 207 return false; 208} 209 210/** 211 * Remove unwanted chars from ID 212 * 213 * Cleans a given ID to only use allowed characters. Accented characters are 214 * converted to unaccented ones 215 * 216 * @author Andreas Gohr <andi@splitbrain.org> 217 * @param string $raw_id The pageid to clean 218 * @param boolean $ascii Force ASCII 219 * @param boolean $media Allow leading or trailing _ for media files 220 */ 221function cleanID($raw_id,$ascii=false,$media=false){ 222 global $dwfck_conf; 223 224 static $sepcharpat = null; 225 static $cache = array(); 226 227 // check if it's already in the memory cache 228 if (isset($cache[(string)$raw_id])) { 229 return $cache[(string)$raw_id]; 230 } 231 232 233 $sepchar = $dwfck_conf['sepchar']; 234 if($sepcharpat == null) // build string only once to save clock cycles 235 $sepcharpat = '#\\'.$sepchar.'+#'; 236 237 $id = trim((string)$raw_id); 238 $id = utf8_strtolower($id); 239 240 //alternative namespace seperator 241 $id = strtr($id,';',':'); 242 if($dwfck_conf['useslash']){ 243 $id = strtr($id,'/',':'); 244 }else{ 245 $id = strtr($id,'/',$sepchar); 246 } 247 248 if($dwfck_conf['deaccent'] == 2 || $ascii) $id = utf8_romanize($id); 249 if($dwfck_conf['deaccent'] || $ascii) $id = utf8_deaccent($id,-1); 250 251 //remove specials 252 $id = utf8_stripspecials($id,$sepchar,'\*'); 253 254 if($ascii) $id = utf8_strip($id); 255 256 //clean up 257 $id = preg_replace($sepcharpat,$sepchar,$id); 258 $id = preg_replace('#:+#',':',$id); 259 $id = ($media ? trim($id,':.-') : trim($id,':._-')); 260 $id = preg_replace('#:[:\._\-]+#',':',$id); 261 262 $cache[(string)$raw_id] = $id; 263 return($id); 264} 265 266 267/** 268 * Loads the ACL setup and handle user wildcards 269 * 270 * @author Andreas Gohr <andi@splitbrain.org> 271 * @returns array 272 */ 273function auth_loadACL($acl_file){ 274 global $config_cascade; 275 276 $acl = $acl_file; 277 $sess_id = session_id(); 278 if(!isset($sess_id) || $sess_id != $_COOKIE['FCK_NmSp_acl']) { 279 session_id($_COOKIE['FCK_NmSp_acl']); 280 session_start(); 281 if(isset($_SESSION['dwfck_client'])) { 282 $_SERVER['REMOTE_USER'] = $_SESSION['dwfck_client']; 283 } 284 } 285 else { 286 if(isset($_SESSION['dwfck_client'])) { 287 $_SERVER['REMOTE_USER'] = $_SESSION['dwfck_client']; 288 } 289 } 290 //support user wildcard 291 if(isset($_SERVER['REMOTE_USER'])){ 292 $len = count($acl); 293 for($i=0; $i<$len; $i++){ 294 if($acl[$i]{0} == '#') continue; 295 list($id,$rest) = preg_split('/\s+/',$acl[$i],2); 296 $id = str_replace('%USER%',cleanID($_SERVER['REMOTE_USER']),$id); 297 $rest = str_replace('%USER%',auth_nameencode($_SERVER['REMOTE_USER']),$rest); 298 $acl[$i] = "$id\t$rest"; 299 } 300 } 301 else { 302 $acl = str_replace('%USER%',$user,$acl); // fall-back, in case client not found 303 } 304 return $acl; 305} 306 307function checkacl_write_debug($data) { 308 309 return; 310 if (!$handle = fopen('acl.txt', 'a')) { 311 return; 312 } 313 314 fwrite($handle, "$data\n"); 315 fclose($handle); 316 317} 318 319 function get_conf_array($str) { 320 $str = preg_replace('/\s+/',"",$str); 321 return explode(';;', $str); 322 } 323 324 function has_acl_auth($path) { 325 326 } 327 328 329function auth_cleanUser($user) { 330 return $user; 331} 332 333function auth_cleanGroup($group) { 334 return $group; 335 } 336