Linux 特殊权限s 和t 演示

Linux 特殊权限s 和t 演示

前言概念

s 和t 权限会代替原x 权限所在的位置

一、关于t 权限最好的例子是ls -ld /tmp # -d 表示目录
任何人都可以在/tmp下创建文件,且只能删除自己创建的文件(root 用户例外)

二、本文主要演示s 权限,它表示执行者将用于文件创建者同样的权限
注意:仅适用于二进制可执行文件,对于.sh 脚本文件不使用

演示过程

# 1. Ubuntu 14.04 上安装gcc
sudo apt-get install -y gcc

# 2. 切换到/tmp 目录及root 用户
cd /tmp && sudo -s

# 3. 编写两个程序cwrite 和cread,分别用于写入和读取数据
# 为了方便演示,文件都指定为/tmp/rootfile.txt
# 3.1 cwrite.c 用于写入文件
cat > cwrite.c << 'EOF'
#include 
#include 

int main(int argc, char *argv[])  
{
  if(argc < 3)  // 必须有2 个参数
  {
    printf("Usage: %s filename inputstring\n", argv[0]);
    exit(1);
  }

  FILE *fp = NULL;
  fp = fopen(argv[1], "a+");     /*追加模式打开文件*/
  fprintf(fp, "%s\n", argv[2]);  /*写入一行数据*/
  fclose(fp);                    /*关闭文件*/

  // 显示写入文件的结果
  printf("%s >> %s\n", argv[2], argv[1]);
  return 0;
}
EOF

# 3.2 生成cwrite 可执行文件,并设置s 权限
gcc cwrite.c -o cwrite && chmod a-w+rx,u+s $_
# chmod 命令解释:a 表所有去掉w,加上r 和x 权限,u 表文件所有者加上s
# $_ 表上一个命令的最后一个参数
ls -l cwrite  # -r-sr-xr-x,发现s 代替了原来x 权限的位置

# 3.3 cread.c 用于读取文件
cat > cread.c << 'EOF'
#include 
#include 
#include 
#define MAX_LINE 1024

int main(int argc, char *argv[])
{
  if(argc < 2)  // 必须有1 个参数
  {
    printf("Usage: %s filename\n", argv[0]);
    exit(1);
  }

  char buf[MAX_LINE];  /*缓冲区*/
  FILE *fp;            /*文件指针*/
  int len;             /*行字符个数*/

  printf("%s\n", argv[1]);
  fp = fopen(argv[1], "r");
  while(fgets(buf, MAX_LINE, fp) != NULL)
  {
    len = strlen(buf);
    buf[len-1] = '\0';  /*去掉换行符*/
    printf("%s %d \n", buf, len - 1);
  }
  fclose(fp);
  return 0;
}
EOF

# 3.4 生成cread 可执行文件,并设置s 权限
gcc cread.c -o cread && chmod a-w+rx,u+s $_
# chmod 命令解释:a 表所有去掉w,加上r 和x 权限,u 表文件所有者加上s
# $_ 表上一个命令的最后一个参数
ls -l cread  # -r-sr-xr-x,发现s 代替了原来x 权限的位置

# 4. 创建/tmp/rootfile.txt 并设置只有root 可读
echo "root only" > /tmp/rootfile.txt
chmod 400 /tmp/rootfile.txt

# 5. 切换到普通用户abc
su - abc
cat /tmp/rootfile.txt  # 报错,权限不足,Permission denied
/tmp/cread /tmp/rootfile.txt  # 成功读取到/tmp/rootfile.txt 的内容
/tmp/cwrite /tmp/rootfile.txt abc123  # 成功过写入"abc123" 到/tmp/rootfile.txt
/tmp/cread /tmp/rootfile.txt  # 成功读取文件包括上一条命令新增的内容

# 6. 结论
# 由于root 给/tmp/cwrite 和/tmp/cread 赋予了u+s 和o+x 权限
# (u 表示文件所有者,o 表示其他用户,x 表执行权限)
# 所以,其他用户运行/tmp/cwrite 和/tmp/cread 时具有root 的权限
# 其他用户才得以读写只有root 有读权限的/tmp/rootfile.txt 文件

注意事项

# 其他用户必须要有x 执行权限,文件所有者s 或所有者所属的组g 设置了s 权限
# 其他用户在执行该文件的时候,才能获得文件所有者或所有者所属组的权限
# 设置权限也可以用数字的方式,SUID 4, SGID 2, SBIT 1
# 以设置s 权限为例
cd /tmp && touch testfile1 testfile2
chmod 4755 testfile1
# 等价于
chmod u+rwxs,go+rx-w testfile2
# 查看结果
ls -l testfile[12]
#-rwsr-xr-x 1 abc abc 0 Jun 12 12:04 testfile1
#-rwsr-xr-x 1 abc abc 0 Jun 12 12:04 testfile2

# 注意:大写S 和T 的出现
chmod 4655 testfile1
ls -l testfile1
#-rwSr-xr-x 1 abc abc 0 Jun 12 12:04 testfile1
# 出现了大写的S,因为s 和t 这类特殊权限替换的都是x 权限
# 655 在文件所有者u 上并没有x 执行权限,即使给它s 权限也是个空权限
# 所以用大写S 或T 表示该文件有s 或t 权限,但是它们不起作用

参考文档

C 文件读写
C 读取文件实例
C 命令行参数
Linux 特殊权限SUID SGID SBIT
Linux 文件特殊权限s 和t
Linux 文件特殊权限SUID SGID SBIT 详解

你可能感兴趣的:(Linux 特殊权限s 和t 演示)