当たり前の話ではありますが、何を勘違いしてたか、今までsudo -Hすれば、$PATHをはじめとした環境変数がスイッチ後のユーザの物が使われると思っていました。
sudo -H してるのに$PATHが実行ユーザのもの引き継いだままで何故だーとはまっていました。
実際は-Hオプションは$HOMEを書き換えてくれるだけのオプションです。
% man sudo ... 前略 -H The -H (HOME) option requests that the security policy set the HOME environment variable to the home directory of the target user (root by default) as specified by the password database. Depending on the policy, this may be the default behavior.
ちなみに/etc/sudoersにalways_set_homeを指定しておけば、デフォルトで-Hの挙動です。
再現
環境
一般的なubuntu 12.04です。
% lsb_release -a No LSB modules are available. Distributor ID: Ubuntu Description: Ubuntu 12.04.5 LTS Release: 12.04 Codename: precise % uname -a Linux lab 3.2.0-60-generic #91-Ubuntu SMP Wed Feb 19 03:54:44 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux % sudo -V Sudo version 1.8.3p1 Sudoers policy plugin version 1.8.3p1 Sudoers file grammar version 40 Sudoers I/O plugin version 1.8.3p1
準備
$PATHと$HOMEをechoするだけのシェルスクリプトを用意しておきます。
% cat << '...' > /tmp/tmp.sh #!/bin/bash echo $PATH echo $HOME id ... % chmod +x /tmp/tmp.sh
ユーザのPATHの確認
% /tmp/tmp.sh /usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin:/home/masasuzu/bin /home/masasuzu uid=1000(masasuzu) gid=1000(masasuzu) groups=1000(masasuzu),4(adm),20(dialout),24(cdrom),46(plugdev),107(lpadmin),108(sambashare),109(admin)
sudoしてみる
sudo してもユーザの$PATHも$HOMEを引き継いだまま。
% sudo /tmp/tmp.sh /usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin:/home/masasuzu/bin /home/masasuzu uid=0(root) gid=0(root) groups=0(root)
$HOMEはスイッチ後のユーザのものですが、$PATHはそのまま。
% sudo -H /tmp/tmp.sh /usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin:/home/masasuzu/bin /root
ちょっとしたからくり
これたぶん、これを読んでる人が同じ手順を手元で追試してみるとこういう結果にはならないと思います。
Ubuntu 12.04だと/etc/sudoersに下記の記述があるため、sudoしたときにPATHは書き換わってくれるからです。
Defaults secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
セットアップスクリプトの不備でsudoersを書き換える際にsecure_pathをごそっと消してしまったため、前述のように実行ユーザの$PATHが引き継がれておかしなことになっていた次第です。
ちなみにexempt_groupでグループ指定しておけば、secure_pathが指定されず、$PATHを引き継いで使えるようです
% man sudoers ... 前略 secure_path Path used for every command run from sudo. If you don't trust the people running sudo to have a sane PATH environment variable you may want to use this. Another use is if you want to have the "root path" be separate from the "user path." Users in the group specified by the exempt_group option are not affected by secure_path. This option is not set by default.
蛇足1
rootでsudo -Vすると削除される環境変数、引き継ぐ環境変数の一覧を見ることができます。
% sudo sudo -V ... 前略 Environment variables to check for sanity: TERM LINGUAS LC_* LANGUAGE LANG COLORTERM Environment variables to remove: RUBYOPT RUBYLIB PYTHONUSERBASE PYTHONINSPECT PYTHONPATH PYTHONHOME TMPPREFIX ZDOTDIR READNULLCMD NULLCMD FPATH PERL5DB PERL5OPT PERL5LIB PERLLIB PERLIO_DEBUG JAVA_TOOL_OPTIONS SHELLOPTS GLOBIGNORE PS4 BASH_ENV ENV TERMCAP TERMPATH TERMINFO_DIRS TERMINFO _RLD* LD_* PATH_LOCALE NLSPATH HOSTALIASES RES_OPTIONS LOCALDOMAIN CDPATH IFS Environment variables to preserve: XAUTHORIZATION XAUTHORITY TZ PS2 PS1 PATH LS_COLORS KRB5CCNAME HOSTNAME HOME DISPLAY COLORS
蛇足2
secure_pathがデフォルトの状態でも実行の仕方によって挙動の違いがでます。sudoなかなか味わい深い。調べる時間があったらまた書くかも。
% sudo /tmp/tmp.sh /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin /home/masasuzu uid=0(root) gid=0(root) groups=0(root) % sudo -i /tmp/tmp.sh /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin /root uid=0(root) gid=0(root) groups=0(root) % sudo -s /tmp/tmp.sh /usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin:/home/masasuzu/bin /home/masasuzu uid=0(root) gid=0(root) groups=0(root) % sudo su -c /tmp/tmp.sh /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games /root uid=0(root) gid=0(root) groups=0(root) % sudo su - -c /tmp/tmp.sh /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin /root uid=0(root) gid=0(root) groups=0(root)
sudoコマンド味わい深い
— masasuzu? (@masasuz) January 20, 2015