Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C/Linux: How to get users login name without `getlogin`

Tags:

c

linux

I need to retrieve the users username in a C program. I know about getlogin and getlogin_r. But my program has a redirected stdin (because of some forks).

The Problem I face is stated in the manpage:

Note that glibc does not follow the POSIX specification and uses stdin instead of /dev/tty. A bug. (Other recent systems, like SunOS 5.8 and HP-UX 11.11 and FreeBSD 4.8 all return the login name also when stdin is redirected).

Is there any other way I could retrieve the username?

like image 654
Nidhoegger Avatar asked Sep 02 '16 12:09

Nidhoegger


2 Answers

Use getresuid(2) or some of the more specific id retrieval functions to get the id you want (real, effective, or saved-set) (you probably want RUID, if you want to emulate getlogin, in which case you can simply call getuid and forget about the effective and saved-set uid), and then use getpwuid(3) or its reentrant counterpart to translate that to a user id string.

getenv("USER") might give you the same result, but you can't rely on it if you want real security.

Technically, all these may be different from the result obtained by getlogin when stdin is your controlling terminal. If you really need the same answer as what getlogin would get you, you can temporarily make your fd 0 point to your controlling terminal again, then call getlogin, and then restore your fd 0:

int saved_fd0;
if(0>(saved_fd0 = dup(0))
       /*handle error*/;
close(0);

/*open always gets the lowest possible fd number == now 0*/
/*"/dev/tty" is always your current processes's controlling terminal*/
if(0>open("/dev/tty", O_RDONLY))
    /*handle error*/;
/*
getlogin()
..
*/
/*restore saved_fd0*/
if(0>dup2(saved_fd0, 0))
       /*handle error*/;
like image 68
PSkocik Avatar answered Sep 24 '22 07:09

PSkocik


You can retrieve the id user with getuid and then call getpwuid_r to find out the username the corresponds to that id.

Edit: Oops, I meant to say getpwuid_r instead of getpwent_r as correctly @PSkocik pointed out.

like image 30
redneb Avatar answered Sep 23 '22 07:09

redneb