我的模块中有子程序,它使用shadow
文件上的正则表达式搜索检查(常规)用户密码年龄:
Module.pm
my $pwdsetts_dump = "tmp/shadow_dump.txt";
system("cat /etc/shadow > $pwdsetts_dump");
open (my $fh1, "<", $pwdsetts_dump) or die "Could not open file '$pwdsetts_dump': $!";
sub CollectPWDSettings {
my @pwdsettings;
while (my $array = <$fh1>) {
if ($array =~ /^(\S+)[:][$]\S+[:](1[0-9]{4})/) {
my $pwdchange = "$2";
if ("$2" eq "0") {
$pwdchange = "Next login";
}
my %hash = (
"Username" => $1,
"Last change" => $pwdchange
);
push (@pwdsettings, \%hash);
}
}
my $current_date = int(time()/86400); # epoch
my $ndate = shift @_; # n-days
my $search_date = int($current_date - $ndate);
my @sorted = grep{$_->{'Last change'} > $search_date} @pwdsettings;
return \@sorted;
}
脚本分为两个步骤: 1.加载所有密码设置 2.搜索超过n天的密码
在我的主脚本中,我使用以下脚本:
my ($user_changed_pwd);
if (grep{$_->{'Username'} eq $users_to_check} @{Module::CollectPWDSettings("100")}) {
$user_changed_pwd = "no";
}
else {
$user_changed_pwd = "yes";
}
第一步出现问题,AoH永远不会被填充。我也很确定这个子程序对我来说总是有效,strict
和warnings
从不抱怨它,现在坚持,因为某些原因它拒绝工作。
答案 0 :(得分:2)
我刚刚对我的/etc/shadow
运行你的正则表达式而没有匹配。如果我放弃前导1
我会得到一些点击。
E.g:
$array =~ /^(\S+)[:][$]\S+[:]([0-9]{4})/
但就个人而言 - 我建议不要尝试使用正则表达式,而是依赖/etc/shadow
定义为由:
分隔的事实。
my @fields = split ( /:/, $array );
$ 1包含很多东西,我怀疑你想要的是用户名 - 但是因为\S+
贪婪,你可能会意外地以加密密码结束。
这将是$fields[0]
。
然后来自man shadow
的“最后更改”字段为$fields[2]
。
答案 1 :(得分:0)
我认为你的正则表达式是主要问题。不要忘记\S
匹配包括冒号:
在内的任何非空格字符,\S+
会尝试尽可能匹配,因此它会愉快地跳过多个字段文件
我认为使用split
将每条记录分隔为冒号分隔的字段是一种更好的方法。我也认为,最好将数据存储为将用户名与其密码历史相关联的哈希值,而不是两元素哈希数组@pwdsettings
这是我怎么写的。它会打印密码历史记录大于90天的所有用户名列表
use strict;
use warnings;
use Time::Seconds 'ONE_DAY';
my @shadow = do {
open my $fh, '<', '/etc/shadow' or die qq{Unable to open "/etc/shadow" for input: $!};
<$fh>;
};
print "$_\n" for @{ collect_pwd_settings(90) };
sub collect_pwd_settings {
my ($ndate) = @_;
my %pwdsettings;
for ( @shadow ) {
my ($user, $pwdchange) = (split /:/)[0,2];
$pwdsettings{$user} = $pwdchange;
}
my $current_date = time / ONE_DAY;
my @filtered = grep { $current_date - $pwdsettings{$_} > $ndate } keys %pwdsettings;
return \@filtered;
}