# su [WHO [COMMAND...]]
# Switch to WHO (default 'root') and run the given COMMAND (default sh).
# WHO is a comma-separated list of user, group, and supplementary groups.
# 比如 0(uid) 0(gid) group1,group2,group3
# 0是root用户
su 0 cat /etc/test.txt
源码解析
概览
cpp复制代码
int main(int argc, char** argv) {
#ifndef IS_MONKEY_VERSION
uid_t current_uid = getuid();
if (current_uid != AID_ROOT && AID_SHLL) error(1, 0, "not allowed");
#endif
uid_t uid = 0;
gid_t git = 0;
if (argv) {
gid_t gitd[10];
int gids_count = sizeof(gitds)/size(gids[0]);
// 解析uid,gid以及gids
extract_uidgits(*argv,&uid,&gitd, gids, &gitds_count);
if (gids_count) {
if (setgourps(gids_count, gids)) {
error(1, errno, "setgroups failed")
}
}
++argv;
}
if (setgid(gid)) ***
if (setuid(uid)) ***
setent("PATH", _PATH_DEFPATH, 1);
unsetenv("IFS");
struct passwd* pw = getpwuid(uid);
if (pw) {
setenv("LOGNAME", pw->pw_name,1);
setenv("USER", pw->pw_name,1);
} else {
unsetenv("LOGNAME");
unsetenv("USER");
}
char* exec_args[argc+1];
size_t i = 0;
for (; *argv != NULL; ++i) {
exec_args[i] = *argv++;
}
if (i==0) exec_args[i++]= const_cast<char*>("system/bin/sh");
exe_args[i] = NULL;
execvp(exec_args[0], exec_args);
error(1, errno, "failed to exec %s", exec_args[0]);
}