1<? 2require_once("inc/common.php"); 3require_once("inc/io.php"); 4# load the the auth functions 5require_once('inc/auth_'.$conf['authtype'].'.php'); 6 7# some ACL level defines 8define('AUTH_NONE',0); 9define('AUTH_READ',1); 10define('AUTH_EDIT',2); 11define('AUTH_CREATE',4); 12define('AUTH_UPLOAD',8); 13define('AUTH_GRANT',255); 14 15if($conf['useacl']){ 16 auth_login($_REQUEST['u'],$_REQUEST['p']); 17 # load ACL into a global array 18 $AUTH_ACL = file('conf/acl.auth'); 19} 20 21/** 22 * This tries to login the user based on the sent auth credentials 23 * 24 * The authentication works like this: if a username was given 25 * a new login is assumed and user/password are checked - if they 26 * are correct a random authtoken is created which is stored in 27 * the session _and_ in a cookie. 28 * The user stays logged in as long as the session and the cookie 29 * match. This still isn't the securest method but requires an 30 * attacker to steal an existing session _and_ the authtoken 31 * cookie. The actual password is only transfered once per login. 32 * 33 * On a successful login $_SERVER[REMOTE_USER] and $USERINFO 34 * are set. 35*/ 36function auth_login($user,$pass){ 37 global $USERINFO; 38 global $conf; 39 global $lang; 40 $cookie = $_COOKIE['AUTHTOKEN']; 41 $session = $_SESSION[$conf['title']]['authtoken']; 42 43 if(isset($user)){ 44 if (auth_checkPass($user,$pass)){ 45 //make username available as REMOTE_USER 46 $_SERVER['REMOTE_USER'] = $user; 47 //set global user info 48 $USERINFO = auth_getUserData($user); 49 //set authtoken 50 $token = md5(uniqid(rand(), true)); 51 $_SESSION[$conf['title']]['user'] = $user; 52 $_SESSION[$conf['title']]['authtoken'] = $token; 53 setcookie('AUTHTOKEN', $token); 54 }else{ 55 //invalid credentials - log off 56 msg($lang['badlogin'],-1); 57 auth_logoff(); 58 } 59 }elseif(isset($cookie) && isset($session)){ 60 if($cookie == $session){ 61 //make username available as REMOTE_USER 62 $_SERVER['REMOTE_USER'] = $_SESSION[$conf['title']]['user']; 63 //set global user info 64 $USERINFO = auth_getUserData($_SERVER['REMOTE_USER']); 65 }else{ 66 //bad token 67 auth_logoff(); 68 } 69 }else{ 70 //just to be sure 71 auth_logoff(); 72 } 73} 74 75/** 76 * This clears all authenticationdata and thus log the user 77 * off 78 */ 79function auth_logoff(){ 80 global $conf; 81 global $USERINFO; 82 unset($_SESSION[$conf['title']]['authtoken']); 83 unset($_SESSION[$conf['title']]['user']); 84 unset($_SERVER['REMOTE_USER']); 85 $USERINFO=null; 86} 87 88/** 89 * Convinience function for auth_aclcheck 90 */ 91function auth_quickaclcheck($id){ 92 global $conf; 93 global $USERINFO; 94 # if no ACL is used always return upload rights 95 if(!$conf['useacl']) return AUTH_UPLOAD; 96 return auth_aclcheck($id,$_SERVER['REMOTE_USER'],$USERINFO['grps']); 97} 98 99/** 100 * Returns the maximum rights a user has for 101 * the given ID or its namespace 102 */ 103function auth_aclcheck($id,$user,$groups){ 104 global $conf; 105 global $AUTH_ACL; 106 107 # if no ACL is used always return upload rights 108 if(!$conf['useacl']) return AUTH_UPLOAD; 109 110 $ns = getNS($id); 111 $perm = -1; 112 113 if($user){ 114 //prepend groups with @ 115 for($i=0; $i<count($groups); $i++){ 116 $groups[$i] = '@'.$groups[$i]; 117 } 118 //add ALL group 119 $groups[] = '@ALL'; 120 //add User 121 $groups[] = $user; 122 //build regexp 123 $regexp = join('|',$groups); 124 }else{ 125 $regexp = '@ALL'; 126 } 127 128 //check exact match first 129 $matches = preg_grep('/^'.$id.'\s+('.$regexp.')\s+/',$AUTH_ACL); 130 if(count($matches)){ 131 foreach($matches as $match){ 132 $match = preg_replace('/#.*$/','',$match); //ignore comments 133 $acl = preg_split('/\s+/',$match); 134 if($acl[2] > $perm){ 135 $perm = $acl[2]; 136 } 137 } 138 if($perm > -1){ 139 //we had a match - return it 140 return $perm; 141 } 142 } 143 144 //still here? do the namespace checks 145 if($ns){ 146 $path = $ns.':\*'; 147 }else{ 148 $path = '\*'; //root document 149 } 150 151 do{ 152 $matches = preg_grep('/^'.$path.'\s+('.$regexp.')\s+/',$AUTH_ACL); 153 if(count($matches)){ 154 foreach($matches as $match){ 155 $match = preg_replace('/#.*$/','',$match); //ignore comments 156 $acl = preg_split('/\s+/',$match); 157 if($acl[2] > $perm){ 158 $perm = $acl[2]; 159 } 160 } 161 //we had a match - return it 162 return $perm; 163 } 164 165 //get next higher namespace 166 $ns = getNS($ns); 167 168 if($path != '\*'){ 169 $path = $ns.':\*'; 170 if($path == ':\*') $path = '\*'; 171 }else{ 172 //we did this already 173 //looks like there is something wrong with the ACL 174 //break here 175 return $perm; 176 } 177 }while(1); //this should never loop endless 178} 179 180/** 181 * Create a pronouncable password 182 * 183 * @see: http://www.phpbuilder.com/annotate/message.php3?id=1014451 184 */ 185function auth_pwgen(){ 186 $pw = ''; 187 $c = 'bcdfghjklmnprstvwz'; //consonants except hard to speak ones 188 $v = 'aeiou'; //vowels 189 $a = $c.$v; //both 190 191 //use two syllables... 192 for($i=0;$i < 2; $i++){ 193 $pw .= $c[rand(0, strlen($c)-1)]; 194 $pw .= $v[rand(0, strlen($v)-1)]; 195 $pw .= $a[rand(0, strlen($a)-1)]; 196 } 197 //... and add a nice number 198 $pw .= rand(10,99); 199 200 return $pw; 201} 202 203/** 204 * Sends a password to the given user 205 * 206 * returns true on success 207 */ 208function auth_sendPassword($user,$password){ 209 global $conf; 210 global $lang; 211 $users = auth_loadUserData(); 212 $hdrs = ''; 213 214 if(!$users[$user]['mail']) return false; 215 216 $text = rawLocale('password'); 217 $text = str_replace('@DOKUWIKIURL@',getBaseURL(true),$text); 218 $text = str_replace('@FULLNAME@',$users[$user]['name'],$text); 219 $text = str_replace('@LOGIN@',$user,$text); 220 $text = str_replace('@PASSWORD@',$password,$text); 221 $text = str_replace('@TITLE@',$conf['title'],$text); 222 223 if (!empty($conf['mailfrom'])) { 224 $hdrs = 'From: '.$conf['mailfrom']."\n"; 225 } 226 return @mail($users[$user]['mail'],$lang['regpwmail'],$text,$hdrs); 227} 228 229/** 230 * The new user registration - we get our info directly from 231 * $_POST 232 * 233 * It returns true on success and false on any error 234 */ 235function register(){ 236 global $lang; 237 global $conf; 238 239 if(!$_POST['save']) return false; 240 if(!$conf['openregister']) return false; 241 242 //clean username 243 $_POST['login'] = preg_replace('/.*:/','',$_POST['login']); 244 $_POST['login'] = cleanID($_POST['login']); 245 //clean fullname and email 246 $_POST['fullname'] = trim(str_replace(':','',$_POST['fullname'])); 247 $_POST['email'] = trim(str_replace(':','',$_POST['email'])); 248 249 if( empty($_POST['login']) || 250 empty($_POST['fullname']) || 251 empty($_POST['email']) ){ 252 msg($lang['regmissing'],-1); 253 return false; 254 } 255 256 //check mail 257 if(!isvalidemail($_POST['email'])){ 258 msg($lang['regbadmail'],-1); 259 return false; 260 } 261 262 //okay try to create the user 263 $pass = auth_createUser($_POST['login'],$_POST['fullname'],$_POST['email']); 264 if(empty($pass)){ 265 msg($lang['reguexists'],-1); 266 return false; 267 } 268 269 //send him the password 270 if (auth_sendPassword($_POST['login'],$pass)){ 271 msg($lang['regsuccess'],1); 272 return true; 273 }else{ 274 msg($lang['regmailfail'],-1); 275 return false; 276 } 277} 278 279/** 280 * Uses a regular expresion to check if a given mail address is valid 281 * 282 * @see http://www.webmasterworld.com/forum88/135.htm 283 * 284 * May not be completly RFC conform! 285 */ 286function isvalidemail($email){ 287 return eregi("^[0-9a-z]([-_.]?[0-9a-z])*@[0-9a-z]([-.]?[0-9a-z])*\\.[a-z]{2,4}$", $email); 288} 289 290?> 291