[systemd-devel] [HACK/RFC/PATCH] systemd-su: "su" on steroids

David Herrmann dh.herrmann at gmail.com
Thu Dec 12 07:16:37 PST 2013


Hi

On Thu, Dec 12, 2013 at 3:55 PM, Lennart Poettering
<lennart at poettering.net> wrote:
> On Wed, 11.12.13 15:57, David Herrmann (dh.herrmann at gmail.com) wrote:
>
>>
>> Hey
>>
>> On Wed, Dec 11, 2013 at 3:27 PM, Lennart Poettering
>> <lennart at poettering.net> wrote:
>> > On Wed, 11.12.13 13:54, David Herrmann (dh.herrmann at gmail.com) wrote:
>> >
>> >>
>> >> Hi
>> >>
>> >> On Wed, Dec 11, 2013 at 12:18 AM, Lennart Poettering
>> >> <lennart at poettering.net> wrote:
>> >> > On Mon, 02.12.13 21:47, David Herrmann (dh.herrmann at gmail.com) wrote:
>> >> >
>> >> >>
>> >> >> 4h later, I present "systemd-su":
>> >> >>
>> >> >> If you want to give it a try, run:
>> >> >>   systemd-su -u david /bin/sh
>> >> >>
>> >> >> It requires the systemd-suexec helper internally, so if you didn't install
>> >> >> it, use something like this:
>> >> >>   SYSTEMD_SUEXEC=/home/david/dev/systemd/systemd-suexec ./systemd-su -u david sh
>> >> >> Otherwise, systemd-su cannot find the systemd-suexec binary.
>> >> >
>> >> > Hmm, if we allow that "su -" tells logind to create an entirely new
>> >> > session even when called from an existing one, do we still need
>> >> > "systemd-su"? That should be pretty close, no? That sounds easier to
>> >> > do...
>> >>
>> >> You cannot start a session from within an existing session. At least
>> >> if audit-loginids are immutable, this also means the audit-sessionid
>> >> is immutable (as the session ID is updated if, and only if, the
>> >> logind-uid changes).
>> >>
>> >> Of course, immutable audit IDs are a somewhat controversial feature
>> >> (and afaik don't work with containers?) but I still dislike the idea
>> >> of starting sessions from within an existing session. It's ugly and we
>> >> don't actually need it, do we? Currently su/sudo don't start new
>> >> sessions and I think that is fine. Imho, their intention is to change
>> >> the EUID, not to spawn a new session.
>> >>
>> >> So my hack here is just some example to play with, not something for
>> >> real to replace su/sudo.
>> >
>> > The new switch I was suggesting for pam_systemd ("force-new-session=1")
>> > would cause a new session to be started from within an existing one, in
>> > that case decoupling the session id from the audit id. Hence, when you
>> > first log into a computer you will get a session with a session ID
>> > identical to the audit id. However if you use "su -" which then does
>> > force-new-session=1 on pam_system you will get a new session that gets
>> > an independent id, that is decoupled from the audi session, and to avoid
>> > namespace clashes is prefixed with a lower-case "c". We'd only do that
>> > for "su -"/"sudo -i", not for "su", "su -".
>>
>> Yeah, I understand that and our code already does that, except for
>> CreateSession() which always tries to pick up existing sessions. My
>> question rather is: why would anyone want "su --login" to start a new
>> session? Yeah, it's needed to set env-variables correctly on
>> uid-change or set other things. But I've never seen a use-case where
>> someone really wants a new session. Imho, su/sudo is exclusively used
>> to change euids.
>
> Well, people do find it useful to quickly change identities. I use it
> like that all the time too actually. It's a bit like ssh'ing to the
> localhost, except that it doesn't require IP. And I am pretty sure that
> we should support it like that. For example, I make use of it all the
> time in containers, where nspawn just gives me a single console where I
> scan log in once. If I quickly need to change identity, then "su -" and
> "sudo -l" are certainly quicker then to open another window and use "ss"
> or "machinectl login" to get a second login....

Ok.

>> > "su -" and "sudo -i" would hence do the "greatest possible"
>> > disconnection from the originating session. (switch everything possible
>> > except the tty itself)
>>
>> There is actually one thing, that you *cannot* share between
>> legacy/unix sessions, which is the CTTY. Only one SID can be assigned
>> a given TTY as CTTY. We can avoid the setsid() call, obviously, but
>> that seriously questions the idea why a new session is needed. Again,
>> if you want to share the CTTY (which su/sudo usually do), it seems
>> weird to not share the session.
>
> Well, but su/sudo give up the ctty while the transition is being done,
> and takes it back afterwards...

Are you sure? Last time I checked, su/sudo keep the CTTY the whole
time or drop it entirely. Thing is, as long as your bash keeps the
CTTY, no other process can call TIOCSCTTY() (only the session leader
can do that), so once su/sudo drop the CTTY, they cannot reacquire it.
Unless you force the TIOCSCTTY call after setsid().. but that causes
the parent bash and all other processes in its session to loose the
CTTY.
Note, even if you call TIOCSCTTY in the parent bash, after su/sudo
returns, you only set the CTTY for bash, not for the other processes
in the process-group.

But as long as you don't call setsid() and don't drop the CTTY, you're
fine. But you will run under the parent-bash session. So if we don't
care for UNIX SIDs, we can share CTTYs across sessions.

David


More information about the systemd-devel mailing list