vmailmgrd.php 10 KB

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