嵌入式Linux系统编程 — 3.3 chown、fchown 和 lchown 函数更改文件属主

news2025/1/6 16:07:32

目录

1 文件属主

1.1 文件属主概念

1.2 如何查看文件属主 

1.3 有效用户 ID 和有效组 ID

2 chown 函数

2.1 chown命令

2.2 chown函数

2.3 getuid 和 getgid函数 

3 fchown函数

3.1 fchown函数简介

3.2 示例代码

4 lchown函数 


1 文件属主

1.1 文件属主概念

Linux 是一个支持多用户操作的系统,它允许多个用户在同一台机器上工作,而每个文件都与特定的用户和用户组相关联,通过这个信息可以判断文件的所有者和所属组。

文件所有者指的是文件的拥有者,即文件属于哪个用户。通常,文件在创建时,其所有者就是创建它的用户。例如,如果当前登录用户为 ***,通过 touch 命令创建了文件,那么文件的所有者就是 ***。同样,当程序通过 open 函数创建新文件时,文件的所有者将是执行该程序的用户。

文件所属组则指明了文件属于哪个用户组。Linux 系统通过用户 ID(UID)和组 ID(GID)来识别用户和用户组,而不是通过用户名或组名。每个用户和用户组都被分配了一个唯一的 ID,系统通过这些 ID 来管理权限和访问控制。

用户 ID 简称 UID、用户组 ID 简称 GID, 这些都是 Linux 操作系统的基础知识,

1.2 如何查看文件属主 

可以使用 ls 命令或 stat 命令便可以查看到文件的所有者和所属组,如下所示:


文件的用户 ID 和组 ID 分别由 struct stat 结构体中的 st_uid 和 st_gid 所指定。 既然 Linux 下的每一个文件都有与之相关联的用户 ID 和组 ID,那么对于一个进程来说亦是如此,与一个进程相关联的 ID 有很多:

  • 实际用户 ID 和实际组 ID 标识该进程的用户是谁、以及该用户对应的所属组; 实际用户 ID 和实际组 ID 确定了进程所属的用户和组。
  • 进程的有效用户 ID、有效组 ID 以及附属组 ID 用于文件访问权限检查。

1.3 有效用户 ID 和有效组 ID

首先对于有效用户 ID 和有效组 ID 来说,这是进程里面的概念,文件来并无此属性!有效用户 ID 和有效组 ID 是操作系统层面,用于给操作系统判断当前执行该进程的用户在当前环境下对某个文件是否拥有相应的权限。

在 Linux 系统中,当进程对文件进行读写操作时,系统首先会判断该进程是否具有对该文件的读写权限,那如何判断呢?自然是通过该文件的权限位来判断, struct stat 结构体中的 st_mode 字段中就记录了该文件的权限位以及文件类型。

当进行权限检查时,并不是通过进程的实际用户和实际组来参与权限检查的,而是通过有效用户和有效组来参与文件权限检查。 通常, 绝大部分情况下,进程的有效用户等于实际用户(有效用户 ID 等于实际用户 ID) ,有效组等于实际组(有效组 ID 等于实际组 ID) 。

 

2 chown 函数

2.1 chown命令

chown 是一个系统调用,该系统调用可用于改变文件的所有者(用户 ID)和所属组(组 ID) 。其实在Linux 系统下也有一个 chown 命令,该命令的作用也是用于改变文件的所有者和所属组,例如将文件的所有者和所属组修改为 root:

通过chown 该命令确实可以改变文件的所有者和所属组,这个命令内部其实就是调用了chown 函
数来实现功能的, chown 函数原理如下所示。

2.2 chown函数

chown 函数在编程中使用的一个系统调用,用于改变文件或目录的用户和组所有权,chown 函数的原型如下:

#include <sys/types.h>
#include <unistd.h>

int chown(const char *path, uid_t owner, gid_t group);
  • path: 要改变所有权的文件或目录的路径。
  • owner: 新的所有者的用户 ID (UID)。
  • group: 新的组的组 ID (GID)。

虽然该函数用法很简单,但是有以下两个限制条件:

  • 只有超级用户进程能更改文件的用户 ID;
  • 普通用户进程可以将文件的组 ID 修改为其所从属的任意附属组 ID,前提条件是该进程的有效用户 ID 等于文件的用户 ID;而超级用户进程可以将文件的组 ID 修改为任意值。

