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