(無償) logo
世界中で使われるISO標準オフィスソフト(MSオフィス互換)

★LibreOfficeの導入事例★
詳細について

2015年5月4日月曜日

【Linux CentOS 6.5 64bit】強制的にroot権限でスクリプトを動作させる方法

※注意※
以下の方法はあくまでも、安全なローカル環境下、一般ユーザが使用しない環境で試すものです。


あるスクリプトが通常ユーザ権限で動作する場合、
その内部に「root権限が必要な処理」が記述されていると、失敗してしまう。


こういうとき、たとえば次のようにして制限を回避できる。

「root権限が必要な処理」だけ別プログラムとしてファイルに分離し、
SUID(=setuid)をそのファイルに設定し、所有者をrootに設定する。
SUIDが設定された実行ファイルは、
呼び出し元のスクリプトの実行権限に関係なく所有者の権限(この場合はroot)で動作する。
そして、これを元のスクリプトから呼び出すようにすればよい。

しかし、CentOS 6.5では、
スクリプトファイルにsetuidを設定しても、ファイル所有者権限で実行されなかった


そこで、さらに次のようにしてこの制限を回避した。

スクリプトを呼び出して実行するだけのバイナリプログラムを作成し、
これにSUIDを与え、所有者をrootとする。
これによって呼び出されたスクリプトは、root権限で動作することになる。


大元のスクリプト(通常ユーザで動作)
  ↓
  ↓呼び出し
  ↓
バイナリプログラム(SUIDにより、root権限で動作)
  ↓
  ↓呼び出し
  ↓
スクリプト (root権限で動作)



■次のように、C言語でプログラムを作成した。

(内容の説明)

引数として5つの文字列が指定できる。
sprintf関数で、それら引数を一つの文字列にフォーマットして、変数buffに格納する。

最初の引数は、root権限で実行させたいスクリプトへのパスを記述する。
2~5までの引数は、「そのスクリプトに渡す引数」をそれぞれ記述する。
したがって、これらが一つの文字列にフォーマットされると、
スクリプト名を先頭に引数を連ねた「コマンド文字列」が生成される。

setuid関数でrootを指定した上で、system関数にこの「コマンド文字列」を渡し実行させる。


[root@test etc]# vim caller-script-4arg.c
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>

int main(int argc,char *argv[])
{
        char    buff[100];

        sprintf(buff,"%s %s %s %s %s",argv[1],argv[2],argv[3],argv[4],argv[5]);

        setuid( 0 );
        system(buff);

        return 0;
}

■コンパイルした
[root@test etc]# gcc caller-script-4arg.c -o caller-script-4arg


■実行できるようにした
[root@test etc]# chmod +x caller-script-4arg


■さらにSUIDを設定した
これによって、このバイナリファイルは「ファイル所有者(=root)の権限」で、実行される。

[root@test etc]# chmod u+s caller-script-4arg

○ls -all コマンドの結果
-rwsr-xr-x  1 root root    6841  4月 17 00:00 2015 caller-script-4arg
-rw-r--r--  1 root root     256  4月 17 00:00 2015 caller-script-4arg.c

これはあくまでも実験である。全てのユーザーに、このバイナリの実行権限を与えるべきではない


■動作確認
大元のスクリプトにおいて次のようにして記述した。(2例)
作成したバイナリプログラム(root, SUID)に、「test.shとその引数」を、5つの引数として与えた。
(test.shにも実行属性を与えておくこと。)

/etc/caller-script-4arg "/etc/test.sh" "uucp:${admittedgroup}" "${SAVETObase0DIR}" "750" " "

/etc/caller-script-4arg "/test/test.sh" "uucp:${admittedgroup}" "${SAVETODIR}" "770" "-R"

test.sh内には、chmodや、chownが含まれていたが、
root権限でtest.shが実行されたので、うまく処理ができるようになった。



(参考)
・setuid on shell scripts
< http://www.tuxation.com/setuid-on-shell-scripts.html > 2015年5月4日

・sprintf
< http://www9.plala.or.jp/sgwr-t/lib/sprintf.html > 2015年5月4日

・UNIX処方箋:SUIDとは
< http://www.itmedia.co.jp/enterprise/articles/0804/08/news014.html > 2015年5月4日

・setuid は慎重に
< http://www.ipa.go.jp/security/awareness/vendor/programmingv1/b07_03.html > 2015年5月4日