vmailmgrd.php 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288
  1. <?php
  2. /**
  3. * Change password vmailmgrd backend
  4. *
  5. * Backend won't work, if vmail.inc file is not included. vmail.inc file
  6. * should be part of your vmailmgr install. In some cases it is included in
  7. * separate package.
  8. *
  9. * If you use modified vmail.inc, it must provide vchpass() function that
  10. * acts same way as stock (vmailmgr v.0.96.9) vmail.inc function call
  11. * and other vmail.inc functions should use same $vm_tcphost and
  12. * $vm_tcphost_port globals as used by stock vm_daemon_raw() function call.
  13. * If you have heavily modified vmail.inc and this backend does not work
  14. * correctly - recheck, if you can reproduce your problem with stock
  15. * vmail.inc or adjust backend configuration for your site.
  16. *
  17. * Backend also needs vmailmgrd service. You can find information about
  18. * installing this service in vmailmgr FAQ and vmailmgrd.html.
  19. *
  20. * Backend might require functions, that are available only in SquirrelMail
  21. * v.1.5.1 and v.1.4.4.
  22. *
  23. * @author Tomas Kuliavas <tokul at users.sourceforge.net>
  24. * @copyright &copy; 2005-2007 The SquirrelMail Project Team
  25. * @license http://opensource.org/licenses/gpl-license.php GNU Public License
  26. * @version $Id$
  27. * @link http://www.vmailmgr.org vmailmgr site
  28. * @package plugins
  29. * @subpackage change_password
  30. */
  31. /* Default backend configuration */
  32. /**
  33. * path to vmail.inc
  34. *
  35. * This variable must provide full path to vmail.inc file including filename.
  36. *
  37. * WARNING: Don't disable this variable. It must be set to correct value or
  38. * to empty string. If variable is missing, backend can have security problems
  39. * in some PHP configurations.
  40. * @global string $vmail_inc_path
  41. */
  42. global $vmail_inc_path;
  43. $vmail_inc_path='';
  44. /**
  45. * address of vmailmgrd host.
  46. *
  47. * Leave it empty, if you want to use unix socket
  48. * global is used by vmail.inc functions
  49. * @global string $vm_tcphost
  50. */
  51. global $vm_tcphost;
  52. $vm_tcphost='';
  53. /**
  54. * port of vmailmgrd
  55. *
  56. * global is used by vmail.inc functions.
  57. * @global integer $vm_tcphost_port
  58. */
  59. global $vm_tcphost_port;
  60. $vm_tcphost_port=322;
  61. /**
  62. * Option that controls use of 8bit passwords
  63. * Use of such passwords is not safe, because squirrelmail interface
  64. * can be running in different charsets.
  65. * @global boolean
  66. */
  67. global $cpw_vmailmgrd_8bitpw;
  68. $cpw_vmailmgrd_8bitpw=false;
  69. /* end of backend configuration */
  70. /** load configuration from config.php */
  71. if ( isset($cpw_vmailmgrd) && is_array($cpw_vmailmgrd) && !empty($cpw_vmailmgrd) ) {
  72. if (isset($cpw_vmailmgrd['vmail_inc_path']))
  73. $vmail_inc_path=$cpw_vmailmgrd['vmail_inc_path'];
  74. if (isset($cpw_vmailmgrd['vm_tcphost']))
  75. $vm_tcphost=$cpw_vmailmgrd['vm_tcphost'];
  76. if (isset($cpw_vmailmgrd['vm_tcphost_port']))
  77. $vm_tcphost_port=$cpw_vmailmgrd['vm_tcphost_port'];
  78. if (isset($cpw_vmailmgrd['8bitpw']))
  79. $cpw_vmailmgrd_8bitpw=$cpw_vmailmgrd['8bitpw'];
  80. }
  81. /**
  82. * Init change_password plugin hooks.
  83. */
  84. global $squirrelmail_plugin_hooks;
  85. $squirrelmail_plugin_hooks['change_password_dochange']['vmailmgrd'] =
  86. 'cpw_vmailmgrd_dochange';
  87. $squirrelmail_plugin_hooks['change_password_init']['vmailmgrd'] =
  88. 'cpw_vmailmgrd_init';
  89. /**
  90. * Use this function to do any backend-specific initialisation,
  91. * e.g. checking requirements, before the password change form
  92. * is displayed to the user.
  93. */
  94. function cpw_vmailmgrd_init(){
  95. global $vmail_inc_path, $username, $oTemplate;
  96. if ($vmail_inc_path=='' || ! file_exists($vmail_inc_path)) {
  97. // $vmail_inc_path is not set or file does not exist
  98. error_box(_("Incorrent path to vmail.inc file."));
  99. // close html and stop script execution
  100. $oTemplate->display('footer.tpl');
  101. exit();
  102. }
  103. include_once($vmail_inc_path);
  104. if (! function_exists('vchpass')) {
  105. // included vmail.inc does not have required functions.
  106. error_box(_("Invalid or corrupted vmail.inc file."));
  107. // close html and stop script execution
  108. $oTemplate->display('footer.tpl');
  109. exit();
  110. }
  111. if (! preg_match("/(.*)\@(.*)/", $username)) {
  112. // username does not match vmailmgr syntax
  113. error_box(_("Invalid user."));
  114. // close html and stop script execution
  115. $oTemplate->display('footer.tpl');
  116. exit();
  117. }
  118. }
  119. /**
  120. * function used to change password in change_password plugin hooks.
  121. *
  122. * @param array $data The username/curpw/newpw data.
  123. * @return array Array of error messages.
  124. */
  125. function cpw_vmailmgrd_dochange($data)
  126. {
  127. global $cpw_vmailmgrd_8bitpw;
  128. /**
  129. * getting params from hook function.
  130. */
  131. $username = $data['username'];
  132. $curpw = $data['curpw'];
  133. $newpw = $data['newpw'];
  134. $msgs = array();
  135. // check for new 8bit password
  136. if (! $cpw_vmailmgrd_8bitpw && sq_is8bit($newpw)) {
  137. // 8bit chars in password when backend is configured to block them
  138. array_push($msgs,CPW_INVALID_PW);
  139. return $msgs;
  140. }
  141. // extract username and domain
  142. if (preg_match("/(.*)\@(.*)/", $username, $parts)) {
  143. $vm_user=$parts[1];
  144. $vm_domain=$parts[2];
  145. }
  146. // check if old password matches
  147. $vmgrd_response1 = cpw_vmailmgrd_passwd($vm_user,$vm_domain,$curpw,$curpw);
  148. if ($vmgrd_response1[0]!=0) {
  149. array_push($msgs, CPW_CURRENT_NOMATCH);
  150. return $msgs;
  151. }
  152. // change password
  153. $vmgrd_response2 = cpw_vmailmgrd_passwd($vm_user,$vm_domain,$curpw,$newpw);
  154. if ($vmgrd_response2[0]!=0) {
  155. // TODO: add vmail.inc error message parser.
  156. array_push($msgs, cpw_i18n_vmail_response($vmgrd_response2[1]));
  157. }
  158. return $msgs;
  159. }
  160. /**
  161. * function that calls required vmail.inc functions and returns error codes.
  162. *
  163. * Information about vmailmgr return codes.
  164. * vmailmgr functions return array with two keys.
  165. * Array(
  166. * [0] => error code, integer (0=no error)
  167. * [1] => error message, string
  168. * )
  169. * @return array
  170. */
  171. function cpw_vmailmgrd_passwd($user,$domain,$oldpass,$newpass) {
  172. global $vmail_inc_path;
  173. // variable should be checked by cpw_vmailmgrd_init function
  174. include_once($vmail_inc_path);
  175. return vchpass($domain,$oldpass,$user,$newpass);
  176. }
  177. /**
  178. * Function is used to translate messages returned by vmailmgr
  179. * php library and vmailmgr daemon.
  180. * @param string $string vmailmrgd message.
  181. * @return string translated string.
  182. */
  183. function cpw_i18n_vmail_response($string) {
  184. if ($string=='Empty domain') {
  185. // block one: vchpass responses
  186. $ret = _("Empty domain");
  187. } elseif ($string=='Empty domain password') {
  188. $ret = _("Empty domain password");
  189. } elseif ($string=='Empty username') {
  190. $ret = _("Empty username");
  191. } elseif ($string=='Empty new password') {
  192. $ret = _("Empty new password");
  193. /*
  194. * block is disabled in order to reduce load on translators.
  195. * these error messages should be very rare.
  196. } elseif ($string=='Invalid or unknown base user or domain') {
  197. // block two: vmailmgr daemon strings
  198. $ret = _("Invalid or unknown base user or domain");
  199. } elseif ($string=='Invalid or unknown virtual user') {
  200. $ret = _("Invalid or unknown virtual user");
  201. } elseif ($string=='Invalid or incorrect password') {
  202. $ret = _("Invalid or incorrect password");
  203. } elseif ($string=='Unknown operation to stat') {
  204. $ret = _("Unknown operation to stat");
  205. } elseif (preg_match("/^Incorrect number of parameters to command (.+)/",$string,$match)) {
  206. $ret = sprintf(_("Incorrect number of parameters to command %s"),$match[1]);
  207. } elseif (preg_match("/^Invalid or unknown domain name: (.+)/",$string,$match)) {
  208. $ret = sprintf(_("Invalid or unknown domain name: %s"),$match[1]);
  209. } elseif ($string=='Invalid operation') {
  210. $ret = _("Invalid operation");
  211. } elseif (preg_match("/^Invalid or unknown base user name: (.+)/",$string,$match)) {
  212. $ret = sprintf(_("Invalid or unknown base user name: %s"),$match[1]);
  213. } elseif ($string=='Invalid or incorrect password') {
  214. $ret = _("Invalid or incorrect password");
  215. } elseif ($string=='Base user has no virtual password table') {
  216. $ret = _("Base user has no virtual password table");
  217. } elseif ($string=='Failed while writing initial OK response') {
  218. $ret = _("Failed while writing initial OK response");
  219. } elseif ($string=='Failed while writing list entry') {
  220. $ret = _("Failed while writing list entry");
  221. } elseif ($string=='Internal error -- userpass && !mustexist') {
  222. $ret = _("Internal error -- userpass && !mustexist");
  223. } elseif ($string=='Invalid or unknown base user or domain') {
  224. $ret = _("Invalid or unknown base user or domain");
  225. } elseif ($string=='Incorrect password') {
  226. $ret = CPW_INVALID_PW;
  227. } elseif ($string=='User name does not refer to a virtual user') {
  228. $ret = _("User name does not refer to a virtual user");
  229. } elseif ($string=='Invalid or unknown virtual user') {
  230. $ret = _("Invalid or unknown virtual user");
  231. } elseif ($string=='Virtual user already exists') {
  232. $ret = _("Virtual user already exists");
  233. } elseif ($string=='Timed out waiting for remote') {
  234. $ret = _("Timed out waiting for remote");
  235. } elseif ($string=='Connection to client lost') {
  236. $ret = _("Connection to client lost");
  237. } elseif ($string=="Couldn't decode the command string") {
  238. $ret = _("Couldn't decode the command string");
  239. } elseif ($string=='Empty command string') {
  240. $ret = _("Empty command string");
  241. } elseif ($string=='Error decoding a command parameter') {
  242. $ret = _("Error decoding a command parameter");
  243. } elseif ($string=='read system call failed or was interrupted') {
  244. $ret = _("read system call failed or was interrupted");
  245. } elseif ($string=='Short read while reading protocol header') {
  246. $ret = _("Short read while reading protocol header");
  247. } elseif ($string=='Invalid protocol from client') {
  248. $ret = _("Invalid protocol from client");
  249. } elseif ($string=='Short read while reading message data') {
  250. $ret = _("Short read while reading message data");
  251. } elseif ($string=='Error writing response') {
  252. $ret = _("Error writing response");
  253. */
  254. } else {
  255. // return unknown strings
  256. $ret = $string;
  257. }
  258. return $ret;
  259. }