PostfixAdmin - web based virtual user administration interface for Postfix mail servers https://postfixadmin.github.io/postfixadmin/
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2220 lines
58 KiB

  1. <?php
  2. /**
  3. * Postfix Admin
  4. *
  5. * LICENSE
  6. * This source file is subject to the GPL license that is bundled with
  7. * this package in the file LICENSE.TXT.
  8. *
  9. * Further details on the project are available at :
  10. * http://www.postfixadmin.com or http://postfixadmin.sf.net
  11. *
  12. * @version $Id$
  13. * @license GNU GPL v2 or later.
  14. *
  15. * File: functions.inc.php
  16. * Contains re-usable code.
  17. */
  18. if (ereg ("functions.inc.php", $_SERVER['PHP_SELF']))
  19. {
  20. header ("Location: login.php");
  21. exit;
  22. }
  23. $version = '2.2.0';
  24. /**
  25. * check_session
  26. * Action: Check if a session already exists, if not redirect to login.php
  27. * Call: check_session ()
  28. * @return String username (e.g. foo@example.com)
  29. */
  30. function authentication_get_username()
  31. {
  32. global $CONF;
  33. if (!isset($_SESSION['sessid'])) {
  34. header ("Location: " . $CONF['postfix_admin_url'] . "/login.php");
  35. exit(0);
  36. }
  37. $SESSID_USERNAME = $_SESSION['sessid']['username'];
  38. return $SESSID_USERNAME;
  39. }
  40. /**
  41. * Returns the type of user - either 'user' or 'admin'
  42. * Returns false if neither (E.g. if not logged in)
  43. * @return String admin or user or (boolean) false.
  44. */
  45. function authentication_get_usertype() {
  46. if(isset($_SESSION['sessid'])) {
  47. if(isset($_SESSION['sessid']['type'])) {
  48. return $_SESSION['sessid']['type'];
  49. }
  50. }
  51. return false;
  52. }
  53. /**
  54. *
  55. * Used to determine whether a user has a particular role.
  56. * @param String role-name. (E.g. admin, global-admin or user)
  57. * @return boolean True if they have the requested role in their session.
  58. * Note, user < admin < global-admin
  59. */
  60. function authentication_has_role($role) {
  61. global $CONF;
  62. if(isset($_SESSION['sessid'])) {
  63. if(isset($_SESSION['sessid']['roles'])) {
  64. if(in_array($role, $_SESSION['sessid']['roles'])) {
  65. return true;
  66. }
  67. }
  68. }
  69. return false;
  70. }
  71. /**
  72. * Used to enforce that $user has a particular role when
  73. * viewing a page.
  74. * If they are lacking a role, redirect them to
  75. * $CONF['postfix_admin_url']/login.php
  76. *
  77. * Note, user < admin < global-admin
  78. */
  79. function authentication_require_role($role) {
  80. global $CONF;
  81. // redirect to appropriate page?
  82. if(authentication_has_role($role)) {
  83. return True;
  84. }
  85. header("Location: " . $CONF['postfix_admin_url'] . "/login.php");
  86. exit(0);
  87. }
  88. /**
  89. * @return boolean TRUE if a admin, FALSE otherwise.
  90. */
  91. function authentication_is_admin() {
  92. return authentication_get_usertype() == 'admin';
  93. }
  94. /**
  95. * @return boolean TRUE if a user, FALSE otherwise.
  96. */
  97. function authentication_is_user() {
  98. return authentication_get_usertype() == 'user';
  99. }
  100. /**
  101. * Add an error message for display on the next page that is rendered.
  102. * @param String message to show.
  103. *
  104. * Stores string in session. Flushed through header template.
  105. * @see _flash_string()
  106. */
  107. function flash_error($string) {
  108. _flash_string('error', $string);
  109. }
  110. /**
  111. * Used to display an info message on successful update.
  112. * @param String $string
  113. * Stores data in sessio.
  114. * @see _flash_string()
  115. */
  116. function flash_info($string) {
  117. _flash_string('info', $string);
  118. }
  119. /**
  120. * 'Private' method used for flash_info() and flash_error().
  121. */
  122. function _flash_string($type, $string) {
  123. if(!isset($_SESSION['flash'])) {
  124. $_SESSION['flash'] = array();
  125. }
  126. if(!isset($_SESSION['flash'][$type])) {
  127. $_SESSION['flash'][$type] = array();
  128. }
  129. $_SESSION['flash'][$type][] = $string;
  130. }
  131. //
  132. // check_language
  133. // Action: checks what language the browser uses
  134. // Call: check_language
  135. // Parameter: $use_post - set to 0 if $_POST should NOT be read
  136. //
  137. function check_language ($use_post = 1)
  138. {
  139. global $CONF;
  140. global $supported_languages; # from languages/languages.php
  141. $lang = $CONF['default_language'];
  142. if(isset($_SERVER['HTTP_ACCEPT_LANGUAGE']))
  143. {
  144. $lang_array = preg_split ('/(\s*,\s*)/', $_SERVER['HTTP_ACCEPT_LANGUAGE']);
  145. if (safecookie('lang')) {
  146. array_unshift($lang_array, safecookie('lang')); # prefer language from cookie
  147. }
  148. if ( $use_post && safepost('lang')) {
  149. array_unshift($lang_array, safepost('lang')); # but prefer $_POST['lang'] even more
  150. }
  151. for($i = 0; $i < count($lang_array); $i++)
  152. {
  153. $lang_next = $lang_array[$i];
  154. $lang_next = strtolower(trim($lang_next));
  155. if(array_key_exists($lang_next, $supported_languages))
  156. {
  157. $lang = $lang_next;
  158. break;
  159. }
  160. }
  161. }
  162. return $lang;
  163. }
  164. //
  165. // language_selector
  166. // Action: returns a language selector dropdown with the browser (or cookie) language preselected
  167. // Call: language_selector()
  168. //
  169. function language_selector()
  170. {
  171. global $supported_languages; # from languages/languages.php
  172. $current_lang = check_language();
  173. $selector = '<select name="lang" xml:lang="en" dir="ltr">';
  174. foreach($supported_languages as $lang => $lang_name) {
  175. if ($lang == $current_lang) {
  176. $selected = ' selected="selected"';
  177. } else {
  178. $selected = '';
  179. }
  180. $selector .= "<option value='$lang'$selected>$lang_name</option>";
  181. }
  182. $selector .= "</select>";
  183. return $selector;
  184. }
  185. //
  186. // check_string
  187. // Action: checks if a string is valid and returns TRUE if this is the case.
  188. // Call: check_string (string var)
  189. //
  190. function check_string ($var)
  191. {
  192. if (preg_match ('/^([A-Za-z0-9 ]+)+$/', $var))
  193. {
  194. return true;
  195. }
  196. else
  197. {
  198. return false;
  199. }
  200. }
  201. //
  202. // check_domain
  203. // Action: Checks if domain is valid and returns TRUE if this is the case.
  204. // Call: check_domain (string domain)
  205. //
  206. // TODO: make check_domain able to handle as example .local domains
  207. function check_domain ($domain)
  208. {
  209. global $CONF;
  210. global $PALANG;
  211. if (!preg_match ('/([-0-9A-Z]+\.)+' . '([0-9A-Z]){2,6}$/i', trim ($domain)))
  212. {
  213. flash_error(sprintf($PALANG['pInvalidDomainRegex'], htmlentities($domain)));
  214. return false;
  215. }
  216. if (isset($CONF['emailcheck_resolve_domain']) && 'YES' == $CONF['emailcheck_resolve_domain'] && 'WINDOWS'!=(strtoupper(substr(php_uname('s'), 0, 7))))
  217. {
  218. // Look for an AAAA, A, or MX record for the domain
  219. if(function_exists('checkdnsrr')) {
  220. // AAAA (IPv6) is only available in PHP v. >= 5
  221. if (version_compare(phpversion(), "5.0.0", ">="))
  222. {
  223. if (checkdnsrr($domain,'AAAA')) return true;
  224. }
  225. if (checkdnsrr($domain,'A')) return true;
  226. if (checkdnsrr($domain,'MX')) return true;
  227. flash_error(sprintf($PALANG['pInvalidDomainDNS'], htmlentities($domain)));
  228. return false;
  229. }
  230. else {
  231. flash_error("emailcheck_resolve_domain is enabled, but function (checkdnsrr) missing!");
  232. }
  233. }
  234. return true;
  235. }
  236. /**
  237. * check_email
  238. * Checks if an email is valid - if it is, return true, else false.
  239. * @param String $email - a string that may be an email address.
  240. * @return boolean true if it's an email address, else false.
  241. * TODO: make check_email able to handle already added domains
  242. */
  243. function check_email ($email)
  244. {
  245. global $CONF;
  246. $ce_email=$email;
  247. //strip the vacation domain out if we are using it
  248. //and change from blah#foo.com@autoreply.foo.com to blah@foo.com
  249. if ($CONF['vacation'] == 'YES')
  250. {
  251. $vacation_domain = $CONF['vacation_domain'];
  252. $ce_email = preg_replace("/@$vacation_domain/", '', $ce_email);
  253. $ce_email = preg_replace("/#/", '@', $ce_email);
  254. }
  255. // Perform non-domain-part sanity checks
  256. if (!preg_match ('/^[-!#$%&\'*+\\.\/0-9=?A-Z^_{|}~]+' . '@' . '[^@]+$/i', trim ($ce_email)))
  257. {
  258. flash_error($PALANG['pInvalidMailRegex']);
  259. return false;
  260. }
  261. // Determine domain name
  262. $matches=array();
  263. if (!preg_match('|@(.+)$|',$ce_email,$matches))
  264. {
  265. flash_error($PALANG['pInvalidMailRegex']);
  266. return false;
  267. }
  268. $domain=$matches[1];
  269. # check domain name
  270. return check_domain($domain);
  271. }
  272. /**
  273. * Clean a string, escaping any meta characters that could be
  274. * used to disrupt an SQL string. i.e. "'" => "\'" etc.
  275. *
  276. * @param String (or Array)
  277. * @return String (or Array) of cleaned data, suitable for use within an SQL
  278. * statement.
  279. */
  280. function escape_string ($string)
  281. {
  282. global $CONF;
  283. // if the string is actually an array, do a recursive cleaning.
  284. // Note, the array keys are not cleaned.
  285. if(is_array($string)) {
  286. $clean = array();
  287. foreach(array_keys($string) as $row) {
  288. $clean[$row] = escape_string($string[$row]);
  289. }
  290. return $clean;
  291. }
  292. if (get_magic_quotes_gpc ())
  293. {
  294. $string = stripslashes($string);
  295. }
  296. if (!is_numeric($string))
  297. {
  298. $link = db_connect();
  299. if ($CONF['database_type'] == "mysql")
  300. {
  301. $escaped_string = mysql_real_escape_string($string, $link);
  302. }
  303. if ($CONF['database_type'] == "mysqli")
  304. {
  305. $escaped_string = mysqli_real_escape_string($link, $string);
  306. }
  307. if ($CONF['database_type'] == "pgsql")
  308. {
  309. // php 5.2+ allows for $link to be specified.
  310. if (version_compare(phpversion(), "5.2.0", ">="))
  311. {
  312. $escaped_string = pg_escape_string($link, $string);
  313. }
  314. else
  315. {
  316. $escaped_string = pg_escape_string($string);
  317. }
  318. }
  319. }
  320. else
  321. {
  322. $escaped_string = $string;
  323. }
  324. return $escaped_string;
  325. }
  326. /**
  327. * safeget
  328. * Action: get value from $_GET[$param], or $default if $_GET[$param] is not set
  329. * Call: $param = safeget('param') # replaces $param = $_GET['param']
  330. * - or -
  331. * $param = safeget('param', 'default')
  332. *
  333. * @param String parameter name.
  334. * @param String (optional) - default value if key is not set.
  335. * @return String
  336. */
  337. function safeget ($param, $default="") {
  338. $retval=$default;
  339. if (isset($_GET[$param])) $retval=$_GET[$param];
  340. return $retval;
  341. }
  342. /**
  343. * safepost - similar to safeget()
  344. * @see safeget()
  345. * @param String parameter name
  346. * @param String (optional) default value (defaults to "")
  347. * @return String - value in $_POST[$param] or $default
  348. * same as safeget, but for $_POST
  349. */
  350. function safepost ($param, $default="") {
  351. $retval=$default;
  352. if (isset($_POST[$param])) $retval=$_POST[$param];
  353. return $retval;
  354. }
  355. /**
  356. * safeserver
  357. * @see safeget()
  358. * @param String $param
  359. * @param String $default (optional)
  360. * @return String value from $_SERVER[$param] or $default
  361. */
  362. function safeserver ($param, $default="") {
  363. $retval=$default;
  364. if (isset($_SERVER[$param])) $retval=$_SERVER[$param];
  365. return $retval;
  366. }
  367. /**
  368. * safecookie
  369. * @see safeget()
  370. * @param String $param
  371. * @param String $default (optional)
  372. * @return String value from $_COOKIE[$param] or $default
  373. */
  374. function safecookie ($param, $default="") {
  375. $retval=$default;
  376. if (isset($_COOKIE[$param])) $retval=$_COOKIE[$param];
  377. return $retval;
  378. }
  379. //
  380. // get_domain_properties
  381. // Action: Get all the properties of a domain.
  382. // Call: get_domain_properties (string domain)
  383. //
  384. function get_domain_properties ($domain)
  385. {
  386. global $CONF;
  387. global $table_alias, $table_mailbox, $table_domain;
  388. $list = array ();
  389. $result = db_query ("SELECT COUNT(*) FROM $table_alias WHERE domain='$domain'");
  390. $row = db_row ($result['result']);
  391. $list['alias_count'] = $row[0];
  392. $result = db_query ("SELECT COUNT(*) FROM $table_mailbox WHERE domain='$domain'");
  393. $row = db_row ($result['result']);
  394. $list['mailbox_count'] = $row[0];
  395. $result = db_query ("SELECT SUM(quota) FROM $table_mailbox WHERE domain='$domain'");
  396. $row = db_row ($result['result']);
  397. $list['quota_sum'] = $row[0];
  398. $list['alias_count'] = $list['alias_count'] - $list['mailbox_count'];
  399. $list['alias_pgindex']=array ();
  400. $list['mbox_pgindex']=array ();
  401. $list['mbox_pgindex_count'] = 0;
  402. //while loop to figure index names. use page_size and loop of queries
  403. $i=0;
  404. $current=0;
  405. $page_size = $CONF['page_size'];
  406. $tmpstr="";
  407. $idxlabel="";
  408. $list['alias_pgindex_count'] = 0;
  409. if ( $list['alias_count'] > $page_size )
  410. {
  411. while ( $current < $list['alias_count'] )
  412. {
  413. $limitSql=('pgsql'==$CONF['database_type']) ? "1 OFFSET $current" : "$current, 1";
  414. $query = "SELECT $table_alias.address FROM $table_alias LEFT JOIN $table_mailbox ON $table_alias.address=$table_mailbox.username WHERE $table_alias.domain='$domain' AND $table_mailbox.maildir IS NULL ORDER BY $table_alias.address LIMIT $limitSql";
  415. $result = db_query ("$query");
  416. $row = db_array ($result['result']);
  417. $tmpstr = $row['address'];
  418. //get first 2 chars
  419. $idxlabel = $tmpstr[0] . $tmpstr[1] . "-";
  420. ($current + $page_size - 1 <= $list['alias_count']) ? $current = $current + $page_size - 1 : $current = $list['alias_count'] - 1;
  421. $limitSql=('pgsql'==$CONF['database_type']) ? "1 OFFSET $current" : "$current, 1";
  422. $query = "SELECT $table_alias.address FROM $table_alias LEFT JOIN $table_mailbox ON $table_alias.address=$table_mailbox.username WHERE $table_alias.domain='$domain' AND $table_mailbox.maildir IS NULL ORDER BY $table_alias.address LIMIT $limitSql";
  423. $result = db_query ("$query");
  424. $row = db_array ($result['result']);
  425. $tmpstr = $row['address'];
  426. $idxlabel = $idxlabel . $tmpstr[0] . $tmpstr[1];
  427. $current = $current + 1;
  428. $list['alias_pgindex'][]=$idxlabel;
  429. $i++;
  430. }
  431. $list['alias_pgindex_count']=$i;
  432. }
  433. $i=0;
  434. $current=0;
  435. $page_size = $CONF['page_size'];
  436. $tmpstr="";
  437. $idxlabel="";
  438. if ( $list['mailbox_count'] > $page_size )
  439. {
  440. while ( $current < $list['mailbox_count'] )
  441. {
  442. $limitSql=('pgsql'==$CONF['database_type']) ? "1 OFFSET $current" : "$current, 1";
  443. $query = "SELECT $table_mailbox.username FROM $table_mailbox WHERE $table_mailbox.domain='$domain' ORDER BY $table_mailbox.username LIMIT $limitSql";
  444. $result = db_query ("$query");
  445. $row = db_array ($result['result']);
  446. $tmpstr = $row['username'];
  447. //get first 2 chars
  448. $idxlabel = $tmpstr[0] . $tmpstr[1] . "-";
  449. ($current + $page_size - 1 <= $list['mailbox_count']) ? $current = $current + $page_size - 1 : $current = $list['mailbox_count'] - 1;
  450. $limitSql=('pgsql'==$CONF['database_type']) ? "1 OFFSET $current" : "$current, 1";
  451. $query = "SELECT $table_mailbox.username FROM $table_mailbox WHERE $table_mailbox.domain='$domain' ORDER BY $table_mailbox.username LIMIT $limitSql";
  452. $result = db_query ("$query");
  453. $row = db_array ($result['result']);
  454. $tmpstr = $row['username'];
  455. $idxlabel = $idxlabel . $tmpstr[0] . $tmpstr[1];
  456. $current = $current + 1;
  457. $list['mbox_pgindex'][]=$idxlabel;
  458. $i++;
  459. }
  460. $list['mbox_pgindex_count']=$i;
  461. }
  462. // end mod
  463. $query="SELECT * FROM $table_domain WHERE domain='$domain'";
  464. if ('pgsql'==$CONF['database_type'])
  465. {
  466. $query=" SELECT *, EXTRACT(epoch FROM created) AS uts_created, EXTRACT(epoch FROM modified) AS uts_modified FROM $table_domain WHERE domain='$domain' ";
  467. }
  468. $result = db_query ($query);
  469. $row = db_array ($result['result']);
  470. $list['description'] = $row['description'];
  471. $list['aliases'] = $row['aliases'];
  472. $list['mailboxes'] = $row['mailboxes'];
  473. $list['maxquota'] = $row['maxquota'];
  474. $list['quota'] = $row['quota'];
  475. $list['transport'] = $row['transport'];
  476. $list['backupmx'] = $row['backupmx'];
  477. $list['created'] = $row['created'];
  478. $list['modified'] = $row['modified'];
  479. $list['active'] = $row['active'];
  480. if ($CONF['database_type'] == "pgsql")
  481. {
  482. $list['active']=('t'==$row['active']) ? 1 : 0;
  483. $list['backupmx']=('t'==$row['backupmx']) ? 1 : 0;
  484. $list['created']= gmstrftime('%c %Z',$row['uts_created']);
  485. $list['modified']= gmstrftime('%c %Z',$row['uts_modified']);
  486. }
  487. else
  488. {
  489. $list['active'] = $row['active'];
  490. $list['backupmx'] = $row['backupmx'];
  491. }
  492. return $list;
  493. }
  494. //
  495. // get_mailbox_properties
  496. // Action: Get all the properties of a mailbox.
  497. // Call: get_mailbox_properties (string mailbox)
  498. //
  499. function get_mailbox_properties ($username)
  500. {
  501. global $CONF;
  502. global $table_mailbox;
  503. $query="SELECT * FROM $table_mailbox WHERE username='$username'";
  504. if ('pgsql'==$CONF['database_type'])
  505. {
  506. $query="
  507. SELECT
  508. *,
  509. EXTRACT(epoch FROM created) AS uts_created,
  510. EXTRACT(epoch FROM modified) AS uts_modified
  511. FROM $table_mailbox
  512. WHERE username='$username'
  513. ";
  514. }
  515. $result = db_query ($query);
  516. $row = db_array ($result['result']);
  517. $list['name'] = $row['name'];
  518. $list['maildir'] = $row['maildir'];
  519. $list['quota'] = $row['quota'];
  520. $list['domain'] = $row['domain'];
  521. $list['created'] = $row['created'];
  522. $list['modified'] = $row['modified'];
  523. $list['active'] = $row['active'];
  524. if ($CONF['database_type'] == "pgsql")
  525. {
  526. $list['active']=('t'==$row['active']) ? 1 : 0;
  527. $list['created']= gmstrftime('%c %Z',$row['uts_created']);
  528. $list['modified']= gmstrftime('%c %Z',$row['uts_modified']);
  529. }
  530. else
  531. {
  532. $list['active'] = $row['active'];
  533. }
  534. return $list;
  535. }
  536. //
  537. // check_alias
  538. // Action: Checks if the domain is still able to create aliases.
  539. // Call: check_alias (string domain)
  540. //
  541. function check_alias ($domain)
  542. {
  543. $limit = get_domain_properties ($domain);
  544. if ($limit['aliases'] == 0)
  545. {
  546. return true;
  547. }
  548. if ($limit['aliases'] < 0)
  549. {
  550. return false;
  551. }
  552. if ($limit['alias_count'] >= $limit['aliases'])
  553. {
  554. return false;
  555. }
  556. else
  557. {
  558. return true;
  559. }
  560. }
  561. //
  562. // check_mailbox
  563. // Action: Checks if the domain is still able to create mailboxes.
  564. // Call: check_mailbox (string domain)
  565. //
  566. function check_mailbox ($domain)
  567. {
  568. $limit = get_domain_properties ($domain);
  569. if ($limit['mailboxes'] == 0)
  570. {
  571. return true;
  572. }
  573. if ($limit['mailboxes'] < 0)
  574. {
  575. return false;
  576. }
  577. if ($limit['mailbox_count'] >= $limit['mailboxes'])
  578. {
  579. return false;
  580. }
  581. else
  582. {
  583. return true;
  584. }
  585. }
  586. //
  587. // check_quota
  588. // Action: Checks if the user is creating a mailbox with the correct quota
  589. // Call: check_quota (string domain)
  590. //
  591. function check_quota ($quota, $domain)
  592. {
  593. $limit = get_domain_properties ($domain);
  594. if ($limit['maxquota'] == 0)
  595. {
  596. return true;
  597. }
  598. if (($limit['maxquota'] < 0) and ($quota < 0))
  599. {
  600. return true;
  601. }
  602. if (($limit['maxquota'] > 0) and ($quota == 0))
  603. {
  604. return false;
  605. }
  606. if ($quota > $limit['maxquota'])
  607. {
  608. return false;
  609. }
  610. else
  611. {
  612. return true;
  613. }
  614. }
  615. //
  616. // multiply_quota
  617. // Action: Recalculates the quota from bytes to MBs (multiply, *)
  618. // Call: multiply_quota (string $quota)
  619. //
  620. function multiply_quota ($quota)
  621. {
  622. global $CONF;
  623. if ($quota == -1) return $quota;
  624. $value = $quota * $CONF['quota_multiplier'];
  625. return $value;
  626. }
  627. //
  628. // divide_quota
  629. // Action: Recalculates the quota from MBs to bytes (divide, /)
  630. // Call: divide_quota (string $quota)
  631. //
  632. function divide_quota ($quota)
  633. {
  634. global $CONF;
  635. if ($quota == -1) return $quota;
  636. $value = $quota / $CONF['quota_multiplier'];
  637. return $value;
  638. }
  639. //
  640. // check_owner
  641. // Action: Checks if the admin is the owner of the domain (or global-admin)
  642. // Call: check_owner (string admin, string domain)
  643. //
  644. function check_owner ($username, $domain)
  645. {
  646. global $table_domain_admins;
  647. $result = db_query ("SELECT 1 FROM $table_domain_admins WHERE username='$username' AND (domain='$domain' OR domain='ALL') AND active='1'");
  648. if ($result['rows'] != 1)
  649. {
  650. return false;
  651. }
  652. else
  653. {
  654. return true;
  655. }
  656. }
  657. //
  658. // check_alias_owner
  659. // Action: Checks if the admin is the owner of the alias.
  660. // Call: check_alias_owner (string admin, string alias)
  661. //
  662. function check_alias_owner ($username, $alias)
  663. {
  664. global $CONF;
  665. if (authentication_has_role('global-admin')) return true;
  666. $tmp = preg_split('/\@/', $alias);
  667. if (($CONF['special_alias_control'] == 'NO') && array_key_exists($tmp[0], $CONF['default_aliases']))
  668. {
  669. return false;
  670. }
  671. else
  672. {
  673. return true;
  674. }
  675. }
  676. /**
  677. * List domains for an admin user.
  678. * @param String $username
  679. * @return array of domain names.
  680. */
  681. function list_domains_for_admin ($username)
  682. {
  683. global $CONF;
  684. global $table_domain, $table_domain_admins;
  685. $list = array ();
  686. // does $username need escaping here?
  687. $active_sql = db_get_boolean(True);
  688. $backupmx_sql = db_get_boolean(False);
  689. $query = "SELECT $table_domain.domain, $table_domain_admins.username FROM $table_domain
  690. LEFT JOIN $table_domain_admins ON $table_domain.domain=$table_domain_admins.domain
  691. WHERE $table_domain_admins.username='$username'
  692. AND $table_domain.active=$active_sql
  693. AND $table_domain.backupmx=$backupmx_sql
  694. ORDER BY $table_domain_admins.domain";
  695. $result = db_query ($query);
  696. if ($result['rows'] > 0)
  697. {
  698. $i = 0;
  699. while ($row = db_array ($result['result']))
  700. {
  701. $list[$i] = $row['domain'];
  702. $i++;
  703. }
  704. }
  705. return $list;
  706. }
  707. //
  708. // list_domains
  709. // Action: List all available domains.
  710. // Call: list_domains ()
  711. //
  712. function list_domains ()
  713. {
  714. global $table_domain;
  715. $list = array();
  716. $result = db_query ("SELECT domain FROM $table_domain WHERE domain!='ALL' ORDER BY domain");
  717. if ($result['rows'] > 0)
  718. {
  719. $i = 0;
  720. while ($row = db_array ($result['result']))
  721. {
  722. $list[$i] = $row['domain'];
  723. $i++;
  724. }
  725. }
  726. return $list;
  727. }
  728. //
  729. // admin_exist
  730. // Action: Checks if the admin already exists.
  731. // Call: admin_exist (string admin)
  732. //
  733. function admin_exist ($username)
  734. {
  735. $result = db_query ("SELECT 1 FROM " . table_by_key ('admin') . " WHERE username='$username'");
  736. if ($result['rows'] != 1)
  737. {
  738. return false;
  739. }
  740. else
  741. {
  742. return true;
  743. }
  744. }
  745. //
  746. // domain_exist
  747. // Action: Checks if the domain already exists.
  748. // Call: domain_exist (string domain)
  749. //
  750. function domain_exist ($domain)
  751. {
  752. global $table_domain;
  753. $result = db_query("SELECT 1 FROM $table_domain WHERE domain='$domain'");
  754. if ($result['rows'] != 1)
  755. {
  756. return false;
  757. }
  758. else
  759. {
  760. return true;
  761. }
  762. }
  763. //
  764. // list_admins
  765. // Action: Lists all the admins
  766. // Call: list_admins ()
  767. //
  768. // was admin_list_admins
  769. //
  770. function list_admins ()
  771. {
  772. global $table_admin;
  773. $list = "";
  774. $result = db_query ("SELECT username FROM $table_admin ORDER BY username");
  775. if ($result['rows'] > 0)
  776. {
  777. $i = 0;
  778. while ($row = db_array ($result['result']))
  779. {
  780. $list[$i] = $row['username'];
  781. $i++;
  782. }
  783. }
  784. return $list;
  785. }
  786. //
  787. // get_admin_properties
  788. // Action: Get all the admin properties.
  789. // Call: get_admin_properties (string admin)
  790. //
  791. function get_admin_properties ($username)
  792. {
  793. global $CONF;
  794. global $table_admin, $table_domain_admins;
  795. $list = array ();
  796. $result = db_query ("SELECT * FROM $table_domain_admins WHERE username='$username' AND domain='ALL'");
  797. if ($result['rows'] == 1)
  798. {
  799. $list['domain_count'] = 'ALL';
  800. }
  801. else
  802. {
  803. $result = db_query ("SELECT COUNT(*) FROM $table_domain_admins WHERE username='$username'");
  804. $row = db_row ($result['result']);
  805. $list['domain_count'] = $row[0];
  806. }
  807. $query = "SELECT * FROM $table_admin WHERE username='$username'";
  808. if ('pgsql'==$CONF['database_type']) {
  809. $query="
  810. SELECT
  811. *,
  812. EXTRACT(epoch FROM created) AS uts_created,
  813. EXTRACT (epoch FROM modified) AS uts_modified
  814. FROM $table_admin
  815. WHERE username='$username'
  816. ";
  817. }
  818. $result = db_query ($query);
  819. $row = db_array ($result['result']);
  820. $list['created'] = $row['created'];
  821. $list['modified'] = $row['modified'];
  822. $list['active'] = $row['active'];
  823. if ('pgsql'==$CONF['database_type']) {
  824. $list['active'] = ('t'==$row['active']) ? 1 : 0;
  825. $list['created']= gmstrftime('%c %Z',$row['uts_created']);
  826. $list['modified']= gmstrftime('%c %Z',$row['uts_modified']);
  827. }
  828. return $list;
  829. }
  830. //
  831. // encode_header
  832. // Action: Encode a string according to RFC 1522 for use in headers if it contains 8-bit characters.
  833. // Call: encode_header (string header, string charset)
  834. //
  835. function encode_header ($string, $default_charset = "utf-8")
  836. {
  837. if (strtolower ($default_charset) == 'iso-8859-1')
  838. {
  839. $string = str_replace ("\240",' ',$string);
  840. }
  841. $j = strlen ($string);
  842. $max_l = 75 - strlen ($default_charset) - 7;
  843. $aRet = array ();
  844. $ret = '';
  845. $iEncStart = $enc_init = false;
  846. $cur_l = $iOffset = 0;
  847. for ($i = 0; $i < $j; ++$i)
  848. {
  849. switch ($string{$i})
  850. {
  851. case '=':
  852. case '<':
  853. case '>':
  854. case ',':
  855. case '?':
  856. case '_':
  857. if ($iEncStart === false)
  858. {
  859. $iEncStart = $i;
  860. }
  861. $cur_l+=3;
  862. if ($cur_l > ($max_l-2))
  863. {
  864. $aRet[] = substr ($string,$iOffset,$iEncStart-$iOffset);
  865. $aRet[] = "=?$default_charset?Q?$ret?=";
  866. $iOffset = $i;
  867. $cur_l = 0;
  868. $ret = '';
  869. $iEncStart = false;
  870. }
  871. else
  872. {
  873. $ret .= sprintf ("=%02X",ord($string{$i}));
  874. }
  875. break;
  876. case '(':
  877. case ')':
  878. if ($iEncStart !== false)
  879. {
  880. $aRet[] = substr ($string,$iOffset,$iEncStart-$iOffset);
  881. $aRet[] = "=?$default_charset?Q?$ret?=";
  882. $iOffset = $i;
  883. $cur_l = 0;
  884. $ret = '';
  885. $iEncStart = false;
  886. }
  887. break;
  888. case ' ':
  889. if ($iEncStart !== false)
  890. {
  891. $cur_l++;
  892. if ($cur_l > $max_l)
  893. {
  894. $aRet[] = substr ($string,$iOffset,$iEncStart-$iOffset);
  895. $aRet[] = "=?$default_charset?Q?$ret?=";
  896. $iOffset = $i;
  897. $cur_l = 0;
  898. $ret = '';
  899. $iEncStart = false;
  900. }
  901. else
  902. {
  903. $ret .= '_';
  904. }
  905. }
  906. break;
  907. default:
  908. $k = ord ($string{$i});
  909. if ($k > 126)
  910. {
  911. if ($iEncStart === false)
  912. {
  913. // do not start encoding in the middle of a string, also take the rest of the word.
  914. $sLeadString = substr ($string,0,$i);
  915. $aLeadString = explode (' ',$sLeadString);
  916. $sToBeEncoded = array_pop ($aLeadString);
  917. $iEncStart = $i - strlen ($sToBeEncoded);
  918. $ret .= $sToBeEncoded;
  919. $cur_l += strlen ($sToBeEncoded);
  920. }
  921. $cur_l += 3;
  922. // first we add the encoded string that reached it's max size
  923. if ($cur_l > ($max_l-2))
  924. {
  925. $aRet[] = substr ($string,$iOffset,$iEncStart-$iOffset);
  926. $aRet[] = "=?$default_charset?Q?$ret?= ";
  927. $cur_l = 3;
  928. $ret = '';
  929. $iOffset = $i;
  930. $iEncStart = $i;
  931. }
  932. $enc_init = true;
  933. $ret .= sprintf ("=%02X", $k);
  934. }
  935. else
  936. {
  937. if ($iEncStart !== false)
  938. {
  939. $cur_l++;
  940. if ($cur_l > $max_l)
  941. {
  942. $aRet[] = substr ($string,$iOffset,$iEncStart-$iOffset);
  943. $aRet[] = "=?$default_charset?Q?$ret?=";
  944. $iEncStart = false;
  945. $iOffset = $i;
  946. $cur_l = 0;
  947. $ret = '';
  948. }
  949. else
  950. {
  951. $ret .= $string{$i};
  952. }
  953. }
  954. }
  955. break;
  956. }
  957. }
  958. if ($enc_init)
  959. {
  960. if ($iEncStart !== false)
  961. {
  962. $aRet[] = substr ($string,$iOffset,$iEncStart-$iOffset);
  963. $aRet[] = "=?$default_charset?Q?$ret?=";
  964. }
  965. else
  966. {
  967. $aRet[] = substr ($string,$iOffset);
  968. }
  969. $string = implode ('',$aRet);
  970. }
  971. return $string;
  972. }
  973. //
  974. // generate_password
  975. // Action: Generates a random password
  976. // Call: generate_password ()
  977. //
  978. function generate_password ()
  979. {
  980. $password = substr (md5 (mt_rand ()), 0, 8);
  981. return $password;
  982. }
  983. //
  984. // pacrypt
  985. // Action: Encrypts password based on config settings
  986. // Call: pacrypt (string cleartextpassword)
  987. //
  988. function pacrypt ($pw, $pw_db="")
  989. {
  990. global $CONF;
  991. $pw = stripslashes($pw);
  992. $password = "";
  993. $salt = "";
  994. if ($CONF['encrypt'] == 'md5crypt') {
  995. $split_salt = preg_split ('/\$/', $pw_db);
  996. if (isset ($split_salt[2])) {
  997. $salt = $split_salt[2];
  998. }
  999. $password = md5crypt ($pw, $salt);
  1000. }
  1001. if ($CONF['encrypt'] == 'md5') {
  1002. $password = md5($pw);
  1003. }
  1004. if ($CONF['encrypt'] == 'system') {
  1005. if (ereg ("\$1\$", $pw_db)) {
  1006. $split_salt = preg_split ('/\$/', $pw_db);
  1007. $salt = $split_salt[2];
  1008. }
  1009. else {
  1010. if (strlen($pw_db) == 0) {
  1011. $salt = substr (md5 (mt_rand ()), 0, 2);
  1012. }
  1013. else {
  1014. $salt = substr ($pw_db, 0, 2);
  1015. }
  1016. }
  1017. $password = crypt ($pw, $salt);
  1018. }
  1019. if ($CONF['encrypt'] == 'cleartext') {
  1020. $password = $pw;
  1021. }
  1022. $password = escape_string ($password);
  1023. return $password;
  1024. }
  1025. //
  1026. // md5crypt
  1027. // Action: Creates MD5 encrypted password
  1028. // Call: md5crypt (string cleartextpassword)
  1029. //
  1030. function md5crypt ($pw, $salt="", $magic="")
  1031. {
  1032. $MAGIC = "$1$";
  1033. if ($magic == "") $magic = $MAGIC;
  1034. if ($salt == "") $salt = create_salt ();
  1035. $slist = explode ("$", $salt);
  1036. if ($slist[0] == "1") $salt = $slist[1];
  1037. $salt = substr ($salt, 0, 8);
  1038. $ctx = $pw . $magic . $salt;
  1039. $final = hex2bin (md5 ($pw . $salt . $pw));
  1040. for ($i=strlen ($pw); $i>0; $i-=16)
  1041. {
  1042. if ($i > 16)
  1043. {
  1044. $ctx .= substr ($final,0,16);
  1045. }
  1046. else
  1047. {
  1048. $ctx .= substr ($final,0,$i);
  1049. }
  1050. }
  1051. $i = strlen ($pw);
  1052. while ($i > 0)
  1053. {
  1054. if ($i & 1) $ctx .= chr (0);
  1055. else $ctx .= $pw[0];
  1056. $i = $i >> 1;
  1057. }
  1058. $final = hex2bin (md5 ($ctx));
  1059. for ($i=0;$i<1000;$i++)
  1060. {
  1061. $ctx1 = "";
  1062. if ($i & 1)
  1063. {
  1064. $ctx1 .= $pw;
  1065. }
  1066. else
  1067. {
  1068. $ctx1 .= substr ($final,0,16);
  1069. }
  1070. if ($i % 3) $ctx1 .= $salt;
  1071. if ($i % 7) $ctx1 .= $pw;
  1072. if ($i & 1)
  1073. {
  1074. $ctx1 .= substr ($final,0,16);
  1075. }
  1076. else
  1077. {
  1078. $ctx1 .= $pw;
  1079. }
  1080. $final = hex2bin (md5 ($ctx1));
  1081. }
  1082. $passwd = "";
  1083. $passwd .= to64 (((ord ($final[0]) << 16) | (ord ($final[6]) << 8) | (ord ($final[12]))), 4);
  1084. $passwd .= to64 (((ord ($final[1]) << 16) | (ord ($final[7]) << 8) | (ord ($final[13]))), 4);
  1085. $passwd .= to64 (((ord ($final[2]) << 16) | (ord ($final[8]) << 8) | (ord ($final[14]))), 4);
  1086. $passwd .= to64 (((ord ($final[3]) << 16) | (ord ($final[9]) << 8) | (ord ($final[15]))), 4);
  1087. $passwd .= to64 (((ord ($final[4]) << 16) | (ord ($final[10]) << 8) | (ord ($final[5]))), 4);
  1088. $passwd .= to64 (ord ($final[11]), 2);
  1089. return "$magic$salt\$$passwd";
  1090. }
  1091. function create_salt ()
  1092. {
  1093. srand ((double) microtime ()*1000000);
  1094. $salt = substr (md5 (rand (0,9999999)), 0, 8);
  1095. return $salt;
  1096. }
  1097. function hex2bin ($str)
  1098. {
  1099. $len = strlen ($str);
  1100. $nstr = "";
  1101. for ($i=0;$i<$len;$i+=2)
  1102. {
  1103. $num = sscanf (substr ($str,$i,2), "%x");
  1104. $nstr.=chr ($num[0]);
  1105. }
  1106. return $nstr;
  1107. }
  1108. function to64 ($v, $n)
  1109. {
  1110. $ITOA64 = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
  1111. $ret = "";
  1112. while (($n - 1) >= 0)
  1113. {
  1114. $n--;
  1115. $ret .= $ITOA64[$v & 0x3f];
  1116. $v = $v >> 6;
  1117. }
  1118. return $ret;
  1119. }
  1120. //
  1121. // smtp_mail
  1122. // Action: Sends email to new account.
  1123. // Call: smtp_mail (string To, string From, string Data)
  1124. //
  1125. function smtp_mail ($to, $from, $data)
  1126. {
  1127. global $CONF;
  1128. $smtpd_server = $CONF['smtp_server'];
  1129. $smtpd_port = $CONF['smtp_port'];
  1130. $smtp_server = $_SERVER["SERVER_NAME"];
  1131. $errno = "0";
  1132. $errstr = "0";
  1133. $timeout = "30";
  1134. $fh = @fsockopen ($smtpd_server, $smtpd_port, $errno, $errstr, $timeout);
  1135. if (!$fh)
  1136. {
  1137. return false;
  1138. }
  1139. else
  1140. {
  1141. fputs ($fh, "EHLO $smtp_server\r\n");
  1142. $res = smtp_get_response($fh);
  1143. fputs ($fh, "MAIL FROM:<$from>\r\n");
  1144. $res = smtp_get_response($fh);
  1145. fputs ($fh, "RCPT TO:<$to>\r\n");
  1146. $res = smtp_get_response($fh);
  1147. fputs ($fh, "DATA\r\n");
  1148. $res = smtp_get_response($fh);
  1149. fputs ($fh, "$data\r\n.\r\n");
  1150. $res = smtp_get_response($fh);
  1151. fputs ($fh, "QUIT\r\n");
  1152. $res = smtp_get_response($fh);
  1153. fclose ($fh);
  1154. }
  1155. return true;
  1156. }
  1157. //
  1158. // smtp_get_response
  1159. // Action: Get response from mail server
  1160. // Call: smtp_get_response (string FileHandle)
  1161. //
  1162. function smtp_get_response ($fh)
  1163. {
  1164. $res ='';
  1165. do
  1166. {
  1167. $line = fgets($fh, 256);
  1168. $res .= $line;
  1169. }
  1170. while (preg_match("/^\d\d\d\-/", $line));
  1171. return $res;
  1172. }
  1173. $DEBUG_TEXT = "\n
  1174. <p />\n
  1175. Please check the documentation and website for more information.\n
  1176. <p />\n
  1177. <a href=\"http://postfixadmin.sf.net/\">Postfix Admin</a><br />\n
  1178. <a href='https://sourceforge.net/forum/forum.php?forum_id=676076'>Forums</a>
  1179. ";
  1180. /**
  1181. * db_connect
  1182. * Action: Makes a connection to the database if it doesn't exist
  1183. * Call: db_connect ()
  1184. * Optional parameter: $ignore_errors = TRUE, used by setup.php
  1185. *
  1186. * Return value:
  1187. * a) without $ignore_errors or $ignore_errors == 0
  1188. * - $link - the database connection -OR-
  1189. * - call die() in case of connection problems
  1190. * b) with $ignore_errors == TRUE
  1191. * array($link, $error_text);
  1192. */
  1193. function db_connect ($ignore_errors = 0)
  1194. {
  1195. global $CONF;
  1196. global $DEBUG_TEXT;
  1197. if ($ignore_errors != 0) $DEBUG_TEXT = '';
  1198. $error_text = '';
  1199. $link = 0;
  1200. if ($CONF['database_type'] == "mysql")
  1201. {
  1202. if (function_exists ("mysql_connect"))
  1203. {
  1204. $link = @mysql_connect ($CONF['database_host'], $CONF['database_user'], $CONF['database_password']) or $error_text .= ("<p />DEBUG INFORMATION:<br />Connect: " . mysql_error () . "$DEBUG_TEXT");
  1205. if ($link) {
  1206. @mysql_query("SET CHARACTER SET utf8",$link);
  1207. @mysql_query("SET COLLATION_CONNECTION='utf8_general_ci'",$link);
  1208. $succes = @mysql_select_db ($CONF['database_name'], $link) or $error_text .= ("<p />DEBUG INFORMATION:<br />MySQL Select Database: " . mysql_error () . "$DEBUG_TEXT");
  1209. }
  1210. }
  1211. else
  1212. {
  1213. $error_text .= "<p />DEBUG INFORMATION:<br />MySQL 3.x / 4.0 functions not available!<br />database_type = 'mysql' in config.inc.php, are you using a different database? $DEBUG_TEXT";
  1214. }
  1215. }
  1216. elseif ($CONF['database_type'] == "mysqli")
  1217. {
  1218. if (function_exists ("mysqli_connect"))
  1219. {
  1220. $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");
  1221. if ($link) {
  1222. @mysqli_query($link,"SET CHARACTER SET utf8");
  1223. @mysqli_query($link,"SET COLLATION_CONNECTION='utf8_general_ci'");
  1224. $success = @mysqli_select_db ($link, $CONF['database_name']) or $error_text .= ("<p />DEBUG INFORMATION:<br />MySQLi Select Database: " . mysqli_error ($link) . "$DEBUG_TEXT");
  1225. }
  1226. }
  1227. else
  1228. {
  1229. $error_text .= "<p />DEBUG INFORMATION:<br />MySQL 4.1 functions not available!<br />database_type = 'mysqli' in config.inc.php, are you using a different database? $DEBUG_TEXT";
  1230. }
  1231. }
  1232. elseif ($CONF['database_type'] == "pgsql")
  1233. {
  1234. if (function_exists ("pg_pconnect"))
  1235. {
  1236. $connect_string = "host=" . $CONF['database_host'] . " dbname=" . $CONF['database_name'] . " user=" . $CONF['database_user'] . " password=" . $CONF['database_password'];
  1237. $link = @pg_pconnect ($connect_string) or $error_text .= ("<p />DEBUG INFORMATION:<br />Connect: failed to connect to database. $DEBUG_TEXT");
  1238. if ($link) pg_set_client_encoding($link, 'UNICODE');
  1239. }
  1240. else
  1241. {
  1242. $error_text .= "<p />DEBUG INFORMATION:<br />PostgreSQL functions not available!<br />database_type = 'pgsql' in config.inc.php, are you using a different database? $DEBUG_TEXT";
  1243. }
  1244. }
  1245. else
  1246. {
  1247. $error_text = "<p />DEBUG INFORMATION:<br />Invalid \$CONF['database_type']! Please fix your config.inc.php! $DEBUG_TEXT";
  1248. }
  1249. if ($ignore_errors)
  1250. {
  1251. return array($link, $error_text);
  1252. }
  1253. elseif ($error_text != "")
  1254. {
  1255. print $error_text;
  1256. die();
  1257. }
  1258. elseif ($link)
  1259. {
  1260. return $link;
  1261. }
  1262. else
  1263. {
  1264. print "DEBUG INFORMATION:<br />\n";
  1265. print "Connect: Unable to connect to database<br />\n";
  1266. print "<br />\n";
  1267. print "Make sure that you have set the correct database type in the config.inc.php file<br />\n";
  1268. print $DEBUG_TEXT;
  1269. die();
  1270. }
  1271. }
  1272. /**
  1273. * Returns the appropriate boolean value for the database.
  1274. * Currently only PostgreSQL and MySQL are supported.
  1275. * @param boolean $bool (REQUIRED)
  1276. * @return String or int as appropriate.
  1277. */
  1278. function db_get_boolean($bool) {
  1279. if(!is_bool($bool)) {
  1280. die("Invalid usage of 'db_get_boolean($bool)'");
  1281. }
  1282. global $CONF;
  1283. if($CONF['database_type']=='pgsql') {
  1284. // return either true or false (unquoted strings)
  1285. if($bool) {
  1286. return 'true';
  1287. }
  1288. return 'false';
  1289. }
  1290. elseif($CONF['database_type'] == 'mysql' || $CONF['database_type'] == 'mysqli') {
  1291. if($bool) {
  1292. return 1;
  1293. }
  1294. return 0;
  1295. }
  1296. }
  1297. //
  1298. // db_query
  1299. // Action: Sends a query to the database and returns query result and number of rows
  1300. // Call: db_query (string query)
  1301. // Optional parameter: $ignore_errors = TRUE, used by upgrade.php
  1302. //
  1303. function db_query ($query, $ignore_errors = 0)
  1304. {
  1305. global $CONF;
  1306. global $DEBUG_TEXT;
  1307. $result = "";
  1308. $number_rows = "";
  1309. static $link;
  1310. $error_text = "";
  1311. if ($ignore_errors) $DEBUG_TEXT = "";
  1312. if (!is_resource($link)) $link = db_connect ();
  1313. if ($CONF['database_type'] == "mysql") $result = @mysql_query ($query, $link)
  1314. or $error_text = "<p />DEBUG INFORMATION:<br />Invalid query: " . mysql_error($link) . "$DEBUG_TEXT";
  1315. if ($CONF['database_type'] == "mysqli") $result = @mysqli_query ($link, $query)
  1316. or $error_text = "<p />DEBUG INFORMATION:<br />Invalid query: " . mysqli_error($link) . "$DEBUG_TEXT";
  1317. if ($CONF['database_type'] == "pgsql")
  1318. {
  1319. $result = @pg_query ($link, $query)
  1320. or $error_text = "<p />DEBUG INFORMATION:<br />Invalid query: " . pg_last_error() . "$DEBUG_TEXT";
  1321. }
  1322. if ($error_text != "" && $ignore_errors == 0) die($error_text);
  1323. if ($error_text == "") {
  1324. if (eregi ("^SELECT", $query))
  1325. {
  1326. // if $query was a SELECT statement check the number of rows with [database_type]_num_rows ().
  1327. if ($CONF['database_type'] == "mysql") $number_rows = mysql_num_rows ($result);
  1328. if ($CONF['database_type'] == "mysqli") $number_rows = mysqli_num_rows ($result);
  1329. if ($CONF['database_type'] == "pgsql") $number_rows = pg_num_rows ($result);
  1330. }
  1331. else
  1332. {
  1333. // if $query was something else, UPDATE, DELETE or INSERT check the number of rows with
  1334. // [database_type]_affected_rows ().
  1335. if ($CONF['database_type'] == "mysql") $number_rows = mysql_affected_rows ($link);
  1336. if ($CONF['database_type'] == "mysqli") $number_rows = mysqli_affected_rows ($link);
  1337. if ($CONF['database_type'] == "pgsql") $number_rows = pg_affected_rows ($result);
  1338. }
  1339. }
  1340. $return = array (
  1341. "result" => $result,
  1342. "rows" => $number_rows,
  1343. "error" => $error_text
  1344. );
  1345. return $return;
  1346. }
  1347. // db_row
  1348. // Action: Returns a row from a table
  1349. // Call: db_row (int result)
  1350. //
  1351. function db_row ($result)
  1352. {
  1353. global $CONF;
  1354. $row = "";
  1355. if ($CONF['database_type'] == "mysql") $row = mysql_fetch_row ($result);
  1356. if ($CONF['database_type'] == "mysqli") $row = mysqli_fetch_row ($result);
  1357. if ($CONF['database_type'] == "pgsql") $row = pg_fetch_row ($result);
  1358. return $row;
  1359. }
  1360. // db_array
  1361. // Action: Returns a row from a table
  1362. // Call: db_array (int result)
  1363. //
  1364. function db_array ($result)
  1365. {
  1366. global $CONF;
  1367. $row = "";
  1368. if ($CONF['database_type'] == "mysql") $row = mysql_fetch_array ($result);
  1369. if ($CONF['database_type'] == "mysqli") $row = mysqli_fetch_array ($result);
  1370. if ($CONF['database_type'] == "pgsql") $row = pg_fetch_array ($result);
  1371. return $row;
  1372. }
  1373. // db_assoc
  1374. // Action: Returns a row from a table
  1375. // Call: db_assoc(int result)
  1376. //
  1377. function db_assoc ($result)
  1378. {
  1379. global $CONF;
  1380. $row = "";
  1381. if ($CONF['database_type'] == "mysql") $row = mysql_fetch_assoc ($result);
  1382. if ($CONF['database_type'] == "mysqli") $row = mysqli_fetch_assoc ($result);
  1383. if ($CONF['database_type'] == "pgsql") $row = pg_fetch_assoc ($result);
  1384. return $row;
  1385. }
  1386. //
  1387. // db_delete
  1388. // Action: Deletes a row from a specified table
  1389. // Call: db_delete (string table, string where, string delete)
  1390. //
  1391. function db_delete ($table,$where,$delete)
  1392. {
  1393. $result = db_query ("DELETE FROM $table WHERE " . escape_string($where) . "='" . escape_string($delete) . "'");
  1394. if ($result['rows'] >= 1)
  1395. {
  1396. return $result['rows'];
  1397. }
  1398. else
  1399. {
  1400. return true;
  1401. }
  1402. }
  1403. /**
  1404. * db_insert
  1405. * Action: Inserts a row from a specified table
  1406. * Call: db_insert (string table, array values)
  1407. * @param String $table - table name
  1408. * @param array - key/value map of data to insert into the table.
  1409. * @param array (optional) - array of fields to set to now()
  1410. * @return int - number of inserted rows
  1411. */
  1412. function db_insert ($table, $values, $timestamp = array())
  1413. {
  1414. $table = table_by_key ($table);
  1415. foreach(array_keys($values) as $key) {
  1416. $values[$key] = "'" . escape_string($values[$key]) . "'";
  1417. }
  1418. foreach($timestamp as $key) {
  1419. $values[$key] = "now()";
  1420. }
  1421. $sql_values = "(" . implode(",",escape_string(array_keys($values))).") VALUES (".implode(",",$values).")";
  1422. $result = db_query ("INSERT INTO $table $sql_values");
  1423. return $result['rows'];
  1424. }
  1425. /**
  1426. * db_update
  1427. * Action: Updates a specified table
  1428. * Call: db_update (string table, array values, string where)
  1429. * @param String $table - table name
  1430. * @param String - WHERE condition
  1431. * @param array - key/value map of data to insert into the table.
  1432. * @param array (optional) - array of fields to set to now()
  1433. * @return int - number of updated rows
  1434. */
  1435. function db_update ($table, $where, $values, $timestamp = array())
  1436. {
  1437. $table = table_by_key ($table);
  1438. foreach(array_keys($values) as $key) {
  1439. $sql_values[$key] = escape_string($key) . "='" . escape_string($values[$key]) . "'";
  1440. }
  1441. foreach($timestamp as $key) {
  1442. $sql_values[$key] = escape_string($key) . "=now()";
  1443. }
  1444. $sql="UPDATE $table SET ".implode(",",$sql_values)." WHERE $where";
  1445. $result = db_query ($sql);
  1446. return $result['rows'];
  1447. }
  1448. /**
  1449. * db_log
  1450. * Action: Logs actions from admin
  1451. * Call: db_log (string username, string domain, string action, string data)
  1452. * Possible actions are:
  1453. * 'create_alias'
  1454. * 'create_alias_domain'
  1455. * 'create_mailbox'
  1456. * 'delete_alias'
  1457. * 'delete_alias_domain'
  1458. * 'delete_mailbox'
  1459. * 'edit_alias'
  1460. * 'edit_alias_state'
  1461. * 'edit_alias_domain_state'
  1462. * 'edit_mailbox'
  1463. * 'edit_mailbox_state'
  1464. * 'edit_password'
  1465. */
  1466. function db_log ($username,$domain,$action,$data)
  1467. {
  1468. global $CONF;
  1469. global $table_log;
  1470. $REMOTE_ADDR = $_SERVER['REMOTE_ADDR'];
  1471. $action_list = array('create_alias', 'create_alias_domain', 'delete_alias', 'delete_alias_domain', 'edit_alias', 'create_mailbox', 'delete_mailbox', 'edit_mailbox', 'edit_alias_state', 'edit_alias_domain_state', 'edit_mailbox_state', 'edit_password');
  1472. if(!in_array($action, $action_list)) {
  1473. die("Invalid log action : $action"); // could do with something better?
  1474. }
  1475. if ($CONF['logging'] == 'YES')
  1476. {
  1477. $result = db_query ("INSERT INTO $table_log (timestamp,username,domain,action,data) VALUES (NOW(),'$username ($REMOTE_ADDR)','$domain','$action','$data')");
  1478. if ($result['rows'] != 1)
  1479. {
  1480. return false;
  1481. }
  1482. else
  1483. {
  1484. return true;
  1485. }
  1486. }
  1487. }
  1488. //
  1489. // table_by_key
  1490. // Action: Return table name for given key
  1491. // Call: table_by_key (string table_key)
  1492. //
  1493. function table_by_key ($table_key)
  1494. {
  1495. global $CONF;
  1496. $table = $CONF['database_prefix'].$CONF['database_tables'][$table_key];
  1497. if (empty($table)) $table = $table_key;
  1498. return $table;
  1499. }
  1500. /*
  1501. Called after a mailbox has been created in the DBMS.
  1502. Returns: boolean.
  1503. */
  1504. function mailbox_postcreation($username,$domain,$maildir,$quota)
  1505. {
  1506. if (empty($username) || empty($domain) || empty($maildir))
  1507. {
  1508. trigger_error('In '.__FUNCTION__.': empty username, domain and/or maildir parameter',E_USER_ERROR);
  1509. return FALSE;
  1510. }
  1511. global $CONF;
  1512. $confpar='mailbox_postcreation_script';
  1513. if (!isset($CONF[$confpar]) || empty($CONF[$confpar])) return TRUE;
  1514. $cmdarg1=escapeshellarg($username);
  1515. $cmdarg2=escapeshellarg($domain);
  1516. $cmdarg3=escapeshellarg($maildir);
  1517. if ($quota <= 0) $quota = 0;
  1518. $cmdarg4=escapeshellarg($quota);
  1519. $command=$CONF[$confpar]." $cmdarg1 $cmdarg2 $cmdarg3 $cmdarg4";
  1520. $retval=0;
  1521. $output=array();
  1522. $firstline='';
  1523. $firstline=exec($command,$output,$retval);
  1524. if (0!=$retval)
  1525. {
  1526. error_log("Running $command yielded return value=$retval, first line of output=$firstline");
  1527. print '<p>WARNING: Problems running mailbox postcreation script!</p>';
  1528. return FALSE;
  1529. }
  1530. return TRUE;
  1531. }
  1532. /*
  1533. Called after a mailbox has been altered in the DBMS.
  1534. Returns: boolean.
  1535. */
  1536. function mailbox_postedit($username,$domain,$maildir,$quota)
  1537. {
  1538. if (empty($username) || empty($domain) || empty($maildir))
  1539. {
  1540. trigger_error('In '.__FUNCTION__.': empty username, domain and/or maildir parameter',E_USER_ERROR);
  1541. return FALSE;
  1542. }
  1543. global $CONF;
  1544. $confpar='mailbox_postedit_script';
  1545. if (!isset($CONF[$confpar]) || empty($CONF[$confpar])) return TRUE;
  1546. $cmdarg1=escapeshellarg($username);
  1547. $cmdarg2=escapeshellarg($domain);
  1548. $cmdarg3=escapeshellarg($maildir);
  1549. if ($quota <= 0) $quota = 0;
  1550. $cmdarg4=escapeshellarg($quota);
  1551. $command=$CONF[$confpar]." $cmdarg1 $cmdarg2 $cmdarg3 $cmdarg4";
  1552. $retval=0;
  1553. $output=array();
  1554. $firstline='';
  1555. $firstline=exec($command,$output,$retval);
  1556. if (0!=$retval)
  1557. {
  1558. error_log("Running $command yielded return value=$retval, first line of output=$firstline");
  1559. print '<p>WARNING: Problems running mailbox postedit script!</p>';
  1560. return FALSE;
  1561. }
  1562. return TRUE;
  1563. }
  1564. /*
  1565. Called after a mailbox has been deleted in the DBMS.
  1566. Returns: boolean.
  1567. */
  1568. function mailbox_postdeletion($username,$domain)
  1569. {
  1570. global $CONF;
  1571. $confpar='mailbox_postdeletion_script';
  1572. if (!isset($CONF[$confpar]) || empty($CONF[$confpar]))
  1573. {
  1574. return true;
  1575. }
  1576. if (empty($username) || empty($domain))
  1577. {
  1578. print '<p>Warning: empty username and/or domain parameter.</p>';
  1579. return false;
  1580. }
  1581. $cmdarg1=escapeshellarg($username);
  1582. $cmdarg2=escapeshellarg($domain);
  1583. $command=$CONF[$confpar]." $cmdarg1 $cmdarg2";
  1584. $retval=0;
  1585. $output=array();
  1586. $firstline='';
  1587. $firstline=exec($command,$output,$retval);
  1588. if (0!=$retval)
  1589. {
  1590. error_log("Running $command yielded return value=$retval, first line of output=$firstline");
  1591. print '<p>WARNING: Problems running mailbox postdeletion script!</p>';
  1592. return FALSE;
  1593. }
  1594. return TRUE;
  1595. }
  1596. /*
  1597. Called after a domain has been deleted in the DBMS.
  1598. Returns: boolean.
  1599. */
  1600. function domain_postdeletion($domain)
  1601. {
  1602. global $CONF;
  1603. $confpar='domain_postdeletion_script';
  1604. if (!isset($CONF[$confpar]) || empty($CONF[$confpar]))
  1605. {
  1606. return true;
  1607. }
  1608. if (empty($domain))
  1609. {
  1610. print '<p>Warning: empty domain parameter.</p>';
  1611. return false;
  1612. }
  1613. $cmdarg1=escapeshellarg($domain);
  1614. $command=$CONF[$confpar]." $cmdarg1";
  1615. $retval=0;
  1616. $output=array();
  1617. $firstline='';
  1618. $firstline=exec($command,$output,$retval);
  1619. if (0!=$retval)
  1620. {
  1621. error_log("Running $command yielded return value=$retval, first line of output=$firstline");
  1622. print '<p>WARNING: Problems running domain postdeletion script!</p>';
  1623. return FALSE;
  1624. }
  1625. return TRUE;
  1626. }
  1627. /*
  1628. Called after an alias_domain has been deleted in the DBMS.
  1629. Returns: boolean.
  1630. */
  1631. function alias_domain_postdeletion($alias_domain)
  1632. {
  1633. global $CONF;
  1634. $confpar='alias_domain_postdeletion_script';
  1635. if (!isset($CONF[$confpar]) || empty($CONF[$confpar]))
  1636. {
  1637. return true;
  1638. }
  1639. if (empty($alias_domain))
  1640. {
  1641. print '<p>Warning: empty alias_domain parameter.</p>';
  1642. return false;
  1643. }
  1644. $cmdarg1=escapeshellarg($alias_domain);
  1645. $command=$CONF[$confpar]." $cmdarg1";
  1646. $retval=0;
  1647. $output=array();
  1648. $firstline='';
  1649. $firstline=exec($command,$output,$retval);
  1650. if (0!=$retval)
  1651. {
  1652. error_log("Running $command yielded return value=$retval, first line of output=$firstline");
  1653. print '<p>WARNING: Problems running alias_domain postdeletion script!</p>';
  1654. return FALSE;
  1655. }
  1656. return TRUE;
  1657. }
  1658. /*
  1659. Called by mailbox_postcreation() after a mailbox has been
  1660. created. Immediately returns, unless configuration indicates
  1661. that one or more sub-folders should be created.
  1662. Triggers E_USER_ERROR if configuration error is detected.
  1663. If IMAP login fails, the problem is logged to the system log
  1664. (such as /var/log/httpd/error_log), and the function returns
  1665. FALSE.
  1666. Returns FALSE on all other errors, or TRUE if everything
  1667. succeeds.
  1668. Doesn't clean up, if only some of the folders could be
  1669. created.
  1670. */
  1671. function create_mailbox_subfolders($login,$cleartext_password)
  1672. {
  1673. global $CONF;
  1674. if (empty($login))
  1675. {
  1676. trigger_error('In '.__FUNCTION__.': empty $login',E_USER_ERROR);
  1677. return FALSE;
  1678. }
  1679. if (!isset($CONF['create_mailbox_subdirs']) || empty($CONF['create_mailbox_subdirs'])) return TRUE;
  1680. if (!is_array($CONF['create_mailbox_subdirs']))
  1681. {
  1682. trigger_error('create_mailbox_subdirs must be an array',E_USER_ERROR);
  1683. return FALSE;
  1684. }
  1685. if (!isset($CONF['create_mailbox_subdirs_host']) || empty($CONF['create_mailbox_subdirs_host']))
  1686. {
  1687. trigger_error('An IMAP/POP server host ($CONF["create_mailbox_subdirs_host"]) must be configured, if sub-folders are to be created',E_USER_ERROR);
  1688. return FALSE;
  1689. }
  1690. $s_host=$CONF['create_mailbox_subdirs_host'];
  1691. $s_prefix=$CONF['create_mailbox_subdirs_prefix'];
  1692. $s_options='';
  1693. $s_port='';
  1694. if (
  1695. isset($CONF['create_mailbox_subdirs_hostoptions'])
  1696. && !empty($CONF['create_mailbox_subdirs_hostoptions'])
  1697. ) {
  1698. if (!is_array($CONF['create_mailbox_subdirs_hostoptions']))
  1699. {
  1700. trigger_error('The $CONF["create_mailbox_subdirs_hostoptions"] parameter must be an array',E_USER_ERROR);
  1701. return FALSE;
  1702. }
  1703. foreach ($CONF['create_mailbox_subdirs_hostoptions'] as $o)
  1704. {
  1705. $s_options.='/'.$o;
  1706. }
  1707. }
  1708. if (isset($CONF['create_mailbox_subdirs_hostport']) && !empty($CONF['create_mailbox_subdirs_hostport']))
  1709. {
  1710. $s_port=$CONF['create_mailbox_subdirs_hostport'];
  1711. if (intval($s_port)!=$s_port)
  1712. {
  1713. trigger_error('The $CONF["create_mailbox_subdirs_hostport"] parameter must be an integer',E_USER_ERROR);
  1714. return FALSE;
  1715. }
  1716. $s_port=':'.$s_port;
  1717. }
  1718. $s='{'.$s_host.$s_port.$s_options.'}';
  1719. sleep(1); # give the mail triggering the mailbox creation a chance to do its job
  1720. $i=@imap_open($s,$login,$cleartext_password);
  1721. if (FALSE==$i)
  1722. {
  1723. error_log('Could not log into IMAP/POP server: '.imap_last_error());
  1724. return FALSE;
  1725. }
  1726. foreach($CONF['create_mailbox_subdirs'] as $f)
  1727. {
  1728. $f='{'.$s_host.'}'.$s_prefix.$f;
  1729. $res=imap_createmailbox($i,$f);
  1730. if (!$res) {
  1731. @imap_close($i);
  1732. return FALSE;
  1733. }
  1734. @imap_subscribe($i,$f);
  1735. }
  1736. @imap_close($i);
  1737. return TRUE;
  1738. }
  1739. //
  1740. // gen_show_status
  1741. // Action: Return a string of colored &nbsp;'s that indicate
  1742. // the if an alias goto has an error or is sent to
  1743. // addresses list in show_custom_domains
  1744. // Call: gen_show_status (string alias_address)
  1745. //
  1746. function gen_show_status ($show_alias)
  1747. {
  1748. global $CONF, $table_alias;
  1749. $stat_string = "";
  1750. $stat_goto = "";
  1751. $stat_result = db_query ("SELECT goto FROM $table_alias WHERE address='$show_alias'");
  1752. if ($stat_result['rows'] > 0)
  1753. {
  1754. $row = db_row ($stat_result['result']);
  1755. $stat_goto = $row[0];
  1756. }
  1757. // UNDELIVERABLE CHECK
  1758. if ( $CONF['show_undeliverable'] == 'YES' )
  1759. {
  1760. $gotos=array();
  1761. $gotos=explode(',',$stat_goto);
  1762. $undel_string="";
  1763. //make sure this alias goes somewhere known
  1764. $stat_ok = 1;
  1765. while ( ($g=array_pop($gotos)) && $stat_ok )
  1766. {
  1767. $stat_result = db_query ("SELECT address FROM $table_alias WHERE address = '$g'");
  1768. if ($stat_result['rows'] == 0)
  1769. {
  1770. $stat_ok = 0;
  1771. }
  1772. if ( $stat_ok == 0 )
  1773. {
  1774. $stat_domain = substr($g,strpos($g,"@")+1);
  1775. $stat_vacdomain = substr($stat_domain,strpos($stat_domain,"@")+1);
  1776. if ( $stat_vacdomain == $CONF['vacation_domain'] )
  1777. {
  1778. $stat_ok = 1;
  1779. break;
  1780. }
  1781. for ($i=0; $i < sizeof($CONF['show_undeliverable_exceptions']);$i++)
  1782. {
  1783. if ( $stat_domain == $CONF['show_undeliverable_exceptions'][$i] )
  1784. {
  1785. $stat_ok = 1;
  1786. break;
  1787. }
  1788. }
  1789. }
  1790. } // while
  1791. if ( $stat_ok == 0 )
  1792. {
  1793. $stat_string .= "<span style='background-color:" . $CONF['show_undeliverable_color'] .
  1794. "'>" . $CONF['show_status_text'] . "</span>&nbsp;";
  1795. }
  1796. else
  1797. {
  1798. $stat_string .= $CONF['show_status_text'] . "&nbsp;";
  1799. }
  1800. }
  1801. else
  1802. {
  1803. $stat_string .= $CONF['show_status_text'] . "&nbsp;";
  1804. }
  1805. // POP/IMAP CHECK
  1806. if ( $CONF['show_popimap'] == 'YES' )
  1807. {
  1808. //if the address passed in appears in its own goto field, its POP/IMAP
  1809. if ( preg_match ('/,' . $show_alias . ',/', ',' . $stat_goto . ',') )
  1810. {
  1811. $stat_string .= "<span style='background-color:" . $CONF['show_popimap_color'] .
  1812. "'>" . $CONF['show_status_text'] . "</span>&nbsp;";
  1813. }
  1814. else
  1815. {
  1816. $stat_string .= $CONF['show_status_text'] . "&nbsp;";
  1817. }
  1818. }
  1819. // CUSTOM DESTINATION CHECK
  1820. if ( $CONF['show_custom_count'] > 0 )
  1821. {
  1822. for ($i = 0; $i < sizeof ($CONF['show_custom_domains']); $i++)
  1823. {
  1824. if (preg_match ('/^.*' . $CONF['show_custom_domains'][$i] . '.*$/', $stat_goto))
  1825. {
  1826. $stat_string .= "<span style='background-color:" . $CONF['show_custom_colors'][$i] .
  1827. "'>" . $CONF['show_status_text'] . "</span>&nbsp;";
  1828. }
  1829. else
  1830. {
  1831. $stat_string .= $CONF['show_status_text'] . "&nbsp;";
  1832. }
  1833. }
  1834. }
  1835. else
  1836. {
  1837. $stat_string .= ";&nbsp;";
  1838. }
  1839. // $stat_string .= "<span style='background-color:green'> &nbsp; </span> &nbsp;" .
  1840. // "<span style='background-color:blue'> &nbsp; </span> &nbsp;";
  1841. return $stat_string;
  1842. }
  1843. /*
  1844. Called by create-admin.php and setup.php
  1845. Returns:
  1846. array(
  1847. 'error' => 0, # 0 on success, otherwise > 0
  1848. 'tMessage' => '', # success / failure message
  1849. 'pAdminCreate_admin_username_text' => '', # help text / error message for username
  1850. 'pAdminCreate_admin_password_text' => '' # error message for username
  1851. )
  1852. */
  1853. function create_admin($fUsername, $fPassword, $fPassword2, $fDomains, $no_generate_password=0)
  1854. {
  1855. global $PALANG;
  1856. global $CONF;
  1857. $error = 0;
  1858. $tMessage = '';
  1859. $pAdminCreate_admin_username_text = '';
  1860. $pAdminCreate_admin_password_text = '';
  1861. if (!check_email ($fUsername))
  1862. {
  1863. $error = 1;
  1864. $pAdminCreate_admin_username_text = $PALANG['pAdminCreate_admin_username_text_error1'];
  1865. }
  1866. if (empty ($fUsername) or admin_exist ($fUsername))
  1867. {
  1868. $error = 1;
  1869. $pAdminCreate_admin_username_text = $PALANG['pAdminCreate_admin_username_text_error2'];
  1870. }
  1871. if (empty ($fPassword) or empty ($fPassword2) or ($fPassword != $fPassword2))
  1872. {
  1873. if (empty ($fPassword) and empty ($fPassword2) and $CONF['generate_password'] == "YES" && $no_generate_password == 0)
  1874. {
  1875. $fPassword = generate_password ();
  1876. }
  1877. else
  1878. {
  1879. $error = 1;
  1880. $pAdminCreate_admin_username_text = $PALANG['pAdminCreate_admin_username_text'];
  1881. $pAdminCreate_admin_password_text = $PALANG['pAdminCreate_admin_password_text_error'];
  1882. }
  1883. }
  1884. if ($error != 1)
  1885. {
  1886. $password = pacrypt($fPassword);
  1887. $pAdminCreate_admin_username_text = $PALANG['pAdminCreate_admin_username_text'];
  1888. $result = db_query ("INSERT INTO " . table_by_key('admin') . " (username,password,created,modified) VALUES ('$fUsername','$password',NOW(),NOW())");
  1889. if ($result['rows'] != 1)
  1890. {
  1891. $tMessage = $PALANG['pAdminCreate_admin_result_error'] . "<br />($fUsername)<br />";
  1892. }
  1893. else
  1894. {
  1895. if (!empty ($fDomains[0]))
  1896. {
  1897. for ($i = 0; $i < sizeof ($fDomains); $i++)
  1898. {
  1899. $domain = $fDomains[$i];
  1900. $result = db_query ("INSERT INTO " . table_by_key ('domain_admins') . " (username,domain,created) VALUES ('$fUsername','$domain',NOW())");
  1901. }
  1902. }
  1903. $tMessage = $PALANG['pAdminCreate_admin_result_success'] . "<br />($fUsername";
  1904. if ($CONF['generate_password'] == "YES" && $no_generate_password == 0)
  1905. {
  1906. $tMessage .= " / $fPassword)</br />";
  1907. }
  1908. else
  1909. {
  1910. if ($CONF['show_password'] == "YES" && $no_generate_password == 0)
  1911. {
  1912. $tMessage .= " / $fPassword)</br />";
  1913. }
  1914. else
  1915. {
  1916. $tMessage .= ")</br />";
  1917. }
  1918. }
  1919. }
  1920. }
  1921. # TODO: should we log creation, editing and deletion of admins?
  1922. # Note: needs special handling in viewlog, because domain is empty
  1923. # db_log ($SESSID_USERNAME, '', 'create_admin', "$fUsername");
  1924. return array(
  1925. $error,
  1926. $tMessage,
  1927. $pAdminCreate_admin_username_text,
  1928. $pAdminCreate_admin_password_text
  1929. );
  1930. }
  1931. /*
  1932. Convert $CONF['whatever'] to boolean
  1933. (obviously only useful for settings that can be YES or NO)
  1934. Returns: TRUE (on YES/yes) or FALSE (on NO/no/not set/unknown value)
  1935. */
  1936. function boolconf($setting) {
  1937. global $CONF;
  1938. if (!isset($CONF[$setting])) { # not set
  1939. # TODO: show/log error message on unknown settings?
  1940. return false;
  1941. } elseif (strtoupper($CONF[$setting]) == 'YES') { # YES
  1942. return true;
  1943. } else { # NO, unknown value
  1944. # TODO: show/log error message on unknown value?
  1945. return false;
  1946. }
  1947. }
  1948. $table_admin = table_by_key ('admin');
  1949. $table_alias = table_by_key ('alias');
  1950. $table_alias_domain = table_by_key ('alias_domain');
  1951. $table_domain = table_by_key ('domain');
  1952. $table_domain_admins = table_by_key ('domain_admins');
  1953. $table_log = table_by_key ('log');
  1954. $table_mailbox = table_by_key ('mailbox');
  1955. $table_vacation = table_by_key ('vacation');
  1956. $table_vacation_notification = table_by_key('vacation_notification');
  1957. /* vim: set expandtab softtabstop=3 tabstop=3 shiftwidth=3: */