login -f changing session getlogin(2)

classic Classic list List threaded Threaded
12 messages Options
Reply | Threaded
Open this post in threaded view
|

login -f changing session getlogin(2)

Bryan Drewery-6
This issue has bothered me forever.

As root running 'login -f someuser' and then exit, logname(1) and
getlogin(2) will forever return that user's name, rather than root.

The issue is that login(1) uses setlogin(2) without ever restoring the
login from the parent when it exits.

This is easily fixed by something like:

Index: usr.bin/login/login.c
===================================================================
--- usr.bin/login/login.c     (revision 288456)
+++ usr.bin/login/login.c     (working copy)
@@ -166,6 +166,7 @@
        gid_t egid;
        char *term;
        char *p, *ttyn;
+       char oldlogname[MAXLOGNAME];
        char tname[sizeof(_PATH_TTY) + 10];
        char *arg0;
        const char *tp;
@@ -545,6 +546,9 @@
        }
        pam_session_established = 1;

+       if (getlogin_r(oldlogname, sizeof(oldlogname)) != 0)
+               oldlogname[0] = '\0';
+
        /*
         * We must fork() before setuid() because we need to call
         * pam_close_session() as root.
@@ -567,6 +571,8 @@
                (void)sigprocmask(SIG_SETMASK, &omask, NULL);
                waitpid(pid, &status, 0);
                (void)sigprocmask(SIG_BLOCK, &mask, NULL);
+               if (oldlogname[0] != '\0')
+                       setlogin(oldlogname);
                bail(NO_SLEEP_EXIT, 0);
        }


I'm not sure this is the right way though.

My initial instinct was to use setsid(2) in the child but that clobbers
the terminal.

It makes me wonder if there's bigger architectural issues here that need
addressing with session and login. Perhaps login -f is just a special
case though.

Thanks,
Bryan Drewery


signature.asc (484 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: login -f changing session getlogin(2)

Jilles Tjoelker
On Thu, Oct 01, 2015 at 11:58:53AM -0700, Bryan Drewery wrote:
> This issue has bothered me forever.

> As root running 'login -f someuser' and then exit, logname(1) and
> getlogin(2) will forever return that user's name, rather than root.

> The issue is that login(1) uses setlogin(2) without ever restoring the
> login from the parent when it exits.

> This is easily fixed by something like:

> [snip]

> I'm not sure this is the right way though.

> My initial instinct was to use setsid(2) in the child but that clobbers
> the terminal.

> It makes me wonder if there's bigger architectural issues here that need
> addressing with session and login. Perhaps login -f is just a special
> case though.

I don't think login -f should be used like that. For that use case, su
-l looks more appropriate. In either case, the two login sessions are
strangely intertwined. Using ssh to localhost provides two normal login
sessions.

Resetting the login name also affects processes started by the logged in
user that still run (as long as they have not created a new session).
This may confuse applications and hinders traceability. This breakage
would also affect normal login sessions on terminals.

I think the supposed use case for login -f is a remote login daemon that
handles authentication by itself but wants to delegate account and
session functionality. Indeed, sshd has UseLogin, but it is rarely used
and discouraged.

--
Jilles Tjoelker
_______________________________________________
[hidden email] mailing list
https://lists.freebsd.org/mailman/listinfo/freebsd-arch
To unsubscribe, send any mail to "[hidden email]"
Reply | Threaded
Open this post in threaded view
|

Re: login -f changing session getlogin(2)

Garrett Wollman-7
In reply to this post by Bryan Drewery-6
In article <[hidden email]>, [hidden email] writes:

>I think the supposed use case for login -f is a remote login daemon that
>handles authentication by itself but wants to delegate account and
>session functionality. Indeed, sshd has UseLogin, but it is rarely used
>and discouraged.

Historically, as I remember it, "login" was a shell built-in that was
effectively an alias for "exec login".  It may still be that way in
antique csh.  The assumption from time immemorial is that if login
exits, the parent process will not distinguish it from any other
logout, so login is permitted to overwrite persistent session state.

-GAWollman
_______________________________________________
[hidden email] mailing list
https://lists.freebsd.org/mailman/listinfo/freebsd-arch
To unsubscribe, send any mail to "[hidden email]"
Reply | Threaded
Open this post in threaded view
|

Re: login -f changing session getlogin(2)

Bryan Drewery-6
In reply to this post by Jilles Tjoelker
On 10/1/2015 1:34 PM, Jilles Tjoelker wrote:

> On Thu, Oct 01, 2015 at 11:58:53AM -0700, Bryan Drewery wrote:
>> This issue has bothered me forever.
>
>> As root running 'login -f someuser' and then exit, logname(1) and
>> getlogin(2) will forever return that user's name, rather than root.
>
>> The issue is that login(1) uses setlogin(2) without ever restoring the
>> login from the parent when it exits.
>
>> This is easily fixed by something like:
>
>> [snip]
>
>> I'm not sure this is the right way though.
>
>> My initial instinct was to use setsid(2) in the child but that clobbers
>> the terminal.
>
>> It makes me wonder if there's bigger architectural issues here that need
>> addressing with session and login. Perhaps login -f is just a special
>> case though.
>
> I don't think login -f should be used like that. For that use case, su
> -l looks more appropriate. In either case, the two login sessions are
> strangely intertwined. Using ssh to localhost provides two normal login
> sessions.
>
> Resetting the login name also affects processes started by the logged in
> user that still run (as long as they have not created a new session).
> This may confuse applications and hinders traceability. This breakage
> would also affect normal login sessions on terminals.
>
> I think the supposed use case for login -f is a remote login daemon that
> handles authentication by itself but wants to delegate account and
> session functionality. Indeed, sshd has UseLogin, but it is rarely used
> and discouraged.
>
Well, none of that is documented or its use discouraged. It has been
quite surprising, for example, to find mails sent as the wrong user
weeks after doing a 'login -f' out of habit from root.

Can't we use something like forkpty(3) for the child to avoid the issues
you mention? It calls setsid(2) via login_tty(3).

And actually, 'su -l' NOT calling setlogin(2) is another surprise. I
have used 'login -f' precisely because it simulates a real login and
sets up the environment as the user. If I am dropping into a user's
shell I expect things like 'mail' to have their FROM not root or
wherever I came from in my session.

--
Regards,
Bryan Drewery


signature.asc (484 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: login -f changing session getlogin(2)

Simon J. Gerraty
Hi Bryan

> >> It makes me wonder if there's bigger architectural issues here that need
> >> addressing with session and login. Perhaps login -f is just a special
> >> case though.

As others have indicated your use of 'login -f' is "unexpected".

> Well, none of that is documented or its use discouraged. It has been

People document what they expect others need to know - and that is
framed by their own expectations of usage.
Thus lack of a documented admonition against every possible usage, does
not constitute a guarantee of support.

When eventually someone uses something in an "unexpected" way,
and encounters problems, there are basically three options.

1/ document that that should not be done, or that problems may arise

2/ prevent it being done

3/ make it work

> And actually, 'su -l' NOT calling setlogin(2) is another surprise. I
> have used 'login -f' precisely because it simulates a real login and
> sets up the environment as the user. If I am dropping into a user's
> shell I expect things like 'mail' to have their FROM not root or
> wherever I came from in my session.

Masquerading as another user to that extent, sounds somewhat disturbing
actually, and not something that should really be optimized for.

So I'd guess in this case that #1 is the correct option.
_______________________________________________
[hidden email] mailing list
https://lists.freebsd.org/mailman/listinfo/freebsd-arch
To unsubscribe, send any mail to "[hidden email]"
Reply | Threaded
Open this post in threaded view
|

Re: login -f changing session getlogin(2)

Bryan Drewery-6
On 10/3/2015 10:12 AM, Simon J. Gerraty wrote:

> Hi Bryan
>
>>>> It makes me wonder if there's bigger architectural issues here that need
>>>> addressing with session and login. Perhaps login -f is just a special
>>>> case though.
>
> As others have indicated your use of 'login -f' is "unexpected".
>
>> Well, none of that is documented or its use discouraged. It has been
>
> People document what they expect others need to know - and that is
> framed by their own expectations of usage.
> Thus lack of a documented admonition against every possible usage, does
> not constitute a guarantee of support.
>
> When eventually someone uses something in an "unexpected" way,
> and encounters problems, there are basically three options.
>
> 1/ document that that should not be done, or that problems may arise
>
> 2/ prevent it being done
>
> 3/ make it work
>
>> And actually, 'su -l' NOT calling setlogin(2) is another surprise. I
>> have used 'login -f' precisely because it simulates a real login and
>> sets up the environment as the user. If I am dropping into a user's
>> shell I expect things like 'mail' to have their FROM not root or
>> wherever I came from in my session.
>
> Masquerading as another user to that extent, sounds somewhat disturbing
> actually, and not something that should really be optimized for.
>
> So I'd guess in this case that #1 is the correct option.
>
This still ignores that 'su -l' does the opposite.

Sometimes sysadmins need to masquerade as users for support. Having a
user hand over their SSH password, or adding a password to a service
user that should NOT have remote access, is not the answer.  There needs
to be a way to login fully as a user for debugging issues as that user.

--
Regards,
Bryan Drewery


signature.asc (484 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: login -f changing session getlogin(2)

Simon J. Gerraty
Bryan Drewery <[hidden email]> wrote:
> This still ignores that 'su -l' does the opposite.

The opposite of what?
fwiw I'm not sure I'd want su - calling setlogin()
but then I'm never trying to really masquerade as someone else to the
extent that would matter.

> Sometimes sysadmins need to masquerade as users for support. Having a
> user hand over their SSH password, or adding a password to a service
> user that should NOT have remote access, is not the answer.  There needs
> to be a way to login fully as a user for debugging issues as that user.

There are many ways to skin that cat (eg append your pub key to their
.ssh/authorized_keys)
The easiest is to just use 'login -f' as you are doing, and when
finished logout completely.

I don't think anyone said you cannot use 'login -f',
just that your use isn't what it was intended for.

Adding a BUG/NOTE to the man page to warn anyone using it in this way
to fully logout afterwards is a simple "solution".
_______________________________________________
[hidden email] mailing list
https://lists.freebsd.org/mailman/listinfo/freebsd-arch
To unsubscribe, send any mail to "[hidden email]"
Reply | Threaded
Open this post in threaded view
|

Re: login -f changing session getlogin(2)

Bryan Drewery-6
On 10/3/2015 12:51 PM, Simon J. Gerraty wrote:
> Bryan Drewery <[hidden email]> wrote:
>> This still ignores that 'su -l' does the opposite.
>
> The opposite of what?
> fwiw I'm not sure I'd want su - calling setlogin()
> but then I'm never trying to really masquerade as someone else to the
> extent that would matter.

I said this in another mail. su -l does not change logname, so things
like 'mail' send the mail as 'root' rather than the user.

su.1 claims to set USER to the target user. It does, but lacking the
documentation for a kernel implementation detail of logname it does not
convey that setting USER is not the full story.

So both login and su have unexpected behavior no matter how you look at it.

>
>> Sometimes sysadmins need to masquerade as users for support. Having a
>> user hand over their SSH password, or adding a password to a service
>> user that should NOT have remote access, is not the answer.  There needs
>> to be a way to login fully as a user for debugging issues as that user.
>
> There are many ways to skin that cat (eg append your pub key to their
> .ssh/authorized_keys)
> The easiest is to just use 'login -f' as you are doing, and when
> finished logout completely.
Why does SSH need to even be involved here? This is what I mean by
bigger issues.

--
Regards,
Bryan Drewery


signature.asc (484 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: login -f changing session getlogin(2)

Jilles Tjoelker
In reply to this post by Bryan Drewery-6
On Thu, Oct 01, 2015 at 03:02:21PM -0700, Bryan Drewery wrote:
> Can't we use something like forkpty(3) for the child to avoid the issues
> you mention? It calls setsid(2) via login_tty(3).

This would make sense for a special impersonation tool or for a paranoid
version of su, but not for a normal login.

You can do this right now using script(1), for example
  script /dev/null login -f SOMEUSER

--
Jilles Tjoelker
_______________________________________________
[hidden email] mailing list
https://lists.freebsd.org/mailman/listinfo/freebsd-arch
To unsubscribe, send any mail to "[hidden email]"
Reply | Threaded
Open this post in threaded view
|

Re: login -f changing session getlogin(2)

Bryan Drewery-6
On 10/3/2015 2:08 PM, Jilles Tjoelker wrote:

> On Thu, Oct 01, 2015 at 03:02:21PM -0700, Bryan Drewery wrote:
>> Can't we use something like forkpty(3) for the child to avoid the issues
>> you mention? It calls setsid(2) via login_tty(3).
>
> This would make sense for a special impersonation tool or for a paranoid
> version of su, but not for a normal login.
>
> You can do this right now using script(1), for example
>   script /dev/null login -f SOMEUSER
>
Leaving this bug here in unacceptable to me. It is a clear POLA
violation and is sternly documented in setlogin(2) as the wrong thing to do.

There seems to be unwillingness to discuss actual potential fixes.

--
Regards,
Bryan Drewery


signature.asc (484 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: login -f changing session getlogin(2)

Bryan Drewery-6
In reply to this post by Garrett Wollman-7
On 10/1/2015 2:21 PM, Garrett Wollman wrote:

> In article <[hidden email]>, [hidden email] writes:
>
>> I think the supposed use case for login -f is a remote login daemon that
>> handles authentication by itself but wants to delegate account and
>> session functionality. Indeed, sshd has UseLogin, but it is rarely used
>> and discouraged.
>
> Historically, as I remember it, "login" was a shell built-in that was
> effectively an alias for "exec login".  It may still be that way in
> antique csh.  The assumption from time immemorial is that if login
> exits, the parent process will not distinguish it from any other
> logout, so login is permitted to overwrite persistent session state.
>
Yes, if 'login' always exited the parent too then it would not be a problem.

If we're making that assumption though then why do we so carefully
handle setting up the user context, uid and pam sessions in the child?

If 'login' should not be a user tool and we cannot fix this case then
perhaps it should move to /usr/libexec/login so it is not in the default
path where the user will be enticed to use it.

--
Regards,
Bryan Drewery


signature.asc (484 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: login -f changing session getlogin(2)

Jilles Tjoelker
On Wed, Oct 21, 2015 at 10:05:24AM -0700, Bryan Drewery wrote:
> On 10/1/2015 2:21 PM, Garrett Wollman wrote:
> > In article <[hidden email]>, [hidden email] writes:

> >> I think the supposed use case for login -f is a remote login daemon that
> >> handles authentication by itself but wants to delegate account and
> >> session functionality. Indeed, sshd has UseLogin, but it is rarely used
> >> and discouraged.

> > Historically, as I remember it, "login" was a shell built-in that was
> > effectively an alias for "exec login".  It may still be that way in
> > antique csh.  The assumption from time immemorial is that if login
> > exits, the parent process will not distinguish it from any other
> > logout, so login is permitted to overwrite persistent session state.

> Yes, if 'login' always exited the parent too then it would not be a problem.

> If we're making that assumption though then why do we so carefully
> handle setting up the user context, uid and pam sessions in the child?

The parent login(1) process needs to stay around with root privileges to
clean up PAM and update utmpx when the session ends. Traditionally, PAM
did not exist and utmpx logout updates (utmp/wtmp back then) were done
by init.

> If 'login' should not be a user tool and we cannot fix this case then
> perhaps it should move to /usr/libexec/login so it is not in the default
> path where the user will be enticed to use it.

As I said earlier in the thread, I don't think login(1) can be modified
to make this case work.

Removing its setuid bit would be a start but moving to libexec is the
logical conclusion.

I have seen terminal emulators run 'login -f $USER' on some systems but
likely not FreeBSD. This ensures utmpx is updated but also adds quite a
bit of baggage and reduces flexibility (cannot select a custom shell and
update utmpx). In FreeBSD, the setuid root /usr/libexec/ulog-helper
ensures utmpx can be updated flexibly.

--
Jilles Tjoelker
_______________________________________________
[hidden email] mailing list
https://lists.freebsd.org/mailman/listinfo/freebsd-arch
To unsubscribe, send any mail to "[hidden email]"