Files
ligent/src/priv.h
T
2026-10-03 14:13:21 +08:00

43 lines
2.3 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/* priv.h - 提权:经 sudo 执行单条命令
*
* 先说清楚这个模块**不做**什么,以及为什么:
*
* PAM 认证不等于获得权限。su 之所以能变 root,是因为 /usr/bin/su 这个文件
* 本身是 setuid root —— 内核先把 root 给它,它再验密码、验不过就降权。普通
* 进程调 pam_authenticate() 只能得到"密码对不对",uid 一位都不变。要让 ligent
* 内部认证后真的变 root,唯一的路是把它编译成 setuid root;而它的功能是
* "让模型执行任意命令",setuid root 的它等于把 root 远程执行做成一等功能。
* 所以不走那条路。
*
* 也不做"授权提示"。**密码本身就是授权**:模型敲不出来,你也不可能手滑敲出来。
* 再加一道 y/N 只会是多余的摩擦,还会给出一个虚假的安全模型 —— 好像把关的是
* ligent 的提示,其实真正把关的是 sudo。所以这里只做两件事:
*
* 1. 把命令包成 `sudo -u <用户> -- <argv>` 交出去(**不经 shell**,
* 所以路径/命令里的引号、换行、`;` 注入不进 root 那条命令里);
* 2. 需要密码时,**让终端留在 sudo 手上**,由它自己问、自己存 —— ligent
* 不读、不存、不转发密码。
*
* 唯一由 ligent 把守的是"别卡死":没有控制终端就**根本不去试**,直接说清楚。
* 否则就会起一个在后台等一个没人能看见的密码提示的进程。
*/
#ifndef LIGENT_PRIV_H
#define LIGENT_PRIV_H
#include <stddef.h>
/* 有可用的控制终端吗?判据是能不能打开 /dev/tty,**不是** isatty(0):
* `echo x | ligent ...` 时 stdin 是管道,但终端还在,sudo 照样问得出来。 */
int priv_have_tty(void);
/* 把 argv 包成 `sudo -u <user> -- <原 argv>`(user 为空则 "root")。
* 故意**不带 -n**:需要密码时就让 sudo 自己去问。
* 返回 malloc 的数组,元素是借用的指针 —— 调用方 free 数组本身即可。 */
char **priv_sudo_argv(const char *user, char *const argv[]);
/* sudo 失败时把它的原话换成一句能照做的中文(写进 err)。
* 认不出来就原样透传 —— 宁可给原文,也不要编一句可能不对的解释。 */
void priv_explain(int rc, const char *out, char *err, size_t errlen);
#endif /* LIGENT_PRIV_H */