|
HMDT - Back Number / September, 2001 |
September, 2001
◆ AuthorizationItemSet AuthorizationItem が複数あるのが AuthorizationItemSet だ。
◆ AuthorizationRights AuthorizationRights は AuthorizationItemSet のことね。
◆ AuthorizationEnivironment AuthorizationEnvirionment も AuthorizationItemSet のこと。この 3 つは実体は同じ物だね。
◆ kAuthorizationEmptyEnvironment kAuthorizationEmptyEnvironment は AuthorizationEnvironment に指定できる定数だ。何も指定しないときに使えるよ。
今回は Authorization API で使われる、構造体やフラグや定数だ。 ◆ AuthorizationRef 認証に使われるオブジェクトだ。Authorization API は、すべてこの AuthorizationRef を使って処理をするんだ。
こいつを作るには AuthorizationCreate() を呼ぶ。使い終わって破棄するときは AuthorizationFree() だ。 ◆ AuthorizationFlags これは Authorization API を呼ぶときに設定するフラグなんだ。
各フラグの意味は、だいたいこんな感じだ。もちろん、各 API でちょっとずつフラグの解釈は違うけどね。 kAuthorizationFlagDefaults kAuthorizationFlagInteractionAllowd kAuthorizationFlagExtendRights kAuthorizationFlagDestroyRights ◆ AuthorizationItem 認証に必要な情報を格納するのがこの AuthorizationItem だ。たとえばユーザ名とかパスワードとかね。
name のところには情報の種類を指定するんだけど、こんなものがあるんだ。 kAuthorizationEnvironmentUsername kAuthorizationEnvironmentPassword kAuthorizationEnvironmentShared kAuthorizationRightExecute
◆ 認証されたプロセスの ID AuthorizationExecuteWithPrivileges() で起動されたプロセスの process ID を得る方法はないのか?それじゃ起動した後はパイプしか通信手段がないの?それじゃ、ちゃんと制御できないじゃん。
◆ Authorization の有効期間 認証には有効期間が設定してあるらしい。認証した後、ぼーっとほっておいて、もう一回アクセスしようとすると再認証を求められるんだ。その時間は?どうやって設定するんだ?うーむ、どこに書いてあるのか見つからないぞ。ただ、sudo の man を見てみると、デフォルト 5 分って書いてある。Authorization API を使ったときも、経験的にそのくらいだから、そういうことかも。じゃ、時間を変えるには?どうも Authorization API からは設定する術がないようだ。将来の拡張に期待しましょう。
◆ Authorization API でできること Authorization API でできることは、結論からいうと、ある実行ファイルを実行することだ。実行後はパイプを使って、やりとりできる。つまり、この API は、UNIX ライクな(つーか、UNIX そのもの)コマンドを実行することを念頭に置いたものなんだ。 まず Authorization API は、きみが、いま、どれぐらいの権限を持ってるか調べるんだ。そして、それはあるコマンドを実行するのに十分な権限なのか?ってことも調査できる。もし足りなかったら、それを拡大することもできる。おっと、もちろん適切なパスワードが必要だぜ。そのパスワードの入力をうながすためのダイアログも Authorization API が提供するんだ。 処理の流れを簡単に見てみよう。まず認証オブジェクト AuthorizationRef を作ってやんないといけない。これは AuthorizationCreate() で作れるぜ。 認証オブジェクトができたら、きみがどのくらいの権限を持っているかどうか調べることができる。たとえば /sbin/shutdown を実行できるか?とか。<いきなり shutdown かい。それには AuthorizationCopyRights() を使う。これで、実行できるかどうかが調べられる。 もし、十分な権限がなかったらどうするんだ?その場合は、権限を広げることができるんだ。もちろんパスワードが要求されるぜ。これも AuthorizationCopyRights() を使うんだ。 これで十分な権限を確保していることを確認したら、実行だ!AuthorizationExecuteWithPrivileges() で実行できる。 使い終わった後は、認証オブジェクトを削除するのを忘れずに。AuthorizationFree() だ。
◆ Permission denided を乗りこえる じゃ、デスクトップ・アプリケーションを作るときのことを考えてみよう。この場合でも root 権限が欲しい場合がある。たとえばインストールの時とか、/usr/sbin の下のファイルを削除するときとか<良い子はそんなことしちゃいかん。喜びいさんでやろうとすると、無情の Permission denided が表示されることになるだろう。やかましいわ、おれはこのマシンの所有者だぞ、一人で使ってるんだぞ、ネットワークにも公開してないぞ、だから好きにファイルをいぢらせろー、ぜぃぜぃ、はぁはぁ。と、文句をいっても解決しないのである。だって Mac OS X は UNIX だから。 現実的な解決策は、コマンドラインから操作しているならば sudo を使うことだ。これで root 権限が得られる。じゃ GUI ベースの場合は?Cocoa アプリならば sudo を NSTask で呼び出してもいいけど、めんどくさいよね。そこで Apple から提供されたのが Authorization API なんだ。これを使えば GUI ベースで楽々認証ができるんだぜ!
◆ su 禁止 つまるところ UNIX に皮を被せたものである Mac OS X には、“ユーザ”と“ログイン”っていう概念があるんだ。そして“root”っていう概念もある。ある特定のファイルやディレクトリには root しか触ることができないんだ。しかし、classic の Mac OS にはそんな考え方がなかったので、普通のユーザはそんなことを気にしないだろう。機能拡張やコントロールパネルを外して楽しむように、/bin や /usr/sbin の下のファイルを外して、使用メモリを減らそうと試みるかもしれない。おぉぅ、それはやめてくれぇ。そんなことが流行りはじめたら、混乱を極めることは間違いないだろう。 そこで Apple がとった手段は、10.0 以降の Mac OS X では、デフォルトでの root でのログインを禁止することだった。Oh, my! これは英断と見るべきなのか、暴挙と見るべきなのか?さらにさらに、Apple は su までも禁止したのだった。su というのは、root の権限を得るためのコマンドね。Terminal で su を打つと、次のように表示されるんだ。
root になろうとすると、ひとこと "Sorry"。クール過ぎるぜ! さて、当然このままで終わるわけはなくて、Apple は別の手段を推賞している。それは sudo を使うこと。sudo を使うとコマンドを root 権限で実行することができる。su と違うのは、sudo はすべてのログが残る、ということらしい。つまり su だと、Telnet で侵入されて root になられて好き放題やられちゃうけど、sudo ならばその場合でもログが残るぜ、ということなのだ。うーん、あまり変わらんような気もするが。別の効用もあるのか?
Security.framework をきちんと理解しよう、と思って Authrization.h のヘッダを見てたんだ。結構コメントが充実しているんだよ。もったいないから(?)ちょっと訳してみた、、、あー、時間がないや。走り書きだけ載せていくね。近日中にきちんと訳してみる予定。会社行かんと。じゃ。 AuthorizationCreate 新しい認証オブジェクトを作るんだ。その認証がもういらなくなったら、AuthorizationFree を呼ばないとだめだかんね。 kAuthorizationFlagInteractionAllowed フラグが設定されたときは、必要なときにユーザからの入力を、おらおら早くパスワード入れんかいって、要求するんだ。これの設定に失敗したりすると、ほんとうに必要なときに、errAuthorizationInteractionNotAllowed っていうエラーが起こるんだ。 AuthorizationFree 認証オブジェクトを壊すんだ。kAuthorizationFreeFlagDestroy が設定されたときは、認証に関する権利がすべてなくなるんだ。設定しなかったら、ローカルのだけがなくなって、他のクライアントの分は残るんだ。(訳注:この他のクライアントってのは、他のユーザのことか?それとも他の種類の認証のことか?) AuthorizationCopyRights いま認証されているのはなにか?を、調べるためのものなんだ。 AuthorizationCopyInfo sideband 情報(たとえばアクセス credentials とか)を調べるためのものだ(訳注:わかんねーよ!access credentials ってなに?) AuthorizationMakeExternalForm 認証を外部の "byte blob" の形に変えるんだ。これで他のプロセスに送ることができるぜ(訳注:これもわからんよー) AuthorizationCreateFromExternalForm (訳注:これは上と同じかな。認証の作成も込みみたい) AuthorizationFreeItemSet API を呼んで確保された AuthorizationItemSet のメモリを解放するんだ。 AuthhorizationExecuteWithPrivileges 適切な認証処理が終わった後に、その権限で実行ファイルを実行するんだ。 AuthorizationCopyPrivilegedReference AuthorizationExecuteWithPrivileges で実行されてるツールから、認証オブジェクトを取り出すんだ。
NSArray の話だ。正しいかどうか、ちょっと不安だけど。 NSArray ってのは、Foundation にある配列をあらわすクラスだよね。NSArray には NSObject を入れることができる。さて、自分で NSObject を継承するクラスを作ったら、それを簡単に NSArray に入れることができるのか? そうではない。らしい。NSArray に入れるオブジェクトは copyWithZone: を実装しておかないといけない。実装していなければ、runtime error が発生するんだ。つまり、NSArray に突っ込んだ時点でコピーしているんだね、きっと。参照の保持ではなくて、値の保持である、と。 じゃあ、copyWithZone: を実装するときになにか気をつけることはあるのか?copyWithZone: は、自分のクラスのコピーを作って返すメソッドだ。返り値として id を返すんだけど、このインスタンスは retain されていないといけない。autorelease されてはいけない。
正しくは、こう。
alloc を直接使っている場合は間違えないと思うけど、自前のファクトリメソッドを作って、その中で autorelease している場合は注意が必要だ、と思う。 今回の話は、ドキュメントで確かめたわけではなくて、実際にコードを書いていて気付いただけなので、ほんとに正しいかどうか不安です。よかったら、どなたか、これで正しいのかどうか教えて下さい。
ごぶさた!バケーションを取ってました。南の島で、身も心もリラックスしてきたよ。 さて、どういうわけか、最近英語のメールが多く届くようになりました。どこかで紹介されたのか?ま、その全部が「日本語だからわからねーよ」っていうメールなんですが。 その中に、「OS X 10.1 で NSPreferecnePane ってのが追加されたでしょ。使い方知らない?」っていうのが混じってました。ほうほう、そんなものがあったのか。じゃ、っていうんで System/Library/Frameworks を探してみると、、、おっ、確かに PreferencePanes.framework っていうのものがある。なるほど、これを使えば初期設定パネルが作れるのか。ざっと見ると、うんうん、nib を関連づければいいわけね。10.1 がリリースされたら、フリーウェアで初期設定パネルを作るのが流行りそう。
先日、マウス押しっぱなしでコンテキストメニューを表示できないかなー、と書いたところ、やまかわさんから、performSelector:object:afterDelay: を使えばいいじゃん、と教えていただきました。Thanks! てなわけで、やってみました。 こんな感じのコードを書いてみた。
まず、mouseDown: の中で performSelector:::: を呼び出す。その際、inModes に NSEventTrackingRunLoopMode を設定するのがコツ。これで Cocoa がイベントのトラッキングをしている間でも呼び出される。その後、親の mouseDown: を呼び出す。最後に cancelPreviousPerformRequestsWithTarget::: でセレクタの呼び出しをキャンセルする。 じゃ、動かしてみよう。おっ、でたでた。メニューが出た。やったじゃん。あり?でも、その後の挙動がおかしいぞ、、、 どう動いているのかいろいろ調べてみたところ、設定したメソッドが呼ばれた後、この場合は showContextMenu: ね、親の mouseDown: の中から抜け出てこないようだ。
流れは、まず mouseDown: が呼ばれる。performSelector を設定して、親に制御を移す。その中で Tracking Event Loop が回る。一定時間がたつと、showContextMenu: が呼ばれる。ここでいったん確認するけど、いまはマウスボタン押しっぱなしの状態だよね?で、メニューが表示されるでしょ。その後、マウスボタンを離す。でもこのイベントは、mouseDown: の中の Tracking Event Loop に通知されないようだ。だから、そこから抜けるには、どこかでもう一度クリックしてやらないといけない。これじゃ、まずいでしょー。 うーむ、もうひとひねり必要だな。
|
|
Home | Link | Download | Back Number | Speciall Issue
|