{"record":{"id":"721c832442765bec","repo":"Hmbown/CodeWhale","slug":"codewhale-issue-report-dacl-is-not-current-user-only","errorCode":null,"errorMessage":"Codewhale issue-report DACL is not current-user-only","messagePattern":"Codewhale issue-report DACL is not current-user-only","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/tui/src/tools/github/report.rs","lineNumber":1098,"sourceCode":"        );\n        let mut count = 0;\n        let mut entries: *mut EXPLICIT_ACCESS_W = std::ptr::null_mut();\n        // SAFETY: `dacl` belongs to the live descriptor; Windows allocates the\n        // returned entry array, released by the guard below.\n        let result = unsafe { GetExplicitEntriesFromAclW(dacl, &mut count, &mut entries) };\n        if result != ERROR_SUCCESS {\n            return Err(std::io::Error::from_raw_os_error(result as i32))\n                .context(\"reading Codewhale issue-report DACL entries\");\n        }\n        let _entries = WindowsLocalAllocation(entries.cast());\n        anyhow::ensure!(\n            count == 1 && !entries.is_null(),\n            \"Codewhale issue-report DACL must grant only one user\"\n        );\n        // SAFETY: `count == 1` proves the first returned entry is initialized.\n        let entry = unsafe { &*entries };\n        let trustee_sid: PSID = entry.Trustee.ptstrName.cast();\n        anyhow::ensure!(\n            entry.Trustee.TrusteeForm == TRUSTEE_IS_SID\n                && !trustee_sid.is_null()\n                && unsafe { EqualSid(trustee_sid, user.sid()) } != 0\n                && matches!(entry.grfAccessMode, SET_ACCESS | GRANT_ACCESS)\n                && entry.grfAccessPermissions == FILE_ALL_ACCESS,\n            \"Codewhale issue-report DACL is not current-user-only\"\n        );\n        Ok(())\n    }\n\n    #[cfg(windows)]\n    struct CurrentWindowsUser {\n        token: windows_sys::Win32::Foundation::HANDLE,\n        token_info: Vec<usize>,\n    }\n\n    #[cfg(windows)]\n    impl CurrentWindowsUser {","sourceCodeStart":1080,"sourceCodeEnd":1116,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/73e0f67d83c59909b571efdfc88c4bc28c309cb1/crates/tui/src/tools/github/report.rs#L1080-L1116","documentation":"The DACL has exactly one entry, but that entry is not an unconditional grant of FILE_ALL_ACCESS to the current user's SID: the trustee is not SID-form, the SID is null or differs from the caller's, the access mode is not SET/GRANT, or permissions differ from FILE_ALL_ACCESS. The handle is therefore not provably current-user-only and is rejected.","triggerScenarios":"An ACE grants access to a group or name-mapped trustee instead of the user's SID; the DACL grants a narrower permission mask (e.g. FILE_GENERIC_WRITE); a DENY ACE replaced the grant; or a different account's SID was embedded when the handle was created.","commonSituations":"Handle created under a service account then used by the logged-in user; DACL edited with icacls using name-based trustees that map to groups; running elevated vs non-elevated so the effective user SID differs; sandboxing software rewriting ACEs.","solutions":["Recreate the issue-report handle so Codewhale builds the DACL itself with EqualSid-verified current-user SID and FILE_ALL_ACCESS","Normalize the ACE: `icacls <path> /inheritance:r /grant:r *<current-user-SID>:F`","Confirm the process is running as the same user that created the handle (check elevation/service account)","Audit tools (AV, EDR, group policy) that rewrite ACEs on the temp/report directory"],"exampleFix":"// before\nicacls report.txt /grant:r BUILTIN\\Users:F\n// after\nicacls report.txt /inheritance:r /grant:r \"%USERNAME%\":F","handlingStrategy":"validation","validationCode":"// Confirm the single ACE is the current user with full control\n$a = (Get-Acl $path).Access[0]; $a.IdentityReference.Value -eq $env:USERNAME -and $a.FileSystemRights -eq 'FullControl'","typeGuard":null,"tryCatchPattern":"if let Err(e) = verify_windows_owner_only_handle(h) { if e.to_string().contains(\"current-user-only\") { recreate_handle(); } }","preventionTips":["Run creation and verification under the same user account (watch for elevation changes)","Use SID-based ACEs, not group names","Keep AV/EDR ACL rewrites off the report directory"],"tags":["windows","acl","security","sid"],"backgroundTag":"permission-denied","analyzedSha":"73e0f67d83c59909b571efdfc88c4bc28c309cb1","analyzedAt":"2026-09-22T01:30:00.501Z","contentChangedAt":"2026-09-22T01:30:00.501Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}