どのユーザーが終了信号を送信したかをキャプチャ

どのユーザーが終了信号を送信したかをキャプチャ

管理者権限を持つ他のユーザーがそのスクリプトを使用しようとしている間、休止状態に移行するスクリプトを実行しているとしますpkill。可能であれば、そのシグナルを自分のプロセスに送信したユーザーをどのようにキャプチャできますか?

kill -9 <my_script>SIGKILLでは何もキャプチャまたは実行できないため、このような機能では何もキャプチャできないことがわかります。

答え1

はい、可能です。スクリプトではないかもしれません。これを行うには、次のように信号ハンドラを設定する必要があります。sigactionフラグを使用しSA_SIGINFO、同じ署名付きハンドラーを提供します。

void handler(int sig, siginfo_t *info, void *ucontext)

信号を処理するために呼び出されたときに2番目の引数として受け取るポインタには、送信siginfo_tプロセスのプロセス識別子()、送信プロセスの読み取りユーザー識別子()などの情報が含まれます。送信された信号を使用するために入力されます。info->si_pidinfo->si_uidkillまたはsigqueue

これをPythonとして実装するには多くの作業が必要です。信号モジュール構造にアクセスする方法は提供されていませんsiginfo_t

答え2

bash + ctypes.sh

楽しみに@StephenKittのソリューションを使用して、以下はbashの例です。バッシュプラグイン ctypes.sh(この例ではコンパイルしてインストールする必要があります/usr/local。)

残念ながら、両方の構成は複雑sigactionすぎるため、組み込みコマンドは機能しません。したがって、これらの構造は手動で定義する必要があります。これは非常に面倒で、移植性がありません(オペレーティングシステムやアーキテクチャに)。この例では、x86_64アーキテクチャでLinux> = 4.6を想定しています。siginfo_tctypes.shstructinfo->si_pkey

#!/bin/bash

. /usr/local/bin/ctypes.sh || exit 2

handler () {
    local -a info=(int int int int uint32 uint32 int int64 int64 int64 int pointer int int pointer long int short pointer pointer int pointer int unsigned)
    unpack $3 info

    echo ''
    echo "handler($2, info={${info[@]}}, $4);"
    echo -- handling signal $2 --
    echo "info->si_pid=${info[4]}"
    echo "info->si_uid=${info[5]}"
    return
}
callback -n handler handler void int pointer pointer

SIGUSR2=12
SA_SIGINFO=4

act=(
    $handler
    long:0 long:0 long:0 long:0 long:0 long:0 long:0 long:0 long:0 long:0 long:0 long:0 long:0 long:0 long:0 long:0
    int:$SA_SIGINFO
    pointer:0
)
sizeof_act=$(( 8 + 16 * 8 + 4 + 8 ))

dlcall -n pact -r pointer malloc $sizeof_act
[ $pact != pointer:0 ] || exit 1
pack $pact act

dlcall -n ret -r int sigaction int:$SIGUSR2 $pact pointer:0
[ $ret = int:0 ] || exit 1

echo "sigaction(SIGUSR2, act={${act[@]}}, NULL) = $ret"

echo ''
echo run this: kill -$SIGUSR2 $$
sleep 99

実装する:

1学期:

$ ./siginfo.bash 
sigaction(SIGUSR2, act={pointer:0x7ff26f0d3010 long:0 long:0 long:0 long:0 long:0 long:0 long:0 long:0 long:0 long:0 long:0 long:0 long:0 long:0 long:0 long:0 int:4 pointer:0}, NULL) = int:0

run this: kill -12 24250

2学期:

$ echo $$
21864
$ id -u
1000
$ kill -12 24250
$ 

項目1の結果:

handler(int:12, info={int:12 int:0 int:0 int:0 uint32:21864 uint32:1000 int:0 int64:0 int64:0 int64:0 int:0 pointer:0 int:0 int:0 pointer:0 long:0 int:0 short:0 pointer:0 pointer:0 int:0 pointer:0 int:0 unsigned:0}, pointer:0x7fff4583a500);
-- handling signal int:12 --
info->si_pid=uint32:21864
info->si_uid=uint32:1000

関連情報