真实用户ID,有效用户ID和保存的用户ID之间的区别

mrg*_*mrg 86 unix linux posix

我已经知道真正的用户ID.它是系统中用户的唯一编号.在我的系统中,My uid是

$ echo $UID
1014
$                 
Run Code Online (Sandbox Code Playgroud)

另外两个ID代表什么?什么是有效用户ID和保存的用户ID的使用以及我们在系统中使用它的位置.

Dam*_*mon 133

真实和有效用户ID之间的区别是因为您可能需要临时获取另一个用户的身份(大多数情况下,即root可能是任何用户).如果您只有一个用户ID,那么之后将无法更改回原始用户ID(除非您认为这是理所当然的,以防万一root,使用root's权限更改为任何用户).

因此,真正的用户ID是您真正的用户(拥有该进程的用户),并且有效的用户ID是操作系统查看的内容,以决定是否允许您执行某些操作(大多数情况下) ,有一些例外).

登录时,登录shell会将实际和有效用户ID设置为密码文件提供的相同值(您的真实用户ID).

现在,它也会执行一个setuid程序,除了作为另一个用户运行(例如root)setuid程序应该代表你做一些事情.这是如何运作的?
执行setuid程序后,它将具有您的真实ID(因为您是进程所有者)和文件所有者的有效用户ID(例如root),因为它是setuid.

该程序可以执行超级用户权限所需的任何魔术,然后代表您做某事.这意味着,尝试做一些你不应该做的事情应该会失败.它是如何做到的?好吧,显然通过将其有效用户ID更改为真实用户ID!

现在setuid程序无法切换回来,因为所有内核都知道你的id和... 你的id.砰,你死了.

这是保存的set-user id的用途.

  • 有关保存集用户ID的最后一点的更清晰,请参阅[Wikipedia.](https://en.wikipedia.org/wiki/User_identifier#Saved_user_ID) (5认同)
  • @mik1904:您可能会使用的最重要的一个真正_checks_ 真实 UID 是`access`。这就是其中的 99.9%。还有`setfsuid`(但很少需要)和一些非常低级的函数,你需要(但没有检查)获取/设置优先级或调度程序的真实用户ID,以及传递给信号处理程序或返回的ID `等待`等。_是_真实的身份证件。`execve` 不检查,但如果您更改了真实用户 ID,则_可能会失败_。此外 `fork` 不会检查,但如果达到真实 UID 上的最大进程配额,则_可能会失败_。带有`site:man7.org` 的谷歌是你的朋友。 (2认同)
  • “ping 命令需要打开一个套接字,而 Linux 内核为此需要 root 权限。” 这并不准确。`ping` 需要一个 _raw_ 套接字。任何用户(通常)都可以打开一个套接字,并在 1024 以上进行监听。 (2认同)

Rtm*_*tmY 8

I'll try to explain step by step with some examples.

Short background

Each process has its own 'Process credentials' which includes attributes like PID, the PPID, PGID,session ID and also the real and effective user and group IDs: RUID, EUID, RGID, EGID.

We'll focus on those.


Part 1 - Understand UID and GID

Now I'll log into a shell with my credentials and run:

$ grep $LOGNAME /etc/passwd
rotem:x:1000:1000:rotem,,,:/home/rotem:/bin/bash
Run Code Online (Sandbox Code Playgroud)

You can see my logname (rotem), the UID and GID which are both 1000, and other details like the shell I'm logged into.


Part 2 - Understand RUID and RGID

Every process has an owner and belongs to a group.
In our shell, every process that we'll now run will inherit the privileges of my user account and will run with the same UID and GID.

Lets run a simple command to check it:

$ sleep 10 & ps aux | grep 'sleep'
Run Code Online (Sandbox Code Playgroud)

And check for the process UID and GID:

$ stat -c "%u %g" /proc/$pid/
1000 1000
Run Code Online (Sandbox Code Playgroud)

Those are the Real user ID (RUID) and real group ID (RGID) of the process.

(*) Check other options to view the UID and GID and ways to get this in one-liner in.

For now, accept the fact that the EUID and EGID attributes are 'redundant' and just equals to RUID and RGID behind the scenes.


Part 3 - Understand EUID and EGID

Up until this point it was quiet simple. Now we need to put some more effort in order to understand.

Let's take the ping command as our example.

Search for the binary location with the which command then run ls -la:

-rwsr-xr-x  1 root root   64424 Mar 10  2017  ping
Run Code Online (Sandbox Code Playgroud)

You can see that owner and group of both files are root. This is because the ping command needs to open up a socket and the Linux kernel demands root privilege for that.

But how can I use ping if I don't have root privilege?
Notice the 's' letter instead of 'x' in the owner part of the file permission.
This is a special permission bit for specific binary executable files (like ping and sudo) which is known as setuid.

This is where EUID and EGID comes into play.
What will happen is when a setuid binary like ping executes, the process changes its Effective User ID (EUID) from the default RUID to the owner of this special binary executable file which in this case is - root.
This is all done by the simple fact that this file has the setuid bit.

The kernel make the decision whether this process has the privilege by looking on the EUID of the process. Because now the EUID points to root - this operation won't be rejected by the kernel.

Notice: On latest Linux Releases the the output of the ping command will look different because of the fact that they adopted the Linux Capabilities approach instead of this setuid approach - for those who are not familiar - read here.

Part 4 - What about SUID and SGID?

The Saved user ID (SUID) is being used when a privileged process is running (root for example) and needs to do some unprivileged tasks.

In that case, the effective UID (EUID) from before will be saved inside SUID and then changed to an unprivileged value. When the unprivileged task is completed the EUID will be taken from the value of SUID and switch back to privileged account.


I hope it was clear enough.

  • 除了关于 SUID 的最后一段之外,答案很明确。与特权和特权任务混淆了。如果提供示例很有用。谢谢。 (4认同)
  • https://en.wikipedia.org/wiki/User_identifier#Saved_user_ID 指向用例 (2认同)
  • @KMABadshah 当您分叉一个新进程时,该进程会继承父进程的 RUID。通常,父级的 RUID 属于您的 shell,并且它具有您的 UID。所以新进程有你的UID的RUID。通常这是不会改变的,只有 root 可以改变它。作为一个示例,请考虑 init 进程分叉您的登录 shell。在 fork 期间,shell 将具有 root 的 RUID(因为 shell 的父级是 init)。但是,init 进程使用“/etc/passwd”将 shell 的 RUID 更改为您的 UID。因此,此后登录 shell 的 RUID 将是您的 UID,而不是 root。所以,我们可以说RUID是进程所有者的。 (2认同)