From: nagai@... Date: 2002-03-26T15:35:56+09:00 Subject: [ruby-dev:16609] control uid/gid 永井@知能.九工大です. 現実逃避で,メソッド名等を考え直してみました. 考えてみると,何も Process モジュールに メソッドを用意しなければならないわけでもないので, Process::UserID. などとしてみた案です. 条件判断用のメソッドは追加になっていますが, メソッド体系としては前と変っていません. ぜひ意見をお願いします. ============================================================ uid/gid 操作の生のシステムコールの実装 (ポータビリティは期待できない) Process::ID_Syscall.setuid(id) Process::ID_Syscall.seteuid(id) Process::ID_Syscall.setreuid(rid,eid) Process::ID_Syscall.setgid(id) Process::ID_Syscall.setegid(id) Process::ID_Syscall.setregid(rid,eid) など ============================================================ uid/gid 操作のために実装するメソッド Process::UserID.real_id Process::UserID.effective_id Process::UserID.set(id) Process::UserID.set_effective(id) Process::UserID.exchange_reid Process::UserID.exchangeable? Process::UserID.has_saved_id? Process::UserID.switch_auth Process::UserID.switch_auth { ... } ------------------- Process::GroupID.real_id Process::GroupID.effective_id Process::GroupID.set(id) Process::GroupID.set_effective(id) Process::GroupID.exchange_reid Process::GroupID.exchangeable? Process::GroupID.has_saved_id? Process::GroupID.switch_auth Process::GroupID.switch_auth { ... } ============================================================ Process::UserID.real_id [Process::GroupID.real_id] 仕様 : 現在の実ユーザ ID を得る ============================================================ Process::UserID.effective_id [Process::GroupID.effective_id] 仕様 : 現在の実効ユーザ ID を得る ============================================================ Process::UserID.set(id) [Process::GroupID.set(id)] 仕様 : 実/実効/保存ユーザ ID のすべてを変更して, 他のユーザとしての権限を放棄する. 成功時は id を返す. 完全放棄できない場合(一部ユーザ ID の変更ができない場合)は 例外を発生する. 例外の発生時に,このメソッドを呼び出す前の各ユーザ ID の値が 保存されているかどうかは保証されない. 注意 : 以前の Process.uid= とは互換性がないことに注意. setreuid(id,-1) によって実装されていたものを用いていたケースは, 例えば次のように書き換える必要があるだろう. Process::UserID.exchange_reid ;# (r,e,s)==(u1,u2,??) ==> (u2,u1,??) Process::UserID.set_effective(id);# (u2,u1,??) ==> (u2,id,??) Process::UserID.exchange_reid ;# (u2,id,??) ==> (id,u2,??) ============================================================ Process::UserID.set_effective(id) [Process::GroupID.set_evective(id)] 仕様 : 実効ユーザ ID を変更する. 成功時は id を返す. 保存ユーザ ID の変化は,Process::UserID.exchageable? が true かどうかで決まる. 定義されない環境では,保存ユーザ ID は変化しない. 定義されている環境では,id が実ユーザ ID と異なる値に設定された場合, 保存ユーザ ID は新しい実効ユーザ ID の値に設定される. 設定できない場合は例外を発生する. ============================================================ Process::UserID.exchange_reid [Process::GroupID.exchange_reid] 仕様 : 実ユーザ ID と実効ユーザ ID とを入れ換える. 保存ユーザ ID は新しい実効ユーザ ID と同じになる. 環境依存により実装されていない場合は例外を発生する. 戻り値としては,新しい実効ユーザ ID を返す. ============================================================ Process::UserID.exchangeable? [Process::GroupID.exchangeable?] 仕様 : 実ユーザ ID と実効ユーザ ID との入れ換えが可能な環境かどうか (Process::UserID.exchange_reid が実装されているか) を真偽値で返す. 入れ換え可能なら true を返す. ============================================================ Process::UserID.has_saved_id? [Process::GroupID.has_saved_id?] 仕様 : 保存ユーザ ID を持つ環境かどうかを真偽値で返す. 保存ユーザ ID を持つなら true を返す. ただし,保存ユーザ ID の有無を明確に判定できない環境では, この値は推定値である (誤りの可能性もある) ことに注意が必要. 現在は,次の条件のいずれかが満足される場合に 保存ユーザ ID を持つものと判定する. ・setresuid を持つ ・seteuid を持つ ・_POSIX_SAVED_IDS が真として定義されている ============================================================ Process::UserID.switch_auth [Process::GroupID.switch_auth] Process::UserID.switch_auth { ... } [Process::GroupID.switch_auth { ... }] 仕様 : ユーザ権限を(一時的に)変更する. ブロックが与えられたならば,権限を移行してそのブロックを実行した後, 元の権限に復帰する. 途中で実/実効/保存ユーザ ID を変更しなければ, ブロックを与えない呼び出しを二度実行することで, 権限の一時的変更と元の権限への復帰とが可能となる. ブロックが与えられない場合の戻り値は元に戻せる(変更できる) ID 値, ブロックが与えられた場合の戻り値はブロックの値を返す. 実/実効/保存ユーザ ID が二つのユーザ権限を移行できる状態でなければ 例外を発生する (変更できるのは実ユーザ ID の権限へか, 保存ユーザ ID の権限へかのいずれかである). ブロックを与えた際に,ブロック内でユーザ ID が変更されたなどの理由で 元の権限に復帰できない場合も例外を発生する. 保存ユーザ ID を持たない環境では,このメソッドの実行によって 実ユーザ ID が変化する (ブロックを与えた場合はブロック実行中のみ). ============================================================ -- 永井 秀利 (九工大 知能情報) nagai@ai.kyutech.ac.jp