如何在 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++ 有openfopen API,但创建的文件属于进程uid。

如果我们想改变这个文件的所有者/组,我们可以在文件创建后使用chownfchown API。

但是,是否有一个 API 可以作为另一个用户创建文件,而不是两个 API?

【问题讨论】:

不,没有任何 API。普通用户甚至不允许这样做。 您只能将文件的所有权更改为root,并且无法创建文件,即使对于其他uid或gid拥有的root也是如此。 像创建文件之前一样更改进程的运行对象。 【参考方案1】:

没有专门用于此的 Unix api,但您可以将当前用户更改为 创建文件之前的其他用户,例如:

    确保您有权限。当前有效用户必须是“root”或在可执行文件上设置用户或组 ID。

    致电setgidsetuid给其他用户。

    创建文件。

    如有需要,请致电setuidsetgid 给老用户。

因为用户是进程范围的,如果你的程序是多线程的,你可以 需要 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 之类的程序才能按预期工作——无需让普通用户无需通过sudosu 之类的程序即可成为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 机制提供的守护程序或作为与forkexec 一起运行的二进制文件)。所以从这个意义上说,这在 Linux 中是完全可能的,内核提供了 API,允许从应用程序的角度将其作为简单的库函数调用来实现。

以上是关于如何在 Linux 中通过 C/C++ 以另一个用户身份创建文件?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Turbo C/C++ 中通过引用传递字符串

如何在 C/C++ 中通过 TCP 发送 .mp4 文件?

如何在 Ruby 中通过引用传递?

如何在Windows中通过Cygwin来使用Linux命令行

在 Windows 7 中通过 GnuWin32 使用 Microsoft Visual C/C++ 编译器编译源 (.C) 文件时出错

如何在Ubuntu中通过编译源码包安装软件Pidgin