How to detect a user logged in through GUI in Linux
Asked Answered
W

6

2

I would like to capture the user name logged in through GUI in my program. My program is running as a daemon from root login. If a non root user logs in through GUI my program should be notified. I am pasting my current program which calls a perl script making use of system call to check who is the current user logged in. I am pasting my perl script too for reference.

#include <X11/Xlib.h>
#include <X11/Xos.h>
#include <X11/Xfuncs.h>
#include <X11/Xutil.h>
#include <X11/Xatom.h>
int main()
{
    char *user;
    char buf[1024];
    int fd, ret;
    fd = open("/tmp/log", O_TRUNC|O_RDWR|O_CREAT);
    if (!fd) {
        printf("Error opening file\n");
        exit(1);
    }
    chmod("/tmp/log", S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IWGRP | S_IXGRP
            | S_IROTH | S_IWOTH | S_IXOTH);
    daemon(0, 0);
    while (1) {
        system("perl /home/curr-usr.pl");
        sleep(5);
    } 
    return 0;
}

The perl script which is used to get the current user logged in.

#!/usr/bin/perl
my $result;
$result = `whoami`;
open FH, "+>>", "/tmp/log" or die $!;
print FH "$result ";
close (FH);

In the c program above I am calling the perl script in a while loop every 5 seconds. The perl script makes use of the command "whoami" to get the current user logged in & dumps it into the /tmp/log file.

What I want to achieve is if user1 logs in the perl script should give me the current user to be user1. Instead the perl script gives me root as the current user irrespective of the user I am logged in through GUI as I am running the C program & perl script with root user.

Could anyone please advise me with a mechanism by which the C program could get to know the current user logged in through GUI ? Any help is greatly appreciated.

Wilhelmina answered 13/7, 2012 at 8:58 Comment(2)
I'm not sure you wanna extract login info from the X11 subsystem... Why not use e. g. some of the Linux API to detect user logins?Ectoderm
What I actually want is to have a mapping of X Window & user currently logged in. How could we use Linux API's to detect User logins when we are running the program in one user continuously as my requirement is to get all the users logged in to the system after I start my program. ThanksWilhelmina
R
7

You can detect the user using the main display like this:

#!/bin/bash

#Detect the name of the display in use
display=":$(ls /tmp/.X11-unix/* | sed 's#/tmp/.X11-unix/X##' | head -n 1)"

#Detect the user using such display
user=$(who | grep '('$display')' | awk '{print $1}')

#Detect the id of the user
uid=$(id -u $user)
Rubiaceous answered 27/10, 2016 at 15:28 Comment(1)
For me on Ubuntu 22.04, this does not work. It gets the wrong display when several users are logged in and switch user has been used. The /tmp/.X11-unix/ directory only contains a list of displays but does not seem to have any further information which can be used to determine the one currently in use since it's not necessarily the newest entry when switch user has been used.Salacious
A
2

I am using XFCE4 and LXDM. "who" and "users" report only users that are logged on a terminal. GUI logon is not reported as Nominal Animal pointed out (Thanks!). I use "pgrep xfce" to check if XFCE4 is running. Following prints out current xfce-user:

#!/usr/bin/perl

# Get all processes
my @xfce_processes = `pgrep xfce`;

# If processes exist, get user of first process in list.
if(scalar  @xfce_processes) {
    print `ps -o user h $xfce_processes[0]`;
}
else
{
# No xfce processes. 
     ;
}
Ayer answered 16/4, 2013 at 14:7 Comment(1)
What if there are more than one XFCE session going on? For instance, if people use "Switch user" to allow multiple gui logons. How would I get the current user? This pertains to my so question here: #17997207Linnealinnean
A
1

As you mentioned your program runs as a daemon. Consequently any process it spawns would be run as the same user as one that started that daemon. The user that logs in via UI (or any other method) would never be the user you can get by calling whoami from your daemon.

Instead what you should do is explicitly notify your daemon of a login event or, if that is not an option, keep a list of all the logged-in sessions currently running on the box and see if new sessions appear - that would be a session of a newly logged-in user.

Almandine answered 13/7, 2012 at 9:4 Comment(0)
B
0

The programms who and users get their information from the file /var/run/utmp.

The file contains N entries of the size of "struct utmp", defined in <utmp.h> You are interested in the USER_PROCESS type entries. The host field contains the display.

Note that there are multiple entries for the same display if the user opened some terminal emulations (xterm, konsole...).

You could monitor this file or /var/log/wtmp for a history

struct utmp ut_entry;
FILE    *fp = fopen(UTMP_FILE, "r");

if( !fp )
{
  printf("Could not open utmp file!");
  return;
}

while(fread(&ut_entry, sizeof(struct utmp), 1, fp) == 1)
{
    if(ut_entry.ut_type != USER_PROCESS)
        continue;

    // string entries are not 0 terminated if too long...
    // copy user name to make sure it is 0 terminated

    char tmpUser[UT_NAMESIZE+1] = {0};
    strncpy(tmpUser, ut_entry.ut_user, UT_NAMESIZE);

    // do more stuff... read the display from ut_entry.host
}

For more information see the utmp manual page

Bibliogony answered 2/10, 2012 at 18:33 Comment(1)
In some cases the login manager may not keep the utmp records up to date. I saw this for example on XFCE4, on Ubuntu 11.04. If that is an issue, user1439609 may have to change the problem into "Detect all users active on this machine"; solved simply by scanning the /proc/PID/ directories (using opendir(), readdir(), stat()) to see which user accounts have running processes, and ignoring system (known non-human) users.Ummersen
D
0

You probably want to investigate either ConsoleKit or its newer incarnation loginctl.

These tools are specifically designed for managing seats and sessions, while maintaining distinction between local text console, GUI and remote sessions. They are not guaranteed to be present on every X11 machine, but if yours is relatively recent, chances are it uses either one or the other tool.

Dhole answered 18/4, 2013 at 14:53 Comment(1)
Too bad loginctl uses systemd which is not too widely used among distros. Otherwise it looks as if it is an excellent fit for my question #17997207Linnealinnean
L
0

For anyone else coming here for xfce4, what I had to do was run ps -aux | grep xfce4 then there was a line:

root 2497 0.0 0.3 323052 13408 ? Sl 01:24 0:00 xfce4-session

I run kill -9 2497 and that got rid of it. For me this was a hung instance I wanted to kill from SSH.

Loudmouthed answered 25/6, 2020 at 1:43 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.