I'm developing an OS X Firemonkey application that needs to launch "openvpn", but OpenVPN needs administrator permissions to create the tunnel interface.
I am trying to convert the first sample from this blog post to Delphi: http://www.michaelvobrien.com/blog/2009/07/authorizationexecutewithprivileges-a-simple-example/
Attempting to run this code, sometimes results in the authorisation prompt as expected, but clicking OK completely freezes the debugger and whole system needs to be powered off. It works better running without the debugger, but still sometimes will freeze... I've caught the return code before it crashes a couple of times, and it was errAuthorizationToolExecuteFailure
I'm not very familiar with how OSX does things, is there a better method? Apple doesn't recommend using AuthorizationExecuteWithPrivileges
for this. I don't know of any other way to run openvpn with the permissions it needs.
uses
Macapi.CoreFoundation, Macapi.Foundation, Macapi.Security;
const
kAuthorizationEmptyEnvironment = nil;
procedure TForm1.Button1Click(Sender: TObject);
var
AuthRef: AuthorizationRef;
Status: OSStatus;
begin
Status := AuthorizationCreate(nil,kAuthorizationEmptyEnvironment,kAuthorizationFlagDefaults,@AuthRef);
Status := AuthorizationExecuteWithPrivileges(AuthRef,'/sbin/dmesg',0,'',nil)
end;
The arguments
parameter of AuthorizationExecuteWithPrivileges
expects a pointer to an array of PAnsiChars that is terminated with a nil pointer as the last array item. You are simply passing a pointer to an empty string. That is going to give you random crashes depending on what happens to be in memory after the pointer to the empty string.
Try this:
procedure TForm1.Button1Click(Sender: TObject);
var
AuthRef: AuthorizationRef;
Status: OSStatus;
argv: array[0..0] of PAnsiChar;
begin
ArgV[0] := nil;
AuthRef := nil;
Status := AuthorizationCreate(nil,kAuthorizationEmptyEnvironment,kAuthorizationFlagDefaults,@AuthRef);
Status := AuthorizationExecuteWithPrivileges(AuthRef, '/sbin/dmesg', 0, @argv[0], nil);
AuthorizationFree(AuthRef, kAuthorizationFlagDefaults);
end;