如何在 Linux 中通过 C/C++ 以另一个用户身份创建文件?
Posted
技术标签:
【中文标题】如何在 Linux 中通过 C/C++ 以另一个用户身份创建文件?【英文标题】:How to create file as another user via C/C++ in Linux? 【发布时间】:2019-12-21 13:01:48 【问题描述】:Linux C/C++ 有open
或fopen
API,但创建的文件属于进程uid。
如果我们想改变这个文件的所有者/组,我们可以在文件创建后使用chown
或fchown
API。
但是,是否有一个 API 可以作为另一个用户创建文件,而不是两个 API?
【问题讨论】:
不,没有任何 API。普通用户甚至不允许这样做。 您只能将文件的所有权更改为root
,并且无法创建文件,即使对于其他uid或gid拥有的root
也是如此。
像创建文件之前一样更改进程的运行对象。
【参考方案1】:
没有专门用于此的 Unix api,但您可以将当前用户更改为 创建文件之前的其他用户,例如:
确保您有权限。当前有效用户必须是“root”或在可执行文件上设置用户或组 ID。
致电setgid
和setuid
给其他用户。
创建文件。
如有需要,请致电setuid
和setgid
给老用户。
因为用户是进程范围的,如果你的程序是多线程的,你可以 需要 fork 一个执行我之前列出的步骤的子进程。
但是如果你想让非root用户(比如nobody)运行你的程序,你可以给 可执行文件的权限:
sudo chown root:root ./your_app && sudo chmod gu+s ./you_app
现在您可以拨打setuid(0)
和setgid(0)
获取root权限。
【讨论】:
您不需要调用setuid(0)
或setgid(0)
,因为有效的uid 将是0
(因为s
位),它允许您直接将uid 设置为其他用户。
您需要在调用setuid()
之前调用setgid()
— 否则,setgid()
将失败,因为该进程不再具有 root 权限。传统上,如果具有root
权限的进程调用setuid()
来设置非零(非根)UID,则无法将有效UID 更改回root
(因此保存的UID 将被重置)。这是必要的,这样login
之类的程序才能按预期工作——无需让普通用户无需通过sudo
或su
之类的程序即可成为root
。
另外,您应该提及chown
系统调用选项,因为它更通用。他们只需要CAP_CHOWN
。【参考方案2】:
这在 Linux 中是不可能的。
允许这样做可能会导致一些微妙的安全漏洞(远程代码执行、破坏其他用户的文件等),因此是不允许的。
相反,请在sudo
下运行该进程。
【讨论】:
我认为 fork 和 exec suid root 二进制文件(无论是对要创建的文件执行额外检查的 sudo 或自定义二进制文件)是允许执行此操作的 API。所以第一段有点不正确。如果您在安装时具有管理员访问权限,则是可能的。 @hyde:这是 API 的另一种定义。如果您在系统调用级别工作(问题似乎如此),那么执行其他程序(甚至sudo
)并不是真正的API——是的,它使用fork()
和exec*()
,但它不是这不是 API 通常用来描述的简单系统调用。
@JonathanLeffler 取决于您是否将“Linux”视为操作系统(例如,您可以将 C 标准库或通常的 Linux 库视为可用的 API)还是内核(仅在这种情况下系统调用、/dev 和 /proc 下的特殊文件等都可以算作 API)。该问题涉及操作系统库(提及fopen
)。
或者,换一种说法,你当然可以将“以另一个用户创建文件”包装成一个可以安装在基本上任何 Linux 中的包,它会提供一个 .so 库、一个 .h 文件用于使用该库构建软件,以及该库使用的帮助程序“suid root”二进制文件(通过某些 IPC 机制提供的守护程序或作为与fork
和exec
一起运行的二进制文件)。所以从这个意义上说,这在 Linux 中是完全可能的,内核提供了 API,允许从应用程序的角度将其作为简单的库函数调用来实现。以上是关于如何在 Linux 中通过 C/C++ 以另一个用户身份创建文件?的主要内容,如果未能解决你的问题,请参考以下文章
如何在Windows中通过Cygwin来使用Linux命令行
在 Windows 7 中通过 GnuWin32 使用 Microsoft Visual C/C++ 编译器编译源 (.C) 文件时出错