Java中有“封装”的概念,简单来讲,就是把类的属性和方法设置为private/protected,这样只能在类的内部访问这些属性和方法,并提供public方法来调用private方法或者获取/修改private属性。
在linux权限中,有时也会遇到类似的问题,比如你希望其他用户能够对你的文件做一些统计工作,但又不想让他们获取文件的内容,这时候就可以写一个程序来进行统计工作,让其他用户调用这个程序。或者另外一种场景,你只希望他们能够读取你文件的前10行摘要。
借助于SUID权限,就可以实现,具有SUID的文件有以下特征:
* SUID 权限仅对二进制程序(binary program)有效;
* 执行者对于该程序需要具有 x 的可执行权限;
* 本权限仅在执行该程序的过程中有效 (run-time);
* 执行者将具有该程序拥有者 (owner) 的权限。
假设程序wordcount和文本sample.txt属于用户qingsong,其中wordcount可以统计sample.txt中的字符数、行数和单词数。
另一个用户inst97具有wordcount的执行权限,但对sample.txt没有访问权限。那么当inst97尝试用wordcount统计sample.txt单词数时,就会报错。如果此时qingsong不想赋sample.txt的读权限给inst97,但又想让其完成统计工作,就可以给wordcount赋予SUID权限,那么当inst97执行wordcount期间,就获得了qingsong的权限。(是不是有点类似于java中的封装)
wordcount.c代码如下
#include <stdio.h>
#define IN 1 /*inside a word*/
#define OUT 0 /*outsite a word*/
/*Purepose of this program is count words, lines and characters from file*/
/*Code Source: The C programming language*/
/*File name: wordcount.c*/
int main(int argc, char *argv[])
{
int c, nword, nline, nchar;
int states;
FILE *fp;
if (argc != 2) {
printf("Wrong number of pamaters!\n");
printf("Usage: wordcount filename\n");
return 1;
}
nword=nline=nchar=0;
states=OUT;
if ((fp=fopen(*++argv, "r")) == NULL) {
printf("Open file %s failed\n", *argv);
return 1;
}
while((c=getc(fp)) != EOF) {
nchar++;
if ( c == '\n')
nline++;
if ( c=='\n' || c==' ' || c=='\t')
states=OUT;
else if (states==OUT) {
nword++;
states=IN;
}
}
printf("Lines:%d, Words:%d, Chars:%d\n", nline, nword, nchar);
fclose(fp);
return 0;
}
编译C程序,验证结果,wc程序一样:
qingsong@db2a:~/cprogram$ gcc -o wordcount wordcount.c
qingsong@db2a:~/cprogram$ ./wordcount sample.txt
Lines:34, Words:84, Chars:594
qingsong@db2a:~/cprogram$ wc sample.txt
34 84 594 sample.txt
qingsong@db2a:~/cprogram$ ls -l wordcount
-rwxrwxr-x 1 qingsong admin 8732 Aug 30 04:38 wordcount
qingsong@db2a:~/cprogram$ chmod 640 sample.txt
qingsong@db2a:~/cprogram$ ls -l sample.txt
-rw-r----- 1 qingsong admin 594 Aug 30 03:52 sample.txt
现在切换到 inst97用户,来使用wordcount统计sample.txt,会报错误:
inst97@db2a:/home/qingsong/cprogram$ . /wordcount sample.txt
Open file sample.txt failed
切换回 qingsong,给程序wordcount赋予SUID权限即可,wordcount原来的权限是775,要赋予SUID的权限,只需要在775前面加个4。赋权之后,可以看到ls -l的输出中多了一项s,表示SUID权限
qingsong@db2a:~/cprogram$ chmod 4775 wordcount
qingsong@db2a:~/cprogram$ ls -l wordcount
-rwsrwxr-x 1 qingsong admin 8732 Aug 30 04:38 wordcount
切换到 inst97用户:
inst97@db2a:/home/qingsong/cprogram$ cat sample.txt
cat: sample.txt: Permission denied
inst97@db2a:/home/qingsong/cprogram$ ./wordcount sample.txt
Lines:34, Words:84, Chars:594 <--可以通过程序wordcount“打开”文件,进行统计任务
需要注意一点,SUID只对二进制文件有效,下面的shell脚本可以实现同样的统计功能,但并没有什么用:
qingsong@db2a:~/cprogram$ cat wordcount.sh
#!/bin/bash
#filename wordcount.sh
nword=`egrep -o '\S+' $1 | wc -l`
nline=`awk 'END{print NR}' $1`
n1=`egrep -o '.' $1 | wc -l`
let nchar=n1+nline;
echo "Lines:$nline, Words:$nword, Chars:$nchar"
qingsong@db2a:~/cprogram$ chmod +x wordcount.sh
qingsong@db2a:~/cprogram$ chmod 4775 wordcount.sh
qingsong@db2a:~/cprogram$ ls -l wordcount.sh
-rwsrwxr-x 1 qingsong admin 200 Aug 30 05:14 wordcount.sh
qingsong@db2a:~/cprogram$ ./wordcount.sh sample.txt
Lines:34, Words:84, Chars:594
qingsong@db2a:~/cprogram$ su inst97
Password:
inst97@db2a:/home/qingsong/cprogram$ ./wordcount.sh sample.txt
egrep: sample.txt: Permission denied
awk: cannot open sample.txt (Permission denied)
egrep: sample.txt: Permission denied
Lines:, Words:0, Chars:0
还有另外两个权限SGID,SBIT,参考链接:
http://blog.csdn.net/qingsong3333/article/details/77726215
补充:最后那个脚本统计行数、单词数和字符数可以使用下面的awk语句来实现: