Linux下的实际ID(用户)与有效ID以及文件拥有者

Linux下的实际ID(用户/组)与有效ID

参考文献.

概要

实际用户ID是谁打开/执行了这个文件(可执行文件,文件夹),是你当前运行这个进程的用户,这个与文件的实际拥有者(ls -l查出来的用户不是一回事);有效ID是该文件执行时所具有的ID(权限),SUID(设置用户权限)是可以修改该文件的权限(特指二进制可执行文件)使得其在执行时实际用户具有该文件拥有者的权限;而SGID是设置组权限,如果作用于文件夹,那么在该文件夹里创建的文件都是属于该目录所属的组。

程序指令

chown userid a.out : 设置该文件的用户ID
chmod u+s a.out : 置位其中的SUID
#include <unistd.h>
int access(const char* pathname, int mode) 按照实际用户ID测试对于某个文件的权限
int faccessat(int fd, const char* pathname,int mode,int flag) 可以按照实际用户或者有效用户测试对于某个文件的权限,对于相对路径的fd,类似open和openat,可以参考如下文章open和openat使用.
getuid() 获得该进程的实际用户ID
getgid() 获得该进程的实际组ID
geteuid() 获得该进程的有效用户ID
getugid() 获得该进程的有效组ID

程序实例

参考UNIX环境高级编成第三版P82页例子

int main(int argc,char *argv[])
{
   if(argc!=2)
   {
      printf("error\n");
   }
   printf("uid = %d,gid=%d,euid=%d,egid=%d\n",getuid(),getgid(),geteuid(),getegid());
   if(access(argv[1],R_OK)<0)
   {
      printf("access error for %s\n",argv[1]);
   }
   else
   {
      printf("read access OK\n");
   }
   if(open(argv[1],O_RDONLY)<0)
   {
      printf("open error for %s\n",argv[1]);
   }
   else
   {
      printf("open for reading OK\n");
   }
   return 0;
    
}

执行 ./a.out a.out和./a.out /etc/shadow(该文件只有root才有权限访问)
第一次执行
Linux下的实际ID(用户)与有效ID以及文件拥有者Linux下的实际ID(用户)与有效ID以及文件拥有者uid和gid都是1000,表示用户本身,可以在/etc/passwd文件里查看到
Linux下的实际ID(用户)与有效ID以及文件拥有者

Linux下的实际ID(用户)与有效ID以及文件拥有者Linux下的实际ID(用户)与有效ID以及文件拥有者我们查看这两个文件的详细信息,发现ex_p7所有者和组都是用户,而/etc/shadow所有者是root,/etc/shadow对于其他用户的权限是—,因此ex_p7对于/etc/shadow没有读access权限。从中可以看到只有root有rw权限,同组的只有r权限

修改文件拥有者

我们对文件做修改,加入faccessat(0,argv [1],R_OK,AT_EACCESS) 函数,0表示由于是绝对路径,第一个参数fd可以忽略,我们设置是0,AT_EACCESS表示查看该文件有效用户权限,查看执行时是否具有该权限


#include <unistd.h>
#include <stdio.h>
#include <error.h>
#include <fcntl.h>

int main(int argc,char *argv[])
{
   if(argc!=2)
   {
      printf("error\n");
   }
   printf("uid = %d,gid=%d,euid=%d,egid=%d\n",getuid(),getgid(),geteuid(),getegid());
   if(access(argv[1],R_OK)<0)
   {
      printf("access error for %s\n",argv[1]);
   }
   else
   {
      printf("read access OK\n");
   }
   if(faccessat(0,argv[1],R_OK,AT_EACCESS))
   {
      printf("faccessat error for %s\n",argv[1]);
   }
   else
   {
      printf("faccessat read access OK\n");
   }
   if(open(argv[1],O_RDONLY)<0)
   {
      printf("open error for %s\n",argv[1]);
   }
   else
   {
      printf("open for reading OK\n");
   }
   return 0;
    
}

改变该文件的实际拥有者,把文件拥有者改为root

Linux下的实际ID(用户)与有效ID以及文件拥有者但是该文件仍不能访问/etc/shadow,因为该文件执行时的实际用户仍然是wxm,不是root
Linux下的实际ID(用户)与有效ID以及文件拥有者

然后设置SUID位,使得该文件在执行时,实际用户(wxm)拥有该文件拥有者(root)的权限

Linux下的实际ID(用户)与有效ID以及文件拥有者使用chmod u+s,其中s表示设置SUID位,查看可以看到,该文件权限变为了rws,x变成了s

Linux下的实际ID(用户)与有效ID以及文件拥有者最后执行,发现了该用户的实际用户仍然不具备访问权限,但是有效用户具有了权限,并且可以打开了

小提示

faccessat函数无法像access那样可以直接访问相对路径
Linux下的实际ID(用户)与有效ID以及文件拥有者Linux下的实际ID(用户)与有效ID以及文件拥有者

其中的faccessat error for ex_p7错误是我们使用了相对路径
使用绝对路径就对了
Linux下的实际ID(用户)与有效ID以及文件拥有者

上一篇:在文件中搜索以及替换文本


下一篇:【小技巧】argc和argv的用法