Objective:ユーザーパスワードがロックされている場合、つまりユーザーのハッシュされたパスワードを含む/ etc/shadowの2番目のフィールドの最初の文字が感嘆符( '!')である場合、/etc/shadow
をチェックインします。
目的の出力:「True」または「False」のいずれかを含む$disabled
という名前の変数
ユーザー名は$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"`
これは、root権限でCronによって実行されるスクリプトのフラグメントであるため、必要なすべての情報にアクセスできます。
Awkですべてを実行しないのはなぜですか?
awk -F: '/<username>/ {if(substr($2,1,1) == "!"){print "True"} else {print "False"}}' /etc/shadow
shadow
ファイルを手動で解析しないでくださいこのようなファイルの解析は、すべての不測の事態に対処できないと壊れやすくなります(たとえば、無効化されたパスワードは単一の*
としてエンコードされることがよくあります。他のソリューションはそれを処理しますか?)。
さらに、認証はshadow
を介して行われない可能性があります(代わりにNISまたはldapを介して、または誰が何を知っているかを介して)。これをすべて処理する標準的なツールがあります。この場合、passwd
:
-S、--statusアカウントのステータス情報を表示します。ステータス情報は7つのフィールドで構成されます。最初のフィールドはユーザーのログイン名です。 2番目のフィールドは、ユーザーアカウントにロックされたパスワード(L)、パスワードがない(NP)、または使用可能なパスワード(P)があるかどうかを示します。 3番目のフィールドには、最後にパスワードを変更した日付が表示されます。次の4つのフィールドは、パスワードの最小経過期間、最大経過期間、警告期間、および非アクティブ期間です。これらの年齢は日数で表されます。
したがって、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
を手動で編集することはできません。
_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()
を使用するため、同じようにソートするユーザー名の間違ったエントリをチェックしてしまう可能性があります。
Passwdフィールドが文字列*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 =:を移動してコードを単純化