return to SSR TOP
return to Daemon Lab TOP

FreeBSD+SamabaでPDC


概要

FreeBSDとSambaでPDCを導入する方法を、ロ技研の例で示します。 というか、ロ技研での運用を1年間続けてきてだいぶ良い感じなので、公開します。

なぜPDC?

詳しいところは Sambaのページを見てもらえばいいのですが。
簡単にメリットを挙げると。

まずはインストール

まぁFreeBSDユーザなら何も考えずにpackageなりportsから入れればOKですね。 ja版があるので私はそれを入れています。

samb.conf

smb.confの内容はこんな感じ。詳細はコメントで書いてます。
[global]
        #一番windowsからの使い勝手の良いhex方式(16進数)でファイル名を書く
        coding system = hex
        #クライアントは日本語windowsなので
        client code page = 932
        
        #ワークグループとい書いてあるけど、domain名のことです
        workgroup = ANK
        #このサーバの名前
        netbios name = ANKO
        netbios aliases = SUN
        #どのIPで接続するか(別に制限する気がなければ指定は不要) 
        interfaces = 10.0.0.2
        bind interfaces only = Yes
        
        #今時この設定をあえてnoにする理由は無いでしょう
        encrypt passwords = Yes
        
        #ドメイン管理者のグループを指定しています。
        #権限を振りかざす必要性を感じなければ指定しない方がいいのかも
        domain admin group = @domadmin
        #ユーザがログオンしたときに自動実行するべきバッチファイルを指定します
        #クライアントはこのファイルを勝手に探して勝手に実行します
        #時刻の同期等に使うと便利です。
        logon script = login.bat
        #ホームディレクトリをHドライブとしてマウントします(かなり便利)
        logon drive = h:
        #ドメインログオン機能を有効にします(PDCになるってこと)
        domain logons = Yes
        #ドメインマスターになります、名前の解決は俺にまかせろい!ってことです
        domain master = True
        #winsをとりあえず有効化してますが・・・そんなに気にする必要無いような
        wins support = Yes

#ここの共有名は固定ですよ〜〜気をつけてください〜〜
#logon script等はここに置くように決まっています。
#ユーザからは見える必要もないし、ここのファイルは管理者以外変更出来ないようにしましょう
[NETLOGON]
        path = /usr/local/samba/netlogon
        writeable = Yes
        browseable = No
        #netlogonにクライアントがつないでくるときはログオンしたときぐらいなので
        #これを利用してログオン検知スクリプトを走らせています。
        root preexec = /root/bin/win-login.sh %u %m &
#ここも共有名固定
#各人のhomeの設定です・・・短いけどこの程度で実は十分
[homes]
        writeable = Yes
        browseable = No
        
        ##################################追加################################################
        #以下の行を足すことで、ほかのユーザのホームが見えなくなります
        #つけたい人はつけてください(ロ技研はつけてないけど)
        valid user = %S
        
        
#みんなで共有するディレクトリもつくりました
[public]
        #日本語コメントを書くときcoding system = hexとしているのでこのように
        #hexフォーマットで書く必要があります
        comment = :82:b1:82:b1:82:cd:8c:f6:97:70
        path = /usr/public
        #pubというダミーユーザになりきって書き込みます
        force user = pub
        force group = pub
        writeable = Yes
        
        #ここでこのようにパーミッションの設定をしているのは後述
        create mask = 0774
        directory mask = 0775
#各メンバーのディレクトリを見ちゃおう
#ちょっと工夫したつもり
[members]
        comment = members
        #/usr/homeとは別に/usr/homesというディレクトリがあります
        #ここには各人の~/publicへのリンクがあります
        path = /usr/homes
        #pubグループにしかみせません(理由は後述)
        valid users = +pub
        force user = pub
        force group = pub
        
        writeable = Yes
        
        #このパーミッションの理由は後述
        create mask = 0774
        force create mode = 0660
        directory mask = 0775
        force directory mode = 0775

ディレクトリ構成

各人のホーム以下のディレクトリは

drwxr-xr-x  public
drwxrwxr-x  public/incomming
そして各人はpubグループとなっています。(属してるじゃなくてpasswdファイルの方でそうなっている)
全員を同じグループにするのはセキュリティ上どうか?という話がありますが今回は無視。

