root/alternc/trunk/bureau/class/m_mem.php

Revision 2076, 17.6 kB (checked in by anarcat, 10 months ago)

add a alternc_del_session() hook that removes the phpMyAdmin cookie on logout

Closes: #1082

Line 
1 <?php
2 /*
3  $Id: m_mem.php,v 1.19 2006/01/12 08:04:43 anarcat Exp $
4  ----------------------------------------------------------------------
5  LICENSE
6
7  This program is free software; you can redistribute it and/or
8  modify it under the terms of the GNU General Public License (GPL)
9  as published by the Free Software Foundation; either version 2
10  of the License, or (at your option) any later version.
11
12  This program is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  GNU General Public License for more details.
16
17  To read the license please visit http://www.gnu.org/copyleft/gpl.html
18  ----------------------------------------------------------------------
19  Original Author of file: Benjamin Sonntag
20  Purpose of file: Manage Login session on the virtual desktop and
21      member parameters
22  ----------------------------------------------------------------------
23 */
24 /**
25 * This class manage user sessions in the web desktop.
26 *
27 * This class manage user sessions and administration in AlternC.
28 * @copyright    AlternC-Team 2002-2005 http://alternc.org/
29 *
30 */
31 class m_mem {
32
33   /** Original uid for the temporary uid swapping (for administrators) */
34   var $olduid=0;
35  
36   /** This array contains the Tableau contenant les champs de la table "membres" du membre courant
37    * Ce tableau est utilisable globalement par toutes les classes filles.
38    */
39   var $user;
40   /** Tableau contenant les champs de la table "local" du membre courant
41    * Ce tableau est utilisable globalement par toutes les classes filles.
42    * Note : les champs de "local" sont spécifiques à l'hébergeur.
43    */
44   var $local;
45
46   /* ----------------------------------------------------------------- */
47   /**
48    * Constructeur
49    */
50   function m_mem() {
51   }
52
53   /* ----------------------------------------------------------------- */
54   /** Check that the current user is an admnistrator.
55    * @return boolean TRUE if we are super user, or FALSE if we are not.
56    */
57   function checkright() {
58     return ($this->user["su"]=="1");
59   }
60
61   /* ----------------------------------------------------------------- */
62   /** Start a session in the web desktop. Check username and password.
63    * <b>Note : </b>If the user entered a bas password, the failure will be logged
64    * and told to the corresponding user on next successfull login.
65    * @param $username string Username that want to get connected.
66    * @param $password string User Password.
67    * @return boolean TRUE if the user has been successfully connected, or FALSE if an error occured.
68    */
69   function login($username,$password,$restrictip=0) {
70     global $db,$session,$err,$cuid;
71     $err->log("mem","login",$username);
72     //    $username=addslashes($username);
73     //    $password=addslashes($password);
74     $db->query("select * from membres where login='$username';");
75     if ($db->num_rows()==0) {
76       $err->raise("mem",1);
77       return false;
78     }
79     $db->next_record();
80     if (_md5cr($password,$db->f("pass"))!=$db->f("pass")) {
81       $db->query("UPDATE membres SET lastfail=lastfail+1 WHERE uid='".$db->f("uid")."';");
82       $err->raise("mem",1);
83       return false;
84     }
85     if (!$db->f("enabled")) {
86       $err->raise("mem",2);
87       return false;
88     }
89     $this->user=$db->Record;
90     $cuid=$db->f("uid");
91     if ($restrictip) {
92       $ip="INET_ATON('".getenv("REMOTE_ADDR")."')";
93     } else $ip="0";
94     /* Close sessions that are more than 2 days old. */
95     $db->query("DELETE FROM sessions WHERE DATE_ADD(ts,INTERVAL 2 DAY)<NOW();");
96     /* Open the session : */
97     $session=md5(uniqid(mt_rand()));
98     $db->query("insert into sessions (sid,ip,uid) values ('$session',$ip,'$cuid');");
99     setcookie("session",$session,0,"/");
100     $err->error=0;
101     /* Fill in $local */
102     $db->query("SELECT * FROM local WHERE uid='$cuid';");
103     if ($db->num_rows()) {
104       $db->next_record();
105       $this->local=$db->Record;
106     }
107     return true;
108   }
109
110   /* ----------------------------------------------------------------- */
111   /** Start a session as another user from an administrator account.
112    * This function is not the same as su. setid connect the current user in the destination
113    * account (for good), and su allow any user to become another account for some commands only.
114    * (del_user, add_user ...) and allow to bring back admin rights with unsu
115    *
116    * @param $id integer User id where we will connect to.
117    * @return boolean TRUE if the user has been successfully connected, FALSE else.
118    */
119   function setid($id) {
120     global $db,$session,$err,$cuid;
121     $err->log("mem","setid",$username);
122     $db->query("select * from membres where uid='$id';");
123     if ($db->num_rows()==0) {
124       $err->raise("mem",1);
125       return false;
126     }
127     $db->next_record();
128     $this->user=$db->Record;
129     $cuid=$db->f("uid");
130     $ip=getenv("REMOTE_ADDR");
131     $session=md5(uniqid(mt_rand()));
132     $db->query("insert into sessions (sid,ip,uid) values ('$session',INET_ATON('$ip'),'$cuid');");
133     setcookie("session",$session,0,"/");
134     $err->error=0;
135     /* Fill in $local */
136     $db->query("SELECT * FROM local WHERE uid='$cuid';");
137     if ($db->num_rows()) {
138       $db->next_record();
139       $this->local=$db->Record;
140     }
141     return true;
142   }
143
144   /* ----------------------------------------------------------------- */
145   /** Suite à la connexion de l'utilisateur, réinitialise ses paramètres de dernière connexion
146    */
147   function resetlast() {
148     global $db,$cuid;
149     $ip=addslashes(getenv("REMOTE_HOST"));
150     if (!$ip) $ip=addslashes(getenv("REMOTE_ADDR"));
151     $db->query("UPDATE membres SET lastlogin=NOW(), lastfail=0, lastip='$ip' WHERE uid='$cuid';");
152   }
153
154   /* ----------------------------------------------------------------- */
155   /** Vérifie que la session courante est correcte (cookie ok et ip valide).
156    * Si besoin, et si réception des champs username & password, crée une nouvelle
157    * session pour l'utilisateur annoncé.
158    * Cette fonction doit être appellée à chaque page devant être authentifiée.
159    * et AVANT d'émettre des données. (un cookie peut être envoyé)
160    * @global string $session Le cookie de session eventuel
161    * @global string $username/password le login/pass de l'utilisateur
162    * @return TRUE si la session est correcte, FALSE sinon.
163    */
164   function checkid() {
165     global $db,$err,$session,$username,$password,$cuid,$restrictip;
166     if ($username && $password) {
167       return $this->login($username,$password,$restrictip);
168     }
169     $session=addslashes($session);
170     if (strlen($session)!=32) {
171       $err->raise("mem",3);
172       return false;
173     }
174     $ip=getenv("REMOTE_ADDR");
175     $db->query("select uid,INET_ATON('$ip') as me,ip from sessions where sid='$session'");
176     if ($db->num_rows()==0) {
177       $err->raise("mem",4);
178       return false;
179     }
180     $db->next_record();
181     if ($db->f("ip")) {
182       if ($db->f("me")!=$db->f("ip")) {
183     $err->raise("mem",5);
184     return false;
185       }
186     }
187     $cuid=$db->f("uid");
188     $db->query("select * from membres where uid='$cuid';");
189     $db->next_record();
190     $this->user=$db->Record;
191     $err->error=0;
192     /* Remplissage de $local */
193     $db->query("SELECT * FROM local WHERE uid='$cuid';");
194     if ($db->num_rows()) {
195       $db->next_record();
196       $this->local=$db->Record;
197     }
198     return true;
199   }
200
201   /* ----------------------------------------------------------------- */
202   /** Change l'identité d'un utilisateur temporairement.
203    * @global string $uid Utilisateur dont on prends l'identité
204    * @return TRUE si la session est correcte, FALSE sinon.
205    */
206   function su($uid) {
207     global $cuid,$db,$err;
208     if (!$this->olduid)
209     $this->olduid=$cuid;
210     $db->query("select * from membres where uid='$uid';");
211     if ($db->num_rows()==0) {
212       $err->raise("mem",1);
213       return false;
214     }
215     $db->next_record();
216     $this->user=$db->Record;
217     $cuid=$db->f("uid");
218     return true;
219   }
220
221   /* ----------------------------------------------------------------- */
222   /** Retourne a l'identite d'origine de l'utilisateur apres su.
223    * @return TRUE si la session est correcte, FALSE sinon.
224    */
225   function unsu() {
226     global $cuid;
227     if (!$this->olduid)
228     return false;
229     $this->su($this->olduid);
230     $this->olduid=0;
231     return true;
232   }
233
234
235   /* ----------------------------------------------------------------- */
236   /** Termine une session du bureau virtuel (logout)
237    * @return boolean TRUE si la session a bien été détruite, FALSE sinon.
238    */
239   function del_session() {
240     global $db,$session,$user,$err,$cuid,$classes;
241     $err->log("mem","del_session");
242     $session=addslashes($session);
243     setcookie("session","",0,"/");
244     if ($session=="") {
245       $err->error=0;
246       return true;
247     }
248     if (strlen($session)!=32) {
249       $err->raise("mem",3);
250       return false;
251     }
252     $ip=getenv("REMOTE_ADDR");
253     $db->query("select uid,INET_ATON('$ip') as me,ip from sessions where sid='$session'");
254     if ($db->num_rows()==0) {
255       $err->raise("mem",4);
256       return false;
257     }
258     $db->next_record();
259     if ($db->f("me")!=$db->f("ip")) {
260       $err->raise("mem",5);
261       return false;
262     }
263     $cuid=$db->f("uid");
264     $db->query("delete from sessions where sid='$session';");
265     $err->error=0;
266     
267     # Invoker le logout dans toutes les autres classes
268     foreach($classes as $c) {
269       if (method_exists($GLOBALS[$c],"alternc_del_session")) {
270         $GLOBALS[$c]->alternc_del_session($dom);
271       }
272     }
273     return true;
274   }
275
276   /* ----------------------------------------------------------------- */
277   /** Change le mot de passe de l'utilisateur courant.
278    * @param string $oldpass Ancien mot de passe.
279    * @param string $newpass Nouveau mot de passe
280    * @param string $newpass2 Nouveau mot de passe (à nouveau)
281    * @return boolean TRUE si le mot de passe a été changé, FALSE sinon.
282    */
283   function passwd($oldpass,$newpass,$newpass2) {
284     global $db,$err,$cuid;
285     $err->log("mem","passwd");
286     $oldpass=stripslashes($oldpass);
287     $newpass=stripslashes($newpass);
288     $newpass2=stripslashes($newpass2);
289     if (!$this->user["canpass"]) {
290       $err->raise("mem",11);
291       return false;
292     }
293     if ($this->user["pass"]!=_md5cr($oldpass,$this->user["pass"])) {
294       $err->raise("mem",6);
295       return false;
296     }
297     if ($newpass!=$newpass2) {
298       $err->raise("mem",7);
299       return false;
300     }
301     if (strlen($newpass)<3) {
302       $err->raise("mem",8);
303       return false;
304     }
305     $newpass=_md5cr($newpass);
306     $db->query("UPDATE membres SET pass='$newpass' WHERE uid='$cuid';");
307     $err->error=0;
308     return true;
309   }
310
311   /* ----------------------------------------------------------------- */
312   /** Change les préférences administrateur d'un compte
313    * @param integer $admlist Mode de visualisation des membres (0=large 1=courte)
314    * @return boolean TRUE si les préférences ont été changées, FALSE sinon.
315    */
316   function adminpref($admlist) {
317     global $db,$err,$cuid;
318     $err->log("mem","admlist");
319     if (!$this->user["su"]) {
320       $err->raise("mem",12);
321       return false;
322     }
323     $db->query("UPDATE membres SET admlist='$admlist' WHERE uid='$cuid';");
324     $err->error=0;
325     return true;
326   }
327
328   /* ----------------------------------------------------------------- */
329   /** Envoie en mail le mot de passe d'un compte.
330    * <b>Note : </b>On ne peut demander le mot de passe qu'une seule fois par jour.
331    * TODO : Translate this mail into the localization program.
332    * TODO : Check this function's !
333    * @return boolean TRUE si le mot de passe a été envoyé avec succès, FALSE sinon.
334    */
335   function send_pass($login) {
336     global $err,$db,$L_HOSTING,$L_FQDN;
337     $err->log("mem","send_pass");
338     $db->query("SELECT * FROM membres WHERE login='$login';");
339     if (!$db->num_rows()) {
340       $err->raise("mem",2);
341       return false;
342     }
343     $db->next_record();
344     if (time()-$db->f("lastaskpass")<86400) {
345       $err->raise("mem",7);
346       return false;
347     }
348     $txt="Bonjour,
349 Il semblerait que vous ayez demandé à recevoir le mot de passe du
350 compte ".$login." sur $L_HOSTING
351 Voici donc le nom d'utilisateur et le mot de passe qui vous
352 permettront de rentrer sur le bureau virtuel :
353
354 --------------------------------------
355
356 Nom d'utilisateur : ".$db->f("login")."
357
358 Mot de passe : ".$db->f("pass")."
359
360 --------------------------------------
361
362 Note : si vous n'avez pas fait cette demande, cela signifie que
363 quelqu'un l'a faite pour vous. Vous pouvez donc ignorer ce message.
364 Si cela se reproduit, n'hésitez pas à contacter l'administrateur
365 de votre serveur.
366
367 Cordialement.
368 ";
369     mail($db->f("mail"),"Votre mot de passe sur $L_HOSTING",$txt,"From: postmaster@$L_FQDN\nReply-to: postmaster@$L_FQDN");
370     $db->query("UPDATE membres SET lastaskpass=".time()." WHERE login='$login';");
371     return true;
372   }
373
374   /* ----------------------------------------------------------------- */
375   /** Change le mail d'un membre (première etape, envoi du CookiE)
376    * TODO : insert this mail string into the localization system
377    * @param string $newmail Nouveau mail souhaité pour le membre.
378    * @return string le cookie si le mail a bien été envoyé, FALSE sinon
379    */
380   function ChangeMail1($newmail) {
381     global $err,$db,$L_HOSTING,$L_FQDN,$cuid;
382     $err->log("mem","changemail1",$newmail);
383     $db->query("SELECT * FROM membres WHERE uid='$cuid';");
384     if (!$db->num_rows()) {
385       $err->raise("mem",2);
386       return false;
387     }
388     $db->next_record();
389
390     // un cookie de 20 caractères pour le mail
391     $COOKIE=substr(md5(uniqid(rand(),1)),0,20);
392     // et de 6 pour la clé à entrer. ca me semble suffisant...
393     $KEY=substr(md5(uniqid(rand(),1)),0,6);
394     // TODO : Translate this and insert this in alternc.po
395     $txt="Bonjour,
396 Quelqu'un (peut-etre vous) a demandé le changement de l'email du compte
397 ".$db->f("login")." sur $L_HOSTING
398 Afin de confirmer que cet email est valide, merci de vous rendre à l'adresse
399 ci-dessous :
400
401 https://$L_FQDN/admin/mem_cm.php?usr=$cuid&cookie=$COOKIE
402
403 (attention : si cette adresse est coupée sur 2 lignes, ne pas oublier de
404 reconstituer sur une seule ligne). Le bureau vous demandera la clé qui vous
405 a été donnée lors de la demande de changement d'email.
406
407 Note : si vous n'avez pas fait cette demande, cela signifie que quelqu'un
408 l'a faite pour vous. Vous pouvez donc ignorer ce message. Si cela se
409 reproduit, n'hésitez pas à contacter l'administrateur de votre serveur.
410
411 Cordialement.
412 ";
413     mail($newmail,"Changement d'email sur $L_HOSTING",$txt,"From: postmaster@$L_FQDN\nReply-to: postmaster@$L_FQDN");
414     // Supprime les demandes précédentes de ce compte !
415     $db->query("DELETE FROM chgmail WHERE uid='$cuid';");
416     $db->query("INSERT INTO chgmail (cookie,ckey,uid,mail,ts) VALUES ('$COOKIE','$KEY','$cuid','$newmail',".time().");");
417     // Supprime les cookies de la veille :)
418     $lts=time()-86400;
419     $db->query("DELETE FROM chgmail WHERE ts<'$lts';");
420     return $KEY;
421   }
422
423   /* ----------------------------------------------------------------- */
424     /** Change le mail d'un membre (seconde etape, CookiE+clé = application)
425      * @param string $COOKIE Cookie envoyé par mail
426      * @param string $KEY clé affichée à l'écran
427      * @param integer $uid Utilisateur concerné (on est hors session)
428      * @return TRUE si le mail a bien été modifié, FALSE sinon
429      */
430     function ChangeMail2($COOKIE,$KEY,$uid) {
431       global $err,$db,$L_HOSTING,$L_FQDN;
432       $err->log("mem","changemail2",$uid);
433       $db->query("SELECT * FROM chgmail WHERE cookie='$COOKIE' and ckey='$KEY' and uid='$uid';");
434       if (!$db->num_rows()) {
435     $err->raise("mem",9);
436     return false;
437       }
438       $db->next_record();
439
440       // met à jour le compte :
441       $db->query("UPDATE membres SET mail='".$db->f("mail")."' WHERE uid='$uid';");
442
443       $db->query("DELETE FROM chgmail WHERE uid='$uid';");
444       // Supprime les cookies de la veille :)
445       $lts=time()-86400;
446       $db->query("DELETE FROM chgmail WHERE ts<'$lts';");
447       return true;
448     }
449
450     /* ----------------------------------------------------------------- */
451     /** Modifie le paramètre d'aide en ligne (1/0)
452      * @param integer $show Faut-il (1) ou non (0) afficher l'aide en ligne
453      */
454     function set_help_param($show) {
455       global $db,$err,$cuid;
456       $err->log("mem","set_help_param",$show);
457       $db->query("UPDATE membres SET show_help='$show' WHERE uid='$cuid';");
458     }
459
460     /* ----------------------------------------------------------------- */
461     /** Dit si l'aide en ligne est demandée
462      * @return boolean TRUE si l'aide en ligne est demandée, FALSE sinon.
463      */
464     function get_help_param() {
465       return $this->user["show_help"];
466     }
467
468     /* ----------------------------------------------------------------- */
469     /** Affiche (echo) l'aide contextuelle
470      * @param integer $file Numéro de fichier d'aide à afficher.
471      * @return TRUE si l'aide contextuelle a été trouvée, FALSE sinon
472      */
473   function show_help($file) {
474     global $err;
475     $err->log("mem","show_help",$show);
476     if ($this->user["show_help"]) {
477       $hlp=_("hlp_$file");
478       if ($hlp!="hlp_$file") {
479     $hlp=ereg_replace(
480               "HELPID_([0-9]*)",
481               "<a href=\"javascript:help(\\1);\"><img src=\"/admin/aide/help.png\" width=\"17\" height=\"17\" style=\"vertical-align: middle;\" alt=\""._("Help")."\" /></a>",$hlp);
482     echo "<p class=\"hlp\">".$hlp."</p>";
483     return true;
484       }
485       return false;
486     } else {
487       return true;
488     }
489   }
490
491
492   /* ----------------------------------------------------------------- */
493   /**
494    * Exports all the personnal user related information for an account.
495    * @access private
496    * EXPERIMENTAL 'sid' function ;)
497    */
498   function alternc_export($tmpdir) {
499     global $db,$err;
500     $err->log("mem","export");
501     $str="<mem>\n";
502
503     foreach ($this->user as $k=>$v) {
504       $str.="   <$k>".xml_entities($v)."</$k>\n";
505     }
506     $str.="</mem>\n";
507     return $str;
508   }
509
510
511
512
513 } /* Classe Membre */
514
515 ?>
516
Note: See TracBrowser for help on using the browser.