Mac OS X Leopardテクノロジーレポート集となる
【レポート】秘められた"真の革新"を暴く - the inner universe of Leopard
【レポート】the inner universe of Leopard - 「rcの引退とlaunchdの強化」
【特集】Mac OS X独自のディレクトリサービスOpen DirectoryとdsLocal(前編) - the inner universe of Leopard
もあわせてお楽しみください。

まず最初に注意点。

DirectoryService APIを使ったプログラミングは行うべきではない。CocoaやCarbonにはもう少しマシで使い物になるAPIがある。UNIX側のAPIを見てもPAMなどのまだマシなAPIはある。選択可能な回避策があるならば、それが何であれそちらを採用することを"強く強く"推奨する。繰り返すが、DirectoryService APIを使うべきではない。

この警告を無視してでも使いたい、Mac OS Xの暗部に触れたい、見返りの全くない冒険をしたいというユーザは、以下を参考にしてほしい。なお、この件についての問い合わせは遠慮していただけるとありがたい。

さて、DirectoryService APIを扱うにあたっては「node」「record」「attribute」の3つの概念があることに注意されたい(図1)。

図1: node、record、attributeの関係。nodeは第1階層と第2階層で組になっており、第1階層がディレクトリサービスの種別、第2階層がIPアドレスなどの情報源の所在という形になっている。例えば、LDAPサーバごとに異なるnodeと見なされる。recordは実際に格納されているデータの単位で、アカウント情報ならばユーザ1名が1recordに相当する。attributeはその中のキーと値で対応付けられる属性のことを指す

nodeは各ディレクトリサービスのサーバを意味するツリーのトップに当たるもので、サービスの形式とサーバの位置の2要素で作られるパスとなる。例えば/Local/DefaultはdsLocalというディレクトリサービス(/Local)の1つで、そのMac自身のツリーを指す。/LDAPv3/192.168.0.1ならLDAPv3でアクセスされるディレクトリサービスで、IPアドレスが192.168.0.1だ。

recordはディレクトリに格納される一塊のデータで、例えばユーザとかグループ、ホスト1つに相当する。recordは通常そのrecordの形式ごとに分類され、別のパスが用意される。例えば、/Local/Default/Users/meというrecordが存在した場合、これは/Local/Defaultというnodeに存在する、ユーザという形式のrecordで、名称がmeというものを指す。

recordはその種別ごとに階層構造を構築し、アクセスされる。この階層はrecordTypeとかrecordの形式と呼ばれることがある。

こうした階層構造やレコードの格納方式については、実際のディレクトリサービスごとに異なるが、そうした違いは、「【特集】Mac OS X独自のディレクトリサービスOpen DirectoryとdsLocal(前編) - the inner universe of Leopard」のdsLocalのdsmappingのようなマッピング情報を用いて、そのディレクトリサービスにアクセスするプラグインの中で吸収し、DirectoryServiceでは共通の名称を用意し、実際にディレクトリサービスへアクセスするプラグインが共通名称を個別の名称に変換するようになっている。このユーザという形式の場合、DirectoryServiceでは「kDSStdRecordTypeUsers」という定義になる。

attributeはそれぞれのrecordの持つ属性である。例えばユーザというrecordならば、そのユーザのユーザ名やUUID、UID、GID、シェルなどといった情報がattributeとして格納されている。attributeはattributeそのものの名称と、1つないし複数の値によって構成されている。

一般的なDirectoryServiceの手順としては、

  1. DirectoryServiceに接続する
  2. nodeを指定してnodeに接続する
  3. 必要ならば認証を行う
  4. nodeからrecordを読み書きする
  5. recordからattributeを読み書きする

といった手順になる。重要な注意点としては、3の認証が挙げられる。このタイミング、すなわちnodeに接続後recordを取得する前に認証を行わないと、recordの読み取りは可能だがrecordやattributeの作成や編集といった書き込み操作ができなくなってしまう。また、この認証操作そのものがかなり難物である。これについては後ほど実際のコードを交えて説明する。