/usr/homes(membersで共有)のしたには各人の~/publicへのシンボリックリンクがあります。 (実際には各人の~/publicへのシンボリックリンクを入学年度ごとのディレクトリに分類しています)

ホームとmembersの関係

以上の説明で、自分のホームディレクトリとmembers共有の関係がわかった人は私の文章は読むだけ無駄です。 私よりきっと詳しいでしょう。
理屈をこねてもわかりにくいので、実例で説明します。

ちなみに、ホーム経由でincommingにファイルをおくとmembers経由から上書き出来ないファイルが出来ます。 他人に解放してる地区という意味では矛盾するのでロ技研では運用上避けてもらうようにしてます。
この事により以下のメリットがあります

ログオンスクリプト

smb.confで指定していたlogon.batの中身をここで公開します。
例のごとくスクリプトにコメントを書いていきます。
実は、先代管理者の時代から会ったものをわずかに書き換えただけ
ホームをHドライブに、\\anko\publicをPドライブに\\anko\membersをXドライブに接続しています。

if "%OS%"=="Windows_NT" goto windowsNT
rem windows 9x系の場合
:windows
rem H,P,Xドライブを接続し直します
net use h: /delete
net use p: /delete
net use x: /delete
net use h: /home
net use p: \\anko\public
net use x: \\anko\members


del h:\#netset.bat
rem netset2は先代管理者の作成したプログラムで
rem HOST名、USER名、DOMAIN名,OSの種類などを判別しH:\#netset.batという
rem ファイル名の環境変数設定バッチファイルとして出力します。
z:netset2 h:\#netset.bat set z:winset
call h:\#netset.bat
del h:\#netset.bat

goto loginbat
rem windowsNT系のための設定です
:windowsNT
rem ホームは自動で接続されるので、PとXのみ接続し直します
net use p: /delete
net use x: /delete
net use p: \\anko\public
net use x: \\anko\members
rem 上記netset2と互換性を取るための環境変数の代入
set HOST=%COMPUTERNAME%
set USER=%USERNAME%
set DOMAIN=%USERDOMAIN%

:loginbat
rem 各人のホームに各人が記述したlogin.batがあれば実行します。
rem 上記HOST,USER,DOMAIN等の環境変数が利用可能です

if not exist h:\winlogin\_login.bat goto skip
call h:\winlogin\_login.bat
:skip
%SystemDrive%
cd %SystemRoot%
goto end
:end
rem 時刻の同期を取ります
NET TIME \\anko /SET /y
ものすごく久しぶりにこのバッチファイルを読んだんですけど・・・前管理者は結構パラノイアかも。。。
とりあえず、各共有が自動的に各ドライブに接続され、必要なら自分の書いたログオンスクリプトも同時に実行され、 且つ、時刻の同期を取るログオンスクリプトになっています。
ここで、各人のログオンスクリプトを実行する際環境変数に今ログオン仕様としているマシンの情報がちゃんと入ってるのが みそですね。

日々のメッセージを出したい

[NETLOGON]のroot preexec = /root/bin/win-login.sh %u %m &には実は日々の連絡事項を出すという目的があります。 ここでのみそは、windows標準の機能しか使わないってことです。結構持ち込みノートPCでドメインログオンする人が多いので・・・
以下は/root/bin/win-login.shの中身です

#!/bin/sh
#$1にユーザ名が入り $2にホスト名が入ります

#とりあえずこのスクリプトが呼ばれたというログを取ります(デバグ用)
echo `/bin/date -j  "+%Y/%m/%d-%H:%M:%S"`:$1 login to $2 >>/var/log/win-login.log

#all.txtというファイルがあったら、その中身をsmbclientのメッセージ機能でクライアントに送ります
#くらいあんとにはポップアップメッセージとしてでます。
if test -e /usr/public/motd/all.txt
then
/usr/local/samba/bin/smbclient -M $2 < /usr/public/motd/all.txt
fi

#各ユーザ名のファイルがあったらそれもメッセージとして送ります。
if test -e /usr/public/motd/$1.txt
then
/usr/local/samba/bin/smbclient -M $2 < /usr/public/motd/$1.txt
fi
簡単なスクリプトなんですけれども、部会の告知などには結構便利です。

