/etc/passwd で $GECOS 値を参照して名前と姓を抽出するために awk または sed を使用する bash スクリプト

/etc/passwd で $GECOS 値を参照して名前と姓を抽出するために awk または sed を使用する bash スクリプト

赤い帽子サンプルスクリプトがありますNISからFreeIPAにユーザーを移行します。nis-user.sh次のようになります。

#!/bin/sh
# $1 is the NIS domain, $2 is the NIS master server
ypcat -d $1 -h $2 passwd > /dev/shm/nis-map.passwd 2>&1

IFS=$'\n'
for line in $(cat /dev/shm/nis-map.passwd) ; do
    IFS=' '
    username=$(echo $line | cut -f1 -d:)
    # Not collecting encrypted password because we need cleartext password
    # to create kerberos key
    uid=$(echo $line | cut -f3 -d:)
    gid=$(echo $line | cut -f4 -d:)
    gecos=$(echo $line | cut -f5 -d:)
    homedir=$(echo $line | cut -f6 -d:)
    shell=$(echo $line | cut -f7 -d:)

    # Now create this entry
    echo passw0rd1 | ipa user-add $username --first=NIS --last=USER \
         --password --gidnumber=$gid --uid=$uid --gecos='$gecos' --homedir=$homedir \
         --shell=$shell
    ipa user-show $username
done 

これは名前をNISに設定し、姓をUSERに設定します。私たち/etc/passwdのファイルには、次のユーザーが含まれています。

juser:x:4841:200:Jane Q. User:/home/juser:/bin/tcsh
kuser:x:5761:200:User, K.:/home/kuser:/bin/bash

もちろん、状況は複雑になります。以下は、名前と姓を抽出できるという提案を受けました。これを逆にしてカンマ(例:kuser)で区切ると、ほとんどの名前がキャプチャされます。

