I have a Cocoa application that need admin permission to execute a cmd, but in some extreme case like filename containing double quote, this code does not work.
NSString *fileName = @"~/Documents/My\" File/";
NSString *cmd = [NSString stringWithFormat:@"chown -R '%@' '%@';NSUserName(), fileName];
NSString *cmd_execute = [NSString stringWithFormat:@"do shell script
\"%@\" with administrator privileges",cmd_execute];
//This line is the problem, our %@ contains double quote, so cocoa
//cannot interpret correctly.
Here is the correct way to pass arguments into an AppleScript handler using NSAppleScript:
This avoids the need to munge and compile AS scripts on the fly - which, as your original ObjC code demonstrates, is a rich opportunity to introduce bugs and security holes into your program due to inadequate sanitization.
...
And here is the correct way to assemble shell script strings in AppleScript:
AppleScript's
do shell script
command doesn't provide a safe mechanism for passing arguments (it's deficient in a lot of other ways too), but AS strings have aquoted form
property that at least returns a quoted and escaped version of the text suitable for concatenating into a shell script string....
Of course, calling into shell via
do shell script
AppleScript just to runchmod
with escalated priveleges is not a little hacky in itself, though this is mostly Apple's fault for not providing a simple official API for doing so (e.g. by adding a 'run with admin privileges' option toNSUserScriptTask
).Apple do provide a sample project, SMJobBless that shows how to add and run privileged processes using the Service Management framework and launchd. But it's a sufficiently complex solution that a lot of folks will (knowingly or unknowingly) cut corners or do the wrong thing entirely, which rather defeats the point of providing a secure way of doing things in the first place. But you'll need to take that up with Apple.