linux文件权限笔记

前言

本文描述的权限是指文件或目录的基本权限,不涉及selinux。

权限构成

位域表示

位域111009080706050403020100
权限SGTrwxrwxrwx

- S位代表可执行文件可提升至所有者权限执行。非可执行文件无效。
- G位代表可执行文件可提升至文件所在组权限执行。非可执行文件无效。
- T位代表目录权限粘滞,只有所有者和root可删除。非目录无效。

设置

  • S位

chmod u+s [file/dir]

  • G位

chmod g+s [file/dir]

  • T位

chmod g+s [file/dir]

注意

  • S、G和T位都不可复制,就是说具备S、G或T位的文件的拷贝不会保留对应的S、G或T位。

  • S和G位受所在文件系统挂载方式限制。例如在/dev/shm下面的文件权限不能提升(浪费了笔者不少时间)。

例如

  • S位例子
zyitong@Z228M ~ % ls -l /usr/bin/passwd
-rwsr-xr-x 1 root root 47032  127  2016 /usr/bin/passwd*

passwd需要修改/etc/passwd文件,普通用户对于/etc/passwd是没有权限的。通过passwd则可以修改。

  • G位例子
zyitong@Z228M ~ % ls -l /sbin/unix_chkpwd
-rwxr-sr-x 1 root shadow 35536  317 01:47 /sbin/unix_chkpwd*
  • T位例子
zyitong@Z228M /sbin % ls -lh 
drwxrwxrwt  13 root root 4.0K  84 18:13 tmp/

用户建立该目录之后,只有该用户才有权限删除。即使目录所在组具有rwx权限,组内的用户也是没有权限删除。但子目录的T位需要重新设置。

字段表示

  • 第9位

表示文件类型,可以为p、d、l、s、c、b和-:
p表示命名管道文件
d表示目录文件
l表示符号连接文件
-表示普通文件
s表示socket文件
c表示字符设备文件
b表示块设备文件

  • 第8-6位

分别表示所有者对应的读、写、执行权限,表现形式为rwx。如果对应权限没有,该表示为-。如果存在S位且可执行,则执行权限位为s;如果存在S位且不可执行,则执行权限位为S(表示没有生效);

  • 第5-3位

分别表示同组用户对应的读、写、执行权限,表现形式为rwx。如果对应权限没有,该表示为-。如果存在G位且可执行,则执行权限位为s;如果存在G位且不可执行,则执行权限位为S(表示没有生效);

  • 第2-0位

分别表示其他用户对应的读、写、执行权限,表现形式为rwx。如果对应权限没有,该表示为-。如果存在T位存在且可执行,则执行权限位为t;如果存在粘帖位存在且为不可执行,则执行权限位为T。

例如

% ls -lh /dev/null
crw-rw-rw- 1 root root 1, 3  84 09:02 /dev/null

表示字符设备文件,所有者、文件所在组和其他用户都具有读写权限,都没有执行权限,没有S,G和T位。

附录

C提升权限

  • 源码
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/types.h>

#include "common.h"

static int fileprint(char *path)
{
    int ret = 0;
    long size;

    struct stat status;

    int fd = 0;
    char *fp = NULL;

#if 0
    ret = access(path, R_OK);
    if(ret != 0){
        VERR("%s access failed(%s)!\n", path, strerror(errno));
        return -1;
    }
#endif

    fd = open(path, O_RDONLY);
    if(fd < 0){
        VERR("open %s failed(%s)\n", path, strerror(errno));
        return -1;
    }

    ret = fstat(fd, &status);
    if(ret != 0){
        VERR("%s fstat failed(%s)!\n", path, strerror(errno));
        close(fd);
        return -1;
    }

    VDBG("the size of %s is %ld bytes\n", path, status.st_size);
    fp = mmap(NULL, status.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
    if(fp == MAP_FAILED){
        VERR("mmap failed(%s)!\n", strerror(errno));
    }
    close(fd);

    vdump(fp, status.st_size);

    ret = munmap(fp, status.st_size);
    if(ret != 0){
        VERR("munmap failed(%s)!", strerror(errno));
    }

    return ret;
}

int main(int argc, char *argv[])
{
    int ret;

    ret = getuid();
    VINFO("uid %d\n", ret);

    ret = geteuid();
    VINFO("euid %d\n", ret);

#if 1
    ret = seteuid(0);
    if(ret != 0){
        VERR("setuid failed(%s)!\n", strerror(errno));
        exit(-errno);
    }
#endif

    ret = getuid();
    VINFO("uid %d\n", ret);

    ret = geteuid();
    VINFO("euid %d\n", ret);

    ret = fileprint("root.txt");
    return ret;
}
  • 使用
# root权限下
gcc -c common.c &&\
gcc -c suid.c &&\
gcc -o suid suid.o common.o &&\
chown root:root suid &&\
chmod 4111 suid

在普通用户权限下,可以验证suid能读取只有root权限能读取的文件。也就是说可以提升权限。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值