[英]Retrieve logged on user name or id in the process running under root
我需要从特权(根)应用程序运行另一个具有当前登录用户的应用程序。
getenv("USER")
和getenv("LOGNAME")
在特权应用程序中返回“root”。 有效和当前用户 id 为 0。
cat /proc/self/status | grep [GU]id:
Uid: 0 0 0 0
Gid: 0 0 0 0
我发现了一些接近我需要的东西user-1000.slice
,但我想避免在文件/proc/self/cgroup
上使用fscanf
。
cat /proc/self/cgroup | fgrep user
9:devices:/user.slice
8:pids:/user.slice/user-1000.slice
1:name=systemd:/user.slice/user-1000.slice/session-c1.scope
下面的代码根据需要输出 1000。 有没有更方便的方法或 API 从特权应用程序获取当前 UI session 的用户名?
#include <stdio.h>
int main() {
int luid = 0;
char line[100];
FILE* file = fopen("/proc/self/cgroup", "r");
while (fgets(line, sizeof(line), file)) {
if (sscanf(line, "%*d:pids:/user.slice/user-%d.slice", &luid) == 1)
break;
}
fclose(file);
printf("Logged on User Id: ");
luid ? printf("%d\n", luid) : printf("Not found\n");
return 0;
}
getlogin() - 给出当前登录用户的名称 - 可能是您正在寻找的。 但是它存在潜在的问题(有关详细信息,请参见链接页面)。
Unix 下的“当前 UI 会话”不是机器范围的概念。 这是没有意义的,因为 Unix 起源于多用户系统,这意味着可能有几个人同时登录,每个人都有几个 UI session。 在我正在工作的机器上就是这种情况,有 4 人登录,6 个 UI 会话和大约 20 个非 UI 会话。
有一个当前登录人员的数据库/var/run/utmp
。 维护这个数据库在某种程度上取决于程序的判断(例如,我使用的 gnome-terminal 版本允许在数据库中添加或不添加条目)。 数据库格式在utmp(5)
中描述,并且有访问它的函数(参见getutent(3)
)。 有一些程序可以显示其内容( who(1)
和w(1)
)并修改它( sessreg(1)
)。
我不确定您的目的是什么,因此很难推荐一种方法。 确保您的显示管理器在utmp
中添加一个条目并解析who
可能是最简单的结果,但您必须注意您所做的假设。
假设 root session 从终端使用“pkexec”启动。
从终端运行 pkexec 时,会显示以下进程层次结构:
pstree -p | grep $$
...
|-gnome-terminal-(3295)-+-bash(3302)---bash(93463)-+-grep(93500)
...
在这种情况下,可以根据以下逻辑提取用户:
在 shell 中更容易做到,因此如果可能,请按照部分示例逃到 shell:
char buff[50], cur_user[50] ;
int cur_user_pid = 0 ;
sprintf(buff, "x=$(ps -oppid= %d) ; ps -ouid,user= $x", getppid()) ;
FILE *fp = popen(buff, "r") ;
fscanf(fp, "%d %s", &cur_user_pid, curr_user) ;
pclose(fp) ;
如果无法逃到 shell,我相信可以使用 /proc 文件系统遍历进程树。 Per 如何获得祖父母/祖先进程 ID? ,它在“/proc/[pid]/stat”的第四个字段中可用。
我最近注意到暴发户进程在登录用户下运行,我认为它在 root 下运行。 因此,我下面的解决方案看起来比从/proc/self/cgroup
中提取用户 ID 的解决方案要好。
#include <stdio.h>
int main() {
int uid = -1;
char line[100];
pid_t sid = getsid(0);
sprintf(line, "/proc/%d/status", sid);
FILE *file = fopen(line, "r");
while (fgets(line, sizeof(line), file)) {
if (sscanf(line, "Uid: %d", &uid) == 1)
break;
}
fclose(file);
printf("Logged on User Id: ");
uid != -1 ? printf("%d\n", uid) : printf("Not found\n");
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.