Fixed extern declaration from pointer to array
[minix.git] / servers / pm / getset.c
bloba2da959d770f367bc1ce0a072e3d3553ed13ea3e
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"
14 #include "param.h"
16 /*===========================================================================*
17 * do_get *
18 *===========================================================================*/
19 PUBLIC int do_get()
21 /* Handle GETUID, GETGID, GETPID, GETPGRP.
24 register struct mproc *rmp = mp;
25 int r, proc;
26 int ngroups;
28 switch(call_nr) {
29 case GETGROUPS:
30 ngroups = m_in.grp_no;
31 if (ngroups > NGROUPS_MAX || ngroups < 0)
32 return(EINVAL);
34 if (ngroups == 0) {
35 r = rmp->mp_ngroups;
36 break;
39 if (ngroups < rmp->mp_ngroups)
40 /* Asking for less groups than available */
41 return(EINVAL);
44 r = sys_datacopy(SELF, (vir_bytes) rmp->mp_sgroups, who_e,
45 (vir_bytes) m_in.groupsp, ngroups * sizeof(gid_t));
47 if (r != OK)
48 return(r);
50 r = rmp->mp_ngroups;
51 break;
52 case GETUID:
53 r = rmp->mp_realuid;
54 rmp->mp_reply.reply_res2 = rmp->mp_effuid;
55 break;
57 case GETGID:
58 r = rmp->mp_realgid;
59 rmp->mp_reply.reply_res2 = rmp->mp_effgid;
60 break;
62 case MINIX_GETPID:
63 r = mproc[who_p].mp_pid;
64 rmp->mp_reply.reply_res2 = mproc[rmp->mp_parent].mp_pid;
65 break;
67 case GETPGRP:
68 r = rmp->mp_procgrp;
69 break;
71 default:
72 r = EINVAL;
73 break;
75 return(r);
78 /*===========================================================================*
79 * do_set *
80 *===========================================================================*/
81 PUBLIC int do_set()
83 /* Handle SETUID, SETEUID, SETGID, SETEGID, SETSID. These calls have in common
84 * that, if successful, they will be forwarded to VFS as well.
86 register struct mproc *rmp = mp;
87 message m;
88 int r, i;
89 int ngroups;
91 switch(call_nr) {
92 case SETUID:
93 case SETEUID:
94 if (rmp->mp_realuid != (uid_t) m_in.usr_id &&
95 rmp->mp_effuid != SUPER_USER)
96 return(EPERM);
97 if(call_nr == SETUID) rmp->mp_realuid = (uid_t) m_in.usr_id;
98 rmp->mp_effuid = (uid_t) m_in.usr_id;
100 m.m_type = PM_SETUID;
101 m.PM_PROC = rmp->mp_endpoint;
102 m.PM_EID = rmp->mp_effuid;
103 m.PM_RID = rmp->mp_realuid;
105 break;
107 case SETGID:
108 case SETEGID:
109 if (rmp->mp_realgid != (gid_t) m_in.grp_id &&
110 rmp->mp_effuid != SUPER_USER)
111 return(EPERM);
112 if(call_nr == SETGID) rmp->mp_realgid = (gid_t) m_in.grp_id;
113 rmp->mp_effgid = (gid_t) m_in.grp_id;
115 m.m_type = PM_SETGID;
116 m.PM_PROC = rmp->mp_endpoint;
117 m.PM_EID = rmp->mp_effgid;
118 m.PM_RID = rmp->mp_realgid;
120 break;
121 case SETGROUPS:
122 if (rmp->mp_effuid != SUPER_USER)
123 return(EPERM);
125 ngroups = m_in.grp_no;
127 if (ngroups > NGROUPS_MAX || ngroups < 0)
128 return(EINVAL);
130 if (m_in.groupsp == NULL)
131 return(EFAULT);
133 r = sys_datacopy(who_e, (vir_bytes) m_in.groupsp, SELF,
134 (vir_bytes) rmp->mp_sgroups,
135 ngroups * sizeof(gid_t));
136 if (r != OK)
137 return(r);
139 for (i = ngroups; i < NGROUPS_MAX; i++)
140 rmp->mp_sgroups[i] = 0;
141 rmp->mp_ngroups = ngroups;
143 m.m_type = PM_SETGROUPS;
144 m.PM_PROC = rmp->mp_endpoint;
145 m.PM_GROUP_NO = rmp->mp_ngroups;
146 m.PM_GROUP_ADDR = rmp->mp_sgroups;
148 break;
149 case SETSID:
150 if (rmp->mp_procgrp == rmp->mp_pid) return(EPERM);
151 rmp->mp_procgrp = rmp->mp_pid;
153 m.m_type = PM_SETSID;
154 m.PM_PROC = rmp->mp_endpoint;
156 break;
158 default:
159 return(EINVAL);
162 /* Send the request to FS */
163 tell_fs(rmp, &m);
165 /* Do not reply until FS has processed the request */
166 return(SUSPEND);