Saturday, December 13, 2008

关于set-user-ID位

今天, 有人问我:为什么一般用户可以在X环境下, 可以把机器给关了, 但是在console下就要使用root权限.

其实, 这个问题很简单的. 一个很常看的例子就是sudo程序了. 看看吧:

jessinio@jessinio-laptop:/tmp$ ls -l $(which sudo)
-rwsr-xr-x 2 root root 115136 2008-09-01 21:17 /usr/bin/sudo

两个特点:
1. sudo的拥有者为root
2. 有一个"s"位

什么是"s"位, 它又有什么作用的呢?

"s"位就是"set-user-ID"的意思, 作用就是让其它用户运行有"s"位的程序时都可以等于程序的拥用者运行此程序一样.

就如sudo的例子, jessinio用户可以sudo时, 可以等于root(sudo程序的拥有者)运行一样.(这里不谈与sudo与sudoers文件的关系)

set-user-ID的得到是从chmod(system call)得到的.如:

jessinio@jessinio-laptop:/tmp$ sudo chmod u+s wrapper.o

这里有两个问题:
1. 对脚本文件不起作用(原理后面解释)
2. symbolic links文件不起作用

对于脚本的问题, 由于脚本是被解释器运行的, 如果解释器没有set-user-ID位的话, 脚本文件有set-user-ID位也没有意思

比如:readme.txt有set-user-ID, 使用vim编辑这个文件也不行使vim进程有root权限的

对于symbolic links的问题, 在chmod的man手册中就说清楚了:

chmod never changes the permissions of symbolic links; the chmod system call cannot
change their permissions. This is not a problem since the permissions of symbolic links
are never used. However, for each symbolic link listed on the command line, chmod
changes the permissions of the pointed-to file. In contrast, chmod ignores symbolic
links encountered during recursive directory traversals.

上面的是linux的chmod的man手册.

但是在FreeBSD中, chmod是可以使用"-h"参数去令chmod程序去修改文件的权限(当然有set-user-ID), 但是, 还是不起作用的, 因为对于unix/linux系统来说, symbolic links文件的permissions是被忽略的

问题又来了, 对于写脚本的人来说, 怎么利用上set-user-ID呢?

答案是使用编译型语言写wrapper

简单的例子如下:

#include
int main (int argc, char ** argv) {

int err;
char *newenv[] = { NULL };

if ((err = execle("./runfile.py", "pauseme", NULL, newenv)) < 0 ) {
exit(err);
}

return 0; // never reached!
}

其中, runfile.py就是这个目标wraper程序要去调用的脚本程序. 这样, 当wrapper程序有set-user-ID位的情况下, runfile.py脚本就会被set-user-ID用户去调用, 就是等于有set-user-ID位了^_^


上面的wrapper.c文件的处理方法:

jessinio@jessinio-laptop:/tmp$ gcc wrapper.c -o wrapper.o
jessinio@jessinio-laptop:/tmp$ sudo chmod root:root wrapper.o
jessinio@jessinio-laptop:/tmp$ sudo chmod u+s wrapper.o

注意: 每次使用chmod设置permissions后, set-user-ID都会被去掉的.可以重新设置它

No comments:

Post a Comment

Note: Only a member of this blog may post a comment.