xref: /minix3/minix/servers/ipc/utility.c (revision 0baafa0ef4760fc6c0d2e86ae5f07c8acb9cd272)
1433d6423SLionel Sambuc #include "inc.h"
2433d6423SLionel Sambuc 
3*0baafa0eSDavid van Moolenbroek int
4*0baafa0eSDavid van Moolenbroek check_perm(struct ipc_perm * req, endpoint_t who, int mode)
5433d6423SLionel Sambuc {
6433d6423SLionel Sambuc 	int req_mode;
7433d6423SLionel Sambuc 	int cur_mode;
8*0baafa0eSDavid van Moolenbroek 	uid_t uid;
9*0baafa0eSDavid van Moolenbroek 	gid_t gid;
10433d6423SLionel Sambuc 
11*0baafa0eSDavid van Moolenbroek 	uid = getnuid(who);
12*0baafa0eSDavid van Moolenbroek 	gid = getngid(who);
13433d6423SLionel Sambuc 	mode &= 0666;
14433d6423SLionel Sambuc 
15*0baafa0eSDavid van Moolenbroek 	/* Root is allowed to do anything. */
16433d6423SLionel Sambuc 	if (uid == 0)
17433d6423SLionel Sambuc 		return 1;
18433d6423SLionel Sambuc 
19433d6423SLionel Sambuc 	if (uid == req->uid || uid == req->cuid) {
20*0baafa0eSDavid van Moolenbroek 		/* Same user. */
21433d6423SLionel Sambuc 		req_mode = (req->mode >> 6) & 0x7;
22433d6423SLionel Sambuc 		cur_mode = (mode >> 6) & 0x7;
23433d6423SLionel Sambuc 	} else if (gid == req->gid || gid == req->cgid) {
24*0baafa0eSDavid van Moolenbroek 		/* Same group. */
25433d6423SLionel Sambuc 		req_mode = (req->mode >> 3) & 0x7;
26433d6423SLionel Sambuc 		cur_mode = (mode >> 3) & 0x7;
27433d6423SLionel Sambuc 	} else {
28*0baafa0eSDavid van Moolenbroek 		/* Other user and group. */
29433d6423SLionel Sambuc 		req_mode = req->mode & 0x7;
30433d6423SLionel Sambuc 		cur_mode = mode & 0x7;
31433d6423SLionel Sambuc 	}
32433d6423SLionel Sambuc 
33*0baafa0eSDavid van Moolenbroek 	return (cur_mode && ((cur_mode & req_mode) == cur_mode));
34433d6423SLionel Sambuc }
35