summaryrefslogtreecommitdiff
path: root/uidswap.c
diff options
context:
space:
mode:
Diffstat (limited to 'uidswap.c')
-rw-r--r--uidswap.c39
1 files changed, 6 insertions, 33 deletions
diff --git a/uidswap.c b/uidswap.c
index 8bf6b244e..49f76d818 100644
--- a/uidswap.c
+++ b/uidswap.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: uidswap.c,v 1.39 2015/06/24 01:49:19 dtucker Exp $ */ 1/* $OpenBSD: uidswap.c,v 1.41 2018/07/18 11:34:04 dtucker Exp $ */
2/* 2/*
3 * Author: Tatu Ylonen <ylo@cs.hut.fi> 3 * Author: Tatu Ylonen <ylo@cs.hut.fi>
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -49,6 +49,7 @@ static gid_t saved_egid = 0;
49/* Saved effective uid. */ 49/* Saved effective uid. */
50static int privileged = 0; 50static int privileged = 0;
51static int temporarily_use_uid_effective = 0; 51static int temporarily_use_uid_effective = 0;
52static uid_t user_groups_uid;
52static gid_t *saved_egroups = NULL, *user_groups = NULL; 53static gid_t *saved_egroups = NULL, *user_groups = NULL;
53static int saved_egroupslen = -1, user_groupslen = -1; 54static int saved_egroupslen = -1, user_groupslen = -1;
54 55
@@ -92,10 +93,11 @@ temporarily_use_uid(struct passwd *pw)
92 fatal("getgroups: %.100s", strerror(errno)); 93 fatal("getgroups: %.100s", strerror(errno));
93 } else { /* saved_egroupslen == 0 */ 94 } else { /* saved_egroupslen == 0 */
94 free(saved_egroups); 95 free(saved_egroups);
96 saved_egroups = NULL;
95 } 97 }
96 98
97 /* set and save the user's groups */ 99 /* set and save the user's groups */
98 if (user_groupslen == -1) { 100 if (user_groupslen == -1 || user_groups_uid != pw->pw_uid) {
99 if (initgroups(pw->pw_name, pw->pw_gid) < 0) 101 if (initgroups(pw->pw_name, pw->pw_gid) < 0)
100 fatal("initgroups: %s: %.100s", pw->pw_name, 102 fatal("initgroups: %s: %.100s", pw->pw_name,
101 strerror(errno)); 103 strerror(errno));
@@ -110,7 +112,9 @@ temporarily_use_uid(struct passwd *pw)
110 fatal("getgroups: %.100s", strerror(errno)); 112 fatal("getgroups: %.100s", strerror(errno));
111 } else { /* user_groupslen == 0 */ 113 } else { /* user_groupslen == 0 */
112 free(user_groups); 114 free(user_groups);
115 user_groups = NULL;
113 } 116 }
117 user_groups_uid = pw->pw_uid;
114 } 118 }
115 /* Set the effective uid to the given (unprivileged) uid. */ 119 /* Set the effective uid to the given (unprivileged) uid. */
116 if (setgroups(user_groupslen, user_groups) < 0) 120 if (setgroups(user_groupslen, user_groups) < 0)
@@ -131,37 +135,6 @@ temporarily_use_uid(struct passwd *pw)
131 strerror(errno)); 135 strerror(errno));
132} 136}
133 137
134void
135permanently_drop_suid(uid_t uid)
136{
137#ifndef NO_UID_RESTORATION_TEST
138 uid_t old_uid = getuid();
139#endif
140
141 debug("permanently_drop_suid: %u", (u_int)uid);
142 if (setresuid(uid, uid, uid) < 0)
143 fatal("setresuid %u: %.100s", (u_int)uid, strerror(errno));
144
145#ifndef NO_UID_RESTORATION_TEST
146 /*
147 * Try restoration of UID if changed (test clearing of saved uid).
148 *
149 * Note that we don't do this on Cygwin, or on Solaris-based platforms
150 * where fine-grained privileges are available (the user might be
151 * deliberately allowed the right to setuid back to root).
152 */
153 if (old_uid != uid &&
154 (setuid(old_uid) != -1 || seteuid(old_uid) != -1))
155 fatal("%s: was able to restore old [e]uid", __func__);
156#endif
157
158 /* Verify UID drop was successful */
159 if (getuid() != uid || geteuid() != uid) {
160 fatal("%s: euid incorrect uid:%u euid:%u (should be %u)",
161 __func__, (u_int)getuid(), (u_int)geteuid(), (u_int)uid);
162 }
163}
164
165/* 138/*
166 * Restores to the original (privileged) uid. 139 * Restores to the original (privileged) uid.
167 */ 140 */