| 4043 | } |
| 4044 | |
| 4045 | static bool win_runtime_directory_secure(const wchar_t *runtime_dir) { |
| 4046 | win_security_t security; |
| 4047 | if (!win_security_init(&security)) { |
| 4048 | return false; |
| 4049 | } |
| 4050 | bool created = CreateDirectoryW(runtime_dir, &security.attributes) != 0; |
| 4051 | if (!created && GetLastError() != ERROR_ALREADY_EXISTS) { |
| 4052 | win_security_destroy(&security); |
| 4053 | return false; |
| 4054 | } |
| 4055 | DWORD attributes = GetFileAttributesW(runtime_dir); |
| 4056 | if (attributes == INVALID_FILE_ATTRIBUTES || (attributes & FILE_ATTRIBUTE_DIRECTORY) == 0 || |
| 4057 | (attributes & FILE_ATTRIBUTE_REPARSE_POINT) != 0) { |
| 4058 | win_security_destroy(&security); |
| 4059 | return false; |
| 4060 | } |
| 4061 | HANDLE directory = |
| 4062 | CreateFileW(runtime_dir, READ_CONTROL | WRITE_DAC | WRITE_OWNER, |
| 4063 | FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, |
| 4064 | FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT, NULL); |
| 4065 | bool can_write_owner = directory != INVALID_HANDLE_VALUE; |
| 4066 | if (!can_write_owner) { |
| 4067 | directory = |
| 4068 | CreateFileW(runtime_dir, READ_CONTROL | WRITE_DAC, |
| 4069 | FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, |
| 4070 | FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT, NULL); |
| 4071 | } |
| 4072 | if (directory == INVALID_HANDLE_VALUE) { |
| 4073 | win_security_destroy(&security); |
| 4074 | return false; |
| 4075 | } |
| 4076 | BY_HANDLE_FILE_INFORMATION file_info; |
| 4077 | bool valid_handle = GetFileInformationByHandle(directory, &file_info) != 0 && |
| 4078 | (file_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0 && |
| 4079 | (file_info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) == 0; |
| 4080 | bool owner_exact = valid_handle && win_file_owner_secure(&security, directory, true); |
| 4081 | /* One-time normalization of the admin-group default-owner artifact: a |
| 4082 | * directory created by plain mkdir under an Administrators-default-owner |
| 4083 | * token (standard policy on Windows Server) is born owned by BUILTIN\ |
| 4084 | * Administrators even though it is this account's own private dir. A |
| 4085 | * TRUSTED owner (the launcher's directory policy: SYSTEM, Administrators, |
| 4086 | * TrustedInstaller) is re-stamped to the exact token user inside the same |
| 4087 | * repair that already re-protects the DACL; any other owner remains |
| 4088 | * refused, and the final validation below still demands the exact user. */ |
| 4089 | bool owner_ok = owner_exact || (valid_handle && can_write_owner && |
| 4090 | win_file_owner_secure(&security, directory, false)); |
| 4091 | DWORD secure_result = ERROR_ACCESS_DENIED; |
| 4092 | if (valid_handle && owner_ok) { |
| 4093 | secure_result = security.set_security_info( |
| 4094 | directory, SE_FILE_OBJECT, |
| 4095 | (owner_exact ? 0U : (DWORD)OWNER_SECURITY_INFORMATION) | DACL_SECURITY_INFORMATION | |
| 4096 | PROTECTED_DACL_SECURITY_INFORMATION, |
| 4097 | owner_exact ? NULL : security.user_sid, NULL, security.acl, NULL); |
| 4098 | } |
| 4099 | if (valid_handle && owner_ok && secure_result != ERROR_SUCCESS) { |
| 4100 | ipc_validation_detail_set("owner/DACL repair failed (status %lu%s)", |
| 4101 | (unsigned long)secure_result, |
| 4102 | can_write_owner ? "" : ", WRITE_OWNER unavailable"); |
no test coverage detected