繁体   English   中英

在 root 下运行的进程中检索登录的用户名或 id

[英]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)
         ...

在这种情况下,可以根据以下逻辑提取用户:

  1. 查找当前进程的祖父:cur_user_pid
  2. 根据具体的设置,可能需要 go 增加额外的层,直到检测到非根 ID。
  3. 查找用户 id cur_user_pid

在 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM