Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I think the previous iteration of this question was a little bit like a carpet bomb of questions, so that may have turned people off to it (to the point of almost being flagged for removal) so I'll start a new one that hopefully people can have an easier time with.

Basically, my overall interest is in understanding logname and getlogin() as it relates to audit trails. It breaks down like this:

1) My understanding is that logname and getlogin() both display the auid that would/will end up showing in the session's audit logs. Is that correct? I know auid is an immutable process attribute, but I was interested in knowing whether the two are necessarily the same or just usually the same. This would help me with writing scripts/helper programs that can make access control decisions based on the user's original identity, rather than just who they happen to be at the moment or a mutable environmental variable.

2) I still don't understand how the exploit of CVE 2003-0388 being shown was supposed to work. If someone could explain that to me, it would be great.

My primary interest is with point #1, though.

share|improve this question
2  
I don't even know what an auid is, but logname and getlogin() get the username from utmp by cross-referencing to the current tty, don't they? For that reason they're not secure. –  Celada Jun 4 '13 at 18:33
    
auid is a process attribute that's used in audit forensics for when you want to match a particular session ID to particular username. The logname utility uses getlogin() and looking at the man page for getlogin I am now starting to see utmp so that's a good catch on that one. Since utmp is only writable by root, it's still somewhat secure but I was really interested in getting auid directly so I can depend on immutable kernel structures than writable files. If you come across anything like that, post it as an answer so I can accept it. –  Joel Davis Jun 4 '13 at 18:54
    
@Celada, I've found my ultimate answer, but you've answered the question that was posed, so can you submit it as such so I can accept it? –  Joel Davis Jun 4 '13 at 19:18
add comment

2 Answers 2

up vote 3 down vote accepted

getlogin() and logname (which just calls getlogin()) obtain the logged-in username by looking up the current tty in utmp and reporting the login name found in that utmp record. The reason they do that is that they are designed to work on systems where multiple usernames might map to the same uid (a practice generally frowned upon but sometimes used to create multiple root accounts or different login names that start custom shells but all map to the same underlying uid). When used with such accounts, getpwuid(getuid()) will only report the first match from the passwd database, whereas getlogin() will find the one that was actually used to log in.

However, because this function relies on the contents of a writable file, it is not worthy of the same level of trust as getpwuid(getuid()). It's true that only privileged processes should be able to write utmp, but there are a few "extra" programs that are often configured to be able to write it (generally by being setgid-utmp) like GNU screen and you might not want to trust those. I know that historically on some SysV systems I used to manage, utmp was prone to get corrupted occasionally.

share|improve this answer
add comment

As @Celada pointed out, both logname and getlogin() depend on /var/run/utmp, which puts them at mid-level trustworthiness (it's a regular file instead of something that necessarily gets regenerated with reboots, unlike kernel structures, so there's a slight possibility of contamination if they can boot from CD or something, then again what couldn't they compromise if they did that?). There is hope hiding in plain sight though. I had been intentionally ignoring /proc/$$/loginuid up to this point because it was owned by the invoking user and the writable bit was set for owner, so I figured it was mostly just a convenience and not a security mechanism. It appears this assumption was incorrect. Here is the descriptive text for a kernel patch submitted towards the end of 2011:

At the moment we allow tasks to set their loginuid if they have CAP_AUDIT_CONTROL. In reality we want tasks to set the loginuid when they log in and it be impossible to ever reset. We had to make it mutable even after it was once set (with the CAP) because on update and admin might have to restart sshd. Now sshd would get his loginuid and the next user which logged in using ssh would not be able to set his loginuid.

Systemd has changed how userspace works and allowed us to make the kernel work the way it should. With systemd users (even admins) are not supposed to restart services directly. The system will restart the service for them. Thus since systemd is going to loginuid==-1, sshd would get -1, and sshd would be allowed to set a new loginuid without special permissions.

If an admin in this system were to manually start an sshd he is inserting himself into the system chain of trust and thus, logically, it's his loginuid that should be used!

So is it listed as writable by the user? Yes. Can the user actually change it? Only if they're root or have CAP_AUDIT_CONTROL (which is probably not a lot of people). The most secure solution I can find is to actually pull this from /proc/$$/loginuid (if writing a shell script or on the command line) or audit_getloginuid() from a program.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.