Remove support for Solaris pre-8
[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 int
40 afs_xsetgroups(uap, rvp)
41      u_int uap;                 /* this is gidsetsize */
42      gid_t *rvp;                /* this is gidset */
43 {
44     int code = 0;
45     struct vrequest treq;
46     struct proc *proc = ttoproc(curthread);
47
48     AFS_STATCNT(afs_xsetgroups);
49     AFS_GLOCK();
50     code = afs_InitReq(&treq, proc->p_cred);
51     AFS_GUNLOCK();
52     if (code)
53         return code;
54     code = setgroups(uap, rvp);
55
56     /* Note that if there is a pag already in the new groups we don't
57      * overwrite it with the old pag.
58      */
59     if (PagInCred(proc->p_cred) == NOPAG) {
60         if (((treq.uid >> 24) & 0xff) == 'A') {
61             AFS_GLOCK();
62             /* we've already done a setpag, so now we redo it */
63             AddPag(treq.uid, &proc->p_cred);
64             AFS_GUNLOCK();
65         }
66     }
67     return code;
68 }
69
70 int
71 setpag(cred, pagvalue, newpag, change_parent)
72      struct cred **cred;
73      afs_uint32 pagvalue;
74      afs_uint32 *newpag;
75      afs_uint32 change_parent;
76 {
77     gid_t *gidset;
78     int ngroups, code;
79     int j;
80
81     AFS_STATCNT(setpag);
82
83     gidset = (gid_t *) osi_AllocSmallSpace(AFS_SMALLOCSIZ);
84
85     mutex_enter(&curproc->p_crlock);
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     /* afs_setgroups will release curproc->p_crlock */
102     if (code = afs_setgroups(cred, ngroups, gidset, change_parent)) {
103         osi_FreeSmallSpace((char *)gidset);
104         return (code);
105     }
106     osi_FreeSmallSpace((char *)gidset);
107     return code;
108 }
109
110
111 static int
112 afs_getgroups(struct cred *cred, gid_t * gidset)
113 {
114     int ngrps, savengrps;
115     gid_t *gp;
116
117     AFS_STATCNT(afs_getgroups);
118
119     gidset[0] = gidset[1] = 0;
120 #if defined(AFS_SUN510_ENV)
121     savengrps = ngrps = crgetngroups(cred);
122     gp = crgetgroups(cred);
123 #else
124     savengrps = ngrps = cred->cr_ngroups;
125     gp = cred->cr_groups;
126 #endif
127     while (ngrps--)
128         *gidset++ = *gp++;
129     return savengrps;
130 }
131
132
133
134 static int
135 afs_setgroups(struct cred **cred, int ngroups, gid_t * gidset,
136               int change_parent)
137 {
138     gid_t *gp;
139
140     AFS_STATCNT(afs_setgroups);
141
142     if (ngroups > ngroups_max) {
143         mutex_exit(&curproc->p_crlock);
144         return EINVAL;
145     }
146     if (!change_parent)
147         *cred = (struct cred *)crcopy(*cred);
148 #if defined(AFS_SUN510_ENV)
149     crsetgroups(*cred, ngroups, gidset);
150     gp = crgetgroups(*cred);
151 #else
152     (*cred)->cr_ngroups = ngroups;
153     gp = (*cred)->cr_groups;
154 #endif
155     while (ngroups--)
156         *gp++ = *gidset++;
157     mutex_exit(&curproc->p_crlock);
158     if (!change_parent)
159         crset(curproc, *cred);  /* broadcast to all threads */
160     return (0);
161 }