uid,gid:
实际用户id和实际组id,进程的这两个id在登入时从口令文件/etc/passwd中获取。
euid,geid:
有效用户id,有效组id 决定了我们的进程访问文件的权限。进程的有效用户id通常就是实际用户id。
suid,sgid:
当一个进程访问设置了set-user-ID或是set-group-ID标志的文件时,该文件的宿主用户id被保存在suid中。
例如:修改用户密码时,需要使用命令passwd以及写文件/etc/passwd或是/etc/shadow
/usr/bin/passwd
-rwsr-xr-x 1 root root 41284 Sep 12 2012 passwd
/etc/passwd
-rw-r--r-- 1 root root 1147 Mar 22 2015 passwd
/etc/shadow
-rw-r----- 1 root shadow 928 Mar 7 10:52 shadow
命令passwd设置了s位,所以当用户进程执行passwd程序时
i = inode->i_mode;
e_uid = (i & S_ISUID) ? inode->i_uid : current->euid;
e_gid = (i & S_ISGID) ? inode->i_gid : current->egid;
current->euid = e_uid;
current->egid = e_gid;
所以用户进程的e_uid和e_gid 就变了passwd的用户id和组id,即root。
后续该进程操作/etc/passwd或是/etc/shadow时 就能通过权限检查
int mode = inode->i_mode;
/* special case: not even root can read/write a deleted file */
if (inode->i_dev && !inode->i_nlinks)
return 0;
else if (current->euid==inode->i_uid)
mode >>= 6;
else if (current->egid==inode->i_gid)
mode >>= 3;
if (((mode & mask & 0007) == mask) || suser())
return 1;
return 0;
检查进程对文件的操作权限时,使用的是euid或是guid
而当一个进程创建新文件时,该文件的uid和gid也是进程的euid和egid
inode->i_uid=current->euid;
inode->i_gid=current->egid;