您的位置:首页 > 运维架构 > Linux

Linux: 通过SUID权限来实现“封装”

2017-08-30 22:01 330 查看
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语句来实现:

 awk '{nw = nw + NF; nc = nc + length($0) + 1} END {print NR, "lines", nw, "words", nc, "chars"}' 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  linux SGID SUID SBIT