Linux 入门记录:十三、Linux 扩展权限
一、默认权限
每一个终端都有一个 umask 属性,是用来确定新建文件或目录的默认权限的“掩码”(mask 有“掩码”的含义,至于 u,后面说)。
Linux 中一般有默认的权限掩码,使用命令 umask 用以查看或设置:
umask 查看默认掩码 umask 0022 设置默认掩码
一般地,普通用户(uid 为 500 以上)的权限掩码默认为 0002,root 用户(uid 为 0)的权限掩码默认为 0022。
如果新建了一个文件或目录,那么这个文件或目录的默认权限等于 文件或目录的默认最高权限 & (~ umask) 。
那么,“文件或目录的默认最高权限”是多少呢?一般来说,目录的默认最高权限是 0777,文件的默认最高权限为 0666(去掉了 x 权限,禁止执行,安全考虑)。注意:Linux 的权限值是八进制的!所以,网上的某些所谓十进制减法运算来计算新建文件或目录默认权限的逻辑是错误的。还有什么分情况讨论的,在我看来实在麻烦。用计算机思维来理解计算机,这是我认为最合理、最准确且最简单的思维方式。
怎么记忆和理解这个运算逻辑?
umask,我把它的中文全称记为用于“位取反的权限掩码”。“位取反” 来自 "u",“掩码” 来自 "mask" 。拿这个位取反的权限掩码(~ umask)跟默认最高权限相与 "&",就得到了新建文件(或目录)的默认权限。
怎么理解?
这里主要是“掩码”:掩码是用来和目标数进行位与 "&" 运算,取得目标数里跟掩码的位均为 1 的位组合,并将跟掩码中位为 0 的对应位全部丢弃。掩码的原理是的原理,任何数和 1 相与都是它本身,任何数和 0 相与都是 0。而一个数跟掩码的反码(位取反)进行位与 "&" 运算,得到结果恰恰相反,结果是保留这个数里跟掩码里位为 0 相对应的位,丢弃跟掩码里位为1 相对应的位。
这里的 umask 就是这个作用,用默认最高权限跟取反的 umask 相与,就从默认最高权限里丢弃了 umask 不允许的权限。所以并不是简单的十进制减法运算,例如 umask 值为 0022 和 0033 的时候,普通用户新建文件的默认权限都是 0644(因为 0666 & (~ 0022) 和 0666 & (~ 0033) 的运算结果是一样的),用 rwx 符号表示就是 -rw-r--r-- 。
二、特殊权限
除了普通权限外,还有三个特殊权限:
权限 | 对文件的影响 | 对目录的影响 |
suid |
以文件的所属用户身份执行, 而非执行文件的用户 |
无 |
sgid |
以文件所属组身份执行 |
在该目录中创建的任意新文件的 所属组与该目录的所属组相同, 即子文件自动继承该目录的所属组 |
sticky | 无 |
对目录拥有写入权限的用户仅可以 删除其拥有的文件,无法删除其他 用户所拥有的文件 |
拥有suid权限的passwd命令
Linux 中普通用户的密码口令都保存在 /etc/shadow 文件里,这个文件的权限是只有root用户和root组才可以访问的。那么普通用户是怎么修改自己密码的呢?Linux 提供了 passwd 命令,普通用户使用这个命令来修改自己的密码:
我们看到,这个 passwd 命令的 U 模型里有个 "s" 占用了原来的 "x" 权限,这表示执行该命令的用户拥有 "suid" 权限,以 root 用户身份来运行,所以普通用户可以通过执行 passwd 命令来修改自己的密码,并将它写到 /etc/shadow 文件里。
三、设置特殊权限
设置 suid:
chmod u+s filename
设置 sgid:
chmod g+s filename
设置 sticky:
chmod o+t filename
其中,设置 sgid 权限会使 "s" 替换 G 模型的 "x" 权限,例如:"-rwxr-s---";设置 sticky 权限会使 "t" 替换 O 模型的 "x" 权限,例如:"drwxr-xr-t"。这里我所说的 G 模型、O 模型是 Linux 权限所采用的 UGO 模型。
一般来说,我们使用 sgid 来设置目录的权限,它允许了目录的子文件(或目录)自动继承该目录的所属组,常见的情况例如市场部目录的员工目录自动属于市场部用户组。经常使用 sticky 来设置目录下的用户可以删除自己的文件,但不能删除别人的文件,例如营销部目录的员工文件可以被员工删除,但不能删除同事的文件。
与普通权限一样,特殊权限也可以用八进制数值表示:
suid = 4 (2 ^ 2) sgid = 2 (2 ^ 1) sticky = 1 (2 ^ 0)
所以,我们也可以通过以下命令设置:
chmod 4755 filename 普通权限755,所属用户可读可写可执行,所属组和其他用户不可写,特殊权限允许以所属用户身份执行