#include <afsconfig.h>
#include "afs/param.h"
-RCSID
- ("$Header$");
#include "afs/sysincludes.h"
#include "afsincludes.h"
+/* Copy one credential structure to another, being careful about references */
+static inline void
+afs_copy_creds(cred_t *to_cred, const cred_t *from_cred) {
+ afs_set_cr_uid(to_cred, afs_cr_uid(from_cred));
+ afs_set_cr_gid(to_cred, afs_cr_gid(from_cred));
+ afs_set_cr_ruid(to_cred, afs_cr_ruid(from_cred));
+ afs_set_cr_rgid(to_cred, afs_cr_rgid(from_cred));
+ get_group_info(afs_cr_group_info(from_cred));
+ afs_set_cr_group_info(to_cred, afs_cr_group_info(from_cred));
+}
+
cred_t *
crget(void)
{
cred_t *tmp;
-#if !defined(GFP_NOFS)
-#define GFP_NOFS GFP_KERNEL
-#endif
tmp = kmalloc(sizeof(cred_t), GFP_NOFS);
+ memset(tmp, 0, sizeof(cred_t));
if (!tmp)
- osi_Panic("crget: No more memory for creds!\n");
-
- tmp->cr_ref = 1;
+ osi_Panic("crget: No more memory for creds!\n");
+
+#if defined(STRUCT_TASK_HAS_CRED)
+ get_cred(tmp);
+#else
+ atomic_set(&tmp->cr_ref, 1);
+#endif
return tmp;
}
void
crfree(cred_t * cr)
{
- if (cr->cr_ref > 1) {
- cr->cr_ref--;
- return;
+#if defined(STRUCT_TASK_HAS_CRED)
+ put_cred(cr);
+#else
+ if (atomic_dec_and_test(&cr->cr_ref)) {
+ put_group_info(afs_cr_group_info(cr));
+ kfree(cr);
}
-
-#if defined(AFS_LINUX26_ENV)
- put_group_info(cr->cr_group_info);
#endif
-
- kfree(cr);
}
crdup(cred_t * cr)
{
cred_t *tmp = crget();
-
- tmp->cr_uid = cr->cr_uid;
- tmp->cr_ruid = cr->cr_ruid;
- tmp->cr_gid = cr->cr_gid;
- tmp->cr_rgid = cr->cr_rgid;
-
-#if defined(AFS_LINUX26_ENV)
- get_group_info(cr->cr_group_info);
- tmp->cr_group_info = cr->cr_group_info;
+#if defined(STRUCT_TASK_HAS_CRED)
+ afs_copy_creds(tmp, cr);
#else
- memcpy(tmp->cr_groups, cr->cr_groups, NGROUPS * sizeof(gid_t));
- tmp->cr_ngroups = cr->cr_ngroups;
-#endif
+ afs_set_cr_uid(tmp, afs_cr_uid(cr));
+ afs_set_cr_ruid(tmp, afs_cr_ruid(cr));
+ afs_set_cr_gid(tmp, afs_cr_gid(cr));
+ afs_set_cr_rgid(tmp, afs_cr_rgid(cr));
+ get_group_info(afs_cr_group_info(cr));
+ afs_set_cr_group_info(tmp, afs_cr_group_info(cr));
+#endif
return tmp;
}
cred_t *
crref(void)
{
+#if defined(STRUCT_TASK_HAS_CRED)
+ return (cred_t *)get_current_cred();
+#else
cred_t *cr = crget();
- cr->cr_uid = current_fsuid();
- cr->cr_ruid = current_uid();
- cr->cr_gid = current_fsgid();
- cr->cr_rgid = current_gid();
+ afs_set_cr_uid(cr, current_fsuid());
+ afs_set_cr_ruid(cr, current_uid());
+ afs_set_cr_gid(cr, current_fsgid());
+ afs_set_cr_rgid(cr, current_gid());
-#if defined(AFS_LINUX26_ENV)
task_lock(current);
get_group_info(current_group_info());
- cr->cr_group_info = current_group_info();
+ afs_set_cr_group_info(cr, current_group_info());
task_unlock(current);
-#else
- memcpy(cr->cr_groups, current->groups, NGROUPS * sizeof(gid_t));
- cr->cr_ngroups = current->ngroups;
-#endif
+
return cr;
+#endif
}
-
/* Set the cred info into the current task */
void
crset(cred_t * cr)
if (current->cred != current->real_cred)
return;
new_creds = prepare_creds();
- new_creds->fsuid = cr->cr_uid;
- new_creds->uid = cr->cr_ruid;
- new_creds->fsgid = cr->cr_gid;
- new_creds->gid = cr->cr_rgid;
+ /* Drop the reference to group_info - we'll overwrite it in afs_copy_creds */
+ put_group_info(new_creds->group_info);
+ afs_copy_creds(new_creds, current_cred());
+
+ commit_creds(new_creds);
#else
- current->fsuid = cr->cr_uid;
- current->uid = cr->cr_ruid;
- current->fsgid = cr->cr_gid;
- current->gid = cr->cr_rgid;
-#endif
-#if defined(AFS_LINUX26_ENV)
-{
struct group_info *old_info;
- /* using set_current_groups() will sort the groups */
- get_group_info(cr->cr_group_info);
+ current->fsuid = afs_cr_uid(cr);
+ current->uid = afs_cr_ruid(cr);
+ current->fsgid = afs_cr_gid(cr);
+ current->gid = afs_cr_rgid(cr);
+ get_group_info(afs_cr_group_info(cr));
task_lock(current);
-#if defined(STRUCT_TASK_HAS_CRED)
- old_info = current->cred->group_info;
- new_creds->group_info = cr->cr_group_info;
- commit_creds(new_creds);
-#else
old_info = current->group_info;
- current->group_info = cr->cr_group_info;
-#endif
+ current->group_info = afs_cr_group_info(cr);
task_unlock(current);
-
put_group_info(old_info);
-}
-#else
- memcpy(current->groups, cr->cr_groups, NGROUPS * sizeof(gid_t));
- current->ngroups = cr->cr_ngroups;
#endif
}