所以,由此可知,文件的用户 ID 和组 ID 并不是随随便便就可以更改的,其实这种设计是为系统安全着想,如果系统中的任何普通用户进程都可以随便更改系统文件的用户 ID 和组 ID,那么也就意味着任何普通用户对系统文件都有任意权限了,这对于操作系统来说将是非常不安全的。

下面是一个简单的 C 语言示例程序,演示如何使用 chown 函数来改变文件的所有者和组。这个示例程序尝试将指定文件的所有者和组更改为特定的用户 ID 和组 ID。

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>

int main(int argc, char *argv[]) {
    // 检查命令行参数数量
    if (argc != 4) {
        fprintf(stderr, "Usage: %s <file> <owner> <group>\n", argv[0]);
        return 1;
    }

    const char *file = argv[1]; // 文件路径
    uid_t owner = atoi(argv[2]); // 新的所有者用户 ID
    gid_t group = atoi(argv[3]); // 新的组 ID

    // 使用 chown 函数改变文件的所有者和组
    if (chown(file, owner, group) == -1) {
        // 如果 chown 失败,打印错误消息
        perror("chown failed");
        return 1;
    }

    printf("Ownership of '%s' changed to owner %d, group %d\n", file, owner, group);
    return 0;
}

程序接收三个命令行参数:要改变所有权的文件的路径,新的所有者的用户 ID,以及新的组 ID。使用 atoi 函数将用户和组 ID 的字符串转换为整数。使用 chown 函数尝试改变文件的所有权。如果 chown 函数调用失败,perror 函数将打印错误消息,程序返回 1。如果成功,程序将打印一条消息,表明所有权已更改。运行结果如下:

2.3 getuid 和 getgid函数 

在 Linux 系统下,可以使用 getuid 和 getgid 两个系统调用分别用于获取当前进程的用户 ID 和用户组ID,这里说的进程的用户 ID 和用户组 ID 指的就是进程的实际用户 ID 和实际组 ID,这两个系统调用函数原型如下所示:

#include <unistd.h> 

uid_t getuid(void);
  • 返回值:返回当前进程的实际用户 ID。如果发生错误,返回 -1 并设置 errno
#include <unistd.h> gid_t getgid(void);
  • 返回值:返回当前进程的实际组 ID。如果发生错误,返回 -1 并设置 errno

下面是一个简单的示例,展示如何使用 getuidgetgid 函数:

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>

int main() {
    uid_t my_uid = getuid();
    gid_t my_gid = getgid();

    printf("Current User ID: %d\n", my_uid);
    printf("Current Group ID: %d\n", my_gid);

    return 0;
}

 程序运行结果如下:

 

3 fchown函数

3.1 fchown函数简介

fchown 用于改变一个打开文件描述符的所有权。这个函数允许你更改文件的用户 ID (owner) 和组 ID (group),而不需要知道文件的路径名。fchown 函数的原型如下:

#include <unistd.h>

int fchown(int fd, uid_t owner, gid_t group);
  • fd: 要改变所有权的文件的文件描述符。
  • owner: 新的所有者的用户 ID (UID)。
  • group: 新的组的组 ID (GID)。

3.2 示例代码

下面是一个使用 fchown 函数的示例程序:

#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>

int main() {
    int fd = open("example.txt", O_RDONLY); // 打开文件以读取模式
    if (fd == -1) {
        perror("open");
        return 1;
    }

    uid_t new_uid = 1000; // 新用户 ID
    gid_t new_gid = 1000; // 新组 ID

    if (fchown(fd, new_uid, new_gid) == -1) {
        perror("fchown");
        close(fd);
        return 1;
    }

    printf("Changed ownership of file descriptor %d to owner %d, group %d\n", fd, new_uid, new_gid);
    close(fd); // 关闭文件描述符
    return 0;
}

程序首先打开一个名为 "example.txt" 的文件,然后尝试使用 fchown 函数改变该文件的所有权。运行结果如下: 

4 lchown函数 

lchown 函数用于改变一个符号链接的所有者和组。与 chown 不同,lchown 专门用于符号链接,即使符号链接指向的目标文件的所有权被更改,lchown 也会更改符号链接本身的所有者和组。lchown 函数的原型如下:

#include <unistd.h>

