diff options
Diffstat (limited to 'uidswap.c')
-rw-r--r-- | uidswap.c | 39 |
1 files changed, 6 insertions, 33 deletions
@@ -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. */ |
50 | static int privileged = 0; | 50 | static int privileged = 0; |
51 | static int temporarily_use_uid_effective = 0; | 51 | static int temporarily_use_uid_effective = 0; |
52 | static uid_t user_groups_uid; | ||
52 | static gid_t *saved_egroups = NULL, *user_groups = NULL; | 53 | static gid_t *saved_egroups = NULL, *user_groups = NULL; |
53 | static int saved_egroupslen = -1, user_groupslen = -1; | 54 | static 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 | ||
134 | void | ||
135 | permanently_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 | */ |