lib:util: Always include unistd.h for setgroups
[samba.git] / lib / util / setid.c
1 /*
2    Unix SMB/CIFS implementation.
3    setXXid() functions for Samba.
4    Copyright (C) Jeremy Allison 2012
5
6    This program is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 3 of the License, or
9    (at your option) any later version.
10
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15
16    You should have received a copy of the GNU General Public License
17    along with this program.  If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 #ifndef AUTOCONF_TEST
21 #include "replace.h"
22 #include "system/passwd.h"
23
24 #include "../lib/util/setid.h"
25
26 #else
27
28 /* Inside autoconf test. */
29 #if defined(HAVE_UNISTD_H)
30 #include <unistd.h>
31 #endif
32 #include <stdlib.h>
33 #include <stdio.h>
34 #include <sys/types.h>
35 #include <errno.h>
36
37 #if defined(HAVE_UNISTD_H)
38 #include <unistd.h>
39 #endif
40 #ifdef HAVE_SYS_PRIV_H
41 #include <sys/priv.h>
42 #endif
43 #ifdef HAVE_SYS_ID_H
44 #include <sys/id.h>
45 #endif
46
47 /* autoconf tests don't include setid.h */
48 int samba_setresuid(uid_t ruid, uid_t euid, uid_t suid);
49 int samba_setresgid(gid_t rgid, gid_t egid, gid_t sgid);
50 int samba_setreuid(uid_t ruid, uid_t euid);
51 int samba_setregid(gid_t rgid, gid_t egid);
52 int samba_seteuid(uid_t euid);
53 int samba_setegid(gid_t egid);
54 int samba_setuid(uid_t uid);
55 int samba_setgid(gid_t gid);
56 int samba_setuidx(int flags, uid_t uid);
57 int samba_setgidx(int flags, gid_t gid);
58 int samba_setgroups(size_t setlen, const gid_t *gidset);
59
60 #endif
61
62 #if defined(HAVE_LINUX_THREAD_CREDENTIALS)
63 #if defined(HAVE_SYSCALL_H)
64 #include <syscall.h>
65 #endif
66
67 #if defined(HAVE_SYS_SYSCALL_H)
68 #include <sys/syscall.h>
69 #endif
70
71 /* Ensure we can't compile in a mixed syscall setup. */
72 #if !defined(USE_LINUX_32BIT_SYSCALLS)
73 #if defined(SYS_setresuid32) || defined(SYS_setresgid32) || defined(SYS_setreuid32) || defined(SYS_setregid32) || defined(SYS_setuid32) || defined(SYS_setgid32) || defined(SYS_setgroups32)
74 #error Mixture of 32-bit Linux system calls and 64-bit calls.
75 #endif
76 #endif
77
78 #endif
79
80 /* All the setXX[ug]id functions and setgroups Samba uses. */
81 int samba_setresuid(uid_t ruid, uid_t euid, uid_t suid)
82 {
83 #if defined(HAVE_LINUX_THREAD_CREDENTIALS)
84 #if defined(USE_LINUX_32BIT_SYSCALLS)
85         return syscall(SYS_setresuid32, ruid, euid, suid);
86 #else
87         return syscall(SYS_setresuid, ruid, euid, suid);
88 #endif
89 #elif defined(HAVE_SETRESUID)
90         return setresuid(ruid, euid, suid);
91 #else
92         errno = ENOSYS;
93         return -1;
94 #endif
95 }
96
97 int samba_setresgid(gid_t rgid, gid_t egid, gid_t sgid)
98 {
99 #if defined(HAVE_LINUX_THREAD_CREDENTIALS)
100 #if defined(USE_LINUX_32BIT_SYSCALLS)
101         return syscall(SYS_setresgid32, rgid, egid, sgid);
102 #else
103         return syscall(SYS_setresgid, rgid, egid, sgid);
104 #endif
105 #elif defined(HAVE_SETRESGID)
106         return setresgid(rgid, egid, sgid);
107 #else
108         errno = ENOSYS;
109         return -1;
110 #endif
111 }
112
113 int samba_setreuid(uid_t ruid, uid_t euid)
114 {
115 #if defined(HAVE_LINUX_THREAD_CREDENTIALS)
116 #if defined(USE_LINUX_32BIT_SYSCALLS)
117         return syscall(SYS_setreuid32, ruid, euid);
118 #else
119         return syscall(SYS_setreuid, ruid, euid);
120 #endif
121 #elif defined(HAVE_SETREUID)
122         return setreuid(ruid, euid);
123 #else
124         errno = ENOSYS;
125         return -1;
126 #endif
127 }
128
129 int samba_setregid(gid_t rgid, gid_t egid)
130 {
131 #if defined(HAVE_LINUX_THREAD_CREDENTIALS)
132 #if defined(USE_LINUX_32BIT_SYSCALLS)
133         return syscall(SYS_setregid32, rgid, egid);
134 #else
135         return syscall(SYS_setregid, rgid, egid);
136 #endif
137 #elif defined(HAVE_SETREGID)
138         return setregid(rgid, egid);
139 #else
140         errno = ENOSYS;
141         return -1;
142 #endif
143 }
144
145 int samba_seteuid(uid_t euid)
146 {
147 #if defined(HAVE_LINUX_THREAD_CREDENTIALS)
148 #if defined(USE_LINUX_32BIT_SYSCALLS)
149         /* seteuid is not a separate system call. */
150         return syscall(SYS_setresuid32, -1, euid, -1);
151 #else
152         /* seteuid is not a separate system call. */
153         return syscall(SYS_setresuid, -1, euid, -1);
154 #endif
155 #elif defined(HAVE_SETEUID)
156         return seteuid(euid);
157 #else
158         errno = ENOSYS;
159         return -1;
160 #endif
161 }
162
163 int samba_setegid(gid_t egid)
164 {
165 #if defined(HAVE_LINUX_THREAD_CREDENTIALS)
166 #if defined(USE_LINUX_32BIT_SYSCALLS)
167         /* setegid is not a separate system call. */
168         return syscall(SYS_setresgid32, -1, egid, -1);
169 #else
170         /* setegid is not a separate system call. */
171         return syscall(SYS_setresgid, -1, egid, -1);
172 #endif
173 #elif defined(HAVE_SETEGID)
174         return setegid(egid);
175 #else
176         errno = ENOSYS;
177         return -1;
178 #endif
179 }
180
181 int samba_setuid(uid_t uid)
182 {
183 #if defined(HAVE_LINUX_THREAD_CREDENTIALS)
184 #if defined(USE_LINUX_32BIT_SYSCALLS)
185         return syscall(SYS_setuid32, uid);
186 #else
187         return syscall(SYS_setuid, uid);
188 #endif
189 #elif defined(HAVE_SETUID)
190         return setuid(uid);
191 #else
192         errno = ENOSYS;
193         return -1;
194 #endif
195 }
196
197 int samba_setgid(gid_t gid)
198 {
199 #if defined(HAVE_LINUX_THREAD_CREDENTIALS)
200 #if defined(USE_LINUX_32BIT_SYSCALLS)
201         return syscall(SYS_setgid32, gid);
202 #else
203         return syscall(SYS_setgid, gid);
204 #endif
205 #elif defined(HAVE_SETGID)
206         return setgid(gid);
207 #else
208         errno = ENOSYS;
209         return -1;
210 #endif
211 }
212
213 int samba_setuidx(int flags, uid_t uid)
214 {
215 #if defined(HAVE_SETUIDX)
216         return setuidx(flags, uid);
217 #else
218         /* HAVE_LINUX_THREAD_CREDENTIALS doesn't have this. */
219         errno = ENOSYS;
220         return -1;
221 #endif
222 }
223
224 int samba_setgidx(int flags, gid_t gid)
225 {
226 #if defined(HAVE_SETGIDX)
227         return setgidx(flags, gid);
228 #else
229         /* HAVE_LINUX_THREAD_CREDENTIALS doesn't have this. */
230         errno = ENOSYS;
231         return -1;
232 #endif
233 }
234
235 int samba_setgroups(size_t setlen, const gid_t *gidset)
236 {
237 #if defined(HAVE_LINUX_THREAD_CREDENTIALS)
238 #if defined(USE_LINUX_32BIT_SYSCALLS)
239         return syscall(SYS_setgroups32, setlen, gidset);
240 #else
241         return syscall(SYS_setgroups, setlen, gidset);
242 #endif
243 #elif defined(HAVE_SETGROUPS)
244         return setgroups(setlen, gidset);
245 #else
246         errno = ENOSYS;
247         return -1;
248 #endif
249 }