既存のUNIXユーザからLDAPのldifファイルを作る

1. LDAPマイグレーション

現在、nis/yp環境からLDAPへの移行を進めてる。その中で既存のUNIXユーザからLDAPのldifファイルを作る必要があった。
ldifファイルというのは、おおよそ一つのユーザに一つのファイルが割り当てられて、そのファイルにUIDとかGID、ホームディレクトリの場所など、*nixで言うところの /etc/passwd ファイルのようなものだ。またハッシュ化されたパスワードも記載されているので、FreeBSDで言うところの master.passwd だろうか。
さて、このldifファイルは1つのユーザに対して1つのldifが必要になる。
すでにそれなりの数のunixユーザがいるとその作成だけで結構大変だったりする。

2.1 スクリプトで一括作成

やっぱりこの種の問題 –一括でユーザを移行するのって結構しんどいよ問題–、を持ってる人は多く、すでに解決方法を提示してくれてたりする。
単純にはスクリプトをかまして、 /etc/passwd とか(Linuxのシャドウパスワードファイルを対象にしてたり)から一括してldifを作ってくれるものがあったりする。
今回は下記のサイトのスクリプトをありがたく利用させてもらった。

参考サイト: Ubuntu 11.04 – LDAPサーバー – LDAPサーバー構築 : Server World

さて、利用するといっても、実はこのスクリプトはLinuxのシャドウパスワードからldifファイルを作っているので、FreeBSDがベースシステムになっているうちではそのまま利用は出来ない。
というわけで、Server Worldさんに書いてあるとおり、勝手に都合良く編集させてもらって利用することにした。

2.2 ldif作成の前に

ldif作成の前にやらなければならないことがある。FreeBSDではシェル、ホームディレクトリ、UIDの記載された /etc/passwd ファイルと、ハッシュ化されたパスワードが記載されたrootのみ読み出しできる /etc/master.passwd ファイルがある。
今回の移行はパスワードの強化も計るため、全てのユーザのパスワードをランダム文字列に置き換えることにした。
というわけで、 passwdファイルを元に、ランダムパスワードを生に(プレーンテキストで貼り付けた)付与したpasswd_pファイルを作り、そこからldifファイルを作成することにした。

まずはランダムパスワードを発行するためのスクリプトももらってくる。
参考: 日記/2011-04-29 – BugbearR’s Wiki
手元にあるスクリプトは、上記サイトのものとちょっと違うのだけれど、どうやら広く知られているコードらしい。
パスワードに利用する文字列として、英数+記号を含め、そのなかからヘンな記号(スクリプトに埋め込む際にエスケープが必要になったりして面倒な記号)を省いたものだ。

#!/bin/sh

mkpasswd()
{
    len=$1

    [ -z $len ] && len="8"
    char='[email protected]#$%^&.-_';
    i=1
    while [ $i -le $len ]; do
        rand=`od -vAn -N2 -tu4 < /dev/random`
        str_from=`expr $rand % 70 + 1`
        str=${str}`echo $char | cut -c $str_from-$str_from`
        i=$(( i+1 ))
    done

    echo "$str"
}

rs=`mkpasswd 10`
echo -n $rs

charの値を変えることで出力されるランダムパスワードに利用する文字列を変えることができる。
またその際、かならず str_from=`expr $rand % 70 + 1` にある70の値も変えないとダメ。この70は文字列charの全長になってる。たぶんcharの文字列長を取るようにすれば良いんだろうけど・・・、shでどうやるかわかんない、残念。

2.3 こうしてできた、パスワード付きpasswd

これでようやく、パスワードが埋め込まれたpasswdファイルが出来る。
passwdファイルからpasswd_pファイルを作るには下のようなスクリプトを通してやる。
なお、先例に倣ってbashで。また、ランダムパスワードを作成するスクリプト名はrandpas.shで決め打ち。読み込みのファイルもpasswdで決め打ち。

shell> more makepasswd.sh
#!/usr/local/bin/bash

while read line
do
    PLNAME=`echo $line | cut -d: -f1`
    PPASS=`sh randpas.sh`
    PUID=`echo $line | cut -d: -f3`
    PGID=`echo $line | cut -d: -f4`
    PFNAME=`echo $line | cut -d: -f5`
    PHOME=`echo $line | cut -d: -f6`
    PSHELL=`echo $line | cut -d: -f7`

    echo $PLNAME:$PPASS:$PUID:$PGID:$PFNAME:$PHOME:$PSHELL
