    !==
    !== UNIX-SMB.txt for Samba release 2.0.7 26  Apr 2000
    !==
    寄稿者:	Andrew Tridgell <samba@samba.org>
    日付:	1995/04

    翻訳者: 佐藤文優 <fumiya@samba.gr.jp>
    校正者:	太田俊哉 <oota@pes.com1.fc.nec.co.jp>
    更新日: 1999/02/04

    主題:	UNIX 界における NetBIOS の論文
    ============================================================================

    この短い文書は、SMB の UNIX 上の実装において直面するいくつかの問題と、
    Samba がどのようにしてそれらを対処するかを記述する。これらは
    UNIX<->PC の相互運用性を調べている人たちの助けとなるだろう。

    これは UNIX の PC への接続性についての書類を書いている人たちを
    手助けするために執筆された。

    ユーザ名
    ========

    SMB プロトコルは不明確なユーザ名の概念だけを持つ。初期の SMB プロトコル
    (CORE や COREPLUS など)は、まったくユーザ名の概念がない。最近のプロトコル
    でさえ、クライアントはたびたび、最初にサーバへのユーザ名認証をせずに、操作を
    試みる(特にプリンタの操作)。

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

    主にこの問題は、UNIX サーバが「共有レベル」セキュリティ・モードである時に
    現れる。通常は、これが「ユーザ・レベル」セキュリティ・モードと二者択一の
    既定のモードであり、接続された各々の共有資源が同じユーザになるような
    サーバへの接続を、クライアントに強制する。これは多くのサイトにとって
    不都合である。

    「共有レベル」セキュリティでは、ふつうクライアントは「session setup」
    プロトコルでユーザ名を与えるが、伴うパスワードを与えない。
    次にクライアントは「tree connect」プロトコルを使って資源に接続し、
    パスワードを与える。問題は、PC が、サーバへのアクセスを得るためにはユーザ名と
    パスワードを同時に与えなければならないことを知らないため、PC のユーザが、
    異なる状況でユーザ名とパスワードを入力することにある。ふつうユーザ名は
    ユーザが PC に「ログオン」したときに入力したものである(これは
    Windows for Workgroups を想定している)。パスワードはディスクやプリンタに
    接続するときにユーザが選択するものである。

    ユーザがドライブ接続に関するログインをするとき、まったく異なるユーザ名をよく
    選択する。また、たびたびユーザは、異なるユーザ名で異なるドライブを
    アクセスしたいと思う。UNIX サーバは各パスワードと結合する正しいユーザ名を
    推測する方法を必要とする。

    Samba はいくつかの方法を用いてこの問題を回避しようと試みる。それらは
    ほとんどのケースでうまくゆく。その方法として、ユーザ名マップ(username map
    オプション)、service%user 構文、後の認証用に session setup のユーザ名の保存、
    そしてサービス名からのユーザ名の誘導(直接または user オプションによる)が
    ある。

    ファイルの所有権
    ================

    一般に使われる SMB プロトコルは、「あなたは実行できない。なぜなら
    ファイルを所有していないからだ」と知らせる方法がない。事実、それらは
    ファイルの所有権という概念がまったくない。

    これはいろいろな興味深い問題を引き起こす。たとえば、UNIX のドライブへ
    ファイルをコピーするとき、誰からも書き込み可能だが他人が所有している
    ファイルは、正確に転送されるが誤った日付を受け取る。これの原因は、
    UNIX における utime() の呼び出しは、ファイルが誰からも書き込み可能であっても
    ファイルの所有者または root によってのみ成功することにある。
    セキュリティ上の理由により、Samba はすべてのファイル操作を root ではなく
    認証されたユーザで実行するため、utime() は失敗する。「make」のような
    プログラムが正しくファイル時間の比較ができないだろうから、共有している開発
    ディレクトリが詰まってしまうだろう。

    この問題に対するいくつかのよい解決法がある。ユーザ名のマッピングに
    含める方法(username map オプション)、そして個別の共有資源に対して特定の
    ユーザを強制する方法(force user オプション)である。

    パスワード
    ==========

    多くの SMB クライアントは、パスワードを送る前に大文字に変換(uppercase)する。
    わたしには、なぜこのように動作するのか理解できない。面白いことに、WfWg は
    サーバが COREPLUS より以降のプロトコルで動作している場合だけパスワードを
    大文字に変換する。よって明らかに、責められるのはデータ入力ルーチンではない。

    UNIX パスワードは大文字/小文字(case)を区別する。このため、ユーザが
    大文字/小文字を混ぜたパスワードを使用していると問題となる。

    Samba はこれに対抗するために「password level」オプションか「password server」
    オプションを試みることができる。「password leve」オプションは、提供された
    パスワードを指定した大文字/小文字の数だけ変化するよう Samba にさせる。
    「password server」を使用することで、Samba はほかのマシン(一般には
    WinNT サーバ)を通して、パスワードの正当性を判断させることができる。

    Samba は SMB クライアントによって使用されるパスワードの暗号化手順を
    サポートする。注意として、Microsoft ネットワークにおけるパスワードの
    暗号化の機能はパスワードのハッシュを生成するが、これらは「平文と等価」で
    ある。この方法では、それらパスワードのハッシュを含んだ Samba の smbpasswd
    ファイルが、root ユーザによってのみ読み出し可能であることを保証することが
    *非常に*重要となる。さらなる詳細は ENCRYPTION.txt を参照のこと。

    ロッキング (Locking)
    ====================

    DOS/Windows 環境のもとで可能なロッキング呼び出しは、UNIX で可能なものより
    ずっと豊富である。UNIX サーバ(たとえば Samba)が、標準的な fcntl() を
    基本とした UNIX のロッキング呼び出しを使って SMB のロッキングを実装するには、
    ビットを間に合わせに作る必要があることになる。

    1つの大きな問題は、DOS のロックは 32 ビット(符号なし)の範囲まで可能な
    点にある。UNIX のロッキングは 32 ビットであるが符号ありなため、31 ビットの
    範囲だけ与えられる。不運にも、OLE2 クライアントは OLE のセマフォに使用される
    ロッキングの範囲を選ぶために最上位ビットを使用する。

    この問題を回避するため、Samba は適当なビット・シフトによって 32 ビットの
    範囲を 31 ビットに圧縮する。これは機能するようであるが、理想的でない。
    将来のバージョンでは、この問題に対処するために独立した SMB lockd が
    追加されるだろう。

    これでも、とてもバグが多く(buggy)、わずかな要因でクラッシュするほとんどの
    UNIX の lockd デーモンには効果がない。いくつか少数の UNIX のプログラムが
    バイト範囲のロッキングを使用するだけなため、通常ほとんど使われない。
    DOS/Windows による莫大な数のロック要求のストレスが、システムのデーモンを
    殺すことがある。

    2つめの大きな問題は、いくつかのクライアントによる「opportunistic locking」
    要求である。クライアントが opportunistic locking を要求すると、
    ほかのクライアントが同じファイルになにかをしようと試みた時に、それを
    知らせるようにサーバに依頼する。通知があったとき、クライアントはその
    ロックの解除を望んでいるかどうかを言う。UNIX には opportunistic locking を
    実装するための簡単な方法がないため、現在の Samba はこれをサポートしない。

    拒否モード (Deny Modes)
    =======================

    SMB クライアントがファイルをオープンするとき、クライアントは特定の
    「拒否モード」をファイルに配置するように求める。これらのモード(DENY_NONE、
    DENY_READ、DENY_WRITE、DENY_ALL、DENY_FCB そして DENY_DOS)は、同時に
    ファイルを利用しようとするほかのクライアントが、どの動作を許可されるかを示す。
    たとえば DENY_READ がファイルに配置されると、ファイルを読もうとするオープンの
    試みはすべて失敗するはずである。

    UNIX には同等の概念がない。これらを実装するため、Samba は分離したロック
    ディレクトリに位置するファイル inode に基づいたロック・ファイルか、
    共有メモリの実装を使用する。ロック・ファイルによる方法は扱いにくく
    プロセスとファイルの資源を浪費し、共有メモリによる実装がはるかに好ましく、
    これをサポートするシステムでは既定で使用される。

    落とし戸 UID (trapdoor UIDs)
    ============================

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

    注意してほしいのは、ほかの理由でも「trapdoor uid」メッセージを目にすることが
    ある。詳細は FAQ を参照のこと。

    ポート番号
    ==========

    クライアントは、ソケットに高い「非特権」ポート番号(>1000)を使用し、
    低い「特権」ポート番号のサーバに接続するという習慣がある。UNIX では、
    root 以外のユーザは、1000 以下のポート番号に、接続を待つ(listening)ための
    ソケットをオープンできないようになっている。

    ほとんどの PC を基本とした SMB クライアント(WfWg や WinNT など)は、この習慣に
    まったく従っていない。おもな問題は、 UDP ポート 137 の NetBIOS ネーム
    サービスにある。名前問い合わせ要求はポート 137 を源にやってくる。これは、低い
    ポート番号で入ってくるパケットは許可しないという、一般的なファイアウォールを
    実現するための手法と組み合わせる場合に問題となる。それらのクライアントが、
    低いポート番号を基本としたファイアウォールの向こう側にある NetBIOS ネーム
    サーバに質問できないことを意味する。

    NetBIOS ノード状態問い合わせについては問題はさらに深刻だ。わたしが知る限り、
    WfWg、Win95、WinNT3.5 は、要求の出所のポートが何であろうと、NetBIOS ノード状態
    問い合わせに対してはすべてポート 137 に応答する。これは双方ともポート 137 を
    用いているマシン間で機能するが、root で動作していない UNIX ユーザは、これらの
    OS へのノード状態要求を行うことが不可能であることを意味する。応答は返って
    くるが UNIX ユーザが傍聴できないポート 137 に届く。おもしろいことに、WinNT3.1
    は、これを適切に処理する - 要求の出所のポートにノード状態応答を戻す。

    プロトコルの複雑さ
    ==================

    SMB プロトコルには、多くの「プロトコル・レベル」がある。新しい機能が Microsoft
    オペレーティング・システムに追加されるたび、新しい能力を外部に提供するため、
    同等の機能を SMB プロトコルの新しいプロトコル・レベルに追加しているように
    見える。

    これはプロトコルが非常に「肥大」していることを意味し、それぞれのファイル
    操作を実行する多くの方法を提供している。SMB サーバは複雑に、大きくする
    必要があることになる。また、バグがないように作るのはかなり難しい。まさに
    Samba はこの問題に苦しんでいる。WinNT などのほかのサーバはすべての呼び出しの
    すべての差異をサポートしておらず、利用可能な無数の SMB 呼び出しを
    サポートする上で、MS の開発者にとっては間違いなく頭痛の種となっている。

    SMB プロトコルには約 65 もの「トップ・レベル」操作(SMBread や SMBwrite など)
    がある。それらのいくつかは数百ものサブ機能を含んでいる(SMBtrans は
    DosPrintQAdd や NetSessionEnum など、少なくとも120のサブ機能を持っている)。
    それらすべては、いくつかのオプションを受けて動作方法を変更することができる。
    多くはいくつもの「情報レベル」を受け取り、戻す必要がある構造体を変える
    ことができる。Samba は 2 つの「トップ・レベル」機能以外のすべてをサポートする。
    それらは 8 つだけの SMBtrans サブ機能をサポートしている。NT でさえ、それらの
    すべてをサポートしていない。

    Samba は現在、Win95 や WinNT3.5 で提案された「NT LM 0.12」プロトコルまでを
    サポートする。幸運にも、このプロトコル・レベルは「能力」領域を持ち、
    超すごい最新鋭(super-duper new-fangled)のオプションを、サーバがサポート
    しているかどうかを示す。これは、このプロトコル・レベルの実装をより簡単に作る
    手助けとなる。

    さらに SMB の仕様書にも問題がある。SMB は X/Open の仕様であるが、X/Open の
    本は少しも理想的ではなく、多くの重要な問題を取り扱わずに想像に任せている。
    Microsoft は最近、SMB プロトコルを CIFS (Common Internet File System) と
    名前を変えて新たな仕様を公開した。これらは古い X/Open の文書よりも遙かに
    優れているが、依然として記述されていないコールと特徴が存在する。