regen pidl all: rm epan/dissectors/pidl/*-stamp; pushd epan/dissectors/pidl/ && make...
[wireshark-sm.git] / wsutil / privileges.c
blob6ee0dfd563112a4c47d0b02ebac1632bafdfed83
1 /* privileges.c
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
9 */
11 #include "config.h"
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 */
16 #endif
17 #include "privileges.h"
19 #include <wsutil/ws_assert.h>
20 #include <wsutil/wslog.h>
22 #ifdef _WIN32
23 #include <windows.h>
24 #include <wchar.h>
25 #include <tchar.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.
32 void
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
42 * errors.
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.
54 bool
55 started_with_special_privs(void)
57 return false;
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.
66 bool
67 running_with_special_privs(void)
69 return false;
73 * For now, we don't do anything when asked to relinquish special privileges.
75 void
76 relinquish_special_privs_perm(void)
81 * Get the current username. String must be g_free()d after use.
83 char *
84 get_cur_username(void) {
85 char *username;
86 username = g_strdup("UNKNOWN");
87 return username;
91 * Get the current group. String must be g_free()d after use.
93 char *
94 get_cur_groupname(void) {
95 char *groupname;
96 groupname = g_strdup("UNKNOWN");
97 return groupname;
100 #else /* _WIN32 */
102 #include <sys/types.h>
104 #ifdef HAVE_UNISTD_H
105 #include <unistd.h>
106 #endif
108 #ifdef HAVE_PWD_H
109 #include <pwd.h>
110 #endif
112 #ifdef HAVE_GRP_H
113 #include <grp.h>
114 #endif
116 #include <string.h>
117 #include <errno.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.
134 void
135 init_process_policies(void)
137 ruid = getuid();
138 euid = geteuid();
139 rgid = getgid();
140 egid = getegid();
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.
149 bool
150 started_with_special_privs(void)
152 ws_assert(init_process_policies_called);
153 #ifdef HAVE_ISSETUGID
154 return issetugid();
155 #else
156 return (ruid != euid || rgid != egid || ruid == 0 || rgid == 0);
157 #endif
161 * Return true if the real, effective, or saved (if we can check it) user
162 * ID or group are 0.
164 bool
165 running_with_special_privs(void)
167 #ifdef HAVE_SETRESUID
168 uid_t ru, eu, su;
169 #endif
170 #ifdef HAVE_SETRESGID
171 gid_t rg, eg, sg;
172 #endif
174 #ifdef HAVE_SETRESUID
175 getresuid(&ru, &eu, &su);
176 if (ru == 0 || eu == 0 || su == 0)
177 return true;
178 #else
179 if (getuid() == 0 || geteuid() == 0)
180 return true;
181 #endif
182 #ifdef HAVE_SETRESGID
183 getresgid(&rg, &eg, &sg);
184 if (rg == 0 || eg == 0 || sg == 0)
185 return true;
186 #else
187 if (getgid() == 0 || getegid() == 0)
188 return true;
189 #endif
190 return false;
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.
204 static void
205 setxid_fail(const char *str)
207 ws_error("Attempt to relinquish privileges failed [%s()] - aborting: %s\n",
208 str, g_strerror(errno));
211 void
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");}
227 #else
228 if (setgid(rgid) == -1) {setxid_fail("setgid"); }
229 if (setegid(rgid) == -1) {setxid_fail("setegid");}
230 #endif
232 #ifdef HAVE_SETRESUID
233 if (setresuid(ruid, ruid, ruid) == -1) {setxid_fail("setresuid");}
234 #else
235 if (setuid(ruid) == -1) {setxid_fail("setuid"); }
236 if (seteuid(ruid) == -1) {setxid_fail("seteuid");}
237 #endif
242 * Get the current username. String must be g_free()d after use.
244 char *
245 get_cur_username(void) {
246 char *username;
247 struct passwd *pw = getpwuid(getuid());
249 if (pw) {
250 username = g_strdup(pw->pw_name);
251 } else {
252 username = g_strdup("UNKNOWN");
254 endpwent();
255 return username;
259 * Get the current group. String must be g_free()d after use.
261 char *
262 get_cur_groupname(void) {
263 char *groupname;
264 struct group *gr = getgrgid(getgid());
266 if (gr) {
267 groupname = g_strdup(gr->gr_name);
268 } else {
269 groupname = g_strdup("UNKNOWN");
271 endgrent();
272 return groupname;
275 #endif /* _WIN32 */
278 * Editor modelines
280 * Local Variables:
281 * c-basic-offset: 8
282 * tab-width: 8
283 * indent-tabs-mode: t
284 * End:
286 * ex: set shiftwidth=8 tabstop=8 noexpandtab:
287 * :indentSize=8:tabSize=8:noTabs=false: