简体   繁体   English

C / Linux:如何在没有`getlogin`的情况下获取用户登录名

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

I need to retrieve the users username in a C program. 我需要在C程序中检索用户的用户名。 I know about getlogin and getlogin_r . 我知道getlogingetlogin_r But my program has a redirected stdin (because of some forks ). 但我的程序有一个重定向的标准输入(因为一些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. 请注意,glibc不遵循POSIX规范并使用stdin而不是/ dev / tty。 A bug. 一个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). (其他最新系统,如SunOS 5.8和HP-UX 11.11以及FreeBSD 4.8,都会在重定向stdin时返回登录名)。

Is there any other way I could retrieve the username? 有没有其他方法可以检索用户名?

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. 使用getresuid(2)或一些更具体的id检索函数来获取你想要的id(真实,有效或保存集)(你可能想要RUID,如果你想模仿getlogin ,在这种情况下你可以简单地调用getuid并忘记有效和保存集的uid),然后使用getpwuid(3)或其可重入的对应方将其转换为用户id字符串。

getenv("USER") might give you the same result, but you can't rely on it if you want real security. getenv("USER")可能会给你相同的结果,但如果你想要真正的安全性,就不能依赖它。

Technically, all these may be different from the result obtained by getlogin when stdin is your controlling terminal. 从技术上讲,当stdin是您的控制终端时,所有这些可能与getlogin获得的结果不同。 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: 如果你真的需要和getlogin一样的答案,你可以暂时让你的fd 0指向你的控制终端,然后调用getlogin ,然后恢复你的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*/;

You can retrieve the id user with getuid and then call getpwuid_r to find out the username the corresponds to that id. 您可以使用getuid检索id用户,然后调用getpwuid_r以找出与该id对应的用户名。

Edit : Oops, I meant to say getpwuid_r instead of getpwent_r as correctly @PSkocik pointed out. 编辑 :哎呀,我的意思是说getpwuid_r而不是getpwent_r正如@PSkocik指出的那样。

If you're OK with possible mis-identifications (multiple logins tied to the same UID), you can use getuid(2) or getresuid(2) to get the UID, then use getpwuid(3) to get the name (or, in the case of multiple usernames with the same UID, one of the names, the documentation is not clear on if this is a random name, the first encountered in the file, ...). 如果您对可能的错误标识(多个登录绑定到相同的UID)没问题,可以使用getuid(2)getresuid(2)来获取UID,然后使用getpwuid(3)获取名称(或者,如果多个用户名具有相同的UID,其中一个名称,则文档不清楚这是否是随机名称,第一个在文件中遇到,...)。

This does not rely on any specific file descriptor pointing at the logged-in terminal, nor does it rely on utmp records, but it does rely on the UID being present in /etc/passwd and MAY not identify the correct login name used, in the presence of multiple logins tied to the same UID (although that should be infrequent enough to not be an actual concern). 这不依赖于指向登录终端的任何特定文件描述符,也不依赖于utmp记录,但它确实依赖于/ etc / passwd中存在的UID,并且可能无法识别所使用的正确登录名,多个登录的存在与同一个UID相关联(尽管这种情况应该很少,不足以成为实际问题)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM