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 <stdio.h>
#include <stdlib.h>
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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#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 详解