diff --git a/functions.inc.php b/functions.inc.php index 01fc65b1..17cc047b 100644 --- a/functions.inc.php +++ b/functions.inc.php @@ -268,11 +268,13 @@ function check_domain($domain) { */ function get_password_expiration_value($domain) { $table_domain = table_by_key('domain'); - $domain = escape_string($domain); - $query = "SELECT password_expiry FROM $table_domain WHERE domain='$domain'"; - $result = db_query($query); - $password_expiration_value = db_assoc($result['result']); - return $password_expiration_value['password_expiry']; + $query = "SELECT password_expiry FROM $table_domain WHERE domain= :domain"; + + $result = db_prepared_fetch_one($query, array('domain' => $domain)); + if(is_array($result) && isset($result['password_expiry'])) { + return $result['password_expiry']; + } + return null; } /** @@ -531,12 +533,10 @@ function create_page_browser($idxfield, $querypart) { # get number of rows $query = "SELECT count(*) as counter FROM (SELECT $idxfield $querypart) AS tmp"; - $result = db_query($query); - if ($result['rows'] > 0) { - $row = db_assoc($result['result']); - $count_results = $row['counter'] -1; # we start counting at 0, not 1 + $result = db_prepared_fetch_one($query); + if ($result && isset($result['counter'])) { + $count_results = $result['counter'] -1; # we start counting at 0, not 1 } - # echo "
rows: " . ($count_results +1) . " --- $query"; if ($count_results < $page_size) { return array(); # only one page - no pagebrowser required @@ -583,16 +583,17 @@ function create_page_browser($idxfield, $querypart) { # afterwards: DROP SEQUENCE foo $result = db_query($query); - if ($result['rows'] > 0) { - while ($row = db_assoc($result['result'])) { - if ($row2 = db_assoc($result['result'])) { - $label = substr($row['label'], 0, $label_len) . '-' . substr($row2['label'], 0, $label_len); - $pagebrowser[] = $label; - } else { # only one row remaining - $label = substr($row['label'], 0, $label_len); - $pagebrowser[] = $label; - } + $result = db_prepared_fetch_all($query); + foreach($result as $k => $row) { + if(isset($result[$k + 1])) { + $row2 = $result[$k + 1]; + $label = substr($row['label'], 0, $label_len) . '-' . substr($row2['label'], 0, $label_len); } + else { + $label = substr($row['label'], 0, $label_len); + } + $pagebrowser[] = $label; + } if (db_pgsql()) { @@ -625,15 +626,17 @@ function divide_quota($quota) { */ function check_owner($username, $domain) { $table_domain_admins = table_by_key('domain_admins'); - $E_username = escape_string($username); - $E_domain = escape_string($domain); - $result = db_query("SELECT 1 FROM $table_domain_admins WHERE username='$E_username' AND (domain='$E_domain' OR domain='ALL') AND active='1'"); - if ($result['rows'] == 1 || $result['rows'] == 2) { # "ALL" + specific domain permissions is possible + $result = db_prepared_fetch_all( + "SELECT 1 FROM $table_domain_admins WHERE username= ? AND (domain = ? OR domain = 'ALL') AND active = ?" , + array($username, $domain, db_get_boolean(true)) + ); + + if(sizeof($result) == 1 || sizeof($result) == 2) { # "ALL" + specific domain permissions is possible # TODO: if superadmin, check if given domain exists in the database return true; } else { - if ($result['rows'] > 2) { # more than 2 results means something really strange happened... + if (sizeof($result) > 2) { # more than 2 results means something really strange happened... flash_error("Permission check returned multiple results. Please go to 'edit admin' for your username and press the save " . "button once to fix the database. If this doesn't help, open a bugreport."); } @@ -649,6 +652,7 @@ function check_owner($username, $domain) { * @return array of domain names. */ function list_domains_for_admin($username) { + $table_domain = table_by_key('domain'); $table_domain_admins = table_by_key('domain_admins'); @@ -659,30 +663,40 @@ function list_domains_for_admin($username) { $query = "SELECT $table_domain.domain FROM $table_domain "; $condition[] = "$table_domain.domain != 'ALL'"; - $result = db_query("SELECT username FROM $table_domain_admins WHERE username='$E_username' AND domain='ALL'"); - if ($result['rows'] < 1) { # not a superadmin + $pvalues = array(); + + $result = db_prepared_fetch_one("SELECT username FROM $table_domain_admins WHERE username= :username AND domain='ALL'", array('username' => $username)); + if (empty($result)) { # not a superadmin + $pvalues['username'] = $username; + $pvalues['active'] = db_get_boolean(true); + $pvalues['backupmx'] = db_get_boolean(false); + $query .= " LEFT JOIN $table_domain_admins ON $table_domain.domain=$table_domain_admins.domain "; - $condition[] = "$table_domain_admins.username='$E_username' "; - $condition[] = "$table_domain.active='" . db_get_boolean(true) . "'"; # TODO: does it really make sense to exclude inactive... - $condition[] = "$table_domain.backupmx='" . db_get_boolean(false) . "'"; # TODO: ... and backupmx domains for non-superadmins? + $condition[] = "$table_domain_admins.username = :username "; + $condition[] = "$table_domain.active = :active "; # TODO: does it really make sense to exclude inactive... + $condition[] = "$table_domain.backupmx = :backupmx" ; # TODO: ... and backupmx domains for non-superadmins? } $query .= " WHERE " . join(' AND ', $condition); $query .= " ORDER BY $table_domain.domain"; - $list = array(); - $result = db_query($query); - if ($result['rows'] > 0) { - $i = 0; - while ($row = db_assoc($result['result'])) { - $list[$i] = $row['domain']; - $i++; - } - } - return $list; + $result = db_prepared_fetch_all($query, $pvalues); + + return array_column($result, 'domain'); + } +if(!function_exists('array_column')) { + function array_column(array $array, $column) { + $retval = array(); + foreach($array as $row) { + $retval[] = $row[$column]; + } + return $retval; + } +} + /** * List all available domains. * @@ -692,15 +706,11 @@ function list_domains() { $list = array(); $table_domain = table_by_key('domain'); - $result = db_query("SELECT domain FROM $table_domain WHERE domain!='ALL' ORDER BY domain"); - if ($result['rows'] > 0) { - $i = 0; - while ($row = db_assoc($result['result'])) { - if (is_array($row)) { - $list[$i] = $row['domain']; - $i++; - } - } + $result = db_prepared_fetch_all("SELECT domain FROM $table_domain WHERE domain!='ALL' ORDER BY domain"); + $i = 0; + foreach($result as $row) { + $list[$i] = $row['domain']; + $i++; } return $list; } @@ -929,14 +939,13 @@ function _pacrypt_mysql_encrypt($pw, $pw_db) { // this is apparently useful for pam_mysql etc. $pw = escape_string($pw); if ($pw_db!="") { - $salt=escape_string(substr($pw_db, 0, 2)); - $res=db_query("SELECT ENCRYPT('".$pw."','".$salt."');"); + $values = array('pw' => $pw_db, 'salt' => substr($pw_db, 0, 2)); + $res = db_prepared_fetch_one("SELECT ENCRYPT(:pw,:salt) as result", $values); } else { - $res=db_query("SELECT ENCRYPT('".$pw."');"); + $res= db_prepared_fetch_one("SELECT ENCRYPT(:pw) as result", array('pw' => $pw)); } - $l = db_row($res["result"]); - $password = $l[0]; - return $password; + + return $res['result']; } function _pacrypt_authlib($pw, $pw_db) { @@ -1460,7 +1469,7 @@ EOF; * array($link, $error_text); * * @param bool $ignore_errors - * @return resource|mysqli|SQLite3 connection to db + * @return PDO */ function db_connect() { list($link, $_) = db_connect_with_errors(); @@ -1485,70 +1494,42 @@ function db_connect_with_errors() { } $link = 0; - if ($CONF['database_type'] == "mysql") { - if (function_exists("mysql_connect")) { - $link = @mysql_connect($CONF['database_host'], $CONF['database_user'], $CONF['database_password']) or $error_text .= ("
DEBUG INFORMATION:DEBUG INFORMATION:
MySQL 3.x / 4.0 functions not available! (php5-mysql installed?)
database_type = 'mysql' in config.inc.php, are you using a different database? $DEBUG_TEXT";
- }
- } elseif ($CONF['database_type'] == "mysqli") {
- $is_connected = false;
- if ($CONF['database_use_ssl']) {
- if (function_exists("mysqli_real_connect")) {
- $link = mysqli_init();
- $link->ssl_set($CONF['database_ssl_key'], $CONF['database_ssl_cert'], $CONF['database_ssl_ca'], $CONF['database_ssl_ca_path'], $CONF['database_ssl_cipher']);
- $connected = mysqli_real_connect($link, $CONF['database_host'], $CONF['database_user'], $CONF['database_password'], $CONF['database_name'], $CONF['database_port']);
- $is_connected = $connected;
- } else {
- $error_text .= "
DEBUG INFORMATION:
MySQLi 5 functions not available! (php5-mysqli installed?)
database_type = 'mysqli' in config.inc.php, are you using a different database? $DEBUG_TEXT";
- }
- } else {
- if (function_exists("mysqli_connect")) {
- $link = @mysqli_connect($CONF['database_host'], $CONF['database_user'], $CONF['database_password'], $CONF['database_name'], $CONF['database_port'], $CONF['database_socket']) or $error_text .= ("
DEBUG INFORMATION:
MySQL 4.1 functions not available! (php5-mysqli installed?)
database_type = 'mysqli' in config.inc.php, are you using a different database? $DEBUG_TEXT";
- }
- }
- if ($is_connected && $link instanceof mysqli) {
- @mysqli_query($link, "SET CHARACTER SET utf8");
- @mysqli_query($link, "SET COLLATION_CONNECTION='utf8_general_ci'");
- }
- } elseif (db_sqlite()) {
- if (class_exists("SQLite3")) {
- if ($CONF['database_name'] == '' || !is_dir(dirname($CONF['database_name'])) || !is_writable(dirname($CONF['database_name']))) {
- $error_text .= ("
DEBUG INFORMATION
Connect: given database path does not exist, is not writable, or \$CONF['database_name'] is empty.");
- } else {
- $link = new SQLite3($CONF['database_name']) or $error_text .= ("
DEBUG INFORMATION:
SQLite functions not available! (php5-sqlite installed?)
database_type = 'sqlite' in config.inc.php, are you using a different database? $DEBUG_TEXT";
+ $options = [
+ PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
+ ];
+ $username_password = true;
+
+ if (db_mysql()) {
+ $dsn = "mysql:host={$CONF['database_host']};dbname={$CONF['database_name']};charset=UTF8";
+ if (Config::bool('database_use_ssl')) {
+ $options[PDO::MYSQL_ATTR_SSL_CA] = Config::read_string('database_ssl_ca');
+ $options[PDO::MYSQL_ATTR_SSL_CAPATH] = Config::read_string('database_ssl_ca_path');
+ $options[PDO::MYSQL_ATTR_SSL_CERT] = Config::read_string('database_ssl_cert');
+ $options[PDO::MYSQL_ATTR_SSL_CIPHER] = Config::read_string('database_ssl_cipher');
}
+ $queries[] = 'SET CHARACTER SET utf8';
+ $queries[] = "SET COLLATION_CONNECTION='utf8_general_ci'";
+ }
+ elseif (db_sqlite()) {
+ $dsn = "sqlite:{$CONF['database_name']}";
+ $username_password = false;
} elseif (db_pgsql()) {
- if (function_exists("pg_pconnect")) {
- if (!isset($CONF['database_port'])) {
- $CONF['database_port'] = '5432';
- }
- $connect_string = "host=" . $CONF['database_host'] . " port=" . $CONF['database_port'] . " dbname=" . $CONF['database_name'] . " user=" . $CONF['database_user'] . " password=" . $CONF['database_password'];
- $link = @pg_pconnect($connect_string) or $error_text .= ("
DEBUG INFORMATION:
Connect: failed to connect to database. $DEBUG_TEXT");
- if ($link) {
- pg_set_client_encoding($link, 'UNICODE');
- }
- } else {
- $error_text .= "
DEBUG INFORMATION:
PostgreSQL functions not available! (php5-pgsql installed?)
database_type = 'pgsql' in config.inc.php, are you using a different database? $DEBUG_TEXT";
+ if (!isset($CONF['database_port'])) {
+ $CONF['database_port'] = '5432';
}
+ $dsn = "pgsql:host={$CONF['database_host']};port={$CONF['database_port']};dbname={$CONF['database_name']};charset=UTF8";
} else {
$error_text = "
DEBUG INFORMATION:
Invalid \$CONF['database_type']! Please fix your config.inc.php! $DEBUG_TEXT";
}
+ if($username_password) {
+ $link = new PDO($dsn, Config::read_string('database_user'), Config::read_string('database_pass'), $options);
+ }
+ else {
+ $link = new PDO($dsn, null, null, $options);
+ }
+
+
return array($link, $error_text);
}
@@ -1649,148 +1630,98 @@ function db_sqlite() {
}
}
+/**
+ * @param string $sql
+ * @param array $values
+ * @return array
+ */
+function db_prepared_fetch_all($sql, array $values = array()) {
+ $r = db_prepared_query($sql, $values);
+ return $r['result']->fetchAll(PDO::FETCH_ASSOC);
+}
+
+/**
+ * @param string $sql
+ * @param array $values
+ * @return array
+ */
+function db_prepared_fetch_one($sql, array $values = array()) {
+ $r = db_prepared_query($sql, $values);
+ return $r['result']->fetch(PDO::FETCH_ASSOC);
+}
+
+
+function db_prepared_insert($sql, array $values = array()) {
+ $link = db_connect();
+ $error_text = '';
+
+ try {
+ $stmt = $link->prepare($sql);
+ $stmt->execute($values);
+ }
+ catch(PDOException $e) {
+ $error_text = "Invalid query: " . $e->getMessage() . " caused by " . $sql ;
+ error_log($error_text);
+ }
+ return $stmt->rowCount();
+}
+
+/**
+ * @param string $sql
+ * @param array $values
+ * @param bool $ignore_errors - set to true to ignore errors.
+ * @return array e.g. ['result' => PDOStatement, 'error' => string ]
+ */
+function db_prepared_query($sql, array $values = array(), $ignore_errors = false) {
+
+ $link = db_connect();
+ $error_text = '';
+
+ try {
+ $stmt = $link->prepare($sql);
+ $stmt->execute($values);
+ }
+ catch(PDOException $e) {
+ $error_text = "Invalid query: " . $e->getMessage() . " caused by " . $sql ;
+ error_log($error_text);
+ if(!$ignore_errors) {
+ die("DEBUG INFORMATION: " . $e->getMessage() . "
Check your error_log for the failed query");
+ }
+ }
+
+
+ return array(
+ "result" => $stmt,
+ "error" => $error_text,
+ );
+}
+
/**
* @param string $query SQL to execute
* @param int $ignore_errors (default 0 aka do not ignore errors)
* @return array ['result' => resource, 'rows' => int ,'error' => string]
*/
-function db_query($query, $ignore_errors = 0) {
- global $CONF;
- global $DEBUG_TEXT;
- $result = "";
- $number_rows = "";
- $link = db_connect();
- $error_text = "";
- if ($ignore_errors) {
- $DEBUG_TEXT = "";
- }
-
- if ($CONF['database_type'] == "mysql" && is_resource($link)) {
- $result = @mysql_query($query, $link) or $error_text = "Invalid query: " . mysql_error($link);
- }
- if ($CONF['database_type'] == "mysqli" && $link instanceof mysqli) {
- $result = @mysqli_query($link, $query) or $error_text = "Invalid query: " . mysqli_error($link);
- }
- if (db_sqlite() && $link instanceof SQLite3) {
- $result = @$link->query($query) or $error_text = "Invalid query: " . $link->lastErrorMsg();
- }
- if (db_pgsql() && is_resource($link)) {
- /* @var resource $link */
- $result = @pg_query($link, $query) or $error_text = "Invalid query: " . pg_last_error();
- }
- if ($error_text != "" && $ignore_errors == 0) {
- error_log($error_text);
- error_log("caused by query: $query");
- die("
DEBUG INFORMATION:
$error_text
Check your error_log for the failed query. $DEBUG_TEXT"); - } - - if ($error_text == "") { - if (db_sqlite() && $result instanceof SQLite3Result && $link instanceof SQLite3) { - /* @var SQLite3Result $result */ - /* @var SQLite3 $link */ - if ($result->numColumns()) { - // Query returned something - $num_rows = 0; - while (@$result->fetchArray(SQLITE3_ASSOC)) { - $num_rows++; - } - $result->reset(); - $number_rows = $num_rows; - } else { - // Query was UPDATE, DELETE or INSERT - $number_rows = $link->changes(); - } - } elseif (preg_match("/^SELECT/i", trim($query))) { - /* @var resource $result */ - // if $query was a SELECT statement check the number of rows with [database_type]_num_rows (). - if ($CONF['database_type'] == "mysql" && is_resource($result)) { - $number_rows = mysql_num_rows($result); - } - if ($CONF['database_type'] == "mysqli" && $result instanceof mysqli_result) { - $number_rows = mysqli_num_rows($result); - } - if (db_pgsql() && is_resource($result)) { - $number_rows = pg_num_rows($result); - } - } else { - /* @var resource $result */ - // if $query was something else, UPDATE, DELETE or INSERT check the number of rows with - // [database_type]_affected_rows (). - if ($CONF['database_type'] == "mysql" && is_resource($link)) { - $number_rows = mysql_affected_rows($link); - } - if ($CONF['database_type'] == "mysqli" && $link instanceof mysqli) { - $number_rows = mysqli_affected_rows($link); - } - if (db_pgsql() && is_resource($result)) { - $number_rows = pg_affected_rows($result); - } - } - } - - $return = array( - "result" => $result, - "rows" => $number_rows, - "error" => $error_text - ); - return $return; +function db_query($query, $ignore_errors = 0) +{ + return db_prepared_query($query, array(), $ignore_errors == 0); } - - // db_row // Action: Returns a row from a table // Call: db_row (int result) -/** - * Returns numerically indexed array. - * - * @param resource|mysqli_result|SQLite3Result $result - * @return array - */ -function db_row($result) { - global $CONF; - $row = ""; - if ($CONF['database_type'] == "mysql" && is_resource($result)) { - $row = mysql_fetch_row($result); - } - if ($CONF['database_type'] == "mysqli" && $result instanceof mysqli_result) { - $row = mysqli_fetch_row($result); - } - if (db_sqlite() && $result instanceof SQLite3Result) { - $row = $result->fetchArray(SQLITE3_NUM); - } - if (db_pgsql() && is_resource($result)) { - $row = pg_fetch_row($result); - } - if (!is_array($row)) { - return array(); - } - return $row; -} /** * Get an associative array from a DB query resource. * - * @param mixed $result - either resource or SQLite3Result depending on DB type chosen. + * @param PDOStatement $result * @return array */ -function db_assoc($result) { - global $CONF; - $row = []; - if ($CONF['database_type'] == "mysql" && is_resource($result)) { - $row = mysql_fetch_assoc($result); - } - if ($CONF['database_type'] == "mysqli" && $result instanceof mysqli_result) { - $row = mysqli_fetch_assoc($result); - } - if (db_sqlite() && $result instanceof SQLite3Result) { - $row = $result->fetchArray(SQLITE3_ASSOC); - } - if (db_pgsql() && is_resource($result)) { - $row = pg_fetch_assoc($result); - } +function db_assoc(PDOStatement $result) { + + $row = $result->fetch(PDO::FETCH_ASSOC); + if (!is_array($row)) { $row = []; } @@ -1812,17 +1743,14 @@ function db_assoc($result) { function db_delete($table, $where, $delete, $additionalwhere='') { $table = table_by_key($table); - $query = "DELETE FROM $table WHERE $where ='" . escape_string($delete) . "' " . $additionalwhere; - $result = db_query($query); + $query = "DELETE FROM $table WHERE $where = ? $additionalwhere"; + + return db_prepared_insert($query, [$delete]); - if ($result['rows'] >= 1) { - return $result['rows']; - } else { - return 0; - } } + /** * db_insert * Action: Inserts a row from a specified table @@ -1836,10 +1764,6 @@ function db_delete($table, $where, $delete, $additionalwhere='') { function db_insert($table, array $values, $timestamp = array('created', 'modified')) { $table = table_by_key($table); - foreach (array_keys($values) as $key) { - $values[$key] = "'" . escape_string($values[$key]) . "'"; - } - foreach ($timestamp as $key) { if (db_sqlite()) { $values[$key] = "datetime('now')"; @@ -1866,9 +1790,27 @@ function db_insert($table, array $values, $timestamp = array('created', 'modifie } } - $sql_values = "(" . implode(",", array_keys($values)) .") VALUES (". implode(",", $values).")"; - $result = db_query("INSERT INTO $table $sql_values"); - return $result['rows']; + + $value_string = ''; + $comma = ''; + $prepared_statment_values = $values; + + foreach($values as $field => $value) { + if(in_array($field, $timestamp)) { + $value_string .= $comma . $value; // see above. + unset($prepared_statment_values[$field]); + } + else { + $value_string .= $comma . ":{$field}"; + } + $comma = ','; + } + + + return db_prepared_insert( + "INSERT INTO $table (" . implode(",", array_keys($values)) .") VALUES ($value_string)", + $prepared_statment_values); + } @@ -1884,57 +1826,48 @@ function db_insert($table, array $values, $timestamp = array('created', 'modifie * @return int - number of updated rows */ function db_update($table, $where_col, $where_value, $values, $timestamp = array('modified')) { - $where = $where_col . " = '" . escape_string($where_value) . "'"; - return db_update_q($table, $where, $values, $timestamp); -} - -/** - * db_update_q - * Action: Updates a specified table - * Call: db_update_q (string table, string where, array values [, array timestamp]) - * @param string $table - table name - * @param string $where - WHERE condition (as SQL) - * @param array $values - key/value map of data to insert into the table. - * @param array $timestamp (optional) - array of fields to set to now() - default: array('modified') - * @return int - number of updated rows - */ -function db_update_q($table, $where, $values, $timestamp = array('modified')) { - global $CONF; $table_key = table_by_key($table); $sql_values = array(); - foreach ($values as $key => $value) { - $sql_values[$key] = $key . "='" . escape_string($value) . "'"; - } + $sql = "UPDATE $table_key SET "; - foreach ($timestamp as $key) { - if (db_sqlite()) { - $sql_values[$key] = escape_string($key) . "=datetime('now')"; - } else { - $sql_values[$key] = escape_string($key) . "=now()"; + $set = array(); + foreach ($values as $key => $value) { + if(in_array($key, $timestamp)) { + if(db_sqlite()) { + $set[] = " $key = datetime('now') "; + } + else { + $set[] = " $key = now() "; + } } - } + else { + $set[] = " $key = :$key "; + $pvalues[$key] = $value; + } + + } /* @todo this needs refactoring/moving out from here */ if (Config::bool('password_expiration')) { - if ($table == 'mailbox' && preg_match('/@/', $where)) { - $where_type = explode('=', $where); - $email = ($where_type[1]); + if ($table == 'mailbox' && preg_match('/@/', $where_value)) { + $email = $where_value; $domain_dirty = explode('@',$email)[1]; $domain = substr($domain_dirty, 0, -1); $password_expiration_value = get_password_expiration_value($domain); $key = 'password_expiry'; - $sql_values[$key] = $key . " = now() + interval " . $password_expiration_value . " day"; + $set[] = " $key = now() + interval {$password_expiration_value} day"; } } - $sql="UPDATE $table_key SET " . implode(",", $sql_values) . " WHERE $where"; - $result = db_query($sql); - if (array_key_exists('rows', $result)) { - return $result['rows']; - } - return 0; + $pvalues['where'] = $where_value; + + + $sql="UPDATE $table_key SET " . implode(",", $set) . " WHERE $where_col = :where"; + + return db_prepared_insert($sql, $pvalues); + } @@ -2105,16 +2038,12 @@ function check_db_version($error_out = true) { $table = table_by_key('config'); $sql = "SELECT value FROM $table WHERE name = 'version'"; - $r = db_query($sql); + $row = db_prepared_fetch_one($sql); - $dbversion = 0; - - if ($r['rows'] == 1) { - $row = db_assoc($r['result']); - if (isset($row['value'])) { - $dbversion = (int) $row['value']; - } - } else { + if (isset($row['value'])) { + $dbversion = (int) $row['value']; + } + else { db_query("INSERT INTO $table (name, value) VALUES ('version', '0')", 0); } @@ -2141,13 +2070,11 @@ function gen_show_status($show_alias) { $table_alias = table_by_key('alias'); $stat_string = ""; - $show_alias = escape_string($show_alias); - $stat_goto = ""; - $stat_result = db_query("SELECT goto FROM $table_alias WHERE address='$show_alias'"); - if ($stat_result['rows'] > 0) { - $row = db_row($stat_result['result']); - $stat_goto = $row[0]; + $stat_result = db_prepared_fetch_all("SELECT goto FROM $table_alias WHERE address=?", [$show_alias]); + + if (sizeof($stat_result) > 0) { + $stat_goto = $stat_result[0]['goto']; } $delimiter_regex = null; @@ -2175,11 +2102,21 @@ function gen_show_status($show_alias) { list($local_part, $stat_domain) = explode('@', $g); + $v = array(); + $stat_delimiter = ""; + + $sql = "SELECT address FROM $table_alias WHERE address = ? OR address = ?"; + $v[] = $g; + $v[] = '@' . $stat_domain; + if (!empty($CONF['recipient_delimiter']) && isset($delimiter_regex)) { - $stat_delimiter = "OR address = '" . escape_string(preg_replace($delimiter_regex, "@", $g)) . "'"; + $v[] = preg_replace($delimiter_regex, "@", $g); + $sql .= " OR address = ? "; } - $stat_result = db_query("SELECT address FROM $table_alias WHERE address = '" . escape_string($g) . "' OR address = '@" . escape_string($stat_domain) . "' $stat_delimiter"); + + $stat_result = db_prepared_query($sql, $v); + if (array_key_exists('rows', $stat_result) && $stat_result['rows'] == 0) { $stat_ok = 0; } @@ -2198,7 +2135,7 @@ function gen_show_status($show_alias) { // Vacation CHECK if ( $CONF['show_vacation'] == 'YES' ) { - $stat_result = db_query("SELECT * FROM ". $CONF['database_tables']['vacation'] ." WHERE email = '" . $show_alias . "' AND active = '" . db_get_boolean(true) . "'") ; + $stat_result = db_prepared_query("SELECT * FROM ". $CONF['database_tables']['vacation'] ." WHERE email = ? AND active = ? ", array($show_alias, db_get_boolean(true) )) ; if ($stat_result['rows'] == 1) { $stat_string .= "" . $CONF['show_status_text'] . " "; } else { @@ -2208,7 +2145,10 @@ function gen_show_status($show_alias) { // Disabled CHECK if ( $CONF['show_disabled'] == 'YES' ) { - $stat_result = db_query("SELECT * FROM ". $CONF['database_tables']['mailbox'] ." WHERE username = '" . $show_alias . "' AND active = '" . db_get_boolean(false) . "'"); + $stat_result = db_prepared_query( + "SELECT * FROM ". $CONF['database_tables']['mailbox'] ." WHERE username = ? AND active = ?", + array($show_alias, db_get_boolean(false)) + ); if ($stat_result['rows'] == 1) { $stat_string .= "" . $CONF['show_status_text'] . " "; } else { @@ -2223,7 +2163,7 @@ function gen_show_status($show_alias) { $now = "datetime('now')"; } - $stat_result = db_query("SELECT * FROM ". $CONF['database_tables']['mailbox'] ." WHERE username = '" . $show_alias . "' AND password_expiry <= $now AND active = '" . db_get_boolean(true) . "'"); + $stat_result = db_prepared_query("SELECT * FROM ". $CONF['database_tables']['mailbox'] ." WHERE username = ? AND password_expiry <= ? AND active = ?", array( $show_alias , $now , db_get_boolean(true) )); if ($stat_result['rows'] == 1) { $stat_string .= "" . $CONF['show_status_text'] . " "; diff --git a/model/MailboxHandler.php b/model/MailboxHandler.php index 4ad2fda8..024e9d6e 100644 --- a/model/MailboxHandler.php +++ b/model/MailboxHandler.php @@ -479,11 +479,11 @@ class MailboxHandler extends PFAHandler { return false; } else { $table_mailbox = table_by_key('mailbox'); - $query = "SELECT SUM(quota) FROM $table_mailbox WHERE domain = '" . escape_string($domain) . "'"; - $query .= " AND username != '" . escape_string($this->id) . "'"; - $result = db_query($query); - $row = db_row($result['result']); - $cur_quota_total = divide_quota($row[0]); # convert to MB + $query = "SELECT SUM(quota) as sum FROM $table_mailbox WHERE domain = ? AND username != ?"; + + $rows = db_prepared_fetch_all($query, array($domain, $this->id)); + + $cur_quota_total = divide_quota($rows[0]['sum']); # convert to MB if (($quota + $cur_quota_total) > $limit['quota']) { $rval = false; } else { diff --git a/model/PFAHandler.php b/model/PFAHandler.php index 91103fdb..f50d36c3 100644 --- a/model/PFAHandler.php +++ b/model/PFAHandler.php @@ -725,15 +725,11 @@ abstract class PFAHandler { $query .= " LIMIT $limit OFFSET $offset "; } - $result = db_query($query); - $db_result = array(); - if ($result['rows'] != 0) { - while ($row = db_assoc($result['result'])) { - if (is_array($row)) { - $db_result[$row[$this->id_field]] = $row; - } - } + + $result = db_prepared_fetch_all($query); + foreach($result as $row) { + $db_result[$row[$this->id_field]] = $row; } $db_result = $this->read_from_db_postprocess($db_result); @@ -818,18 +814,17 @@ abstract class PFAHandler { * @return boolean true on successful login (i.e. password matches etc) */ public function login($username, $password) { - $username = escape_string($username); $table = table_by_key($this->db_table); $active = db_get_boolean(true); - $query = "SELECT password FROM $table WHERE " . $this->id_field . "='$username' AND active='$active'"; + $query = "SELECT password FROM $table WHERE {$this->id_field} = :username AND active = :active"; + + $values = array('username' => $username, 'active' => $active); + + $result = db_prepared_fetch_all($query,$values); + if (sizeof($result) == 1) { + $row = $result[0]; - $result = db_query($query); - if ($result['rows'] == 1) { - $row = db_assoc($result['result']); - if (!is_array($row)) { - return false; - } $crypt_password = pacrypt($password, $row['password']); if ($row['password'] == $crypt_password) { @@ -866,19 +861,17 @@ abstract class PFAHandler { * @return boolean true on success (i.e. code matches etc) */ public function checkPasswordRecoveryCode($username, $token) { - $username = escape_string($username); $table = table_by_key($this->db_table); $active = db_get_boolean(true); - $query = "SELECT token FROM $table WHERE " . $this->id_field . "='$username' AND token <> '' AND active='$active' AND NOW() < token_validity"; - $result = db_query($query); - if ($result['rows'] == 1) { - $row = db_assoc($result['result']); + $query = "SELECT token FROM $table WHERE {$this->id_field} = :username AND token <> '' AND active = :active AND NOW() < token_validity"; + $values = array('username' => $username, 'active' => $active); + + $result = db_prepared_fetch_all($query, $values); + if(sizeof($result) == 1) { + $row = $result[0]; - if (!is_array($row)) { - return false; - } $crypt_token = pacrypt($token, $row['token']); if ($row['token'] == $crypt_token) { diff --git a/model/VacationHandler.php b/model/VacationHandler.php index ca3912f5..e00d9e0f 100644 --- a/model/VacationHandler.php +++ b/model/VacationHandler.php @@ -186,16 +186,16 @@ class VacationHandler extends PFAHandler { * will return false if no existing data */ public function get_details() { - $table_vacation = table_by_key('vacation'); - $E_username = escape_string($this->username); - $sql = "SELECT * FROM $table_vacation WHERE email = '$E_username'"; - $result = db_query($sql); - if ($result['rows'] != 1) { + $table_vacation = table_by_key('vacation'); + + $sql = "SELECT * FROM $table_vacation WHERE email = :username"; + $result = db_prepared_fetch_all($sql, array('username' => $this->username)); + if(sizeof($result) != 1) { return false; } - $row = db_assoc($result['result']); + $row = $result[0]; if (!is_array($row)) { return false; diff --git a/public/backup.php b/public/backup.php index 059571de..227134b5 100644 --- a/public/backup.php +++ b/public/backup.php @@ -65,8 +65,11 @@ if ($_SERVER['REQUEST_METHOD'] == "GET") { umask(077); $path = (ini_get('upload_tmp_dir') != '') ? ini_get('upload_tmp_dir') : '/tmp'; date_default_timezone_set(@date_default_timezone_get()); # Suppress date.timezone warnings - $filename = "postfixadmin-" . date("Ymd") . "-" . getmypid() . ".sql"; - $backup = $path . DIRECTORY_SEPARATOR . $filename; + + // Should use mktemp() or similar. + $backup = tempnam($path, 'postfixadmin-' . date('Ymd')); + + $filename = basename($backup) . '.sql'; $header = "#\n# Postfix Admin $version\n# Date: " . date("D M j G:i:s T Y") . "\n#\n"; @@ -94,38 +97,39 @@ if ($_SERVER['REQUEST_METHOD'] == "GET") { ); for ($i = 0 ; $i < sizeof($tables) ; ++$i) { - $result = db_query("SHOW CREATE TABLE " . table_by_key($tables[$i])); - if ($result['rows'] > 0) { - while ($row = db_row($result['result'])) { - fwrite($fh, "{$row[1]};\n\n"); - } + $result = db_prepared_fetch_all("SHOW CREATE TABLE " . table_by_key($tables[$i])); + foreach($result as $row) { + fwrite($fh, array_pop($row)); } + } for ($i = 0 ; $i < sizeof($tables) ; ++$i) { - $result = db_query("SELECT * FROM " . table_by_key($tables[$i])); - if ($result['rows'] > 0) { - while ($row = db_assoc($result['result'])) { - $fields = array_keys($row); - $values = array_values($row); - $values = array_map(function ($str) { - return escape_string($str); - }, $values); + // may be a large resultset? + $pdo = db_connect(); + $stmt = $pdo->prepare('SELECT * FROM ' . table_by_key($tables[$i])); + $stmt->execute(); + while($row = $stmt->fetch(PDO::FETCH_ASSOC)) { + $fields = array_keys($row); + $values = array_values($row); + $values = array_map(function ($str) { + return escape_string($str); + }, $values); - fwrite($fh, "INSERT INTO ". $tables[$i] . " (". implode(',', $fields) . ") VALUES ('" . implode('\',\'', $values) . "');\n"); - $fields = ""; - $values = ""; - } + fwrite($fh, "INSERT INTO ". $tables[$i] . " (". implode(',', $fields) . ") VALUES ('" . implode('\',\'', $values) . "');\n"); + $fields = ""; + $values = ""; } + } } header("Content-Type: text/plain"); header("Content-Disposition: attachment; filename=\"$filename\""); header("Content-Transfer-Encoding: binary"); - header("Content-Length: " . filesize("$backup")); + header("Content-Length: " . filesize($backup)); header("Content-Description: Postfix Admin"); - $download_backup = fopen("$backup", "r"); - unlink("$backup"); + $download_backup = fopen($backup, "r"); + unlink($backup); fpassthru($download_backup); } /* vim: set expandtab softtabstop=3 tabstop=3 shiftwidth=3: */ diff --git a/public/broadcast-message.php b/public/broadcast-message.php index deef5fb4..66aed0be 100644 --- a/public/broadcast-message.php +++ b/public/broadcast-message.php @@ -63,14 +63,8 @@ if ($_SERVER['REQUEST_METHOD'] == "POST") { if (intval(safepost('mailboxes_only')) == 0) { $q .= " UNION SELECT goto FROM $table_alias WHERE active='" . db_get_boolean(true) . "' AND ".db_in_clause("domain", $wanted_domains)."AND goto NOT IN ($q)"; } - $result = db_query($q); - if ($result['rows'] > 0) { - while ($row = db_assoc($result['result'])) { - if (is_array($row)) { - $recipients[] = $row['username']; - } - } - } + $result = db_prepared_fetch_all($q); + $recipients = array_column($result, 'username'); $recipients = array_unique($recipients); diff --git a/public/list-virtual.php b/public/list-virtual.php index 1c3a16cc..9696d15b 100644 --- a/public/list-virtual.php +++ b/public/list-virtual.php @@ -220,54 +220,52 @@ if (Config::bool('used_quotas') && (! Config::bool('new_quota_table'))) { $mailbox_pagebrowser_query = "$sql_from\n$sql_join\n$sql_where\n$sql_order" ; $query = "$sql_select\n$mailbox_pagebrowser_query\n$sql_limit"; -$result = db_query($query); +$result = db_prepared_fetch_all($query); $tMailbox = array(); -if ($result['rows'] > 0) { - $delimiter = preg_quote($CONF['recipient_delimiter'], "/"); - $goto_single_rec_del = ""; - while ($row = db_assoc($result['result'])) { - if (!is_array($row)) { - continue; - } - if ($display_mailbox_aliases) { - $goto_split = explode(",", $row['goto']); - $row['goto_mailbox'] = 0; - $row['goto_other'] = array(); +$delimiter = preg_quote($CONF['recipient_delimiter'], "/"); +$goto_single_rec_del = ""; - foreach ($goto_split as $goto_single) { - if (!empty($CONF['recipient_delimiter'])) { - $goto_single_rec_del = preg_replace('/' .$delimiter. '[^' .$delimiter. '@]*@/', "@", $goto_single); - } +foreach($result as $row) { - if ($goto_single == $row['username'] || $goto_single_rec_del == $row['username']) { # delivers to mailbox - $row['goto_mailbox'] = 1; - } elseif (Config::bool('vacation') && strstr($goto_single, '@' . $CONF['vacation_domain'])) { # vacation alias - TODO: check for full vacation alias - # skip the vacation alias, vacation status is detected otherwise - } else { # forwarding to other alias - $row['goto_other'][] = $goto_single; - } + if ($display_mailbox_aliases) { + $goto_split = explode(",", $row['goto']); + $row['goto_mailbox'] = 0; + $row['goto_other'] = array(); + + foreach ($goto_split as $goto_single) { + if (!empty($CONF['recipient_delimiter'])) { + $goto_single_rec_del = preg_replace('/' .$delimiter. '[^' .$delimiter. '@]*@/', "@", $goto_single); + } + + if ($goto_single == $row['username'] || $goto_single_rec_del == $row['username']) { # delivers to mailbox + $row['goto_mailbox'] = 1; + } elseif (Config::bool('vacation') && strstr($goto_single, '@' . $CONF['vacation_domain'])) { # vacation alias - TODO: check for full vacation alias + # skip the vacation alias, vacation status is detected otherwise + } else { # forwarding to other alias + $row['goto_other'][] = $goto_single; } } - if (db_pgsql()) { - // XXX - $row['modified'] = date('Y-m-d H:i', strtotime($row['modified'])); - $row['created'] = date('Y-m-d H:i', strtotime($row['created'])); - $row['active']=('t'==$row['active']) ? 1 : 0; - - if (Config::bool('vacation_control_admin')) { - if ($row['v_active'] == null) { - $row['v_active'] = 'f'; - } - $row['v_active']=('t'==$row['v_active']) ? 1 : 0; - } - } - $tMailbox[] = $row; } + if (db_pgsql()) { + // XXX + $row['modified'] = date('Y-m-d H:i', strtotime($row['modified'])); + $row['created'] = date('Y-m-d H:i', strtotime($row['created'])); + $row['active']=('t'==$row['active']) ? 1 : 0; + + if (Config::bool('vacation_control_admin')) { + if ($row['v_active'] == null) { + $row['v_active'] = 'f'; + } + $row['v_active']=('t'==$row['v_active']) ? 1 : 0; + } + } + $tMailbox[] = $row; } + $alias_data['msg']['can_create'] = false; $tCanAddMailbox = false; diff --git a/public/setup.php b/public/setup.php index 73df46f7..f4c18680 100644 --- a/public/setup.php +++ b/public/setup.php @@ -41,6 +41,7 @@ $f_mysql_connect = function_exists("mysql_connect"); $f_mysqli_connect = function_exists("mysqli_connect"); $f_pg_connect = function_exists("pg_connect"); $f_sqlite_open = class_exists("SQLite3"); +$f_pdo = class_exists('PDO'); $f_session_start = function_exists("session_start"); $f_preg_match = function_exists("preg_match"); $f_mb_encode_mimeheader = function_exists("mb_encode_mimeheader"); @@ -302,8 +303,8 @@ if ($error != 0) { if ($error == 0 && $pw_check_result == 'pass_OK') { // XXX need to ensure domains table includes an 'ALL' entry. $table_domain = table_by_key('domain'); - $r = db_query("SELECT * FROM $table_domain WHERE domain = 'ALL'"); - if ($r['rows'] == 0) { + $rows = db_prepared_fetch_all("SELECT * FROM $table_domain WHERE domain = 'ALL'"); + if(empty($rows)) { db_insert('domain', array('domain' => 'ALL', 'description' => '', 'transport' => '')); // all other fields should default through the schema. } diff --git a/public/upgrade.php b/public/upgrade.php index 263dfeb1..a8c6e31d 100644 --- a/public/upgrade.php +++ b/public/upgrade.php @@ -13,18 +13,15 @@ if (!isset($CONF) || !is_array($CONF)) { /** - * Use this to check whether an object (Table, index etc) exists within a + * Use this to check whether an object (table, index etc) exists within a * PostgreSQL database. * @param string the object name * @return boolean true if it exists */ function _pgsql_object_exists($name) { $sql = "select relname from pg_class where relname = '$name'"; - $r = db_query($sql); - if ($r['rows'] == 1) { - return true; - } - return false; + $r = db_prepared_fetch_one($sql); + return !empty($r); } /** @@ -51,30 +48,24 @@ function _pgsql_field_exists($table, $field) { AND pg_catalog.pg_table_is_visible(c.oid) ) AND a.attname = '$field' "; - $r = db_query($sql); - $row = db_row($r['result']); - if ($row) { - return true; - } - return false; + $r = db_prepared_fetch_all($sql); + + return !empty($r); } function _mysql_field_exists($table, $field) { # $table = table_by_key($table); # _mysql_field_exists is always called with the expanded table name - don't expand it twice - $sql = "SHOW COLUMNS FROM $table LIKE '$field'"; - $r = db_query($sql); - $row = db_row($r['result']); + $sql = "SHOW COLUMNS FROM $table LIKE ?"; + $r = db_prepared_fetch_all($sql, array( $field)); - if ($row) { - return true; - } - return false; + return !empty($r); } function _sqlite_field_exists($table, $field) { $sql = "PRAGMA table_info($table)"; - $r = db_query($sql); - while ($row = db_row($r['result'])) { + $r = db_prepared_fetch_all($sql); + + foreach($r as $row) { if ($row[1] == $field) { return true; } @@ -128,8 +119,7 @@ function printdebug($text) { $table = table_by_key('config'); if ($CONF['database_type'] == 'pgsql') { // check if table already exists, if so, don't recreate it - $r = db_query("SELECT relname FROM pg_class WHERE relname = '$table'"); - if ($r['rows'] == 0) { + if(!_pgsql_object_exists($table)) { $pgsql = " CREATE TABLE $table ( id SERIAL, @@ -1420,18 +1410,13 @@ function upgrade_1284_mysql_pgsql() { # migrate the ALL domain to the superadmin column # Note: The ALL domain is not (yet) deleted to stay backwards-compatible for now (will be done in a later upgrade function) - $result = db_query("SELECT username FROM " . table_by_key('domain_admins') . " where domain='ALL'"); + $result = db_prepared_fetch_all("SELECT username FROM " . table_by_key('domain_admins') . " where domain='ALL'"); - if ($result['rows'] > 0) { - while ($row = db_assoc($result['result'])) { - if (!is_array($row)) { - break; - } - - printdebug("Setting superadmin flag for " . $row['username']); - db_update('admin', 'username', $row['username'], array('superadmin' => db_get_boolean(true))); - } + foreach($result as $row) { + printdebug("Setting superadmin flag for " . $row['username']); + db_update('admin', 'username', $row['username'], array('superadmin' => db_get_boolean(true))); } + } function upgrade_1345_mysql() { diff --git a/public/users/password-recover.php b/public/users/password-recover.php index e182e944..9013a5ca 100644 --- a/public/users/password-recover.php +++ b/public/users/password-recover.php @@ -57,18 +57,22 @@ function sendCodebySMS($to, $username, $code) { if ($_SERVER['REQUEST_METHOD'] === "POST") { $start_time = microtime(true); - $tUsername = escape_string(safepost('fUsername')); - if (empty($tUsername) || !is_string($tUsername)) { + $username = safepost('fUsername', null); + if (empty($sername) || !is_string($username)) { die("fUsername field required"); } + $tUsername = escape_string($username); + + $handler = $context === 'admin' ? new AdminHandler : new MailboxHandler; $token = $handler->getPasswordRecoveryCode($tUsername); if ($token !== false) { $table = table_by_key($context === 'users' ? 'mailbox' : 'admin'); - $result = db_query("SELECT * FROM $table WHERE username='$tUsername'"); - $row = db_assoc($result['result']); + $row = db_prepared_fetch_one("SELECT * FROM $table WHERE username= :username", array('username' => $username)); + + // $row must exist unless there's a race condition? $email_other = isset($row['email_other']) ? trim($row['email_other']) : null; $phone = isset($row['phone']) ? trim($row['phone']) : null; diff --git a/public/viewlog.php b/public/viewlog.php index f8132d8e..289d5f47 100644 --- a/public/viewlog.php +++ b/public/viewlog.php @@ -61,18 +61,17 @@ if ($error != 1) { $table_log = table_by_key('log'); $page_size = isset($CONF['page_size']) ? intval($CONF['page_size']) : 35; - $query = "SELECT timestamp,username,domain,action,data FROM $table_log WHERE domain='$fDomain' ORDER BY timestamp DESC LIMIT $page_size"; + $query = "SELECT timestamp,username,domain,action,data FROM $table_log WHERE domain= :domain ORDER BY timestamp DESC LIMIT $page_size"; + if (db_pgsql()) { - $query = "SELECT extract(epoch from timestamp) as timestamp,username,domain,action,data FROM $table_log WHERE domain='$fDomain' ORDER BY timestamp DESC LIMIT $page_size"; + $query = "SELECT extract(epoch from timestamp) as timestamp,username,domain,action,data FROM $table_log WHERE domain= :domain ORDER BY timestamp DESC LIMIT $page_size"; } - $result = db_query($query); - if ($result['rows'] > 0) { - while ($row = db_assoc($result['result'])) { - if (is_array($row) && db_pgsql()) { - $row['timestamp'] = gmstrftime('%c %Z', $row['timestamp']); - } - $tLog[] = $row; + $result = db_prepared_fetch_all($query, array('domain' => $fDomain)); + foreach($result as $row) { + if (is_array($row) && db_pgsql()) { + $row['timestamp'] = gmstrftime('%c %Z', $row['timestamp']); } + $tLog[] = $row; } } diff --git a/tests/CheckOwnerTest.php b/tests/CheckOwnerTest.php index bb4108ec..3501014d 100644 --- a/tests/CheckOwnerTest.php +++ b/tests/CheckOwnerTest.php @@ -5,8 +5,7 @@ require_once('common.php'); class CheckOwnerTest extends \PHPUnit\Framework\TestCase { public function testBasic() { $check = check_owner('random@example.com', 'test.com'); - - $this->assertFalse($check); + $this->assertFalse($check, "there should be no entries in test.com as it's an invalid/non-existant domain"); } } diff --git a/tests/DbBasicTest.php b/tests/DbBasicTest.php index 96c8cfa2..82b8f492 100644 --- a/tests/DbBasicTest.php +++ b/tests/DbBasicTest.php @@ -3,8 +3,20 @@ require_once('common.php'); class DbBasicTest extends \PHPUnit\Framework\TestCase { + + private $test_domain; + + public function setUp() { + $db = db_connect(); + $test_domain = 'test' . uniqid() . '.com'; + $this->test_domain = $test_domain; + + $db->exec("DELETE FROM domain WHERE domain = '$test_domain'"); + + } public function testInsertDeleteDomain() { - $domain = "test". uniqid() . '.com'; + +$domain = $this->test_domain; $username = 'testusername' . uniqid(); @@ -12,7 +24,7 @@ class DbBasicTest extends \PHPUnit\Framework\TestCase { 1, db_insert( 'domain', - array('domain' => $domain, 'description' => '', 'transport' => '', 'password_expiry' => 99) + array('domain' => $domain, 'description' => 'test', 'transport' => '', 'password_expiry' => 99) ) ); @@ -33,12 +45,16 @@ class DbBasicTest extends \PHPUnit\Framework\TestCase { ) ); - $ret = db_query("SELECT * FROM mailbox WHERE username = '$username'"); + $ret = db_prepared_fetch_one("SELECT * FROM mailbox WHERE username = :username", array('username' => $username)); - $this->assertEquals(1, $ret['rows']); - $data = db_assoc($ret['result']); - $this->assertEquals($data['name'], 'blah updated'); + $this->assertTrue(!empty($ret)); + $this->assertTrue(is_array($ret)); + + + $this->assertEquals($ret['name'], 'blah updated'); + + $this->assertEquals(0, db_delete('mailbox', 'username', 'blahblahinvalid')); $this->assertEquals(1, db_delete('mailbox', 'username', $username)); $this->assertEquals(1, db_delete('domain', 'domain', $domain)); diff --git a/tests/bootstrap.php b/tests/bootstrap.php index 093f6a7e..eeccb6b3 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -10,7 +10,7 @@ require_once(dirname(__FILE__) . '/../common.php'); $CONF['default_language'] = 'en'; $CONF['language_hook'] = ''; -$db_file = '/tmp/postfixadmin.sqlite.test'; +$db_file = dirname(__FILE__) . '/postfixadmin.sqlite.test'; $CONF['database_type'] = 'sqlite'; $CONF['database_name'] = $db_file; @@ -18,9 +18,9 @@ Config::write('database_type', 'sqlite'); Config::write('database_name', $db_file); clearstatcache(); -if (file_exists($db_file)) { - unlink($db_file); -} +//if (file_exists($db_file)) { +// unlink($db_file); +//} require_once(dirname(__FILE__) . '/../public/upgrade.php');