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