Evoadmin-mail is a Web Interface for manage an LDAP directory designed for mail accounts.
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.

add-mail-unix.pl 17KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653
  1. #!/usr/bin/perl -w
  2. # Script de creation de compte mail/LDAP (cas UNIX)
  3. # Copyright (c) 2004-2009 Evolix - Tous droits reserves
  4. use strict;
  5. use warnings;
  6. use Net::LDAP; # libnet-ldap-perl debian package
  7. use Getopt::Std;
  8. use Term::ReadKey; # libterm-readkey-perl debian package
  9. use MIME::Base64; #
  10. use Digest::SHA1; # libdigest-sha?(1)-perl debian package
  11. use Quota; # libquota-perl debian package
  12. use Crypt::SmbHash; # libcrypt-smbhash-perl debian package
  13. use MIME::Lite; # libmime-lite-perl debian package
  14. use Switch;
  15. # Parametres LDAP
  16. our $dn='dc=example,dc=com';
  17. our $host='127.0.0.1';
  18. our $binddn='cn=perl,ou=ldapusers,dc=example,dc=com';
  19. our $password='XXX';
  20. our $adminmail='admin@example.com';
  21. our $file='/var/log/evolix.log';
  22. my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst)=localtime(time);
  23. our $date= sprintf("%4d-%02d-%02d %02d:%02d ",$year+1900,$mon+1,$mday,$hour,$min);
  24. sub usage()
  25. {
  26. print STDERR << "EOF";
  27. usage: $0 [-hualmcdpx]
  28. -h : aide
  29. -u : ajoute un compte
  30. -a : ajoute un alias
  31. -l : liste les comptes
  32. -m : liste les alias
  33. -c : modifier compte
  34. -d : modifier alias
  35. -p : modifier password
  36. -x : supprimer un compte
  37. EOF
  38. exit;
  39. }
  40. sub add()
  41. {
  42. printf("Entrez le compte a creer (sans partie @...) : ");
  43. my $login = <STDIN>;
  44. chomp $login;
  45. my $ldap = Net::LDAP->new($host) or die "$@";
  46. my $mesg = $ldap->bind($binddn,password => $password, version => 3);
  47. our $edn = 'ou=people,' . $dn;
  48. # Voir si le compte existe deja
  49. my $result = $ldap->search(
  50. base => $edn,
  51. filter => "(uid=$login)",
  52. attrs => "uid"
  53. );
  54. $result->code && die $result->error;
  55. if ($result->entries) { printf("Erreur, ce compte existe deja...\n"); exit; }
  56. # TODO : detecter si un @ dans le login
  57. # TODO : generer un mot de passe
  58. printf("Entrez le mot de passe : ");
  59. ReadMode('noecho');
  60. my $pass = ReadLine(0);
  61. chomp $pass;
  62. ReadMode('normal');
  63. printf("\n");
  64. # Recuperer le max(UID) +1
  65. $result = $ldap->search(
  66. base => $dn,
  67. filter => "(objectClass=posixAccount)",
  68. attrs => "uidNumber"
  69. );
  70. $result->code && die $result->error;
  71. my $uid = 10000; # Les uidNumber commencent a 10000
  72. my @entries = $result->entries;
  73. my $entr;
  74. foreach $entr (@entries) {
  75. if ( $entr->get_value("uidNumber") > $uid ) {
  76. $uid = $entr->get_value("uidNumber");
  77. }
  78. }
  79. $uid++;
  80. # Ajouter l'enregistrement
  81. # set SSHA1 LDAP passwd with http://www.taclug.org/documents/openldap_presentation.html
  82. my $ctx = Digest::SHA1->new;
  83. $ctx->add($pass);
  84. $ctx->add('salt');
  85. my $hashedPasswd = '{SSHA}' . encode_base64($ctx->digest . 'salt' ,'');
  86. $result = $ldap->add( 'uid='. $login .','. $edn ,
  87. attr => [
  88. 'uid' => $login,
  89. 'sn' => $login,
  90. 'cn' => $login,
  91. 'objectclass' => ['inetOrgPerson','posixAccount','shadowAccount','mailAccount'],
  92. 'uidNumber' => $uid,
  93. 'gidNumber' => '10000',
  94. 'userPassword' => $hashedPasswd,
  95. 'homeDirectory' => '/home/' . $login,
  96. 'loginShell' => '/bin/bash',
  97. 'mailacceptinggeneralid' => $login,
  98. 'maildrop' => $login,
  99. 'accountActive' => 'TRUE',
  100. 'authsmtpActive' => 'TRUE',
  101. 'courierActive' => 'TRUE',
  102. 'webmailActive' => 'TRUE'
  103. ]
  104. ) or die "heh : $!";
  105. $result->code && die $result->error;
  106. $ldap->unbind;
  107. # $HOME
  108. mkdir "/home/$login/",0700 ;
  109. # TODO : voir pourquoi les drois ne sont pas pris en compte
  110. chmod 0700,"/home/$login/";
  111. chown $uid,10000,"/home/$login/";
  112. # QUOTA
  113. Quota::setqlim(Quota::getqcarg("/home"), $uid, 1024000, 1536000, 0, 0, 1, 0);
  114. # INIT MAIL
  115. my $msg = MIME::Lite->new(
  116. From => $adminmail,
  117. To => $login,
  118. CC => '',
  119. Subject => "Initialisation du compte",
  120. Type => 'TEXT',
  121. Data => "Ceci est un mail d'initialisation de votre compte."
  122. );
  123. MIME::Lite->send('smtp', "localhost", Timeout=>60);
  124. $msg -> send;
  125. printf("Ajout OK\n");
  126. # on log
  127. open F, ">>$file";
  128. print F ("$date [add.pl] Ajout compte $login\n");
  129. close F;
  130. }
  131. sub aadd()
  132. {
  133. printf("Entrez l'alias a creer : ");
  134. my $alias = <STDIN>;
  135. chomp $alias;
  136. # TODO : voir si l'alias est correct...
  137. my $ldap = Net::LDAP->new($host) or die "$@";
  138. my $mesg = $ldap->bind($binddn,password => $password, version => 3);
  139. our $edn = 'ou=people,' . $dn;
  140. # Voir si le compte existe deja
  141. my $result = $ldap->search(
  142. base => $edn,
  143. filter => "(mailacceptinggeneralid=$alias)",
  144. attrs => "mailacceptinggeneralid"
  145. );
  146. $result->code && die $result->error;
  147. if ($result->entries) { printf("Erreur, cet alias existe deja...\n"); exit; }
  148. printf("Entrez vers ou l'alias pointe : ");
  149. my $drop = <STDIN>;
  150. chomp $drop;
  151. $result = $ldap->add( 'mailacceptinggeneralid='. $alias .','. $edn ,
  152. attr => [
  153. 'mailacceptinggeneralid' => $alias,
  154. 'maildrop' => $drop,
  155. 'objectclass' => ['mailAlias'],
  156. 'accountActive' => 'TRUE'
  157. ]
  158. ) or die "heh : $!";
  159. $mesg->code && die $mesg->error;
  160. $ldap->unbind;
  161. printf("Ajout OK\n");
  162. # on log
  163. open F, ">>$file";
  164. print F ("$date [add.pl] Ajout alias $alias\n");
  165. close F;
  166. }
  167. sub liste1()
  168. {
  169. my $ldap = Net::LDAP->new($host) or die "$@";
  170. my $mesg = $ldap->bind($binddn,password => $password, version => 3);
  171. my $result = $ldap->search(
  172. base => $dn,
  173. filter => "(objectClass=mailAccount)",
  174. attrs => "uid"
  175. );
  176. $result->code && die $result->error;
  177. my @entries = $result->entries;
  178. my $entr;
  179. my @liste;
  180. foreach $entr (@entries) {
  181. my $mailacc ="";
  182. foreach my $value ($entr->get_value("mailacceptinggeneralid")) {
  183. $mailacc = $value.",".$mailacc;
  184. }
  185. $mailacc =~ s/,$//;
  186. my $maildrop ="";
  187. foreach my $value ($entr->get_value("maildrop")) {
  188. $maildrop = $value.",".$maildrop;
  189. }
  190. $maildrop =~ s/,$//;
  191. @liste = ($entr->get_value("uid").":".$mailacc."->".$maildrop,@liste);
  192. }
  193. $ldap->unbind;
  194. my @out;
  195. @out = sort @liste;
  196. foreach $entr (@out) {
  197. print $entr."\n";
  198. }
  199. }
  200. sub liste2()
  201. {
  202. my $ldap = Net::LDAP->new($host) or die "$@";
  203. my $mesg = $ldap->bind($binddn,password => $password, version => 3);
  204. my $result = $ldap->search(
  205. base => $dn,
  206. filter => "(objectClass=mailAlias)",
  207. attrs => "mailacceptinggeneralid"
  208. );
  209. $result->code && die $result->error;
  210. my @entries = $result->entries;
  211. my $entr;
  212. my @liste;
  213. foreach $entr (@entries) {
  214. my $maildrop ="";
  215. foreach my $value ($entr->get_value("maildrop")) {
  216. $maildrop = $value.",".$maildrop;
  217. }
  218. $maildrop =~ s/,$//;
  219. @liste = ($entr->get_value("mailacceptinggeneralid").":".$maildrop,@liste);
  220. }
  221. $ldap->unbind;
  222. my @out;
  223. @out = sort @liste;
  224. foreach $entr (@out) {
  225. print $entr."\n";
  226. }
  227. }
  228. sub adel() {
  229. printf("Entrez l'alias a effacer : ");
  230. my $alias = <STDIN>;
  231. chomp $alias;
  232. my $ldap = Net::LDAP->new($host) or die "$@";
  233. my $mesg = $ldap->bind($binddn,password => $password, version => 3);
  234. my $dndelete = 'mailacceptinggeneralid=' . $alias .',ou=people,'. $dn;
  235. $ldap->delete( $dndelete );
  236. $ldap->unbind;
  237. printf("Suppression OK\n");
  238. }
  239. # modification d'un compte
  240. sub mod() {
  241. printf("Entrez le compte a modifier: ");
  242. my $login = <STDIN>;
  243. chomp $login;
  244. my $ldap = Net::LDAP->new($host) or die "$@";
  245. my $mesg = $ldap->bind($binddn,password => $password, version => 3);
  246. my $result = $ldap->search(
  247. base => $dn,
  248. filter => "(uid=$login)",
  249. );
  250. $result->code && die $result->error;
  251. print "Compte " . $result->entry(0)->get_value("uid") . " trouvé\n\n";
  252. print "=> Mail(s) accepté(s) pour ce compte :\n";
  253. foreach my $value ($result->entry(0)->get_value("mailacceptinggeneralid")) {
  254. print "- " . $value . "\n";
  255. }
  256. print "\n";
  257. print "=> Ce compte est renvoyé vers :\n";
  258. foreach my $value ($result->entry(0)->get_value("maildrop")) {
  259. print "- " . $value . "\n";
  260. }
  261. print "\n";
  262. print "Que voulez-vous faire ?\n";
  263. print "(activer|desactiver|ajouter-mail|suppr-mail|ajouter-redir|suppr-redir)\n";
  264. my $action = <STDIN>;
  265. chomp $action;
  266. my $actiondn = 'uid=' . $login .',ou=people,'. $dn;
  267. switch ($action) {
  268. case (/^activer/i) {
  269. $ldap->modify( $actiondn, replace => { 'AccountActive' => 'TRUE' } );
  270. print "compte $login activé\n";
  271. # on log
  272. open F, ">>$file";
  273. print F ("$date [add.pl] Activation compte $login\n");
  274. close F;
  275. }
  276. case (/^d.sactiver/i) {
  277. $ldap->modify( $actiondn, replace => { 'AccountActive' => 'FALSE' } );
  278. print "compte $login desactivé\n";
  279. open F, ">>$file";
  280. print F ("$date [add.pl] Desactivation compte $login\n");
  281. close F;
  282. }
  283. case (/^ajouter.?mail/i) {
  284. printf("Entrez le mail a ajouter : ");
  285. my $newmail = <STDIN>;
  286. chomp $newmail;
  287. $ldap->modify( $actiondn, add => { 'mailacceptinggeneralid' => $newmail } );
  288. print "Ajout $newmail OK\n";
  289. open F, ">>$file";
  290. print F ("$date [add.pl] Ajout mail $newmail sur compte $login\n");
  291. close F;
  292. }
  293. case (/^suppr.?mail/i) {
  294. printf("Entrez le mail a supprimer : ");
  295. my $oldmail = <STDIN>;
  296. chomp $oldmail;
  297. $ldap->modify( $actiondn, delete => { 'mailacceptinggeneralid' => $oldmail } );
  298. print "Suppression $oldmail OK\n";
  299. open F, ">>$file";
  300. print F ("$date [add.pl] Suppression mail $oldmail sur compte $login\n");
  301. close F;
  302. }
  303. case (/^ajouter.?redir/i) {
  304. printf("Entrez la redirection a ajouter : ");
  305. my $newredir = <STDIN>;
  306. chomp $newredir;
  307. $ldap->modify( $actiondn, add => { 'maildrop' => $newredir } );
  308. print "Ajout $newredir OK\n";
  309. open F, ">>$file";
  310. print F ("$date [add.pl] Ajout redirection $newredir sur compte $login\n");
  311. close F;
  312. }
  313. case (/^suppr.?redir/i) {
  314. printf("Entrez la redirection a supprimer : ");
  315. my $oldredir = <STDIN>;
  316. chomp $oldredir;
  317. $ldap->modify( $actiondn, delete => { 'maildrop' => $oldredir } );
  318. print "Suppression $oldredir OK\n";
  319. open F, ">>$file";
  320. print F ("$date [add.pl] Suppression redirection $oldredir sur compte $login\n");
  321. close F;
  322. }
  323. }
  324. $ldap->unbind;
  325. }
  326. # modification d'un alias
  327. sub amod() {
  328. printf("Entrez l'alias a modifier: ");
  329. my $alias = <STDIN>;
  330. chomp $alias;
  331. my $ldap = Net::LDAP->new($host) or die "$@";
  332. my $mesg = $ldap->bind($binddn,password => $password, version => 3);
  333. my $result = $ldap->search(
  334. base => $dn,
  335. filter => "(&(mailacceptinggeneralid=$alias)(objectClass=mailAlias))",
  336. );
  337. $result->code && die $result->error;
  338. print "Alias " . $result->entry(0)->get_value("mailacceptinggeneralid") . " trouvé\n\n";
  339. print "=> Mail(s) accepté(s) pour cet alias :\n";
  340. foreach my $value ($result->entry(0)->get_value("mailacceptinggeneralid")) {
  341. print "- " . $value . "\n";
  342. }
  343. print "\n";
  344. print "=> Cet alias est renvoyé vers :\n";
  345. foreach my $value ($result->entry(0)->get_value("maildrop")) {
  346. print "- " . $value . "\n";
  347. }
  348. print "\n";
  349. print "Que voulez-vous faire ?\n";
  350. print "(activer|desactiver|suppr|ajouter-mail|suppr-mail|ajouter-redir|suppr-redir)\n";
  351. my $action = <STDIN>;
  352. chomp $action;
  353. my $actiondn = 'mailacceptinggeneralid=' . $alias .',ou=people,'. $dn;
  354. switch ($action) {
  355. case (/^activer/i) {
  356. $ldap->modify( $actiondn, replace => { 'AccountActive' => 'TRUE' } );
  357. print "Alias $alias activé\n";
  358. open F, ">>$file";
  359. print F ("$date [add.pl] Activation alias $alias\n");
  360. close F;
  361. }
  362. case (/^d.sactiver/i) {
  363. $ldap->modify( $actiondn, replace => { 'AccountActive' => 'FALSE' } );
  364. print "Alias $alias desactivé\n";
  365. open F, ">>$file";
  366. print F ("$date [add.pl] Desactivation alias $alias\n");
  367. close F;
  368. }
  369. case (/^ajouter.?mail/i) {
  370. printf("Entrez le mail a ajouter : ");
  371. my $newmail = <STDIN>;
  372. chomp $newmail;
  373. $ldap->modify( $actiondn, add => { 'mailacceptinggeneralid' => $newmail } );
  374. print "Ajout $newmail OK\n";
  375. open F, ">>$file";
  376. print F ("$date [add.pl] Ajout mail $newmail pour alias $alias\n");
  377. close F;
  378. }
  379. case (/^suppr.?mail/i) {
  380. printf("Entrez le mail a supprimer : ");
  381. my $oldmail = <STDIN>;
  382. chomp $oldmail;
  383. $ldap->modify( $actiondn, delete => { 'mailacceptinggeneralid' => $oldmail } );
  384. print "Suppression $oldmail OK\n";
  385. open F, ">>$file";
  386. print F ("$date [add.pl] Suppresion mail $oldmail pour alias $alias\n");
  387. close F;
  388. }
  389. case (/^ajouter.?redir/i) {
  390. printf("Entrez la redirection a ajouter : ");
  391. my $newredir = <STDIN>;
  392. chomp $newredir;
  393. $ldap->modify( $actiondn, add => { 'maildrop' => $newredir } );
  394. print "Ajout $newredir OK\n";
  395. open F, ">>$file";
  396. print F ("$date [add.pl] Ajout redirection $newredir pour alias $alias\n");
  397. close F;
  398. }
  399. case (/^suppr.?redir/i) {
  400. printf("Entrez la redirection a supprimer : ");
  401. my $oldredir = <STDIN>;
  402. chomp $oldredir;
  403. $ldap->modify( $actiondn, delete => { 'maildrop' => $oldredir } );
  404. print "Suppression $oldredir OK\n";
  405. open F, ">>$file";
  406. print F ("$date [add.pl] Suppression redirection $oldredir pour alias $alias\n");
  407. close F;
  408. }
  409. case (/^suppr/i) {
  410. $ldap->delete( $actiondn );
  411. print "Suppression alias $alias OK\n";
  412. open F, ">>$file";
  413. print F ("$date [add.pl] Suppression alias $alias\n");
  414. close F;
  415. }
  416. }
  417. $ldap->unbind;
  418. }
  419. # modification d'un password
  420. sub passwd() {
  421. printf("Entrez le compte pour réinitialiser le mot de passe : ");
  422. my $login = <STDIN>;
  423. chomp $login;
  424. my $ldap = Net::LDAP->new($host) or die "$@";
  425. my $mesg = $ldap->bind($binddn,password => $password, version => 3);
  426. my $result = $ldap->search(
  427. base => $dn,
  428. filter => "(uid=$login)",
  429. );
  430. $result->code && die $result->error;
  431. print "Compte " . $result->entry(0)->get_value("uid") . " trouvé\n";
  432. my $actiondn = 'uid=' . $login .',ou=people,'. $dn;
  433. print "Entrez le nouveau mot de passe : ";
  434. ReadMode('noecho');
  435. my $pass = ReadLine(0);
  436. chomp $pass;
  437. ReadMode('normal');
  438. printf("\n");
  439. # set SSHA1 LDAP passwd with http://www.taclug.org/documents/openldap_presentation.html
  440. my $ctx = Digest::SHA1->new;
  441. $ctx->add($pass);
  442. $ctx->add('salt');
  443. my $hashedPasswd = '{SSHA}' . encode_base64($ctx->digest . 'salt' ,'');
  444. $ldap->modify( $actiondn, replace => { 'userPassword' => $hashedPasswd } );
  445. print "Réinitialisation password $login OK\n";
  446. open F, ">>$file";
  447. print F ("$date [add.pl] Modification passwd sur le compte $login\n");
  448. close F;
  449. $ldap->unbind;
  450. }
  451. # suppression d'un compte
  452. sub del()
  453. {
  454. printf("Entrez le compte a supprimer : ");
  455. my $login = <STDIN>;
  456. chomp $login;
  457. # initialisation de la connexion LDAP
  458. my $ldap = Net::LDAP->new($host) or die "$@";
  459. my $mesg = $ldap->bind($binddn,password => $password, version => 3);
  460. my $result = $ldap->search(
  461. base => $dn,
  462. filter => "(uid=$login)",
  463. );
  464. $result->code && die $result->error;
  465. if (! $result->entries) {
  466. $ldap->unbind;
  467. printf("Erreur, ce compte n'existe pas...\n"); exit;
  468. }
  469. print "Compte " . $result->entry(0)->get_value("uid") . " trouvé\n";
  470. my $dndelete = 'uid=' . $login .',ou=people,'. $dn;
  471. $ldap->delete( $dndelete );
  472. print "Suppression de l'annuaire LDAP OK\n";
  473. # On vire le $HOME
  474. my $day = $date;
  475. $day =~ s/ .*//;
  476. `mv /home/$login /home/$login.backup$day`;
  477. print "Suppression du repertoire /home/$login\n";
  478. open F, ">>$file";
  479. print F ("$date, suppression compte $login\n");
  480. close F;
  481. $ldap->unbind;
  482. }
  483. # main() : options possibles
  484. my %options=();
  485. my $opt_string = 'hualmcdpx';
  486. getopts("$opt_string",\%options);
  487. if ($options{h}) { &usage; }
  488. elsif ($options{u}) { &add; }
  489. elsif ($options{a}) { &aadd; }
  490. elsif ($options{l}) { &liste1; }
  491. elsif ($options{m}) { &liste2; }
  492. elsif ($options{c}) { &mod; }
  493. elsif ($options{d}) { &amod; }
  494. elsif ($options{p}) { &passwd; }
  495. elsif ($options{x}) { &del; }
  496. else { &usage; }