Chapter 1. UNIX領域におけるNetBIOS

Andrew Tridgell

April 1995

Table of Contents

概要
ユーザー名
ファイルの所有権
パスワード
ファイルのロック
拒否モード
Trapdoor UID
ポート番号
プロトコルの複雑さ

概要

これは、UNIX上でのSMB実装で直面するいくつかの問題について記述し、Sambaがどのように それらを実装したかを説明した短い文書である。これらはUNIX<->PC間の相互運用を 調べる人の手助けになるかもしれない。

PCへの接続機能を、UNIX上で実装している人の手助けとなるように書かれた。

ユーザー名

SMBプロトコルはおおざっぱなユーザー名の概念しか持っていない。初期のSMBプロトコル (たとえばCOREとCOREPLUS)では、まったくユーザー名の概念がなかった。そのあとの プロトコルでもクライアントはしばしば(特にプリンターの操作において)、サーバー上で 最初にユーザー名を検証しないで運用をしていた。

UNIXのセキュリティは、ユーザー名/パスワードペアを基本としている。UNIXマシンは ある種の認証なしには、どのような実質的な操作もクライアントには許可しない。

UNIXサーバーが"共有レベル"でのセキュリティモードになっていたときに、主に問題が 発生する。これは多くのサイトで不評である、各接続済の共有に対して同じユーザーとして クライアントがサーバーに接続する事を通常強制する、"ユーザーレベル"セキュリティモードの 代替となる既定値のモードである。

"共有レベル"セキュリティでは、クライアントは通常"session setup"プロトコル中に おいて、ユーザー名を提供するが、対応するパスワードは提供しない。クライアントは 次に"tree connect"プロトコルを使ってリソースに接続し、パスワードを提供する。 問題は、PC上のユーザーは異なった場面でユーザー名とパスワードを入力することであり、 サーバーにアクセスする時に、両方を一緒にする必要があることを知らないということである。 ユーザー名は通常PCに"ログオン"するときに入力する(これはWindows for Workgroupを 仮定している)。パスワードはディスクやプリンターに接続するときに選択する。

ユーザーは、しばしばドライブの接続のためのログオンに、全く異なったユーザー名を選ぶ。 しばしば、異なったドライブに異なったユーザー名でアクセスすることも望む。UNIX サーバーは各パスワードに結びつけるための正しいユーザー名を何らかの方法で見極める 必要がある。

Sambaはこの問題をいくつかの方法を使って防ごうとする。それらは大変多くの場合、 成功する。その方法にはusername map、service%userという書式、後の認証のために session setupのユーザー名を保持してサービス名からユーザー名を判断する(directoryか user=オプション経由で)などがある。

ファイルの所有権

通常使われるSMBプロトコルは、"ファイルを所有していないのでその操作はできません" という事を通知する方法を持っていない。要するに、全くファイルの所有権という概念が ないのである。

これは、ある種の興味深い問題を引き起こす。たとえば、UNIXマシンにファイルをコピー し、ファイルは誰でも書き込み可能(world writeable)だが、他のユーザーで所有されている 場合、ファイルは正しく転送されるが、間違った日付を受け取ることになる。これは、 UNIX配下ではutime()システムコールは、たとえファイルがすべてのユーザーに対して 書き込み可能だったとしても、ファイルの所有者かrootでのみ成功するという理由による。 セキュリティ上の理由により、Sambaはすべてのファイル操作を認証したユーザーの権限で 行い、rootでは行わないので、utime()が失敗する。これは"make"のようなプログラムが ファイルの時間を正しく取れないということで、共有された開発ディレクトリが不整合になる 可能性がある。

この問題に対するいくつかの解決方法があり、その中には、ユーザー名のマップと 特定の共有に対して特定のユーザー名を強制する方法などがある。

パスワード

平文パスワードが使われる場合、非常に古いSMBクライアントは送信前に パスワードを大文字にする。なぜそうなっているかについては不明である。 興味深いことに、WfWgは、COREPLUSよりもレベルが高いプロトコルで動いている時のみ パスワードを大文字にするので、データ入力ルーチンに責がないのは明白である。