ユーザの追加

ロ技研では部員を入学年度で区分けするという風習があるのでそれにならない、各人のホームも入学年度で区分けされています。 なので、以下のようなスクリプトを書いています。

#! /bin/sh
#引数の簡単なチェック
if test -z $3
then
echo "ex.: add_user.sh 99 akira pass"
else
#ユーザIDを1000番から4000番の間から選び、シェルにはbashを使用しtemplete_userディレクトリをコピーしてホームを/home/入学年度/以下に作る
pw user add -n $2 -i 1000,4000 -s /usr/local/bin/bash -g pub -m -k /etc/template_user -b /home/$1
#members共有のところにシンボリックリンクを張る
ln -s /home/$1/$2/public /usr/homes/$1/$2
#昔はここでunixのパスワードを設定していた(なぜかやめた)
#./both_add.pl $2
#sambaのユーザとして追加
/usr/local/samba/bin/smbpasswd -n -a $2
#samba(ドメインログオン)のパスワードを設定
printf  $3\\n$3\\n |/usr/local/samba/bin/smbpasswd -s $2
fi
以上のようなスクリプトを組むことによって作業の省力化を図っています。
いやぁ、スクリプトってべんりですね。

マシンの追加

ドメインにマシンを参加させるには「マシン名$」というダミーユーザをunix上につくってsambaに登録する必要があります。 しかしFreeBSD標準のadd_userではそのようなユーザ名ははねられてしまいます。つまりvipwなりなんなりを使えということになります。
そこで下記の二つのスクリプトを使います。
add_mac.sh

#!/bin/sh
export NEW_NAME=$1
export EDITOR=/root/samba/add_mac.pl
#add_mac.plがエディタですよ〜と嘘をついて、vipwを起動します。
/usr/sbin/vipw
#sambaに登録します
/usr/local/samba/bin/smbpasswd -m -a $1
add_mac.pl(エディタのフリをするスクリプト)
#!/usr/bin/perl
#マシン用ダミーユーザのグループIDは1003にしてあります
$mac_grp='1003';
#vipwから渡される編集すべきファイル
$pas_file=$ARGV[0];
#引数チェック
print "file is ".$pas_file."\n";
#print "input mac name\n";
#$new_name=;
$new_name = $ENV{'NEW_NAME'};
$new_name =~ s/\n//;
$new_name =~ s/ //;
if($new_name eq ""){
        print "input machine name!\n";
        exit(1);
}

#確認をかねてエディタのフリをするためにキー入力を行います
#ほんとはこんなことしなくても良い方法あるんだろうけど・・手抜き
print "new machine name is $new_name . Are you sure?";
;
#自分が取るべきUIDとかすでに同一名がないかをちぇっく
open PAS ,"+>> $pas_file" or die('cannt open');;
$max=5000;
seek PAS,0,0;
while (){
    ($uname,$pass,$uid)=split(/:/);
    if($uid>$max && $uid <10000){
        $max=$uid;
    }
    if($uname eq $new_name.'$'){
        print "the name is already exists\n";
        close PAS;
        exit(1);
    }
}
$max +=1;
#ダミーユーザを追加
print "user id = $uid :user name = $new_name :group id = $mac_grp\n";
seek PAS,0,2;
print PAS $new_name.'$:*:'. $max .':'.$mac_grp.'::0:0:samba mac_acount '.$new_name."::\n";
print $new_name.'$:*:'. $max .':'.$mac_grp.'::0:0:samba mac_acount '.$new_name."::\n";
close PAS;
まぁインチキくさいけど使えるからOKってことにしています

まとめ

まぁ、こんな感じで使えます
使い出すとこの環境はもう抜け出せません、かなり良い感じのぬるま湯です。 アカウント数が数十になるようなところでは試してみる価値はあるかもしれません。まぁPCの運用形態によりますが・・・・ いままでsamba単体の解説サイトは多くあったのですが、それでどういう風なシステム組んでるよ?という実例があまりなかったので 書いてみました。参考になれば幸いです。あと、なんか変なところあったら指摘してくださいましm(_ _)m。

ほんとのところ

本当は、さらにweb関連やらPDFプリンタ関連やらでこれより設定は複雑になってますが、今回ははしょりました。