Solaris ssh pam_krb

Jeffrey Hutzelman jhutz at cmu.edu
Fri Mar 31 20:22:32 EST 2006



On Friday, March 31, 2006 06:27:22 PM -0600 Nicolas Williams 
<Nicolas.Williams at sun.com> wrote:

> On Fri, Mar 31, 2006 at 07:07:43PM -0500, Jeffrey Hutzelman wrote:
>> On Friday, March 31, 2006 05:24:04 PM -0600 Nicolas Williams
>> <Nicolas.Williams at sun.com> wrote:
>>
>> >> - Encrypted (local) filesystems
>> >
>> > Orthogonal to PAGs.  The kernel needs to know keys for encrypting
>> > objects/filesystems, but access controls are as normal (ACLs, mode
>> > bits).
>> >
>> > We're planning on per-filesystem (think ZFS) keys, too, so there's no
>> > per-"session" keys to worry about.
>>
>> I was thinking in terms of different users' files being encrypted with
>> different keys, which would require the kernel to track keys on
>> approximately a per-PAG basis.
>
> PAGs are not persistent across reboots, so, no, we can't do that.


Huh?  I wasn't suggesting using PAG's to name keys.  When a user runs 
whatever command gives the kernel the key for his files, that key should be 
associated with his PAG, so that processes which are part of his current 
session have access to the files, and other processes do not.

In other words, this should work just like other filesystems.



>> >> - Kernel-mode ticket caches
>> >
>> > Circular logic.
>>
>> No, it's not.  We already established that ticket caches are separate
>> from  PAG management.  If you want kernel-mode ticket caches (and some
>> of us do),  then you need kernel-mode access to PAG->appid mappings.
>
> "Kernel-mode ticket caches" is not an application.  An application is
> something that would use them.

"Kernel-mode ticket caches" _is_ an application of PAG's.

There may be any number of applications of kernel-mode ticket caches; there 
certainly seem to be any number of people who want to deploy them.


> Right, but in the AFS model PAGs don't provide for access control
> (though user-mode applications could use PAGs for access control given
> APIs like door_cred(3DOOR) and getpeerucred(3C)).  I think that is a
> useful simplification.  I'd like to keep it.

In the AFS model, we more or less make the assumption that impersonating 
another PAG is hard.  Not impossible, certainly, but hard enough that doing 
it requires making finding another process that has the credentials you 
want and tracing it.  That means that PAG's are an effective means of 
limiting access to credentials in a wide variety of scenarios.  It means I 
don't have to have full access to destroy the universe in every window in 
order to perform an administrative operation in one.  It means I can 
compile software in such a way that I _know_ the build process isn't 
writing to the source area, because it doesn't have the credentials to do 
so.  And so on.

I think we agree that PAG's should not be used as a general replacement for 
UID's in all access-control situations, and don't need to be able to be 
used that way.  I'm not suggesting that kernel-supported IPC mechanisms 
gain PAG-based access control facilities.  But I do expect that various 
user-mode applications, possibly including gssd, will use them to determine 
exactly who is allowed access to what.


> I don't think you want per-file keys.  Do you really want to interact
> for every file you open?

Of course not.  Which is why the kernel needs to cache the keys.

> Or every directory?  (Never mind POSIX hard
> links.)  Per-filesystem is enough, and PAM modules can "log" you into
> your filesystems.

Yes, but where is it going to put the key?  Once I've "logged in", how does 
the kernel distinguish between my processes, which are allowed to access 
files using the key I typed, and yours, which are not?  The answer is that 
they're in different PAG's, and the kernel associates the key I typed with 
my PAG and not with yours.

But in a multi-application PAG world, _no_ application can directly use the 
real PAG ID as an identifier, because it changes too much.  Instead they 
need an application-specific identifier.  That applies to encrypted 
filesystems, to AFS, and, I suspect, to NFS as well, though you might not 
yet recognize that.



