次のように、bashプロンプトにsudoセッション状態を追加できます。
function sudo_active() {
if sudo -n /bin/true 2> /dev/null
then
printf '(sudo) '
fi
}
PS1="$PS1"'$(sudo_active)'
これにより、一連の sudo コマンドを実行でき、sudo セッションがまだアクティブであることを確認できます。セッションを早く終了したりsudo -k
、シェルを閉じたり、注意事項を覚えたりするなどの方法を使用できます。
このアプローチの問題の1つは、sudo権限なしで新しいプロンプトが実行されるたびに、システムログに次のメッセージが追加されることです。
sudo[25653]: myusername : a password is required ; TTY=pts/13 ; PWD=/home/myusername/ ; USER=root ; COMMAND=/bin/true
別の問題は、これがsudo
毎回プロンプトでコマンドを実行するため、passwd_timeout
必要なコマンドを実行しなくても、コマンドを実行するたびに(値に応じて)タイムアウトが再び延長されることですsudo
。
sudoセッションがまだアクティブであることをテストし、副作用としてセッションを継続的に再拡張せずにbashプロンプトに表示する方法はありますか?
答え1
sudoが各ユーザーに対して生成するタイムスタンプファイルを使用して、そのユーザーがsudoコマンドを使用した時間を見つけることができます。設定された時間(デフォルトは5分)より長い場合は、timestamp_timeout
新しいsudoにパスワードが必要です。
各ユーザーのファイルは/var/run/sudo/ts/
(私のシステムでは)下に作成されます。man sudoers
ソースが示すように、フォーマットはセクションで説明されています。タイムスタンプ.cそしてcheck.hこれは、struct timestamp_entry_v1
structまたは最新のstructで記述された複数のレコードで構成されていますstruct timestamp_entry
。
Gitバージョンは古いシステムの対応するソースよりも最新であるため、以前の構造バージョン1を使用しています。追加フィールドを持つ新しいバージョン2が必要になる場合があります。
以下は、ハードワイヤードユーザーの履歴をダンプする最小限のCプログラムです。
/* https://unix.stackexchange.com/a/595473/119298
* struct from
* https://github.com/sudo-project/sudo/blob/master/plugins/sudoers/check.h
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#define TS_VERSION 1
/* Time stamp entry types */
#define TS_GLOBAL 0x01
#define TS_TTY 0x02
#define TS_PPID 0x03
#define TS_LOCKEXCL 0x04
/* Time stamp flags */
#define TS_DISABLED 0x01 /* entry disabled */
#define TS_ANYUID 0x02 /* ignore uid, only valid in the key */
struct timestamp_entry {
unsigned short version; /* version number */
unsigned short size; /* entry size */
unsigned short type; /* TS_GLOBAL, TS_TTY, TS_PPID */
unsigned short flags; /* TS_DISABLED, TS_ANYUID */
uid_t auth_uid; /* uid to authenticate as */
pid_t sid; /* session ID associated with tty/ppid */
struct timespec ts; /* timestamp (CLOCK_MONOTONIC) */
union {
dev_t ttydev; /* tty device number */
pid_t ppid; /* parent pid */
} u;
};
void main(int argc, char **argv){
struct timestamp_entry entry;
struct timespec now;
int fd = open("/var/run/sudo/ts/meuh",O_RDONLY);
if(fd<0)exit(1);
clock_gettime(CLOCK_MONOTONIC, &now);
while(read(fd,&entry,sizeof(entry))==sizeof(entry)){
printf("type=%d flags=%d uid=%d sid=%d elapsedtime=%d\n",
entry.type, entry.flags, entry.auth_uid, entry.sid,
entry.ts.tv_sec-now.tv_sec);
}
exit(0);
}
私のシステムでこのsetuidルートをコンパイルして実行すると、次の行が表示されます。
type=4 flags=0 uid=0 sid=0 elapsedtime=-4763540
type=2 flags=1 uid=1000 sid=7003 elapsedtime=-4763540
type=2 flags=0 uid=1000 sid=4378 elapsedtime=-12
タイプ 4 の最初の項目は、レコードをロックするために使用されます。他の行はttyごとにすることができます。フラグ1は、アイテムが無効になっていることを示します(例:のためsudo -k
)。最後の行は、12秒前にプロセス4378でsudoコマンドを実行したuid 1000です。 5*60秒未満なので、追加のsudoにはまだパスワードは必要ありません。