int lchown(const char *path, uid_t owner, gid_t group);
  • path: 符号链接的路径。
  • owner: 新的所有者的用户 ID (UID)。
  • group: 新的组的组 ID (GID)。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1803930.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

“中新美”三重身份,能帮SHEIN解决上市问题吗?

一家公司的海外上市之路能有多复杂&#xff1f;辗转多地的SHEIN&#xff0c;可能是当前最有话语权回答这个问题的公司。最近&#xff0c;它又有了新消息。 在上市信息多次更改后&#xff0c;伦敦正在成为SHEIN最有可能的“着陆”点。巴伦周刊援引英国天空新闻报道称&#xff0…

可以抛弃纸质礼金簿了,以后登记礼金可以用这款小程序

可以抛弃纸质礼金簿了&#xff0c;以后登记礼金可以用这款小程序 小程序介绍使用主要技术代码来源项目演示首页和我的关于和设置收礼功能送礼功能我的家庭和数据统计 总结 大家好&#xff0c;这里是程序猿代码之路&#xff0c;先说说为什么想搞这一个小程序呢&#xff0c;主要是…

Unity 编辑器扩展 一键替换指定物体下的所有材质球

先看效果 实现方案 1&#xff1a;创建几个用于测试的Cube 2&#xff1a;创建一个脚本 3:编写脚本内容 主要是这部分的逻辑 附上完整代码 using System.Collections; using System.Collections.Generic; using UnityEditor; using UnityEngine;public class Tool {[MenuItem(…

计算机基础(8)——音频数字化(模电与数电)

&#x1f497;计算机基础系列文章&#x1f497; &#x1f449;&#x1f340;计算机基础&#xff08;1&#xff09;——计算机的发展史&#x1f340;&#x1f449;&#x1f340;计算机基础&#xff08;2&#xff09;——冯诺依曼体系结构&#x1f340;&#x1f449;&#x1f34…

vscode输出控制台中文显示乱码最有效解决办法

当VSCode的输出控制台中文显示乱码时&#xff0c;一个有效的解决办法是通过设置环境变量来确保编码的正确性。以下是解决方式&#xff1a; 首先&#xff0c;设置环境变量以修正乱码问题&#xff1a; 如果上述方法没有解决乱码问题&#xff0c;请继续以下步骤&#xff1a; 右键…

JSON 格式说明

文章目录 一、关于 JSON二、JSON 常见格式1、对象2、数组3、值4、字符串5、数值6、空白 三、各语言对 Json 的支持 官网&#xff1a;https://www.json.org/json-en.html (本文翻译自此) 一、关于 JSON JSON&#xff08;JavaScript Object Notation&#xff09;是一种轻量级的数…

【CS.CN】深入探讨下HTTP的Connection头:通过keep-alive实现高效网络连接

文章目录 0 序言0.1 由来0.2 使用场景0.3 现在还需要吗&#xff1f; 1 Connection: keep-alive的机制2 语法 && 通过设置Connection: keep-alive优化性能3 验证与性能提升4 总结References 0 序言 0.1 由来 Connection头部字段在HTTP/1.1中被引入&#xff0c;主要用于…

Linux安装RocketMQ教程【带图文命令巨详细】

巨详细Linux安装Nacos教程RocketMQ教程 1、检查残留版本2、上传压缩包至服务器2.1压缩包获取2.2创建相关目录 3、安装RocketMQ4、配置RocketMQ4.1修改runserver.sh和runbroker.sh启动脚本4.2新增broker.conf配置信息4.3启动关闭rocketmq4.4配置开机自启动&#xff08;扩展项&am…

Vxe UI vue 使用 VxeUI.previewImage() 图片预览方法

Vxe UI vue 使用 VxeUI.previewImage() 图片预览方法的调用 查看 github 代码 调用全局方法 VxeUI.previewImage() 参数说明&#xff1a; urlList&#xff1a;图片列表&#xff0c;支持传字符串&#xff0c;也可以传对象数组 [{url: xx’l}] activeIndex&#xff1a;指定默…

力扣经典面试题-旋转链表(Java)

1.题目描述&#xff1a;给你一个链表的头节点 head &#xff0c;旋转链表&#xff0c;将链表每个节点向右移动 k 个位置。 示例 1&#xff1a; 输入&#xff1a;head [1,2,3,4,5], k 2 输出&#xff1a;[4,5,1,2,3] 示例 2&#xff1a; 输入&#xff1a;head [0,1,2], k …

