diff options
Diffstat (limited to 'uidswap.c')
-rw-r--r-- | uidswap.c | 27 |
1 files changed, 24 insertions, 3 deletions
@@ -16,6 +16,7 @@ RCSID("$OpenBSD: uidswap.c,v 1.24 2003/05/29 16:58:45 deraadt Exp $"); | |||
16 | 16 | ||
17 | #include "log.h" | 17 | #include "log.h" |
18 | #include "uidswap.h" | 18 | #include "uidswap.h" |
19 | #include "xmalloc.h" | ||
19 | 20 | ||
20 | /* | 21 | /* |
21 | * Note: all these functions must work in all of the following cases: | 22 | * Note: all these functions must work in all of the following cases: |
@@ -38,7 +39,7 @@ static gid_t saved_egid = 0; | |||
38 | /* Saved effective uid. */ | 39 | /* Saved effective uid. */ |
39 | static int privileged = 0; | 40 | static int privileged = 0; |
40 | static int temporarily_use_uid_effective = 0; | 41 | static int temporarily_use_uid_effective = 0; |
41 | static gid_t saved_egroups[NGROUPS_MAX], user_groups[NGROUPS_MAX]; | 42 | static gid_t *saved_egroups = NULL, *user_groups = NULL; |
42 | static int saved_egroupslen = -1, user_groupslen = -1; | 43 | static int saved_egroupslen = -1, user_groupslen = -1; |
43 | 44 | ||
44 | /* | 45 | /* |
@@ -68,18 +69,38 @@ temporarily_use_uid(struct passwd *pw) | |||
68 | 69 | ||
69 | privileged = 1; | 70 | privileged = 1; |
70 | temporarily_use_uid_effective = 1; | 71 | temporarily_use_uid_effective = 1; |
71 | saved_egroupslen = getgroups(NGROUPS_MAX, saved_egroups); | 72 | |
73 | saved_egroupslen = getgroups(0, NULL); | ||
72 | if (saved_egroupslen < 0) | 74 | if (saved_egroupslen < 0) |
73 | fatal("getgroups: %.100s", strerror(errno)); | 75 | fatal("getgroups: %.100s", strerror(errno)); |
76 | if (saved_egroupslen > 0) { | ||
77 | saved_egroups = xrealloc(saved_egroups, | ||
78 | saved_egroupslen * sizeof(gid_t)); | ||
79 | if (getgroups(saved_egroupslen, saved_egroups) < 0) | ||
80 | fatal("getgroups: %.100s", strerror(errno)); | ||
81 | } else { /* saved_egroupslen == 0 */ | ||
82 | if (saved_egroups) | ||
83 | xfree(saved_egroups); | ||
84 | } | ||
74 | 85 | ||
75 | /* set and save the user's groups */ | 86 | /* set and save the user's groups */ |
76 | if (user_groupslen == -1) { | 87 | if (user_groupslen == -1) { |
77 | if (initgroups(pw->pw_name, pw->pw_gid) < 0) | 88 | if (initgroups(pw->pw_name, pw->pw_gid) < 0) |
78 | fatal("initgroups: %s: %.100s", pw->pw_name, | 89 | fatal("initgroups: %s: %.100s", pw->pw_name, |
79 | strerror(errno)); | 90 | strerror(errno)); |
80 | user_groupslen = getgroups(NGROUPS_MAX, user_groups); | 91 | |
92 | user_groupslen = getgroups(0, NULL); | ||
81 | if (user_groupslen < 0) | 93 | if (user_groupslen < 0) |
82 | fatal("getgroups: %.100s", strerror(errno)); | 94 | fatal("getgroups: %.100s", strerror(errno)); |
95 | if (user_groupslen > 0) { | ||
96 | user_groups = xrealloc(user_groups, | ||
97 | user_groupslen * sizeof(gid_t)); | ||
98 | if (getgroups(user_groupslen, user_groups) < 0) | ||
99 | fatal("getgroups: %.100s", strerror(errno)); | ||
100 | } else { /* user_groupslen == 0 */ | ||
101 | if (user_groups) | ||
102 | xfree(user_groups); | ||
103 | } | ||
83 | } | 104 | } |
84 | /* Set the effective uid to the given (unprivileged) uid. */ | 105 | /* Set the effective uid to the given (unprivileged) uid. */ |
85 | if (setgroups(user_groupslen, user_groups) < 0) | 106 | if (setgroups(user_groupslen, user_groups) < 0) |