ルートとして実行されているデーモンによって開始されるプロセスがありますが、このプロセスの特権を平均的なユーザーの特権に「ダウングレード」したいと考えています。これは可能ですか?はいの場合はどうですか?
PS:MacでUNIXを実行する
プロセス自体がsetuid(2)を呼び出す必要があります。まだ実行していない場合は、chroot(8)内で実行することも検討する必要があります。私の知る限り、rootが別のプロセスのuidを変更する方法はありません。
ルートとして実行する理由がポートのバインドである場合は、通常のユーザーとして上位ポートで実行し、OS Xでipfw(8)を使用してポート80/443/etcを上位ポートに転送することをお勧めします。
http://support.crashplanpro.com/doku.php/recipe/forward_port_443_to_pro_server_on_mac_osx
Sudo tcpdump -Z
は、initgroups(3)、setgid(2)、setuid(2)を使用して、自身のプロセスのroot特権を削除します。
# code taken from:
# http://www.opensource.Apple.com/source/tcpdump/tcpdump-32/tcpdump/tcpdump.c
/* Drop root privileges and chroot if necessary */
static void
droproot(const char *username, const char *chroot_dir)
{
...
if (initgroups(pw->pw_name, pw->pw_gid) != 0 ||
setgid(pw->pw_gid) != 0 || setuid(pw->pw_uid) != 0) {
fprintf(stderr, "tcpdump: Couldn't change to '%.32s' uid=%lu gid=%lu: %s\n",
username,
(unsigned long)pw->pw_uid,
(unsigned long)pw->pw_gid,
pcap_strerror(errno));
exit(1);
}
...
}
su
を使用して、他のユーザーとしてコマンドを実行できます。
su USERNAME -c COMMAND
特権をCOMMAND
に下げてUSER
を実行します。
デフォルトでは、su
はターゲットユーザーのシェルインタープリターを使用してコマンドを実行することに注意してください。対照的に、Sudo
のデフォルトの動作は、COMMAND
をスタンドアロンプログラムとして扱い、現在の環境で実行されます。もちろん、これらのデフォルトの動作は、さまざまなスイッチと環境変数で変更できます。
特権をドロップするには、ドロップする非rootユーザーが必要です。次に、そのユーザーに切り替えるだけです。
#define UNPRIV_UID 48
#define UNPRIV_GID 48
if (getuid() == 0) { // we are root
// setting UID/GID requires root privileges, so if you don't set
// the GID first, you won't be able to do it at all.
if (setgid(UNPRIV_GID)!=0) die("Failed to set nonroot GID");
if (setuid(UNPRIV_UID)!=0) die("Failed to set nonroot UID");
}
ASSERT(getuid() != 0);
これは、ラッパースクリプトではなくプログラム内自体で行われることに注意してください。多くのプログラムは、特定の目的(たとえば、小さい番号のポートにバインドする)のためにroot権限を必要としますが、その後はrootを必要としません。したがって、これらのプログラムはrootとして起動しますが、不要になったら特権を削除します。
Root権限がまったく必要ない場合は、rootとして実行しないでください。例えば。:
# Change this:
myprog -C /my/config/file
# To this:
Sudo -u someuser myprog -C /my/config/file
# Or this
su someuser -c "myprog -C /my/config/file"
別の実行可能ファイルを実行している場合、つまりexecve
または別のexec
ファミリの関数を呼び出している場合、おそらくsystem
またはpopen
であり、子プロセスは最初から特権なしで実行する必要があります。その場合、最も簡単な方法は、シェルを関与させてsu
を呼び出すことです。以下は、Perlでのコードの外観の概要であり、に必要な引用を示しています。
$Shell_command = quotemeta($path_to_executable) . " --option";
$Shell_command =~ s/'/'\\''/; # protect single quotes for the use as argument to su
$su_command = sprintf("su -c '%s' %s", $Shell_command, quotemeta($user_name));
open(PIPE, "$su_command |") or die;
子プロセスがルートとして開始する必要があるが、後で特権を削除する必要がある場合は、プロセス内の特権をダウングレードする方法を示す この回答のコード を参照してください。