1/*
2 * Copyright (c) 2018 FUJITSU LIMITED. All rights reserved.
3 * Author: yang xu <xuyang.jy@cn.fujitsu.com>
4 *
5 * This program is free software;  you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY;  without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
13 * the GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19#ifndef COMPAT_TST_16_H__
20#define COMPAT_TST_16_H__
21
22#include <errno.h>
23#include <grp.h>
24#include <sys/fsuid.h>
25#include <sys/types.h>
26#include <unistd.h>
27
28#include "compat_gid.h"
29#include "compat_uid.h"
30#include "lapi/syscalls.h"
31
32int setresuid(uid_t ruid, uid_t euid, uid_t suid);
33int setresgid(gid_t rgid, gid_t egid, gid_t sgid);
34
35
36/* If the platform has __NR_sys_name32 defined it
37 * means that __NR_sys_name is a 16-bit version of
38 * sys_name() syscall
39 */
40#ifdef TST_USE_COMPAT16_SYSCALL
41# define TST_CREATE_SYSCALL(sys_name, ...) ({ \
42	if (__NR_##sys_name##32 != __LTP__NR_INVALID_SYSCALL) { \
43		return tst_syscall(__NR_##sys_name, ##__VA_ARGS__); \
44	} else { \
45		tst_brk(TCONF, \
46			"16-bit version of %s() is not supported on your " \
47			"platform", #sys_name); \
48		return -1; \
49	} \
50})
51#else
52# define TST_CREATE_SYSCALL(sys_name, ...) ({\
53	return sys_name(__VA_ARGS__); \
54})
55#endif
56
57#define UID16_CHECK(uid, sys_name) ({ \
58	if (!UID_SIZE_CHECK(uid)) { \
59		tst_brk(TBROK, \
60			"uid %d of %s is too large for testing 16-bit " \
61			"version of %s()", uid, #uid, #sys_name); \
62	} \
63})
64#define GID16_CHECK(gid, sys_name) ({ \
65	if (!GID_SIZE_CHECK(gid)) { \
66		tst_brk(TBROK, \
67			"gid %d of %s is too large for testing 16-bit " \
68			"version of %s()", gid, #gid, #sys_name); \
69	} \
70})
71
72int SETGROUPS(size_t gidsetsize, GID_T *list)
73{
74	TST_CREATE_SYSCALL(setgroups, gidsetsize, list);
75}
76
77int GETGROUPS(size_t gidsetsize, GID_T *list)
78{
79	TST_CREATE_SYSCALL(getgroups, gidsetsize, list);
80}
81
82int SETUID(UID_T uid)
83{
84	TST_CREATE_SYSCALL(setuid, uid);
85}
86
87UID_T GETUID(void)
88{
89	TST_CREATE_SYSCALL(getuid);
90}
91
92int SETGID(GID_T gid)
93{
94	TST_CREATE_SYSCALL(setgid, gid);
95}
96
97GID_T GETGID(void)
98{
99	TST_CREATE_SYSCALL(getgid);
100}
101
102UID_T GETEUID(void)
103{
104	TST_CREATE_SYSCALL(geteuid);
105}
106
107GID_T GETEGID(void)
108{
109	TST_CREATE_SYSCALL(getegid);
110}
111
112int SETFSUID(UID_T uid)
113{
114	TST_CREATE_SYSCALL(setfsuid, uid);
115}
116
117int SETFSGID(GID_T gid)
118{
119	TST_CREATE_SYSCALL(setfsgid, gid);
120}
121
122int SETREUID(UID_T ruid, UID_T euid)
123{
124	TST_CREATE_SYSCALL(setreuid, ruid, euid);
125}
126int SETREGID(GID_T rgid, GID_T egid)
127{
128	TST_CREATE_SYSCALL(setregid, rgid, egid);
129}
130
131int SETRESUID(UID_T ruid, UID_T euid, UID_T suid)
132{
133	TST_CREATE_SYSCALL(setresuid, ruid, euid, suid);
134}
135
136int SETRESGID(GID_T rgid, GID_T egid, GID_T sgid)
137{
138	TST_CREATE_SYSCALL(setresgid, rgid, egid, sgid);
139}
140
141int FCHOWN(unsigned int fd, UID_T owner, GID_T group)
142{
143	TST_CREATE_SYSCALL(fchown, fd, owner, group);
144}
145
146int LCHOWN(const char *path, UID_T owner, GID_T group)
147{
148	TST_CREATE_SYSCALL(lchown, path, owner, group);
149}
150
151int CHOWN(const char *path, UID_T owner, GID_T group)
152{
153	TST_CREATE_SYSCALL(chown, path, owner, group);
154}
155#endif /* COMPAT_TST_16_H__ */
156