Uniquely identifying a user: is it possible?

Thad P Floryan thad at cup.portal.com
Tue Jan 9 03:35:11 AEST 1990


Recently there have been 3 different programs posted which, among other things,
report the last-login date-and-time of a user on a SystemV system:

Greg Woods' lastlog (in alt.sources),
Lenny Tropiano's logininit 2.1 (in comp.sys.att and unix-pc.sources), and
my lastlogin 1.0 (in comp.sys.att and unix-pc.sources).

Each program uses different strategies, and each has a related problem!

If it could be GUARANTEED that any of the programs above would ONLY be
invoked from one's .profile, then they DO work.  But ...

As one is on-line for awhile, circumstances change, and conditions may cause
the programs to fail.  I'm not talking about just the situation where one user
may have multiple simultaneous sessions whose "last logins" affect the results.
No.  Something much more fundamental:

	Failure to UNIQUELY identify the user.

Greg's and Lenny's programs, when this happens, essentially report the failure
with a message similar to "cannot locate utmp entry for tty"; my program fails
by reporting the information for root and alters the non-root user's file with
root's last login date&time.

(Well, whaddya expect for a free program and a 1 pico Second warranty?  :-)

So, what is the source of these failures?  After some experimentation:

1)	using getuid(), or
2)	assuming the user HAS a controlling terminal.
	^^^^^^^^
(There's THAT word again; Benny Hill's probably laughing his head off! :-)

So, how are these failures invoked?

1)	"su", or
2)	redirecting stdin, stdout AND stderr (by whatever means).

I put together a "test" program that exercises the causes and displays the
symptoms of the failures.  The program is ugly as sin as it was pieced together
as I was flipping through all the SysV docs.  If anyone's interested I could
email a copy; the source is only 3K and is uncommented though its output is
nicely formatted.

>From my experiments and reading the docs, it appears that the ONLY parameter
one can get with 100% certainty in these regards is the login name of the user.

It does NOT "appear" possible to always identify the specific "terminal" of the
user so as to match the entry(ies) in the /etc/utmp file ... unless, perhaps,
one uses nlist() on /unix and starts peeking through system memory, which is
beyond the capabilities of any program(s) that may be developed by the "normal"
user.

It also appears the only things that "could" be matched in the /etc/utmp file
(using "normally" available information) are the user's login name and the
controlling terminal; all this using the getutent(), getutid() or getutline().

The writeup of getlogin(3C) claims the correct way to determine the login name
is to use cuserid(3S); or getlogin(3C) (if getlogin() fails then getpwuid(),
and if getpwuid() fails (re: getuid()), then one is SOL.)

If one is su'd to root or another user, getuid() does NOT return your UID,
but, instead, that of the user to which you've su'd.

If stdin, stdout and stderr are ALL redirected (e.g." < infil > outfil 2>&1 " )
then ttyslot(3C) and ttyname(3C) both fail if none of the file descriptors
reference a terminal (such as is the case during "total" redirection).

I've also discovered that a portion of the docs for ttyslot(3C) is WRONG
regarding returned value, because a returned value of 0 is a valid "index"
into /etc/utmp.  The value that it DOES return on failure, as shown by
running my test program under one of the failure-mode conditions, is -1.

And before you say "Aw, just some more piddling UNIXPC-specific problems",
let it be known I've tested the program on several implementations of SysV
on AT&T machines and two different implementations of HP-UX; same problem
on all systems to which I have access.  A friend is checking this out for
me on an Amdahl UTS machine as I'm writing this, but I believe she'll find
the same problem (she's also checking out the HDB Dialers & Devices stuff :-)

A simple demonstration of the problem using who(1):

	$ who am i
	thad       p0           Jan  7 16:21
	$ ls -l fish
	-rw-r--r--  1 thad    users         0 Jan  7 18:34 fish
	$ cat fish
	$ who am i < fish > crap 2>&1
	$ cat crap
  ===>	process not attached to terminal
	Usage:	who [-rbtpludAasT] [am i] [utmp_like_file]
	... help output deleted ...

Aha!  Just received a call back from my friend at Amdahl (she works on the
UTS kernel software (SysV-derived)) and:

1)	$ who am i < fish > crap 2>&1
	$ cat crap
  ===>	You must have a terminal attached.

2)	The Dialers and Devices require the same "\M", "\m" and ",M" as do
	the systems we've recently been discussing in another message thread
	and for the same reasons.  Sheesh, a wide-spread problem & "solution".

Pardon the use of "cat crap" in the above example, but my friend has two cats
and she thought it was hilarious!  Then she zingered me with: Amdahl is now
producing their UNIX 7300 systems, running the UTS kernel.  Now I wonder where
they got THAT number ^^^^ ?!?!  :-)

In any event, what this all boils down to is the "simple" question:

  ===>	Is there a way to 100% positively, absolutely, unequivocally,   <===
  ===>	unerringly identify the current login user's /etc/utmp session  <===
  ===>	record under ALL conditions of su'iness and output redirection  <===
  ===>	and multiple simultaneous logins?                               <===

That identification of the login user's record:

1) MUST succeed even if there are multiple same-user sessions online (meaning
   logging in twice from two different terminals),
2) MUST succeed even if the user is su'd, and
3) MUST succeed even if all standard streams are re-directed.

Sounds simple, no?  I've gone through every page of all xxx(2*) and xxx(3*)
man pages looking for an answer and nothing is apparent.

If you have an answer to that "simple" question, that runs non-privileged
(heck, even privileged (at this stage of the game)), I'm sure that enquiring
minds would like to know.

Thad Floryan [ thad at cup.portal.com (OR) ..!sun!portal!cup.portal.com!thad ]



More information about the Comp.sys.att mailing list