当前位置: 首页 > news >正文

linux ACL权限控制之组权限控制程序设计

在linux ACL权限控制之用户权限控制程序设计-CSDN博客中建立了两个用户vox和zoe,两个用户组vox和zoe:

切换到vox,新建一个文件testfile并查看其权限:

将testfile所属的组变为zoe,并将组权限从rw降为r:

使用setfacl设置用户zoe的rwx权限:

上面的红框似乎表明文件所属组zoe具备了rwx权限,现在创建新用户spy并加入组zoe:

useradd spy
gpasswd -a spy zoe

切换到spy,使用vim打开testfile:

spy只拥有对testfile的只读权限!ls -l testfile的输出似乎不太可信,用getfacl看一看:

原来group仍然是r权限,多了一个mask且值为rwx,显示在如下红框的位置:

如果强行使用chmod命令将组zoe的权限改为rw呢?结果如下:

1和4表明mask的值变成了rw,2表明group的权限仍为r,使用chmod只能改变mask的值,并不能改变group的值,3表明user zoe的实际有效值为rw而不是rwx。

那么acl中的mask究竟是个啥?

在linux的访问控制列表(ACL)中,mask的作用是限制用户和组的最大有效权限。它作为一个过滤器,确保所有通过ACL设置的用户和组权限都不会超过mask所定义的权限范围。如果某个用户的ACL条目权限超过了mask的限制,那么该用户的实际有效权限将被mask所限制。

简单来说,mask决定了setfacl对user和group设定权限的上限,比如意思mask的值rw,即使zoe被设置成了rwx,最后也只有rw的权限。

现在,编程实现使用acl给group增加权限及改变mask值得功能。

假设有如下文件:

编程实现给group zoe增加rwx的权限,代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <sys/acl.h>

int main() {
    const char *filename = "/home/vox/testfile";
    uid_t group_id = 1002;

    // 获取文件的ACL
    acl_t acl = acl_get_file(filename, ACL_TYPE_ACCESS);
    if (acl == NULL) {
        perror("Failed to get ACL");
        return EXIT_FAILURE;
    }

    // 创建新ACL条目
    acl_entry_t entry;
    if (acl_create_entry(&acl, &entry) == -1) {
        perror("Failed to create ACL entry");
        acl_free(acl);
        return EXIT_FAILURE;
    }

    // 设置条目类型为组
    if (acl_set_tag_type(entry, ACL_GROUP) == -1) {
        perror("Failed to set tag type");
        acl_free(acl);
        return EXIT_FAILURE;
    }

    // 设置组ID为限定符
    if (acl_set_qualifier(entry, &group_id) == -1) {
        perror("Failed to set qualifier");
        acl_free(acl);
        return EXIT_FAILURE;
    }

    // 设置权限(读)
    acl_permset_t permset;
    if (acl_get_permset(entry, &permset) == -1) {
        perror("acl_get_permset failed");
        acl_free(acl);
        return EXIT_FAILURE;
    }
    acl_clear_perms(permset);                  // 清空权限
    acl_add_perm(permset, ACL_READ | ACL_WRITE | ACL_EXECUTE);  // 添加读写执行权限
    if (acl_set_permset(entry, permset) == -1) {
        perror("acl_set_permset failed");
        acl_free(acl);
        return EXIT_FAILURE;
    }

    // 自动计算MASK条目(关键修复)
    if (acl_calc_mask(&acl) == -1) {
        perror("Failed to calculate mask");
        acl_free(acl);
        return EXIT_FAILURE;
    }

    // 验证ACL
    if (acl_valid(acl) == -1) {
        perror("Invalid ACL");
        acl_free(acl);
        return EXIT_FAILURE;
    }

    // 应用ACL到文件
    if (acl_set_file(filename, ACL_TYPE_ACCESS, acl) == -1) {
        perror("Failed to apply ACL");
        acl_free(acl);
        return EXIT_FAILURE;
    }

    // 释放资源
    acl_free(acl);
    return 0;
}

使用如下命令编译:

g++ main.cpp -lacl

sudo执行可执行文件后,使用getfacl查看testfile的权限:

zoe获得了rwx的权限,mask的值为rwx。

