TLPI-Chapter 9 进程凭证
2017-10-22 15:25
267 查看
这一章开始看的有点懵,在网上搜索到一篇文章有助于理解链接地址Set-User-ID
1.每个进程都有一套用数字表示的用户ID和组ID。具体有实际用户ID(real user ID), 实际组ID(real group ID),有效用户ID(effective user ID),有效组ID(effective group ID),保存的set-user-ID和set-group-ID,文件系统用户ID和文件系统组ID,辅助组ID。
将上述种种ID称为进程凭证。
2.实际用户ID和实际组ID:
这两个ID确定了进程所属的用户和组。当用户登录时,会从/etc/passwd文件中读取UID和GID作为实际用户ID和组ID,后续创建的进程都从父进程处继承实际 UID和实际 GID。
3.有效用户ID和有效组ID:
进程尝试访问各种资源时,系统会依据有效用户ID和有效组ID连同辅助组ID一起来确定授予该进程的权限。
有效用户ID为0的用进程拥有的超级用户的所有权限。这样的进程称之为特权级进程,某些系统调用只能由特权级进程执行。
一般有效ID等实际ID,但会有一些操作导致这两种不一样。
4.set-user-id 和 set-group-id程序
set-user-id程序可以将进程的有效id修改为文件属主的ID,从而获得常规情况下并不具有的权限。set-group-id实现同样的功能。比如sudo就可以暂时获得root的权限。
可以使用chmod命令来设置权限位:
chmodu+sprog chmod g+s prog
$ ls -l prog
-rwsr-sr-x 1 root root 302585 Jun 26 15:05 prog
可以发现设置set-user-id后,x标志位别替换为s,当运行set-user-id进程时,内核会将该进程的UID设置为该文件属主的UID,则该进程拥有了对该文件的所有权限。同样推理可知,如果一个文件的属主为root,并且该文件可以设置set-user-id,则某个进程调用set-user-id时,内核就会将该进程的有效ID设置为0(root),则该进程暂时取得了root权限。注意修改的是进程的ID,不是文件的ID。
5.保存set-user-id 和保存set-group-id.
当set-user-id时,会发生如下步骤:
1.若可执行文件的set-user-id权限位已开,则将进程的有效用户ID设置为文件的属主ID,若没开启,则进程的有效ID保持不变。
2.保存set-user-id和保存set-group-id的值由对应的有效ID复制而来,无论正在执行的文件是否设置了set-user-id,复制都会进行。
举例说明:
假设某进程的实际id,有效id,保存的set-user-id都为1000,当其执行了root用户的拥有set-user-id的程序后,进程的ID会发生如下变化:
real=1000 effective=0 saved=0
有不少系统调用,允许将set-user-id程序的有效用户id和实际用户id来回切换,则saved就是为了保存effective的副本。
6.文件系统用户id和组id
在linux系统中,要进行诸如打开文件,改变文件属主,修改文件权限之类的文件系统操作,决定其操作权限的是文件系统用户id和组id。一般文件系统id和有效id是一致的。只有当使用linux的两个系统调用setfsuid()和setfsgid()时才会不一样。
7.获取和修改进程凭证
示例程序
总结:
每个进程都有一干与之相关的用户ID和组ID。实际ID定义了进程所属。在大多数UNIX实现中,进程对诸如文件之类资源的访问,其许可权限由有效ID决定。然后Linux会使用文件系统ID来决定对文件的访问权限,而将有效ID用于检查其它权限。进程辅助组ID则时由出于权限检查目的而另行设立的进程属组集合。存在各种系统调用和库函数支持进程获取和修改其用户ID和组ID。
set-user-ID程序运行时,会将进程有效用户ID设置为文件属主的用户ID。运行某个特殊程序时,这种机制支持用户假借其它用户的身份和特权。相应的,set-group-ID程序会修改运行改程序的进程的有效组ID。保存set-user-ID和保存set-group-ID允许set-user-ID和set-group-ID程序临时性的放弃特权,并在之后恢复特权。
0在用户ID中卓尔不群。通常仅为一个名为root的账号所有。有效用户ID为0的进程属特权级进程。换言之,对于进程发起的各种系统调用,可免于接受通常所要经历的诸多权限检查。
1.每个进程都有一套用数字表示的用户ID和组ID。具体有实际用户ID(real user ID), 实际组ID(real group ID),有效用户ID(effective user ID),有效组ID(effective group ID),保存的set-user-ID和set-group-ID,文件系统用户ID和文件系统组ID,辅助组ID。
将上述种种ID称为进程凭证。
2.实际用户ID和实际组ID:
这两个ID确定了进程所属的用户和组。当用户登录时,会从/etc/passwd文件中读取UID和GID作为实际用户ID和组ID,后续创建的进程都从父进程处继承实际 UID和实际 GID。
3.有效用户ID和有效组ID:
进程尝试访问各种资源时,系统会依据有效用户ID和有效组ID连同辅助组ID一起来确定授予该进程的权限。
有效用户ID为0的用进程拥有的超级用户的所有权限。这样的进程称之为特权级进程,某些系统调用只能由特权级进程执行。
一般有效ID等实际ID,但会有一些操作导致这两种不一样。
4.set-user-id 和 set-group-id程序
set-user-id程序可以将进程的有效id修改为文件属主的ID,从而获得常规情况下并不具有的权限。set-group-id实现同样的功能。比如sudo就可以暂时获得root的权限。
可以使用chmod命令来设置权限位:
chmodu+sprog chmod g+s prog
$ ls -l prog
-rwsr-sr-x 1 root root 302585 Jun 26 15:05 prog
可以发现设置set-user-id后,x标志位别替换为s,当运行set-user-id进程时,内核会将该进程的UID设置为该文件属主的UID,则该进程拥有了对该文件的所有权限。同样推理可知,如果一个文件的属主为root,并且该文件可以设置set-user-id,则某个进程调用set-user-id时,内核就会将该进程的有效ID设置为0(root),则该进程暂时取得了root权限。注意修改的是进程的ID,不是文件的ID。
5.保存set-user-id 和保存set-group-id.
当set-user-id时,会发生如下步骤:
1.若可执行文件的set-user-id权限位已开,则将进程的有效用户ID设置为文件的属主ID,若没开启,则进程的有效ID保持不变。
2.保存set-user-id和保存set-group-id的值由对应的有效ID复制而来,无论正在执行的文件是否设置了set-user-id,复制都会进行。
举例说明:
假设某进程的实际id,有效id,保存的set-user-id都为1000,当其执行了root用户的拥有set-user-id的程序后,进程的ID会发生如下变化:
real=1000 effective=0 saved=0
有不少系统调用,允许将set-user-id程序的有效用户id和实际用户id来回切换,则saved就是为了保存effective的副本。
6.文件系统用户id和组id
在linux系统中,要进行诸如打开文件,改变文件属主,修改文件权限之类的文件系统操作,决定其操作权限的是文件系统用户id和组id。一般文件系统id和有效id是一致的。只有当使用linux的两个系统调用setfsuid()和setfsgid()时才会不一样。
7.获取和修改进程凭证
示例程序
/*************************************************************************\ * Copyright (C) Michael Kerrisk, 2015. * * * * This program is free software. You may use, modify, and redistribute it * * under the terms of the GNU General Public License as published by the * * Free Software Foundation, either version 3 or (at your option) any * * later version. This program is distributed without any warranty. See * * the file COPYING.gpl-v3 for details. * \*************************************************************************/ /* Listing 9-1 */ /* idshow.c Display all user and group identifiers associated with a process. Note: This program uses Linux-specific calls and the Linux-specific file-system user and group IDs. */ #define _GNU_SOURCE #include <unistd.h> #include <sys/fsuid.h> #include <limits.h> #include "ugid_functions.h" /* userNameFromId() & groupNameFromId() */ #include "tlpi_hdr.h" #define SG_SIZE (NGROUPS_MAX + 1) int main(int argc, char *argv[]) { uid_t ruid, euid, suid, fsuid; gid_t rgid, egid, sgid, fsgid; gid_t suppGroups[SG_SIZE]; int numGroups, j; char *p; if (getresuid(&ruid, &euid, &suid) == -1) errExit("getresuid"); if (getresgid(&rgid, &egid, &sgid) == -1) errExit("getresgid"); /* Attempts to change the file-system IDs are always ignored for unprivileged processes, but even so, the following calls return the current file-system IDs */ fsuid = setfsuid(0); fsgid = setfsgid(0); printf("UID: "); p = userNameFromId(ruid); printf("real=%s (%ld); ", (p == NULL) ? "???" : p, (long) ruid); p = userNameFromId(euid); printf("eff=%s (%ld); ", (p == NULL) ? "???" : p, (long) euid); p = userNameFromId(suid); printf("saved=%s (%ld); ", (p == NULL) ? "???" : p, (long) suid); p = userNameFromId(fsuid); printf("fs=%s (%ld); ", (p == NULL) ? "???" : p, (long) fsuid); printf("\n"); printf("GID: "); p = groupNameFromId(rgid); printf("real=%s (%ld); ", (p == NULL) ? "???" : p, (long) rgid); p = groupNameFromId(egid); printf("eff=%s (%ld); ", (p == NULL) ? "???" : p, (long) egid); p = groupNameFromId(sgid); printf("saved=%s (%ld); ", (p == NULL) ? "???" : p, (long) sgid); p = groupNameFromId(fsgid); printf("fs=%s (%ld); ", (p == NULL) ? "???" : p, (long) fsgid); printf("\n"); numGroups = getgroups(SG_SIZE, suppGroups); if (numGroups == -1) errExit("getgroups"); printf("Supplementary groups (%d): ", numGroups); for (j = 0; j < numGroups; j++) { p = groupNameFromId(suppGroups[j]); printf("%s (%ld) ", (p == NULL) ? "???" : p, (long) suppGroups[j]); } printf("\n"); exit(EXIT_SUCCESS); }
总结:
每个进程都有一干与之相关的用户ID和组ID。实际ID定义了进程所属。在大多数UNIX实现中,进程对诸如文件之类资源的访问,其许可权限由有效ID决定。然后Linux会使用文件系统ID来决定对文件的访问权限,而将有效ID用于检查其它权限。进程辅助组ID则时由出于权限检查目的而另行设立的进程属组集合。存在各种系统调用和库函数支持进程获取和修改其用户ID和组ID。
set-user-ID程序运行时,会将进程有效用户ID设置为文件属主的用户ID。运行某个特殊程序时,这种机制支持用户假借其它用户的身份和特权。相应的,set-group-ID程序会修改运行改程序的进程的有效组ID。保存set-user-ID和保存set-group-ID允许set-user-ID和set-group-ID程序临时性的放弃特权,并在之后恢复特权。
0在用户ID中卓尔不群。通常仅为一个名为root的账号所有。有效用户ID为0的进程属特权级进程。换言之,对于进程发起的各种系统调用,可免于接受通常所要经历的诸多权限检查。
相关文章推荐
- TLPI-Chapter 12系统和进程信息
- TLPI-Chapter 6 进程
- 用户和组与进程凭证
- TLPI-Chapter 20 信号
- Linux -- Chapter 11 进程与信号
- Understanding Unix/Linux Programming 笔记:chapter 11:连接到近端或远端的进程:服务器与Socket(套接字)
- chapter 7之进程管理
- Linux -- Chapter 11 进程与信号
- TLPI-Chapter 13文件I/O缓冲
- 进程环境 知识点汇总《APUE》 chapter-7
- chapter 4.1 进程,编写第一个windows应用程序
- Understanding Unix/Linux Programming 笔记:chapter 8:进程和程序:编写命令解释器sh
- Chapter 13 守护进程
- Linux系统编程手册第9章-进程凭证
- chapter 6 进程通信
- Chapter 13 守护进程
- Chapter 8. 进程
- Chapter17— Memory-Mapping Files 进程间共享数据进行通信
- TLPI-Chapter 3系统编程概念
- Chapter17— Memory-Mapping Files 进程间共享数据进行通信