Unix-like系统的文件权限

1 名词解释

uiduser id

一个uid表示系统中的一个用户,可对应多个gid

gidgroup id

一个gid表示系统中的一个组,可对应多个uid

ruidreal user id

一个进程的真实uid,如果不是root,进程间的signal必须是相同的ruid之间才能进行,例如子进程继承了父进程的ruid,所以可以互相signal

rgidreal group id

一个进程的真实gid

euideffective user id

一个进程的有效uid,当一个进程创建或访问文件时,用的不是ruid的权限,而是euid的权限。

egideffective group id

一个进程的有效gid,原理同上

suidsaved user id

一个特权进程(privilege process,它的euid是特权值)在运行中间可能需要做一些非特权工作,就会将euid设置为某个非特权的,这时会将特权值存放在suid,注意,这时进程已经变成非特权进程(unprivileged process)了,而一般普通的非特权进程是无法主动把自己变成一个特权进程的,因为对euid的赋值只能是ruideuidsuid之一,但由于前面把特权值存放在了suid,所以这时进程就可以恢复成特权进程了。

sgidsaved group id

原理同上,给一个特权进程恢复的机会。

fsuidfile system user id

linux引入的,单独控制对文件系统的访问权限,不过一旦euid发生变化,fsuid立即跟着变化。fsuid的用途是,允许一些程序(例如NFS server)拥有一些已知uid的对文件系统的访问权限,但是不拥有uid对应的发送signal的权限。也就是说,在不修改ruideuid的情况下,就改变了文件系统访问权限。对fsuid的赋值只能是ruideuidsuid之一。

fsgidfile system group id

原理同上,赋值只能是rgidegidsgid之一。

 

注:suidsgid和下面所说的SUIDSGID含义不同,这里指的是某一个uidgid的值,而下面的SUIDSGID是一个位(bit)是否设置。缩写相同会导致混淆,所以我用大小写来区分。



2 文件权限基础