UNIXパスワードは大文字小文字を認識する。そのため、もしもユーザーが大文字小文字を混ぜた パスワードを使う場合には問題が生じる。

Sambaは、すべて大文字のパスワードを受け取った場合、すべて小文字にした パスワードでの認証を追加で試みる。Sambaは、大文字小文字のすべての組み合わせ でパスワード認証を試みる "password level" というオプションを使っていたが、 これは削除された。

SambaはSMBクライアントによって提供されるパスワード暗号化方法をサポートする。 Microsoftネットワークにおける暗号化パスワードの使用は、"平文と同等の" パスワードハッシュを提供することと同等であることに注意。これは、それらの パスワードハッシュを含むSambaのsmbpasswdファイルは、rootのみ読み出し可能に すべきであることが*とても重要*であることを意味する。詳細は ENCRYPTION.txtを参照のこと。

ファイルのロック

Samba 2.2以降、Sambaは他のロック方法をうまくサポートしている。この節は 時代遅れである。

DOS/Windows環境におけるロック呼び出しはunix上でのものよりも機能が豊富である。これは、 SMBのロックを実装するために、fcntl()ベースの標準UNIXロック呼び出しを使うことを選択する (Sambaのような)UNIXサーバーは、多少間に合わせで作る必要があるということである。 The locking calls available under a DOS/Windows environment are much richer than those available in unix. This means a unix server (like Samba) choosing to use the standard fcntl() based unix locking calls to implement SMB locking has to improvise a bit.

大きな1つの問題は、DOSのロックは32ビット(符号なし)の幅で行えると言うことである。 UNIXのロック呼び出しは32ビットだが、符号着きであり、31ビット幅しかない。 不幸にも、OLE2クライアントはOLEセマフォのためにロック幅を選択するためにトップ ビットを使う。

この問題に対応するために、Sambaは、適切なビットシフト操作を行うことによって、 32ビット幅を31ビット幅に圧縮する。これは動作するように見えるが、理想的ではない。 将来のバージョンでは、この問題に対処するために、分離されたSMBロックが追加される かもしれない。

多くのUNIXロックデーモンは結構バグがあり、些細なことによってクラッシュすることも 足を引っ張っている。通常、ごくわずかのUNIXプログラムしかバイトレンジロックを使わない という理由で、UNIX環境では、これらは通常ほとんど使われない。DOS/Windowsからクライアント からの非常に大量のロック要求の負荷は、ある種のシステムにおいてはデーモンを終了して しまう。

2番目の大きな問題は、ある種のクライアントから要求される"便宜的ロック(opportunistic locking)" である。もしもクライアントが便宜的ロックを要求した場合、同じファイル上に、他の誰かが 何らかの操作を行おうとしているならば、クライアントがそのロックを開放することを 告げる時、そのことを通知するためにサーバーに要求する。UNIXは便宜的ロックを簡単に実装する すべがなく、現在のSambaはそれをサポートしていない(訳注:古い)。

拒否モード

SMBクライアントがファイルをオープンするとき、ファイル上に設定されている特定の "拒否モード"について問い合わせをする。それらのモード(DENY_NONE, DENY_READ, DENY_WRITE, DENY_ALL, DENY_FCB と DENY_DOS)は、他の誰かが同じ時に同じファイルを使うときに許可 すべき動作を指定する。たとえば、もしもDENY_READがファイル上に設定されている場合、 読み取りのためのファイルへのオープン操作は失敗する。

UNIXは同等の概念を持っていない。これを実装するため、Sambaはファイルのinodeをベースとする ファイルのロックと、ロックディレクトリを分離するか、あるいは、共有メモリ実装を使う。 ファイルロックによる方式は、あまりかっこよくなく、処理のコストがかかりファイルリソースを 消費するが、共有メモリ実装は非常に好ましく(訳注:preferedはミススペル)、それをサポートする システムでは既定値で有効となっている。

Trapdoor UID

SMBセッションは、1つのソケット上でいくつかのUIDを使って動作することが出来る。これは、 ユーザーが、異なったユーザー名で2つの共有に接続するときに起きる。これに対処するために、 UNIXサーバーは1つのプロセス内でUIDを切り替える必要がある。ある種のUNIX(たとえばSCO)では、 このようなことが出来ない。これは、そのようなUNIXでは、クライアントは単一のUIDでの処理に 制限されることを意味する。

