diff --git a/tools/utils/paths.go b/tools/utils/paths.go index 7ae9ec526..b94995370 100644 --- a/tools/utils/paths.go +++ b/tools/utils/paths.go @@ -135,20 +135,34 @@ func macos_user_cache_dir() string { // the algorithm at https://github.com/ydkhatri/MacForensics/blob/master/darwin_path_generator.py // but I cant find a good way to get the generateduid. Requires calling dscl in which case we might as well call getconf // The data is in /var/db/dslocal/nodes/Default/users/.plist but it needs root + // So instead we use various hacks to get it quickly, falling back to running /usr/bin/getconf + + is_ok := func(m string) bool { + s, err := os.Stat(m) + if err != nil { + return false + } + stat, ok := s.Sys().(unix.Stat_t) + return ok && s.IsDir() && int(stat.Uid) == os.Geteuid() && s.Mode().Perm() == 0o700 && unix.Access(m, unix.X_OK|unix.W_OK|unix.R_OK) == nil + } + + if tdir := strings.TrimRight(os.Getenv("TMPDIR"), "/"); filepath.Base(tdir) == "T" { + if m := filepath.Join(filepath.Dir(tdir), "C"); is_ok(m) { + return m + } + } + matches, err := filepath.Glob("/private/var/folders/*/*/C") if err == nil { for _, m := range matches { - s, err := os.Stat(m) - if err == nil { - if stat, ok := s.Sys().(unix.Stat_t); ok && s.IsDir() && int(stat.Uid) == os.Geteuid() && s.Mode().Perm() == 0o700 && unix.Access(m, unix.X_OK|unix.W_OK|unix.R_OK) == nil { - return m - } + if is_ok(m) { + return m } } } out, err := exec.Command("/usr/bin/getconf", "DARWIN_USER_CACHE_DIR").Output() if err == nil { - return strings.TrimSpace(UnsafeBytesToString(out)) + return strings.TrimRight(strings.TrimSpace(UnsafeBytesToString(out)), "/") } return "" }