cae32 (cae32) wrote,
cae32
cae32

Старая версия mailadmin

Почти дембельский аккорд в Ростовэлектросвязи. Дембельским аккордом было объединение баз Телеграфа и Ростовэлектросвязи (+Батайск, +Азов) без перерыва сервиса. Гаржусь! ;-)

Администрилка
вот:

#!/usr/bin/perl
# Copyright (C) 2001 Sergey A. Eremenko
# Created for JSC Rostovtelecom
# Licensed by GPL
#
# $Id: mailadmin v1.0.0 $
#
# ИДЕЯ:
#
# Установить mailadmin в качестве shell для администраторов почты.
# Или для тех, кто входит в группу cyrus и уже имеет нормальный shell,
# достаточно запустить его. Права на исходник ставятся --x--x---, чтобы
# никто не мог подсмотреть код.
#
#

use English ;
use Term::ReadLine ;
use Term::ReadKey ;
use Socket ;
use POSIX qw/isatty/ ;
use IO::Handle ;
use Sys::Syslog qw(:DEFAULT setlogsock) ;
use IMAP::Admin ;
use Getopt::Std ;

sub exec_jah_admin {
        my ($pid,$exit_code) ;
        my ($command,$username,$password) = @_ ;

        syslog ('debug',(caller (0))[3]."(".join (",",@_).")") ;
        if ($pid = open (F,"|-")) {
                F->autoflush (1) ;
                if (defined ($password)) {
                        print F $password || warn "Can't print to pipe: $!\n" ;
                }
                close (F) || warn "Can't close pipe: $!\n" ;
                $exit_code = $? ;
                (0==$exit_code) || warn "$jah_admin returns $exit_code\n" ;
                syslog ('debug',"%s returns %d",$jah_admin,$exit_code) ;
                return $exit_code ;
        }
        else {
                warn "Can't fork: $!\n" unless defined ($pid) ;
                if (defined ($username)) {
                        exec ($jah_admin,"-ZD",$jah_dbname,$command,$username) ||
                            die "Can't exec $jah_admin: $!\n" ;
                }
                else {
                        exec ($jah_admin,"-ZD",$jah_dbname,$command) ||
                            die "Can't exec $jah_admin: $!\n" ;
                }
        }
}

sub help {
        syslog ('debug',(caller (0))[3]."(".join (",",@_).")") ;
        print ( "?, help                                        - display this help\n" .
                "quit, exit, ^D                         - quit this program\n" .
                "ls [boxes...], list [boxes...] - list mailboxes (allow IMAP wildcards)\n" .
                "mk boxes..., create boxes...   - create mailbox\n" .
                "rm boxes..., delete boxes...   - delete mailbox\n" .
                "mv boxes..., rename boxes...   - rename mailbox\n" .
                "lk boxes..., lock boxes...     - lock mailbox\n" .
                "ul boxes..., unlock boxes...   - unlock mailbox\n" .
                "ch boxes..., check boxes...    - check password\n" .
                "pw boxes..., passwd boxes...   - change password\n" .
                ""
        ) ;
}

sub list_mailbox {
        my (@names) ;

        syslog ('debug',(caller (0))[3]."(".join (",",@_).")") ;

        if (!defined (@_) || $#_<0) {
                $_[0] = "*" ;
        }
        foreach (@_) {
                if (!defined (@names = $imap->list ("user." . $_))) {
                        warn ("can't list imap box user.".$_.": ".$imap->{Error}."\n") ;
                        syslog ('info',"can't list imap box user.%s: %s",$_,$imap->{Error}) ;
                        return ;
                }
                foreach (@names) {
                        print $_,"\n" ;
                        $_ =~ s/^user\.// ;
                        &exec_jah_admin ($_) ;
                }
        }
}

sub create_mailbox {
        my $new_password,$retype_password ;

        syslog ('debug',(caller (0))[3]."(".join (",",@_).")") ;

        foreach (@_) {
                if (!$opt_j) {
                        print "$_ New password: " ;
                        Term::ReadKey::ReadMode 'noecho' ;
                        $new_password = Term::ReadKey::ReadLine 0 ;
                        chomp $new_password ;
                        Term::ReadKey::ReadMode 'restore' ;
                        print "\n" ;
                        if ($new_password eq "") {
                                warn "Password clear, skip operation\n" ;
                                syslog ('debug','password clear') ;
                                return ;
                        }
                        print "$_ Retype new password: " ;
                        Term::ReadKey::ReadMode 'noecho' ;
                        $retype_password = Term::ReadKey::ReadLine 0 ;
                        chomp $retype_password ;
                        Term::ReadKey::ReadMode 'restore' ;
                        print "\n" ;
                        if ($new_password ne $retype_password) {
                                warn "Mismatch, skip operation\n" ;
                                syslog ('debug','mismatch') ;
                                return ;
                        }
                }
# create imap
                if ($imap->create ("user." . $_)) {
                        warn ("can't create imap box user.".$_.": ".$imap->{Error}."\n") ;
                        syslog ('info',"can't create imap box user.%s: %s",$_,$imap->{Error}) ;
                        return ;
                }
                if ($imap->set_acl ("user." . $_, $imap_admin_username, "lrswipdca")) {
                        warn ("can't set_acl imap box user.".$_.": ".$imap->{Error}."\n") ;
                        syslog ('info',"can't set_acl imap box user.%s: %s",$_,$imap->{Error}) ;
                        return ;
                }
# create acl for mailadmin
                if (!$opt_j) {
                        &exec_jah_admin ("-c",$_,$new_password) ;
                }
        }
}

sub delete_mailbox {
        syslog ('debug',(caller (0))[3]."(".join (",",@_).")") ;

        foreach (@_) {
# delete imap
                if ($imap->delete ("user." . $_)) {
                        warn ("can't delete imap box user.".$_.": ".$imap->{Error}."\n") ;
                        syslog ('info',"can't delete imap box user.%s: %s",$_,$imap->{Error}) ;
                        return ;
                }
                if (!$opt_j) {
                        &exec_jah_admin ("-d",$_) ;
                }
        }
}

sub rename_mailbox {
        my $new_name ;

        syslog ('debug',(caller (0))[3]."(".join (",",@_).")") ;

        foreach (@_) {
                if (!$opt_j) {
                        print "$_ New name: " ;
                        $new_name = Term::ReadKey::ReadLine 0 ;
                        chomp $new_name ;
# rename imap
                        if ($imap->rename ("user." . $_, "user." . $new_name)) {
                                warn ("can't rename imap box user.".$_.": ".$imap->{Error}."\n") ;
                                syslog ('info',"can't rename imap box user.%s: %s",$_,$imap->{Error}) ;
                                return ;
                        }
                        &exec_jah_admin ("-r",$_,$new_name) ;
                }
                else {
                        print "rename $_ impossible\n" ;
                }
        }
}

sub lock_user {
        syslog ('debug',(caller (0))[3]."(".join (",",@_).")") ;

        foreach (@_) {
                if (!$opt_j) {
                        &exec_jah_admin ("-l",$_) ;
                }
                else {
                        print "lock $_ impossible\n" ;
                }
        }
}

sub unlock_user {
        syslog ('debug',(caller (0))[3]."(".join (",",@_).")") ;

        foreach (@_) {
                if (!$opt_j) {
                        &exec_jah_admin ("-u",$_) ;
                }
                else {
                        print "unlock $_ impossible\n" ;
                }
        }
}

sub check_password {
        my $password ;

        syslog ('debug',(caller (0))[3]."(".join (",",@_).")") ;
        if ($opt_j) {
                print "check impossible\n" ;
                return ;
        }
        foreach (@_) {
                print "$_ Password: " ;
                Term::ReadKey::ReadMode 'noecho' ;
                $password = Term::ReadKey::ReadLine 0 ;
                chomp $password ;
                Term::ReadKey::ReadMode 'restore' ;
                print "\n" ;
                &exec_jah_admin ("-k",$_,$password) ;
        }
}

sub change_password {
        my $new_password,$retype_password ;

        syslog ('debug',(caller (0))[3]."(".join (",",@_).")") ;
        if ($opt_j) {
                print "change password impossible\n" ;
                return ;
        }
        foreach (@_) {
                print "$_ New password: " ;
                Term::ReadKey::ReadMode 'noecho' ;
                $new_password = Term::ReadKey::ReadLine 0 ;
                chomp $new_password ;
                Term::ReadKey::ReadMode 'restore' ;
                print "\n" ;
                if ($new_password eq "") {
                        warn "Password unchanged\n" ;
                        syslog ('debug','password clear') ;
                        return ;
                }
                print "$_ Retype new password: " ;
                Term::ReadKey::ReadMode 'noecho' ;
                $retype_password = Term::ReadKey::ReadLine 0 ;
                chomp $retype_password ;
                Term::ReadKey::ReadMode 'restore' ;
                print "\n" ;
                if ($new_password ne $retype_password) {
                        warn "Mismatch, not changed\n" ;
                        syslog ('debug','mismatch') ;
                        return ;
                }
                &exec_jah_admin ("-p",$_,$new_password) ;
        }
}

# главная программа

# конфигурация

getopts ("j") ;

if (!defined ($opt_j)) {
        (POSIX::isatty (STDIN)) || die "Can't use noninteractive tty\n" ;
}

