假期就要结束了,放假太久都人都有点懒散了。废话少说,继续更新boa的代码阅读笔记吧。
drop_privs();
看函数名字应该是丢弃特权,下面是它的定义。
static void drop_privs(void)
{
/* give away our privs if we can */
if (getuid() == 0) {//root用户,能使用setuid
struct passwd *passwdbuf;
passwdbuf = getpwuid(server_uid); //根据server_uid获取passwd结构
if (passwdbuf == NULL) {
DIE("getpwuid");
}
//初始化进程附加用户组
if (initgroups(passwdbuf->pw_name, passwdbuf->pw_gid) == -1) {
DIE("initgroups");
}
if (setgid(server_gid) == -1) {//设置当前gid为server_gid,必须在setuid之前
DIE("setgid");
}
if (setuid(server_uid) == -1) {//设置当前uid为server_uid
DIE("setuid");
}
/* test for failed-but-return-was-successful setuid
* http://www.securityportal.com/list-archive/bugtraq/2000/Jun/0101.html
*/
if (setuid(0) != -1) {//检测setuid是否存在bug--执行失败但返回成功
DIE("icky Linux kernel bug!");
}
} else {//非root用户,无法使用setuid
if (server_gid || server_uid) {//server_gid和server_uid不同时为0(需要设置uid但权限不够)
log_error_time();
fprintf(stderr, "Warning: "
"Not running as root: no attempt to change"
" to uid %d gid %d\n", server_uid, server_gid);
}
//server_gid和server_uid同时为0(默认值?),重设这两个id为当前用户的值
server_gid = getgid();
server_uid = getuid();
}
}
上面提到了getuid()这个函数,我特意查了这个函数的说明,一共找到两个类似的函数:
uid_t getuid(void); //获得用户 UID 值
uid_t geteuid(void); //获得用户有效 UID 值
setuid()用来重新设置执行目前进程的用户识别码。不过,要让此函数有作用,其有效的用户识别码必须为0(root)。在Linux下,当root 使用setuid()来变换成其他用户识别码时,root权限会被抛弃,完全转换成该用户身份,也就是说,该进程往后将不再具有可setuid()的权 利,如果只是向暂时抛弃root 权限,稍后想重新取回权限,则必须使用seteuid()。
一般在编写具setuid root的程序时,为减少此类程序带来的系统安全风险,在使用完root权限后建议马上执行setuid(getuid());来抛弃root权限。此外,进程uid和euid不一致时Linux系统将不会产生core dump。
具更具体的说明可以参考一篇我转的博客,感觉写的很好http://my.oschina.net/firemiles/blog/324504