2 * Copyright 2000, International Business Machines Corporation and others.
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
14 * Afs_xsetgroups (syscall)
18 #include <afsconfig.h>
19 #include "afs/param.h"
22 #include "afs/sysincludes.h"
23 #include "afs/afsincludes.h"
24 #include "afs/afs_stats.h" /* statistics */
25 #include "sys/syscallargs.h"
27 #define NOUID ((uid_t) -1)
28 #define NOGID ((gid_t) -1)
31 * NetBSD has a very flexible and elegant replacement for Unix
32 * groups KPIs, see kauth(9).
36 static int osi_getgroups(afs_ucred_t *, int, gid_t *);
38 /* why **? are we returning or reallocating creat? */
39 static int osi_setgroups(afs_proc_t *, afs_ucred_t **, int, gid_t *, int);
41 int Afs_xsetgroups(afs_proc_t *, const void *, register_t *);
44 Afs_xsetgroups(afs_proc_t *p, const void *args, register_t *retval)
48 afs_ucred_t *cred = osi_proccred(p);
50 AFS_STATCNT(afs_xsetgroups);
53 code = afs_InitReq(&treq, cred);
59 /* results visible via kauth_cred_getgroups. also does other work */
60 code = sys_setgroups(p, args, retval);
63 * Note that if there is a pag already in the new groups we don't
64 * overwrite it with the old pag.
66 if (PagInCred(cred) == NOPAG) {
67 if (((treq.uid >> 24) & 0xff) == 'A') {
69 /* we've already done a setpag, so now we redo it */
70 AddPag(p, treq.uid, &cred);
78 setpag(afs_proc_t *proc, afs_ucred_t **cred, afs_uint32 pagvalue,
79 afs_uint32 * newpag, int change_parent)
81 gid_t gidset[NGROUPS];
86 ngroups = osi_getgroups(*cred, NGROUPS, gidset);
87 if (afs_get_pag_from_groups(gidset[1], gidset[2]) == NOPAG) {
88 /* We will have to shift grouplist to make room for pag */
89 if (ngroups + 2 > NGROUPS) {
92 for (j = ngroups - 1; j >= 1; j--) {
93 gidset[j + 2] = gidset[j];
97 *newpag = (pagvalue == -1 ? genpag() : pagvalue);
98 afs_get_groups_from_pag(*newpag, &gidset[1], &gidset[2]);
99 code = osi_setgroups(proc, cred, ngroups, gidset, change_parent);
105 osi_getgroups(afs_ucred_t *cred, int ngroups, gid_t *gidset)
107 AFS_STATCNT(afs_getgroups);
109 ngroups = MIN(kauth_cred_ngroups(cred), ngroups);
111 kauth_cred_getgroups(cred, gidset, ngroups, UIO_SYSSPACE);
117 osi_setgroups(afs_proc_t *proc, afs_ucred_t **cred, int ngroups,
118 gid_t * gidset, int change_parent)
123 AFS_STATCNT(afs_setgroups); /* XXX rename statcnt */
125 if (ngroups > NGROUPS)
130 if (!change_parent) {
132 *cred = kauth_cred_dup(ocred);
135 code = kauth_cred_setgroups(*cred, gidset, ngroups, -1, UIO_SYSSPACE);
137 if (!change_parent) {
138 proc_crmod_leave(*cred, ocred, false);