Linux自主访问控制——有效ID与真实ID

在做毕设的时候,碰到了一个场景:需要在普通用户的情况下调用“特权程序”,来访问受保护的文件。相应知识网络安全课学过,这里再回忆并总结一下。

有效ID与真实ID的关系

在Unix的设计中,进程与多个用户ID和用户组ID相关联,包括如下:

1、实际用户ID和实际用户组ID:标识我是谁,身份的识别,谁运行的程序。也就是登录用户的uid和gid,比如我的Linux以simon登录,在Linux运行的所有的命令的实际用户ID都是simon的uid,实际用户组ID都是simon的gid(可以用id命令查看)。

2、有效用户ID和有效用户组ID:进程用来决定我们对资源的访问权限,权利的识别。一般情况下,有效用户ID等于实际用户ID,有效用户组ID等于实际用户组ID。在操作系统中,用euid表示有效用户id。

当设置(SUID)位时,则有效用户ID等于文件的所有者的uid;同样,如果设置了(SGID)位,则有效用户组ID等于文件所有者的gid。也就是说,不论是哪个用户使用该文件,该文件都拥有等同于其创建者(往往是root)的权限。

进程的RealUID和EffectiveUID 以及进程UID的继承关系

一. 身份的标识: Real UID

* 进程的UID只是泛称, 其实有很多种UID(ruid / euid)

* 进程的 Real UID 是进程身份的标识, 用来说明Who am I, 没有实权

* 进程的权限并不是由RealUID来决定的

二. 权限的标识: Effective UID

* 有身份无权限是不行的, 有权限才能为所欲为

* Effective UID 是进程的权利的标识, 标识了该进程的“权利”

* Linux的授权 是 靠 Effective UID 来识别的

* 有权利就能做一切

* 之前说明的,文件、资源以及特权API操作权限 是 通过 Effective UID来识别的

三. 身份和权利的关系

* 默认情况下 Real UID == Effective UID, 所以使用ps命令输出的 就是 Effective UID

* 我们也可以显示完整的 Effective UID 和Real UID

四. ROOT 用户的特权

* Root 用户, 均是指 Effective UID == ROOT的进程

* 不受任何限制,可以为所欲为

* ROOT进程可以调用setUID 修改自己的Real UID,它也可以把自己的Effective UID改为普通的UID。

五. UID的世袭

* 在Linux世界里,为了安全考虑,UID世袭规则: 身份可以世袭,权利不能世袭

* 子进程的 Real UID = Effective UID,  继承 父进程的Real UID

      若父进程的Effective UID 与 Real UID 不一样,则不具有父进程的权利

六、文件的setUID – 文件的setUID标志以及其作用。
临时提升某可执行文件的euid到owner id,同时不需要改变其ruid。这样,普通用户也可以做某些特权行为。

6.1  需求:

    * Linux的passwd是一个可执行程序, 用于修改用户的密码

    * passwd需要修改多用户的账号文件(该文件仅能ROOT用户可以读写)

    * 但是 普通用户 也要修改自己的密码

    * passwd虽然 是平民身份(由普通用户启动),但是却需要皇族的权限  ---- 身份 和 权利不同

6.2 解决:

   * 临时提升进程的Effective UID, 而维持身份不变(Real UID), 让他能够利用特权,而又不传给子进程

Linux自主访问控制——有效ID与真实ID_第1张图片
Readrootfile.c的代码如下:

/*
 * getuid() returns the real user ID of the calling process.
 * geteuid() returns the effective user ID of the calling process.
 */
 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
 
char * get_username_by_id(uid_t uid)
{
    struct passwd *pwd;
 
    pwd = getpwuid(uid);
    return (pwd == NULL) ? NULL : pwd->pw_name;
}
 
int main(int argc, char *argv[])
{
	int fd;
 
	fd = open(argv[1], O_RDWR);
	if(fd == -1)
		perror("Open fail: ");
	else
		printf("Open %s ok.\n", argv[1]);
 
	printf("Real User ID:%d, name=%s\n",
		getuid(), get_username_by_id(getuid()));
	/* 如果设置了Set-User-ID(chmod u+s),那Effective User ID与Owner ID相同。 */
	printf("Effective User ID:%d, name=%s\n",
		geteuid(), get_username_by_id(geteuid()));
 
	close(fd);
 
	return 0;
}

你可能感兴趣的:(本科学习,linux相关,操作系统,linux,unix,服务器)