`

更改用户 ID 和更改组 ID

阅读更多
    UNIX 系统中的特权(如能改变当前日期的表示法)和访问控制(如能否读、写一个特定文件)都是基于用户 ID 和组 ID 的。当程序需要增加或降低特权,需要允许或阻止对某些资源的访问时,都需要更换自己的用户 ID 或组 ID。
    可以使用 setuid 函数设置实际用户 ID 和有效用户 ID,使用 setgid 函数设置实际组 ID 和有效组 ID。
#include <unistd.h>
int setuid(uid_t uid);
int setgid(gid_t gid);
                        /* 两个函数返回值:若成功,返回 0;否则,返回 -1 */

    更改用户 ID 有若干规则(这些规则也适用于组 ID)。
    1、若进程具有超级用户特权,则 setuid 会将实际用户 ID、有效用户 ID 及保存的设置用户 ID(saved set-user-ID)设置为 uid。
    2、若进程没有超级用户特权,但是 uid 等于实际用户 ID 或保存的设置用户 ID,则 setuid 只将有效用户 ID 设置为 uid。
    3、如果上面两个条件都不满足,则将 errno 设置为 EPERM,并返回 -1。
    这里假设 _POSIX_SAVED_IDS 为真,如果没有提供这种功能,则上面所说的关于保存的设置用户 ID 部分都无效(在 POSIX.1 2001 版中,保存的 ID 是强制性功能。而在早期版本中则是可选的。为了测试某实现是否支持该功能,应用程序可在编译时测试常量 _POSIX_SAVED_IDS,或者在运行时以 _SC_SAVED_IDS 参数调用 sysconf 函数)。
    关于内核所维护的这 3 个用户 ID,还要注意以下几点。
    1、只有超级用户进程可以更改实际用户 ID。通常,实际用户 ID 是在登录时由 login(1) 程序设置的,而且决不会改变它。因为 login 是一个超级用户进程,所以当它调用 setuid 时,会设置所有 3 个用户 ID。
    2、仅当对程序文件设置了设置用户 ID 位时,exec 函数才改变有效用户 ID。任何时候都可以调用 setuid 将有效用户 ID 设置为实际用户 ID 或保存的设置用户 ID。
    3、保存的设置用户 ID 位是由 exec 复制有效用户 ID 而得到的。如果设置了文件的设置用户 ID 位,则在 exec 根据文件的用户 ID 设置了进程的有效用户 ID 以后,这个副本就被保存起来了。
    下表总结了更改这 3 个用户 ID 的不同方法。

    注意,在进程标识符操作函数中所述的 getuid 和 geteuid 函数只能获得实际用户 ID 和有效用户 ID 的当前值,并没有可移植的方法去获得保存的设置用户 ID 的当前值(FreeBSD 8.0 和 Linux 3.2.0 提供了 getresuid 和 getresgid 函数,它们可以分别用于获取保存的设置用户 ID 和保存的设置组 ID)。
    历史上,BSD 支持 setreuid 函数,可用于交换实际用户 ID 和有效用户 ID 的值。
#include <unistd.h>
int setreuid(uid_t ruid, uid_t euid);
int setregid(gid_t rgid, gid_t egid);
                              /* 两个函数返回值:若成功,返回 0;否则,返回 -1 */

    如若其中任一参数的值为 -1,则表示相应的 ID 保持不变。
    一个非特权用户总能交换实际用户 ID 和有效用户 ID。这就允许一个设置用户 ID 程序交换成用户的普通权限,以后又可再次交换回设置用户 ID 权限。POSIX.1 引进了保存的设置用户 ID 特性后,其规则也相应加强,它允许一个非特权用户将其有效用户 ID 设置为保存的设置用户 ID(4.3 BSD 没有保存的设置用户 ID 特性,而是使用上面这两个函数来代替。这就允许一个非特权用户交换这两个用户 ID 的值。但当使用此特性的程序生成 shell 进程时,它应该在子进程调用 exec 前将子进程的实际用户 ID 和有效用户 ID 都设置成普通用户 ID。否则当实际用户 ID 具有特权时,shell 进程就可调用 setreuid 交换两个用户 ID 值以获得更多权限)。
    POSIX.1 包含了 seteuid 和 setegid 函数,它们类似于 setuid 和 setgid,但只更改有效用户 ID 和有效组 ID。
#include <unistd.h>
int seteuid(uid_t uid);
int setegid(gid_t gid);
                              /* 两个函数返回值:若成功,返回 0;否则,返回 -1 */

    一个非特权用户可将其有效用户 ID 设置为其实际用户 ID 或其保存的设置用户 ID,而一个特权用户则可将有效用户 ID 设置为 uid。
    下图描述了本文所述的更改 3 个不同用户 ID 的各个函数。

    为说明保存的设置用户 ID 特性的用法,下面就来观察一个使用了该特性的 at(1)程序,它用于调度将来某个时刻要运行的命令(Linux 3.2.0 上的 at 程序的设置用户 ID 是 daemon 用户,FreeBSD 8.0、Mac OS X 10.6.8 以及 Solaris 10 上的 at 程序的设置用户 ID 是 root 用户。这允许 at 命令对守护进程拥有的特权文件具有写权限,守护进程代表用户运行 at 命令。在 Linux 3.2.0 上,程序是用 atd(8)守护进程运行的,在 FreeBSD 8.0 和 Solaris 10 上是通过 cron 守护进程运行的,在 Max OS X 10.6.8 上是通过 launchd(8)守护进程运行的)。为了防止被欺骗而运行不被允许的命令或读、写没有访问权限的文件,at 程序和最终代表用户运行命令的守护进程必须在用户特权和守护进程特权之间切换。下面列出了工作步骤。
    1、程序文件是由 root 用户拥有的,并且其设置用户 ID 位已设置,则运行此程序时得到下列结果:
        实际用户 ID = 我们的用户 ID(未改变)
        有效用户 ID = root
        保存的设置用户 ID = root
    2、at 程序做的第一件事就是降低特权,以用户特权运行。它调用 setuid 函数把有效用户 ID 设置为实际用户 ID,此时得到:
        实际用户 ID = 我们的用户 ID(未改变)
        有效用户 ID = 我们的用户 ID
        保存的设置用户 ID = root(未改变)
    3、at 程序以我们的用户特权运行,直到它需要访问控制哪些命令即将运行,这些命令需要何时运行的配置文件时,at程序的特权会改变。这些文件由为用户运行命令的守护进程持有。at命令调用 setuid 函数把有效用户 ID 设置为 root,因为 setuid 的参数等于保存的设置用户 ID,所以这种调用是许可的,这就是为什么需要保存的设置用户 ID 的原因。现在得到:
        实际用户 ID = 我们的用户 ID(未改变)
        有效用户 ID = root
        保存的设置用户 ID = root(未改变)
    这里因为有效用户 ID 是 root,所以文件访问是允许的。
    4、修改文件从而记录了将要运行的命令以及它们的运行时间以后,at 命令通过调用 seteuid,把有效用户 ID 设置为用户 ID,降低它的特权,防止对特权的误用。此时得到:
        实际用户 ID = 我们的用户 ID(未改变)
        有效用户 ID = 我们的用户 ID
        保存的设置用户 ID = root(未改变)
    5、守护进程开始用 root 特权运行,代表用户运行命令。守护进程调用 fork,子进程调用 setuid 将它的用户 ID 更改为我们的用户 ID。因为子进程以 root 特权运行,更改了所有的 ID,所以:
        实际用户 ID = 我们的用户 ID
        有效用户 ID = 我们的用户 ID
        保存的设置用户 ID = 我们的用户 ID
    现在守护进程可以安全地代表我们运行命令,因为它只能访问我们通常可以访问的文件,并没有额外的权限。

    以这种方式使用保存的设置用户 ID,只有在需要提升特权的时候,我们通过设置程序文件的设置用户 ID 而得到的额外权限。然而,其他时间进程在运行时只具有普通权限。如果进程不能在其结束部分切换回保存的设置用户 ID,那么就不得不在全部运行时间都保持额外的权限(这可能会造成麻烦)。
    注意,上面针对用户 ID 所说的规则也适用于各个组 ID,不过附属组 ID 不受 setgid、setregid 和 setegid 函数的影响。
  • 大小: 9.8 KB
  • 大小: 11.3 KB
分享到:
评论

相关推荐

    linux用户和组的管理

    本篇将详细阐述Linux用户和组的管理相关知识,以帮助你更好地理解和操作这一领域。 一、用户与用户账户 1. 用户类型:在Linux中,用户分为普通用户和超级用户(root用户)。普通用户对系统资源有特定的访问权限,...

    Linux操作系统中用户管理内容

    2. `groupmod`:修改用户组信息,如`groupmod -g new_GID groupname`更改组ID,`groupmod -n new_groupname old_groupname`更改组名。 3. `groupdel`:删除用户组,`groupdel groupname`将删除指定的用户组。 4. `...

    Linux用户管理和设备管理

    ### Linux用户管理和设备...以上内容详细介绍了如何在 Linux 中进行用户和组的管理,包括用户的创建、删除、属性修改以及组的创建、管理权限分配等。通过对这些命令的熟悉掌握,可以更好地控制系统的安全性和访问权限。

    Linux操作系统案例教程电子用户与组群管理PPT学习教案.pptx

    - `/etc/group`:记录所有组的信息,包括组名、组ID和组内的用户列表。 - `/etc/shadow`:存储用户的密码信息,出于安全考虑,密码通常不保存在`/etc/passwd`中。 5. **用户和组案例分析** - **权限问题排查**:...

    centos的用户、组权限、添加删除用户等操作的详细操作命令

    - `groupmod`:用于修改现有组的属性,如更改组名。 - `groupdel`:用于删除组。 ### 四、口令管理 - `passwd`:用于设置或更改用户密码。 - `passwd -l 用户名`:锁定用户账户,使其无法登录。 - `passwd -S ...

    实验7Linux用户管理201911181

    在Linux操作系统中,用户和用户组的管理是系统管理员日常工作中不可或缺的部分。这个实验主要涵盖了Linux用户和用户组管理的一些基本操作,适用于Ubuntu这样的Linux发行版。以下是对实验内容的详细解释: 1. **添加...

    操作系统 linux

    - `groupmod` 命令允许修改组信息,如更改组ID(GID)或组名。 - `groupdel` 命令用于删除组。 4. **压缩和打包工具**: - `gzip` 和 `gunzip` 用于压缩和解压缩文件,`bzip2` 和 `bunzip2` 提供更高程度的压缩...

    Linux精品学习资料2

    - `-g &lt;GID&gt;`: 更改组ID。 - `-n &lt;新组名&gt;`: 更改组名。 - `-o`: 允许重复使用GID。 - **示例**: `[root@liulinuxhome]# groupmod -n linuxtest1 linuxtest`,将`linuxtest`组名更改为`linuxtest1`。 7. **...

    Linux常用命令和管理01-文件权限详解1

    当创建新用户时,`useradd`命令用于创建用户账户,`groupadd`用于创建新组,而`usermod`用于修改用户属性,如`uid`、`gid`和附加组。例如,`useradd -u 2200 -g distro -G peguin mandriva`将创建一个名为mandriva的...

    UNIX命令集合

    Groupmod**: 用于修改用户组的信息,如更改组名、组ID等。 **6. Groupdel**: 用于删除用户组。注意,在删除之前应确保没有用户属于该组。 **7. Passwd**: 用于更改用户的密码。支持为特定用户更改密码或管理员...

    Linux命令大全完整版

    - `-g GID`: 更改组ID - **示例**: `groupmod -n newgroup oldgroup` --- ##### 12. `halt` - **功能**: 关闭系统。 - **用法**: `halt [选项]` - `-p`: 停机后关闭电源 - **示例**: `halt -p` --- ##### 13....

    ubuntu命令大全

    - `-g gid`:更改组ID。 - **groupdel** - `groupdel groupname`:删除用户组。 **24. 用户组成员管理** - **gpasswd** - `gpasswd -a username groupname`:将用户添加到组。 - **id** - `id username`:显示...

    rill:Clojure事件采购工具包

    更改组ID和工件ID 请注意,我们为0.2.0发行版更改了group-id和artifact-id,在此我们还将旧的rill / rill工件分解为单独的组件。 [rill-event-sourcing/rill.event_store " 0.2.3-RC1 " ] ; if you're talking to ...

    Linux命令集合-最全-最新-最方便的

    - `-g`: 更改组ID。 #### `groupdel` - **命令**: `groupdel` - **功能**: 删除组。 ### 10. 打印管理 #### `redhat-config-printer` - **命令**: `redhat-config-printer` - **功能**: 配置打印机。 #### `lp`...

    IBM aix常用命令集合

    15. **chown(更改所有者)** 和 **chgrp(更改组)**:这两个命令用于改变文件或目录的所有者和所属组。 16. **lsattr(查看文件属性)** 和 **chattr(更改文件属性)**:查看和设置文件的特殊属性,如隐藏、不可...

    liunx 命令

    `chown user file`更改所有者,`chgrp group file`更改组。 16. **sudo**:以管理员身份运行命令。`sudo command`允许非root用户执行需要管理员权限的命令。 17. **apt-get**/**yum**:软件包管理器。在Debian/...

Global site tag (gtag.js) - Google Analytics