就是模拟setuid seteuid setreuid setresuid,感觉代码比书上大段的文字好记,就写成代码形式了。
// setuid.cc: 模拟<unistd.h>中的设置用户ID的方法的作用 #include <stdio.h> #include <errno.h> int real = 0; // 实际用户ID int effective = 0; // 有效用户ID int saved = 0; // 保存的设置用户ID void showid(); // 打印所有ID inline bool hasPrivilege() { return effective == 0; } #define EINVAL_RETURN { errno = EINVAL; return -1; } #define EPERM_RETURN { errno = EPERM; return -1; } int setuid(int uid) // 修改所有用户ID { if (uid < 0) EINVAL_RETURN; if (!hasPrivilege() && uid != real && uid != saved) EPERM_RETURN; if (hasPrivilege()) real = effective = saved = uid; else effective = uid; return 0; } int seteuid(int euid) // 修改有效用户ID { if (euid < 0) EINVAL_RETURN; if (!hasPrivilege() && euid != real && euid != saved) EPERM_RETURN; effective = euid; return 0; } int setreuid(int ruid, int euid) // 修改实际/有效用户ID { if (ruid < -1 || euid < -1) EINVAL_RETURN; if (!hasPrivilege()) { if (ruid != -1 && ruid != real && ruid != effective) EPERM_RETURN; if (euid != -1 && euid != real && euid != effective && euid != saved) EPERM_RETURN; } int old_real = real; real = (ruid != -1) ? ruid : real; effective = (euid != -1) ? euid : effective; if (effective != old_real) saved = effective; return 0; } // 非SUSv3规范, 其他UNIX实现对其也鲜有支持 int setresuid(int ruid, int euid, int suid) // 修改实际/有效/保存用户ID { if (ruid < -1 || euid < -1 || suid < -1) EINVAL_RETURN; if (!hasPrivilege()) { if (ruid != -1 && ruid != real && ruid != effective && ruid != saved) EPERM_RETURN; if (euid != -1 && euid != real && euid != effective && euid != saved) EPERM_RETURN; if (suid != -1 && suid != real && suid != effective && suid != saved) EPERM_RETURN; } real = (ruid != -1) ? ruid : real; effective = (euid != -1) ? euid : effective; saved = (suid != -1) ? suid : saved; return 0; } int main() { real = 1000; // 下面4句只能执行其中1句 // setuid(2000); setreuid(-1, 2000); // seteuid(2000); // setresuid(-1, 2000, 3000); showid(); return 0; } void showid() { printf("实际用户ID: %4d\n", real); printf("有效用户ID: %4d\n", effective); printf("保存的设置用户ID: %4d\n", saved); }
main函数是TLPI第9章习题第1道的运行结果,然后模拟了一遍功能,后面几道也很简单就能做出来了。以后忘记的话看遍代码就能很快记起来了。
时间: 2024-10-22 16:37:53