tools/llvm: Do not build with symbols
[minix3.git] / minix / servers / pm / getset.c
blob2ed157c24247735a3c5fe300df76ff99765c4651
1 /* This file handles the 6 system calls that get and set uids and gids.
2 * It also handles getpid(), setsid(), and getpgrp(). The code for each
3 * one is so tiny that it hardly seemed worthwhile to make each a separate
4 * function.
5 */
7 #include "pm.h"
8 #include <minix/callnr.h>
9 #include <minix/endpoint.h>
10 #include <limits.h>
11 #include <minix/com.h>
12 #include <signal.h>
13 #include "mproc.h"
15 /*===========================================================================*
16 * do_get *
17 *===========================================================================*/
18 int do_get()
20 /* Handle PM_GETUID, PM_GETGID, PM_GETGROUPS, PM_GETPID, PM_GETPGRP, PM_GETSID,
21 * PM_ISSETUGID.
23 register struct mproc *rmp = mp;
24 int r;
25 int ngroups;
27 switch(call_nr) {
28 case PM_GETGROUPS:
29 ngroups = m_in.m_lc_pm_groups.num;
30 if (ngroups > NGROUPS_MAX || ngroups < 0)
31 return(EINVAL);
33 if (ngroups == 0) {
34 r = rmp->mp_ngroups;
35 break;
38 if (ngroups < rmp->mp_ngroups)
39 /* Asking for less groups than available */
40 return(EINVAL);
42 r = sys_datacopy(SELF, (vir_bytes) rmp->mp_sgroups, who_e,
43 m_in.m_lc_pm_groups.ptr, ngroups * sizeof(gid_t));
45 if (r != OK)
46 return(r);
48 r = rmp->mp_ngroups;
49 break;
50 case PM_GETUID:
51 r = rmp->mp_realuid;
52 rmp->mp_reply.m_pm_lc_getuid.euid = rmp->mp_effuid;
53 break;
55 case PM_GETGID:
56 r = rmp->mp_realgid;
57 rmp->mp_reply.m_pm_lc_getgid.egid = rmp->mp_effgid;
58 break;
60 case PM_GETPID:
61 r = mproc[who_p].mp_pid;
62 rmp->mp_reply.m_pm_lc_getpid.parent_pid = mproc[rmp->mp_parent].mp_pid;
63 break;
65 case PM_GETPGRP:
66 r = rmp->mp_procgrp;
67 break;
69 case PM_GETSID:
71 struct mproc *target;
72 pid_t p = m_in.m_lc_pm_getsid.pid;
73 target = p ? find_proc(p) : &mproc[who_p];
74 r = ESRCH;
75 if(target)
76 r = target->mp_procgrp;
77 break;
79 case PM_ISSETUGID:
80 r = !!(rmp->mp_flags & TAINTED);
81 break;
83 default:
84 r = EINVAL;
85 break;
87 return(r);
90 /*===========================================================================*
91 * do_set *
92 *===========================================================================*/
93 int do_set()
95 /* Handle PM_SETUID, PM_SETEUID, PM_SETGID, PM_SETGROUPS, PM_SETEGID, and
96 * SETSID. These calls have in common that, if successful, they will be
97 * forwarded to VFS as well.
99 register struct mproc *rmp = mp;
100 message m;
101 int r, i;
102 int ngroups;
103 uid_t uid;
104 gid_t gid;
106 memset(&m, 0, sizeof(m));
108 switch(call_nr) {
109 case PM_SETUID:
110 case PM_SETEUID:
111 uid = m_in.m_lc_pm_setuid.uid;
112 if (rmp->mp_realuid != uid && rmp->mp_effuid != SUPER_USER)
113 return(EPERM);
114 if(call_nr == PM_SETUID) rmp->mp_realuid = uid;
115 rmp->mp_effuid = uid;
117 m.m_type = VFS_PM_SETUID;
118 m.VFS_PM_ENDPT = rmp->mp_endpoint;
119 m.VFS_PM_EID = rmp->mp_effuid;
120 m.VFS_PM_RID = rmp->mp_realuid;
122 break;
124 case PM_SETGID:
125 case PM_SETEGID:
126 gid = m_in.m_lc_pm_setgid.gid;
127 if (rmp->mp_realgid != gid && rmp->mp_effuid != SUPER_USER)
128 return(EPERM);
129 if(call_nr == PM_SETGID) rmp->mp_realgid = gid;
130 rmp->mp_effgid = gid;
132 m.m_type = VFS_PM_SETGID;
133 m.VFS_PM_ENDPT = rmp->mp_endpoint;
134 m.VFS_PM_EID = rmp->mp_effgid;
135 m.VFS_PM_RID = rmp->mp_realgid;
137 break;
138 case PM_SETGROUPS:
139 if (rmp->mp_effuid != SUPER_USER)
140 return(EPERM);
142 ngroups = m_in.m_lc_pm_groups.num;
144 if (ngroups > NGROUPS_MAX || ngroups < 0)
145 return(EINVAL);
147 if (ngroups > 0 && m_in.m_lc_pm_groups.ptr == 0)
148 return(EFAULT);
150 r = sys_datacopy(who_e, m_in.m_lc_pm_groups.ptr, SELF,
151 (vir_bytes) rmp->mp_sgroups,
152 ngroups * sizeof(gid_t));
153 if (r != OK)
154 return(r);
156 for (i = 0; i < ngroups; i++) {
157 if (rmp->mp_sgroups[i] > GID_MAX)
158 return(EINVAL);
160 for (i = ngroups; i < NGROUPS_MAX; i++) {
161 rmp->mp_sgroups[i] = 0;
163 rmp->mp_ngroups = ngroups;
165 m.m_type = VFS_PM_SETGROUPS;
166 m.VFS_PM_ENDPT = rmp->mp_endpoint;
167 m.VFS_PM_GROUP_NO = rmp->mp_ngroups;
168 m.VFS_PM_GROUP_ADDR = (char *) rmp->mp_sgroups;
170 break;
171 case PM_SETSID:
172 if (rmp->mp_procgrp == rmp->mp_pid) return(EPERM);
173 rmp->mp_procgrp = rmp->mp_pid;
175 m.m_type = VFS_PM_SETSID;
176 m.VFS_PM_ENDPT = rmp->mp_endpoint;
178 break;
180 default:
181 return(EINVAL);
184 /* Send the request to VFS */
185 tell_vfs(rmp, &m);
187 /* Do not reply until VFS has processed the request */
188 return(SUSPEND);