source: alternc/trunk/bureau/class/m_mysql.php @ 2943

Revision 2943, 27.5 KB checked in by fufroma, 2 years ago (diff)

Séparation des bases de données utilisateurs de la base
de donnée systéme.

Attention ! Bug ! $db et $dbu ne sont pas étanche !
Il faut se pencher sur la class db_mysql.php pour
finir l'isolation

Line 
1<?php
2/*
3 $Id: m_mysql.php,v 1.35 2005/12/18 09:51:32 benjamin Exp $
4 ----------------------------------------------------------------------
5 AlternC - Web Hosting System
6 Copyright (C) 2002 by the AlternC Development Team.
7 http://alternc.org/
8 ----------------------------------------------------------------------
9 Based on:
10 Valentin Lacambre's web hosting softwares: http://altern.org/
11 ----------------------------------------------------------------------
12 LICENSE
13
14 This program is free software; you can redistribute it and/or
15 modify it under the terms of the GNU General Public License (GPL)
16 as published by the Free Software Foundation; either version 2
17 of the License, or (at your option) any later version.
18
19 This program is distributed in the hope that it will be useful,
20 but WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22 GNU General Public License for more details.
23
24 To read the license please visit http://www.gnu.org/copyleft/gpl.html
25 ----------------------------------------------------------------------
26 Original Author of file: Benjamin Sonntag
27 Purpose of file: Manage mysql database for users.
28 ----------------------------------------------------------------------
29*/
30/**
31 * MySQL user database management for AlternC.
32 * This class manage user's databases in MySQL, and user's MySQL accounts.
33 *
34 * @copyright    AlternC-Team 2002-2005 http://alternc.org/
35 */
36
37class DBU_mysql extends DB_Sql {
38  var $Host,$HumanHostname,$User,$Password;
39
40  /**
41  * Creator
42  */
43  function DBU_mysql() {
44
45    # Use the dbusers file if exist, else use default alternc configuration
46    if ( is_readable("/etc/alternc/dbusers.cnf") ) {
47      $mysqlconf=file_get_contents("/etc/alternc/dbusers.cnf");
48    } else {
49      $mysqlconf=file_get_contents("/etc/alternc/my.cnf");
50    }
51    $mysqlconf=explode("\n",$mysqlconf);
52
53    # Read the configuration
54    foreach ($mysqlconf as $line) {
55      # First, read the "standard" configuration
56      if (preg_match('/^([A-Za-z0-9_]*) *= *"?(.*?)"?$/', trim($line), $regs)) {
57          switch ($regs[1]) {
58          case "user":
59              $user = $regs[2];
60              break;
61          case "password":
62              $password = $regs[2];
63              break;
64          case "host":
65              $host = $regs[2];
66              break;
67          }
68      }
69      # Then, read specific alternc configuration
70      if (preg_match('/^#alternc_var ([A-Za-z0-9_]*) *= *"?(.*?)"?$/', trim($line), $regs)) {
71        $$regs[1]=$regs[2];
72      }
73    }
74
75    # Set value of human_host if unset
76    if (! isset($human_hostname) || empty($human_hostname)) {
77      if ( checkip($host) || checkipv6($host) ) {
78        $human_hostname = gethostbyaddr($host);
79      } else {
80        $human_hostname = $host;
81      }
82    }
83
84
85    # Create the object
86    $this->Host     = $host;
87    $this->User     = $user;
88    $this->Password = $password;
89// TODO BUG BUG BUG
90// c'est pas étanche : $db se retrouve avec Database de $sql->dbu . Danger, faut comprendre pourquoi
91    $this->Database = "alternc";
92    $this->HumanHostname = $human_hostname;
93
94  }
95}
96
97
98class m_mysql {
99  var $dbu;
100
101  /*---------------------------------------------------------------------------*/
102  /** Constructor
103  * m_mysql([$mid]) Constructeur de la classe m_mysql, initialise le membre concerne
104  */
105  function m_mysql() {
106    $this->dbu = new DBU_mysql();
107  }
108
109
110  /* ----------------------------------------------------------------- */
111  /** Hook called by m_quota to obtain the quota managed by this class.
112   * Quota name
113   */
114  function alternc_quota_names() {
115    return array("mysql","mysql_users");
116  }
117
118
119  /* ----------------------------------------------------------------- */
120  /**
121   * Password kind used in this class (hook for admin class)
122   */
123  function alternc_password_policy() {
124    return array("mysql"=>"MySQL users");
125  }
126
127
128  /*---------------------------------------------------------------------------*/
129  /** Get the list of the database for the current user.
130   * @return array returns an associative array as follow : <br>
131   *  "db" => database name "bck" => backup mode for this db
132   *  "dir" => Backup folder.
133   *  Returns FALSE if the user has no database.
134   */
135  function get_dblist() {
136    global $db,$err,$bro,$cuid;
137    $err->log("mysql","get_dblist");
138    $db->query("SELECT login,pass,db, bck_mode, bck_dir FROM db WHERE uid='$cuid' ORDER BY db;");
139    if (!$db->num_rows()) {
140      $err->raise("mysql",11);
141      return false;
142    }
143    $c=array();
144    while ($db->next_record()) {
145      list($dbu,$dbn)=split_mysql_database_name($db->f("db"));
146      $c[]=array("db"=>$db->f("db"), "name"=>$dbn,"bck"=>$db->f("bck_mode"), "dir"=>$db->f("bck_dir"), "login"=>$db->f("login"), "pass"=>$db->f("pass"));
147    }
148    return $c;
149  }
150
151
152  /*---------------------------------------------------------------------------*/
153  /** Returns the details of a user's database.
154   * $dbn is the name of the database (after the _) or nothing for the database "$user"
155   * @return array returns an associative array as follow :
156   *  "db" => Name of the database
157   *  "bck" => Current bckup mode
158   *  "dir" => Backup directory
159   *  "size" => Size of the database (in bytes)
160   *  "pass" => Password of the user
161   *  "history" => Number of backup we keep
162   *  "gzip" => Does we compress the dumps ?
163   *  Returns FALSE if the user has no database of if the database does not exist.
164   */
165  function get_mysql_details($dbn) {
166    global $db,$err,$bro,$mem,$cuid;
167    $root="/var/alternc/html/".substr($mem->user["login"],0,1)."/".$mem->user["login"];
168    $err->log("mysql","get_mysql_details");
169    $dbname=$mem->user["login"].($dbn?"_":"").$dbn;
170    $size=$this->get_db_size($dbname);
171    $db->query("SELECT login,pass,db, bck_mode, bck_gzip, bck_dir, bck_history FROM db WHERE uid='$cuid' AND db='$dbname';");
172    if (!$db->num_rows()) {
173      $err->raise("mysql",4);
174      return array("enabled"=>false);
175    }
176    $c=array();
177    $db->next_record();
178    list($dbu,$dbn)=split_mysql_database_name($db->f("db"));
179    return array("enabled"=>true,"login"=>$db->f("login"),"db"=>$db->f("db"), "name"=>$dbn,"bck"=>$db->f("bck_mode"), "dir"=>substr($db->f("bck_dir"),strlen($root)), "size"=>$size, "pass"=>$db->f("pass"), "history"=>$db->f("bck_history"), "gzip"=>$db->f("bck_gzip"));
180  }
181
182
183  /*---------------------------------------------------------------------------*/
184  /** Create a new database for the current user.
185   * @param $dbn string Database name ($user_$dbn is the mysql db name)
186   * @return TRUE if the database $user_$db has been successfully created, or FALSE if
187   * an error occured, such as over quota user.
188   */
189  function add_db($dbn) {
190    global $db,$err,$quota,$mem,$cuid;
191    $err->log("mysql","add_db",$dbn);
192    if (!$quota->cancreate("mysql")) {
193      $err->raise("mysql",1);
194      return false;
195    }
196    if (!ereg("^[0-9a-z]*$",$dbn)) {
197      $err->raise("mysql",2);
198      return false;
199    }
200    $dbname=$mem->user["login"].($dbn?"_":"").$dbn;
201    if (strlen($dbname) > 64) {
202      $err->raise("mysql",12);
203      return false;
204    }
205    $db->query("SELECT * FROM db WHERE db='$dbname';");
206    if ($db->num_rows()) {
207      $err->raise("mysql",3);
208      return false;
209    }
210    // find the login/pass for this user :
211    $db->query("SELECT login,pass FROM db WHERE uid='$cuid' LIMIT 0,1;");
212    if (!$db->num_rows()) {
213      $lo=$mem->user["login"];
214      $pa="";
215    } else {
216      $db->next_record();
217      $lo=addslashes($db->f("login"));
218      $pa=addslashes($db->f("pass"));
219    }
220    if ($this->dbu->query("CREATE DATABASE `$dbname`;")) {
221      // Ok, database does not exist, quota is ok and dbname is compliant. Let's proceed
222      $db->query("INSERT INTO db (uid,login,pass,db,bck_mode) VALUES ('$cuid','$lo','$pa','$dbname',0);");
223      // give everything but GRANT on db.*
224      // we assume there's already a user
225      $this->dbu->query("GRANT ALL PRIVILEGES ON `".$dbname."`.* TO '".$lo."'@'$this->client'");
226      return true;
227    } else {
228      $err->raise("mysql",3);
229      return false;
230    }
231  }
232
233
234  /*---------------------------------------------------------------------------*/
235  /** Delete a database for the current user.
236   * @param $dbn string Name of the database to delete. The db name is $user_$dbn
237   * @return TRUE if the database $user_$db has been successfully deleted, or FALSE if
238   *  an error occured, such as db does not exist.
239   */
240  function del_db($dbn) {
241    global $db,$err,$mem,$cuid;
242    $err->log("mysql","del_db",$dbn);
243
244    $dbname=addslashes($mem->user["login"].($dbn?"_":"").$dbn);
245    $db->query("SELECT login FROM db WHERE db='$dbname';");
246    if (!$db->num_rows()) {
247      $err->raise("mysql",4);
248      return false;
249    }
250    $db->next_record();
251    $login=$db->f("login");
252
253    // Ok, database exists and dbname is compliant. Let's proceed
254    $db->query("DELETE FROM db WHERE uid='$cuid' AND db='$dbname';");
255    $this->dbu->query("DROP DATABASE `$dbname`;");
256    $db->query("SELECT COUNT(*) AS cnt FROM db WHERE uid='$cuid';");
257    $db->next_record();
258    $this->dbu->query("REVOKE ALL PRIVILEGES ON `".$dbname."`.* FROM '".$login."'@'$this->client'");
259    if ($this->dbu->f("cnt")==0) {
260      $this->dbu->query("DELETE FROM mysql.user WHERE User='".$login."';");
261      $this->dbu->query("FLUSH PRIVILEGES;");
262    }
263    return true;
264  }
265 
266
267  /*---------------------------------------------------------------------------*/
268  /** Set the backup parameters for the database $db
269   * @param $db string database name
270   * @param $bck_mode integer Backup mode (0 = none 1 = daily 2 = weekly)
271   * @param $bck_history integer How many backup should we keep ?
272   * @param $bck_gzip boolean shall we compress the backup ?
273   * @param $bck_dir string Directory relative to the user account where the backup will be stored
274   * @return boolean true if the backup parameters has been successfully changed, false if not.
275   */
276  function put_mysql_backup($dbn,$bck_mode,$bck_history,$bck_gzip,$bck_dir) {
277    global $db,$err,$mem,$bro,$cuid;
278    $err->log("mysql","put_mysql_backup");
279    if (!ereg("^[0-9a-z]*$",$dbn)) {
280      $err->raise("mysql",2);
281      return false;
282    }
283    $dbname=$mem->user["login"].($dbn?"_":"").$dbn;
284    $db->query("SELECT * FROM db WHERE uid='$cuid' AND db='$dbname';");
285    if (!$db->num_rows()) {
286      $err->raise("mysql",4);
287      return false;
288    }
289    $db->next_record();
290    $bck_mode=intval($bck_mode);
291    $bck_history=intval($bck_history);
292    if ($bck_gzip)
293      $bck_gzip="1";
294    else
295      $bck_gzip="0";
296    if (!$bck_mode)
297      $bck_mode="0";
298    if (!$bck_history) {
299      $err->raise("mysql",5);
300      return false;
301    }
302    if (($bck_dir=$bro->convertabsolute($bck_dir,0))===false) { // return a full path or FALSE
303      $err->raise("mysql",6);
304      return false;
305    }
306    $db->query("UPDATE db SET bck_mode='$bck_mode', bck_history='$bck_history', bck_gzip='$bck_gzip', bck_dir='$bck_dir' WHERE uid='$cuid' AND db='$dbname';");
307    return true;
308  }
309
310
311  /*---------------------------------------------------------------------------*/
312  /** Change the password of the user in MySQL
313   * @param $password string new password (cleartext)
314   * @return boolean TRUE if the password has been successfully changed, FALSE else.
315   */
316  function put_mysql_details($password) {
317    global $db,$err,$mem,$cuid,$admin;
318    $err->log("mysql","put_mysql_details");
319    $db->query("SELECT * FROM db WHERE uid='$cuid';");
320    if (!$db->num_rows()) {
321      $err->raise("mysql",7);
322      return false;
323    }
324    $db->next_record();
325    $login=$db->f("login");
326
327    if (strlen($password)>16) {
328      $err->raise("mysql",8);
329      return false;
330    }
331    if (!$password) {
332      $err->raise("mysql",20);
333      return false;     
334    }
335
336    // Check this password against the password policy using common API :
337    if (is_callable(array($admin,"checkPolicy"))) {
338      if (!$admin->checkPolicy("mysql",$login,$password)) {
339              return false; // The error has been raised by checkPolicy()
340      }
341    }
342
343    // Update all the "pass" fields for this user :
344    $db->query("UPDATE db SET pass='$password' WHERE uid='$cuid';");
345    $this->dbu->query("SET PASSWORD FOR '$login'@'$this->client' = PASSWORD('$password')");
346    return true;
347  }
348
349
350  /* ----------------------------------------------------------------- */
351  /** Create a new mysql account for this user
352   * @param string cleartext password for the new account
353   * It also create the first database.
354   */
355  function new_mysql($password) {
356    global $db,$err,$mem,$cuid,$admin;
357    $err->log("mysql","new_mysql");
358    if (strlen($password)>16) {
359      $err->raise("mysql",8);
360      return false;
361    }
362    if (!$password) {
363      $err->raise("mysql",20);
364      return false;     
365    }
366    $db->query("SELECT * FROM db WHERE uid='$cuid';");
367    if ($db->num_rows()) {
368      $err->raise("mysql",10);
369      return false;
370    }
371    $login=$mem->user["login"];
372    $dbname=$mem->user["login"];
373
374    // Username cannot be longer than 16 characters
375    if (strlen($login)>16) {
376      $err->raise("mysql",15);
377      return false;
378    }
379
380    // Check this password against the password policy using common API :
381    if (is_callable(array($admin,"checkPolicy"))) {
382      if (!$admin->checkPolicy("mysql",$login,$password)) {
383        return false; // The error has been raised by checkPolicy()
384      }
385    }   
386
387    // OK, creation now...
388    $db->query("INSERT INTO db (uid,login,pass,db) VALUES ('$cuid','".$login."','$password','".$dbname."');");
389    // give everything but GRANT on $user.*
390    $this->dbu->query("GRANT ALL PRIVILEGES ON `".$dbname."`.* TO '".$login."'@'$this->client' IDENTIFIED BY '".addslashes($password)."'");
391    $this->dbu->query("CREATE DATABASE `".$dbname."`;");
392    return true;
393  }
394
395
396  /* ----------------------------------------------------------------- */
397  /** Restore a sql database.
398   * @param $file string The filename, relative to the user root dir, which contains a sql dump
399   * @param $stdout boolean shall-we dump the error to stdout ?
400   * @param $id integer The ID of the database to dump to.
401   * @return boolean TRUE if the database has been restored, or FALSE if an error occurred
402   */
403  function restore($file,$stdout,$id) { 
404// TODO don't work with the separated sql serveur for dbusers
405    global $err,$bro,$mem,$L_MYSQL_HOST;
406    if (!$r=$this->get_mysql_details($id)) { 
407      return false; 
408    } 
409    if (!($fi=$bro->convertabsolute($file,0))) {
410      $err->raise("mysql",9);
411      return false; 
412    }
413    if (substr($fi,-3)==".gz") {
414      $exe="/bin/gzip -d -c <".escapeshellarg($fi)." | /usr/bin/mysql -h".escapeshellarg($L_MYSQL_HOST)." -u".escapeshellarg($r["login"])." -p".escapeshellarg($r["pass"])." ".escapeshellarg($r["db"]); 
415    } elseif (substr($fi,-4)==".bz2") { 
416      $exe="/usr/bin/bunzip2 -d -c <".escapeshellarg($fi)." | /usr/bin/mysql -h".escapeshellarg($L_MYSQL_HOST)." -u".escapeshellarg($r["login"])." -p".escapeshellarg($r["pass"])." ".escapeshellarg($r["db"]); 
417    } else { 
418      $exe="/usr/bin/mysql -h".escapeshellarg($L_MYSQL_HOST)." -u".escapeshellarg($r["login"])." -p".escapeshellarg($r["pass"])." ".escapeshellarg($r["db"])." <".escapeshellarg($fi); 
419    }
420    $exe .= " 2>&1";
421   
422    echo "<code><pre>" ;
423    if ($stdout) {
424      passthru($exe,$ret);
425    } else {
426      exec ($exe,$ret);
427    }
428    echo "</pre></code>" ;
429    if ($ret != 0) {
430      return false ;
431    } else {
432      return true ;
433    }
434  }
435
436 
437  /* ----------------------------------------------------------------- */
438  /** Get the size of a database
439   * @param $dbname name of the database
440   * @return integer database size
441   * @access private
442   */
443  function get_db_size($dbname) {
444    global $db,$err;
445   
446    $this->dbu->query("SHOW TABLE STATUS FROM `$dbname`;");
447    $size = 0;
448    while ($db->next_record()) {
449      $size += $db->f('Data_length') + $db->f('Index_length')   + $db->f('Data_free');
450    }
451    return $size;
452  }
453 
454 
455  /* ------------------------------------------------------------ */
456  /**
457   * Returns the list of database users of an account
458   **/
459  function get_userslist() {
460    global $db,$err,$bro,$cuid;
461    $err->log("mysql","get_userslist");
462    $db->query("SELECT name FROM dbusers WHERE uid='$cuid' ORDER BY name;");
463    if (!$db->num_rows()) {
464      $err->raise("mysql",19);
465      return false;
466    }
467    $c=array();
468    while ($db->next_record()) {
469      $c[]=array("name"=>substr($db->f("name"),strpos($db->f("name"),"_")+1));
470    }
471
472    return $c;
473  }
474
475
476  /* ------------------------------------------------------------ */
477  /**
478   * Create a new user in MySQL rights tables
479   * @param $usern the username (we will add _[alternc-account] to it)
480   * @param $password The password for this username
481   * @param $passconf The password confirmation
482   * @return TRUE if the user has been created in MySQL or FALSE if an error occurred
483   **/
484  function add_user($usern,$password,$passconf) {
485    global $db,$err,$quota,$mem,$cuid,$admin;
486    $err->log("mysql","add_user",$usern);
487
488    $usern=trim($usern);
489    $user=addslashes($mem->user["login"]."_".$usern);
490    $pass=addslashes($password);
491
492    if (!$usern) {
493      $err->raise("mysql",21);
494      return false;
495    }
496    if (!$pass) {
497      $err->raise("mysql",20);
498      return false;
499    }
500    if (!$quota->cancreate("mysql_users")) {
501      $err->raise("mysql",13);
502      return false;
503    }
504    if (!ereg("^[0-9a-z]",$usern)) {
505      $err->raise("mysql",14);
506      return false;
507    }
508   
509    // We check the length of the COMPLETE username, not only the part after _
510    if (strlen($user) > 16) {
511      $err->raise("mysql",15);
512      return false;
513    }
514    $db->query("SELECT * FROM dbusers WHERE name='$user';");
515    if ($db->num_rows()) {
516      $err->raise("mysql",16);
517      return false;
518    }
519    if ($password != $passconf || !$password) {
520      $err->raise("mysql",17);
521      return false;
522    }
523
524    // Check this password against the password policy using common API :
525    if (is_callable(array($admin,"checkPolicy"))) {
526      if (!$admin->checkPolicy("mysql",$user,$password)) {
527              return false; // The error has been raised by checkPolicy()
528      }
529    }
530
531    // We create the user account (the "file" right is the only one we need globally to be able to use load data into outfile)
532    $this->dbu->query("GRANT file ON *.* TO '$user'@'$this->client' IDENTIFIED BY '$pass';");
533    // We add him to the user table
534    $db->query("INSERT INTO dbusers (uid,name) VALUES($cuid,'$user');");
535    return true;
536  }
537
538  /* ------------------------------------------------------------ */
539  /**
540   * Change a user's MySQL password
541   * @param $usern the username
542   * @param $password The password for this username
543   * @param $passconf The password confirmation
544   * @return TRUE if the password has been changed in MySQL or FALSE if an error occurred
545   **/
546  function change_user_password($usern,$password,$passconf) {
547    global $db,$err,$quota,$mem,$cuid,$admin;
548    $err->log("mysql","add_user",$usern);
549
550    $usern=trim($usern);
551    $user=addslashes($mem->user["login"]."_".$usern);
552    $pass=addslashes($password);
553    if ($password != $passconf || !$password) {
554      $err->raise("mysql",17);
555      return false;
556    }
557
558    // Check this password against the password policy using common API :
559    if (is_callable(array($admin,"checkPolicy"))) {
560      if (!$admin->checkPolicy("mysql",$user,$password)) {
561        return false; // The error has been raised by checkPolicy()
562      }
563    }
564
565    $this->dbu->query("SET PASSWORD FOR '$user'@'$this->client' = PASSWORD('$pass')");
566    return true;
567  }
568
569
570
571  /* ------------------------------------------------------------ */
572  /**
573   * Delete a user in MySQL rights tables
574   * @param $user the username (we will add "[alternc-account]_" to it) to delete
575   * @return TRUE if the user has been deleted in MySQL or FALSE if an error occurred
576   **/
577  function del_user($user) {
578    global $db,$err,$mem,$cuid,$L_MYSQL_DATABASE;
579    $err->log("mysql","del_user",$user);
580    if (!ereg("^[0-9a-z]",$user)) {
581      $err->raise("mysql",14);
582      return false;
583    }
584    $db->query("SELECT name FROM dbusers WHERE name='".$mem->user["login"]."_$user';");
585    if (!$db->num_rows()) {
586      $err->raise("mysql",18);
587      return false;
588    }
589    $db->next_record();
590    $login=$db->f("name");
591
592    // Ok, database exists and dbname is compliant. Let's proceed
593    $this->dbu->query("REVOKE ALL PRIVILEGES ON *.* FROM '".$mem->user["login"]."_$user'@'$this->client';");
594    $this->dbu->query("DELETE FROM mysql.db WHERE User='".$mem->user["login"]."_$user' AND Host='$this->client';");
595    $this->dbu->query("DELETE FROM mysql.user WHERE User='".$mem->user["login"]."_$user' AND Host='$this->client';");
596    $this->dbu->query("FLUSH PRIVILEGES");
597    $this->dbu->query("DELETE FROM dbusers WHERE uid='$cuid' AND name='".$mem->user["login"]."_$user';");
598    return true;
599  }
600
601
602  /* ------------------------------------------------------------ */
603  /**
604   * Return the list of the database rights of user $user
605   * @param $user the username
606   * @return array An array of database name and rights
607   **/
608  function get_user_dblist($user) {
609    global $db,$err,$mem,$cuid,$L_MYSQL_DATABASE;
610    $err->log("mysql","get_user_dblist");
611
612    $r=array();
613    $dblist=$this->get_dblist();
614
615    for ( $i=0 ; $i<count($dblist) ; $i++ ) {
616      $this->dbu->query("SELECT Db, Select_priv, Insert_priv, Update_priv, Delete_priv, Create_priv, Drop_priv, References_priv, Index_priv, Alter_priv, Create_tmp_table_priv, Lock_tables_priv FROM mysql.db WHERE User='".$mem->user["login"].($user?"_":"").$user."' AND Host='$this->client' AND Db='".$dblist[$i]["db"]."';");
617      if ($this->dbu->next_record())
618        $r[]=array("db"=>$dblist[$i]["name"], "select"=>$this->dbu->f("Select_priv"), "insert"=>$this->dbu->f("Insert_priv"),   "update"=>$this->dbu->f("Update_priv"), "delete"=>$this->dbu->f("Delete_priv"), "create"=>$this->dbu->f("Create_priv"), "drop"=>$this->dbu->f("Drop_priv"), "references"=>$this->dbu->f("References_priv"), "index"=>$this->dbu->f("Index_priv"), "alter"=>$this->dbu->f("Alter_priv"), "create_tmp"=>$this->dbu->f("Create_tmp_table_priv"), "lock"=>$this->dbu->f("Lock_tables_priv"));
619      else
620        $r[]=array("db"=>$dblist[$i]["name"], "select"=>"N", "insert"=>"N", "update"=>"N", "delete"=>"N", "create"=>"N", "drop"=>"N", "references"=>"N", "index"=>"N", "alter"=>"N", "Create_tmp"=>"N", "lock"=>"N" );
621    }
622   
623    return $r;
624  }
625
626  /* ------------------------------------------------------------ */
627  /**
628   * Set the access rights of user $user to database $dbn to be rights $rights
629   * @param $user the username to give rights to
630   * @param $dbn The database to give rights to
631   * @param $rights The rights as an array of MySQL keywords (insert, select ...)
632   * @return boolean TRUE if the rights has been applied or FALSE if an error occurred
633   *
634   **/
635  function set_user_rights($user,$dbn,$rights) {
636    global $mem, $db;
637
638    $usern=addslashes($mem->user["login"].($user?"_":"").$user);
639    $dbname=addslashes($mem->user["login"].($dbn?"_":"").$dbn);
640    // On génère les droits en fonction du tableau de droits
641    for( $i=0 ; $i<count($rights) ; $i++ ) {
642      switch ($rights[$i]) {
643        case "select":
644          $strrights.="SELECT,";
645          break;
646        case "insert":
647          $strrights.="INSERT,";
648          break;
649        case "update":
650          $strrights.="UPDATE,";
651          break;
652        case "delete":
653          $strrights.="DELETE,";
654          break;
655        case "create":
656          $strrights.="CREATE,";
657          break;
658        case "drop":
659          $strrights.="DROP,";
660          break;
661        case "references":
662          $strrights.="REFERENCES,";
663          break;
664        case "index":
665          $strrights.="INDEX,";
666          break;
667        case "alter":
668          $strrights.="ALTER,";
669          break;
670        case "create_tmp":
671          $strrights.="CREATE TEMPORARY TABLES,";
672          break;
673        case "lock":
674          $strrights.="LOCK TABLES,";
675          break;
676      }
677    }
678
679    // We reset all user rights on this DB :
680    $this->dbu->query("SELECT * FROM mysql.db WHERE User = '$usern' AND Db = '$dbname';");
681    if($this->dbu->num_rows())
682      $this->dbu->query("REVOKE ALL PRIVILEGES ON $dbname.* FROM '$usern'@'$this->client';");
683    if( $strrights ){
684      $strrights=substr($strrights,0,strlen($strrights)-1);
685      $this->dbu->query("GRANT $strrights ON $dbname.* TO '$usern'@'$this->client';");     
686    }
687    $this->dbu->query("FLUSH PRIVILEGES");
688    return TRUE;
689  }
690
691
692  /* ----------------------------------------------------------------- */
693  /** Hook function called by the quota class to compute user used quota
694   * Returns the used quota for the $name service for the current user.
695   * @param $name string name of the quota
696   * @return integer the number of service used or false if an error occured
697   * @access private
698   */
699  function alternc_get_quota($name) {
700    global $err,$db,$cuid;
701    if ($name=="mysql") {
702      $err->log("mysql","alternc_get_quota");
703      $c=$this->get_dblist();
704      if (is_array($c)) {
705              return count($c);
706      } else {
707              return 0;
708      }
709    } elseif ($name=="mysql_users") {
710      $err->log("mysql","alternc_get_quota");
711      $c=$this->get_userslist();
712      if(is_array($c))
713        return count($c);
714      else
715        return 0;
716    } else return false;
717  }
718 
719 
720  /* ----------------------------------------------------------------- */
721  /** Hook function called when a user is deleted.
722   * AlternC's standard function that delete a member
723   * @access private
724   */
725  function alternc_del_member() {
726    global $db,$err,$cuid;
727    $err->log("mysql","alternc_del_member");
728    $c=$this->get_dblist();
729    if (is_array($c)) {
730      for($i=0;$i<count($c);$i++) {
731              $this->del_db($c[$i]["name"]);
732      }
733    }
734    $d=$this->get_userslist();
735    if (is_array($d)) {
736      for($i=0;$i<count($d);$i++) {
737              $this->del_user($d[$i]["name"]);
738      }
739    }
740    return true;
741  }
742
743
744  /* ----------------------------------------------------------------- */
745  /** Hook function called when a user is logged out.
746   * We just remove the cookie created in admin/sql_admin.php
747   * @access private
748   */
749  function alternc_del_session() {
750    setcookie("REMOTE_USER","");
751    setcookie("REMOTE_PASSWORD","");
752  }
753
754 
755  /* ----------------------------------------------------------------- */
756  /**
757   * Exporte all the mysql information of an account
758   * @access private
759   * EXPERIMENTAL 'sid' function ;)
760   */
761  function alternc_export($tmpdir) {
762//TODO don't work with separated sql server for dbusers
763    global $db,$err,$cuid;
764    $err->log("mysql","export");
765    $db->query("SELECT login, pass, db, bck_mode, bck_dir, bck_history, bck_gzip FROM db WHERE uid='$cuid';");
766    if ($db->next_record()) {
767      $str="<mysql>\n";
768      $str.="  <login>".xml_entities($db->Record["login"])."</login>";
769      $str.="  <pass>".xml_entities($db->Record["pass"])."</pass>";
770      do {
771        // Do the dump :
772        $filename=$tmpdir."/mysql.".$db->Record["db"].".sql.gz";
773        exec("/usr/bin/mysqldump --add-drop-table --allow-keywords -Q -f -q -a -e -u".escapeshellarg($db->Record["login"])." -p".escapeshellarg($db->Record["pass"])." ".escapeshellarg($db->Record["db"])." |/bin/gzip >".escapeshellarg($filename));
774        $str.="  <db>\n";
775        $str.="    <name>".xml_entities($db->Record["db"])."</name>\n";
776        if ($s["bck_mode"]!=0) {
777          $str.="    <backup>\n";
778          $str.="      <mode>".xml_entities($db->Record["bck_mode"])."</mode>\n";
779          $str.="      <dir>".xml_entities($db->Record["bck_dir"])."</dir>\n";
780          $str.="      <history>".xml_entities($db->Record["bck_history"])."</history>\n";
781          $str.="      <gzip>".xml_entities($db->Record["bck_gzip"])."</gzip>\n";
782          $str.="    </backup>\n";
783        }
784        $str.="  </db>\n";
785      } while ($db->next_record());
786      $str.="</mysql>\n";
787    }
788    return $str;
789  }
790
791
792} /* Class m_mysql */
793
794?>
Note: See TracBrowser for help on using the repository browser.