netatalk.io

Netatalk 4.5.0

ACL のサポート

AFP の ACL サポートは Solaris の ZFS ACL、派生したプラットフォーム、そして、Linux の POSIX 1e ACL で実装されている。

設定

基本的な方式で運用するならば設定することは何もない。Netatalk は ACL をオンザフライで読み込み、そののちいわゆる UARights パーミションビット経由で AFP クライアントに送られる有効なパーミッションを算出する。 マック上では、これらのビットを Finder ウィンドウ内のパーミッションと調整するために Finder が使用する。例:UNIX のモードでは書き込み専用だが ACL がユーザーに書き込み権限を与えているフォルダーは有効な読み書き権限を表示する。権限のマッピングなしに Finder は読み込み専用アイコンを表示するだろうし、ユーザーはそのフォルダーに書き込みはできないであろう。

デフォルトでは、認証ユーザーに有効なパーミションは UNIX のモードではなく、前記 UARights の機構のみに対応付けられる。この挙動は設定オプション map acls で修正することができる。

しかしながら、Finder の「情報を見る」ウィンドウでもターミナルでも、ACL を見ることは不可能で、そこで見ているのは macOS で ACL がどのように設計されたのかという結果である。もしクライアント上でも ACL を表示させたいと思うならば、諸々を認証ドメイン(ディレクトリサービス、例えば、LDAP や OpenDirectory)の一部と、より内包されているようにして、クライアント側でもサーバー側でもセットアップをおこなうべきである。その理由は、macOS ACL UID と GID だけでなく UUID と紐付いているためである。このため、afpd は全てのファイルシステムの UID と GID を UUID に紐付けできなければならない。そうすれば、afpd は macOS の UUID に紐付けた UNIX UID と GID も含めたサーバー側の ACL を返すことができる。

Netatalk は LDAP クエリーを使ってディレクトリサーバーに問い合わせができる。ディレクトリサーバー(Active Directory、Open Directory)が既にユーザーとグループの UUID 属性を提供している。 あるいはディレクトリサーバー(例えば OpenLDAP)に使用されていない属性を再利用する(あるいは新たに追加する)のいずれかである。

より踏み込むと:

  1. ZFS を使っている Solarisの ZFS ボリュームごとに対して、

    Netatalk を使用したいと思っているあらゆるボリュームを下記 ZFS ACL のプロパティを設定するべきである:

    aclinherit = passthrough
    aclmode = passthrough
    

    このプロパティが何をするのか、どのように適用するのか、についての説明は、ホストの ZFS ドキュメンテーション(例えば man zfs)を確認のこと。

  2. 認証ドメイン

    サーバーとクライアントがセキュリティ連携の一部となっていて、ユーザー id データは共通のソースから出てこなければならない。Darwin の ACL は UUID に基づいている。なので、AFP 3.2 での ACL の仕様は Darwin の ACL である。故に id データのソースは全てのユーザーとグループの属性を提供できなければならない。ここで UUID は ASCII テキストとして保管されている。言い換えれば:

    • UUID を何らかの属性に保管している場合は Open Directory サーバーないしは LDAP サーバーが必要である。

    • クライアントはこのサーバーを使用するように構成されていなければならない。

    • サーバーは nsswitch と PAM 経由で使用されるよう構成しなければならない。

    • Netatalk が LDAP 検索クエリでユーザーとグループの UUID を引き出せるように、afp.conf 内で ACL 専用のオプションを使って Netatalk を設定しなければならない。

macOS の ACL

アクセス制御リスト (ACL) と共に、macOS は正統的な UNIX のパーミッションモデルの有力な拡張を提案した。 ACL は、所定のユーザーあるいはグループのパーミッションのセットを明示的に許可したり拒否するアクセス制御エントリー (ACE) の番号つきリストである。

ユーザー ID、またはグループ ID と紐付いている UNIX パーミッションとは異なり、ACL は UUID と紐付いている。この理由により、あるオブジェクトの ACL にアクセスすると、サーバーとクライアントは、UUID と ユーザー/グループ ID 間の変換をしてくれる、共通のディレクトリサービスを使うことを要求される。

