2007-03-24 08:27:00 +01:00
< ? php
2007-09-30 17:53:54 +02:00
/**
* Postfix Admin
*
* LICENSE
* This source file is subject to the GPL license that is bundled with
* this package in the file LICENSE . TXT .
*
2013-11-10 16:57:32 +01:00
* Further details on the project are available at http :// postfixadmin . sf . net
2007-09-30 17:53:54 +02:00
*
* @ version $Id $
* @ license GNU GPL v2 or later .
*
* File : functions . inc . php
* Contains re - usable code .
*/
2007-03-24 08:27:00 +01:00
2014-05-06 21:46:27 +02:00
$version = '2.91' ;
2007-09-22 12:59:24 +02:00
/**
* check_session
* Action : Check if a session already exists , if not redirect to login . php
* Call : check_session ()
* @ return String username ( e . g . foo @ example . com )
*/
2011-06-02 22:51:12 +02:00
function authentication_get_username () {
2011-02-15 22:59:03 +01:00
if ( defined ( 'POSTFIXADMIN_CLI' )) {
return 'CLI' ;
}
2011-12-20 02:06:49 +01:00
if ( defined ( 'POSTFIXADMIN_SETUP' )) {
return 'SETUP.PHP' ;
}
2009-01-15 13:24:36 +01:00
if ( ! isset ( $_SESSION [ 'sessid' ])) {
2011-04-10 00:09:37 +02:00
header ( " Location: login.php " );
2009-01-15 13:24:36 +01:00
exit ( 0 );
}
$SESSID_USERNAME = $_SESSION [ 'sessid' ][ 'username' ];
return $SESSID_USERNAME ;
2007-03-24 08:27:00 +01:00
}
2007-09-22 12:59:24 +02:00
/**
* Returns the type of user - either 'user' or 'admin'
* Returns false if neither ( E . g . if not logged in )
* @ return String admin or user or ( boolean ) false .
*/
function authentication_get_usertype () {
2009-01-15 13:24:36 +01:00
if ( isset ( $_SESSION [ 'sessid' ])) {
if ( isset ( $_SESSION [ 'sessid' ][ 'type' ])) {
return $_SESSION [ 'sessid' ][ 'type' ];
}
}
return false ;
2007-03-24 08:27:00 +01:00
}
2007-09-22 12:59:24 +02:00
/**
*
* Used to determine whether a user has a particular role .
* @ param String role - name . ( E . g . admin , global - admin or user )
* @ return boolean True if they have the requested role in their session .
* Note , user < admin < global - admin
*/
function authentication_has_role ( $role ) {
2009-01-15 13:24:36 +01:00
if ( isset ( $_SESSION [ 'sessid' ])) {
if ( isset ( $_SESSION [ 'sessid' ][ 'roles' ])) {
if ( in_array ( $role , $_SESSION [ 'sessid' ][ 'roles' ])) {
return true ;
}
}
}
return false ;
2007-03-24 08:27:00 +01:00
}
2007-09-22 12:59:24 +02:00
/**
* Used to enforce that $user has a particular role when
* viewing a page .
2012-05-28 20:07:33 +02:00
* If they are lacking a role , redirect them to login . php
2007-09-22 12:59:24 +02:00
*
* Note , user < admin < global - admin
*/
function authentication_require_role ( $role ) {
2009-01-15 13:24:36 +01:00
// redirect to appropriate page?
if ( authentication_has_role ( $role )) {
return True ;
}
2012-05-28 19:43:39 +02:00
2012-05-28 20:07:33 +02:00
header ( " Location: login.php " );
2009-01-15 13:24:36 +01:00
exit ( 0 );
2007-09-22 12:59:24 +02:00
}
2007-03-24 08:27:00 +01:00
2007-09-28 21:27:51 +02:00
/**
* Add an error message for display on the next page that is rendered .
2012-04-29 16:39:41 +02:00
* @ param String / Array message ( s ) to show .
2007-09-28 21:27:51 +02:00
*
* Stores string in session . Flushed through header template .
* @ see _flash_string ()
*/
function flash_error ( $string ) {
2009-01-15 13:24:36 +01:00
_flash_string ( 'error' , $string );
2007-09-28 21:27:51 +02:00
}
/**
* Used to display an info message on successful update .
2012-04-29 16:39:41 +02:00
* @ param String / Array message ( s ) to show .
* Stores data in session .
2007-09-28 21:27:51 +02:00
* @ see _flash_string ()
*/
function flash_info ( $string ) {
2009-01-15 13:24:36 +01:00
_flash_string ( 'info' , $string );
2007-09-28 21:27:51 +02:00
}
/**
* 'Private' method used for flash_info () and flash_error () .
*/
function _flash_string ( $type , $string ) {
2012-04-29 16:39:41 +02:00
if ( is_array ( $string )) {
foreach ( $string as $singlestring ) {
_flash_string ( $type , $singlestring );
}
2013-02-19 23:22:59 +01:00
return ;
2012-04-29 16:39:41 +02:00
}
2009-01-15 13:24:36 +01:00
if ( ! isset ( $_SESSION [ 'flash' ])) {
$_SESSION [ 'flash' ] = array ();
}
if ( ! isset ( $_SESSION [ 'flash' ][ $type ])) {
$_SESSION [ 'flash' ][ $type ] = array ();
}
$_SESSION [ 'flash' ][ $type ][] = $string ;
2007-09-28 21:27:51 +02:00
}
2007-03-24 08:27:00 +01:00
//
// check_language
// Action: checks what language the browser uses
// Call: check_language
2007-12-30 21:16:07 +01:00
// Parameter: $use_post - set to 0 if $_POST should NOT be read
2007-03-24 08:27:00 +01:00
//
2011-06-02 22:51:12 +02:00
function check_language ( $use_post = 1 ) {
2009-01-15 13:24:36 +01:00
global $supported_languages ; # from languages/languages.php
2013-04-01 23:59:56 +02:00
$lang = Config :: read ( 'default_language' );
2009-01-15 13:24:36 +01:00
2011-06-02 22:51:12 +02:00
if ( isset ( $_SERVER [ 'HTTP_ACCEPT_LANGUAGE' ])) {
2009-01-15 13:24:36 +01:00
$lang_array = preg_split ( '/(\s*,\s*)/' , $_SERVER [ 'HTTP_ACCEPT_LANGUAGE' ]);
if ( safecookie ( 'lang' )) {
array_unshift ( $lang_array , safecookie ( 'lang' )); # prefer language from cookie
}
if ( $use_post && safepost ( 'lang' )) {
array_unshift ( $lang_array , safepost ( 'lang' )); # but prefer $_POST['lang'] even more
}
2011-06-02 22:51:12 +02:00
for ( $i = 0 ; $i < count ( $lang_array ); $i ++ ) {
2009-01-15 13:24:36 +01:00
$lang_next = $lang_array [ $i ];
$lang_next = strtolower ( trim ( $lang_next ));
2013-10-31 21:38:14 +01:00
$lang_next = preg_replace ( '/;.*$/' , '' , $lang_next ); # remove things like ";q=0.8"
2011-06-02 22:51:12 +02:00
if ( array_key_exists ( $lang_next , $supported_languages )) {
2009-01-15 13:24:36 +01:00
$lang = $lang_next ;
break ;
}
}
}
return $lang ;
2007-03-24 08:27:00 +01:00
}
2007-12-30 02:32:33 +01:00
//
// language_selector
// Action: returns a language selector dropdown with the browser (or cookie) language preselected
// Call: language_selector()
//
2011-06-02 22:51:12 +02:00
function language_selector () {
2009-01-15 13:24:36 +01:00
global $supported_languages ; # from languages/languages.php
2008-07-29 21:32:32 +02:00
2009-01-15 13:24:36 +01:00
$current_lang = check_language ();
2007-12-30 02:32:33 +01:00
2009-01-15 13:24:36 +01:00
$selector = '<select name="lang" xml:lang="en" dir="ltr">' ;
2007-03-24 08:27:00 +01:00
2009-01-15 13:24:36 +01:00
foreach ( $supported_languages as $lang => $lang_name ) {
if ( $lang == $current_lang ) {
$selected = ' selected="selected"' ;
} else {
$selected = '' ;
}
$selector .= " <option value=' $lang ' $selected > $lang_name </option> " ;
}
$selector .= " </select> " ;
return $selector ;
2007-12-30 02:32:33 +01:00
}
2007-03-24 08:27:00 +01:00
2013-04-01 23:22:30 +02:00
/**
* Checks if a domain is valid
* @ param string $domain
* @ return empty string if the domain is valid , otherwise string with the errormessage
*
* TODO : make check_domain able to handle as example . local domains
* TODO : skip DNS check if the domain exists in PostfixAdmin ?
*/
2011-06-02 22:51:12 +02:00
function check_domain ( $domain ) {
2014-02-13 21:11:05 +01:00
if ( ! preg_match ( '/^([-0-9A-Z]+\.)+' . '([0-9A-Z]){2,13}$/i' , ( $domain ))) {
2013-10-13 20:11:18 +02:00
return sprintf ( Config :: lang ( 'pInvalidDomainRegex' ), htmlentities ( $domain ));
2009-01-15 13:24:36 +01:00
}
2008-07-30 01:18:40 +02:00
2013-06-06 22:53:37 +02:00
if ( Config :: bool ( 'emailcheck_resolve_domain' ) && 'WINDOWS' != ( strtoupper ( substr ( php_uname ( 's' ), 0 , 7 )))) {
2008-07-30 01:18:40 +02:00
2009-01-15 13:24:36 +01:00
// Look for an AAAA, A, or MX record for the domain
2008-07-30 01:18:40 +02:00
2009-01-15 13:24:36 +01:00
if ( function_exists ( 'checkdnsrr' )) {
// AAAA (IPv6) is only available in PHP v. >= 5
2011-06-02 22:51:12 +02:00
if ( version_compare ( phpversion (), " 5.0.0 " , " >= " )) {
2013-04-01 23:22:30 +02:00
if ( checkdnsrr ( $domain , 'AAAA' )) return '' ;
2009-01-15 13:24:36 +01:00
}
2013-04-01 23:22:30 +02:00
if ( checkdnsrr ( $domain , 'A' )) return '' ;
if ( checkdnsrr ( $domain , 'MX' )) return '' ;
2013-10-13 20:11:18 +02:00
return sprintf ( Config :: lang ( 'pInvalidDomainDNS' ), htmlentities ( $domain ));
2011-06-02 22:51:12 +02:00
} else {
2013-04-01 23:22:30 +02:00
return 'emailcheck_resolve_domain is enabled, but function (checkdnsrr) missing!' ;
2009-01-15 13:24:36 +01:00
}
}
2009-11-05 15:55:39 +01:00
2013-04-01 23:22:30 +02:00
return '' ;
2007-03-24 08:27:00 +01:00
}
2007-10-25 14:29:38 +02:00
/**
* check_email
* Checks if an email is valid - if it is , return true , else false .
* @ param String $email - a string that may be an email address .
2013-04-01 23:22:30 +02:00
* @ return empty string if it ' s a valid email address , otherwise string with the errormessage
2007-10-25 14:29:38 +02:00
* TODO : make check_email able to handle already added domains
*/
2011-06-02 22:51:12 +02:00
function check_email ( $email ) {
2009-01-15 13:24:36 +01:00
$ce_email = $email ;
2007-08-17 17:10:59 +02:00
2009-01-15 13:24:36 +01:00
//strip the vacation domain out if we are using it
//and change from blah#foo.com@autoreply.foo.com to blah@foo.com
2013-06-06 22:53:37 +02:00
if ( Config :: bool ( 'vacation' )) {
2013-04-01 23:51:29 +02:00
$vacation_domain = Config :: read ( 'vacation_domain' );
2011-09-24 13:49:14 +02:00
$ce_email = preg_replace ( " /@ $vacation_domain\ $ / " , '' , $ce_email );
2009-01-15 13:24:36 +01:00
$ce_email = preg_replace ( " /#/ " , '@' , $ce_email );
}
2007-06-20 03:48:44 +02:00
2009-01-15 13:24:36 +01:00
// Perform non-domain-part sanity checks
2012-05-27 21:06:37 +02:00
if ( ! preg_match ( '/^[-!#$%&\'*+\\.\/0-9=?A-Z^_{|}~]+' . '@' . '[^@]+$/i' , $ce_email )) {
2013-10-13 20:11:18 +02:00
return Config :: lang_f ( 'pInvalidMailRegex' , $email );
2009-01-15 13:24:36 +01:00
}
2007-03-24 08:27:00 +01:00
2009-01-15 13:24:36 +01:00
// Determine domain name
$matches = array ();
2011-06-02 22:51:12 +02:00
if ( ! preg_match ( '|@(.+)$|' , $ce_email , $matches )) {
2013-10-13 20:11:18 +02:00
return Config :: lang_f ( 'pInvalidMailRegex' , $email );
2009-01-15 13:24:36 +01:00
}
$domain = $matches [ 1 ];
2008-07-30 01:18:40 +02:00
2009-01-15 13:24:36 +01:00
# check domain name
return check_domain ( $domain );
2007-03-24 08:27:00 +01:00
}
2007-09-28 21:27:51 +02:00
/**
* Clean a string , escaping any meta characters that could be
* used to disrupt an SQL string . i . e . " ' " => " \ ' " etc .
*
* @ param String ( or Array )
* @ return String ( or Array ) of cleaned data , suitable for use within an SQL
* statement .
*/
2011-06-02 22:51:12 +02:00
function escape_string ( $string ) {
2009-01-15 13:24:36 +01:00
global $CONF ;
// if the string is actually an array, do a recursive cleaning.
// Note, the array keys are not cleaned.
if ( is_array ( $string )) {
$clean = array ();
foreach ( array_keys ( $string ) as $row ) {
$clean [ $row ] = escape_string ( $string [ $row ]);
}
return $clean ;
}
2011-06-02 22:51:12 +02:00
if ( get_magic_quotes_gpc ()) {
2009-01-15 13:24:36 +01:00
$string = stripslashes ( $string );
}
2011-06-02 22:51:12 +02:00
if ( ! is_numeric ( $string )) {
2009-01-15 13:24:36 +01:00
$link = db_connect ();
2011-06-02 22:51:12 +02:00
if ( $CONF [ 'database_type' ] == " mysql " ) {
2009-01-15 13:24:36 +01:00
$escaped_string = mysql_real_escape_string ( $string , $link );
}
2011-06-02 22:51:12 +02:00
if ( $CONF [ 'database_type' ] == " mysqli " ) {
2009-01-15 13:24:36 +01:00
$escaped_string = mysqli_real_escape_string ( $link , $string );
}
2013-11-16 01:00:53 +01:00
if ( db_pgsql ()) {
2009-01-15 13:24:36 +01:00
// php 5.2+ allows for $link to be specified.
2011-06-02 22:51:12 +02:00
if ( version_compare ( phpversion (), " 5.2.0 " , " >= " )) {
2009-01-15 13:24:36 +01:00
$escaped_string = pg_escape_string ( $link , $string );
2011-06-02 22:51:12 +02:00
} else {
2009-01-15 13:24:36 +01:00
$escaped_string = pg_escape_string ( $string );
}
}
2011-06-02 22:51:12 +02:00
} else {
2009-01-15 13:24:36 +01:00
$escaped_string = $string ;
}
return $escaped_string ;
2007-03-24 08:27:00 +01:00
}
2007-10-25 14:29:38 +02:00
/**
* safeget
* Action : get value from $_GET [ $param ], or $default if $_GET [ $param ] is not set
* Call : $param = safeget ( 'param' ) # replaces $param = $_GET['param']
* - or -
* $param = safeget ( 'param' , 'default' )
*
* @ param String parameter name .
* @ param String ( optional ) - default value if key is not set .
* @ return String
*/
2007-10-23 01:49:10 +02:00
function safeget ( $param , $default = " " ) {
2009-01-15 13:24:36 +01:00
$retval = $default ;
if ( isset ( $_GET [ $param ])) $retval = $_GET [ $param ];
return $retval ;
2007-10-23 01:49:10 +02:00
}
2007-10-25 14:29:38 +02:00
/**
* safepost - similar to safeget ()
* @ see safeget ()
* @ param String parameter name
* @ param String ( optional ) default value ( defaults to " " )
* @ return String - value in $_POST [ $param ] or $default
* same as safeget , but for $_POST
*/
2007-10-23 01:49:10 +02:00
function safepost ( $param , $default = " " ) {
2009-01-15 13:24:36 +01:00
$retval = $default ;
if ( isset ( $_POST [ $param ])) $retval = $_POST [ $param ];
return $retval ;
2007-10-23 01:49:10 +02:00
}
2007-10-25 14:29:38 +02:00
/**
* safeserver
* @ see safeget ()
* @ param String $param
* @ param String $default ( optional )
* @ return String value from $_SERVER [ $param ] or $default
*/
2007-10-23 01:49:10 +02:00
function safeserver ( $param , $default = " " ) {
2009-01-15 13:24:36 +01:00
$retval = $default ;
if ( isset ( $_SERVER [ $param ])) $retval = $_SERVER [ $param ];
return $retval ;
2007-10-23 01:49:10 +02:00
}
2007-12-30 02:32:33 +01:00
/**
* safecookie
* @ see safeget ()
* @ param String $param
* @ param String $default ( optional )
* @ return String value from $_COOKIE [ $param ] or $default
*/
function safecookie ( $param , $default = " " ) {
2009-01-15 13:24:36 +01:00
$retval = $default ;
if ( isset ( $_COOKIE [ $param ])) $retval = $_COOKIE [ $param ];
return $retval ;
2007-12-30 02:32:33 +01:00
}
2013-12-01 20:05:14 +01:00
/**
* safesession
* @ see safeget ()
* @ param String $param
* @ param String $default ( optional )
* @ return String value from $_SESSION [ $param ] or $default
*/
function safesession ( $param , $default = " " ) {
$retval = $default ;
if ( isset ( $_SESSION [ $param ])) $retval = $_SESSION [ $param ];
return $retval ;
}
2011-07-30 00:06:52 +02:00
/**
* pacol
* @ param int $allow_editing
* @ param int $display_in_form
* @ param int display_in_list
* @ param String $type
* @ param String PALANG_label
* @ param String PALANG_desc
* @ param any optional $default
* @ param array optional $options
* @ param int $not_in_db
* @ return array for $struct
*/
2011-10-25 23:28:55 +02:00
function pacol ( $allow_editing , $display_in_form , $display_in_list , $type , $PALANG_label , $PALANG_desc , $default = " " , $options = array (), $not_in_db = 0 , $dont_write_to_db = 0 , $select = " " , $extrafrom = " " ) {
2013-10-13 20:11:18 +02:00
if ( $PALANG_label != '' ) $PALANG_label = Config :: lang ( $PALANG_label );
if ( $PALANG_desc != '' ) $PALANG_desc = Config :: lang ( $PALANG_desc );
2011-07-30 00:06:52 +02:00
return array (
'editable' => $allow_editing ,
'display_in_form' => $display_in_form ,
'display_in_list' => $display_in_list ,
'type' => $type ,
'label' => $PALANG_label , # $PALANG field label
'desc' => $PALANG_desc , # $PALANG field description
'default' => $default ,
'options' => $options ,
'not_in_db' => $not_in_db ,
2011-10-25 23:28:55 +02:00
'dont_write_to_db' => $dont_write_to_db ,
2011-10-23 00:49:01 +02:00
'select' => $select , # replaces the field name after SELECT
'extrafrom' => $extrafrom , # added after FROM xy - useful for JOINs etc.
2011-07-30 00:06:52 +02:00
);
}
2007-03-24 08:27:00 +01:00
//
// get_domain_properties
// Action: Get all the properties of a domain.
// Call: get_domain_properties (string domain)
//
2011-06-02 22:51:12 +02:00
function get_domain_properties ( $domain ) {
2009-01-15 13:24:36 +01:00
2011-10-30 00:58:08 +02:00
$handler = new DomainHandler ();
if ( ! $handler -> init ( $domain )) {
die ( " Error: " . join ( " \n " , $handler -> errormsg ));
2009-01-15 13:24:36 +01:00
}
2011-10-30 00:58:08 +02:00
if ( ! $handler -> view ()) {
die ( " Error: " . join ( " \n " , $handler -> errormsg ));
2009-01-15 13:24:36 +01:00
}
2013-10-13 18:11:15 +02:00
$result = $handler -> result ();
2011-10-30 00:58:08 +02:00
return $result ;
2007-03-24 08:27:00 +01:00
}
2011-04-10 00:37:11 +02:00
/**
* create_page_browser
* Action : Get page browser for a long list of mailboxes , aliases etc .
* Call : $pagebrowser = create_page_browser ( 'table.field' , 'query' , 50 ) # replaces $param = $_GET['param']
*
* @ param String idxfield - database field name to use as title
* @ param String query - core part of the query ( starting at " FROM " )
* @ return String
*/
2011-04-10 18:30:49 +02:00
function create_page_browser ( $idxfield , $querypart ) {
2011-04-10 00:37:11 +02:00
global $CONF ;
2011-04-10 18:30:49 +02:00
$page_size = ( int ) $CONF [ 'page_size' ];
2011-04-10 00:37:11 +02:00
$label_len = 2 ;
$pagebrowser = array ();
2011-04-10 18:30:49 +02:00
if ( $page_size < 2 ) { # will break the page browser
die ( '$CONF[\'page_size\'] must be 2 or more!' );
}
# get number of rows
2012-05-28 19:27:17 +02:00
$query = " SELECT count(*) as counter FROM (SELECT $idxfield $querypart ) AS tmp " ;
2011-04-10 18:30:49 +02:00
$result = db_query ( $query );
if ( $result [ 'rows' ] > 0 ) {
$row = db_array ( $result [ 'result' ]);
$count_results = $row [ 'counter' ] - 1 ; # we start counting at 0, not 1
}
# echo "<p>rows: " . ($count_results +1) . " --- $query";
if ( $count_results < $page_size ) {
return array (); # only one page - no pagebrowser required
}
2011-04-10 00:37:11 +02:00
2011-04-10 18:30:49 +02:00
# init row counter
2011-04-10 00:37:11 +02:00
$initcount = " SET @row=-1 " ;
2013-11-16 01:00:53 +01:00
if ( db_pgsql ()) {
2011-04-10 21:20:31 +02:00
$initcount = " CREATE TEMPORARY SEQUENCE rowcount MINVALUE 0 " ;
}
2011-04-10 00:37:11 +02:00
$result = db_query ( $initcount );
2011-04-10 18:30:49 +02:00
# get labels for relevant rows (first and last of each page)
$page_size_zerobase = $page_size - 1 ;
$query = "
2012-05-13 23:09:03 +02:00
SELECT * FROM (
2011-04-10 18:30:49 +02:00
SELECT $idxfield AS label , @ row := @ row + 1 AS row $querypart
) idx WHERE MOD ( idx . row , $page_size ) IN ( 0 , $page_size_zerobase ) OR idx . row = $count_results
" ;
2012-05-13 23:09:03 +02:00
2013-11-16 01:00:53 +01:00
if ( db_pgsql ()) {
2011-04-10 21:20:31 +02:00
$query = "
SELECT * FROM (
SELECT $idxfield AS label , nextval ( 'rowcount' ) AS row $querypart
) idx WHERE MOD ( idx . row , $page_size ) IN ( 0 , $page_size_zerobase ) OR idx . row = $count_results
" ;
}
2011-04-10 18:30:49 +02:00
# echo "<p>$query";
2011-04-10 00:37:11 +02:00
# TODO: $query is MySQL-specific
# PostgreSQL:
# http://www.postgresql.org/docs/8.1/static/sql-createsequence.html
# http://www.postgresonline.com/journal/archives/79-Simulating-Row-Number-in-PostgreSQL-Pre-8.4.html
# http://www.pg-forum.de/sql/1518-nummerierung-der-abfrageergebnisse.html
2011-04-10 18:30:49 +02:00
# CREATE TEMPORARY SEQUENCE foo MINVALUE 0 MAXVALUE $page_size_zerobase CYCLE
2011-04-10 00:37:11 +02:00
# afterwards: DROP SEQUENCE foo
$result = db_query ( $query );
if ( $result [ 'rows' ] > 0 ) {
while ( $row = db_array ( $result [ 'result' ])) {
if ( $row2 = db_array ( $result [ 'result' ])) {
$label = substr ( $row [ 'label' ], 0 , $label_len ) . '-' . substr ( $row2 [ 'label' ], 0 , $label_len );
$pagebrowser [] = $label ;
2011-04-10 18:30:49 +02:00
} else { # only one row remaining
$label = substr ( $row [ 'label' ], 0 , $label_len );
2011-04-10 00:37:11 +02:00
$pagebrowser [] = $label ;
}
}
}
2013-11-16 01:00:53 +01:00
if ( db_pgsql ()) {
2011-04-10 21:20:31 +02:00
db_query ( " DROP SEQUENCE rowcount " );
}
2011-04-10 00:37:11 +02:00
return $pagebrowser ;
}
2007-03-24 08:27:00 +01:00
//
// divide_quota
// Action: Recalculates the quota from MBs to bytes (divide, /)
// Call: divide_quota (string $quota)
//
2011-06-02 22:51:12 +02:00
function divide_quota ( $quota ) {
2009-01-15 13:24:36 +01:00
if ( $quota == - 1 ) return $quota ;
2013-04-01 23:59:56 +02:00
$value = round ( $quota / Config :: read ( 'quota_multiplier' ), 2 );
2009-01-15 13:24:36 +01:00
return $value ;
2007-03-24 08:27:00 +01:00
}
//
// check_owner
2007-11-04 01:50:09 +01:00
// Action: Checks if the admin is the owner of the domain (or global-admin)
2007-03-24 08:27:00 +01:00
// Call: check_owner (string admin, string domain)
//
2011-06-02 22:51:12 +02:00
function check_owner ( $username , $domain ) {
2013-12-08 20:41:01 +01:00
$table_domain_admins = table_by_key ( 'domain_admins' );
2011-08-21 22:58:20 +02:00
$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' " );
2012-06-03 00:13:27 +02:00
if ( $result [ 'rows' ] == 1 || $result [ 'rows' ] == 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...
flash_error ( " Permission check returned multiple results. Please go to 'edit admin' for your username and press the save "
2009-11-30 13:48:25 +01:00
. " button once to fix the database. If this doesn't help, open a bugreport. " );
2012-06-03 00:13:27 +02:00
}
2009-01-15 13:24:36 +01:00
return false ;
}
2007-03-24 08:27:00 +01:00
}
//
// check_alias_owner
// Action: Checks if the admin is the owner of the alias.
// Call: check_alias_owner (string admin, string alias)
//
2011-06-02 22:51:12 +02:00
function check_alias_owner ( $username , $alias ) {
2009-01-15 13:24:36 +01:00
global $CONF ;
if ( authentication_has_role ( 'global-admin' )) return true ;
$tmp = preg_split ( '/\@/' , $alias );
2011-06-02 22:51:12 +02:00
if (( $CONF [ 'special_alias_control' ] == 'NO' ) && array_key_exists ( $tmp [ 0 ], $CONF [ 'default_aliases' ])) {
2009-01-15 13:24:36 +01:00
return false ;
2011-06-02 22:51:12 +02:00
} else {
2009-01-15 13:24:36 +01:00
return true ;
}
2007-03-24 08:27:00 +01:00
}
2007-09-28 21:27:51 +02:00
/**
2007-09-28 22:28:18 +02:00
* List domains for an admin user .
2007-09-28 21:27:51 +02:00
* @ param String $username
* @ return array of domain names .
*/
2011-06-02 22:51:12 +02:00
function list_domains_for_admin ( $username ) {
2013-12-08 20:41:01 +01:00
$table_domain = table_by_key ( 'domain' );
$table_domain_admins = table_by_key ( 'domain_admins' );
2009-01-15 13:24:36 +01:00
2011-11-12 21:44:35 +01:00
$E_username = escape_string ( $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
$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?
}
$query .= " WHERE " . join ( ' AND ' , $condition );
$query .= " ORDER BY $table_domain .domain " ;
$list = array ();
2009-01-15 13:24:36 +01:00
$result = db_query ( $query );
2011-06-02 22:51:12 +02:00
if ( $result [ 'rows' ] > 0 ) {
2009-01-15 13:24:36 +01:00
$i = 0 ;
2011-06-02 22:51:12 +02:00
while ( $row = db_array ( $result [ 'result' ])) {
2009-01-15 13:24:36 +01:00
$list [ $i ] = $row [ 'domain' ];
$i ++ ;
}
}
return $list ;
2007-03-24 08:27:00 +01:00
}
//
// list_domains
// Action: List all available domains.
// Call: list_domains ()
//
2011-06-02 22:51:12 +02:00
function list_domains () {
2009-01-15 13:24:36 +01:00
$list = array ();
2007-03-24 08:27:00 +01:00
2013-12-08 20:41:01 +01:00
$table_domain = table_by_key ( 'domain' );
2009-01-15 13:24:36 +01:00
$result = db_query ( " SELECT domain FROM $table_domain WHERE domain!='ALL' ORDER BY domain " );
2011-06-02 22:51:12 +02:00
if ( $result [ 'rows' ] > 0 ) {
2009-01-15 13:24:36 +01:00
$i = 0 ;
2011-06-02 22:51:12 +02:00
while ( $row = db_array ( $result [ 'result' ])) {
2009-01-15 13:24:36 +01:00
$list [ $i ] = $row [ 'domain' ];
$i ++ ;
}
}
return $list ;
2007-03-24 08:27:00 +01:00
}
//
// list_admins
// Action: Lists all the admins
// Call: list_admins ()
//
// was admin_list_admins
//
2011-06-02 22:51:12 +02:00
function list_admins () {
2012-05-08 00:53:04 +02:00
$handler = new AdminHandler ();
2007-03-24 08:27:00 +01:00
2013-10-13 18:11:15 +02:00
$handler -> getList ( '' );
return $handler -> result ();
2007-03-24 08:27:00 +01:00
}
//
// encode_header
// Action: Encode a string according to RFC 1522 for use in headers if it contains 8-bit characters.
// Call: encode_header (string header, string charset)
//
2011-06-02 22:51:12 +02:00
function encode_header ( $string , $default_charset = " utf-8 " ) {
if ( strtolower ( $default_charset ) == 'iso-8859-1' ) {
2009-01-15 13:24:36 +01:00
$string = str_replace ( " \240 " , ' ' , $string );
}
$j = strlen ( $string );
$max_l = 75 - strlen ( $default_charset ) - 7 ;
$aRet = array ();
$ret = '' ;
$iEncStart = $enc_init = false ;
$cur_l = $iOffset = 0 ;
2011-06-02 22:51:12 +02:00
for ( $i = 0 ; $i < $j ; ++ $i ) {
switch ( $string { $i }) {
case '=' :
case '<' :
case '>' :
case ',' :
case '?' :
case '_' :
if ( $iEncStart === false ) {
$iEncStart = $i ;
}
$cur_l += 3 ;
if ( $cur_l > ( $max_l - 2 )) {
2009-01-15 13:24:36 +01:00
$aRet [] = substr ( $string , $iOffset , $iEncStart - $iOffset );
$aRet [] = " =? $default_charset ?Q? $ret ?= " ;
$iOffset = $i ;
$cur_l = 0 ;
$ret = '' ;
$iEncStart = false ;
2011-06-02 22:51:12 +02:00
} else {
$ret .= sprintf ( " =%02X " , ord ( $string { $i }));
2009-01-15 13:24:36 +01:00
}
2011-06-02 22:51:12 +02:00
break ;
case '(' :
case ')' :
if ( $iEncStart !== false ) {
2009-01-15 13:24:36 +01:00
$aRet [] = substr ( $string , $iOffset , $iEncStart - $iOffset );
2011-06-02 22:51:12 +02:00
$aRet [] = " =? $default_charset ?Q? $ret ?= " ;
2009-01-15 13:24:36 +01:00
$iOffset = $i ;
2011-06-02 22:51:12 +02:00
$cur_l = 0 ;
$ret = '' ;
$iEncStart = false ;
2009-01-15 13:24:36 +01:00
}
2011-06-02 22:51:12 +02:00
break ;
case ' ' :
if ( $iEncStart !== false ) {
2009-01-15 13:24:36 +01:00
$cur_l ++ ;
2011-06-02 22:51:12 +02:00
if ( $cur_l > $max_l ) {
2009-01-15 13:24:36 +01:00
$aRet [] = substr ( $string , $iOffset , $iEncStart - $iOffset );
$aRet [] = " =? $default_charset ?Q? $ret ?= " ;
$iOffset = $i ;
$cur_l = 0 ;
$ret = '' ;
2011-06-02 22:51:12 +02:00
$iEncStart = false ;
} else {
$ret .= '_' ;
2009-01-15 13:24:36 +01:00
}
2011-06-02 22:51:12 +02:00
}
break ;
default :
$k = ord ( $string { $i });
if ( $k > 126 ) {
if ( $iEncStart === false ) {
// do not start encoding in the middle of a string, also take the rest of the word.
$sLeadString = substr ( $string , 0 , $i );
$aLeadString = explode ( ' ' , $sLeadString );
$sToBeEncoded = array_pop ( $aLeadString );
$iEncStart = $i - strlen ( $sToBeEncoded );
$ret .= $sToBeEncoded ;
$cur_l += strlen ( $sToBeEncoded );
}
$cur_l += 3 ;
// first we add the encoded string that reached it's max size
if ( $cur_l > ( $max_l - 2 )) {
$aRet [] = substr ( $string , $iOffset , $iEncStart - $iOffset );
$aRet [] = " =? $default_charset ?Q? $ret ?= " ;
$cur_l = 3 ;
$ret = '' ;
$iOffset = $i ;
$iEncStart = $i ;
}
$enc_init = true ;
$ret .= sprintf ( " =%02X " , $k );
} else {
if ( $iEncStart !== false ) {
$cur_l ++ ;
if ( $cur_l > $max_l ) {
$aRet [] = substr ( $string , $iOffset , $iEncStart - $iOffset );
$aRet [] = " =? $default_charset ?Q? $ret ?= " ;
$iEncStart = false ;
$iOffset = $i ;
$cur_l = 0 ;
$ret = '' ;
} else {
$ret .= $string { $i };
}
2009-01-15 13:24:36 +01:00
}
}
2011-06-02 22:51:12 +02:00
break ;
# end switch
2009-01-15 13:24:36 +01:00
}
}
2011-06-02 22:51:12 +02:00
if ( $enc_init ) {
if ( $iEncStart !== false ) {
2009-01-15 13:24:36 +01:00
$aRet [] = substr ( $string , $iOffset , $iEncStart - $iOffset );
$aRet [] = " =? $default_charset ?Q? $ret ?= " ;
2011-06-02 22:51:12 +02:00
} else {
2009-01-15 13:24:36 +01:00
$aRet [] = substr ( $string , $iOffset );
}
$string = implode ( '' , $aRet );
}
return $string ;
2007-03-24 08:27:00 +01:00
}
//
// generate_password
// Action: Generates a random password
// Call: generate_password ()
//
2011-04-10 16:16:17 +02:00
function generate_password () {
2011-09-25 20:39:20 +02:00
// length of the generated password
$length = 8 ;
2011-04-10 16:16:17 +02:00
// define possible characters
$possible = " 2345678923456789abcdefghijkmnpqrstuvwxyzABCDEFGHIJKLMNPQRSTUVWXYZ " ; # skip 0 and 1 to avoid confusion with O and l
// add random characters to $password until $length is reached
$password = " " ;
while ( strlen ( $password ) < $length ) {
// pick a random character from the possible ones
$char = substr ( $possible , mt_rand ( 0 , strlen ( $possible ) - 1 ), 1 );
// we don't want this character if it's already in the password
if ( ! strstr ( $password , $char )) {
$password .= $char ;
}
}
2009-01-15 13:24:36 +01:00
return $password ;
2007-03-24 08:27:00 +01:00
}
2011-09-25 20:39:20 +02:00
/**
* Check if a password is strong enough based on the conditions in $CONF [ 'password_validation' ]
* @ param String $password
* @ return array of error messages , or empty array if the password is ok
*/
function validate_password ( $password ) {
2013-03-03 01:34:53 +01:00
$val_conf = Config :: read ( 'password_validation' );
2011-09-25 20:39:20 +02:00
$result = array ();
2013-03-03 01:34:53 +01:00
$minlen = ( int ) Config :: read ( 'min_password_length' ); # used up to 2.3.x - check it for backward compatibility
if ( $minlen > 0 ) {
$val_conf [ '/.{' . $minlen . '}/' ] = " password_too_short $minlen " ;
2011-09-25 20:39:20 +02:00
}
2013-03-03 01:34:53 +01:00
foreach ( $val_conf as $regex => $message ) {
2011-09-25 20:39:20 +02:00
if ( ! preg_match ( $regex , $password )) {
$msgparts = preg_split ( " / / " , $message , 2 );
if ( count ( $msgparts ) == 1 ) {
2013-10-13 20:11:18 +02:00
$result [] = Config :: lang ( $msgparts [ 0 ]);
2011-09-25 20:39:20 +02:00
} else {
2013-10-13 20:11:18 +02:00
$result [] = sprintf ( Config :: lang ( $msgparts [ 0 ]), $msgparts [ 1 ]);
2011-09-25 20:39:20 +02:00
}
}
}
2013-03-03 01:34:53 +01:00
2011-09-25 20:39:20 +02:00
return $result ;
}
2009-03-08 22:16:41 +01:00
/**
* Encrypt a password , using the apparopriate hashing mechanism as defined in
* config . inc . php ( $CONF [ 'encrypt' ]) .
* When wanting to compare one pw to another , it ' s necessary to provide the salt used - hence
* the second parameter ( $pw_db ), which is the existing hash from the DB .
*
* @ param string $pw
* @ param string $encrypted password
* @ return string encrypted password .
*/
2011-06-02 22:51:12 +02:00
function pacrypt ( $pw , $pw_db = " " ) {
2009-01-15 13:24:36 +01:00
global $CONF ;
$pw = stripslashes ( $pw );
$password = " " ;
$salt = " " ;
if ( $CONF [ 'encrypt' ] == 'md5crypt' ) {
$split_salt = preg_split ( '/\$/' , $pw_db );
if ( isset ( $split_salt [ 2 ])) {
$salt = $split_salt [ 2 ];
}
$password = md5crypt ( $pw , $salt );
}
2009-03-14 00:32:20 +01:00
elseif ( $CONF [ 'encrypt' ] == 'md5' ) {
2009-01-15 13:24:36 +01:00
$password = md5 ( $pw );
}
2009-03-14 00:32:20 +01:00
elseif ( $CONF [ 'encrypt' ] == 'system' ) {
2013-12-01 22:48:14 +01:00
if ( $pw_db ) {
$password = crypt ( $pw , $pw_db );
2011-06-02 22:51:12 +02:00
} else {
2013-12-01 22:48:14 +01:00
$password = crypt ( $pw );
2009-01-15 13:24:36 +01:00
}
}
2009-03-14 00:32:20 +01:00
elseif ( $CONF [ 'encrypt' ] == 'cleartext' ) {
2009-01-15 13:24:36 +01:00
$password = $pw ;
}
2009-01-15 15:32:43 +01:00
// See https://sourceforge.net/tracker/?func=detail&atid=937966&aid=1793352&group_id=191583
// this is apparently useful for pam_mysql etc.
2011-06-02 22:51:12 +02:00
elseif ( $CONF [ 'encrypt' ] == 'mysql_encrypt' ) {
2012-01-11 00:03:38 +01:00
$pw = escape_string ( $pw );
2009-01-15 15:32:43 +01:00
if ( $pw_db != " " ) {
2012-01-15 12:22:01 +01:00
$salt = escape_string ( substr ( $pw_db , 0 , 2 ));
2009-01-15 15:32:43 +01:00
$res = db_query ( " SELECT ENCRYPT(' " . $pw . " ',' " . $salt . " '); " );
} else {
$res = db_query ( " SELECT ENCRYPT(' " . $pw . " '); " );
}
$l = db_row ( $res [ " result " ]);
$password = $l [ 0 ];
}
2009-11-05 15:55:39 +01:00
2009-03-14 00:32:20 +01:00
elseif ( $CONF [ 'encrypt' ] == 'authlib' ) {
2009-02-09 20:11:43 +01:00
$flavor = $CONF [ 'authlib_default_flavor' ];
$salt = substr ( create_salt (), 0 , 2 ); # courier-authlib supports only two-character salts
2009-07-13 15:27:44 +02:00
if ( preg_match ( '/^{.*}/' , $pw_db )) {
2009-02-09 20:11:43 +01:00
// we have a flavor in the db -> use it instead of default flavor
2010-12-16 00:17:08 +01:00
$result = preg_split ( '/[{}]/' , $pw_db , 3 ); # split at { and/or }
2009-02-09 20:11:43 +01:00
$flavor = $result [ 1 ];
$salt = substr ( $result [ 2 ], 0 , 2 );
}
2009-11-05 15:55:39 +01:00
2009-02-09 20:11:43 +01:00
if ( stripos ( $flavor , 'md5raw' ) === 0 ) {
$password = '{' . $flavor . '}' . md5 ( $pw );
} elseif ( stripos ( $flavor , 'md5' ) === 0 ) {
$password = '{' . $flavor . '}' . base64_encode ( md5 ( $pw , TRUE ));
} elseif ( stripos ( $flavor , 'crypt' ) === 0 ) {
$password = '{' . $flavor . '}' . crypt ( $pw , $salt );
2009-11-05 15:55:39 +01:00
} elseif ( stripos ( $flavor , 'SHA' ) === 0 ) {
$password = '{' . $flavor . '}' . base64_encode ( sha1 ( $pw , TRUE ));
2009-02-09 20:11:43 +01:00
} else {
2009-08-01 07:07:20 +02:00
die ( " authlib_default_flavor ' " . $flavor . " ' unknown. Valid flavors are 'md5raw', 'md5', 'SHA' and 'crypt' " );
2009-02-09 20:11:43 +01:00
}
}
2009-11-05 15:55:39 +01:00
2009-03-14 00:32:20 +01:00
elseif ( preg_match ( " /^dovecot:/ " , $CONF [ 'encrypt' ])) {
$split_method = preg_split ( '/:/' , $CONF [ 'encrypt' ]);
2013-11-01 20:54:25 +01:00
$method = strtoupper ( $split_method [ 1 ]); # TODO: if $pw_db starts with {method}, change $method accordingly
2013-10-07 20:42:59 +02:00
if ( ! preg_match ( " /^[A-Z0-9.-]+ $ / " , $method )) { die ( " invalid dovecot encryption method " ); } # TODO: check against a fixed list?
2013-10-03 20:53:34 +02:00
# if (strtolower($method) == 'md5-crypt') die("\$CONF['encrypt'] = 'dovecot:md5-crypt' will not work because dovecotpw generates a random salt each time. Please use \$CONF['encrypt'] = 'md5crypt' instead.");
2013-10-03 22:01:31 +02:00
# $crypt_method = preg_match ("/.*-CRYPT$/", $method);
2009-03-14 00:32:20 +01:00
2013-10-07 20:42:59 +02:00
# digest-md5 and SCRAM-SHA-1 hashes include the username - until someone implements it, let's declare it as unsupported
2013-10-03 22:29:54 +02:00
if ( strtolower ( $method ) == 'digest-md5' ) die ( " Sorry, \$ CONF['encrypt'] = 'dovecot:digest-md5' is not supported by PostfixAdmin. " );
2013-10-07 20:42:59 +02:00
if ( strtoupper ( $method ) == 'SCRAM-SHA-1' ) die ( " Sorry, \$ CONF['encrypt'] = 'dovecot:scram-sha-1' is not supported by PostfixAdmin. " );
# TODO: add -u option for those hashes, or for everything that is salted (-u was available before dovecot 2.1 -> no problem with backward compability)
2013-10-03 22:29:54 +02:00
2013-10-03 22:01:31 +02:00
$dovecotpw = " doveadm pw " ;
2009-03-14 00:32:20 +01:00
if ( ! empty ( $CONF [ 'dovecotpw' ])) $dovecotpw = $CONF [ 'dovecotpw' ];
2009-11-02 19:46:48 +01:00
# Use proc_open call to avoid safe_mode problems and to prevent showing plain password in process table
$spec = array (
2009-11-05 15:55:39 +01:00
0 => array ( " pipe " , " r " ), // stdin
2011-06-05 22:23:04 +02:00
1 => array ( " pipe " , " w " ), // stdout
2 => array ( " pipe " , " w " ), // stderr
2009-11-05 15:55:39 +01:00
);
2009-11-02 19:46:48 +01:00
2013-10-07 20:42:59 +02:00
$nonsaltedtypes = " SHA|SHA1|SHA256|SHA512|CLEAR|CLEARTEXT|PLAIN|PLAIN-TRUNC|CRAM-MD5|HMAC-MD5|PLAIN-MD4|PLAIN-MD5|LDAP-MD5|LANMAN|NTLM|RPA " ;
$salted = ! preg_match ( " /^( $nonsaltedtypes )( \ .B64| \ .BASE64| \ .HEX)? $ / " , strtoupper ( $method ) );
2013-10-03 22:01:31 +02:00
$dovepasstest = '' ;
2013-10-07 20:42:59 +02:00
if ( $salted && ( ! empty ( $pw_db )) ) {
# only use -t for salted passwords to be backward compatible with dovecot < 2.1
2013-10-03 22:01:31 +02:00
$dovepasstest = " -t " . escapeshellarg ( $pw_db );
2013-10-03 20:53:34 +02:00
}
2013-10-03 22:01:31 +02:00
$pipe = proc_open ( " $dovecotpw '-s' $method $dovepasstest " , $spec , $pipes );
2009-03-14 00:32:20 +01:00
if ( ! $pipe ) {
2009-11-02 19:46:48 +01:00
die ( " can't proc_open $dovecotpw " );
2009-03-14 00:32:20 +01:00
} else {
2013-10-03 22:01:31 +02:00
// use dovecot's stdin, it uses getpass() twice (except when using -t)
2009-11-05 15:55:39 +01:00
// Write pass in pipe stdin
2013-10-03 22:01:31 +02:00
if ( empty ( $dovepasstest )) {
2013-10-03 20:53:34 +02:00
fwrite ( $pipes [ 0 ], $pw . " \n " , 1 + strlen ( $pw )); usleep ( 1000 );
}
2009-11-05 15:55:39 +01:00
fwrite ( $pipes [ 0 ], $pw . " \n " , 1 + strlen ( $pw ));
fclose ( $pipes [ 0 ]);
2009-11-02 19:46:48 +01:00
2009-11-05 15:55:39 +01:00
// Read hash from pipe stdout
$password = fread ( $pipes [ 1 ], " 200 " );
2011-06-05 22:23:04 +02:00
2013-10-03 22:01:31 +02:00
if ( empty ( $dovepasstest )) {
2013-10-03 20:53:34 +02:00
if ( ! preg_match ( '/^\{' . $method . '\}/' , $password )) {
$stderr_output = stream_get_contents ( $pipes [ 2 ]);
error_log ( 'dovecotpw password encryption failed.' );
error_log ( 'STDERR output: ' . $stderr_output );
die ( " can't encrypt password with dovecotpw, see error log for details " );
}
} else {
if ( ! preg_match ( '(verified)' , $password )) {
$password = " Thepasswordcannotbeverified " ;
} else {
$password = rtrim ( str_replace ( '(verified)' , '' , $password ));
}
2011-06-05 22:23:04 +02:00
}
fclose ( $pipes [ 1 ]);
fclose ( $pipes [ 2 ]);
2009-11-05 15:55:39 +01:00
proc_close ( $pipe );
2009-11-02 19:46:48 +01:00
2013-11-01 20:54:25 +01:00
if ( ( ! empty ( $pw_db )) && ( substr ( $pw_db , 0 , 1 ) != '{' ) ) {
# for backward compability with "old" dovecot passwords that don't have the {method} prefix
$password = str_replace ( '{' . $method . '}' , '' , $password );
}
2013-10-03 20:53:34 +02:00
$password = rtrim ( $password );
2009-03-14 00:32:20 +01:00
}
}
else {
die ( 'unknown/invalid $CONF["encrypt"] setting: ' . $CONF [ 'encrypt' ]);
}
2009-01-15 13:24:36 +01:00
return $password ;
2007-03-24 08:27:00 +01:00
}
//
// md5crypt
// Action: Creates MD5 encrypted password
// Call: md5crypt (string cleartextpassword)
//
2011-06-02 22:51:12 +02:00
function md5crypt ( $pw , $salt = " " , $magic = " " ) {
2009-01-15 13:24:36 +01:00
$MAGIC = " $ 1 $ " ;
if ( $magic == " " ) $magic = $MAGIC ;
if ( $salt == " " ) $salt = create_salt ();
$slist = explode ( " $ " , $salt );
if ( $slist [ 0 ] == " 1 " ) $salt = $slist [ 1 ];
$salt = substr ( $salt , 0 , 8 );
$ctx = $pw . $magic . $salt ;
$final = hex2bin ( md5 ( $pw . $salt . $pw ));
2011-06-02 22:51:12 +02:00
for ( $i = strlen ( $pw ); $i > 0 ; $i -= 16 ) {
if ( $i > 16 ) {
2009-01-15 13:24:36 +01:00
$ctx .= substr ( $final , 0 , 16 );
2011-06-02 22:51:12 +02:00
} else {
2009-01-15 13:24:36 +01:00
$ctx .= substr ( $final , 0 , $i );
}
}
$i = strlen ( $pw );
2011-06-02 22:51:12 +02:00
while ( $i > 0 ) {
2009-01-15 13:24:36 +01:00
if ( $i & 1 ) $ctx .= chr ( 0 );
else $ctx .= $pw [ 0 ];
$i = $i >> 1 ;
}
$final = hex2bin ( md5 ( $ctx ));
2011-06-02 22:51:12 +02:00
for ( $i = 0 ; $i < 1000 ; $i ++ ) {
2009-01-15 13:24:36 +01:00
$ctx1 = " " ;
2011-06-02 22:51:12 +02:00
if ( $i & 1 ) {
2009-01-15 13:24:36 +01:00
$ctx1 .= $pw ;
2011-06-02 22:51:12 +02:00
} else {
2009-01-15 13:24:36 +01:00
$ctx1 .= substr ( $final , 0 , 16 );
}
if ( $i % 3 ) $ctx1 .= $salt ;
if ( $i % 7 ) $ctx1 .= $pw ;
2011-06-02 22:51:12 +02:00
if ( $i & 1 ) {
2009-01-15 13:24:36 +01:00
$ctx1 .= substr ( $final , 0 , 16 );
2011-06-02 22:51:12 +02:00
} else {
2009-01-15 13:24:36 +01:00
$ctx1 .= $pw ;
}
$final = hex2bin ( md5 ( $ctx1 ));
}
$passwd = " " ;
$passwd .= to64 ((( ord ( $final [ 0 ]) << 16 ) | ( ord ( $final [ 6 ]) << 8 ) | ( ord ( $final [ 12 ]))), 4 );
$passwd .= to64 ((( ord ( $final [ 1 ]) << 16 ) | ( ord ( $final [ 7 ]) << 8 ) | ( ord ( $final [ 13 ]))), 4 );
$passwd .= to64 ((( ord ( $final [ 2 ]) << 16 ) | ( ord ( $final [ 8 ]) << 8 ) | ( ord ( $final [ 14 ]))), 4 );
$passwd .= to64 ((( ord ( $final [ 3 ]) << 16 ) | ( ord ( $final [ 9 ]) << 8 ) | ( ord ( $final [ 15 ]))), 4 );
$passwd .= to64 ((( ord ( $final [ 4 ]) << 16 ) | ( ord ( $final [ 10 ]) << 8 ) | ( ord ( $final [ 5 ]))), 4 );
$passwd .= to64 ( ord ( $final [ 11 ]), 2 );
return " $magic $salt\ $ $passwd " ;
2007-03-24 08:27:00 +01:00
}
2011-06-02 22:51:12 +02:00
function create_salt () {
2009-01-15 13:24:36 +01:00
srand (( double ) microtime () * 1000000 );
$salt = substr ( md5 ( rand ( 0 , 9999999 )), 0 , 8 );
return $salt ;
2007-03-24 08:27:00 +01:00
}
2012-01-11 19:40:58 +01:00
/**/ if ( ! function_exists ( 'hex2bin' )) { # PHP around 5.3.8 includes hex2bin as native function - http://php.net/hex2bin
2011-06-02 22:51:12 +02:00
function hex2bin ( $str ) {
2009-01-15 13:24:36 +01:00
$len = strlen ( $str );
$nstr = " " ;
2011-06-02 22:51:12 +02:00
for ( $i = 0 ; $i < $len ; $i += 2 ) {
2009-01-15 13:24:36 +01:00
$num = sscanf ( substr ( $str , $i , 2 ), " %x " );
$nstr .= chr ( $num [ 0 ]);
}
return $nstr ;
2007-03-24 08:27:00 +01:00
}
2012-04-15 22:46:29 +02:00
/**/ }
2012-02-04 00:43:45 +01:00
/*
* remove item $item from array $array
*/
function remove_from_array ( $array , $item ) {
# array_diff might be faster, but doesn't provide an easy way to know if the value was found or not
# return array_diff($array, array($item));
$ret = array_search ( $item , $array );
if ( $ret === false ) {
$found = 0 ;
} else {
$found = 1 ;
unset ( $array [ $ret ]);
}
return array ( $found , $array );
}
2011-06-02 22:51:12 +02:00
function to64 ( $v , $n ) {
2009-01-15 13:24:36 +01:00
$ITOA64 = " ./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz " ;
$ret = " " ;
2011-06-02 22:51:12 +02:00
while (( $n - 1 ) >= 0 ) {
2009-01-15 13:24:36 +01:00
$n -- ;
$ret .= $ITOA64 [ $v & 0x3f ];
$v = $v >> 6 ;
}
return $ret ;
2007-03-24 08:27:00 +01:00
}
2010-12-25 23:04:16 +01:00
/**
* smtp_mail
* Action : Send email
* Call : smtp_mail ( string to , string from , string subject , string body ]) - or -
* Call : smtp_mail ( string to , string from , string data ) - DEPRECATED
* @ param String - To :
* @ param String - From :
* @ param String - Subject : ( if called with 4 parameters ) or full mail body ( if called with 3 parameters )
* @ param String ( optional , but recommended ) - mail body
* @ return bool - true on success , otherwise false
* TODO : Replace this with something decent like PEAR :: Mail or Zend_Mail .
*/
function smtp_mail ( $to , $from , $data , $body = " " ) {
2009-01-15 13:24:36 +01:00
global $CONF ;
$smtpd_server = $CONF [ 'smtp_server' ];
$smtpd_port = $CONF [ 'smtp_port' ];
2010-09-27 01:14:42 +02:00
//$smtp_server = $_SERVER["SERVER_NAME"];
$smtp_server = php_uname ( " n " );
2009-01-15 13:24:36 +01:00
$errno = " 0 " ;
$errstr = " 0 " ;
$timeout = " 30 " ;
2010-12-25 23:04:16 +01:00
if ( $body != " " ) {
$maildata =
" To: " . $to . " \n "
. " From: " . $from . " \n "
. " Subject: " . encode_header ( $data ) . " \n "
. " MIME-Version: 1.0 \n "
. " Content-Type: text/plain; charset=utf-8 \n "
. " Content-Transfer-Encoding: 8bit \n "
. " \n "
. $body
;
} else {
$maildata = $data ;
}
2009-01-15 13:24:36 +01:00
$fh = @ fsockopen ( $smtpd_server , $smtpd_port , $errno , $errstr , $timeout );
2011-06-02 22:51:12 +02:00
if ( ! $fh ) {
2011-10-20 14:13:39 +02:00
error_log ( " fsockopen failed - errno: $errno - errstr: $errstr " );
2009-01-15 13:24:36 +01:00
return false ;
2011-06-02 22:51:12 +02:00
} else {
2009-02-16 13:40:15 +01:00
$res = smtp_get_response ( $fh );
2009-01-15 13:24:36 +01:00
fputs ( $fh , " EHLO $smtp_server\r\n " );
$res = smtp_get_response ( $fh );
fputs ( $fh , " MAIL FROM:< $from > \r \n " );
$res = smtp_get_response ( $fh );
fputs ( $fh , " RCPT TO:< $to > \r \n " );
$res = smtp_get_response ( $fh );
fputs ( $fh , " DATA \r \n " );
$res = smtp_get_response ( $fh );
2010-12-25 23:04:16 +01:00
fputs ( $fh , " $maildata\r\n . \r \n " );
2009-01-15 13:24:36 +01:00
$res = smtp_get_response ( $fh );
fputs ( $fh , " QUIT \r \n " );
$res = smtp_get_response ( $fh );
fclose ( $fh );
}
return true ;
2007-03-24 08:27:00 +01:00
}
2011-07-19 23:12:25 +02:00
/**
* smtp_get_admin_email
* Action : Get configured email address or current user if nothing configured
* Call : smtp_get_admin_email
* @ return String - username / mail address
*/
function smtp_get_admin_email () {
2013-10-08 21:30:28 +02:00
$admin_email = Config :: read ( 'admin_email' );
if ( ! empty ( $admin_email ))
return $admin_email ;
2011-07-19 23:12:25 +02:00
else
return authentication_get_username ();
}
2007-03-24 08:27:00 +01:00
//
// smtp_get_response
// Action: Get response from mail server
// Call: smtp_get_response (string FileHandle)
//
2011-06-02 22:51:12 +02:00
function smtp_get_response ( $fh ) {
2009-01-15 13:24:36 +01:00
$res = '' ;
2011-06-02 22:51:12 +02:00
do {
2013-10-08 21:30:28 +02:00
$line = fgets ( $fh , 256 );
$res .= $line ;
}
while ( preg_match ( " /^ \ d \ d \ d \ -/ " , $line ));
return $res ;
2007-03-24 08:27:00 +01:00
}
$DEBUG_TEXT = " \n
2009-01-15 13:24:36 +01:00
< p /> \n
Please check the documentation and website for more information . \n
< p /> \n
< a href = \ " http://postfixadmin.sf.net/ \" >Postfix Admin</a><br /> \n
2013-11-18 23:57:37 +01:00
< a href = 'https://sourceforge.net/p/postfixadmin/discussion/676076' > Forums </ a >
2009-01-15 13:24:36 +01:00
" ;
2007-03-24 08:27:00 +01:00
2007-10-07 19:23:29 +02:00
/**
* db_connect
* Action : Makes a connection to the database if it doesn ' t exist
* Call : db_connect ()
2007-11-02 00:58:12 +01:00
* Optional parameter : $ignore_errors = TRUE , used by setup . php
2007-10-07 19:23:29 +02:00
*
* Return value :
2007-11-02 00:58:12 +01:00
* a ) without $ignore_errors or $ignore_errors == 0
2007-10-07 19:23:29 +02:00
* - $link - the database connection - OR -
* - call die () in case of connection problems
2007-11-02 00:58:12 +01:00
* b ) with $ignore_errors == TRUE
2007-10-07 19:23:29 +02:00
* array ( $link , $error_text );
*/
2011-06-02 22:51:12 +02:00
function db_connect ( $ignore_errors = 0 ) {
2009-01-15 13:24:36 +01:00
global $CONF ;
global $DEBUG_TEXT ;
if ( $ignore_errors != 0 ) $DEBUG_TEXT = '' ;
$error_text = '' ;
$link = 0 ;
2011-06-02 22:51:12 +02:00
if ( $CONF [ 'database_type' ] == " mysql " ) {
if ( function_exists ( " mysql_connect " )) {
2009-01-15 13:24:36 +01:00
$link = @ mysql_connect ( $CONF [ 'database_host' ], $CONF [ 'database_user' ], $CONF [ 'database_password' ]) or $error_text .= ( " <p />DEBUG INFORMATION:<br />Connect: " . mysql_error () . " $DEBUG_TEXT " );
if ( $link ) {
@ mysql_query ( " SET CHARACTER SET utf8 " , $link );
@ mysql_query ( " SET COLLATION_CONNECTION='utf8_general_ci' " , $link );
$succes = @ mysql_select_db ( $CONF [ 'database_name' ], $link ) or $error_text .= ( " <p />DEBUG INFORMATION:<br />MySQL Select Database: " . mysql_error () . " $DEBUG_TEXT " );
}
2011-06-02 22:51:12 +02:00
} else {
2010-12-16 00:17:08 +01:00
$error_text .= " <p />DEBUG INFORMATION:<br />MySQL 3.x / 4.0 functions not available! (php5-mysql installed?)<br />database_type = 'mysql' in config.inc.php, are you using a different database? $DEBUG_TEXT " ;
2009-01-15 13:24:36 +01:00
}
2011-06-02 22:51:12 +02:00
} elseif ( $CONF [ 'database_type' ] == " mysqli " ) {
if ( function_exists ( " mysqli_connect " )) {
2009-01-15 13:24:36 +01:00
$link = @ mysqli_connect ( $CONF [ 'database_host' ], $CONF [ 'database_user' ], $CONF [ 'database_password' ]) or $error_text .= ( " <p />DEBUG INFORMATION:<br />Connect: " . mysqli_connect_error () . " $DEBUG_TEXT " );
if ( $link ) {
@ mysqli_query ( $link , " SET CHARACTER SET utf8 " );
@ mysqli_query ( $link , " SET COLLATION_CONNECTION='utf8_general_ci' " );
$success = @ mysqli_select_db ( $link , $CONF [ 'database_name' ]) or $error_text .= ( " <p />DEBUG INFORMATION:<br />MySQLi Select Database: " . mysqli_error ( $link ) . " $DEBUG_TEXT " );
}
2011-06-02 22:51:12 +02:00
} else {
2010-12-16 00:17:08 +01:00
$error_text .= " <p />DEBUG INFORMATION:<br />MySQL 4.1 functions not available! (php5-mysqli installed?)<br />database_type = 'mysqli' in config.inc.php, are you using a different database? $DEBUG_TEXT " ;
2009-01-15 13:24:36 +01:00
}
2013-11-16 01:00:53 +01:00
} elseif ( db_pgsql ()) {
2011-06-02 22:51:12 +02:00
if ( function_exists ( " pg_pconnect " )) {
2009-11-05 15:55:39 +01:00
if ( ! isset ( $CONF [ 'database_port' ])) {
$CONF [ 'database_port' ] = '5432' ;
}
2009-09-01 16:01:44 +02:00
$connect_string = " host= " . $CONF [ 'database_host' ] . " port= " . $CONF [ 'database_port' ] . " dbname= " . $CONF [ 'database_name' ] . " user= " . $CONF [ 'database_user' ] . " password= " . $CONF [ 'database_password' ];
2009-01-15 13:24:36 +01:00
$link = @ pg_pconnect ( $connect_string ) or $error_text .= ( " <p />DEBUG INFORMATION:<br />Connect: failed to connect to database. $DEBUG_TEXT " );
if ( $link ) pg_set_client_encoding ( $link , 'UNICODE' );
2011-06-02 22:51:12 +02:00
} else {
2010-12-16 00:17:08 +01:00
$error_text .= " <p />DEBUG INFORMATION:<br />PostgreSQL functions not available! (php5-pgsql installed?)<br />database_type = 'pgsql' in config.inc.php, are you using a different database? $DEBUG_TEXT " ;
2009-01-15 13:24:36 +01:00
}
2011-06-02 22:51:12 +02:00
} else {
2009-01-15 13:24:36 +01:00
$error_text = " <p />DEBUG INFORMATION:<br />Invalid \$ CONF['database_type']! Please fix your config.inc.php! $DEBUG_TEXT " ;
}
2011-06-02 22:51:12 +02:00
if ( $ignore_errors ) {
2009-01-15 13:24:36 +01:00
return array ( $link , $error_text );
2011-06-02 22:51:12 +02:00
} elseif ( $error_text != " " ) {
2009-01-15 13:24:36 +01:00
print $error_text ;
die ();
2011-06-02 22:51:12 +02:00
} elseif ( $link ) {
2009-01-15 13:24:36 +01:00
return $link ;
2011-06-02 22:51:12 +02:00
} else {
2009-01-15 13:24:36 +01:00
print " DEBUG INFORMATION:<br /> \n " ;
print " Connect: Unable to connect to database<br /> \n " ;
print " <br /> \n " ;
print " Make sure that you have set the correct database type in the config.inc.php file<br /> \n " ;
print $DEBUG_TEXT ;
die ();
}
2007-03-24 08:27:00 +01:00
}
2007-09-23 15:33:50 +02:00
/**
* Returns the appropriate boolean value for the database .
* Currently only PostgreSQL and MySQL are supported .
* @ param boolean $bool ( REQUIRED )
* @ return String or int as appropriate .
*/
function db_get_boolean ( $bool ) {
2011-10-19 17:25:33 +02:00
if ( ! ( is_bool ( $bool ) || $bool == '0' || $bool == '1' ) ) {
2014-05-12 01:09:18 +02:00
error_log ( " Invalid usage of 'db_get_boolean( $bool )' " );
2009-01-15 13:24:36 +01:00
die ( " Invalid usage of 'db_get_boolean( $bool )' " );
}
2013-11-16 01:00:53 +01:00
if ( db_pgsql ()) {
2009-01-15 13:24:36 +01:00
// return either true or false (unquoted strings)
if ( $bool ) {
2009-08-04 22:41:24 +02:00
return 't' ;
2009-01-15 13:24:36 +01:00
}
2009-08-04 22:41:24 +02:00
return 'f' ;
2013-11-16 01:00:53 +01:00
} elseif ( Config :: Read ( 'database_type' ) == 'mysql' || Config :: Read ( 'database_type' ) == 'mysqli' ) {
2009-01-15 13:24:36 +01:00
if ( $bool ) {
return 1 ;
}
return 0 ;
2011-10-17 00:19:55 +02:00
} else {
die ( 'Unknown value in $CONF[database_type]' );
}
}
2013-11-16 01:00:53 +01:00
/**
* returns true if PostgreSQL is used , false otherwise
*/
function db_pgsql () {
if ( Config :: Read ( 'database_type' ) == 'pgsql' ) {
return true ;
} else {
return false ;
}
}
2007-03-24 08:27:00 +01:00
//
// db_query
// Action: Sends a query to the database and returns query result and number of rows
// Call: db_query (string query)
2007-11-02 00:58:12 +01:00
// Optional parameter: $ignore_errors = TRUE, used by upgrade.php
2007-03-24 08:27:00 +01:00
//
2011-06-02 22:51:12 +02:00
function db_query ( $query , $ignore_errors = 0 ) {
2009-01-15 13:24:36 +01:00
global $CONF ;
global $DEBUG_TEXT ;
$result = " " ;
$number_rows = " " ;
static $link ;
$error_text = " " ;
if ( $ignore_errors ) $DEBUG_TEXT = " " ;
2012-05-13 23:09:03 +02:00
# mysql and pgsql $link are resources, mysqli $link is an object
if ( ! ( is_resource ( $link ) || is_object ( $link ) ) ) $link = db_connect ();
2009-01-15 13:24:36 +01:00
if ( $CONF [ 'database_type' ] == " mysql " ) $result = @ mysql_query ( $query , $link )
2013-11-18 23:57:37 +01:00
or $error_text = " Invalid query: " . mysql_error ( $link );
2009-01-15 13:24:36 +01:00
if ( $CONF [ 'database_type' ] == " mysqli " ) $result = @ mysqli_query ( $link , $query )
2013-11-18 23:57:37 +01:00
or $error_text = " Invalid query: " . mysqli_error ( $link );
2013-11-16 01:00:53 +01:00
if ( db_pgsql ()) {
2009-01-15 13:24:36 +01:00
$result = @ pg_query ( $link , $query )
2013-11-18 23:57:37 +01:00
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 ( " <p />DEBUG INFORMATION:<br /> $error_text <p>Check your error_log for the failed query. $DEBUG_TEXT " );
2009-01-15 13:24:36 +01:00
}
if ( $error_text == " " ) {
2011-06-02 22:51:12 +02:00
if ( preg_match ( " /^SELECT/i " , trim ( $query ))) {
2009-01-15 13:24:36 +01:00
// if $query was a SELECT statement check the number of rows with [database_type]_num_rows ().
if ( $CONF [ 'database_type' ] == " mysql " ) $number_rows = mysql_num_rows ( $result );
if ( $CONF [ 'database_type' ] == " mysqli " ) $number_rows = mysqli_num_rows ( $result );
2013-11-16 01:00:53 +01:00
if ( db_pgsql () ) $number_rows = pg_num_rows ( $result );
2011-06-02 22:51:12 +02:00
} else {
2009-01-15 13:24:36 +01:00
// if $query was something else, UPDATE, DELETE or INSERT check the number of rows with
// [database_type]_affected_rows ().
if ( $CONF [ 'database_type' ] == " mysql " ) $number_rows = mysql_affected_rows ( $link );
if ( $CONF [ 'database_type' ] == " mysqli " ) $number_rows = mysqli_affected_rows ( $link );
2013-11-16 01:00:53 +01:00
if ( db_pgsql () ) $number_rows = pg_affected_rows ( $result );
2009-01-15 13:24:36 +01:00
}
}
$return = array (
" result " => $result ,
" rows " => $number_rows ,
" error " => $error_text
);
return $return ;
2007-03-24 08:27:00 +01:00
}
// db_row
// Action: Returns a row from a table
// Call: db_row (int result)
2014-03-16 22:52:26 +01:00
2011-06-02 22:51:12 +02:00
function db_row ( $result ) {
2009-01-15 13:24:36 +01:00
global $CONF ;
$row = " " ;
if ( $CONF [ 'database_type' ] == " mysql " ) $row = mysql_fetch_row ( $result );
if ( $CONF [ 'database_type' ] == " mysqli " ) $row = mysqli_fetch_row ( $result );
2013-11-16 01:00:53 +01:00
if ( db_pgsql () ) $row = pg_fetch_row ( $result );
2009-01-15 13:24:36 +01:00
return $row ;
2007-03-24 08:27:00 +01:00
}
// db_array
// Action: Returns a row from a table
// Call: db_array (int result)
//
2011-06-02 22:51:12 +02:00
function db_array ( $result ) {
2009-01-15 13:24:36 +01:00
global $CONF ;
$row = " " ;
if ( $CONF [ 'database_type' ] == " mysql " ) $row = mysql_fetch_array ( $result );
if ( $CONF [ 'database_type' ] == " mysqli " ) $row = mysqli_fetch_array ( $result );
2013-11-16 01:00:53 +01:00
if ( db_pgsql () ) $row = pg_fetch_array ( $result );
2009-01-15 13:24:36 +01:00
return $row ;
2007-03-24 08:27:00 +01:00
}
// db_assoc
// Action: Returns a row from a table
// Call: db_assoc(int result)
//
2011-06-02 22:51:12 +02:00
function db_assoc ( $result ) {
2009-01-15 13:24:36 +01:00
global $CONF ;
$row = " " ;
if ( $CONF [ 'database_type' ] == " mysql " ) $row = mysql_fetch_assoc ( $result );
if ( $CONF [ 'database_type' ] == " mysqli " ) $row = mysqli_fetch_assoc ( $result );
2013-11-16 01:00:53 +01:00
if ( db_pgsql () ) $row = pg_fetch_assoc ( $result );
2009-01-15 13:24:36 +01:00
return $row ;
2007-03-24 08:27:00 +01:00
}
//
// db_delete
// Action: Deletes a row from a specified table
// Call: db_delete (string table, string where, string delete)
//
2011-11-27 22:24:29 +01:00
function db_delete ( $table , $where , $delete , $additionalwhere = '' ) {
2010-12-25 23:04:16 +01:00
$table = table_by_key ( $table );
2011-11-27 22:24:29 +01:00
$query = " DELETE FROM $table WHERE " . escape_string ( $where ) . " =' " . escape_string ( $delete ) . " ' " . $additionalwhere ;
2009-01-15 13:24:36 +01:00
$result = db_query ( $query );
2011-04-11 00:12:56 +02:00
if ( $result [ 'rows' ] >= 1 ) {
2009-01-15 13:24:36 +01:00
return $result [ 'rows' ];
2011-04-11 00:12:56 +02:00
} else {
return 0 ;
2009-01-15 13:24:36 +01:00
}
2007-03-24 08:27:00 +01:00
}
2007-11-03 20:03:43 +01:00
/**
* db_insert
* Action : Inserts a row from a specified table
2010-12-25 23:04:16 +01:00
* Call : db_insert ( string table , array values [, array timestamp ])
* @ param String - table name
* @ param array - key / value map of data to insert into the table .
* @ param array ( optional ) - array of fields to set to now () - default : array ( 'created' , 'modified' )
2007-11-04 01:50:09 +01:00
* @ return int - number of inserted rows
2007-11-03 20:03:43 +01:00
*/
2011-06-02 22:51:12 +02:00
function db_insert ( $table , $values , $timestamp = array ( 'created' , 'modified' ) ) {
2009-01-15 13:24:36 +01:00
$table = table_by_key ( $table );
2007-11-04 01:54:09 +01:00
2009-01-15 13:24:36 +01:00
foreach ( array_keys ( $values ) as $key ) {
$values [ $key ] = " ' " . escape_string ( $values [ $key ]) . " ' " ;
}
2007-11-04 01:50:09 +01:00
2009-01-15 13:24:36 +01:00
foreach ( $timestamp as $key ) {
$values [ $key ] = " now() " ;
}
2008-07-29 21:32:32 +02:00
2009-01-15 13:24:36 +01:00
$sql_values = " ( " . implode ( " , " , escape_string ( array_keys ( $values ))) . " ) VALUES ( " . implode ( " , " , $values ) . " ) " ;
2007-11-02 00:58:12 +01:00
2009-01-15 13:24:36 +01:00
$result = db_query ( " INSERT INTO $table $sql_values " );
return $result [ 'rows' ];
2007-11-04 01:50:09 +01:00
}
/**
* db_update
* Action : Updates a specified table
2010-12-31 21:13:53 +01:00
* Call : db_update ( string table , string where_col , string where_value , array values [, array timestamp ])
2010-12-25 23:04:16 +01:00
* @ param String - table name
2010-12-31 21:13:53 +01:00
* @ param String - column of WHERE condition
* @ param String - value of WHERE condition
2007-11-04 01:50:09 +01:00
* @ param array - key / value map of data to insert into the table .
2010-12-25 23:04:16 +01:00
* @ param array ( optional ) - array of fields to set to now () - default : array ( 'modified' )
2007-11-04 01:50:09 +01:00
* @ return int - number of updated rows
*/
2010-12-31 21:13:53 +01:00
function db_update ( $table , $where_col , $where_value , $values , $timestamp = array ( 'modified' ) ) {
$where = $where_col . " = ' " . escape_string ( $where_value ) . " ' " ;
2011-03-06 03:14:10 +01:00
return db_update_q ( $table , $where , $values , $timestamp );
2010-12-31 21:13:53 +01:00
}
/**
* db_update_q
* Action : Updates a specified table
* Call : db_update_q ( string table , string where , array values [, array timestamp ])
* @ param String - table name
* @ param String - WHERE condition ( as SQL )
* @ param array - key / value map of data to insert into the table .
* @ param array ( 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' ) ) {
2009-01-15 13:24:36 +01:00
$table = table_by_key ( $table );
2007-11-04 01:50:09 +01:00
2009-01-15 13:24:36 +01:00
foreach ( array_keys ( $values ) as $key ) {
$sql_values [ $key ] = escape_string ( $key ) . " =' " . escape_string ( $values [ $key ]) . " ' " ;
}
2007-11-04 01:50:09 +01:00
2009-01-15 13:24:36 +01:00
foreach ( $timestamp as $key ) {
$sql_values [ $key ] = escape_string ( $key ) . " =now() " ;
}
2007-11-04 01:50:09 +01:00
2009-01-15 13:24:36 +01:00
$sql = " UPDATE $table SET " . implode ( " , " , $sql_values ) . " WHERE $where " ;
2007-11-04 01:50:09 +01:00
2009-01-15 13:24:36 +01:00
$result = db_query ( $sql );
return $result [ 'rows' ];
2007-11-02 00:58:12 +01:00
}
2010-12-25 23:04:16 +01:00
/**
* db_begin / db_commit / db_rollback
* Action : BEGIN / COMMIT / ROLLBACK transaction ( PostgreSQL only ! )
* Call : db_begin ()
*/
function db_begin () {
2013-11-16 01:00:53 +01:00
if ( db_pgsql ()) { # TODO: also enable for mysql? (not supported by MyISAM, which is used for most tables)
2010-12-25 23:04:16 +01:00
db_query ( 'BEGIN' );
}
}
function db_commit () {
2013-11-16 01:00:53 +01:00
if ( db_pgsql ()) {
2010-12-25 23:04:16 +01:00
db_query ( 'COMMIT' );
}
}
function db_rollback () {
2013-11-16 01:00:53 +01:00
if ( db_pgsql ()) {
2010-12-25 23:04:16 +01:00
db_query ( 'ROLLBACK' );
}
}
2007-11-02 00:58:12 +01:00
2007-03-24 08:27:00 +01:00
2007-11-03 20:03:43 +01:00
/**
* db_log
* Action : Logs actions from admin
2011-02-15 23:20:27 +01:00
* Call : db_log ( string domain , string action , string data )
2014-03-16 22:52:26 +01:00
* Possible actions are defined in $LANG [ " pViewlog_action_ $action " ]
2007-09-28 22:28:18 +02:00
*/
2011-06-02 22:51:12 +02:00
function db_log ( $domain , $action , $data ) {
2010-09-27 01:14:42 +02:00
$REMOTE_ADDR = getRemoteAddr ();
2009-01-15 13:24:36 +01:00
2011-02-15 22:59:03 +01:00
$username = authentication_get_username ();
2014-03-16 22:52:26 +01:00
if ( Config :: Lang ( " pViewlog_action_ $action " ) == '' ) {
2009-01-15 13:24:36 +01:00
die ( " Invalid log action : $action " ); // could do with something better?
}
2013-06-06 22:53:37 +02:00
if ( Config :: bool ( 'logging' )) {
2010-12-25 23:04:16 +01:00
$logdata = array (
'username' => " $username ( $REMOTE_ADDR ) " ,
'domain' => $domain ,
'action' => $action ,
'data' => $data ,
);
$result = db_insert ( 'log' , $logdata , array ( 'timestamp' ) );
2010-12-25 23:59:11 +01:00
if ( $result != 1 ) {
2009-01-15 13:24:36 +01:00
return false ;
2010-12-25 23:59:11 +01:00
} else {
2009-01-15 13:24:36 +01:00
return true ;
}
}
2007-03-24 08:27:00 +01:00
}
2009-11-02 01:24:40 +01:00
/**
* db_in_clause
* Action : builds and returns the " field in(x, y) " clause for database queries
* Call : db_in_clause ( string field , array values )
*/
function db_in_clause ( $field , $values ) {
2009-11-05 15:55:39 +01:00
return " $field IN (' "
. implode ( " ',' " , escape_string ( array_values ( $values )))
. " ') " ;
2009-11-02 01:24:40 +01:00
}
2007-03-24 08:27:00 +01:00
2011-10-22 13:12:03 +02:00
/**
* db_where_clause
* Action : builds and returns a WHERE clause for database queries . All given conditions will be AND ' ed .
* Call : db_where_clause ( array $conditions , array $struct )
* param array $conditios : array ( 'field' => 'value' , 'field2' => ' value2 , ... )
* param array $struct - field structure , used for automatic bool conversion
*/
function db_where_clause ( $condition , $struct ) {
if ( ! is_array ( $condition )) {
die ( 'db_where_cond: parameter $cond is not an array!' );
} elseif ( count ( $condition ) == 0 ) {
die ( " db_where_cond: parameter is an empty array! " ); # die() might sound harsh, but can prevent information leaks
} elseif ( ! is_array ( $struct )) {
die ( 'db_where_cond: parameter $struct is not an array!' );
}
foreach ( $condition as $field => $value ) {
if ( isset ( $struct [ $field ]) && $struct [ $field ][ 'type' ] == 'bool' ) $value = db_get_boolean ( $value );
$parts [] = " $field =' " . escape_string ( $value ) . " ' " ;
}
2013-06-23 22:02:05 +02:00
$query = " WHERE ( " . join ( " AND " , $parts ) . " ) " ;
2011-10-22 13:12:03 +02:00
return $query ;
}
2007-03-24 08:27:00 +01:00
//
// table_by_key
// Action: Return table name for given key
// Call: table_by_key (string table_key)
//
2011-06-02 22:51:12 +02:00
function table_by_key ( $table_key ) {
2009-01-15 13:24:36 +01:00
global $CONF ;
2010-09-27 01:14:42 +02:00
if ( empty ( $CONF [ 'database_tables' ][ $table_key ])) {
$table = $table_key ;
} else {
$table = $CONF [ 'database_tables' ][ $table_key ];
}
return $CONF [ 'database_prefix' ] . $table ;
2007-03-24 08:27:00 +01:00
}
2008-05-21 23:05:48 +02:00
/*
Called after an alias_domain has been deleted in the DBMS .
Returns : boolean .
*/
2013-06-23 16:59:55 +02:00
# TODO: This function is never called
2011-06-02 22:51:12 +02:00
function alias_domain_postdeletion ( $alias_domain ) {
2009-01-15 13:24:36 +01:00
global $CONF ;
$confpar = 'alias_domain_postdeletion_script' ;
2011-06-02 22:51:12 +02:00
if ( ! isset ( $CONF [ $confpar ]) || empty ( $CONF [ $confpar ])) {
2009-01-15 13:24:36 +01:00
return true ;
}
2011-06-02 22:51:12 +02:00
if ( empty ( $alias_domain )) {
2009-01-15 13:24:36 +01:00
print '<p>Warning: empty alias_domain parameter.</p>' ;
return false ;
}
$cmdarg1 = escapeshellarg ( $alias_domain );
$command = $CONF [ $confpar ] . " $cmdarg1 " ;
$retval = 0 ;
$output = array ();
$firstline = '' ;
$firstline = exec ( $command , $output , $retval );
2011-06-02 22:51:12 +02:00
if ( 0 != $retval ) {
2009-01-15 13:24:36 +01:00
error_log ( " Running $command yielded return value= $retval , first line of output= $firstline " );
print '<p>WARNING: Problems running alias_domain postdeletion script!</p>' ;
return FALSE ;
}
return TRUE ;
2008-05-21 23:05:48 +02:00
}
2007-08-31 02:31:35 +02:00
//
// gen_show_status
// Action: Return a string of colored 's that indicate
// the if an alias goto has an error or is sent to
// addresses list in show_custom_domains
// Call: gen_show_status (string alias_address)
//
2011-06-02 22:51:12 +02:00
function gen_show_status ( $show_alias ) {
2013-12-08 20:41:01 +01:00
global $CONF ;
$table_alias = table_by_key ( 'alias' );
2009-01-15 13:24:36 +01:00
$stat_string = " " ;
2014-02-17 14:43:47 +01:00
$show_alias = escape_string ( $show_alias );
2009-01-15 13:24:36 +01:00
$stat_goto = " " ;
$stat_result = db_query ( " SELECT goto FROM $table_alias WHERE address=' $show_alias ' " );
2011-06-02 22:51:12 +02:00
if ( $stat_result [ 'rows' ] > 0 ) {
2009-01-15 13:24:36 +01:00
$row = db_row ( $stat_result [ 'result' ]);
$stat_goto = $row [ 0 ];
}
2011-06-03 00:53:40 +02:00
if ( ! empty ( $CONF [ 'recipient_delimiter' ])) {
$delimiter = preg_quote ( $CONF [ 'recipient_delimiter' ], " / " );
$delimiter_regex = '/' . $delimiter . '[^' . $delimiter . '@]*@/' ;
}
2009-01-15 13:24:36 +01:00
// UNDELIVERABLE CHECK
2011-06-02 22:51:12 +02:00
if ( $CONF [ 'show_undeliverable' ] == 'YES' ) {
2009-01-15 13:24:36 +01:00
$gotos = array ();
$gotos = explode ( ',' , $stat_goto );
$undel_string = " " ;
//make sure this alias goes somewhere known
$stat_ok = 1 ;
2011-06-02 22:51:12 +02:00
while ( ( $g = array_pop ( $gotos )) && $stat_ok ) {
2011-06-03 00:53:40 +02:00
list ( /*NULL*/ , $stat_domain ) = explode ( '@' , $g );
2009-05-03 19:23:48 +02:00
$stat_delimiter = " " ;
2009-11-05 15:55:39 +01:00
if ( ! empty ( $CONF [ 'recipient_delimiter' ])) {
2011-06-03 00:53:40 +02:00
$stat_delimiter = " OR address = ' " . preg_replace ( $delimiter_regex , " @ " , $g ) . " ' " ;
2009-11-05 15:55:39 +01:00
}
2011-06-03 00:53:40 +02:00
$stat_result = db_query ( " SELECT address FROM $table_alias WHERE address = ' $g ' OR address = '@ $stat_domain ' $stat_delimiter " );
2011-06-02 22:51:12 +02:00
if ( $stat_result [ 'rows' ] == 0 ) {
2009-01-15 13:24:36 +01:00
$stat_ok = 0 ;
2007-09-21 14:33:14 +02:00
}
2011-06-02 22:51:12 +02:00
if ( $stat_ok == 0 ) {
2011-06-03 00:53:40 +02:00
if ( $stat_domain == $CONF [ 'vacation_domain' ] || in_array ( $stat_domain , $CONF [ 'show_undeliverable_exceptions' ]) ) {
2009-01-15 13:24:36 +01:00
$stat_ok = 1 ;
}
2007-09-21 14:33:14 +02:00
}
2009-01-15 13:24:36 +01:00
} // while
2011-06-02 22:51:12 +02:00
if ( $stat_ok == 0 ) {
2009-01-15 13:24:36 +01:00
$stat_string .= " <span style='background-color: " . $CONF [ 'show_undeliverable_color' ] .
" '> " . $CONF [ 'show_status_text' ] . " </span> " ;
2011-06-02 22:51:12 +02:00
} else {
2007-09-21 14:33:14 +02:00
$stat_string .= $CONF [ 'show_status_text' ] . " " ;
2009-01-15 13:24:36 +01:00
}
2011-06-03 01:13:34 +02:00
}
2009-01-15 13:24:36 +01:00
// POP/IMAP CHECK
2011-06-02 22:51:12 +02:00
if ( $CONF [ 'show_popimap' ] == 'YES' ) {
2009-11-05 15:55:39 +01:00
$stat_delimiter = " " ;
if ( ! empty ( $CONF [ 'recipient_delimiter' ])) {
2011-06-03 00:53:40 +02:00
$stat_delimiter = ',' . preg_replace ( $delimiter_regex , " @ " , $stat_goto );
2009-11-05 15:55:39 +01:00
}
2009-05-14 21:16:00 +02:00
2009-01-15 13:24:36 +01:00
//if the address passed in appears in its own goto field, its POP/IMAP
2011-06-03 00:53:40 +02:00
# TODO: or not (might also be an alias loop) -> check mailbox table!
2011-06-02 22:51:12 +02:00
if ( preg_match ( '/,' . $show_alias . ',/' , ',' . $stat_goto . $stat_delimiter . ',' ) ) {
2009-01-15 13:24:36 +01:00
$stat_string .= " <span style='background-color: " . $CONF [ 'show_popimap_color' ] .
" '> " . $CONF [ 'show_status_text' ] . " </span> " ;
2011-06-02 22:51:12 +02:00
} else {
2009-01-15 13:24:36 +01:00
$stat_string .= $CONF [ 'show_status_text' ] . " " ;
}
}
// CUSTOM DESTINATION CHECK
2011-06-02 22:51:12 +02:00
if ( count ( $CONF [ 'show_custom_domains' ]) > 0 ) {
for ( $i = 0 ; $i < sizeof ( $CONF [ 'show_custom_domains' ]); $i ++ ) {
if ( preg_match ( '/^.*' . $CONF [ 'show_custom_domains' ][ $i ] . '.*$/' , $stat_goto )) {
2009-01-15 13:24:36 +01:00
$stat_string .= " <span style='background-color: " . $CONF [ 'show_custom_colors' ][ $i ] .
" '> " . $CONF [ 'show_status_text' ] . " </span> " ;
2011-06-02 22:51:12 +02:00
} else {
2009-01-15 13:24:36 +01:00
$stat_string .= $CONF [ 'show_status_text' ] . " " ;
}
}
2011-06-02 22:51:12 +02:00
} else {
2009-01-15 13:24:36 +01:00
$stat_string .= " ; " ;
}
2007-08-31 02:31:35 +02:00
2009-01-15 13:24:36 +01:00
// $stat_string .= "<span style='background-color:green'> </span> " .
// "<span style='background-color:blue'> </span> ";
return $stat_string ;
2007-08-31 02:31:35 +02:00
}
2010-09-27 01:14:42 +02:00
function getRemoteAddr () {
$REMOTE_ADDR = 'localhost' ;
if ( isset ( $_SERVER [ 'REMOTE_ADDR' ]))
$REMOTE_ADDR = $_SERVER [ 'REMOTE_ADDR' ];
return $REMOTE_ADDR ;
}
2007-10-07 19:23:29 +02:00
2009-02-09 20:11:43 +01:00
/* vim: set expandtab softtabstop=4 tabstop=4 shiftwidth=4: */