| 4452 | } |
| 4453 | |
| 4454 | static bool win_directory_component_secure(win_security_t *security, const wchar_t *path) { |
| 4455 | HANDLE directory = |
| 4456 | CreateFileW(path, FILE_READ_ATTRIBUTES | READ_CONTROL, |
| 4457 | FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, |
| 4458 | FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT, NULL); |
| 4459 | if (directory == INVALID_HANDLE_VALUE) { |
| 4460 | return false; |
| 4461 | } |
| 4462 | BY_HANDLE_FILE_INFORMATION info; |
| 4463 | /* Default Windows profile ancestors grant cross-account add-subdirectory. |
| 4464 | * That permits siblings but cannot replace the existing next path |
| 4465 | * component. Keep every other mutation right forbidden; the final runtime |
| 4466 | * directory is separately owner-validated and given a protected DACL. */ |
| 4467 | DWORD mutation = win_private_mutation_rights() & ~((DWORD)FILE_ADD_SUBDIRECTORY); |
| 4468 | bool valid = GetFileInformationByHandle(directory, &info) != 0 && |
| 4469 | (info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0 && |
| 4470 | (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) == 0 && |
| 4471 | win_file_security_secure(security, directory, false, mutation, true); |
| 4472 | (void)CloseHandle(directory); |
| 4473 | return valid; |
| 4474 | } |
| 4475 | |
| 4476 | static bool win_private_directory_tree_secure(const wchar_t *directory_path) { |
| 4477 | if (!directory_path) { |
no test coverage detected