2012-02-15 8 views
6

権限4750のプロセスがあります。私のLinuxシステムには2人のユーザーが存在します。 rootユーザーとappzユーザー。このプロセスは、 "appz"ユーザとして実行されるプロセスマネージャの権限を継承します。Cでsetuidプログラムを実行する正しい方法

私は2つの基本的なルーチンがあります。

void do_root (void) 
{ 
     int status; 
     status = seteuid (euid); 
     if (status < 0) { 
     exit (status); 
     }  
} 

/* undo root permissions */ 
void undo_root (void) 
{ 
int status; 
     status = seteuid (ruid); 
     if (status < 0) { 
       exit (status); 
     } 
     status = setuid(ruid); 
     if (status < 0) { 
       exit (status); 
     } 
} 

私の流れは以下の通りです:

int main() { 
undo_root(); 
do some stuff; 
do_root(); 
bind(port 80); //needs root perm 
undo_root(); 
while(1) { 

    accept commads() 
    if (commands needs root user access) 
    { 
     do_root(); 
     execute(); 
     undo_root(); 

    } 

} 

あなたは私がルートとしていくつかのコマンドを実行したい見ることができるように。権限を一時的に削除しようとしています。タスクにrootアクセスが必要な場合は、do_rootとundo_rootの間でコマンドをラップします。

しかし、私のプログラムは動作していないようです。

標準的な方法は何ですか?

+0

seteuidが失敗したときに終了するのではなく、perrorあなたのプログラムはなぜそれが失敗しているかをあなたに伝えます。 –

+4

root権限を削除すると、戻せません! – Petesh

+0

技術的には、プロセスではなく4750のアクセス権を持つプログラムを保持しているファイルです。パーミッションが 'root:group:4750'であると直接言いません - それは安全な推論ですか? –

答えて

5

古い学校の方法は、RUIDとEUIDを交換するではsetreuid()を使用しdo_rootとundo_rootの両方にすることです。

setreuid(geteuid(), getuid()); 

プログラムは、完全なセキュリティ監査を行うのに十分に小さい場合、これは完全に受け入れています。

new-schoolの方法ははるかに複雑で、rootとして何をするのかを受け入れる子をfork()し、setuid(getuid())を実行して親に永続的にルートを落とします。子どもは受け取ったすべての指令を検証する責任があります。十分な大きさのプログラムの場合、これはセキュリティ監査が必要なコードの量を減らし、ユーザーがジョブ制御でプロセスを管理したり、終了させたりすることができます。

+0

どういう意味ですか?両方の機能にコードをコピー&ペーストするだけですか? – cateof

+0

はい。 __________ – Joshua

2

setuid manページには、次のように述べている:

...一時的に、その後、ルート 権限を落とし、root以外のユーザーのIDを仮定し、希望にset-user-ID-rootプログラムあなたがsetuid()を使用することができないことにsetuid()

意味を使用することはできません後で root権限を取り戻します。 seteuid()と、おそらくsetreuid()を使用する必要があります。詳細はSetuid Program Exampleを参照してください。

+0

私のプログラムはこのGNUページに基づいています。 do_setuidの代わりに、私は最初do_rootを行いました。 – cateof

+0

@cateof:あなたが投稿したコードで 'setuid'関数を使うのが分かります。それは片道切符です。 –

5

Hao Chen、David Wagner、およびDrew Deanによる論文「Setuid Demystified」があります。 USENIX 2002で発表されました。setuid()とトランジションがどのように詳細に機能するかを記述しています(2002年現在)。それはよく読む価値があります(何度か、私は1年か2年が経過しています)。

Peteshコメントで述べたようにEUID 0を持つプロセスがnuid != 0setuid(nuid)を行う際に、基本的に、バックroot(EUID 0)権限に方法はありません。そして、確かにそうであることが不可欠です。それ以外の場合、ログインすると、ログインするプロセスrootはあなた自身の特権に制限されません。rootに戻ることができます。保存されたUIDは事を複雑にしますが、私はそれがsetuid()を行っているEUID 0の一方向トラップに影響するとは思いません。

関連する問題