Remove the RCSID macro
[openafs.git] / src / afs / SOLARIS / 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  * Implements:
12  * setgroups (syscall)
13  * setpag
14  *
15  */
16
17 #include <unistd.h>
18 #ifdef AFS_SUN510_ENV
19 #include <sys/cred.h>
20 #endif
21
22 #include <afsconfig.h>
23 #include "afs/param.h"
24
25
26 #include "afs/sysincludes.h"
27 #include "afsincludes.h"
28 #include "afs/afs_stats.h"      /* statistics */
29
30
31 static int
32   afs_getgroups(struct cred *cred, gid_t * gidset);
33
34 static int
35   afs_setgroups(struct cred **cred, int ngroups, gid_t * gidset,
36                 int change_parent);
37
38
39 #if     defined(AFS_SUN55_ENV)
40 int
41 afs_xsetgroups(uap, rvp)
42      u_int uap;                 /* this is gidsetsize */
43      gid_t *rvp;                /* this is gidset */
44 #else
45 struct setgroupsa {
46     u_int gidsetsize;
47     gid_t *gidset;
48 };
49
50 afs_xsetgroups(uap, rvp)
51      struct setgroupsa *uap;
52      rval_t *rvp;
53 #endif
54 {
55     int code = 0;
56     struct vrequest treq;
57     struct proc *proc = ttoproc(curthread);
58
59     AFS_STATCNT(afs_xsetgroups);
60     AFS_GLOCK();
61     code = afs_InitReq(&treq, proc->p_cred);
62     AFS_GUNLOCK();
63     if (code)
64         return code;
65     code = setgroups(uap, rvp);
66
67     /* Note that if there is a pag already in the new groups we don't
68      * overwrite it with the old pag.
69      */
70     if (PagInCred(proc->p_cred) == NOPAG) {
71         if (((treq.uid >> 24) & 0xff) == 'A') {
72             AFS_GLOCK();
73             /* we've already done a setpag, so now we redo it */
74             AddPag(treq.uid, &proc->p_cred);
75             AFS_GUNLOCK();
76         }
77     }
78     return code;
79 }
80
81 int
82 setpag(cred, pagvalue, newpag, change_parent)
83      struct cred **cred;
84      afs_uint32 pagvalue;
85      afs_uint32 *newpag;
86      afs_uint32 change_parent;
87 {
88     gid_t *gidset;
89     int ngroups, code;
90     int j;
91
92     AFS_STATCNT(setpag);
93
94     gidset = (gid_t *) osi_AllocSmallSpace(AFS_SMALLOCSIZ);
95
96     mutex_enter(&curproc->p_crlock);
97     ngroups = afs_getgroups(*cred, gidset);
98
99     if (afs_get_pag_from_groups(gidset[0], gidset[1]) == NOPAG) {
100         /* We will have to shift grouplist to make room for pag */
101         if ((sizeof gidset[0]) * (ngroups + 2) > AFS_SMALLOCSIZ) {
102             osi_FreeSmallSpace((char *)gidset);
103             return (E2BIG);
104         }
105         for (j = ngroups - 1; j >= 0; j--) {
106             gidset[j + 2] = gidset[j];
107         }
108         ngroups += 2;
109     }
110     *newpag = (pagvalue == -1 ? genpag() : pagvalue);
111     afs_get_groups_from_pag(*newpag, &gidset[0], &gidset[1]);
112     /* afs_setgroups will release curproc->p_crlock */
113     if (code = afs_setgroups(cred, ngroups, gidset, change_parent)) {
114         osi_FreeSmallSpace((char *)gidset);
115         return (code);
116     }
117     osi_FreeSmallSpace((char *)gidset);
118     return code;
119 }
120
121
122 static int
123 afs_getgroups(struct cred *cred, gid_t * gidset)
124 {
125     int ngrps, savengrps;
126     gid_t *gp;
127
128     AFS_STATCNT(afs_getgroups);
129
130     gidset[0] = gidset[1] = 0;
131 #if defined(AFS_SUN510_ENV)
132     savengrps = ngrps = crgetngroups(cred);
133     gp = crgetgroups(cred);
134 #else
135     savengrps = ngrps = cred->cr_ngroups;
136     gp = cred->cr_groups;
137 #endif
138     while (ngrps--)
139         *gidset++ = *gp++;
140     return savengrps;
141 }
142
143
144
145 static int
146 afs_setgroups(struct cred **cred, int ngroups, gid_t * gidset,
147               int change_parent)
148 {
149     gid_t *gp;
150
151     AFS_STATCNT(afs_setgroups);
152
153     if (ngroups > ngroups_max) {
154         mutex_exit(&curproc->p_crlock);
155         return EINVAL;
156     }
157     if (!change_parent)
158         *cred = (struct cred *)crcopy(*cred);
159 #if defined(AFS_SUN510_ENV)
160     crsetgroups(*cred, ngroups, gidset);
161     gp = crgetgroups(*cred);
162 #else
163     (*cred)->cr_ngroups = ngroups;
164     gp = (*cred)->cr_groups;
165 #endif
166     while (ngroups--)
167         *gp++ = *gidset++;
168     mutex_exit(&curproc->p_crlock);
169     if (!change_parent)
170         crset(curproc, *cred);  /* broadcast to all threads */
171     return (0);
172 }