Import Upstream version 1.8.5
[hcoop/debian/openafs.git] / src / afs / LINUX / osi_cred.c
CommitLineData
805e021f
CE
1/*
2 * Copyright 2000, International Business Machines Corporation and others.
3 * All Rights Reserved.
4 *
5 * This software has been released under the terms of the IBM Public
6 * License. For details, see the LICENSE file in the top-level source
7 * directory or online at http://www.openafs.org/dl/license10.html
8 */
9
10/*
11 * osi_cred.c - Linux cred handling routines.
12 *
13 */
14#include <afsconfig.h>
15#include "afs/param.h"
16
17
18#include "afs/sysincludes.h"
19#include "afsincludes.h"
20
21/* Copy one credential structure to another, being careful about references */
22static inline void
23afs_copy_creds(cred_t *to_cred, const cred_t *from_cred) {
24#if defined(STRUCT_TASK_STRUCT_HAS_CRED)
25 /* Skip afs_from_kuid/afs_make_kuid round trip */
26 to_cred->fsuid = from_cred->fsuid;
27 to_cred->fsgid = from_cred->fsgid;
28 to_cred->uid = from_cred->uid;
29 to_cred->gid = from_cred->gid;
30#else
31 afs_set_cr_uid(to_cred, afs_cr_uid(from_cred));
32 afs_set_cr_gid(to_cred, afs_cr_gid(from_cred));
33 afs_set_cr_ruid(to_cred, afs_cr_ruid(from_cred));
34 afs_set_cr_rgid(to_cred, afs_cr_rgid(from_cred));
35#endif
36 get_group_info(afs_cr_group_info(from_cred));
37 afs_set_cr_group_info(to_cred, afs_cr_group_info(from_cred));
38}
39
40cred_t *
41crget(void)
42{
43 cred_t *tmp;
44
45 tmp = kmalloc(sizeof(cred_t), GFP_NOFS);
46 if (!tmp)
47 osi_Panic("crget: No more memory for creds!\n");
48
49#if defined(STRUCT_TASK_STRUCT_HAS_CRED)
50 get_cred(tmp);
51#else
52 atomic_set(&tmp->cr_ref, 1);
53#endif
54 return tmp;
55}
56
57void
58crfree(cred_t * cr)
59{
60#if defined(STRUCT_TASK_STRUCT_HAS_CRED)
61 put_cred(cr);
62#else
63 if (atomic_dec_and_test(&cr->cr_ref)) {
64 put_group_info(afs_cr_group_info(cr));
65 kfree(cr);
66 }
67#endif
68}
69
70
71/* Return a duplicate of the cred. */
72cred_t *
73crdup(cred_t * cr)
74{
75 cred_t *tmp = crget();
76#if defined(STRUCT_TASK_STRUCT_HAS_CRED)
77 afs_copy_creds(tmp, cr);
78#else
79 afs_set_cr_uid(tmp, afs_cr_uid(cr));
80 afs_set_cr_ruid(tmp, afs_cr_ruid(cr));
81 afs_set_cr_gid(tmp, afs_cr_gid(cr));
82 afs_set_cr_rgid(tmp, afs_cr_rgid(cr));
83
84 get_group_info(afs_cr_group_info(cr));
85 afs_set_cr_group_info(tmp, afs_cr_group_info(cr));
86#endif
87 return tmp;
88}
89
90cred_t *
91crref(void)
92{
93#if defined(STRUCT_TASK_STRUCT_HAS_CRED)
94 return (cred_t *)get_current_cred();
95#else
96 cred_t *cr = crget();
97
98 afs_set_cr_uid(cr, current_fsuid());
99 afs_set_cr_ruid(cr, current_uid());
100 afs_set_cr_gid(cr, current_fsgid());
101 afs_set_cr_rgid(cr, current_gid());
102
103 task_lock(current);
104 get_group_info(current_group_info());
105 afs_set_cr_group_info(cr, current_group_info());
106 task_unlock(current);
107
108 return cr;
109#endif
110}
111
112/* Set the cred info into the current task */
113void
114crset(cred_t * cr)
115{
116#if defined(STRUCT_TASK_STRUCT_HAS_CRED)
117 struct cred *new_creds;
118
119 /* If our current task doesn't have identical real and effective
120 * credentials, commit_cred won't let us change them, so we just
121 * bail here.
122 */
123 if (current->cred != current->real_cred)
124 return;
125 new_creds = prepare_creds();
126 /* Drop the reference to group_info - we'll overwrite it in afs_copy_creds */
127 put_group_info(new_creds->group_info);
128 afs_copy_creds(new_creds, cr);
129
130 commit_creds(new_creds);
131#else
132 struct group_info *old_info;
133
134 current->fsuid = afs_cr_uid(cr);
135 current->uid = afs_cr_ruid(cr);
136 current->fsgid = afs_cr_gid(cr);
137 current->gid = afs_cr_rgid(cr);
138
139 get_group_info(afs_cr_group_info(cr));
140 task_lock(current);
141 old_info = current->group_info;
142 current->group_info = afs_cr_group_info(cr);
143 task_unlock(current);
144 put_group_info(old_info);
145#endif
146}