Skip to content

fix: 提权运行时定位到真实用户的 TCC 数据库 - #1

Merged
cuijianzhuang merged 1 commit into
mainfrom
fix/tcc-db-path-under-sudo
Aug 29, 2026
Merged

cuijianzhuang merged 1 commit into
mainfrom
fix/tcc-db-path-under-sudo

Conversation

@cuijianzhuang

Copy link
Copy Markdown
Owner

问题

勾选「以管理员权限运行」对摄像头 / 麦克风授权时执行失败:

执行错误: 找不到 TCC 数据库: /var/root/Library/Application Support/com.apple.TCC/TCC.db

摄像头、麦克风等记录在用户级 TCC.db(~/Library/Application Support/com.apple.TCC/TCC.db),但 sudo / osascript 提权后 NSHomeDirectory() 返回 /var/root,helper 于是跑去 root 的家目录找库。

改动

Sources/tccplus.swift

  • 新增 realUserHome(),按四级顺序解析真实用户家目录:
    1. TCC_USER_HOME 环境变量(调用方显式指定)
    2. SUDO_USER 对应的 passwd 记录
    3. SCDynamicStoreCopyConsoleUser 拿到的图形界面登录用户 —— osascript 提权不保留 SUDO_USER,走这条
    4. NSHomeDirectory()(本来就是普通用户运行)
  • 找不到数据库时的报错补上当前用户与解析出的家目录,便于判断走错了哪条分支

Sources/App.swift

  • 提权执行的命令串前显式 export TCC_USER_HOME=<NSHomeDirectory()>,不依赖环境变量的保留行为
  • 新增 systemScopedServices:只有屏幕录制、辅助功能、输入监控、完全磁盘访问位于系统级库需要 root
  • 提权开关默认关闭,并跟随勾选自动设置;下方加一行说明当前所选权限是否需要提权
  • onChange(of:) 用两参数版本以保持 macOS 13 兼容(三参数版是 14+)

验证

内置 helper 的三条解析分支实测:

场景 结果
普通用户 定位到用户库,成功
SUDO_USER=cuijianzhuang 定位到用户库,成功
TCC_USER_HOME=$HOME 定位到用户库,成功
SUDO_USER=nobody 如预期报 /var/empty/...,确认优先级生效

./build.sh --universal 通过,产物为 x86_64 arm64 通用二进制。

评审注意

  • 未能在真实 sudo 环境下端到端验证(需要交互输入密码),分支逻辑通过构造环境变量覆盖。
  • 提权开关改为自动跟随勾选后,用户手动改过的状态会在下次改变勾选时被覆盖。考虑到误勾提权正是本 issue 的诱因,这里选择了「总是给出正确默认值」而非记住用户偏好。

🤖 Generated with Claude Code

sudo / osascript 提权后 NSHomeDirectory() 返回 /var/root,helper 会去
root 的家目录找用户级 TCC.db 而报「找不到」。改为按 TCC_USER_HOME →
SUDO_USER → 控制台登录用户 → NSHomeDirectory 的顺序解析真实家目录,
GUI 提权执行时显式导出 TCC_USER_HOME。

顺带:只有屏幕录制/辅助功能/输入监控/完全磁盘访问位于系统级库需要
root,提权开关改为跟随勾选自动设置,默认关闭。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@cuijianzhuang
cuijianzhuang merged commit 77ab96f into main Aug 29, 2026
1 check passed

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 67396a587d

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread Sources/App.swift
@State private var selected: Set<String> = ["Microphone", "Camera"]
@State private var action: TCCAction = .add
@State private var useAdmin = true
@State private var useAdmin = false

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Update the documented privilege default

Changing this default to false leaves the user-facing instructions inconsistent: README.md:73 still says that administrator mode is enabled by default and always presents a password dialog. With the default Camera/Microphone selection, users now see neither behavior, so the permissions documentation should describe the new service-dependent automatic switching.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant