Skip to content

Instantly share code, notes, and snippets.

@haircut
Last active June 5, 2023 16:27
Show Gist options
  • Star 8 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save haircut/20bc1b3f9ef0cec7d869a87b0db92fd3 to your computer and use it in GitHub Desktop.
Save haircut/20bc1b3f9ef0cec7d869a87b0db92fd3 to your computer and use it in GitHub Desktop.
Backs up authdb, then modifies them so users can modify Energy Saver, Network, Printers & Scanners, Date & Time, Time Machine
#!/usr/bin/python
'''
Modifies authorizations database to allow standard users to change select
system preferences.
A great guide to available authorization rights can be found at:
https://www.dssw.co.uk/reference/authorization-rights/index.html
USE AT YOUR OWN RISK
'''
import os
import datetime
import plistlib
import subprocess
# Path to back up current rights to
BACKUP_PATH = '/Library/Application Support/JAMF/auth_bkp'
# List of authorizations to be granted to modify
RIGHTS = ['system.preferences',
'system.preferences.datetime',
'system.preferences.timemachine',
'system.preferences.energysaver',
'system.preferences.network',
'system.preferences.printing']
# 'Level' at which to set the rights
# - 'allow' permanently unlocks the associated preference pane(s)
# - 'authenticate-session-owner-or-admin' requires entering credentials to
# unlock the preference pane(s), but allows standard users to do so
RIGHT_LEVEL = 'authenticate-session-owner-or-admin'
# Store current datetime
DTNOW = datetime.datetime.now().strftime('%Y-%m-%d-%H-%M-%S')
def get_auth_right(right, format='string'):
'''Gets the specified authorization right in plist format'''
cmd = ['/usr/bin/security', 'authorizationdb', 'read', right]
proc = subprocess.Popen(cmd, stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
out, _ = proc.communicate()
if format == 'plist':
return plistlib.readPlistFromString(out)
else:
return out
def backup_right_plist(right):
'''Backs up the original right definition'''
# Construct path to backup file, then ensure the path exists
path = os.path.join(BACKUP_PATH, DTNOW, '{}.plist'.format(right))
directory = os.path.dirname(path)
if not os.path.exists(directory):
os.makedirs(directory)
# Get the right definition as a plist
plist = get_auth_right(right)
# Write out the backup file
with open(path, 'w+') as out_plist:
out_plist.write(plist)
def set_right(right, level):
'''Sets the specified right to "allow"'''
cmd = ['/usr/bin/security', 'authorizationdb', 'write', right, level]
proc = subprocess.Popen(cmd, stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
out, _ = proc.communicate()
def main():
'''Main'''
for right in RIGHTS:
backup_right_plist(right)
set_right(right, RIGHT_LEVEL)
if __name__ == '__main__':
main()
@kylejericson
Copy link

@haircut Could we get this script updated to be bash so it will work with the next macOS when Python is removed?

@haircut
Copy link
Author

haircut commented Mar 12, 2022

@kylejericson I don't currently have a need for this workflow, so I don't intend to rewrite it in another language. It's a thin wrapper around /usr/bin/security authorizationdb system calls and you may be able to adapt that to your and your clients' needs.

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