ACL と UNIX のパーミションの相互関係は比較的シンプルなものである。ACL はオプションなので、UNIX パーミションはアクセス制御のデフォルトのメカニズムの役割をする。オブジェクトの UNIX パーミションを変更しても ACL は手付かずのままで、ACL の修正でもオブジェクトの UNIX パーミションは決して変更されない。アクセスチェックの間、macOS は最初に以下の順序で ACE の評価をして、オブジェクトの ACL を検査する: 全てのリクエスト権限が許可されるまで、リクエストされた権限が ACE によって明示的に拒否された、あるいはリストの最後までたどり着いた。である。ACL がない、あるいは ACL に許可されたパーミションがリクエストを実行するのに十分でない場合、macOS は次にオブジェクトの UNIX パーミションの評価に入る。 つまり、ACL は常に UNIX のパーミションより優先順位が上位ということである。

ZFS の ACL

ZFS の ACL はほぼ macOS の ACL に匹敵するものである。 両者ともほぼ同一の良い粒度のパーミションと設定の継承が提供されている。

POSIX の ACL

概要

macOS あるいは NFSv4 の ACL と比較すると、POSIX ACL は、伝統的な UNIX パーミションの制限を打開するには異質で汎用性のないアプローチを表現している。実装は POSIX 標準を取り込んだものを基礎としている。

POSIX 1003.1e 標準では二つのタイプの ACL を定義している。ファイルとディレクトリは、 アクセスチェックのために問い合わせを受けるアクセス ACL を保持することができる。 ディレクトリはアクセスチェックには向いていないデフォルトの ACL も保持することができる。デフォルトの ACL 付きでディレクトリの内側に新規オブジェクトが作成された時、デフォルトの ACL はそれがアクセス ACL であるものとして新規オブジェクトに適用される。サブディレクトリは親ディレクトリのデフォルト ACL を継承する。 継承制御にそれ以上のメカニズムは何もない。

設計上、POSIX ACL と macOS 間の違いに含まれている特筆すべき点は:

POSIX 1003.1e は6つの異なるタイプの ACL エントリーを定義している。前半の3つは標準の UNIX パーミションを統合するのに用いられている。これらは ACL として最小限の形であり、存在することは必須であり、 そして各々のタイプにつきたった一つのエントリーだけが ACL 内に許される。

残りのエントリーのタイプは伝統的パーミションモデルの拡張である:

ACL を意識していないアプリケーションとの互換性を維持のため、POSIX 1003.1e は、オブジェクトの UNIX パーミションを検索したり処理するシステムコールやユーティリティーのセマンティクスを変える。オブジェクトが必要最低限の ACL のみ保持している場合、UNIX パーミションのグループパーミションビットは ACL_GROUP_OBJ エントリーの値に対応する。

しかしながら、もし ACL に ACL_MASK エントリーが含まれている場合、挙動は異なるものとなる。UNIX パーミションのグループパーミションビットは ACL_MASK エントリーの値に対応する、すなわち、chmod g-w の呼び出しは、グループに対する書き込みアクセスを無効にするだけでなく、 ACL_USER ないしは ACL_GROUP エントリーによって許可されていた書き込みアクセスのエンティティ全てを無効にするのである。

POSIX ACL から macOS の ACL へのマッピング

クライアントがオブジェクトの ACL を読み込もうとした時、afpd は POSIX ACL からそれに等価な macOS の ACL にマップする。オブジェクトの ACL の書き込みには afpd が macOS の ACL を POSIX ACL にマップすることが要求される。POSIX ACL の設計上の制約から、マッピングを経た結果がオリジナルの ACL のセマンティクスと概ね同じになるような正確なマッピングを見出すことは通常不可能である。

macOS クライアントは POSIX 1003.1e 特有の UNIX パーミションと ACL_MASK との関係を意識していないので、afpd は互換性問題を回避するためにこの機能をクライアントに公開せず、そして afpd は *unix パーミションと ACL をアップルの AFP 用リファレンス実装がするのと同じ方法で扱う。オブジェクトの UNIX パーミションがリクエストされた時、afpd は適切なグループ権限を算出し、FPUNIXPrivs 構造の “permissions” と “ua_permissions” 要素を介し、オーナーおよび全ての者のアクセス権限も共に付して、リクエストした側に結果を返す。(Apple Filing Protocol Reference の 181 ページ参照) オブジェクトのパーミションを変更すると、afpd は常に ACL_USER_OBJ、ACL_GROUP_OBJ および ACL_OTHERS を更新する。もし ACL_MASK エントリーも存在すれば、新しいグループの権限が有効になり、かつ、既存の ACL_USER あるいは ACL_GROUP 型のエントリーは手付かずになるような ACL_MASK の値の再計算を afpd が行う。