その他の理由により、"trapdoor uid"メッセージも受け取る事があり得ることに注意。 詳細はFAQを参照のこと。

ポート番号

ソケット上のクライアントは、ポート番号が大きな値(>1000)の"非特権"ポート番号を使い、 サーバーへの接続は小さな値の"特権"ポートを使うという慣習がある。これは、UNIX上では、 1000よりも小さなポート番号上で、非rootなユーザーが、リッスンのためにポートを 開けないようにさせている。

ほとんどのPCベースのSMBクライアント(たとえばWfWgとWinNT)はこの習慣を完全に守っていない。 主犯はUDPのポート137でのNetBIOSの名前解決である。名前問い合わせ要求はソースポート137 から来る。これは、小さな(低位の)ポート番号で入ってくるパケットを許可しないよくある ファイアウォールの設定を使うときに問題になる。これは、それらクライアントは、低位の ポートベースのファイアウォールの反対側にあるNetBIOSネームサーバーに問い合わせできないことを 意味する。

NetBIOSノードステータスの問い合わせにおいては問題はより深刻である。WfWg、Win95と WinNT3.5のすべてが、要求元のソースポートが何であっても、ポート137上でNetBIOS ノードステータスを返す。これは両者ともポート137を使うマシン間では動作するが、 UNIXユーザーが、その種のOSでrootとして動作していない限り、ノードステータスを処理 出来ないことを意味する。答えに戻ると、ポート137はUNIXユーザーがリッスンできない。 興味深いことに、WindowsNT3.1ではこれが出来る。これは、要求中のソースポートに ノードステータスを返信する。

プロトコルの複雑さ

SMBプロトコルには数多くの"プロトコルレベル"がある。MicrosoftのOSに新しい機能が追加された たびごとに、新しい能力を"具現化"するために、SMBプロトコルの新しいプロトコルレベル中に 同等の機能を追加しているように見える。

これは、プロトコルは非常に"肥大化していて"、各ファイル操作に対して種々の方法を提供 していることを意味する。これは、SMBサーバーが複雑で肥大化してしまうことを意味する。 また、サーバーのバグをなくすことがとても困難であることも意味する。この問題で苦しむのは Sambaだけではなく、すべての呼び出しのすべての相違をサポートしないWindowsNTのような、 他のサーバーでもありえ、有効な無数のSMB呼び出しをサポートするためにMicrosoftの開発者に とっては全く持って頭痛の元である。

65種類もの(たとえばSMBreadとSMBwrite)のような"最上位の"操作がSMBプロトコル中にある。 それらのいくつかは数百ものサブ機能を含んでいる(SMBtransは少なくとも120の サブ機能を含み、たとえばそれらはDosPrintQAdd と NetSessionEnum)。それらのすべては その動作を変えるいくつかのオプションが指定できる。多くは、結果を返すのに必要と される、構造体を変更する"情報レベル"が何十種類もありえる。Sambaは2つの"最上位の" 機能を除いてすべてをサポートする。それは、SMBtransサブ機能の8つのみ(これまでの所) をサポートする。NTでさえ、全部をサポートしない。

Sambaは現在Windows95とWindowsNT3.5によって提供されている"NT LM 0.12"プロトコルまでを サポートしている。幸運なことにこのプロトコルレベルは、サーバーがサポートする、 とびきりの、新規なオプションを指定する"capabilities"フィールドを持っている。 これは、このプロトコルレベルの実装をより容易にすることを手助けしている。

また、SMBの仕様による問題もある。SMBはX/Openの仕様であるが、X/Openの書籍は理想的 からほど遠く、多くの重要な項目が欠落していて、多くを推測しなければならない。 Microsoftは最近SMBプロトコルをCIFS(Common Internet File System)と改名し、 新しい仕様を公開した。それは古いX/Openのドキュメントと比べると、とても優れているが、 引き続き文書化されていない呼び出しと機能が残っている。この仕様は、Microsoftによって 提供されているCIFS開発者メーリングリストによって活発に作業されている。