web-dev-qa-db-ja.com

BASH:ユーザーパスワードがロックされているかどうかを/ etc / shadowで確認します

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によって実行されるスクリプトのフラグメントであるため、必要なすべての情報にアクセスできます。

6
DavDav

Awkですべてを実行しないのはなぜですか?

awk -F: '/<username>/ {if(substr($2,1,1) == "!"){print "True"} else {print "False"}}' /etc/shadow
3
hardillb

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を手動で編集することはできません。

26
marcelm
_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"]_と字句的に比較します。 _""_がないと、フィールドは数値のように見える場合、数値で比較される可能性があります(たとえば、infINFまたはInfinityと照合します)。

_LC_ALL=C_がないと、一部のawk実装は_==_字句比較にstrcoll()を使用するため、同じようにソートするユーザー名の間違ったエントリをチェックしてしまう可能性があります。

3

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 =:を移動してコードを単純化

0
schily