How to detect a user logged in through GUI in Linux

牧云@^-^@ 提交于 2019-12-14 03:55:42

问题


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.


回答1:


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)



回答2:


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.




回答3:


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. 
     ;
}



回答4:


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




回答5:


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.



来源:https://stackoverflow.com/questions/11467258/how-to-detect-a-user-logged-in-through-gui-in-linux

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!