done < passwd shell> bash makepasswd.sh > passwd_p

さて、これでようやく必要なファイルになりました。

3. ついにldif作成

ようやく準備が整ったので、passwd_pファイルを元にldifの作成を行う。
Server Worldさんのスクリプトに手を加えてコレにさっき作ったpasswd_pファイルを食わせることにする。

#!/usr/local/bin/bash
SUFFIX='dc=l2tp,dc=org'
LDIF='ldapuser.l2tp.org.ldif'

while read line
do
        #echo $line
        UID1=`echo $line | cut -d: -f1`
        NAME=`echo $line | cut -d: -f5 | cut -d, -f1`
        LDIF='/root/ldapuser/ldif/ldapuser.'$UID1'.l2tp.org.ldif'
        echo  $line, $UID1
        echo -n > $LDIF
        if [ ! "$NAME" ]
        then
        NAME=$UID1
        else
        NAME=`echo $NAME | sed -e "s/%/ /g"`
        fi
        SN=`echo $NAME | awk '{print $2}'`
        if [ ! "$SN" ]
        then
        SN=$NAME
        fi
        GIVEN=`echo $NAME | awk '{print $1}'`
        UID2=`echo $line | cut -d: -f3`
        GID=`echo $line | cut -d: -f4`
        PASS1=`echo $line | cut -d: -f2`
        PASS2=`slappasswd -s $PASS1`
        SHELL=`echo $line | cut -d: -f7`
        HOME=`echo $line | cut -d: -f6`
        FLAG="0"
        EXPIRE="-1"
        MIN="0"
        MAX="-1"
        WARN="7"
        LAST=`date +%s`

        # user ldif
        echo "dn: uid=$UID1,ou=People,$SUFFIX" >> $LDIF
        echo "objectClass: inetOrgPerson" >> $LDIF
        echo "objectClass: posixAccount" >> $LDIF
        echo "objectClass: shadowAccount" >> $LDIF
        echo "uid: $UID1" >> $LDIF
        echo "sn: $SN" >> $LDIF
        echo "givenName: $GIVEN" >> $LDIF
        echo "cn: $NAME" >> $LDIF
        echo "displayName: $NAME" >> $LDIF
        echo "uidNumber: $UID2" >> $LDIF
        echo "gidNumber: 983" >> $LDIF # l2tp wo default
        echo "#userPassword: $PASS1" >> $LDIF
        echo "userPassword: $PASS2" >> $LDIF
        echo "gecos: $NAME" >> $LDIF
        echo "loginShell: $SHELL" >> $LDIF
        echo "homeDirectory: $HOME" >> $LDIF
        echo "shadowExpire: $EXPIRE" >> $LDIF
        echo "shadowFlag: $FLAG" >> $LDIF
        echo "shadowWarning: $WARN" >> $LDIF
        echo "shadowMin: $MIN" >> $LDIF
        echo "shadowMax: $MAX" >> $LDIF
        echo "shadowLastChange: $LAST" >> $LDIF
        echo >> $LDIF
done < /root/ldapuser/passwd_p

変更点として、デフォルトグループを983で決め打ち、シャドウパスワード周りを決め打ち(shadow*)、保存はディレクトリの下に、などなど。そうしてできあがったldifファイルは下記の通り。

dn: uid=hogetan,ou=People,dc=l2tp,dc=org
objectClass: inetOrgPerson
objectClass: posixAccount
objectClass: shadowAccount
uid: hogetan
sn: HogetandaYo
givenName: Hogetan
cn: Hogetan
displayName: Hogetan
uidNumber: 1000
gidNumber: 1000
userPassword: {SSHA}hogehoge
gecos: Hogetan
loginShell: /bin/tcsh
homeDirectory: /home/hogetan
shadowExpire: -1
shadowFlag: 0
shadowWarning: 7
shadowMin: 0
shadowMax: -1
shadowLastChange: 1319107306

そしてこれらのldifファイルを食わせる。

4. ldifを食わせておしまい

コメントを残す