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
8 #include <minix/callnr.h>
9 #include <minix/endpoint.h>
11 #include <minix/com.h>
15 /*===========================================================================*
17 *===========================================================================*/
21 /* Handle PM_GETUID, PM_GETGID, PM_GETGROUPS, PM_GETPID, PM_GETPGRP, PM_GETSID,
24 register struct mproc
*rmp
= mp
;
30 ngroups
= m_in
.m_lc_pm_groups
.num
;
31 if (ngroups
> NGROUPS_MAX
|| ngroups
< 0)
39 if (ngroups
< rmp
->mp_ngroups
)
40 /* Asking for less groups than available */
43 r
= sys_datacopy(SELF
, (vir_bytes
) rmp
->mp_sgroups
, who_e
,
44 m_in
.m_lc_pm_groups
.ptr
, ngroups
* sizeof(gid_t
));
53 rmp
->mp_reply
.m_pm_lc_getuid
.euid
= rmp
->mp_effuid
;
58 rmp
->mp_reply
.m_pm_lc_getgid
.egid
= rmp
->mp_effgid
;
62 r
= mproc
[who_p
].mp_pid
;
63 rmp
->mp_reply
.m_pm_lc_getpid
.parent_pid
= mproc
[rmp
->mp_parent
].mp_pid
;
73 pid_t p
= m_in
.m_lc_pm_getsid
.pid
;
74 target
= p
? find_proc(p
) : &mproc
[who_p
];
77 r
= target
->mp_procgrp
;
81 r
= !!(rmp
->mp_flags
& TAINTED
);
91 /*===========================================================================*
93 *===========================================================================*/
97 /* Handle PM_SETUID, PM_SETEUID, PM_SETGID, PM_SETGROUPS, PM_SETEGID, and
98 * SETSID. These calls have in common that, if successful, they will be
99 * forwarded to VFS as well.
101 register struct mproc
*rmp
= mp
;
108 memset(&m
, 0, sizeof(m
));
112 uid
= m_in
.m_lc_pm_setuid
.uid
;
113 /* NetBSD specific semantics: setuid(geteuid()) may fail. */
114 if (rmp
->mp_realuid
!= uid
&& rmp
->mp_effuid
!= SUPER_USER
)
116 /* BSD semantics: always update all three fields. */
117 rmp
->mp_realuid
= uid
;
118 rmp
->mp_effuid
= uid
;
121 m
.m_type
= VFS_PM_SETUID
;
122 m
.VFS_PM_ENDPT
= rmp
->mp_endpoint
;
123 m
.VFS_PM_EID
= rmp
->mp_effuid
;
124 m
.VFS_PM_RID
= rmp
->mp_realuid
;
129 uid
= m_in
.m_lc_pm_setuid
.uid
;
130 /* BSD semantics: seteuid(geteuid()) may fail. */
131 if (rmp
->mp_realuid
!= uid
&& rmp
->mp_svuid
!= uid
&&
132 rmp
->mp_effuid
!= SUPER_USER
)
134 rmp
->mp_effuid
= uid
;
136 m
.m_type
= VFS_PM_SETUID
;
137 m
.VFS_PM_ENDPT
= rmp
->mp_endpoint
;
138 m
.VFS_PM_EID
= rmp
->mp_effuid
;
139 m
.VFS_PM_RID
= rmp
->mp_realuid
;
144 gid
= m_in
.m_lc_pm_setgid
.gid
;
145 if (rmp
->mp_realgid
!= gid
&& rmp
->mp_effuid
!= SUPER_USER
)
147 rmp
->mp_realgid
= gid
;
148 rmp
->mp_effgid
= gid
;
151 m
.m_type
= VFS_PM_SETGID
;
152 m
.VFS_PM_ENDPT
= rmp
->mp_endpoint
;
153 m
.VFS_PM_EID
= rmp
->mp_effgid
;
154 m
.VFS_PM_RID
= rmp
->mp_realgid
;
159 gid
= m_in
.m_lc_pm_setgid
.gid
;
160 if (rmp
->mp_realgid
!= gid
&& rmp
->mp_svgid
!= gid
&&
161 rmp
->mp_effuid
!= SUPER_USER
)
163 rmp
->mp_effgid
= gid
;
165 m
.m_type
= VFS_PM_SETGID
;
166 m
.VFS_PM_ENDPT
= rmp
->mp_endpoint
;
167 m
.VFS_PM_EID
= rmp
->mp_effgid
;
168 m
.VFS_PM_RID
= rmp
->mp_realgid
;
173 if (rmp
->mp_effuid
!= SUPER_USER
)
176 ngroups
= m_in
.m_lc_pm_groups
.num
;
178 if (ngroups
> NGROUPS_MAX
|| ngroups
< 0)
181 if (ngroups
> 0 && m_in
.m_lc_pm_groups
.ptr
== 0)
184 r
= sys_datacopy(who_e
, m_in
.m_lc_pm_groups
.ptr
, SELF
,
185 (vir_bytes
) rmp
->mp_sgroups
,
186 ngroups
* sizeof(gid_t
));
190 for (i
= 0; i
< ngroups
; i
++) {
191 if (rmp
->mp_sgroups
[i
] > GID_MAX
)
194 for (i
= ngroups
; i
< NGROUPS_MAX
; i
++) {
195 rmp
->mp_sgroups
[i
] = 0;
197 rmp
->mp_ngroups
= ngroups
;
199 m
.m_type
= VFS_PM_SETGROUPS
;
200 m
.VFS_PM_ENDPT
= rmp
->mp_endpoint
;
201 m
.VFS_PM_GROUP_NO
= rmp
->mp_ngroups
;
202 m
.VFS_PM_GROUP_ADDR
= (char *) rmp
->mp_sgroups
;
206 if (rmp
->mp_procgrp
== rmp
->mp_pid
) return(EPERM
);
207 rmp
->mp_procgrp
= rmp
->mp_pid
;
209 m
.m_type
= VFS_PM_SETSID
;
210 m
.VFS_PM_ENDPT
= rmp
->mp_endpoint
;
218 /* Send the request to VFS */
221 /* Do not reply until VFS has processed the request */