linux 中的用户ID (ZZ)

2024-06-05 11:58
文章标签 linux 用户 id zz

本文主要是介绍linux 中的用户ID (ZZ),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、进程与权限

A.进程时Linux/Unix操作系统中最重要的抽象之一

B.进程是一个处于执行期的程序(目标代码存储在某种介质上)
A process is a program(object code stored on some media) in the midst of
execution.

而进程在执行过程中经常涉及到文件访问操作等
1.一个运行中的进程究竟可以访问哪些资源,而不能访问哪些资源?
2.一个进程运行过程中如何实现在某个执行阶段拥有一些权限而在另一个阶段又具备另外一种权限呢?

上述状况对应于进程的访问权限以及进程执行中不同权限的切换。这一切都和进程实际用户ID,进程有效用户ID,进程保存设置用户ID有关联。

二、进程的用户ID

1.实际用户ID(real user id,RUID)

为该进程的创建者的用户ID,也可以说是进程的执行者。该ID仅root用户可以修改

2.有效用户ID(effective user id,EUID)

该ID用户标识用户进程执行操作的权限。例如:如果EUID是0即(root),此时进程拥有root用户权限。普通用户可以将EUID设置为RUID或者SUID,而超级用户可以将EUID设置为任意的合法UID。

注意:对于一个可执行的二进制文件,如果其set-user-id bit被设置,则运行改程序时,对应进程的有效用户ID(EUID)为该文件的文件所有者用户ID。

3.保存设置用户ID(saved set-user-id,SUID)

对于没有设置set-uid-bit的可执行程序而言,其对应进程的保存设置用户ID(SUID)为其实际用户ID;而对于设置了set-uid-bit的程序而言,其对应的保存设置用户ID(SUID)为该可执行文件的文件拥有者用户ID。只能root用户权限,才能更改(当一个程序文件运行的时候,其值已经确定)。

注意:linux不提供返回保存的设置-用户-ID的函数

总结:
RUID代表此进程是哪个用户创建的, EUID代表此进程所拥有的权限,SUID保存了EUID,当EUID改变后,如果想回到以前的EUID,此时SUID将发挥作用。

三、相关API

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

int setuid(uid);

可以用setuid函数设置实际用户ID和有效用户ID。注意,我们并不能想怎么设就怎么设。有若干规则需要我们遵守:

(1)若进程具有超级用户特权,则setuid函数将实际用户ID、有效用户ID,以及保存的设置-用户-D设置为uid。

(2)若进程没有超级用户特权,但是uid等于实际用户ID或保存的设置-用户-ID,则setuid只将有效用户ID设置为。不改变实际用户ID和保存的设置-用户-ID。

(3)如果上面两个条件都不满足,则errno设置为EPERM,并返回出错.。

关于内核所维护的三个用户ID,还要注意下列几点

(1)只有超级用户进程可以更改实际用户ID。通常,实际用户ID是在用户登录时,由login(1)程序设置的,而且决不会改变它。因为login是一个超级用户进程,当它调用setuid时,设置所有三个用户ID。

(2)仅当对程序文件设置了 set-user-id bit时,exec函数设置有效用户ID为文件所有者。如果set-user-id bit没有设置,则exec函数不会改变有效用户ID,而将其位置原先值。任何时候都可以调用setuid,将有效用户ID设置为实际用户ID或保存的设置-用户-ID。自然,不能讲有效用户ID设置为任意随机值。

四、探究

案例一:
有个要在MacOS上实现一个关机程序,它熟悉linux,其实老祖宗都是unix,所以MacOS对他并不陌生。如下他写了如下程序实现关机



编译运行:



从上面看,这段代码可以实现关机,但是有个不符合要求的地方,运行程序不能是超级用户,只能是普通用户。

他很苦恼,后来找到了我,我做了如下事情



呵呵,可以了。我将这个可执行文件的owner和group都改为了root,然后有讲其set-user-id bit位加以了设置。这样以普通用户运行这个程序时,此进程的EUID就是root了,这样满足了shutdown命令执行的权限。

