849dbdde7998cdcd7740375dc1d6aaa673dc74ba
[openafs.git] / src / afs / UKERNEL / osi_groups.c
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  * afs_xsetgroups (asserts FALSE)
12  * setpag (aliased to use_setpag in sysincludes.h)
13  */
14 #include <afsconfig.h>
15 #include "afs/param.h"
16
17 RCSID
18     ("$Header$");
19
20 #include "afs/sysincludes.h"
21 #include "afsincludes.h"
22 #include "afs/afs_stats.h"      /* statistics */
23
24
25 int
26 afs_xsetgroups()
27 {
28     usr_assert(0);
29 }
30
31 static int
32 afs_getgroups(struct AFS_UCRED *cred, gid_t * gidset)
33 {
34     int ngrps, savengrps;
35     gid_t *gp;
36
37     AFS_STATCNT(afs_getgroups);
38
39     gidset[0] = gidset[1] = 0;
40     savengrps = ngrps = cred->cr_ngroups;
41     gp = cred->cr_groups;
42     while (ngrps--)
43         *gidset++ = *gp++;
44     return savengrps;
45 }
46
47
48
49 static int
50 afs_setgroups(struct AFS_UCRED **cred, int ngroups, gid_t * gidset,
51               int change_parent)
52 {
53     int ngrps;
54     int i;
55     gid_t *gp;
56
57     AFS_STATCNT(afs_setgroups);
58
59     if (ngroups > NGROUPS_MAX)
60         return EINVAL;
61     if (!change_parent)
62         *cred = (struct AFS_UCRED *)crcopy(*cred);
63     (*cred)->cr_ngroups = ngroups;
64     gp = (*cred)->cr_groups;
65     while (ngroups--)
66         *gp++ = *gidset++;
67     return (0);
68 }
69
70 int
71 usr_setpag(struct usr_ucred **cred, afs_uint32 pagvalue, afs_uint32 * newpag,
72            int change_parent)
73 {
74     gid_t *gidset;
75     int ngroups, code;
76     int j;
77
78     AFS_STATCNT(setpag);
79
80     gidset = (gid_t *) osi_AllocSmallSpace(AFS_SMALLOCSIZ);
81     ngroups = afs_getgroups(*cred, gidset);
82
83     if (afs_get_pag_from_groups(gidset[0], gidset[1]) == NOPAG) {
84         /* We will have to shift grouplist to make room for pag */
85         if ((sizeof gidset[0]) * (ngroups + 2) > AFS_SMALLOCSIZ) {
86             osi_FreeSmallSpace((char *)gidset);
87             return (E2BIG);
88         }
89         for (j = ngroups - 1; j >= 0; j--) {
90             gidset[j + 2] = gidset[j];
91         }
92         ngroups += 2;
93     }
94     *newpag = (pagvalue == -1 ? genpag() : pagvalue);
95     afs_get_groups_from_pag(*newpag, &gidset[0], &gidset[1]);
96     if ((code = afs_setgroups(cred, ngroups, gidset, change_parent))) {
97         osi_FreeSmallSpace((char *)gidset);
98         return (code);
99     }
100     osi_FreeSmallSpace((char *)gidset);
101
102     return 0;
103 }