客观的:检查/etc/shadow
用户密码是否被锁定,即 /etc/shadow 中第二个字段(包含用户的哈希密码)中的第一个字符是否是感叹号('!')
期望的输出:名为$disabled
包含“True”或“False”的变量
用户名在$uname
变量中,我做了这样的事情:
disabled=`cat /etc/shadow |grep $uname |awk -F\: '{print$2}'`
# I now have the password and need one more pipe into the check for the character
# which is where I'm stuck. I would like to do like (in PHP syntax):
| VARIABLE=="!"?"True":"False"`
这是一个脚本的片段,将由 Cron 以 root 权限运行,因此可以访问所有所需的信息。
答案1
不要shadow
手动解析文件
如果您未能考虑到所有可能发生的情况,则解析此类文件是脆弱的(例如,禁用的密码通常被编码为单个*
;其他解决方案是否可以处理该问题?)。
此外,身份验证可能不会通过shadow
(而是通过 NIS 或 ldap 或谁知道什么)进行。有一些标准工具可以为您处理所有这些问题。在这种情况下,passwd
:
-S,--状态 显示帐户状态信息。状态信息由7个字段组成。第一个字段是用户的登录名。第二个字段指示用户帐户是否具有锁定密码 (L)、没有密码 (NP) 或具有可用密码 (P)。第三个字段给出最后一次密码更改的日期。接下来的四个字段是密码的最短期限、最长期限、警告期限和不活动期限。这些年龄以天数表示。
所以passwd -S | cut -d ' ' -f 2
会产生你需要的东西。一个简单的 if/then 会将其转换为您想要的变量:
if [ "$(passwd -S "$USER" | cut -d ' ' -f 2)" = "P" ]
then
disabled="False"
else
disabled="True"
fi
这同样适用于锁定用户密码;这最好通过usermod
(--lock
选项)完成,而不是shadow
手动编辑。
答案2
为什么不直接用 awk 来完成这一切呢?
awk -F: '/<username>/ {if(substr($2,1,1) == "!"){print "True"} else {print "False"}}' /etc/shadow
答案3
U=$user LC_ALL=C awk -F: < /etc/shadow '
$1 "" == ENVIRON["U"] {
user_found = 1
if ($2 ~ /^!/) {
print "True"
exit 0
} else {
print "False"
exit 1
}
}
END {
if (!user_found) {
print "False"
print "User "ENVIRON["U"]" not found" > "/dev/stderr"
exit 2
}
}'
$1 "" == ENVIRON["U"]
将第一个字段与ENVIRON["U"]
词法进行比较。如果没有,如果字段看起来像数字(例如导致匹配或匹配) ""
,则它们最终可能会进行数字比较。inf
INF
Infinity
如果没有LC_ALL=C
,由于某些awk
实现使用 strcoll()
词法==
比较,它最终可能会检查排序相同的用户名的错误条目。
答案4
当 passwd 字段为 string 时,用户被锁定*LK*
,但您无法检查它,因为/etc/shadow
出于安全原因只能由 root 读取。
如果权限不是问题,请尝试以下操作:
while IFS=: read USER PW REST; do
if [ "$USER" = "$uname" ]; then
if [ "$PW" = "*LK*" ]; then
echo "$uname" Locked
fi
fi
done < /etc/shadow
编辑:移动 IFS=: 以使代码更简单