sudo 原理
详细介绍参考这里sudo命令实现原理简析
以下简单介绍下关键的部分!
SUID 的概念
What is SUID and how to set it in Linux?
SUID (Set owner User ID up on execution) is a special type of file permissions given to a file. Normally in Linux/Unix when a program runs, it inherits access permissions from the logged in user. SUID is defined as giving temporary permissions to a user to run a program/file with the permissions of the file owner rather that the user who runs it. In simple words users will get file owner‘s permissions as well as owner UID and GID when executing a file/program/command.
如上 suid
(Set owner User ID up on execution) 概念就是:如果文件被设置了suid
属性,那么运行时候,这个程序的权限就会以文件拥有所有者的权限来运行。所以如果这个文件的所有者是 root 那么这个文件将以 root 权限运行!!!
具有 suid 的程序在 ls -la
时候能看到一个 s
属性。这个属性用 chmod +4000
或者 chmod +s
都可以添加!
setuid 函数
如下摘取自 man setuid
:
PROLOG
This manual page is part of the POSIX Programmer's Manual. The Linux implementation of this interface may
differ (consult the corresponding Linux manual page for details of Linux behavior), or the interface may not
be implemented on Linux.
NAME
setuid — set user ID
SYNOPSIS
#include <unistd.h>
int setuid(uid_t uid);
DESCRIPTION
If the process has appropriate privileges, setuid() shall set the real user ID, effective user ID, and the
saved set-user-ID of the calling process to uid.
If the process does not have appropriate privileges, but uid is equal to the real user ID or the saved set-
user-ID, setuid() shall set the effective user ID to uid; the real user ID and saved set-user-ID shall remain
unchanged.
The setuid() function shall not affect the supplementary group list in any way.
RETURN VALUE
Upon successful completion, 0 shall be returned. Otherwise, -1 shall be returned and errno set to indicate the error.
sudo 简单实现
最关键的一步就是调用setuid
函数把 uid 设置为 0,即 root。这一步能成功在于,程序具有 suid 属性,他的 euid 是 0(root)所以能成功执行 setuid 函数。
代码如下:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(int argc, char **argv)
{
if (setuid(0))
return -1;
if (argc > 1)
execvp(argv[1], argv + 1);
else
return -1;
}
如下是执行log