案例二:

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <unistd.h>
  4. #include <sys/types.h>
  5. #include <sys/stat.h>
  6. #include <fcntl.h>

  7. void test_read_file(const char *name)
  8. {
  9. int fd = -1;

  10. fd = open(name ,O_RDWR);
  11. if(fd < 0){
  12. printf("=[ERROR]:read failed.\n");
  13. }else{
  14. printf("=[OK]:read successful\n");
  15. close(fd);
  16. }
  17. }

  18. //打印uid和euid
  19. void p_states()
  20. {
  21. int uid = 0;
  22. int euid = 0;

  23. printf("------Current states--------\n");
  24. printf("real uid\t %d\n",getuid());
  25. printf("effective uid\t %d\n",geteuid());
  26. printf("----------------------------\n");
  27. }

  28. //调用setuid
  29. void run_setuid_fun(int uid)
  30. {
  31. if(setuid(uid) == -1)
  32. {
  33. printf("=[ERROR]:setuid(%d) error\n",uid);
  34. }

  35. p_states();
  36. }

  37. //调用setuid
  38. void run_seteuid_fun(int uid)
  39. {
  40. if(setuid(uid) == -1)
  41. {
  42. printf("=[ERROR]:seteuid(%d) error\n",uid);
  43. }

  44. p_states();
  45. }

  46. int main()
  47. {
  48. int t_re = 0;
  49. const char *file = "root_only.txt";

  50. printf("\nTEST 1:\n");
  51. p_states();
  52. //此时real uid = login user id
  53. //effective uid = root
  54. //saved uid = root
  55. test_read_file(file);

  56. getchar();

  57. printf("\nTEST 2:setuid(getuid())\n");
  58. run_seteuid_fun(getuid());
  59. //此时real uid = login user id
  60. //effective uid = login user id
  61. //saved uid = root
  62. test_read_file(file);

  63. getchar();

  64. printf("\nTEST 3:setuid(0)\n");
  65. run_setuid_fun(0);
  66. //此时real uid = login user id
  67. //effective uid = root
  68. //saved uid = root
  69. test_read_file(file);

  70. getchar();

  71. printf("\nTEST 4:setuid(0)\n");
  72. run_setuid_fun(0);
  73. //此时real uid = root
  74. //effective uid = root
  75. //saved uid = root
  76. test_read_file(file);

  77. getchar();

  78. printf("\nTEST 5:setuid(503)\n");
  79. run_setuid_fun(503);
  80. //此时real uid = login user id
  81. //effective id = login user id
  82. //saved uid = login user id
  83. test_read_file(file);

  84. getchar();

  85. printf("\nTEST 6:setuid(0)\n");
  86. //read uid = login user id
  87. //effective uid = login user id
  88. //saved uid = login user id
  89. run_setuid_fun(0);
  90. test_read_file(file);

  91. return 0;
  92. }
编译运行:



root_only.txt文件建立:



第一次:

RUID:实际用户
EUID:文件所有者(root)
SUID:文件所有者(root)



此时进程拥有root用户权限,能对 root_only.txt 进行读写操作

第二次:

此时普通用户调用setuid(getuid()),只会将EUID改为getuid(),其他都不变
RUID:实际用户
EUID:实际用户
SUID:root



此时进程没有有root用户权限,不能能对 root_only.txt 进行读写操作

第三次:

此时普通用户调用seteuid(0),只会将EUID改为0,其他都不变
RUID:实际用户
EUID:root
SUID:root



此时进程拥有root用户权限,能对 root_only.txt 进行读写操作

第四次:

此时进程拥有root用户权限,调用setuid(0),会将三个ID都设置为0
RUID:root
EUID:root
SUID:root



此时进程拥有root用户权限,能对 root_only.txt 进行读写操作

第五次:

此时进程拥有root用户权限,调用setuid(503),会将三个ID都设置为503
RUID:503
EUID:503
SUID:503



此时进程拥有普通用户权限,不能对 root_only.txt 进行读写操作

第六次:

此时进程拥有普通用户权限,调用setuid(0),此时RUID,SUID都不为0,这一次操作将失败
RUID:503
EUID:503
SUID:503


此时进程拥有普通用户权限,不能能对 root_only.txt 进行读写操作

