Merge 1.8.0~pre4 packaging into master
[pkg-k5-afs_openafs.git] / src / afs / NBSD / osi_groups.c
blob78b80e70bdba23117f3644c5608f0fa452e5326d
1 /*
2 * Copyright 2000, International Business Machines Corporation and others.
3 * All Rights Reserved.
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 */
11 * osi_groups.c
13 * Implements:
14 * Afs_xsetgroups (syscall)
15 * setpag
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 *);
43 int
44 Afs_xsetgroups(afs_proc_t *p, const void *args, register_t *retval)
46 int code = 0;
47 struct vrequest treq;
48 afs_ucred_t *cred = osi_proccred(p);
50 AFS_STATCNT(afs_xsetgroups);
52 AFS_GLOCK();
53 code = afs_InitReq(&treq, cred);
54 AFS_GUNLOCK();
56 if (code)
57 return code;
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') {
68 AFS_GLOCK();
69 /* we've already done a setpag, so now we redo it */
70 AddPag(p, treq.uid, &cred);
71 AFS_GUNLOCK();
74 return code;
77 int
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];
82 int ngroups, code;
83 int j;
85 AFS_STATCNT(setpag);
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) {
90 return (E2BIG);
92 for (j = ngroups - 1; j >= 1; j--) {
93 gidset[j + 2] = gidset[j];
95 ngroups += 2;
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);
100 return code;
104 static int
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);
112 return ngroups;
116 static int
117 osi_setgroups(afs_proc_t *proc, afs_ucred_t **cred, int ngroups,
118 gid_t * gidset, int change_parent)
120 int code;
121 afs_ucred_t *ocred;
123 AFS_STATCNT(afs_setgroups); /* XXX rename statcnt */
125 if (ngroups > NGROUPS)
126 return EINVAL;
128 proc_crmod_enter();
130 if (!change_parent) {
131 ocred = *cred;
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);
141 return code;