$PROGRAM_NAME = 'mailadmin' ;
$prompt = (getpwuid ($UID))[0]. '@' . $PROGRAM_NAME . '% ' ;
$| = 1 ;
$imap_hostname = "localhost" ;
$imap_admin_username = "mailadmin" ;
$imap_admin_password = "" ;
$imap_protocol = getprotobyname ('tcp') || 6 ;
$imap_port = getservbyname ('imap','tcp') || 143 ;
$jah_dbname = "/usr/local/etc/jahpwd.db" ;
$jah_admin = "/usr/local/sbin/jahadm" ;
$max_command_length = 2 ;
$max_history_length = 25 ;

setlogsock 'unix' ;
openlog ($PROGRAM_NAME,'pid','local0') ;
syslog ('info','started by %s',(getpwuid ($UID))[0]) ;

$imap = new IMAP::Admin (Server => $imap_hostname,
                Login => $imap_admin_username,
                Password => $imap_admin_password,
                Port => $imap_port) ;
$term = new Term::ReadLine ($PROGRAM_NAME) ;

        # в историю включаем только строки более $max_command_length символов
$term->MinLine ($max_command_length+1) ;
        # в истории храним не более $max_history_length строк
$term->StifleHistory ($max_history_length) ;

$first_command = 1 ;
$last_command = 0 ;

while ($opt_j?$command = :defined ($command = $term->readline ($prompt))) {
        if (length ($command)>$max_command_length &&
                $prev_command eq $command && !$first_command) {
# если повторяется последняя команда, оставляем в истории только одну
# копию, типа как в deco
                $term->remove_history ($term->Attribs->{history_length}-1) ;
        }
        $first_command = 0 ;
# body
        $command =~ s/^\s+// ;
        $command =~ s/\s+$// ;
        ($command,@cmd_args) = split (/\s+/,$command) ;
        if ($command eq "" or $command =~ /^\?/ or $command =~ /^he?l?p?$/) {
                &help ;
        }
        elsif ($command =~ /^qu?i?t?$/ or $command =~ /^ex?i?t?$/) {
                $last_command = 1 ;
                last ;
        }
        elsif ($command =~ /^ls$/ or $command =~ /^lis?t?$/) {
                &list_mailbox (@cmd_args) ;
        }
        elsif ($command =~ /^mk$/ or $command =~ /^cre?a?t?e?$/) {
                &create_mailbox (@cmd_args) ;
        }
        elsif ($command =~ /^rm$/ or $command =~ /^del?e?t?e?$/) {
                &delete_mailbox (@cmd_args) ;
        }
        elsif ($command =~ /^mv$/ or $command =~ /^ren?a?m?e?$/) {
                &rename_mailbox (@cmd_args) ;
        }
        elsif ($command =~ /^lk$/ or $command =~ /^loc?k?$/) {
                &lock_user (@cmd_args) ;
        }
        elsif ($command =~ /^ul$/ or $command =~ /^unl?o?c?k?$/) {
                &unlock_user (@cmd_args) ;
        }
        elsif ($command =~ /^che?c?k?$/) {
                &check_password (@cmd_args) ;
        }
        elsif ($command =~ /^pw$/ or $command =~ /^pas?s?w?d?$/) {
                &change_password (@cmd_args) ;
        }
        else {
                warn "$command " . join (' ',@cmd_args) . ": invalid\n" ;
                syslog ('info',"invalid command: %s",
                    $command . ' ' . join (' ',@cmd_args)) ;
        }

        if (length ($command)>$max_command_length) {
                $prev_command = $command ;
        }
}

syslog ('info','finished by %s',(getpwuid ($UID))[0]) ;
closelog ;
$imap->close ;

if (!$last_command && !$opt_j) {
        print "\n" ;
}


Ходить туда только тем, кому интересно в коде копаться.
Subscribe

  • История Успеха

    Сбербизнес рекламирует свои ненавязчивые услуги вот каким чудесным текстом. Финал истории просто прекрасен. Омичи не подкачали, показали, что…

  • Люди везде одинаковы

    vitiay недавно был на курсах по обучению на тему "как заставить пролетария трудиться не за зарплату, а на субботнике". Как и следовало…

  • А вы думали, сыр-бор из-за древних камней?

    Перспективнейшей отраслью для НКР является горнорудная промышленность: недра республики богаты залежами различных металлов – железа, цинка, свинца,…

  • Post a new comment

    Error

    default userpic

    Your reply will be screened

    Your IP address will be recorded 

    When you submit the form an invisible reCAPTCHA check will be performed.
    You must follow the Privacy Policy and Google Terms of use.
  • 2 comments