diff options
-rw-r--r-- | include/mingw.h | 5 | ||||
-rw-r--r-- | loginutils/suw32.c | 10 | ||||
-rw-r--r-- | win32/mingw.c | 44 |
3 files changed, 37 insertions, 22 deletions
diff --git a/include/mingw.h b/include/mingw.h index c4c2e199a..7a07de619 100644 --- a/include/mingw.h +++ b/include/mingw.h | |||
@@ -640,3 +640,8 @@ char *xappendword(const char *str, const char *word); | |||
640 | int windows_env(void); | 640 | int windows_env(void); |
641 | void change_critical_error_dialogs(const char *newval) FAST_FUNC; | 641 | void change_critical_error_dialogs(const char *newval) FAST_FUNC; |
642 | char *exe_relative_path(const char *tail); | 642 | char *exe_relative_path(const char *tail); |
643 | enum { | ||
644 | ELEVATED_PRIVILEGE = 1, | ||
645 | ADMIN_ENABLED = 2 | ||
646 | }; | ||
647 | int elevation_state(void); | ||
diff --git a/loginutils/suw32.c b/loginutils/suw32.c index edf42177b..a0afe5bb7 100644 --- a/loginutils/suw32.c +++ b/loginutils/suw32.c | |||
@@ -44,6 +44,16 @@ int suw32_main(int argc UNUSED_PARAM, char **argv) | |||
44 | char *bb_path, *cwd, *realcwd, *q, *args; | 44 | char *bb_path, *cwd, *realcwd, *q, *args; |
45 | DECLARE_PROC_ADDR(BOOL, ShellExecuteExA, SHELLEXECUTEINFOA *); | 45 | DECLARE_PROC_ADDR(BOOL, ShellExecuteExA, SHELLEXECUTEINFOA *); |
46 | 46 | ||
47 | #if ENABLE_DROP || ENABLE_CDROP || ENABLE_PDROP | ||
48 | // If privilege has been dropped (ELEVATED_PRIVILEGE but not | ||
49 | // ADMIN_ENABLED) ShellExecuteEx() thinks we already have elevated | ||
50 | // privilege and doesn't raise privilege. In that case, give up. | ||
51 | if (elevation_state() == ELEVATED_PRIVILEGE) { | ||
52 | xfunc_error_retval = 2; | ||
53 | bb_error_msg_and_die("unable to restore privilege"); | ||
54 | } | ||
55 | #endif | ||
56 | |||
47 | opt = getopt32(argv, "c:NW", &opt_command); | 57 | opt = getopt32(argv, "c:NW", &opt_command); |
48 | argv += optind; | 58 | argv += optind; |
49 | if (argv[0]) { | 59 | if (argv[0]) { |
diff --git a/win32/mingw.c b/win32/mingw.c index f2b025e43..97bc95d8e 100644 --- a/win32/mingw.c +++ b/win32/mingw.c | |||
@@ -1174,49 +1174,49 @@ char *get_user_name(void) | |||
1174 | return user_name; | 1174 | return user_name; |
1175 | } | 1175 | } |
1176 | 1176 | ||
1177 | #if ENABLE_DROP || ENABLE_CDROP || ENABLE_PDROP | ||
1178 | /* | 1177 | /* |
1179 | * When 'drop' drops privileges TokenIsElevated is still TRUE. | 1178 | * When 'drop' drops privileges TokenIsElevated is still TRUE. |
1180 | * Find out if we're really privileged by checking if the group | 1179 | * Find out if we're really privileged by checking if the group |
1181 | * BUILTIN\Administrators is enabled. | 1180 | * BUILTIN\Administrators is enabled. |
1182 | */ | 1181 | */ |
1183 | static int | 1182 | int |
1184 | really_privileged(void) | 1183 | elevation_state(void) |
1185 | { | 1184 | { |
1186 | BOOL admin_enabled; | 1185 | int elevated = FALSE; |
1186 | int enabled = TRUE; | ||
1187 | HANDLE h; | ||
1188 | #if ENABLE_DROP || ENABLE_CDROP || ENABLE_PDROP | ||
1189 | BOOL admin_enabled = TRUE; | ||
1187 | unsigned char admin[16] = { | 1190 | unsigned char admin[16] = { |
1188 | 0x01, 0x02, 0x00, 0x00, | 1191 | 0x01, 0x02, 0x00, 0x00, |
1189 | 0x00, 0x00, 0x00, 0x05, | 1192 | 0x00, 0x00, 0x00, 0x05, |
1190 | 0x20, 0x00, 0x00, 0x00, | 1193 | 0x20, 0x00, 0x00, 0x00, |
1191 | 0x20, 0x02, 0x00, 0x00 | 1194 | 0x20, 0x02, 0x00, 0x00 |
1192 | }; | 1195 | }; |
1193 | |||
1194 | if (CheckTokenMembership(NULL, (PSID)admin, &admin_enabled)) | ||
1195 | return admin_enabled; | ||
1196 | |||
1197 | return TRUE; | ||
1198 | } | ||
1199 | #else | ||
1200 | # define really_privileged() (TRUE) | ||
1201 | #endif | 1196 | #endif |
1202 | 1197 | ||
1203 | int getuid(void) | ||
1204 | { | ||
1205 | int ret = DEFAULT_UID; | ||
1206 | HANDLE h; | ||
1207 | |||
1208 | if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &h)) { | 1198 | if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &h)) { |
1209 | TOKEN_ELEVATION elevation = { 0 }; | 1199 | TOKEN_ELEVATION elevation = { 0 }; |
1210 | DWORD size; | 1200 | DWORD size; |
1211 | 1201 | ||
1212 | if (GetTokenInformation(h, TokenElevation, &elevation, | 1202 | if (GetTokenInformation(h, TokenElevation, &elevation, |
1213 | sizeof(elevation), &size)) { | 1203 | sizeof(elevation), &size)) |
1214 | if (elevation.TokenIsElevated && really_privileged()) | 1204 | elevated = elevation.TokenIsElevated != 0; |
1215 | ret = 0; | ||
1216 | } | ||
1217 | CloseHandle(h); | 1205 | CloseHandle(h); |
1218 | } | 1206 | } |
1219 | return ret; | 1207 | |
1208 | #if ENABLE_DROP || ENABLE_CDROP || ENABLE_PDROP | ||
1209 | if (CheckTokenMembership(NULL, (PSID)admin, &admin_enabled)) | ||
1210 | enabled = admin_enabled != 0; | ||
1211 | #endif | ||
1212 | |||
1213 | return elevated | (enabled << 1); | ||
1214 | } | ||
1215 | |||
1216 | int getuid(void) | ||
1217 | { | ||
1218 | return elevation_state() == (ELEVATED_PRIVILEGE | ADMIN_ENABLED) ? | ||
1219 | 0 : DEFAULT_UID; | ||
1220 | } | 1220 | } |
1221 | 1221 | ||
1222 | struct passwd *getpwnam(const char *name) | 1222 | struct passwd *getpwnam(const char *name) |