BASH:检查 /etc/shadow 用户密码是否被锁定

BASH:检查 /etc/shadow 用户密码是否被锁定

客观的:检查/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"]词法进行比较。如果没有,如果字段看起来像数字(例如导致匹配或匹配) "",则它们最终可能会进行数字比较。infINFInfinity

如果没有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=: 以使代码更简单

相关内容