sudo
- setuidビットでroot権限を取得
- 実行者、ホスト、ターゲットユーザー、コマンドを特定
- sudoersのルールと順次照合
- 認証(パスワードまたはタイムスタンプ)
- fork → setuid/setgid → execveでコマンドを実行
Info
-uオプションがない場合、rootがデフォルト
- setgidの場合、ターゲットユーザーのプライマリグループに設定
動作
1
2// sudo 内部コード (擬似コード)
3
4struct context {
5 char *real_user; // "john" (RUIDから)
6 char *hostname; // "macbook-pro.local"
7 char *target_user; // "postgres" (-u オプション)
8 char *target_group; // "postgres" (-g オプションまたはデフォルト)
9 jchar *command; // "/usr/bin/psql"
10 char **args; // コマンド引数
11};
12
13context ctx = {
14 .real_user = getpwuid(getuid()), // john
15 .hostname = gethostname(), // macbook-pro.local
16 .target_user = parse_u_option() ?: "root", // postgres
17 .command = find_command_path("psql"), // /usr/bin/psql
18};
19
20// sudoers ファイル読み込み (root 権限が必要)
21FILE *sudoers = fopen("/etc/sudoers", "r");
22
23// パース結果 (例)
24rules[] = {
25 { user: "root", host: "ALL", runas_user: "ALL", runas_group: "ALL", command: "ALL" },
26 {
27 user: "%admin", // % = グループ
28 host: "ALL",
29 runas_user: "ALL",
30 runas_group: "ALL",
31 command: "ALL"
32 },
33 // ... その他のルール
34};
35
36// ルール照合
37// 認証 (+タイムスタンプ確認)
38// コマンド実行
sudoers
/etc/sudoers
構文
1# ユーザー ホスト = (実行されるユーザー) コマンド
2%admin ALL = (ALL) ALL