Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 5 Sep 2002 12:13:52 +0100
From:      Matthew Seaman <m.seaman@infracaninophile.co.uk>
To:        Ruben de Groot <fbsd-q@bzerk.org>
Cc:        "Brian T. Schellenberger" <bts@babbleon.org>, freebsd-questions@FreeBSD.ORG
Subject:   Re: passwd: Permission denied
Message-ID:  <20020905111352.GA32849@happy-idiot-talk.infracaninophi>
In-Reply-To: <20020905073321.GA65524@ei.bzerk.org>
References:  <200209041755.24531.bts@babbleon.org> <20020904231555.GC28529@happy-idiot-talk.infracaninophi> <200209042156.04364.bts@babbleon.org> <20020905073321.GA65524@ei.bzerk.org>

next in thread | previous in thread | raw e-mail | index | archive | help
On Thu, Sep 05, 2002 at 09:33:21AM +0200, Ruben de Groot wrote:
> On Wed, Sep 04, 2002 at 09:56:03PM -0400, Brian T. Schellenberger typed:

> > I was trying to change the password from an xterm where I had done an
> > 
> > su - baduser
> > 
> > to change to the userid.  I thought that with the - option su acted 
> > "just like" a login, but I was wrong.  When I actually logged in from a 
> > console window, it worked just fine.
> > 
> > Live and learn.
> > 
> > Does anybody know how su - differs from a "real" login, exactly?
> 
> It's a matter of real and effective user id. Use
> su - baduser
> passwd baduser
> to change this user's password, or just passwd baduser (as root).

Well, sort of.  Once you've su'd to another user, usually both the
real and effective UIDs are set to the new user.

Then running a setuid root program like passwd will set the euid to
root.  That's equivalent to the situation you'ld have by logging in
directly as the new user.

However, what was biting Brian is that passwd(1) without arguments
uses getlogin() as the default username to change the password for:

(snipped from /usr/src/usr.bin/passwd/passwd.c)

        if ((uname = getlogin()) == NULL)
                err(1, "getlogin");

        switch(argc) {
        case 0:
                break;
        case 1:
                uname = argv[0];
                break;
        default:
                usage();
        }

and then later it tests that either the real user is root (uid 0) or that
the UID associated with username is the same as the real UID of the
process:

(snipped from /usr/src/usr.bin/passwd/local_passwd.c)

        if (!(pw = getpwnam(uname)))
                errx(1, "unknown user %s", uname);

[...]

        uid = getuid();
        if (uid && uid != pw->pw_uid)
                errx(1, "%s", strerror(EACCES));

The problem Brian saw then arose because getlogin() is unaffected by su:

(getlogin(2) man page)

     The getlogin() routine returns the login name of the user associated with
     the current session, as previously set by setlogin().  The name is nor-
     mally associated with a login shell at the time a session is created, and
     is inherited by all processes descended from the login shell.  (This is
     true even if some of those processes assume another user ID, for example
     when su(1) is used).

So, passwd(1) would always work for root, but after su(1) it still
defaults to changing the password of the original user.  For ordinary
users, after su(1) the same applies, but ordinary users aren't
permitted to change each others' passwords.  The trick is to get into
the habit of always specifying the username when you run passwd(1).

	Cheers,

	Matthew


-- 
Dr Matthew J Seaman MA, D.Phil.                       26 The Paddocks
                                                      Savill Way
                                                      Marlow
Tel: +44 1628 476614                                  Bucks., SL7 1TH UK

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-questions" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20020905111352.GA32849>