在 Linux 系統中使用者透過 UID 區分身份,其中又分為
- EUID (Effective UID) 當建立、存取檔案時發揮作用
- RUID (Real UID) 實際行程 (Process) 的真正擁有者、影響傳送訊號 (Signal) 的權限
- SUID (Saved UID) 當降權時、將原本的權限暫存的。非 root 下 EUID 只能設定更改成 RUID、SUID 兩種
當系統登入時會檢查 /etc/passwd 下的內容、其中每行又透過 冒號 (:) 區隔分為 7 欄,分別為
- username
- password 其中 x 表示密碼儲存在 /etc/shadow 下、* 表示不允許登入
- UID
- GID
- Description
- home directory
- login shell
C
這是一個 C 版本的 setuid 簡單程式:
/* Simple get/set UID C program. The program set the set-uid-bit with root owner, the progam
* first has the root uid and can downgrade the privilege by the seteuid.
*
* > gcc test.c
* > chown root a.out
* > chmod +s a.out
* > ./a.out
*/
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
int main() {
uid_t uid;
gid_t gid;
fprintf(stdout, "uid: %d, gid: %d\n", getuid(), getgid());
fprintf(stdout, "euid: %d, egid: %d\n", geteuid(), getegid());
fprintf(stdout, "seteuid to 0: %d %m\n", seteuid(getuid()));
fprintf(stdout, "uid: %d, gid: %d\n", getuid(), getgid());
fprintf(stdout, "euid: %d, egid: %d\n", geteuid(), getegid());
fprintf(stdout, "seteuid to 0: %d %m\n", seteuid(0));
fprintf(stdout, "uid: %d, gid: %d\n", getuid(), getgid());
fprintf(stdout, "euid: %d, egid: %d\n", geteuid(), getegid());
return 0;
}