first=$(echo $gecos | sed -e 's/\(.*\), \(.*$\)/\2 \1/' | awk '{print $1}'
last=$(echo $gecos | sed -e 's/\(.*\), \(.*$\)/\2 \1/' | awk '{print $NF}'

$firstとはどのように使用しますか$last

テストするために、変数の結果を$gecos次のようにパイプしてみましたawk

first=$(echo $line | cut -f5 -d: | awk '{print $1}':)

awk: cmd. line:1: {print $1}:
awk: cmd. line:1:           ^ syntax error

gecos=次の行(この行の後ろ)のみを追加しようとすると、同じエラーが発生します。

first=$(echo $gecos | awk '{print $1}':)

編集:ああ、コロンの位置が私を引き付けます。これは働きます:

first=$(echo $gecos | sed -e 's/\(.*\), \(.*$\)/\2 \1/' | awk '{print $1}')
last=$(echo $gecos | sed -e 's/\(.*\), \(.*$\)/\2 \1/' | awk '{print $NF}')

今、次の部分に進みます…

だから私も連れて行きたいこの提案、次のようにCRYPTを使用してハッシュされたパスワードを取得します。

userpassword='{CRYPT}$6$blahblah$moregibberish' testuser

Rob Cの前のヒントに従いました。ここそしてここ

これが重要かどうかはわかりませんが /etc/libuser.confcrypt_style = sha512

私が追加したスクリプトに以下を追加しました。

password1=$(echo $line | cut -f2 -d:)

そして今このアイテムを作成してください部分:

--setattr "userpassword='{CRYPT}$password1'"

デバッグがオンのときに記録される内容は次のとおりです。

[Tue Feb 02 22:08:52.541857 2021] [wsgi:error] [pid 16097:tid 16365] [remote x.x.x.x:59726] ipa: INFO: [jsonserver_session] [email protected]: user_add/1('john', givenname='John', sn='Smith', homedirectory='/home/smith', gecos="'John Smith'", loginshell='/bin/tcsh', uidnumber=5319, gidnumber=150, setattr=("userpassword='{CRYPT}the-actual-hash-of-the-password'",), version='2.239'): SUCCESS

ではこれは{CRYPT}説明ができないようですが?また、いくつかのデバッグも追加しました。

echo "Password hash value is $password1"

印刷されるのは元のハッシュ値 sans です{CRYPT}

したがって、スクリプトの外部でテストするためにテストユーザーを追加しました。

ipa user-add --first=test --last=user --setattr userpassword='{CRYPT} the-actual-hash-of-the-password' testuser

その後、次のコマンドを実行しましたが、パスワードが機能しました。

ldapsearch -x -D 'uid=testuser,cn=users,cn=accountsdc=ourdomain,dc=edu' -W

# testuser, users, accounts, ourdomain.edu
dn: uid=testuser,cn=users,cn=accounts,dc=ourdomain,dc=edu
givenName: test
sn: user
uid: testuser
cn: test user
displayName: test user
initials: tu
gecos: test user
krbPrincipalName: [email protected]
objectClass: top
objectClass: person
objectClass: organizationalperson
objectClass: inetorgperson
objectClass: inetuser
objectClass: posixaccount
objectClass: krbprincipalaux
objectClass: krbticketpolicyaux
objectClass: ipaobject
objectClass: ipasshuser
objectClass: fasuser
objectClass: ipaSshGroupOfPubKeys
objectClass: mepOriginEntry
loginShell: /bin/sh
homeDirectory: /home/testuser
mail: [email protected]
krbCanonicalName: [email protected]
ipaUniqueID: 34ee1f48-65d2-11eb-8c33-001ec9ab7ef0
uidNumber: 1520800007
gidNumber: 1520800007
memberOf: cn=ipausers,cn=groups,cn=accounts,dc=ourdomain,dc=edu
krbLastPwdChange: 20210203034524Z
krbPasswordExpiration: 20210504034524Z

# testuser, groups, accounts, ourdomain.edu
dn: cn=testuser,cn=groups,cn=accounts,dc=ourdomain,dc=edu
objectClass: posixgroup
objectClass: ipaobject
objectClass: mepManagedEntry
objectClass: top
cn: testuser
gidNumber: 1520800007
description: User private group for testuser
mepManagedBy: uid=testuser,cn=users,cn=accounts,dc=ourdomain,dc
 =edu
ipaUniqueID: 34f39b4e-65d2-11eb-8c33-001ec9ab7ef0

# search result
search: 2
result: 0 Success

現在のバージョンでも可能でしょうか?

ベストアンサー1

2つの修正:

--setattr "userpassword={CRYPT}$password1" --gidnumber=$gid

また、ユーザー名を設定するスクリプトの上部で、echoコマンドを二重引用符で囲みます。

username="$(echo $line | cut -f1 -d:)"

したがって、最終スクリプトは次のようにする必要があります。

#!/bin/sh
# $1 is the NIS domain, $2 is the NIS master server
ypcat -d $1 -h $2 passwd > /dev/shm/nis-map.passwd 2>&1

IFS=$'\n'
for line in $(cat /dev/shm/nis-map.passwd) ; do
    IFS=' '
    username="$(echo $line | cut -f1 -d:)"
    # Not collecting encrypted password because we need cleartext password
    # to create kerberos key
    uid=$(echo $line | cut -f3 -d:)
    gid=$(echo $line | cut -f4 -d:)
    gecos=$(echo $line | cut -f5 -d:)
    homedir=$(echo $line | cut -f6 -d:)
    shell=$(echo $line | cut -f7 -d:)

    # Now create this entry
    echo passw0rd1 | ipa user-add $username --first=NIS --last=USER \
         --password --gidnumber=$gid --uid=$uid --gecos='$gecos' --homedir=$homedir \
         --shell=$shell
    ipa user-show $username
done 

中間イニシャル、姓、名前を含む項目を処理するには、次のコマンドを使用できます。

# Change Last, First to First Last. (Fill in dummy for empty gecos.)
if [ -z "$gecos" ]; then
firstlast='First Last'
else
firstlast=$(echo $gecos | sed -e 's/\(.*\), \(.*$\)/\2 \1/')
fi

# Extract First and Last into separate variables
first=$(echo $firstlast | awk '/^(\w|[-'\''])+ \w\. / { print $1,
$2; } \
/^(\w|[-'\''])+ (\w|[-'\''])+(
|$)/ {
print $1; }' )
#echo this dollar 1 $1 this is dollar 2 $2
last=$(echo $firstlast | awk 'BEGIN {ORS=" ";} \
/^(\w|[-'\''])+ \w\. / { for (i=3;
i<=NF; i++) print $i; } \
/^(\w|[-'\''])+ (\w|[-'\''])+(
|$)/ {
for (i=2; i<=NF; i++) print $i; }' \
| sed 's/ *$//' )

おすすめ記事