stanfordcorenlp+python做中文nlp任务,得到的结果中全是空字符串,而不是中文字符串

问题描述 代码&#xff1a; from stanfordcorenlp import StanfordCoreNLP import logging#中文中的应用&#xff0c;一定记得下载中文jar包&#xff0c;并标志lang‘zh’ nlp_zh StanfordCoreNLP(rD:\stanford-corenlp-full-2016-10-31, port8094, langzh,quietFalse,logg…

基于YOLOv8的海面石油泄露检测实例分割完整含数据集

需要收集包含海面石油泄漏的图像数据集&#xff0c;并进行标注以指示泄漏区域。接下来&#xff0c;可以使用深度学习框架如PyTorch或TensorFlow&#xff0c;基于YOLO&#xff08;You Only Look Once&#xff09;系列的目标检测模型结构&#xff0c;进行训练。YOLO系列的模型具有…

电压模式 R-2R DAC 的工作原理和特性

在本文中&#xff0c;我们将探索什么是 R-2R DAC 以及如何实现它们。 首先&#xff0c;我们将简要回顾一下开尔文分频器 DAC。这种结构很简单&#xff0c;但需要大量电阻和开关来实现高分辨率 DAC。此问题的一种解决方案是称为 R-2R DAC 的 DAC 结构。这些结构巧妙地利用梯形网…

Elasticsearch 认证模拟题 - 14

一、题目 在集群中输入以下指令&#xff1a; PUT phones/_doc/1 {"brand":"Samsumg","model":"Galaxy S9","features":[{"type":"os", "value":"Android"},{"type":&q…

李飞飞解读创业方向:「空间智能」

在AI领域&#xff0c;李飞飞教授一直是一个举足轻重的存在。她的研究和见解不仅推动了计算机视觉的发展&#xff0c;更对人工智能的未来方向产生了深远的影响。在最近的一次演讲中&#xff0c;李飞飞详细解读了她对于「空间智能」的见解。本文将对她的演讲内容进行详细解读&…

如何使用GPT-4o函数调用构建一个实时应用程序?

本教程介绍了如何使用OpenAI最新的LLM GPT-4o通过函数调用将实时数据引入LLM。 我们在LLM函数调用指南(详见https://thenewstack.io/a-comprehensive-guide-to-function-calling-in-llms/)中讨论了如何将实时数据引入聊天机器人和代理。现在&#xff0c;我们将通过将来自Fligh…

持续警惕火灾风险:学校可燃气体报警器的定期校准检验

可燃气体报警器在学校中的安装、检验和校准对于保护师生生命安全至关重要。 接下来&#xff0c;佰德将探讨可燃气体报警器在学校中的必要性&#xff0c;以及相关实际案例和数据&#xff0c;为您呈现一个安全的学习环境。 一、学校安全不能掉以轻心 学校是培养未来的摇篮&…

Android限制参数传递之StringDef注解的使用

文章目录 1. 引言2. 注解 StringDef2.1 举例2.2 StringDef源码解释 3. 其他类似注解 IntDef、LongDef4. 总结 1. 引言 在参数传递时&#xff0c;如果你想限制传入的参数只能是特定的几个值&#xff0c;该怎么做呢&#xff1f; 除了把参数类型定义为枚举值&#xff0c;还可以使…

Boom 3D软件最新版下载及详细安装教程

值得肯定的是Boom 3D最新版新增的Boom音量控制器和Controlled Boost功能为使用者提供了一个完美的控制&#xff0c;通过一个整齐的设计切换栏的系统音频输出&#xff0c;帮助他们轻松调整音量&#xff0c;从而让他们实现理想的音频输出&#xff0c;有需要的欢迎来开心电玩下载使…

C++笔记之一个函数多个返回值的方法、std::pair、std::tuple、std::tie的用法

C++笔记之一个函数多个返回值的方法、std::pair、std::tuple、std::tie的用法 —— 2024-06-08 杭州 code review! 文章目录 C++笔记之一个函数多个返回值的方法、std::pair、std::tuple、std::tie的用法一.从一个函数中获取多个返回值的方法1. 使用结构体或类2. 使用`std::t…