Subject: Re: bug#45571: Support stable uids and gids for all accounts
From: Leo Prikler <[email-masked]>
To: Danny Milosavljevic <[email-masked]>
Date: Sat, 02 Jan 2021 00:16:45 +0100

Hi Danny,

Am Freitag, den 01.01.2021, 21:22 +0100 schrieb Danny Milosavljevic:
> Hi Leo,
> 
> On Fri, 01 Jan 2021 19:44:12 +0100
> Leo Prikler <[email-masked]> wrote:
> 
> > Ah, that puts things into perspective.  In other words, the problem
> > is
> > not, that Guix doesn't read /etc/passwd at all, but that it reads
> > the
> > wrong one (the host instead of the guest, so to speak).  Should
> > this
> > perhaps be a parameter instead?
> 
> Considering the goal of Guix, it's weird that with Guix, one needs to
> store&restore /etc/passwd at all.  It's state, but not very useful
> one.
> I mean that's how it is right now--but it's still weird.
> 
> With /etc/shadow maybe there's a slightly better case, but note that
> the key
> to find stuff in /etc/shadow can't be the uid--the uid isn't even in
> there!
AFAIU yes, it's state, but not one that Guix can simply do away with. 
There is not yet a syntax for keeping secrets, which would be needed to
fully populate /etc from config.scm.  Perhaps we'll get there some day.

Also IIUC, account names are supposedly unique, hence my proposed patch
to #45570.

> > How is that explicit?  The % even implies, that it's considered
> > internal to the definition.
> 
> Explicit means that the user-account record is initialized right
> there (every
> time account-service-type is extended), by a literal.
> 
> And it is.  You can see it plain as day in the guix git repo where
> account-service-type is used in gnu/services/ .
> 
> Implicit would be if some code would generate this <user-account>
> record
> on-the-fly, usually leaving stuff hard to change by the maintainer.
Fair enough, that's explicit in some sense, but not explicit if we take
the config.scm as the point of reference.  Since there's no way of
explicitly setting it from there without advanced wizardry.

> '(user-account (name "x") ...)' is about as explicit as it gets for a
> record.
> 
> The "%" in the name of the binding changes nothing in the literal
> value.
> 
> And it indeed is possible to add (uid 4711) in the literal and it
> will work
> just fine.
I'm aware you're joking, or at least I hope you are, but I shouldn't
have to point out why hardcoding ids into those literals is a bad idea.

> >  Instead, you'd have (darkstat-accounts
> > config), which default to the current value of %darkstat-accounts,
> > but
> > are configurable at least in the way that they allow you to set
> > their
> > ids.
> 
> Oh, you want internal service users to be USER-configurable.  Indeed
> that is
> also what Jason suggested in the initial mail.
> 
> But I think that that would put undue burden on each user and is
> really just
> a workaround.
> I would really like to caution against us doing a "whack a mole"
> development
> approach, where workarounds like that are introduced to work around
> bugs
> without understanding the underlying causes.  So I disagree that
> having
> internal service users be user-configurable is a good idea.
"Undue burden on each user" is a bit exaggerated, considering that the
defaults work fine for most.  Making them user-configurable would even
allow hardcoding a default ID, because users would be able to change
that ID if they wanted a different one, eliminating even more reasons
to configure them if not for the reason of "because I want to".

I also disagree, that this is a problem, that we can solve as Guix
System alone.  Even if we were to implement your hash idea, other
distros would still be keeping their numbering systems.  If you share
an NFS with a legacy system, you'd still need a mapping or inherit
accounts from their settings -- neither of which sound great, but
compromises have to be made.

In that sense, I agree with Jason that it is a problem, that you can't
set service [GU]IDs when you want (or need) to.  The question is how to
best make them configurable.

> > In the realm of Guix system, this could be resolved by allowing the
> > user to choose the "seeds" for those files, so to speak (in
> > commands
> > such as init, vm, deploy, etc.), could it not?
> 
> Sure, but that's a last resort.  Better is to eliminate state if
> possible.
Keyword being "if possible".  It is currently not possible to eliminate
shadow.

> > > (5) Also for not having this bug with containers, it would still
> > > be
> > > better to
> > > just make uid and gid mandatory for "user-account" records.
> > > 
> > > (6) Since (5) would move the burden to the user, it would be
> > > better
> > > usability
> > > to generate uid and gid in a deterministic manner as a default.  
> > Is the current logic non-deterministic in any way other than
> > supporting
> > the reuse of old entries (which you yourself agree is a good
> > thing)?
> 
> It generates uids using a counter, so it depends on what order
> user-accounts are created in by Guix, which depends on the order the
> user
> specifies services in /etc/config.scm and on the order to user
> accounts
> are specified in gnu/services/ by guix maintainers.  Then the service
> executable (potentially) goes on to create files using those uids.
> 
> That means that if you remove or reorder service references in
> /etc/config.scm,
> the uids "want" to change.  The only reason they don't change is
> because the
> logic prefers the existing /etc/passwd's uids--a stopgap measure at
> the last
> second to prevent total chaos.
> 
> Does any of this sound good to you?
Keeping value judgements aside, it does sound deterministic.
Relying on order is also not that big of a deal if you have ways of
ensuring order, but you'd also have to ensure, that the expected order
is the same as the one actually used, and that's significantly harder
to do.

An example: You could expect user accounts to be numbered in the order
they appear in the field, but you could also expect them to be numbered
in reverse order (because services can add accounts and they're usually
consed).  In that sense, yeah, relying on order is certainly not
optimal.

> I mean, strictly speaking, it's better than the alternative--but
> that's a low
> bar.
> 
> Better would be a making the uid field mandatory and/or generating
> each uid
> from the respective name.
Statistically speaking hashes collide sooner than incrementing numbers
do.  Granted, they might work as mitigation, but they're no solution on
their own either.

> > As far as I understand it, same config.scm + same
> > /etc/{passwd,group,shadow} => same /etc/{passwd,group,shadow}.
> 
> That is the intention of (gnu system shadow), I think.
You mean (gnu build accounts), right?

> I can't say whether that's the case in practice now or not.  It
> certainly was not the case a few
> years ago where I did run into the same problem (a necessary
> condition for
> the problem to manifest is that the services change--but my
> /etc/config.scm
> services forms have been stable for a long time now, and Guix
> upstream also
> doesn't change service definitions a lot anymore.  So who knows?).
Well, the point here was not to state how outputs differ when the
inputs differ, but what happens, when they stay the same.  I have
another machine, that I carried over from a Gentoo install using
different user names, and there I have a different UID from this
machine, where I did a clean install (and it has stayed the same UID
since).  IOW this appears to be functioning as intended.

Regards,
Leo