[SSSD] Design discussion: SSSD running as a non-root user

Simo Sorce ssorce at redhat.com
Mon Nov 3 15:29:41 UTC 2014


On Mon, 3 Nov 2014 16:08:16 +0100
Jakub Hrozek <jhrozek at redhat.com> wrote:

> On Sat, Nov 01, 2014 at 05:21:51PM -0400, Simo Sorce wrote:
> > On Sat, 1 Nov 2014 17:24:53 +0100
> > Jakub Hrozek <jhrozek at redhat.com> wrote:
> > 
> > > On Wed, Jul 23, 2014 at 03:38:13PM +0200, Jakub Hrozek wrote:
> > > > === Providers  ===
> > > > The providers are dynamically loadable libraries that are
> > > > loaded by the `sssd_be` process. After startup, the sssd_be
> > > > process dlopens the provider library and dlsyms the handlers.
> > > > During sssd operation, the `sssd_be` process mostly unpacks
> > > > requests arriving on the SBUS and calls the provider-specific
> > > > handlers.
> > > > 
> > > > We have two options here - either drop the privileges in the
> > > > provider library itself or directly in the `sssd_be` process.
> > > > Dropping privileges in the `sssd_be` process has the advantage
> > > > of modifying only one place and being sure that no matter the
> > > > back end, the privileges would always be dropped.
> > > > 
> > > > On the other hand, becoming user in the library itself might be
> > > > beneficial for scenarios where the back end requires root
> > > > access for initialization. Also, if some third-party
> > > > proprietary module absolutely requires to run as root, we
> > > > shouldn't enforce the privilege drop.
> > > > 
> > > > If we don't care about the third party modules, we could take an
> > > > approach where the provider would drop privilege as soon as it
> > > > can and after all the initialization was completed, the sssd_be
> > > > process would ensure the privileges are indeed dropped. Because
> > > > there are no third party back ends so far and there was no
> > > > attempt to write one, this is currently safe.
> > > 
> > > After some experimentation and poking at the krb5 code, I think a
> > > different route is needed. We can't reasonably drop the
> > > privileges in the provider's setup routines themselves, because
> > > we don't know if another provider needs root privileges or not.
> > > For example consider a LDAP + Kerberos combination, the LDAP ID
> > > provider can't drop privileges until Kerberos provider
> > > initializes because the Kerberos provider might need root
> > > privileges to check exisiting ccaches for renewal after startup.
> > > 
> > > We can drop privileges after the whole initialization finishes,
> > > but we should strive to reduce the privileged code even further.
> > > 
> > > Michal had an idea of adding another function to the providers
> > > that would perform privileged init, then sssd_be would drop privs
> > > and proceed with the rest of the init.
> > > 
> > > So the initialization would change from:
> > >     id_provider = dlopen()
> > >     id_init = dlsym(id_provider)
> > >     id_init()
> > > 
> > >     auth_provider = dlopen()
> > >     auth_init = dlsym(auth_provider)
> > >     auth_init()
> > > 
> > >     [...]
> > > 
> > >     become_user(sssd)
> > > 
> > > to something like:
> > >     id_provider = dlopen()
> > >     auth_provider = dlopen()
> > >     privileged_id_init = dlsym(id_provider)
> > >     privileged_auth_init = dlsym(auth_provider)
> > >     privileged_id_init()
> > >     privileged_auth_init()
> > > 
> > >     become_user(sssd)
> > > 
> > >     id_init()
> > >     auth_init()
> > > 
> > > The privileged init would initialize private data the provider
> > > needs and pass it on to the non-privileged init code.
> > > 
> > > There are some other alternatives, like a setuid setup process or
> > > performing the initialization in the monitor, but I like this
> > > option the best because passing on complex data structures
> > > between processes is tricky. This way we also keep no knowledge
> > > about provider internals outside the provider code.
> > > 
> > > Simo, I CC-ed you directly because I know you prefer to be aware
> > > of changes to the data_provider_be.c module. Do you agree with
> > > this plan?
> > 
> > Are we sure we will be able to meaningfully separate "privileged
> > initialization" from non-privileged items ?
> 
> Right now we've identified the places that need root access during
> initialization because we crawled the whole SSSD codebase while making
> it rootless -- they're the keytab processing after startup of IPA and
> AD providers and reading the ccaches of users when initializing the
> renewal. In general, the only access where we might fail unprivileged
> atm is keytab access or ccache access.
> 
> I can't guarantee other problems in the future, true, but that's not a
> problem limited to initialization, but we might run into a similar
> problem during runtime as well.

Given keytabs can be rotated during the lifetime of sssd I think we
should rather have a suid helper (or use gss-proxy in conjuction with
sssd) to access the keytab, or sssd_be will fail to handle keyroation
in future.

> > My fear is that we complicate the init system and end up having all
> > initialization in privileged_*_init() anyway, and *_init() become
> > empty shells.
> > 
> > I am comfortable with keeping the whole init privileged TBH.
> 
> Right, the initialization is a small window, at least time-wise,
> compared to the code that runs during regular SSSD execution.
> Separating the privileged init would have two benefits from my point
> of view. 1) Making the surface of the code that runs as root smaller
> in general. This is mostly interested in downstream groups that aim at
>     limiting the root code.

This sounds like it would be better served by a helper though.

>     2) Being able to separate the code that we know is required to run
>     privileged and be able to unit test SSSD as a whole during make
>     check, using wrappers.

Same as above.
 
> With 1) we can wait for some feedback from downstream. 2) is more of a
> convenience -- in order for SSSD to run as a completely different
> user, we need to do changes in the monitor (like stop requiring that
> monitor runs as root)

Hopefully this will not cause issues in monitoring network or
resolv.conf and other files that is done there.

> In conclusion, for now maybe we can file a ticket describing the
> privileged init, defer it and wait for downstream feedback as well as
> see how our testing with a custom destdir goes. Revive this ticket if
> we see a need and keep the backend init privileged now.

+1

Simo.

-- 
Simo Sorce * Red Hat, Inc * New York



More information about the sssd-devel mailing list