1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
|
'\" et
.TH SETUID "3P" 2017 "IEEE/The Open Group" "POSIX Programmer's Manual"
.\"
.SH PROLOG
This manual page is part of the POSIX Programmer's Manual.
The Linux implementation of this interface may differ (consult
the corresponding Linux manual page for details of Linux behavior),
or the interface may not be implemented on Linux.
.\"
.SH NAME
setuid
\(em set user ID
.SH SYNOPSIS
.LP
.nf
#include <unistd.h>
.P
int setuid(uid_t \fIuid\fP);
.fi
.SH DESCRIPTION
If the process has appropriate privileges,
\fIsetuid\fR()
shall set the real user ID, effective user ID, and the saved
set-user-ID of the calling process to
.IR uid .
.P
If the process does not have appropriate privileges, but
.IR uid
is equal to the real user ID or the saved set-user-ID,
\fIsetuid\fR()
shall set the effective user ID to
.IR uid ;
the real user ID and saved set-user-ID shall remain unchanged.
.P
The
\fIsetuid\fR()
function shall not affect the supplementary group list in any way.
.SH "RETURN VALUE"
Upon successful completion, 0 shall be returned. Otherwise, \-1
shall be returned and
.IR errno
set to indicate the error.
.SH ERRORS
The
\fIsetuid\fR()
function shall fail, return \-1, and set
.IR errno
to the corresponding value if one or more of the following are true:
.TP
.BR EINVAL
The value of the
.IR uid
argument is invalid and not supported by the implementation.
.TP
.BR EPERM
The process does not have appropriate privileges and
.IR uid
does not match the real user ID or the saved set-user-ID.
.LP
.IR "The following sections are informative."
.SH EXAMPLES
None.
.SH "APPLICATION USAGE"
None.
.SH RATIONALE
The various behaviors of the
\fIsetuid\fR()
and
\fIsetgid\fR()
functions when called by non-privileged processes reflect the behavior
of different historical implementations. For portability, it is
recommended that new non-privileged applications use the
\fIseteuid\fR()
and
\fIsetegid\fR()
functions instead.
.P
The saved set-user-ID capability allows a program to regain the
effective user ID established at the last
.IR exec
call. Similarly, the saved set-group-ID capability allows a program to
regain the effective group ID established at the last
.IR exec
call. These capabilities are derived from System V. Without them, a
program might have to run as superuser in order to perform the same
functions, because superuser can write on the user's files. This is a
problem because such a program can write on any user's files, and so
must be carefully written to emulate the permissions of the calling
process properly. In System V, these capabilities have traditionally
been implemented only via the
\fIsetuid\fR()
and
\fIsetgid\fR()
functions for non-privileged processes. The fact that the behavior of
those functions was different for privileged processes made them
difficult to use. The POSIX.1\(hy1990 standard defined the
\fIsetuid\fR()
function to behave differently for privileged and unprivileged users.
When the caller had appropriate privileges, the function set the real
user ID, effective user ID, and saved set-user ID of the calling process
on implementations that supported it. When the caller did not have
appropriate privileges, the function set only the effective user ID,
subject to permission checks. The former use is generally needed for
utilities like
.IR login
and
.IR su ,
which are not conforming applications and thus outside the scope of
POSIX.1\(hy2008. These utilities wish to change the user ID irrevocably to a new
value, generally that of an unprivileged user. The latter use is needed
for conforming applications that are installed with the set-user-ID bit
and need to perform operations using the real user ID.
.P
POSIX.1\(hy2008 augments the latter functionality with a mandatory feature named
_POSIX_SAVED_IDS. This feature permits a set-user-ID application to
switch its effective user ID back and forth between the values of its
.IR exec -time
real user ID and effective user ID. Unfortunately, the POSIX.1\(hy1990 standard did not
permit a conforming application using this feature to work properly when
it happened to be executed with (implementation-defined)
appropriate privileges. Furthermore, the application did not even have a
means to tell whether it had this privilege. Since the saved
set-user-ID feature is quite desirable for applications, as evidenced
by the fact that NIST required it in FIPS 151\(hy2, it has been mandated by
POSIX.1\(hy2008. However, there are implementors who have been reluctant to
support it given the limitation described above.
.P
The 4.3BSD system handles the problem by supporting separate
functions:
\fIsetuid\fR()
(which always sets both the real and effective user IDs, like
\fIsetuid\fR()
in POSIX.1\(hy2008 for privileged users), and
\fIseteuid\fR()
(which always sets just the effective user ID, like
\fIsetuid\fR()
in POSIX.1\(hy2008 for non-privileged users). This separation of functionality
into distinct functions seems desirable. 4.3BSD does not support the
saved set-user-ID feature. It supports similar functionality of
switching the effective user ID back and forth via
\fIsetreuid\fR(),
which permits reversing the real and effective user IDs. This model
seems less desirable than the saved set-user-ID because the real user
ID changes as a side-effect. The current 4.4BSD includes saved
effective IDs and uses them for
\fIseteuid\fR()
and
\fIsetegid\fR()
as described above. The
\fIsetreuid\fR()
and
\fIsetregid\fR()
functions will be deprecated or removed.
.P
The solution here is:
.IP " *" 4
Require that all implementations support the functionality of the saved
set-user-ID, which is set by the
.IR exec
functions and by privileged calls to
\fIsetuid\fR().
.IP " *" 4
Add the
\fIseteuid\fR()
and
\fIsetegid\fR()
functions as portable alternatives to
\fIsetuid\fR()
and
\fIsetgid\fR()
for non-privileged and privileged processes.
.P
Historical systems have provided two mechanisms for a set-user-ID
process to change its effective user ID to be the same as its real user
ID in such a way that it could return to the original effective user
ID: the use of the
\fIsetuid\fR()
function in the presence of a saved set-user-ID, or the use of the BSD
\fIsetreuid\fR()
function, which was able to swap the real and effective user IDs. The
changes included in POSIX.1\(hy2008 provide a new mechanism using
\fIseteuid\fR()
in conjunction with a saved set-user-ID. Thus, all implementations with
the new
\fIseteuid\fR()
mechanism will have a saved set-user-ID for each process, and most of
the behavior controlled by _POSIX_SAVED_IDS has been changed
to agree with the case where the option was defined. The
\fIkill\fR()
function is an exception. Implementors of the new
\fIseteuid\fR()
mechanism will generally be required to maintain compatibility with the
older mechanisms previously supported by their systems. However,
compatibility with this use of
\fIsetreuid\fR()
and with the _POSIX_SAVED_IDS behavior of
\fIkill\fR()
is unfortunately complicated. If an implementation with a saved
set-user-ID allows a process to use
\fIsetreuid\fR()
to swap its real and effective user IDs, but were to leave the saved
set-user-ID unmodified, the process would then have an effective user
ID equal to the original real user ID, and both real and saved
set-user-ID would be equal to the original effective user ID. In that
state, the real user would be unable to kill the process, even though
the effective user ID of the process matches that of the real user, if
the
\fIkill\fR()
behavior of _POSIX_SAVED_IDS was used. This is obviously not
acceptable. The alternative choice, which is used in at least one
implementation, is to change the saved set-user-ID to the effective
user ID during most calls to
\fIsetreuid\fR().
The standard developers considered that alternative to be less correct
than the retention of the old behavior of
\fIkill\fR()
in such systems. Current conforming applications shall accommodate
either behavior from
\fIkill\fR(),
and there appears to be no strong reason for
\fIkill\fR()
to check the saved set-user-ID rather than the effective user ID.
.SH "FUTURE DIRECTIONS"
None.
.SH "SEE ALSO"
.IR "\fIexec\fR\^",
.IR "\fIgetegid\fR\^(\|)",
.IR "\fIgeteuid\fR\^(\|)",
.IR "\fIgetgid\fR\^(\|)",
.IR "\fIgetuid\fR\^(\|)",
.IR "\fIsetegid\fR\^(\|)",
.IR "\fIseteuid\fR\^(\|)",
.IR "\fIsetgid\fR\^(\|)",
.IR "\fIsetregid\fR\^(\|)",
.IR "\fIsetreuid\fR\^(\|)"
.P
The Base Definitions volume of POSIX.1\(hy2017,
.IR "\fB<sys_types.h>\fP",
.IR "\fB<unistd.h>\fP"
.\"
.SH COPYRIGHT
Portions of this text are reprinted and reproduced in electronic form
from IEEE Std 1003.1-2017, Standard for Information Technology
-- Portable Operating System Interface (POSIX), The Open Group Base
Specifications Issue 7, 2018 Edition,
Copyright (C) 2018 by the Institute of
Electrical and Electronics Engineers, Inc and The Open Group.
In the event of any discrepancy between this version and the original IEEE and
The Open Group Standard, the original IEEE and The Open Group Standard
is the referee document. The original Standard can be obtained online at
http://www.opengroup.org/unix/online.html .
.PP
Any typographical or formatting errors that appear
in this page are most likely
to have been introduced during the conversion of the source files to
man page format. To report such errors, see
https://www.kernel.org/doc/man-pages/reporting_bugs.html .
|