aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/mingw.h5
-rw-r--r--loginutils/suw32.c10
-rw-r--r--win32/mingw.c44
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);
640int windows_env(void); 640int windows_env(void);
641void change_critical_error_dialogs(const char *newval) FAST_FUNC; 641void change_critical_error_dialogs(const char *newval) FAST_FUNC;
642char *exe_relative_path(const char *tail); 642char *exe_relative_path(const char *tail);
643enum {
644 ELEVATED_PRIVILEGE = 1,
645 ADMIN_ENABLED = 2
646};
647int 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 */
1183static int 1182int
1184really_privileged(void) 1183elevation_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
1203int 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
1216int getuid(void)
1217{
1218 return elevation_state() == (ELEVATED_PRIVILEGE | ADMIN_ENABLED) ?
1219 0 : DEFAULT_UID;
1220} 1220}
1221 1221
1222struct passwd *getpwnam(const char *name) 1222struct passwd *getpwnam(const char *name)