getpwuid vs. getpwnam

John Cecere John.Cecere at Sun.COM
Wed Dec 1 08:43:04 EST 2004


Ben Lindstrom wrote:

>On Tue, 30 Nov 2004, John Cecere wrote:
>
>  
>
>>This issue has probably been brought up before, but I'll mention it anyway.
>>
>>I just downloaded and built openssh 3.9p1 on Solaris 8. In my
>>environment, I have two root accounts. The normal one and an alternate
>>one (rjohn - uid 0) with it's own home directory (/export/home/rjohn).
>>After building and installing openssh, I was having trouble getting my
>>RSA authentication to work. In investigating it, I noticed that it was
>>attempting to use /.ssh/id_rsa.pub as my public key file instead of
>>/export/home/rjohn/.ssh/id_rsa.pub.  Digging a little deeper, I found
>>that, in the client modules ssh.c and tildexpand.c, it uses the call
>>getpwuid(uid) as the basis for determining what the user's home
>>directory is. In my case, this resolves to / instead of /export/home/rjohn.
>>
>>Wouldn't it be more appropriate to use something like
>>getpwnam(getenv("LOGNAME")) instead ? Since the login program itself (in
>>both Linux and Solaris) sets LOGNAME, it's a reasonably safe assumption
>>that it will get set correctly. Even if it's not set, the program could
>>    
>>
>
>We don't call /sbin/login by default.  Therefor who would set it?
>
> - Ben
>
>  
>
Ben,

It appears that it's getting set by sshd. I ran a debug session on the 
server, and this is what the client tells me:

scoobydoo# ssh -l rjohn saturn
Last login: Tue Nov 30 16:18:14 2004 from scoobydoo
pw->pw_name = rjohn
Environment:
  USER=rjohn
  LOGNAME=rjohn
  HOME=/export/home/rjohn
  PATH=/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin
  MAIL=/var/mail//rjohn
  SHELL=/bin/ksh
  TZ=US/Eastern
  SSH_CLIENT=129.154.57.77 1023 22
  SSH_CONNECTION=129.154.57.77 1023 129.154.57.49 22
  SSH_TTY=/dev/pts/2
  TERM=xterm
Sun Microsystems Inc.   SunOS 5.8       Generic Patch   October 2001
saturn#


I don't have UseLogin set in my config file here. It looks like the 
chunk of code below from session.c is setting LOGNAME. However, I'm not 
sure that this is totally related to what I'm talking about. I put a 
printf right before the line that references LOGNAME below (notice the 
line above that reads pw->pw_name = rjohn). The way it derives 
pw->pw_name below (session.c is a module of the server, not the client) 
seems to be different than the way it's derived from the client to 
determine what the user's home directory is for parsing the .ssh directory.

I haven't traced back where the *pw structure is getting set for this 
module, but I'm going to guess that it wasn't a call to getpwuid

        if (!options.use_login) {
                /* Set basic environment. */
                for (i = 0; i < s->num_env; i++)
                        child_set_env(&env, &envsize, s->env[i].name,
                            s->env[i].val);

                child_set_env(&env, &envsize, "USER", pw->pw_name);
                child_set_env(&env, &envsize, "LOGNAME", pw->pw_name);
#ifdef _AIX
                child_set_env(&env, &envsize, "LOGIN", pw->pw_name);
#endif
                child_set_env(&env, &envsize, "HOME", pw->pw_dir);
#ifdef HAVE_LOGIN_CAP
                if (setusercontext(lc, pw, pw->pw_uid, LOGIN_SETPATH) < 0)
                        child_set_env(&env, &envsize, "PATH", 
_PATH_STDPATH);
                else
                        child_set_env(&env, &envsize, "PATH", 
getenv("PATH"));
#else /* HAVE_LOGIN_CAP */
# ifndef HAVE_CYGWIN
                /*
                 * There's no standard path on Windows. The path contains
                 * important components pointing to the system directories,
                 * needed for loading shared libraries. So the path better
                 * remains intact here.
                 */
#  ifdef HAVE_ETC_DEFAULT_LOGIN
                read_etc_default_login(&env, &envsize, pw->pw_uid);
                path = child_get_env(env, "PATH");
#  endif /* HAVE_ETC_DEFAULT_LOGIN */
                if (path == NULL || *path == '\0') {
                        child_set_env(&env, &envsize, "PATH",
                            s->pw->pw_uid == 0 ?
                                SUPERUSER_PATH : _PATH_STDPATH);
                }

Thanks,
John

-- 
John Cecere
Sun Microsystems
732-302-3922 / john.cecere at sun.com




More information about the openssh-unix-dev mailing list