Linux authentication / credential management
Hi Linus,
Would you be willing to consider having a "credential cache" in Linux 2.5 (or is this something you'd rather leave to 2.7)?
The first part of what I'm thinking of is a structure like the following that has a Process Authentication Group ID and a list of authentication tokens for filesystems such as AFS & NFSv4 kerberos keys, NTFS ACLs, SAMBA login details.
struct auth_session {
struct atomic_t usage;
pag_t pag; /* process auth group ID */
struct list_head tokens;
rwlock_t lock;
};Each token would be defined as follows, the most significant bit being a pointer to a blob of arbitrary data for the use of the filesystem:
struct auth_token {
struct list_head link;
struct auth_token_ops *ops;
atomic_t usage;
time_t expiry;
void *data;
};
struct auth_token_ops {
const char *type;
void (*release)(struct auth_session *session,
struct auth_token *token);
};Two additional system calls would be required: setpag() to create a new session and attach to it, and getpag() to find out what a process's session ID is.
Note that these sessions are different from job-control sessions and process groups.
The second part is to detach all the user and group information from the task structure and put it into a separate structure of its own, which each task (or task group) would then refer to:
struct auth_context {
atomic_t usage;
uid_t uid, euid, suid;
gid_t gid, egid, sgid;
int ngroups;
gid_t groups[NGROUPS];
struct user_struct *user;
struct auth_session *session;
};
struct task_struct {
...
struct auth_context *auth;
struct auth_context *fsauth;
...
};Furthermore each struct file would refer to one of these contexts, the pointer being set at the moment of opening:
struct file {
...
struct auth_context *f_auth;
...
};
struct file *dentry_open(...)
{
...
f->f_auth = get_auth_context(current->fsauth);
...
}This structure would then become "copy on modify if shared", otherwise files could have their security details changed when the process that opened them changes its details.
Alternatively, the task structure could just point to the credential cache entry for that process.
ADDITIONAL POSSIBILITIES
========================
(*) It may be worth making the supplementary group list a token dangling from
the auth_session struct.
Alternatively, the groups could be put in a separate ref-counted structure of their own.
(*) Make auth_context into a stack of permission structures, pushing extra
nodes on to effect separation of EUID, UID and SUID for example. The
structure would then become:
struct auth_context {
struct auth_context *next;
atomic_t usage;
int type; /* 0=real, 1=temp effective */
uid_t uid;
gid_t gid;
int ngroups;
gid_t groups[NGROUPS];
struct user_struct *user;
struct auth_session *session;
};
The effective credentials would just be whatever is at the TOS.
Temporary changes of authentication tokens would be fairly simple (just
push and pop). SetUID programs would just push another context on the
stack, which then could be popped off by setuid(SAVED_IDS).
Things like setresuid() would manipulate the top three entries on the
stack. (*) The kernel capabilities masks could also be offloaded into this
structure.
(*) A set of convenience functions could be provided to:
- extract the current UID/GID from a context (eg: used by creat)
- test RWX permission against a context (eg: used by open)
This would then abstract the UID/GID concept, making it easier to extend the access control system.
(*) It might be possible to pass an auth_context* to readpage instead of a
file*.
David
Quoted 3 lines · * David Howells ([email protected]) wrote:
Would you be willing to consider having a "credential cache" in Linux 2.5 (or is this something you'd rather leave to 2.7)?
Did you look at the vfs_cred patch that Trond was floating before feature freeze? It doesn't have the session bit, but has the credential cache, modelled from BSD credentials.
http://marc.theaimsgroup.com/?l=linux-kernel&m=103081213416497&w=2
and the ucred patch which lead to this thread:
http://marc.theaimsgroup.com/?l=linux-kernel&m=103074971719243&w=2
It's certainly simpler, but could it be used as a starting point?
thanks,
-chris
Signature · 1 line
Linux Security Modules http://lsm.immunix.org http://lsm.bkbits.net
Quoted 4 lines · David Howells
The first part of what I'm thinking of is a structure like the following that has a Process Authentication Group ID and a list of authentication tokens for filesystems such as AFS & NFSv4 kerberos keys, NTFS ACLs, SAMBA login details.
PAGs have been proposed over and over again and there is one fundamental problem, my PAG isn't your PAG.
(although in this specific case, if you're looking at it with the AFS hat it probably is).
Some people want to have an authentication identifier they can keep synchronized across a cluster, so they want to be able to set the 'PAG' to any arbitrary value. However Coda (and AFS) prefer to have something that just guarantees to be a unique identifier for a group of related tasks (aka. newpag). Allowing someone to set the pag in this case nullifies the usefulness of the tag because there is no guarantee that it is unique. It would be similar to allowing someone to specify their own process id.
What happened to your 'task ornaments', I figured that that would have been the best way to tag processes with information and allow individual filesystems to define their own preferred semantics.
http://www.ussg.iu.edu/hypermail/linux/kernel/0201.3/0480.html
Jan