这篇关于linux 中的用户ID (ZZ)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1032992

相关文章

Linux中shell解析脚本的通配符、元字符、转义符说明

《Linux中shell解析脚本的通配符、元字符、转义符说明》:本文主要介绍shell通配符、元字符、转义符以及shell解析脚本的过程,通配符用于路径扩展,元字符用于多命令分割,转义符用于将特殊... 目录一、linux shell通配符(wildcard)二、shell元字符(特殊字符 Meta)三、s

Linux之软件包管理器yum详解

《Linux之软件包管理器yum详解》文章介绍了现代类Unix操作系统中软件包管理和包存储库的工作原理,以及如何使用包管理器如yum来安装、更新和卸载软件,文章还介绍了如何配置yum源,更新系统软件包... 目录软件包yumyum语法yum常用命令yum源配置文件介绍更新yum源查看已经安装软件的方法总结软

linux报错INFO:task xxxxxx:634 blocked for more than 120 seconds.三种解决方式

《linux报错INFO:taskxxxxxx:634blockedformorethan120seconds.三种解决方式》文章描述了一个Linux最小系统运行时出现的“hung_ta... 目录1.问题描述2.解决办法2.1 缩小文件系统缓存大小2.2 修改系统IO调度策略2.3 取消120秒时间限制3

Linux alias的三种使用场景方式

《Linuxalias的三种使用场景方式》文章介绍了Linux中`alias`命令的三种使用场景:临时别名、用户级别别名和系统级别别名,临时别名仅在当前终端有效,用户级别别名在当前用户下所有终端有效... 目录linux alias三种使用场景一次性适用于当前用户全局生效,所有用户都可调用删除总结Linux

Linux:alias如何设置永久生效

《Linux:alias如何设置永久生效》在Linux中设置别名永久生效的步骤包括:在/root/.bashrc文件中配置别名,保存并退出,然后使用source命令(或点命令)使配置立即生效,这样,别... 目录linux:alias设置永久生效步骤保存退出后功能总结Linux:alias设置永久生效步骤

数据库oracle用户密码过期查询及解决方案

《数据库oracle用户密码过期查询及解决方案》:本文主要介绍如何处理ORACLE数据库用户密码过期和修改密码期限的问题,包括创建用户、赋予权限、修改密码、解锁用户和设置密码期限,文中通过代码介绍... 目录前言一、创建用户、赋予权限、修改密码、解锁用户和设置期限二、查询用户密码期限和过期后的修改1.查询用

Linux使用fdisk进行磁盘的相关操作

《Linux使用fdisk进行磁盘的相关操作》fdisk命令是Linux中用于管理磁盘分区的强大文本实用程序,这篇文章主要为大家详细介绍了如何使用fdisk进行磁盘的相关操作,需要的可以了解下... 目录简介基本语法示例用法列出所有分区查看指定磁盘的区分管理指定的磁盘进入交互式模式创建一个新的分区删除一个存

Linux使用dd命令来复制和转换数据的操作方法

《Linux使用dd命令来复制和转换数据的操作方法》Linux中的dd命令是一个功能强大的数据复制和转换实用程序,它以较低级别运行,通常用于创建可启动的USB驱动器、克隆磁盘和生成随机数据等任务,本文... 目录简介功能和能力语法常用选项示例用法基础用法创建可启动www.chinasem.cn的 USB 驱动

高效管理你的Linux系统: Debian操作系统常用命令指南

《高效管理你的Linux系统:Debian操作系统常用命令指南》在Debian操作系统中,了解和掌握常用命令对于提高工作效率和系统管理至关重要,本文将详细介绍Debian的常用命令,帮助读者更好地使... Debian是一个流行的linux发行版,它以其稳定性、强大的软件包管理和丰富的社区资源而闻名。在使用

Linux Mint Xia 22.1重磅发布: 重要更新一览

《LinuxMintXia22.1重磅发布:重要更新一览》Beta版LinuxMint“Xia”22.1发布,新版本基于Ubuntu24.04,内核版本为Linux6.8,这... linux Mint 22.1「Xia」正式发布啦!这次更新带来了诸多优化和改进,进一步巩固了 Mint 在 Linux 桌面