> I'd rather keep the kernel-side of things simple.  I do care not to
> preclude interesting applications, but so far I've seen no real or
> imagined application that needs more than simple PAGs kernel-side.

Simple PAG's are fine, if you're only going to do simple PAG's.  But as 
soon as you do multi-application PAG's where changing any one application's 
appid means creating a new underlying PAG with the other applications' 
mappings shared, then you run into problems if there is _any_ application 
that is unaware of the mapping mechanism, or unable to use it.



> The encrypted filesystem argument holds no water, IMO.  Ken H. agrees
> that all other kernel-side applications can upcall to do PAG->stuff
> resolution if need be.  What's left?

Ken is wrong.  The access rights cache is consulted on every file access, 
and requires knowing AFS's identifier for the user's credentials, because 
that identifier is necessarily used to index the access cache.  So, we must 
be able to answer the question "what is AFS's appid for this process", and 
because it is a question we ask for _every file access_ and thus 
performance-critical, we cannot do an upcall every time.  Give me a way to 
reliably find out AFS's appid for a given process without doing an upcall, 
and I really don't care much what you do for everyone else.

I think you're making the same mistake the Linux kernel keyring people did 
when I had this discussion with them, which is to assume that PAG's are all 
about the keys, and so all you have to do is provide a way to store and 
control access to the keys.  But it's not about the keys; its about having 
an identifier that we can safely use in kernel data structures to identify 
data related to that PAG.  I have no problem with doing an upcall to get 
the credentials I need to authenticate a new connection, or even to rekey 
an existing one.  But I don't think I can afford to do an upcall every time 
I make an RPC, and I certainly can't afford one every time I need to know a 
process's PAG so I can look up its access rights.


> Also, note that we can make the API hide all the relevant details, such
> that if we ever need multi-app PAG associations in the kernel we can
> move the whole implementation from user-land into the kernel.

Well, yes.  But if you invent multi-app PAG's and don't provide a kernel 
interface for discovering the mappings, then I can't use it for AFS.  So 
I'm arguing for making the mappings visible in the kernel from the get-go.


> Which leaves the argument of where the complexity belongs.  You know
> where I stand on that :)

Yeah, but there's really not that much complexity.  You're already talking 
about allocating a kernel data structure to represent a PAG.  I'm just 
asking you to make it big enough to actually hold multiple appid's, instead 
of just one number that one has to contact a user-mode process to 
interpret.  Note that I'm not asking for the kernel to provide more than 
rudimentary access controls for PAG mappings.  In fact, you could provide 
basically the same semantics as you would for simple PAG's:

1) any process can found out what its PAG's are
2) any process can request a new PAG for a specific app
3) any process can request a new PAG for "all apps", which really means
   whatever apps the process already has PAG's for.
4) no process can make any other changes to its PAG's.
5) some processes can find out the PAG's of other processes

(2) means you allocate a new PAG strcture, set a new PAG for the requested
app, and copy the PAG's for all the other existing apps.  (3) means you 
allocate a new structure and set new PAG's for all the existing apps; it's 
essentially an optimization, since the user-mode code could do that given 
(1) and (2).

I'm not sure what "some" means in case 5, but it's a question you'd have to 
answer anyway.  The simplest answer is that any process can examine the 
PAG's of any other process that is visible to it (so, presumably not across 
zones).  I don't see any reason to need something more complex than that.

You can allocate PAG ID's for all apps out of the same 64-bit pool, and 
application types are managed in user space.  A kernel-mode application 
would have to know its app type ID, but _that_ it can do with an upcall. 
For encrypting filesystems, you could even allocate separate type ID's for 
each filesystem, if you wanted to let users scope access to different 
filesystems separately (for example, I need one set of keys for my homedir, 
and another set for someplace I keep extra-sensitive data.  I want to 
create a new process which shares the homedir-access keys, but has a 
separate PAG with respect to the extra-sensitive area so that those keys 
don't leak into the rest of my session).


-- Jeff



More information about the Kerberos mailing list