改变mask的值为r,代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <sys/acl.h>

int main() {
    const char *filename = "/home/vox/testfile";
    uid_t group_id = 1002;

    // 1. 获取文件的ACL(假设文件已有基础ACL)
    acl_t acl = acl_get_file(filename, ACL_TYPE_ACCESS);
    if (acl == NULL) {
        perror("acl_get_file failed");
        return EXIT_FAILURE;
    }

    // 2. 添加扩展条目(ACL_USER)
    acl_entry_t group_entry;
    if (acl_create_entry(&acl, &group_entry) == -1) {
        perror("acl_create_entry failed");
        acl_free(acl);
        return EXIT_FAILURE;
    }
    if (acl_set_tag_type(group_entry, ACL_GROUP) == -1 ||
        acl_set_qualifier(group_entry, &group_id) == -1) {
        perror("Failed to set group entry");
        acl_free(acl);
        return EXIT_FAILURE;
    }

    // 设置组权限为 rwx
    acl_permset_t group_perms;
    acl_get_permset(group_entry, &group_perms);
    acl_clear_perms(group_perms);
    acl_add_perm(group_perms, ACL_READ | ACL_WRITE | ACL_EXECUTE);
    acl_set_permset(group_entry, group_perms);

    // 3. 手动创建并设置 MASK 条目
    acl_entry_t mask_entry;
    if (acl_create_entry(&acl, &mask_entry) == -1) {
        perror("acl_create_entry for mask failed");
        acl_free(acl);
        return EXIT_FAILURE;
    }
    if (acl_set_tag_type(mask_entry, ACL_MASK) == -1) {
        perror("acl_set_tag_type for mask failed");
        acl_free(acl);
        return EXIT_FAILURE;
    }

    // 设置 MASK 权限为 r--(限制最大权限)
    acl_permset_t mask_perms;
    acl_get_permset(mask_entry, &mask_perms);
    acl_clear_perms(mask_perms);
    acl_add_perm(mask_perms, ACL_READ);
    acl_set_permset(mask_entry, mask_perms);

    // 4. 验证并应用ACL
    if (acl_valid(acl) == -1) {
        perror("Invalid ACL");
        acl_free(acl);
        return EXIT_FAILURE;
    }
    if (acl_set_file(filename, ACL_TYPE_ACCESS, acl) == -1) {
        perror("acl_set_file failed");
        acl_free(acl);
        return EXIT_FAILURE;
    }

    acl_free(acl);
    return 0;
}

编译执行,使用getfacl查看testfile的权限:

相关文章:

  • 卡特兰数问题
  • 端侧设备(如路由器、家庭网关、边缘计算盒子、工业网关等)的典型系统、硬件配置和内存大小
  • 【矩阵快速幂】P2100 凌乱的地下室|省选-
  • AI+基础工具:解锁业务增长原子级能力,To B 落地新方向
  • 红宝书第十九讲:详解JavaScript的Fetch API与Ajax请求
  • 利用虚拟化技术实现高级Hook
  • Success is the sum of small efforts repeated day in and day out.
  • 1.Python 计算机二级题库:选择题
  • 【大模型】视觉语言模型:Qwen2.5-VL的使用
  • 分布式ID生成器:雪花算法原理与应用解析
  • 航拍数据集汇总,覆盖车辆/船舶检测/物体评估/城市景观……
  • 了解图像质量评价指标PSNR
  • JAVA实现动态IP黑名单过滤
  • 基于聚类与引力斥力优化的选址算法
  • 71. 我的第一个Linux驱动实验
  • 树莓派超全系列文档--(11)RaspberryOS上使用 Python控制GPIO
  • 鸿蒙项目源码-购物商城v2.0-原创!原创!原创!
  • 【Java】JVM
  • 优化MyBatis-Plus批量插入策略
  • 第十二章:补充介绍pip与配置及Python结构层次
  • 深圳建设工程网/北京seo服务行者
  • 山西本土网站建设/app推广地推接单网
  • 佛山最好的网站建设公司/信息流优化师工作总结
  • 宁波网站建设风格/seo的优化方案
  • web技术网站开发/武汉seo公司
  • 百度建立企业网站建设的目的/网络推广合作资源平台