C / Linux: how to get username without getlogin

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

The problem I am facing is listed in the man page:

Note that glibc does not comply with the POSIX specification and uses stdin instead of / dev / tty. Bug. (Other recent systems such as 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 to get the username?

+6
source share
3 answers

Use getresuid (2) or some of the more specific id lookup functions to get the desired identifier (real, effective, or saved) set) (you probably want a RUID if you want to emulate getlogin , in which case you can just call getuid and forget about the efficient and saved uid), and then use getpwuid (3) or its repeated instance to translate this value into the user identifier string.

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

Technically, all of them may differ from the result obtained by getlogin when stdin is your control terminal. If you really need the same answer as getlogin for you, you can temporarily direct your fd 0 to your control terminal, 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 controlling terminal*/ if(0>open("/dev/tty", O_RDONLY)) /*handle error*/; /* getlogin() .. */ /*restore saved_fd0*/ if(0>dup2(saved_fd0, 0)) /*handle error*/; 
+6
source

You can get the user ID using getuid and then call getpwuid_r to find out that the username matches this id.

Change Unfortunately, I wanted to say getpwuid_r instead of getpwent_r , as @PSkocik pointed out.

+5
source

If everything is okay with possible invalid identifiers (multiple logins tied to the same UID), you can use getuid(2) or getresuid(2) to get the UID, and then use getpwuid(3) to get the name ( or, in the case of several user names with the same UID, one of the names, the documentation is fuzzy, if it is a random name, the first one appears in the file, ...).

It does not depend on any particular file descriptor pointing to the connected terminal, and does not rely on utmp entries, but it relies on the UID present in / etc / passwd, and CANNOT determine the correct login name if there are several logins associated with it to the same UID (although this should be infrequent so as not to be a real problem).

+2
source

All Articles