2 * Routines for handling privileges, e.g. set-UID and set-GID on UNIX.
4 * Wireshark - Network traffic analyzer
5 * By Gerald Combs <gerald@wireshark.org>
6 * Copyright 2006 Gerald Combs
8 * SPDX-License-Identifier: GPL-2.0-or-later
12 #define WS_LOG_DOMAIN LOG_DOMAIN_WSUTIL
14 #if defined(HAVE_SETRESUID) || defined(HAVE_SETREGUID)
15 #define _GNU_SOURCE /* Otherwise [sg]etres[gu]id won't be defined on Linux */
17 #include "privileges.h"
19 #include <wsutil/ws_assert.h>
20 #include <wsutil/wslog.h>
28 * Called when the program starts, to save whatever credential information
29 * we'll need later, and to do whatever other specialized platform-dependent
30 * initialization we want.
33 init_process_policies(void)
36 * If we have SetProcessDEPPolicy(), turn "data execution
37 * prevention" on - i.e., if the MMU lets you set execute
38 * permission on a per-page basis, turn execute permission
39 * off on most data pages. SetProcessDEPPolicy() fails on
40 * 64-bit Windows (it's *always* on there), but if it fails,
41 * we don't care (we did our best), so we don't check for
45 SetProcessDEPPolicy(PROCESS_DEP_ENABLE
);
49 * For now, we say the program wasn't started with special privileges.
50 * There are ways of running programs with credentials other than those
51 * for the session in which it's run, but I don't know whether that'd be
52 * done with Wireshark/TShark or not.
55 started_with_special_privs(void)
61 * For now, we say the program isn't running with special privileges.
62 * There are ways of running programs with credentials other than those
63 * for the session in which it's run, but I don't know whether that'd be
64 * done with Wireshark/TShark or not.
67 running_with_special_privs(void)
73 * For now, we don't do anything when asked to relinquish special privileges.
76 relinquish_special_privs_perm(void)
81 * Get the current username. String must be g_free()d after use.
84 get_cur_username(void) {
86 username
= g_strdup("UNKNOWN");
91 * Get the current group. String must be g_free()d after use.
94 get_cur_groupname(void) {
96 groupname
= g_strdup("UNKNOWN");
102 #include <sys/types.h>
119 static uid_t ruid
, euid
;
120 static gid_t rgid
, egid
;
121 static bool init_process_policies_called
;
124 * Called when the program starts, to save whatever credential information
125 * we'll need later, and to do whatever other specialized platform-dependent
126 * initialization we want.
128 * The credential information we'll need later on UNIX is the real and
129 * effective UID and GID.
131 * XXX - do any UN*Xes have opt-in "no execute on data pages by default"
132 * permission? This would be the place to request it.
135 init_process_policies(void)
142 init_process_policies_called
= true;
146 * "Started with special privileges" means "started out set-UID or set-GID",
147 * or run as the root user or group.
150 started_with_special_privs(void)
152 ws_assert(init_process_policies_called
);
153 #ifdef HAVE_ISSETUGID
156 return (ruid
!= euid
|| rgid
!= egid
|| ruid
== 0 || rgid
== 0);
161 * Return true if the real, effective, or saved (if we can check it) user
165 running_with_special_privs(void)
167 #ifdef HAVE_SETRESUID
170 #ifdef HAVE_SETRESGID
174 #ifdef HAVE_SETRESUID
175 getresuid(&ru
, &eu
, &su
);
176 if (ru
== 0 || eu
== 0 || su
== 0)
179 if (getuid() == 0 || geteuid() == 0)
182 #ifdef HAVE_SETRESGID
183 getresgid(&rg
, &eg
, &sg
);
184 if (rg
== 0 || eg
== 0 || sg
== 0)
187 if (getgid() == 0 || getegid() == 0)
194 * Permanently relinquish set-UID and set-GID privileges.
195 * If error, abort since we probably shouldn't continue
196 * with elevated privileges.
197 * Note that if this error occurs when dumpcap is called from
198 * wireshark or tshark, the message seen will be
199 * "Child dumpcap process died:". This is obscure but we'll
200 * consider it acceptable since it should be highly unlikely
201 * that this error will occur.
205 setxid_fail(const char *str
)
207 ws_error("Attempt to relinquish privileges failed [%s()] - aborting: %s\n",
208 str
, g_strerror(errno
));
212 relinquish_special_privs_perm(void)
215 * If we were started with special privileges, set the
216 * real and effective group and user IDs to the original
217 * values of the real and effective group and user IDs.
218 * If we're not, don't bother - doing so seems to mung
219 * our group set, at least in Mac OS X 10.5.
221 * (Set the effective UID last - that takes away our
222 * rights to set anything else.)
224 if (started_with_special_privs()) {
225 #ifdef HAVE_SETRESGID
226 if (setresgid(rgid
, rgid
, rgid
) == -1) {setxid_fail("setresgid");}
228 if (setgid(rgid
) == -1) {setxid_fail("setgid"); }
229 if (setegid(rgid
) == -1) {setxid_fail("setegid");}
232 #ifdef HAVE_SETRESUID
233 if (setresuid(ruid
, ruid
, ruid
) == -1) {setxid_fail("setresuid");}
235 if (setuid(ruid
) == -1) {setxid_fail("setuid"); }
236 if (seteuid(ruid
) == -1) {setxid_fail("seteuid");}
242 * Get the current username. String must be g_free()d after use.
245 get_cur_username(void) {
247 struct passwd
*pw
= getpwuid(getuid());
250 username
= g_strdup(pw
->pw_name
);
252 username
= g_strdup("UNKNOWN");
259 * Get the current group. String must be g_free()d after use.
262 get_cur_groupname(void) {
264 struct group
*gr
= getgrgid(getgid());
267 groupname
= g_strdup(gr
->gr_name
);
269 groupname
= g_strdup("UNKNOWN");
283 * indent-tabs-mode: t
286 * ex: set shiftwidth=8 tabstop=8 noexpandtab:
287 * :indentSize=8:tabSize=8:noTabs=false: