Commit | Line | Data |
---|---|---|
805e021f CE |
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 | * osi_groups.c | |
11 | * | |
12 | * Implements: | |
13 | * Afs_xsetgroups (syscall) | |
14 | * setpag | |
15 | * | |
16 | */ | |
17 | #include <afsconfig.h> | |
18 | #include "afs/param.h" | |
19 | #include <sys/param.h> | |
20 | #include <sys/sysproto.h> | |
21 | ||
22 | ||
23 | #include "afs/sysincludes.h" | |
24 | #include "afsincludes.h" | |
25 | #include "afs/afs_stats.h" /* statistics */ | |
26 | ||
27 | static int | |
28 | afs_getgroups(struct ucred *cred, int ngroups, gid_t * gidset); | |
29 | ||
30 | static int | |
31 | afs_setgroups(struct thread *td, struct ucred **cred, int ngroups, | |
32 | gid_t * gidset, int change_parent); | |
33 | ||
34 | ||
35 | int | |
36 | Afs_xsetgroups(struct thread *td, struct setgroups_args *uap) | |
37 | { | |
38 | int code = 0; | |
39 | struct vrequest treq; | |
40 | struct ucred *cr; | |
41 | ||
42 | cr = crdup(td->td_ucred); | |
43 | ||
44 | AFS_STATCNT(afs_xsetgroups); | |
45 | AFS_GLOCK(); | |
46 | ||
47 | code = afs_InitReq(&treq, cr); | |
48 | AFS_GUNLOCK(); | |
49 | crfree(cr); | |
50 | if (code) | |
51 | #if (__FreeBSD_version >= 900044) | |
52 | return sys_setgroups(td, uap); /* afs has shut down */ | |
53 | #else | |
54 | return setgroups(td, uap); /* afs has shut down */ | |
55 | #endif | |
56 | ||
57 | #if (__FreeBSD_version >= 900044) | |
58 | code = sys_setgroups(td, uap); | |
59 | #else | |
60 | code = setgroups(td, uap); | |
61 | #endif | |
62 | /* Note that if there is a pag already in the new groups we don't | |
63 | * overwrite it with the old pag. | |
64 | */ | |
65 | cr = crdup(td->td_ucred); | |
66 | ||
67 | if (PagInCred(cr) == NOPAG) { | |
68 | if (((treq.uid >> 24) & 0xff) == 'A') { | |
69 | AFS_GLOCK(); | |
70 | /* we've already done a setpag, so now we redo it */ | |
71 | AddPag(td, treq.uid, &cr); | |
72 | AFS_GUNLOCK(); | |
73 | } | |
74 | } | |
75 | crfree(cr); | |
76 | return code; | |
77 | } | |
78 | ||
79 | ||
80 | int | |
81 | setpag(struct thread *td, struct ucred **cred, afs_uint32 pagvalue, | |
82 | afs_uint32 * newpag, int change_parent) | |
83 | { | |
84 | #if defined(AFS_FBSD81_ENV) | |
85 | gid_t *gidset; | |
86 | int gidset_len = ngroups_max + 1; | |
87 | #elif defined(AFS_FBSD80_ENV) | |
88 | gid_t *gidset; | |
89 | int gidset_len = NGROUPS; /* 1024 */ | |
90 | #else | |
91 | gid_t gidset[NGROUPS]; | |
92 | int gidset_len = NGROUPS; /* 16 */ | |
93 | #endif | |
94 | int ngroups, code; | |
95 | int j; | |
96 | ||
97 | AFS_STATCNT(setpag); | |
98 | #ifdef AFS_FBSD80_ENV | |
99 | gidset = osi_Alloc(gidset_len * sizeof(gid_t)); | |
100 | #endif | |
101 | ngroups = afs_getgroups(*cred, gidset_len, gidset); | |
102 | if (afs_get_pag_from_groups(gidset[1], gidset[2]) == NOPAG) { | |
103 | /* We will have to shift grouplist to make room for pag */ | |
104 | if (ngroups + 2 > gidset_len) { | |
105 | return (E2BIG); | |
106 | } | |
107 | for (j = ngroups - 1; j >= 1; j--) { | |
108 | gidset[j + 2] = gidset[j]; | |
109 | } | |
110 | ngroups += 2; | |
111 | } | |
112 | *newpag = (pagvalue == -1 ? genpag() : pagvalue); | |
113 | afs_get_groups_from_pag(*newpag, &gidset[1], &gidset[2]); | |
114 | code = afs_setgroups(td, cred, ngroups, gidset, change_parent); | |
115 | #ifdef AFS_FBSD80_ENV | |
116 | osi_Free(gidset, gidset_len * sizeof(gid_t)); | |
117 | #endif | |
118 | return code; | |
119 | } | |
120 | ||
121 | ||
122 | static int | |
123 | afs_getgroups(struct ucred *cred, int ngroups, gid_t * gidset) | |
124 | { | |
125 | int ngrps, savengrps; | |
126 | gid_t *gp; | |
127 | ||
128 | AFS_STATCNT(afs_getgroups); | |
129 | savengrps = ngrps = MIN(ngroups, cred->cr_ngroups); | |
130 | gp = cred->cr_groups; | |
131 | while (ngrps--) | |
132 | *gidset++ = *gp++; | |
133 | return savengrps; | |
134 | } | |
135 | ||
136 | ||
137 | static int | |
138 | afs_setgroups(struct thread *td, struct ucred **cred, int ngroups, | |
139 | gid_t * gidset, int change_parent) | |
140 | { | |
141 | return (0); | |
142 | } |