suid が利かなくてはまった

perl スクリプトの中で secure ログを cat するような処理を書いていて、secure ログを cat するには root 権限が必要なので、
その perl スクリプトを suid すればいいよね、と軽く考えていた。
suid はほぼ使う機会が無いので知らなかったのだけど、実はスクリプト系のものには suid は無効らしい。

perl やら ruby やら sh やらのスクリプトは、chmod u+s しても効果がない。バイナリな実行ファイルでないと、OS は setuid/gid フラグを無視してしまって意図した権限で実行してくれない。それを許すと 穴になるからしかたないというのは承知してるけどさ、どーしてもやりたいこともあるわけで、そのたびごとに C のラッパーを書くのはめんどくさい。仕事だからやるけどさ

http://ya.maya.st/d/200908a.html

で、suid で変更したidは起動したプロセスでのみ有効で、内部で別プロセスを生成するときには変更前のidが使われる、と同僚が教えてくれたので、これも初耳。以下、ちょっと検証として、あってるのかあってないのか、微妙なコード。

#include <unistd.h>
#include <pwd.h>
#include <stdio.h>

void main (char* args) {
        struct passwd* pw;
        pw=getpwuid(geteuid());
        printf("%s\n",pw->pw_name);
        system("id");
}
$ gcc a.c;sudo chown root:root a.out; sudo chmod u+s a.out;./a.out
root
uid=501(kamei) gid=501(kamei) groups=501(kamei),10(wheel)

「system("id");」のとこは、合ってるのかどうか自信ない。

ちなみに、perl では、昔は suidperl ってのをインストールすると、suid を使えたようだが、今はたぶん使えなさそう。
あんまりこれをまじめに調べるモチベーションが無いので、すみません、適当にぐぐった結果ですmm