AuthorizationExecuteWithPrivileges

Mac OSX specific forum
User avatar
Airr
User
User
Posts: 49
Joined: Tue Oct 04, 2005 4:29 am
Contact:

AuthorizationExecuteWithPrivileges

Post by Airr »

(Note: This API is considered deprecated and has been for years. It still works in Sierra, though).

I recently needed to be able to run a shell command that requires root/sudo access in order to complete successfully, and decided to see if I could use the Security Framework to accomplish this. Note that Apple's recommended approach to this is to create a privileged helper tool that actually performs the desired function(s). Not wanting to go down that rabbit hole yet, I put together the following example.

It creates 4 *.txt files in a restricted system area (/etc).

The code is a bit fugly, but does the job.

Comments welcome!

Code: Select all

; Parameter to pass to AuthorizationCreate when no environment is being provided.
#kAuthorizationEmptyEnvironment = 0

; AuthorizationFlags
Enumeration AuthorizationFlags
  #kAuthorizationFlagDefaults               = 0
	#kAuthorizationFlagInteractionAllowed	    = (1 << 0)
	#kAuthorizationFlagExtendRights			      = (1 << 1)
	#kAuthorizationFlagPartialRights			    = (1 << 2)
	#kAuthorizationFlagDestroyRights			    = (1 << 3)
	#kAuthorizationFlagPreAuthorize			      = (1 << 4)
EndEnumeration

; Error codes returned by Authorization API.
Enumeration AuthorizationResult
  #errAuthorizationSuccess                 = 0      ;/* The authorization was successful. */
	#errAuthorizationInvalidSet              = -60001 ;/* The authorization rights are invalid. */
	#errAuthorizationInvalidRef              = -60002 ;/* The authorization reference is invalid. */
	#errAuthorizationInvalidTag              = -60003 ;/* The authorization tag is invalid. */
	#errAuthorizationInvalidPointer          = -60004 ;/* The returned authorization is invalid. */
	#errAuthorizationDenied                  = -60005 ;/* The authorization was denied. */
	#errAuthorizationCanceled                = -60006 ;/* The authorization was cancelled by the user. */
	#errAuthorizationInteractionNotAllowed   = -60007 ;/* The authorization was denied since no user interaction was possible. */
	#errAuthorizationInternal                = -60008 ;/* Unable To obtain authorization For this operation. */
	#errAuthorizationExternalizeNotAllowed	 = -60009 ;/* The authorization is Not allowed To be converted To an external format. */
	#errAuthorizationInternalizeNotAllowed	 = -60010 ;/* The authorization is Not allowed To be created from an external format. */
	#errAuthorizationInvalidFlags            = -60011 ;/* The provided option flag(s) are invalid For this authorization operation. */
	#errAuthorizationToolExecuteFailure      = -60031 ;/* The specified program could Not be executed. */
	#errAuthorizationToolEnvironmenterror    = -60032 ;/* An invalid status was returned during execution of a privileged tool. */
	#errAuthorizationBadAddress              = -60033 ;/* The requested socket address is invalid (must be 0-1023 inclusive). */
EndEnumeration


ImportC "/System/Library/Frameworks/Security.framework/Security"
  AuthorizationCreate(rights, environment, flags, *AuthorizationRef)
  AuthorizationExecuteWithPrivileges(AuthorizationRef, cmd, flags, *arguments, file_ptr)
  AuthorizationFree(authRef,flags)
EndImport

Structure CMD
  parameter1.s
  parameter2.s
  parameter3.s
  parameter4.s
  parameter5.s
  parameter6.s
  parameter7.s
  parameter8.s
  cmd_terminator.i
EndStructure

Procedure.s UTF8 (in$)
   Protected s.s = Space(Len(in$) / 2)
   PokeS(@s, in$, -1, #PB_UTF8)
   ProcedureReturn s
EndProcedure
 
Procedure.l LaunchPrivilegedProcess(cmd.s, 
                                    arg1.s,
                                    arg2.s=#Null$,
                                    arg3.s=#Null$,
                                    arg4.s=#Null$,
                                    arg5.s=#Null$,
                                    arg6.s=#Null$,
                                    arg7.s=#Null$,
                                    arg8.s=#Null$)
  Protected AuthRef
  Protected ArgList.CMD
  Protected retval.l

  ArgList\parameter1 = UTF8(arg1)
  ArgList\parameter2 = UTF8(arg2)
  ArgList\parameter3 = UTF8(arg3)
  ArgList\parameter4 = UTF8(arg4)
  ArgList\parameter5 = UTF8(arg5)
  ArgList\parameter6 = UTF8(arg6)
  ArgList\parameter7 = UTF8(arg7)
  ArgList\parameter8 = UTF8(arg8)
  
  status = AuthorizationCreate(NULL, #kAuthorizationEmptyEnvironment, #kAuthorizationFlagDefaults,@AuthRef)
  
  If  status = #errAuthorizationSuccess
    status = AuthorizationExecuteWithPrivileges(AuthRef, UTF8(cmd), #kAuthorizationFlagDefaults, @ArgList,NULL)
    retval = PeekL(@status)
    AuthorizationFree(AuthRef, #kAuthorizationFlagDestroyRights)
  Else
    ProcedureReturn status
  EndIf
  ProcedureReturn retval  
EndProcedure

result = LaunchPrivilegedProcess("/usr/bin/touch","/etc/00-test.txt","/etc/01-test.txt","/etc/02-test.txt","/etc/03-test.txt")
If result = #errAuthorizationSuccess
  MessageRequester("Status","Authorization Successful")
EndIf

"Programming is like Poetry. Sometimes the words just escape you..." -me, to my manager.