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

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"}' 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值