diff --git a/proc/pids.c b/proc/pids.c index 5f9ea1e8..5928e4f6 100644 --- a/proc/pids.c +++ b/proc/pids.c @@ -170,6 +170,7 @@ REG_set(ID_FGID, u_int, fgid) REG_set(ID_FGROUP, str, fgroup) REG_set(ID_FUID, u_int, fuid) REG_set(ID_FUSER, str, fuser) +REG_set(ID_LOGIN, s_int, luid) REG_set(ID_PGRP, s_int, pgrp) REG_set(ID_PID, s_int, tid) REG_set(ID_PPID, s_int, ppid) @@ -342,6 +343,7 @@ srtDECL(noop) { #define f_either PROC_SPARE_1 // either status or stat (favor stat) #define f_grp PROC_FILLGRP +#define f_login PROC_FILL_LUID #define f_lxc PROC_FILL_LXC #define f_ns PROC_FILLNS #define f_oom PROC_FILLOOM @@ -419,6 +421,7 @@ static struct { { RS(ID_FGROUP), x_ogroup, NULL, QS(str), 0, TS(str) }, { RS(ID_FUID), f_status, NULL, QS(u_int), 0, TS(u_int) }, { RS(ID_FUSER), x_ouser, NULL, QS(str), 0, TS(str) }, // freefunc NULL w/ cached string + { RS(ID_LOGIN), f_login, NULL, QS(s_int), 0, TS(s_int) }, { RS(ID_PGRP), f_stat, NULL, QS(s_int), 0, TS(s_int) }, { RS(ID_PID), 0, NULL, QS(s_int), 0, TS(s_int) }, // oldflags: free w/ simple_nextpid { RS(ID_PPID), f_either, NULL, QS(s_int), 0, TS(s_int) }, diff --git a/proc/pids.h b/proc/pids.h index 96635b1d..f6c15810 100644 --- a/proc/pids.h +++ b/proc/pids.h @@ -59,6 +59,7 @@ enum pids_item { PIDS_ID_FGROUP, // str PIDS_ID_FUID, // u_int PIDS_ID_FUSER, // str + PIDS_ID_LOGIN, // s_int PIDS_ID_PGRP, // s_int PIDS_ID_PID, // s_int PIDS_ID_PPID, // s_int diff --git a/proc/readproc.c b/proc/readproc.c index 1fe7ce04..77642f86 100644 --- a/proc/readproc.c +++ b/proc/readproc.c @@ -877,6 +877,25 @@ static char *lxc_containers (const char *path) { } return lxc_none; } + + + // Provide the user id at login (or -1 if not available) +static int login_uid (const char *path) { + char buf[PROCPATHLEN]; + int fd, id, in; + + id = -1; + snprintf(buf, sizeof(buf), "%s/loginuid", path); + if ((fd = open(buf, O_RDONLY, 0)) != -1) { + in = read(fd, buf, sizeof(buf) - 1); + close(fd); + if (in > 0) { + buf[in] = '\0'; + id = atoi(buf); + } + } + return id; +} /////////////////////////////////////////////////////////////////////// @@ -998,6 +1017,9 @@ static proc_t* simple_readproc(PROCTAB *restrict const PT, proc_t *restrict cons if (flags & PROC_FILL_LXC) // value the lxc name p->lxcname = lxc_containers(path); + if (flags & PROC_FILL_LUID) // value the login user id + p->luid = login_uid(path); + if (rc == 0) return p; errno = ENOMEM; next_proc: @@ -1132,6 +1154,9 @@ static proc_t* simple_readtask(PROCTAB *restrict const PT, const proc_t *restric if (flags & PROC_FILL_LXC) t->lxcname = lxc_containers(path); + if (flags & PROC_FILL_LUID) + t->luid = login_uid(path); + if (rc == 0) return t; errno = ENOMEM; next_task: diff --git a/proc/readproc.h b/proc/readproc.h index 7fa09e84..a477570c 100644 --- a/proc/readproc.h +++ b/proc/readproc.h @@ -165,6 +165,8 @@ typedef struct proc_t { *sd_uunit; // n/a systemd user unit id char *lxcname; // n/a lxc container name + int + luid; // loginuid user id at login } proc_t; // PROCTAB: data structure holding the persistent information readproc needs @@ -223,6 +225,7 @@ typedef struct PROCTAB { #define PROC_FILLNS 0x8000 // fill in proc_t namespace information #define PROC_FILLSYSTEMD 0x80000 // fill in proc_t systemd information #define PROC_FILL_LXC 0x800000 // fill in proc_t lxcname, if possible +#define PROC_FILL_LUID 0x400000 // fill in proc_t luid (login user id) #define PROC_LOOSE_TASKS 0x2000 // treat threads as if they were processes