64-bit VFS_LSEEK_OFF
[minix3.git] / servers / pm / getset.c
blob347213ebcb4f45c88b8ca0efeba11ddb0665fc42
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.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 (vir_bytes) m_in.PM_GROUPS_PTR,
44 ngroups * sizeof(gid_t));
46 if (r != OK)
47 return(r);
49 r = rmp->mp_ngroups;
50 break;
51 case PM_GETUID:
52 r = rmp->mp_realuid;
53 rmp->mp_reply.PM_GETUID_EUID = rmp->mp_effuid;
54 break;
56 case PM_GETGID:
57 r = rmp->mp_realgid;
58 rmp->mp_reply.PM_GETGID_EGID = rmp->mp_effgid;
59 break;
61 case PM_GETPID:
62 r = mproc[who_p].mp_pid;
63 rmp->mp_reply.PM_GETPID_PARENT = mproc[rmp->mp_parent].mp_pid;
64 break;
66 case PM_GETPGRP:
67 r = rmp->mp_procgrp;
68 break;
70 case PM_GETSID:
72 struct mproc *target;
73 pid_t p = m_in.PM_GETSID_PID;
74 target = p ? find_proc(p) : &mproc[who_p];
75 r = ESRCH;
76 if(target)
77 r = target->mp_procgrp;
78 break;
80 case PM_ISSETUGID:
81 r = !!(rmp->mp_flags & TAINTED);
82 break;
84 default:
85 r = EINVAL;
86 break;
88 return(r);
91 /*===========================================================================*
92 * do_set *
93 *===========================================================================*/
94 int do_set()
96 /* Handle PM_SETUID, PM_SETEUID, PM_SETGID, PM_SETGROUPS, PM_SETEGID, and
97 * SETSID. These calls have in common that, if successful, they will be
98 * forwarded to VFS as well.
100 register struct mproc *rmp = mp;
101 message m;
102 int r, i;
103 int ngroups;
104 uid_t uid;
105 gid_t gid;
107 memset(&m, 0, sizeof(m));
109 switch(call_nr) {
110 case PM_SETUID:
111 case PM_SETEUID:
112 uid = (uid_t) m_in.PM_SETUID_UID;
113 if (rmp->mp_realuid != uid && rmp->mp_effuid != SUPER_USER)
114 return(EPERM);
115 if(call_nr == PM_SETUID) rmp->mp_realuid = uid;
116 rmp->mp_effuid = uid;
118 m.m_type = VFS_PM_SETUID;
119 m.VFS_PM_ENDPT = rmp->mp_endpoint;
120 m.VFS_PM_EID = rmp->mp_effuid;
121 m.VFS_PM_RID = rmp->mp_realuid;
123 break;
125 case PM_SETGID:
126 case PM_SETEGID:
127 gid = (gid_t) m_in.PM_SETGID_GID;
128 if (rmp->mp_realgid != gid && rmp->mp_effuid != SUPER_USER)
129 return(EPERM);
130 if(call_nr == PM_SETGID) rmp->mp_realgid = gid;
131 rmp->mp_effgid = gid;
133 m.m_type = VFS_PM_SETGID;
134 m.VFS_PM_ENDPT = rmp->mp_endpoint;
135 m.VFS_PM_EID = rmp->mp_effgid;
136 m.VFS_PM_RID = rmp->mp_realgid;
138 break;
139 case PM_SETGROUPS:
140 if (rmp->mp_effuid != SUPER_USER)
141 return(EPERM);
143 ngroups = m_in.PM_GROUPS_NUM;
145 if (ngroups > NGROUPS_MAX || ngroups < 0)
146 return(EINVAL);
148 if (ngroups > 0 && m_in.PM_GROUPS_PTR == NULL)
149 return(EFAULT);
151 r = sys_datacopy(who_e, (vir_bytes) m_in.PM_GROUPS_PTR, SELF,
152 (vir_bytes) rmp->mp_sgroups,
153 ngroups * sizeof(gid_t));
154 if (r != OK)
155 return(r);
157 for (i = 0; i < ngroups; i++) {
158 if (rmp->mp_sgroups[i] > GID_MAX)
159 return(EINVAL);
161 for (i = ngroups; i < NGROUPS_MAX; i++) {
162 rmp->mp_sgroups[i] = 0;
164 rmp->mp_ngroups = ngroups;
166 m.m_type = VFS_PM_SETGROUPS;
167 m.VFS_PM_ENDPT = rmp->mp_endpoint;
168 m.VFS_PM_GROUP_NO = rmp->mp_ngroups;
169 m.VFS_PM_GROUP_ADDR = (char *) rmp->mp_sgroups;
171 break;
172 case PM_SETSID:
173 if (rmp->mp_procgrp == rmp->mp_pid) return(EPERM);
174 rmp->mp_procgrp = rmp->mp_pid;
176 m.m_type = VFS_PM_SETSID;
177 m.VFS_PM_ENDPT = rmp->mp_endpoint;
179 break;
181 default:
182 return(EINVAL);
185 /* Send the request to VFS */
186 tell_vfs(rmp, &m);
188 /* Do not reply until VFS has processed the request */
189 return(SUSPEND);