diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..8d9bfac --- /dev/null +++ b/.gitignore @@ -0,0 +1,96 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +*.egg-info/ +.installed.cfg +*.egg + +# PyInstaller +*.manifest +*.spec + +# Unit test / coverage reports +htmlcov/ +.tox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +.hypothesis/ +.pytest_cache/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# pyenv +.python-version + +# celery beat schedule file +celerybeat-schedule + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ diff --git a/README.md b/README.md index dbc9fb1..bec4430 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,20 @@ Apple has a utility in `/usr/bin` named `tccutil`, but it only supports one command, which is to `reset` the entire database. It has been like this for many versions of macOS. I wanted a command-line utility that would be able to add, remove, list, and take other actions. +## Understanding Global vs Local TCC Databases + +macOS maintains two separate TCC databases: + +1. **Global TCC Database** (`/Library/Application Support/com.apple.TCC/TCC.db`) + - System-wide permissions that apply to all users + - **Requires sudo/admin privileges** to modify + - Used by default when running `tccutil.py` without the `--user` flag + +2. **Local User TCC Database** (`~/Library/Application Support/com.apple.TCC/TCC.db`) + - User-specific permissions + - **Does NOT require sudo** - users can modify their own database + - Accessed by using the `--user` flag (e.g., `tccutil.py --list -u`) + ## SIP Notice This tool needs SIP disabled in order to function. The risk of doing so is up to you. @@ -58,7 +72,10 @@ Clone this repo and manually copy `tccutil.py` to `/usr/local/bin` or run from a ## Usage -**This utility needs super-user priveleges for most operations.** It is important that you either run this as root or use `sudo`, otherwise it won't work and you will end up with “permission denied” errors. +**Important:** The privileges required depend on which database you're modifying: + +- **Global TCC Database** (default): Requires super-user privileges. Run with `sudo`. +- **Local User TCC Database** (with `--user` flag): Does NOT require `sudo`. Can be run as a regular user. ``` @@ -96,30 +113,20 @@ optional arguments: ### Examples +#### Global TCC Database (System-wide, requires sudo) + List existing Entries in the Accessibility Database ```bash sudo tccutil.py --list ``` -List existing Entries in the Accessibility Database specific to the current user - -```bash -sudo tccutil.py --list -u -``` - Add `/usr/bin/osascript` to the Accessibility Database (using UNIX-Style Option) ```bash sudo tccutil.py -i /usr/bin/osascript ```` -Add `/usr/bin/osascript` to the Accessibility Database specific to user 'myuser' (using UNIX-Style Option) - -```bash -sudo tccutil.py -i /usr/bin/osascript -u myuser -```` - Add *Script Editor* to the Accessibility Database (using Long Option) ```bash @@ -150,6 +157,26 @@ Reset system wide accessibility database sudo tccutil.py reset ALL ``` +#### Local User TCC Database (User-specific, no sudo required) + +List existing Entries in the current user's Accessibility Database + +```bash +tccutil.py --list -u +``` + +Add `/usr/bin/osascript` to the current user's Accessibility Database + +```bash +tccutil.py -i /usr/bin/osascript -u +``` + +Add `/usr/bin/osascript` to a specific user's Accessibility Database + +```bash +tccutil.py -i /usr/bin/osascript -u myuser +``` + ## Contributing Many people have contributed already, so feel free to make a PR and we'll get it merged in. diff --git a/tccutil.py b/tccutil.py index e27e923..de89cc0 100755 --- a/tccutil.py +++ b/tccutil.py @@ -25,7 +25,7 @@ util_name = os.path.basename(sys.argv[0]) # Utility Version -util_version = '1.5.0' +util_version = '1.5.1' # Current OS X version osx_version = version(mac_ver()[0]) # mac_ver() returns 10.16 for Big Sur instead 11.+ @@ -36,6 +36,9 @@ # Set "sudo" to True if called with Admin-Privileges. sudo = True if os.getuid() == 0 else False +# Track if we're using local (user-specific) database +using_local_db = False + # Default Verbosity verbose = False @@ -105,9 +108,14 @@ def display_version(): def sudo_required(): """Check if user has root priveleges to access the database.""" + # Local user database doesn't require sudo + if using_local_db: + return + if not sudo: print("Error:", file=sys.stderr) - print(f" When accessing the Accessibility Database, {util_name} needs to be run with admin-privileges.\n", file=sys.stderr) + print(f" When accessing the global TCC Database, {util_name} needs to be run with admin-privileges.", file=sys.stderr) + print(f" To modify the local user database without sudo, use the --user flag.\n", file=sys.stderr) display_help(1) @@ -333,10 +341,12 @@ def main(): return global tcc_db + global using_local_db if args.user != None: try: if (len(args.user) > 0): pwd.getpwnam(args.user) - tcc_db = os.path.abspath(os.path.expanduser(f'~{args.user}/{tcc_db}')) + tcc_db = os.path.abspath(os.path.expanduser(f'~{args.user}/Library/Application Support/com.apple.TCC/TCC.db')) + using_local_db = True except KeyError: print(f'User "{args.user}" does not exist. Do you mean to use "{args.user}" as ACTION?', file=sys.stderr) sys.exit(1)