Move contents of afs_osi_gcpags to per-OS files
[openafs.git] / src / afs / NBSD / 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  * osi_groups.c
12  *
13  * Implements:
14  * Afs_xsetgroups (syscall)
15  * setpag
16  *
17  */
18 #include <afsconfig.h>
19 #include "afs/param.h"
20
21
22 #include "afs/sysincludes.h"
23 #include "afsincludes.h"
24 #include "afs/afs_stats.h"      /* statistics */
25
26 #define NOCRED  ((struct ucred *) -1)
27 #define NOUID   ((uid_t) -1)
28 #define NOGID   ((gid_t) -1)
29
30
31 static int
32   afs_getgroups(struct ucred *cred, int ngroups, gid_t * gidset);
33
34 static int
35   afs_setgroups(struct proc *proc, struct ucred **cred, int ngroups,
36                 gid_t * gidset, int change_parent);
37
38 int
39 Afs_xsetgroups(p, args, retval)
40      struct proc *p;
41      void *args;
42      int *retval;
43 {
44     int code = 0;
45     struct vrequest treq;
46
47     AFS_STATCNT(afs_xsetgroups);
48     AFS_GLOCK();
49
50     /*    code = afs_InitReq(&treq, u.u_cred); */
51     code = afs_InitReq(&treq, curproc->p_cred->pc_ucred);
52     AFS_GUNLOCK();
53     if (code)
54         return code;
55
56     code = setgroups(p, args, retval);
57     /* Note that if there is a pag already in the new groups we don't
58      * overwrite it with the old pag.
59      */
60     if (PagInCred(curproc->p_cred->pc_ucred) == NOPAG) {
61         if (((treq.uid >> 24) & 0xff) == 'A') {
62             AFS_GLOCK();
63             /* we've already done a setpag, so now we redo it */
64             AddPag(p, treq.uid, &p->p_rcred);
65             AFS_GUNLOCK();
66         }
67     }
68     return code;
69 }
70
71
72 int
73 setpag(proc, cred, pagvalue, newpag, change_parent)
74      struct proc *proc;
75      struct ucred **cred;
76      afs_uint32 pagvalue;
77      afs_uint32 *newpag;
78      afs_uint32 change_parent;
79 {
80     gid_t gidset[NGROUPS];
81     int ngroups, code;
82     int j;
83
84     AFS_STATCNT(setpag);
85     ngroups = afs_getgroups(*cred, NGROUPS, gidset);
86     if (afs_get_pag_from_groups(gidset[0], gidset[1]) == NOPAG) {
87         /* We will have to shift grouplist to make room for pag */
88         if (ngroups + 2 > NGROUPS) {
89             return (E2BIG);
90         }
91         for (j = ngroups - 1; j >= 0; j--) {
92             gidset[j + 2] = gidset[j];
93         }
94         ngroups += 2;
95     }
96     *newpag = (pagvalue == -1 ? genpag() : pagvalue);
97     afs_get_groups_from_pag(*newpag, &gidset[0], &gidset[1]);
98     code = afs_setgroups(proc, cred, ngroups, gidset, change_parent);
99     return code;
100 }
101
102
103 static int
104 afs_getgroups(struct ucred *cred, int ngroups, gid_t * gidset)
105 {
106     int ngrps, savengrps;
107     gid_t *gp;
108
109     AFS_STATCNT(afs_getgroups);
110     savengrps = ngrps = MIN(ngroups, cred->cr_ngroups);
111     gp = cred->cr_groups;
112     while (ngrps--)
113         *gidset++ = *gp++;
114     return savengrps;
115 }
116
117
118
119 static int
120 afs_setgroups(struct proc *proc, struct ucred **cred, int ngroups,
121               gid_t * gidset, int change_parent)
122 {
123     int ngrps;
124     int i;
125     gid_t *gp;
126     struct ucred *newcr, *cr;
127
128     AFS_STATCNT(afs_setgroups);
129     /*
130      * The real setgroups() call does this, so maybe we should too.
131      *
132      */
133     if (ngroups > NGROUPS)
134         return EINVAL;
135     cr = *cred;
136     if (!change_parent) {
137         crhold(cr);
138         newcr = crcopy(cr);
139     } else
140         newcr = cr;
141     newcr->cr_ngroups = ngroups;
142     gp = newcr->cr_groups;
143     while (ngroups--)
144         *gp++ = *gidset++;
145     if (!change_parent) {
146         substitute_real_creds(proc, NOUID, NOUID, NOGID, NOGID, newcr);
147     }
148     *cred = newcr;
149     return (0);
150 }