Chinaunix首页 | 论坛 | 博客
  • 博客访问: 5351977
  • 博文数量: 1144
  • 博客积分: 11974
  • 博客等级: 上将
  • 技术积分: 12312
  • 用 户 组: 普通用户
  • 注册时间: 2005-04-13 20:06
文章存档

2017年(2)

2016年(14)

2015年(10)

2014年(28)

2013年(23)

2012年(29)

2011年(53)

2010年(86)

2009年(83)

2008年(43)

2007年(153)

2006年(575)

2005年(45)

分类: LINUX

2009-12-09 12:09:28

#!/usr/local/bin/perl

# passwd replacement for solaris < 10
# try to make users select a stronger password
# copyright 2009.05.04 jeremy kister 
# v2009061901

# to install, simply:
# mv /usr/bin/passwd /usr/bin/passwd.orig
# chmod 0 /usr/bin/passwd.orig
# mv passwd.pl /usr/bin/passwd
# chown root:sys /usr/bin/passwd
# chmod 6555 /usr/bin/passwd
#
# set CRYPT_DEFAULT=1 in /etc/security/policy.conf
# modify $NIS (below) - 0 if not using NIS, 1 if using NIS

use strict;
use Crypt::PasswdMD5 qw(unix_md5_crypt);

my $NIS = 1;

$SIG{INT} = $SIG{QUIT} = $SIG{HUP} = sub { cleanup(); };

foreach my $key (keys %ENV){
    # make suid perl safer..
    next if($key eq 'USER');
    delete $ENV{$key};
}

my $user = $ENV{USER};
if(@ARGV >= 1){
    if( $< ){
        die "I don't support any arguments\n";
    }else{
        if(@ARGV == 1){
            $user = shift;
        }else{
            die "I'll only take a username as an argument\n";
        }
    }
}

unless($user =~ /^[a-z]{3,12}[0-9]?$/){
    die "invalid user: $user\n";
}

die "wont change root pw\n" if($user eq 'root');

srand(time() ^($$ + ($$ << 15)));
my @set = ('.', '/', '0'..'9', 'A'..'Z', 'a'..'z');
my $salt = join ('', map { $set[ rand ( @set) ] } (1 .. 8));

open(TSTMP, ">/etc/stmp.$$") || die "cannot write to /etc/stmp.$$: $!\n";
close TSTMP;
chmod(0600, "/etc/stmp.$$") || die "cannot set file mode on /etc/stmp.$$: $!\n";

my $have_link;
for(1..5){
    if( link("/etc/stmp.$$", "/etc/stmp") ){
        $have_link = 1;
        last;
    }else{
        sleep 2;
    }
}

unless($have_link){
    print "passwd: Sorry, could not obtain stmp lock.\n";
    exit_evil();
}

my $ocrypt;
open(SHADOW, "/etc/shadow") || die "cannot read shadow file: $!\n";
my @shadow = ;
close SHADOW;
foreach(@shadow){
    if(/^$user:([^:]+):/){
        $ocrypt = $1;
        last;
    }
}

unless($user && $ocrypt){
    print "passwd: User unknown: $user\n";
    exit_evil();
}

my $opw;
print "passwd: Changing password for $user\n";
if( $< ){
    print "Enter existing login password: ";
    system "stty -echo";
    chomp($opw=);
    print "\n";
}

if( $ocrypt eq crypt($opw, $ocrypt) || $< == 0 ){

    my $npw;
    system "stty -echo";
    for my $round (1..3){
        print "New Password: ";
        chomp($npw=);
        print "\n";

        # check strength
        my $err;
        my %types;
        if($npw =~ /$user/i){
            print "passwd: Sorry, can't use your username in your password\n";
            $err++;
        }
        my $rev = reverse($user);
        if($npw =~ /$rev/i){
            print "passwd: Sorry, can't use the reverse of your username in your password\n";
            $err++;
        }
        if(length($npw) < 8 || length($npw) > 255){
            print "passwd: Sorry, password must be 8 to 255 characters.\n";
            $err++;
        }
        $types{uc} = 1 if($npw =~ /[A-Z]/);
        $types{lc} = 1 if($npw =~ /[a-z]/);
        $types{num} = 1 if($npw =~ /[0-9]/);
        $types{special} = 1 if($npw =~ /[^A-Z0-9]/i);
        
        if(keys %types < 3){
            print "Password must contain characters from at least three of the following four classes:\n",
                  " * English Upper Case Letters (A, B, C, .. Z)\n",
                  " * English Lower Case Letters (a, b, c, .. z)\n",
                  " * Westernized Arabic Numerals (0, 1, 2, .. 9)\n",
                  " * Non-alphanumeric (special characters, e.g. punctuation symbols)\n";
            $err++;
        }

        unless($err){
            print "Re-enter new Password: ";
            chomp(my $rpw=);

            if($npw ne $rpw){
                print "passwd(SYSTEM): They don't match.\n";
                $err++;
            }
        }

        if($err){
            if($round == 3){
                exit_evil();
            }else{
                print "\n",
                      "Please try again\n";
            }
        }else{
            last;
        }
    }
    system("stty echo");
    print "\n";

    my $ncrypt = unix_md5_crypt($npw, $salt);
    my $days = sprintf( '%d', (time() / 86400) );

    open(STMP, ">>/etc/stmp") || die "could not append to stmp: $!\n";
    foreach(@shadow){
        if(/^$user:/){
            print STMP "${user}:${ncrypt}:${days}::::::\n";
        }else{
            print STMP;
        }
    }
    close STMP;
   
    rename("/etc/stmp","/etc/shadow") || die "cannot rename stmp to shadow: $!\n";
    unlink("/etc/stmp.$$") || die "cannot unlink stmp.$$: $!\n";
    chmod(0400, "/etc/shadow") || die "cannot set file mode on /etc/shadow: $!\n";

    if($NIS){
        system("cd /var/yp ; /usr/local/bin/make >/dev/null 2>&1");
    }

}else{
    print "passwd: Sorry, wrong passwd\n";
    exit_evil();
}

sub exit_evil {
    print "Permission denied\n";
    cleanup();
    exit 1;
}

sub cleanup {
    unlink("/etc/stmp.$$");
    unlink("/etc/stmp") if($have_link);
    system("stty echo");
    exit;
}
阅读(1200) | 评论(0) | 转发(0) |
0

上一篇:antiabuse.pl

下一篇:qmail_check_default.pl

给主人留下些什么吧!~~