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.

504 lines
17 KiB

  1. <?php
  2. class PostfixAdminUser extends Shell {
  3. /**
  4. * Contains tasks to load and instantiate
  5. *
  6. * @var array
  7. * @access public
  8. */
  9. var $tasks = array('Add', 'Update', 'Delete', 'Password', 'View');
  10. /**
  11. * Show help for this shell.
  12. *
  13. * @access public
  14. */
  15. function help() {
  16. $head = "Usage: postfixadmin-cli user <task> [<address>] [] [-m <method>]\n";
  17. $head .= "-----------------------------------------------\n";
  18. $head .= "Parameters:\n\n";
  19. $commands = array(
  20. 'task' => "\t<task>\n" .
  21. "\t\tAvailable values:\n\n".
  22. "\t\t".sprintf("%-20s %s", "view: ", "View an existing user.")."\n".
  23. "\t\t".sprintf("%-20s %s", "add: ", "Adds a new user with mailbox.")."\n".
  24. "\t\t".sprintf("%-20s %s", "update: ", "Updates a user.")."\n".
  25. "\t\t".sprintf("%-20s %s", "delete: ", "Deletes a user")."\n".
  26. "\t\t".sprintf("%-20s %s", "password: ", "Changes the PW for a user.")."\n",
  27. 'address' => "\t[<address>]\n" .
  28. "\t\tA CakePHP core class name (e.g: Component, HtmlHelper).\n",
  29. );
  30. $this->out($head);
  31. if (!isset($this->args[1])) {
  32. foreach ($commands as $cmd) {
  33. $this->out("{$cmd}\n\n");
  34. }
  35. } elseif (isset($commands[low($this->args[1])])) {
  36. $this->out($commands[low($this->args[1])] . "\n\n");
  37. } else {
  38. $this->out("Command '" . $this->args[1] . "' not found");
  39. }
  40. }
  41. }
  42. class AddTask extends Shell {
  43. /**
  44. * Execution method always used for tasks
  45. *
  46. * @access public
  47. */
  48. # Find one function that matches all executes in shell childclasses.
  49. # Eventually getopts like call in __handle??
  50. function execute() {
  51. if (empty($this->args)) {
  52. $this->__interactive();
  53. }
  54. if (!empty($this->args[0])) {
  55. if (!empty($this->params['g'])) {
  56. $this->__handle($this->args[0], NULL, true, $this->args[1], $this->args[2]);
  57. } else {
  58. $this->__handle($this->args[0], $this->args[1], false, $this->args[2], $this->args[3]);
  59. }
  60. }
  61. }
  62. /**
  63. * Interactive
  64. *
  65. * @access private
  66. */
  67. function __interactive() {
  68. while(0==0) {
  69. $question = "Enter address:";
  70. $address = $this->in($question);
  71. if(preg_match("/^((?:(?:(?:[a-zA-Z0-9][\.\-\+_]?)*)[a-zA-Z0-9])+)\@((?:(?:(?:[a-zA-Z0-9][\.\-_]?){0,62})[a-zA-Z0-9])+)\.([a-zA-Z0-9]{2,6})$/", $address) == 1)
  72. break;
  73. $this->err("Invalid emailaddress");
  74. }
  75. $question = "Do you want to generate a random password?";
  76. $random = $this->in($question, array('y','n'));
  77. $random == 'y' ? $random = true : $random = false;
  78. $password = NULL;
  79. if ($random == false) {
  80. $question = "Enter the password:";
  81. $password = $this->in($question);
  82. }
  83. $question = "Enter name:";
  84. $name = $this->in($question);
  85. $question = "Enter quota (MB):";
  86. $quota = $this->in($question);
  87. $question1[] = "Do you reallywant to add mailbox with this options?";
  88. $question1[] = "Address: \t$address";
  89. if($random)
  90. $question1[] = "Random Password.";
  91. else
  92. $question1[] = "Password: \t$password";
  93. $question1[] = "Name: \t$name";
  94. $question1[] = "Quota: \t$quota MB";
  95. $create = $this->in(join("\n", $question1), array('y','n'));
  96. $create == 'y' ? $random = true : $random = false;
  97. if ($create)
  98. $this->__handle($address, $password, $random, $name, $quota);
  99. }
  100. /**
  101. * Interactive
  102. *
  103. * @access private
  104. */
  105. function __handle($address, $password, $gen = false, $name = '', $quota = 0) {
  106. $pw = NULL;
  107. if ($gen) {
  108. $pw = generate_password();
  109. } elseif ($password != NULL) {
  110. $pw = $password;
  111. }
  112. $handler = new UserHandler($address);
  113. $return = $handler->add($pw, $name, $quota, true, true );
  114. #CHECK!
  115. if ( !empty($this->params['q']) ) {
  116. if( $return == false ) {
  117. $this->_stop(1);
  118. }
  119. } else {
  120. if( $return == false ) {
  121. ### When $this->error is used, $this->_stop is useless.
  122. ### Changed $this->error to stop with level 1.
  123. ### Eventually param q check in $this->error is better!! !Important!
  124. $this->error("Error:", $handler->errormsg);
  125. } else {
  126. $this->out("");
  127. if ($name != '')
  128. $this->out("Mailbox for $name generated.");
  129. else
  130. $this->out("Mailbox generated.");
  131. $this->hr();
  132. $this->out(sprintf('Mailaddress: %-20s', $address));
  133. $this->out(sprintf('Password: %-20s',$pw));
  134. $this->out(sprintf('Quota: %-20sMB',$quota));
  135. $this->hr();
  136. }
  137. #CHECK!
  138. }
  139. return;
  140. }
  141. /**
  142. * Displays help contents
  143. *
  144. * @access public
  145. */
  146. function help() {
  147. $this->hr();
  148. $this->out("Usage: postfixadmin-cli user add <address> [<password>] <name> <quota> [-g]");
  149. $this->hr();
  150. $this->out('Commands:');
  151. $this->out("\n\tadd\n\t\tAdds mailbox in interactive mode.");
  152. $this->out("\n\tadd <address> [<password>] [-g] <name> <quota>\n\t\tAdds mailbox for <address> with password <password> of if -g with rand pw. <quota> in MB.");
  153. $this->out("");
  154. $this->_stop();
  155. }
  156. }
  157. class UpdateTask extends Shell {
  158. /**
  159. * Execution method always used for tasks
  160. *
  161. * @access public
  162. */
  163. function execute() {
  164. if (empty($this->args)) {
  165. $this->help();
  166. //$this->__interactive();
  167. }
  168. if (!empty($this->args[0])) {
  169. $this->help();
  170. }
  171. }
  172. /**
  173. * Interactive
  174. *
  175. * @access private
  176. */
  177. function __interactive() {
  178. }
  179. /**
  180. * Displays help contents
  181. *
  182. * @access public
  183. */
  184. function help() {
  185. $this->hr();
  186. $this->out("Not Implemented yet! If you want to change a password use the password command.");
  187. /*$this->out("Usage: postfixadmin-cli user update <args>");
  188. $this->hr();
  189. $this->out('Commands:');
  190. $this->out("\n\tmodel\n\t\tbakes model in interactive mode.");
  191. $this->out("\n\tmodel <name>\n\t\tbakes model file with no associations or validation");
  192. $this->out("");*/
  193. $this->_stop();
  194. }
  195. }
  196. class DeleteTask extends Shell {
  197. /**
  198. * Execution method always used for tasks
  199. *
  200. * @access public
  201. */
  202. function execute() {
  203. if (empty($this->args)) {
  204. $this->__interactive();
  205. }
  206. if (!empty($this->args[0])) {
  207. $output = $this->__handle($this->args[0]);
  208. $this->out($output);
  209. }
  210. }
  211. /**
  212. * Interactive
  213. *
  214. * @access private
  215. */
  216. function __interactive() {
  217. $question[] = "Which Address do you want to delete?";
  218. $address = $this->in(join("\n", $question));
  219. $question = "Do you really want to delete mailbox of '$address'?";
  220. $create = $this->in($question, array('y','n'));
  221. $create == 'y' ? $random = true : $random = false;
  222. if ($create)
  223. $this->__handle($address);
  224. }
  225. /**
  226. * Interactive
  227. *
  228. * @access private
  229. */
  230. function __handle($address) {
  231. $handler = new UserHandler($address);
  232. $status = $handler->delete();
  233. if ( ! $status ) {
  234. $this->error("Error:", join("\n", $handler->errormsg));
  235. } else {
  236. $this->out("Mailbox of '$address' was deleted.");
  237. }
  238. return;
  239. }
  240. /**
  241. * Displays help contents
  242. *
  243. * @access public
  244. */
  245. function help() {
  246. $this->hr();
  247. $this->out("Usage: postfixadmin-cli user model <arg1>");
  248. $this->hr();
  249. $this->out('Commands:');
  250. $this->out("\n\tdelete\n\t\tdeletes mailbox in interactive mode.");
  251. $this->out("\n\tdelete <address>\n\t\tdeletes mailbox with address <address>");
  252. $this->out("");
  253. $this->_stop();
  254. }
  255. }
  256. class PasswordTask extends Shell {
  257. /**
  258. * Execution method always used for tasks
  259. *
  260. * @access public
  261. */
  262. function execute() {
  263. $random = false;
  264. if (empty($this->args)) {
  265. $this->__interactive();
  266. }
  267. if (!empty($this->args[0])) {
  268. $address = $this->args[0];
  269. if (isset($this->params['g']) && $this->params['g'] == true ) {
  270. $random = true;
  271. $password = NULL;
  272. } elseif (isset($this->args[1]) && strlen($this->args[1]) > 8) { # TODO use $CONF['min_password_length']
  273. $password = $this->args[1];
  274. } else {
  275. $this->Dispatch->stderr('Missing <newpw> or -g. Falling back to interactive mode.');
  276. $this->__interactive();
  277. }
  278. $this->__handle($address, $password, $random);
  279. }
  280. }
  281. /**
  282. * Interactive
  283. *
  284. * @access private
  285. */
  286. function __interactive() {
  287. while(0==0) {
  288. $question = "Which address' password do you want to change?";
  289. $address = $this->in($question);
  290. if(preg_match("/^((?:(?:(?:[a-zA-Z0-9][\.\-\+_]?)*)[a-zA-Z0-9])+)\@((?:(?:(?:[a-zA-Z0-9][\.\-_]?){0,62})[a-zA-Z0-9])+)\.([a-zA-Z0-9]{2,6})$/", $address) == 1)
  291. break;
  292. $this->err("Invalid emailaddress");
  293. }
  294. $question2[] = "Do you want to change the password?";
  295. $question2[] = "Are you really sure?";
  296. $sure = $this->in(join("\n", $question2), array('y','n'));
  297. if ($sure == 'n' ) {
  298. $this->out('You\'re not sure.');
  299. $this->_stop();
  300. }
  301. $question = "Do you want to generate a random password?";
  302. $random = $this->in($question, array('y','n'));
  303. $random == 'y' ? $random = true : $random = false;
  304. $password = NULL;
  305. if ($random == false) {
  306. $question = "Pleas enter the new password?";
  307. $password = $this->in($question);
  308. }
  309. $this->__handle($address, $password, $random);
  310. }
  311. /**
  312. * Interactive
  313. *
  314. * @access private
  315. */
  316. function __handle($address, $password = NULL, $random = false) {
  317. if ($random == true) {
  318. $password = generate_password();
  319. }
  320. if ($password != NULL) {
  321. $handler = new UserHandler($address);
  322. if ( ! $handler->change_pw($password, NULL, false) ){
  323. $this->error("Change Password",join("\n", $handler->errormsg));
  324. }
  325. }
  326. $this->out("");
  327. $this->out("Password updated.");
  328. $this->hr();
  329. $this->out(sprintf('The Mail address is %20s', $address));
  330. $this->out(sprintf('The new password is %20s',$password));
  331. $this->hr();
  332. return ;
  333. }
  334. /**
  335. * Displays help contents
  336. *
  337. * @access public
  338. */
  339. function help() {
  340. $this->out("");
  341. $this->hr();
  342. $this->out("Usage: postfixadmin-cli user password <address> [<newpw>] [-g]");
  343. $this->hr();
  344. $this->out('Commands:');
  345. $this->out("\n\tpassword\n\t\tchanges the password in interactive mode.");
  346. $this->out("\n\tpassword <address> [<newpw>] [-g]\n\t\tchanges the password to <newpw> or if -g genereate a new pw for <address>");
  347. $this->out("");
  348. $this->_stop();
  349. }
  350. }
  351. class ViewTask extends Shell {
  352. /**
  353. * Execution method always used for tasks
  354. *
  355. * @access public
  356. */
  357. function execute() {
  358. if (empty($this->args)) {
  359. $this->__interactive();
  360. }
  361. if (!empty($this->args[0])) {
  362. $output = $this->__handle($this->args[0]);
  363. $this->out($output);
  364. }
  365. }
  366. /**
  367. * Interactive
  368. *
  369. * @access private
  370. */
  371. function __interactive() {
  372. $question[] = "Which Address do you want to view?";
  373. $address = $this->in(join("\n", $question));
  374. $this->__handle($address);
  375. }
  376. /**
  377. * Interactive
  378. *
  379. * @access private
  380. */
  381. function __handle($address) {
  382. $handler = new UserHandler($address);
  383. if ( ! $handler->view() ) {
  384. $this->error("Not Found!", "The user you have searched could not be found.");
  385. }
  386. # TODO: offer alternative output formats (based on parameter)
  387. # TODO: whitespace fix - 8 lines below
  388. $result = $handler->return;
  389. $this->out(sprintf("Entries for: %s\n", $address));
  390. $this->out("");
  391. $this->out(sprintf("+%'-25s+%'-15s+%'-10s+%'-20s+%'-8s+%'-8s+%'-6s+",'','','','','','',''));
  392. $this->out(sprintf('|%25s|%15s|%10s|%20s|%8s|%8s|%6s|', 'Address', 'Name', 'Quota', 'Dir', 'Created', 'Modified', 'Active'));
  393. $this->out(sprintf("+%'-25s+%'-15s+%'-10s+%'-20s+%'-8s+%'-8s+%'-6s+",'','','','','','',''));
  394. $this->out(sprintf('|%25s|%15s|%10s|%20s|%8s|%8s|%6s|', $result['username'], $result['name'], $result['quota'], $result['maildir'], $result['created'], $result['modified'], $result['active']));
  395. $this->out(sprintf("+%'-25s+%'-15s+%'-10s+%'-20s+%'-8s+%'-8s+%'-6s+",'','','','','','',''));
  396. return;
  397. }
  398. /**
  399. * Displays help contents
  400. *
  401. * @access public
  402. */
  403. function help() {
  404. $this->out("");
  405. $this->hr();
  406. $this->out("Usage: postfixadmin-cli user view <address>");
  407. $this->hr();
  408. $this->out('Commands:');
  409. $this->out("\n\tview\n\t\tView user. Select address in interactive mode.");
  410. $this->out("\n\tview <address>\n\t\tView user with address <address>");
  411. $this->out("");
  412. $this->_stop();
  413. }
  414. }