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