如何在 Linux 中通过 C/C++ 以另一个用户身份创建文件?

     2023-03-14     123

关键词:

【中文标题】如何在 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,允许从应用程序的角度将其作为简单的库函数调用来实现。

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

】如何在Ruby中通过引用传递?【英文标题】:HowtopassbyreferenceinRuby?【发布时间】:2017-01-0508:19:14【问题描述】:目前我正在Ruby中开发一个Watcher类,除其他外,它能够找到切换信号的周期持续时间。这通常相当简单,但我面临的... 查看详情

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

】如何在TurboC/C++中通过引用传递字符串【英文标题】:HowtopassastringbyrefrenceinTurboC/C++【发布时间】:2013-10-1313:39:24【问题描述】:[我正在使用以下代码voidfix_filename(char[],char[],int);intmain()inti;chark,l[100];cin>>i;fix_filename(l,"books",i)... 查看详情

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

】如何在C/C++中通过TCP发送.mp4文件?【英文标题】:Howtosend.mp4fileoverTCPinC/C++?【发布时间】:2021-12-3107:44:57【问题描述】:我正在尝试在C++应用程序中通过TCP客户端/服务器发送文件。场景非常简单;客户端发送文件和服务器端接... 查看详情

如何在 LINUX 中通过 CRONTAB 调度脚本 [重复]

】如何在LINUX中通过CRONTAB调度脚本[重复]【英文标题】:HowtoschedulescriptthroughCRONJOBinLINUX[duplicate]【发布时间】:2014-08-0916:15:31【问题描述】:我创建了一个脚本来解析我已经存在的文件。我想在其中应用cronjob,我想在每分钟后自... 查看详情

如何在windows中通过cygwin来使用linux命令行

参考技术A终端会以C:Cygwin主目录作为开始,但是那可能没有用处,因为你可能并没有在那里放置任何文件。你可以使用所有基本的Linux命令,但是要返回C:盘根目录的话你必须切换目录到/cygdrive/c。要想在Windows命令提示符下使用... 查看详情

如何在 Xcode 中通过代码触发按钮

】如何在Xcode中通过代码触发按钮【英文标题】:Howtotriggerabuttonthroughcode,inXcode【发布时间】:2011-01-1723:25:02【问题描述】:在我正在开发的iPhone应用程序中,我需要在UIScrollView中放置按钮,但由于我需要放置这么多按钮来滚动... 查看详情

如何在 Linux tclsh 中通过光标键获取命令历史记录

】如何在Linuxtclsh中通过光标键获取命令历史记录【英文标题】:HowtogetCommandhistorybycursorkeyinLinuxtclsh【发布时间】:2011-03-0318:16:51【问题描述】:可以在TCLshell(tclsh)中使用光标键(如向上箭头键)获取命令历史记录。我正在使用li... 查看详情

如何在 ASP.NET MVC 中通过 Ajax 提交表单?

】如何在ASP.NETMVC中通过Ajax提交表单?【英文标题】:HowdoIsubmitaformviaAjaxinASP.NETMVC?【发布时间】:2011-06-1614:20:56【问题描述】:我有一个由几个部分视图组成的视图,其中一个用Edit按钮显示用户信息。单击Edit按钮时,我对另一... 查看详情

如何在 Linux 中通过 perf 工具捕获 L3 缓存命中和未命中

】如何在Linux中通过perf工具捕获L3缓存命中和未命中【英文标题】:HowtocatchtheL3-cachehitsandmissesbyperftoolinLinux【发布时间】:2013-08-1113:20:58【问题描述】:有什么方法可以通过Linux中的perf工具捕获L3缓存命中和未命中。根据perflistcac... 查看详情

如何在linux中通过命令查看域名对应的ip

...也可以在Linux系统中通过命令进行查询。本教程主要讲解如何在Linux系统中通过命令查看域名对应的IP地址,主要讲解以下5个命令:dig命令它是一个功能强大且灵活的命令行工具,用于查询DNS名称服务器。它执行DNS查询,并显示... 查看详情

如何在 Django 中通过 group by 获得额外的列?

】如何在Django中通过groupby获得额外的列?【英文标题】:HowtogetextracolumnsingroupbyinDjango?【发布时间】:2020-08-2317:40:09【问题描述】:我只想在带有值的注释结果中包含ID(和其他字段)(即分组依据)。我会用一个例子来解释(... 查看详情

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

】在Windows7中通过GnuWin32使用MicrosoftVisualC/C++编译器编译源(.C)文件时出错【英文标题】:GetErrorWhenCompileSource(.C)fileUsingMicrosoftVisualC/C++compilerviaGnuWin32inWindows7【发布时间】:2014-09-1007:44:25【问题描述】:我将向您展示如下步骤......... 查看详情

如何在java中通过UDP发送一个int

】如何在java中通过UDP发送一个int【英文标题】:howtosendanintthroughUDPinjava【发布时间】:2011-03-0818:21:59【问题描述】:我正在尝试编写一些通过UDP发送单个int的代码。我到目前为止的代码:发件人:intnum=2;DatagramSocketsocket=newDatagram... 查看详情

在Linux编程中通过管道在进程之间发送链表结构的最佳方法是啥

】在Linux编程中通过管道在进程之间发送链表结构的最佳方法是啥【英文标题】:Whatisthebestwaytosendlinkedliststructurebetweenprocessesviapipeinlinuxprogramming在Linux编程中通过管道在进程之间发送链表结构的最佳方法是什么【发布时间】:2011... 查看详情

如何在 Mvc Core3 中通过 UserManager 获取具有一个角色的所有用户?

】如何在MvcCore3中通过UserManager获取具有一个角色的所有用户?【英文标题】:HowCanIGetAllUserswithoneRolebyUserManagerinMvcCore3?【发布时间】:2020-05-1400:29:00【问题描述】:如何在MvcCore3中通过UserManager获取具有一个角色的所有用户?我... 查看详情

如何在 C++ 中通过引用返回向量

】如何在C++中通过引用返回向量【英文标题】:HowcanIreturnvectorbyreferenceinC++【发布时间】:2020-06-1819:28:04【问题描述】:我想创建一个通过引用返回向量的函数。但是返回的向量(returned_v)与vec.v不同,而是一个复制的向量。这... 查看详情

使用java中的jsch在linux中通过sudo命令执行shell脚本以启动服务

...usingjschinjava【发布时间】:2016-04-0613:51:21【问题描述】:如何在Linux中通过Java执行shell脚本以通过sudo命令启动服务例如:cmd="sudopath/script.shstart 查看详情

如何在 Swift 中通过操作显示/隐藏 UISearchBar?

】如何在Swift中通过操作显示/隐藏UISearchBar?【英文标题】:Howtoshow/hideUISearchBarbyactioninSwift?【发布时间】:2015-06-2417:32:44【问题描述】:我有一个UITableView和一个UISearchBar。我需要通过用户操作(按下按钮)显示/隐藏我的searchBar... 查看详情