Unix File Permissions and ACLs in OS X
Update:
2008-12-08: POSIX.
2008-12-08: delete "only_inherit" option in the last example, and the last line of chmod.
added how to force apply ACLs to all children (files/subdirectory).
2008-12-10: added part2 link.
注:本文适合于希望了解ACLs在Mac OS X中的实现、应用和管理,并对文件权限有一定了解的技术人员,如果对UNIX的文件管理和权限有一定了解会帮助对本文的理解,同时最好有一定的Shell经验。
此文尽量把主要篇幅着重于介绍ACLs, 同时兼顾一些传统的Unix文件权限的介绍和他们之间的对比。
part 2 已经完成,请到这里看:
Unix File Permissions & ACLs in OS X(part 2)
或者连接: http://blog.csdn.net/afatgoat/archive/2008/12/11/3494974.aspx
一. Unix文件权限简介:
(对于已经了解的读者完全可以跳过这一部分直接到ACLs的介绍)
这里说的Unix File Permissions, 在英文里一般也叫做POSIX permissions, 说的都是一回事。
传统的Unix文件权限定义了文件的owner,group和读写执行权限。
下图是一个例子:
上图中的意思是:该文件的拥有者是John, 属于组是"staff",拥有者(John)/组(Staff)/others(所有不是前面的用户)都有读写执行权利。
而上图中的解释是:该文件的拥有者是John, 组是"staff",拥有者(John)有读写权利,组(Staff)成员有只读权利,others(所有不是前面的用户)都没有任何访问权限。
权限的每一位对应一个二进制位,如上图,这样权限的定义就可以表达为16进制的640了。
当你使用Shell命令的ls显示文件的时候,它可以告诉你文件的权限设置, 记住要使用-l选项。
- $ls-l
- total0
- drwxrwxrwt9rootwheel306Dec511:54Shared
- drwxr--r--+21adminadmin714Dec515:37admin
- drwx------+12studentadmin408Nov1422:11student
- drwxr-xr-x+3rootadmin102Dec114:45test
同时,在OS X中用户可以通过Get Info来察看文件的权限设置,见下图中的Ownership&Permissions部分. 但是GetInfo的功能的局限,好多设置功能必须要用shell命令来完成, 比如设置可执行文件的权限。
对于unix的传统permissions来说,有很多局限,比如:你希望用户bob对你的一个文件可读,而不希望bob所属的组的其它人有访问权限,同时你的组要有只读权限,这样就比较麻烦,如果你把bob加入到你的组,那么很有可能bob获得了读取你其它文件的权利,你也不希望把bob的组设置成给文件的组,那样bob组的其它成员就有了对本文件的读取权利。一个有可能的实现方法是,创建一个新组,其中包括了自己所在组的所有成员和bob,然后设定你的文件属于这个新组。但是问题是,这样会把你的组变得越来越复杂,以至于过一段时间你就无法维护那些组了。原因是什么?因为一个文件只可能设定对一个组的对应。还有一点就是权限继承,你无法让系统默认一个目录里面的文件一致地继承目录指定的权限,因为Unix里面没有多种继承关系的定义。还有,它没有定义删除delete权限,而有写write权限的同时就有了delete权限。
二:ACLs的介绍:
ACLs是Access Control Lists的缩写, 其实ACLs就是提供了一种稍微复杂但是更多选择的控制文件权限的方法。
Mac OS X 中是在OS X 10.4中开始引入ACL技术的。在Windows 系统中我记得是在Windows 2000中引入的。
从技术角度说, ACLs是添加到文件系统上的权限管理的列表. 列表可以是空,从而默认的Unix权限起作用. ACLs中可以包括一个或者多个ACEs(Access Control Entries),每个ACEs包括下面的信息:
. actor: 此项适用的用户/用户组
. Allow/Deny: 操作是准许还是禁止
. actions:都有那些权限是准许的或者禁止的
. inherit: 这个ACE将如何被它的子文件继承
可以定义的权限(actions)
1. 对于所有文件/目录适用的权限:
. delete:删除
. writeattr: (basic attributes)
. readextattr: (extended attributes)
. readsecurity: (ACLs)
. writesecurity: (ownership, mode, ACL)
. chown: 变更ownership
2. 只适合于目录的权限:
. list: 罗列内容
. search: 适用文件名称查找.
. add_file:
. add_subdirectory:
. delete_child:
只适合于普通文件的:
. read:
. write:
. append:
. excute:
而继承规则的定义:
. file_inherit: 继承给文件,而只有新文件自动继承.
. directory_inherit: 继承给目录,而只有新子目录自动继承.
. limit_inherit: 这个规则只适用于目录,它阻止进一步的继承到孙子文件/目录.
. only_inherit:只是继承到子文件/目录,而不应用到当前的目录.
对于继承上只有在文件/目录生成的时候,它的父目录的ACLs才被一次性地继承,如果后来父目录的ACLs的改变不会自动地应用到以前生成的文件/目录上,所以他们的继承是静态(statistic)的,而父目录的ACLs的改变同时影响到已经存在的文件的方式,叫做动态(Dynamic)的。一些人认为OS X选择了这个方式继承是正确的选择,而另外的人认为如果能实现动态和静态的选择更好,相比叫Windows选择的是动态的继承。
虽然是静态的继承,对于一个ACLs中的每个ACEs,只有非继承的ACEs才可以被在此对象上修改,而继承的不可以,要修改,需要到初始定义的ACLs中修改,或者把继承标记删除然后修改。
下图是OS X 10.4 Server中的Workgroup Manager里面列出来的选项。
OS X如何处理ACLs:
. 每个ACEs都是从上到下地处理,最先满足条件的ACE被应用.
. 当所有的ACLs处理完后,POSIX才被处理.
. 当遇到一个deny满足条件时, 处理将停止并将deny作为结果条件.
在定义和设计实施ACLs的建议:
ACLs很复杂,其中有13个权限和12种继承关系可以定义,总共有大约2^13 * 12 = 98,304种情况.
1. 只有当传统的POSIX无法处理的情况再使用ACLs.
2. 使用尽可能少的用户组.
3. 尽量避免对某一个用户建议ACE.
4. 如果希望保护文件,那么使用POSIX权限禁止绝大多数访问,然后使用ACEs来添加被准许的用户组
5. 尽量使用继承关系,这样目录的结构的建立和维护就成为关键.
6. 尽量不要使用deny,因为它很容易造成影响.
7. 不要对OS X的系统对象尝试使用ACLs.
在Finder中你没有完全的自由来修改ACLs.
文件系统相关的考虑:
OS X只支持这些文件系统上的ACLs:
. 磁盘的卷并使用至少是Mac OS Extended File System (HFS+),可以是journaled。
. 通过AFP(Apple Filng Protocol)访问的网络卷(Volumes)
. 通过SMB/CIFS访问的网络卷
对于其它的如: UFS, FAT, VFAT, FAT32和NTFS磁盘卷,或者通过NFS, FTP, or WebDAV协议访问的网络卷
打开和关闭ACLs支持:
因为ACLs耗费磁盘空间,并且降低文件访问速度-当然在当今的高速时代这些可以忽略不计-所以在你的环境中要决定是否使用ACLs(在OS X 10.4中是默认禁止的),然而在OS X Server 10.4或更高版本和OS X 10.5中是默认打开的,而且必须一直保持打开. 如果关闭以前打开的ACls,那么原来的ACLs只是看不见也不起作用,没有丢失,打开后原来的还存在。
如何打开这个功能或者察看卷的状态呢?首先进入Terminal,
察看所有卷的状态输入:fsaclctl -a
- ash-3.2#fsaclctl-a
- ProcessVolume:processing/
- Accesscontrollistsaresupportedon/.
- ProcessVolume:processing/Volumes/Data
- Accesscontrollistsaresupportedon/Volumes/Data.
对于特定卷打开|禁止ACLs功能:
fsaclctl -p path -e| -d
其中-e是打开,-d是禁止.
而path就是该卷的目录比如/Volumes/Macintosh/ HD
例子:
fsaclctl -p / -e
fsaclctl -p /Volumes/Data -d
如何察看一个文件的ACLs纪录呢?
当你使用ls -l察看的时候,如果这个文件/目录应用了ACLs那么它的权限部分的最后有一个+号,然后再用ls命令-e 选项就可以了看到了. 比如:
$ ls -l
total 8
drwxr-xr-x 14 schooladmin wheel 476 Nov 3 21:41 Admin Utilities
-rw-rw-r-- 1 schooladmin wheel 1648 Oct 17 2006 Bookmarks.org.plist
drwxrwxrwx@ 2 schooladmin wheel 68 Nov 18 11:44 SC Info
drwxr-xr-x+ 2 schooladmin staff 68 Dec 3 21:21 SandBox
ls -le
total 8
drwxr-xr-x 14 schooladmin wheel 476 Nov 3 21:41 Admin Utilities
-rw-rw-r-- 1 schooladmin wheel 1648 Oct 17 2006 Bookmarks.org.plist
drwxrwxrwx@ 2 schooladmin wheel 68 Nov 18 11:44 SC Info
drwxr-xr-x+ 2 schooladmin staff 68 Dec 3 21:21 SandBox
0: group:everyone allow list,add_file,search,delete,add_subdirectory,delete_child,chown,file_inherit,directory_inherit
1: group:everyone allow list,add_file,search,delete,add_subdirectory,delete_child,chown,file_inherit,directory_inherit
看到了吧,其中冒号前面的数字0,1...就是每个ACE在ACLs中的顺序号。
下面介绍ACLs操作命令:
添加一个ACE到指定的文件/目录
chmod +a "permission list" object
它是把当前指定的权限加入到ACLs的最前面。
chomod +a# ? "permission list" object
把此纪录添加到指定的顺序号上,其中?就是那个序号
chmod -a "record" object
把指定"record"从给定目标的ACLs中的所有记录中删除。
chmod -a# ? object
把指定序号?的纪录从给定目标的ACLs中删除。
chmod =a# ? "record" object
为目标的ACLs替换指定位置的纪录为当前指定的
还有两个选项比较有用
chmod -i object
把给定目标的ACLs记录中的inherited标记删除,这样这些原来继承下来的ACLs记录,就变成了自己的ACLs记录了。
chmod -I object
对于给定的目标的ACLs中的标记为"inherited"的记录,全部删除。
这两个选项就是大小写的区别,可是用途大相径庭呀。
chmod -N object
这个最霸道,删除所有的ACLs记录
如何把当前的ACLs记录都应用到当前目录的子目录和文件上呢?
很简单了,原来处理POSIX权限的参数还是起作用的,那就是选项:-R.
使用举例:
举一个例子,用户希望在本地建立一个目录,所有的用户都有对其内的文件目录进行创建/读写/删除的权利,相当于一个sandbox. 选择的目录位置可以是在所有用户的Share目录里面,建立一个Sandbox子目录:
sudo mkdir /Users/Shared/SandBox
sudo chown root:wheel /Users/Shared/SandBox
sudo chmod 755 /Users/Shared/SandBox
chmod +a "everyone allow list,add_file,search,delete,add_subdirectory,delete_child,chown,file_inherit,directory_inherit,only_inherit" SandBox/
chmod +a "everyone allow list,add_file,search,add_subdirectory,delete_child" SandBox
最后大家在使用ACLs的时候,也要注意,不是所有的Mac应用程序都对ACLs敏感,有的旧程序根本就不会理睬ACLs, 而是只使用POSIX权限处理文件,这种情况下,升级旧版本是一个值得首先尝试的选择。
其它:
一个有用的软件叫TinkerTool System, 在里面你可以编辑某个文件目录的ACLs,最有用的是它可以告诉你对于一个用户,最终起作用的ACLs结果是什么。可惜它是付费的,可以到这里找到:http://www.bresink.com/osx/TinkerToolSys.html
对于传统的Unix权限的存储是在metadata里面,而对于OS X的ACLs是存储在文件系统的extended attributes里面。
Ref:
http://www.bresink.com/osx/193281/Docs-en/ACL.html
http://aplawrence.com/MacOSX/acl.html