2.1 用户的分类:文件的拥有者(owner,简称u)、文件的组ID对应的组用户(file'sgroup,简称g)、其它用户(others,简称o)。

   如果是所有用户(包括三种,all,简称a)。

 

2.2 对于一个文件用户可能有以下三种基本权限

 

 

文件

文件夹

r

读文件

列出文件夹内容。屏蔽这个位可以对别人隐藏文件夹中各个文件名。

w

写文件

创建或移除文件。屏蔽这个位可以使文件夹中的文件数目不变。

执行x

执行文件(run it as a program

访问文件夹中的文件。如果不具有x权限:无法cd到这个文件夹;无法创建或删除文件(即使有文件夹w权限);无法读取或写入文件内容(即使对文件夹和文件本身都有rw权限)。

屏蔽这个位,用户唯一能做的就是查看文件夹有哪些文件。

 

结论是:必需对文件夹同时拥有wx权限,才能创建或删除文件;必需对文件夹拥有x权限并对文件拥有rw权限,才能读或写文件。

 

 

2.3 还有三种特殊权限(影响可执行文件,有些系统还影响文件夹)

 

 

文件

文件夹

SUID(setuid bit)

如果设置,当文件执行时设置进程的euid,这个值是文件拥有者的uid

 

SGID(setgid bit)

如果设置,当文件执行时设置进程的egid,这个值是文件所属的组ID

某些系统中,如果对某文件夹设置了这个位,那么无论是拥有者属于哪个组,在此文件夹中创建的文件和此文件夹同组。

sticky bit

如果设置,执行文件时,即使程序结束,二进制映像也保存在swap分区,可以实现快速重启。但是linux并不支持这个特点。

对文件夹设置这个位,则只有此文件夹的拥有者,或者文件夹中文件的拥有者,或者超级用户才能重命名或删除文件。

Solaris有一个独有特性,针对不可执行文件,如果设置了这个位,不会在内核中缓冲。

 

2.4 某些文件系统相关属性

 

例如访问控制列表(ACLs,表示一个文件系统只能由哪些用户访问),一个文件能否被压缩、修改或核心转储,这些属性通常是通过文件系统特有的命令来设置的(例如ext2可以用chattrFFS可以用chrflags)。

所以尽管文件本身的属性可能允许用户进行操作,但是实际操作还是会失败,例如:文件系统属性不允许,文件系统挂载为只读的。

 

2.5 一个文件创建的时候就会分配拥有者和组,通常来说,拥有者是当前用户,组是文件所属文件夹的组。不过这也不是绝对的,取决于操作系统和文件系统的不同。可以用chownchgrp修改文件的拥有者和组。



3 文件权限修改(shell命令)

3.1 相关命令

添加、删除、修改用户或组(这些命令影响uidgid):useradd/userdel/usermod/groupadd/groupdel/groupmod

修改文件拥有者:chown

修改文件所属组:chgrp

修改文件属性:chmod

设置忽略掩码:umask

 

3.2 chmod命令

 

下面详细说明一下chmod,首先我们看一下Linux中对文件权限的显示

---------- 1 guanxin root 0 12-28 09:35 empty.txt
-rwx------ 1 guanxin root 0 12-28 09:36 owner.txt
----rwx--- 1 guanxin root 0 12-28 09:36 group.txt
-------rwx 1 guanxin root 0 12-28 09:36 others.txt

可以看到一共有10个位置,第一个位置标示文件类型(-普通文件,d文件夹,b块设备文件,c字符设备文件,l链接文件,p命名管道文件,s套接字文件),接下来的9个位置分别是拥有者、文件所属组的组用户、其它用户的读、写、执行权限(如果不具有权限显示-,具有权限显示一个对应字母)。

 

Unix-like系统中,文件夹也是文件的一种,所以对于文件夹也可以设置权限。例如:

drwxrwxr--  2 root    root     4096 12-28 09:36 test

以这个test文件夹为例,ug用户拥有全部权限,但是o用户只能ls test,因为具有r权限,但是不能cd test(这需要x权限),也不能rm -ftest/others.txt(这需要wx权限,注意!!!创建和删除文件只需要拥有文件夹的wx权限,而无需对文件本身具有任何权限,例如上面的empty.txt文件的权限是全空,但是用户只要拥有对test文件夹的wx权限,仍然可以删除它!!!)。

 

下面列举几个常用命令:

chmod g+rwx test   # 给g用户添加rwx三种权限
chmod o-wx test    # 删除o用户的wx权限
chmod +x  haha.sh  # 给脚本haha.sh添加执行权限,前面没有指定用户,则默认是a,全部。

设置SUID

chmod u+s a.out
-rwsr-xr-x 1 guanxin root 7577 12-26 12:31 a.out

可以看到owner对应的x权限变成了小写s,如上所述,设置SUID位就会使运行这个文件时获得guanxin用户的权限。当然执行完,权限也就消失了。

一般这功能用于临时获取root权限,例如执行/usr/bin/passwd修改密码,需要访问修改/etc/passswd文件,而这个文件对其它用户而言是只读的,那我想修改自己的密码怎么办?答案是设置SUID位。

-rwsr-xr-x1 root root 27768 2007-01-07 /usr/bin/passwd

可以看到这个文件的拥有者是root,所以执行时会获得root权限。

 

对于文件夹设置SUID位是没有任何作用的,对于没有x权限的文件设置SUID位,结果是一个大写S标志。

-rwS------ 1 guanxin root 15 12-28 10:57 owner.txt
echo haha >>owner.txt   # 如果对owner.txt进行修改,那么它会自动丢失大S属性。
-rw------- 1 guanxin root 20 12-28 11:26 owner.txt

鉴于SUID位容易有安全隐患,万一有人无意中设置被别人钻空子(使得运行特权进程后,不正常结束,通过缓冲区溢出或代码注入继续运行特权程序),所以许多操作系统会忽略对脚本的SUID设置。


设置SGID

chmod g+s a.out
-rwsr-sr-x 1 guanxin root 7577 12-26 12:31 a.out

这时g用户对应的x位变成了小s,它表示文件启动执行时,会获得root组的组权限(设置egid)。同样也是如果对不带x权限的文件设置,会显示大写S

 

如果对文件夹设置SGID位,表示在此文件夹中创建的文件,组都是和文件夹相同。

drwxrwxrwx  2 root    root     4096 12-28 11:43 test      # 没对test文件夹设置SGID位
-rw-rw-r-- 1 guanxin2 guanxin2  0 12-28 11:43 haha3.txt   # 用户guanxin2创建的文件是创建者的名字和组
chmod g+s test
drwxrwsrwx  2 root    root     4096 12-28 11:43 test      # 对test文件夹设置SGID位
-rw-rw-r-- 1 guanxin2 root      0 12-28 11:45 haha4.txt   # 用户guanxin2创建的文件拥有者还是guanxin2,但是组变成了root


设置sticky bit

chmod +t  a.out


4 进程权限修改(Linux系统C函数)

C函数可以用chmod/fchmod来修改文件属性。下面两个表格是在进程运行中如何修改uidgid从而获得不同的权限(空白表示值不变)。

 

 

 

before call

ruid

euid

suid

fsuid

setuid( e )

euid != 0 (eruideuidsuid之一)

 

e

 

e

 

euid == 0(注意,这种情况下,进程无法回到特权级,因为suid也变了。)

e

e

e

e

seteuid( e )

euid != 0 (eruideuidsuid之一)

 

e

 

e

 

euid == 0

 

e

 

e

setreuid( r, e )

euid != 0 (rruideuid之一,eruideuidsuid之一)

r

e

e

e

 

euid == 0

r

e

e

e

setresuid( r, e, s )

euid != 0 (re, sruideuidsuid之一)

r

e

s

e

 

euid == 0

r

e

s

e

setfsuid( f )

euid != 0 (fruideuidsuidfsuid之一)

 

 

 

f

 

euid == 0

 

 

 

f

 

 

before call

rgid

egid

sgid

fsgid

setgid( e )

euid != 0 (ergidegidsgid之一)

 

e

 

e

 

euid == 0

e

e

e

e

setegid( e )

euid != 0 (ergidegidsgid之一)

 

e

 

e

 

euid == 0

 

e

 

e

setregid( r, e )

euid != 0 (rrgidegid之一,ergidegidsgid之一)

r

e

e

e

 

euid == 0

r

e

e

e

setresgid( r, e, s )

euid != 0 (re, srgidegidsgid之一)

r

e

s

e

 

euid == 0

r

e

s

e

setfsgid( f )

euid != 0 (frgidegidsgidfsgid之一)

 

 

 

f

 

euid == 0

 

 

 

f



参考文档

http://en.wikipedia.org/wiki/Sticky_bit

http://en.wikipedia.org/wiki/User_id

http://en.wikipedia.org/wiki/File_system_permissions

GNUcoreutils.info

http://blog.sina.com.cn/s/blog_4c23939b0100q4zl.html

http://www.2cto.com/os/201208/147429.html

http://en.wikipedia.org/wiki/Sgid




你可能感兴趣的:(Unix-like系统的文件权限)