| 4119 | } |
| 4120 | |
| 4121 | static bool win_runtime_directory_secure(const wchar_t *runtime_dir) { |
| 4122 | win_security_t security; |
| 4123 | if (!win_security_init(&security)) { |
| 4124 | return false; |
| 4125 | } |
| 4126 | bool created = CreateDirectoryW(runtime_dir, &security.directory_attributes) != 0; |
| 4127 | if (!created && GetLastError() != ERROR_ALREADY_EXISTS) { |
| 4128 | win_security_destroy(&security); |
| 4129 | return false; |
| 4130 | } |
| 4131 | DWORD attributes = GetFileAttributesW(runtime_dir); |
| 4132 | if (attributes == INVALID_FILE_ATTRIBUTES || (attributes & FILE_ATTRIBUTE_DIRECTORY) == 0 || |
| 4133 | (attributes & FILE_ATTRIBUTE_REPARSE_POINT) != 0) { |
| 4134 | win_security_destroy(&security); |
| 4135 | return false; |
| 4136 | } |
| 4137 | HANDLE directory = |
| 4138 | CreateFileW(runtime_dir, READ_CONTROL | WRITE_DAC | WRITE_OWNER, |
| 4139 | FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, |
| 4140 | FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT, NULL); |
| 4141 | bool can_write_owner = directory != INVALID_HANDLE_VALUE; |
| 4142 | if (!can_write_owner) { |
| 4143 | directory = |
| 4144 | CreateFileW(runtime_dir, READ_CONTROL | WRITE_DAC, |
| 4145 | FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, |
| 4146 | FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT, NULL); |
| 4147 | } |
| 4148 | if (directory == INVALID_HANDLE_VALUE) { |
| 4149 | win_security_destroy(&security); |
| 4150 | return false; |
| 4151 | } |
| 4152 | BY_HANDLE_FILE_INFORMATION file_info; |
| 4153 | bool valid_handle = GetFileInformationByHandle(directory, &file_info) != 0 && |
| 4154 | (file_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0 && |
| 4155 | (file_info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) == 0; |
| 4156 | bool owner_exact = valid_handle && win_file_owner_secure(&security, directory, true); |
| 4157 | /* One-time normalization of the admin-group default-owner artifact: a |
| 4158 | * directory created by plain mkdir under an Administrators-default-owner |
| 4159 | * token (standard policy on Windows Server) is born owned by BUILTIN\ |
| 4160 | * Administrators even though it is this account's own private dir. A |
| 4161 | * TRUSTED owner (the launcher's directory policy: SYSTEM, Administrators, |
| 4162 | * TrustedInstaller) is re-stamped to the exact token user inside the same |
| 4163 | * repair that already re-protects the DACL; any other owner remains |
| 4164 | * refused, and the final validation below still demands the exact user. */ |
| 4165 | bool owner_ok = owner_exact || (valid_handle && can_write_owner && |
| 4166 | win_file_owner_secure(&security, directory, false)); |
| 4167 | DWORD secure_result = ERROR_ACCESS_DENIED; |
| 4168 | if (valid_handle && owner_ok) { |
| 4169 | secure_result = security.set_security_info( |
| 4170 | directory, SE_FILE_OBJECT, |
| 4171 | (owner_exact ? 0U : (DWORD)OWNER_SECURITY_INFORMATION) | DACL_SECURITY_INFORMATION | |
| 4172 | PROTECTED_DACL_SECURITY_INFORMATION, |
| 4173 | owner_exact ? NULL : security.user_sid, NULL, security.directory_acl, NULL); |
| 4174 | } |
| 4175 | if (valid_handle && owner_ok && secure_result != ERROR_SUCCESS) { |
| 4176 | ipc_validation_detail_set("owner/DACL repair failed (status %lu%s)", |
| 4177 | (unsigned long)secure_result, |
| 4178 | can_write_owner ? "" : ", WRITE_OWNER unavailable"); |
no test coverage detected