Messages in this thread | ![/](/images/icornerl.gif) | | From | David Howells <> | Subject | Linux authentication / credential management | Date | Wed, 09 Apr 2003 16:12:14 +0100 |
| |
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 - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
| ![\](/images/icornerr.gif) |