Unix-like 系统的文件权限(转载)

Reading time ~1 minute

网上关于uid这一块的东西多是多,只是大多都太乱了,今天偶然发现一个感觉很好的,mark一下~~~

1 名词解


</tbody> </table>

 

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

2 文件权限基础

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

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

 

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

 

uid(user id)

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

gid(group id)

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

ruid(real user id)

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

rgid(real group id)

一个进程的真实gid

euid(effective user id)

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

egid(effective group id)

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

suid(saved user id)

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

sgid(saved group id)

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

fsuid(file system user id)

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

fsgid(file system group id)

原理同上,赋值只能是rgid、egid、sgid之一。

文件

文件夹

读r

读文件

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

写w

写文件

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

执行x

执行文件(run it as a program)

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

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

 

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

 

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

 

文件

文件夹

SUID(setuid bit)

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

SGID(setgid bit)

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

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

sticky bit

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

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

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

 

2.4 某些文件系统相关属性

 

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

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

 

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

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

3.1 相关命令

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

修改文件拥有者:chown

修改文件所属组:chgrp

修改文件属性:chmod

设置忽略掩码:umask

 

3.2 chmod命令

 

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

  1. ---------- 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系统中,文件夹也是文件的一种,所以对于文件夹也可以设置权限。例如:

  1. 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权限,仍然可以删除它!!!)。

 

下面列举几个常用命令:

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

       

设置SUID位

  1. 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标志。

  1. -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位

  1. 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位,表示在此文件夹中创建的文件,组都是和文件夹相同。

  1. 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

  1. chmod +t  a.out

       

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

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

 

before call

ruid

euid

suid

fsuid

setuid( e )

euid != 0 (e是ruid、euid、suid之一)

e

e

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

e

e

e

e

seteuid( e )

euid != 0 (e是ruid、euid、suid之一)

e

e

euid == 0

e

e

setreuid( r, e )

euid != 0 (r是ruid、euid之一,e是ruid、euid、suid之一)

r

e

e

e

euid == 0

r

e

e

e

setresuid( r, e, s )

euid != 0 (r,e, s是ruid、euid、suid之一)

r

e

s

e

euid == 0

r

e

s

e

setfsuid( f )

euid != 0 (f是ruid、euid、suid、fsuid之一)

f

euid == 0

f

 

before call

rgid

egid

sgid

fsgid

setgid( e )

euid != 0 (e是rgid、egid、sgid之一)

e

e

euid == 0

e

e

e

e

setegid( e )

euid != 0 (e是rgid、egid、sgid之一)

e

e

euid == 0

e

e

setregid( r, e )

euid != 0 (r是rgid、egid之一,e是rgid、egid、sgid之一)

r

e

e

e

euid == 0

r

e

e

e

setresgid( r, e, s )

euid != 0 (r,e, s是rgid、egid、sgid之一)

r

e

s

e

euid == 0

r

e

s

e

setfsgid( f )

euid != 0 (f是rgid、egid、sgid、fsgid之一)

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

原文链接:http://blog.csdn.net/gogdizzy/article/details/8447204

挂载网络文件夹后网络故障时文件操作命令卡死

挂载 NFS 或者 Samba 的时候,经常会由于网络故障导致挂载好的链接断掉。此时如果尝试进行 ls、cd、df 等各种命令,只要与此目录沾上边,就会卡住。如果使用了类似 oh-my-zsh 这种配置的,只要在网络目录中,弹出命令提示符前就会直接卡住。这个时候第一反应就是...… Continue reading

路由折腾记 第四弹

Published on September 02, 2017