Last active
November 23, 2017 12:40
-
-
Save adriannier/e4663482d5d3e7f9e91302f998344f86 to your computer and use it in GitHub Desktop.
Adds standard user temporarily to admin group, launches Console.app, and removes user from admin group right away.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
global gADMIN_USER | |
global gADMIN_PASSWORD | |
on run | |
try | |
-- Check system requirements | |
if requireMinimumSystemVersion("10.12.4") is false then return | |
-- Get current user | |
set standardUser to currentUser() | |
-- Make sure current user is not in admin group already | |
if standardUser is in adminUsers() then | |
error "This user is already an administrator." number 1 | |
end if | |
-- Prompt the user to select an administrator account | |
set gADMIN_USER to selectAdmin() | |
-- Ask for the admin password | |
askForAdminPassword() | |
-- Quit Console if running | |
quitConsoleApp() | |
-- Add current user to admin group | |
addToAdminGroup(standardUser) | |
try | |
-- Launch Console and bring to front | |
activateConsoleApp() | |
on error eMsg number eNum | |
-- Before raising error, clean up by removing user from admin group | |
removeFromAdminGroup(standardUser) | |
error eMsg number eNum | |
end try | |
-- Remove user from admin group | |
removeFromAdminGroup(standardUser) | |
on error eMsg number eNum | |
if eNum = -128 then return | |
activate | |
if eNum = -2700 then | |
display alert "Something went wrong" message eMsg | |
else | |
display alert "Something went wrong" message eMsg & " (" & (eNum as text) & ")" | |
end if | |
end try | |
end run | |
on currentUser() | |
try | |
return do shell script "whoami" | |
on error eMsg number eNum | |
error "Could not get name of current user. " & eMsg number eNum | |
end try | |
end currentUser | |
on adminUsers() | |
try | |
set theOutput to do shell script "dscl . -read /Groups/admin GroupMembership" | |
set o to offset of ": " in theOutput | |
set theOutput to text (o + 2) thru -1 of theOutput | |
set userNames to words of theOutput | |
set filteredUserNames to {} | |
repeat with i from 1 to count of userNames | |
if item i of userNames is not "root" then | |
set end of filteredUserNames to item i of userNames | |
end if | |
end repeat | |
return filteredUserNames | |
on error eMsg number eNum | |
error "Could not get list of administrators. " & eMsg number eNum | |
end try | |
end adminUsers | |
on selectAdmin() | |
set allAdmins to adminUsers() | |
if (count of allAdmins) is 1 then return item 1 of allAdmins | |
set chosenAdmins to choose from list allAdmins default items {item 1 of allAdmins} | |
if chosenAdmins is false then error "User cancelled." number -128 | |
return item 1 of chosenAdmins | |
end selectAdmin | |
on askForAdminPassword() | |
try | |
repeat with i from 1 to 10 | |
set gADMIN_PASSWORD to text returned of (display dialog "Enter password for " & gADMIN_USER & ":" default answer "" with hidden answer) | |
if gADMIN_PASSWORD is not "" then | |
if testUserPassword(gADMIN_USER, gADMIN_PASSWORD) then exit repeat | |
end if | |
-- Throttle subsequent attempts | |
if i < 10 then delay (i * 0.3) | |
end repeat | |
if testUserPassword(gADMIN_USER, gADMIN_PASSWORD) is false then error "Could not authenticate as administrator." number 2 | |
on error eMsg number eNum | |
if eNum is not 1 then | |
error "Could not test admin password. " & eMsg number eNum | |
else | |
error eMsg number eNum | |
end if | |
end try | |
end askForAdminPassword | |
on testUserPassword(theUser, thePassword) | |
try | |
set theOutput to do shell script "/usr/bin/expect -f - <<EOD | |
spawn su " & theUser & " | |
expect \"Password:\" | |
send \"" & thePassword & "\\r\" | |
expect \"$ \" | |
send \"whoami\\r\" | |
expect \"$ \" | |
send \"exit\\r\" | |
EOD" | |
set nl to (ASCII character 13) | |
set testString to "whoami" & nl & theUser & nl | |
if theOutput does not contain testString then | |
return false | |
else | |
return true | |
end if | |
on error eMsg number eNum | |
if eMsg contains "not open" then | |
return false | |
else | |
error "Could not test user password. " & eMsg number eNum | |
end if | |
end try | |
end testUserPassword | |
on addToAdminGroup(userName) | |
try | |
repeat with i from 1 to 3 | |
try | |
-- Make sure current user is not in admin group | |
if userName is in adminUsers() then return | |
-- Run an expect script to switch to the admintrative user and add standard user to admin group | |
do shell script "/usr/bin/expect -f - <<EOD | |
spawn su " & gADMIN_USER & " | |
expect \"Password:\" | |
send \"" & gADMIN_PASSWORD & "\\r\" | |
expect \"$ \" | |
send \"sudo dscl . -append /Groups/admin GroupMembership " & userName & "\\r\" | |
expect \"Password:\" | |
send \"" & gADMIN_PASSWORD & "\\r\" | |
expect \"$ \" | |
send \"exit\\r\" | |
EOD" | |
delay 0.3 | |
-- Check to see if user has been added (in testing sometimes the dscl command was ineffective) | |
if userName is in adminUsers() then return | |
on error eMsg number eNum | |
-- Save error for raising it after the loop | |
end try | |
if i < 3 then delay 1 | |
end repeat | |
error eMsg number eNum | |
on error eMsg number eNum | |
error "Could not remove " & userName & " from the list of administrators. Please do so manually. Error: " & eMsg number eNum | |
end try | |
end addToAdminGroup | |
on removeFromAdminGroup(userName) | |
try | |
repeat with i from 1 to 3 | |
try | |
-- Make sure current user is still in admin group | |
if userName is not in adminUsers() then return | |
-- Run an expect script to switch to the admintrative user and remove standard user from admin group | |
do shell script "/usr/bin/expect -f - <<EOD | |
spawn su " & gADMIN_USER & " | |
expect \"Password:\" | |
send \"" & gADMIN_PASSWORD & "\\r\" | |
expect \"$ \" | |
send \"sudo dscl . -delete /Groups/admin GroupMembership " & userName & "\\r\" | |
expect \"Password:\" | |
send \"" & gADMIN_PASSWORD & "\\r\" | |
expect \"$ \" | |
send \"exit\\r\" | |
EOD" | |
delay 0.3 | |
-- Check to see if user is removed (in testing sometimes the dscl command was ineffective) | |
if userName is not in adminUsers() then return | |
on error eMsg number eNum | |
-- Save error for raising it after the loop | |
end try | |
if i < 3 then delay 1 | |
end repeat | |
error eMsg number eNum | |
on error eMsg number eNum | |
error "Could not remove " & userName & " from the list of administrators. Please do so manually. Error: " & eMsg number eNum | |
end try | |
end removeFromAdminGroup | |
on activateConsoleApp() | |
repeat with i from 1 to 3 | |
if consoleAppRunning() is false then | |
tell application "Console" to activate | |
delay 1 | |
else | |
return | |
end if | |
end repeat | |
if consoleAppRunning() is false then error "Could not launch Console.app." number 3 | |
end activateConsoleApp | |
on consoleAppRunning() | |
try | |
do shell script "pgrep -u `whoami` -f /Applications/Utilities/Console.app" | |
return true | |
on error | |
return false | |
end try | |
end consoleAppRunning | |
on quitConsoleApp() | |
repeat with i from 1 to 3 | |
if consoleAppRunning() then | |
tell application "Console" to quit | |
delay 1 | |
else | |
return | |
end if | |
end repeat | |
if consoleAppRunning() then error "Could not quit Console.app." number 4 | |
end quitConsoleApp | |
on requireMinimumSystemVersion(minimumSystemVersion) | |
set currentVersion to parseVersionString(do shell script "sw_vers -productVersion") | |
set requiredVersion to parseVersionString(minimumSystemVersion) | |
if (majorVersion of currentVersion) < (majorVersion of requiredVersion) then | |
set requirementsMet to false | |
else if (majorVersion of currentVersion) = (majorVersion of requiredVersion) then | |
if (minorVersion of currentVersion) < (minorVersion of requiredVersion) then | |
set requirementsMet to false | |
else if (minorVersion of currentVersion) = (minorVersion of requiredVersion) then | |
if (theRevision of currentVersion) < (theRevision of requiredVersion) then | |
set requirementsMet to false | |
else | |
set requirementsMet to true | |
end if | |
else | |
set requirementsMet to true | |
end if | |
else | |
set requirementsMet to true | |
end if | |
if requirementsMet then return true | |
-- Display a dialog if requirements are not met | |
try | |
set targetLanguage to first word of (do shell script "defaults read NSGlobalDomain AppleLanguages") | |
on error | |
set targetLanguage to "en" | |
end try | |
if targetLanguage is "de" then | |
set dialogTitle to "Nicht unterst" & (ASCII character 159) & "tztes System" | |
set dialogMessage to "Dieses Skript erfordert mindestens die Systemversion " & minimumSystemVersion & ". " | |
else | |
set dialogTitle to "System not supported" | |
set dialogMessage to "This script requires at least system version " & minimumSystemVersion & ". " | |
end if | |
activate | |
if (majorVersion of currentVersion) ≥ 10 and (minorVersion of currentVersion) ≥ 4 then | |
display alert dialogTitle message dialogMessage buttons {"OK"} default button "OK" as warning | |
else | |
display dialog dialogTitle & return & return & dialogMessage buttons {"OK"} default button "OK" with icon 2 | |
end if | |
return false | |
end requireMinimumSystemVersion | |
on parseVersionString(versionString) | |
set prvDlmt to text item delimiters | |
set text item delimiters to "." | |
try | |
set majorVersion to (text item 1 of versionString) as integer | |
on error | |
set majorVersion to 0 | |
end try | |
try | |
set minorVersion to (text item 2 of versionString) as integer | |
on error | |
set minorVersion to 0 | |
end try | |
try | |
set theRevision to (text item 3 of versionString) as integer | |
on error | |
set theRevision to 0 | |
end try | |
set text item delimiters to prvDlmt | |
return {majorVersion:majorVersion, minorVersion:minorVersion, theRevision:theRevision} | |
end parseVersionString |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment