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)
32 afs_getgroups(struct ucred
*cred
, int ngroups
, gid_t
* gidset
);
35 afs_setgroups(struct proc
*proc
, struct ucred
**cred
, int ngroups
,
36 gid_t
* gidset
, int change_parent
);
39 Afs_xsetgroups(p
, args
, retval
)
47 AFS_STATCNT(afs_xsetgroups
);
52 code
= afs_InitReq(&treq
, p
->p_rcred
);
57 code
= setgroups(p
, args
, retval
);
59 * Note that if there is a pag already in the new groups we don't
60 * overwrite it with the old pag.
62 if (PagInCred(p
->p_rcred
) == NOPAG
) {
63 if (((treq
.uid
>> 24) & 0xff) == 'A') {
65 /* we've already done a setpag, so now we redo it */
66 AddPag(p
, treq
.uid
, &p
->p_rcred
);
75 setpag(struct proc
*proc
, struct ucred
**cred
, afs_uint32 pagvalue
,
76 afs_uint32
* newpag
, int change_parent
)
78 gid_t gidset
[NGROUPS
];
83 ngroups
= afs_getgroups(*cred
, NGROUPS
, gidset
);
85 * If the group list is empty, use the task's primary group as the group
86 * list. Otherwise, when setting the PAG, group 0 will be set to arbitrary
87 * gibberish and the PAG, which starts at group offset 1, will not be
88 * properly set because the group count will be wrong (2 instead of 3).
91 gidset
[0] = (*cred
)->cr_gid
;
94 if (afs_get_pag_from_groups(gidset
[1], gidset
[2]) == NOPAG
) {
95 /* We will have to shift grouplist to make room for pag */
96 if (ngroups
+ 2 > NGROUPS
) {
99 for (j
= ngroups
- 1; j
>= 0; j
--) {
100 gidset
[j
+ 2] = gidset
[j
];
104 *newpag
= (pagvalue
== -1 ? genpag() : pagvalue
);
105 afs_get_groups_from_pag(*newpag
, &gidset
[1], &gidset
[2]);
106 code
= afs_setgroups(proc
, cred
, ngroups
, gidset
, change_parent
);
112 afs_getgroups(struct ucred
*cred
, int ngroups
, gid_t
* gidset
)
114 int ngrps
, savengrps
;
117 AFS_STATCNT(afs_getgroups
);
118 savengrps
= ngrps
= MIN(ngroups
, cred
->cr_ngroups
);
119 gp
= cred
->cr_groups
;
127 afs_setgroups(struct proc
*proc
, struct ucred
**cred
, int ngroups
,
128 gid_t
* gidset
, int change_parent
)
130 struct ucred
*cr
= *cred
;
133 AFS_STATCNT(afs_setgroups
);
135 if (ngroups
> NGROUPS
)
141 for (i
= 0; i
< ngroups
; i
++)
142 cr
->cr_groups
[i
] = gidset
[i
];
143 for (i
= ngroups
; i
< NGROUPS
; i
++)
144 cr
->cr_groups
[i
] = NOGROUP
;
145 cr
->cr_ngroups
= ngroups
;