[OpenAFS-devel] Re: Alternative to PAGs
Linus Torvalds
torvalds@transmeta.com
Thu, 15 May 2003 09:53:16 -0700 (PDT)
On Thu, 15 May 2003, David Howells wrote:
>
> (1) Credentials/tokens/keys/whatever are held in a "keyring".
Not "a keyring". At least to me, a "keyring" implies a "bunch of keys",
with no structure to it. That's not what you want from a maintenance
perspective.
You want to have multiple keyrings, with the ability to say "I am now
done with those keys I got from source X". That doesn't mean that you drop
all your credentials, it only means that you have stopped one "session"
(and clearly a session should be able to have many keys).
In particular, one "session" is your default one, and again, clearly that
is not necessarily just a single key.
Also, the fact that you have a default one MUST NOT preclude you from
having access to _another_ keyring too. But accessing that other keyring
does not mean that the keys from that should be added to your default
keyring: you're sharing the default keyring with other processes, so
modifying your default one to add capabilities to _one_ process is clearly
the wrong thing to do.
In other words, you want to not maintain individual keys, you always want
to maintain a _group_ of keys. You don't get "a key" by default. You get
"a group of keys" by default. The group may, of course, contain just a
single key.
So what I think you want is a hierarchy:
- "my credentials" is a "set of keyrings"
- a "keyring" is a "set of keys" aka a "session" (when used as a AFS
session, this is a PAG. Other users might have other naming conventions
for their sets of keys)
- a "key" is an indivisible blob, as far as the base kernel is concerned
(and likely most users of the key too, for that matter).
A key must be on a ring, ie all keys are part of a "session". But a
session may be associated with an arbitrary number of processes, and a
process must be able to maintain multiple sessions at once.
> (4) A user has to be able to override the default keyring, such that they
> can, for instance, perform operations on a remote filesystem with a
> different credential.
I disagree. Your (4) comes from your (1) - inability to have multiple
keyrings. If you have multiple keyrings, you don't "override" anything.
You just have a stackign order (ie the credentials is a _sorted_ list of
keyrings), and you search the credentials for valid keys in order.
> (6) A process must be able to pass a subset of its credentials to a second,
> already running process so that the second process can perform some
> service on its behalf.
A "subset of credentials" _is_ a keyring. You only ever pass keyrings
around. You don't pass individual keys around, but you also aren't forced
to pass off _all_ of your credentials at the same time.
> (8) It must be possible to withdraw a credential.
I think you have a few (different) cases of invalidation:
- you "change the lock" (ie the old key that gave you something now
becomes useless)
- you remove access to a group of keys (ie you remove a keyring, aka
"terminate a session" for one user). Other processes in that session
still have access to the keyring.
- you maintain a session/keyring (add or remove keys from it, and all
processes usign that session will see the changes to the session).
So there are at least three (very different) set of operations that
withdraw a credential and work on different levels.
> (9) The credentials governing access to a file must be associated with a
> struct file, not with the process context currently accessing a file.
This does beg the question: which level of credentials does the file get
associated with. Does it get _all_ the credentials that the opener had (ie
access to every keyring)? Or does it get associated with the one session
that the open() decided was relevant? Or does it get associated with the
single key that was used for the open?
I suspect that the open file should be associated with one "session".
> (10) A struct file will gain its credentials at the time it is opened.
Agreed.
> (12) A SUID process should add the credentials it gains from its new user ID
> to those it inherited from its original context.
But it has to keep them _separate_: it needs to be able to drop it's own
extra keys at some point, and revert to "non-suid-ness". This is why it's
so important to consider the "set of credentials" to be more than just a
"bunch of keys". It has to be bunched up some way.
And my suggestion is that the keyring is that "bunch", and that a suid
application is nothign more than one that got a special keyring at
execve() time. A keyring that it can choose to drop.
Linus