4

How can I run sudo commands from objective-c? I am able to run simple commands that don't require sudo with the following method:

NSTask *task;
task = [[NSTask alloc] init];
[task setLaunchPath: @"/bin/sh"];

NSArray *arguments = [NSArray arrayWithObjects:@"-c" ,[NSString stringWithFormat:@"%@", cmd], nil];


NSLog(@"run command: %@",cmd);
[task setArguments: arguments];

NSPipe *pipe;
pipe = [NSPipe pipe];
[task setStandardOutput: pipe];

NSFileHandle *file;
file = [pipe fileHandleForReading];

[task launch];

NSData *data;
data = [file readDataToEndOfFile];

NSString *output;
output = [[NSString alloc] initWithData: data encoding: NSUTF8StringEncoding];
return output;

When I run a sudo command i get the error: Operation not permitted.

From what I found online I need the gain authorisation. I read the Authorisation documentation from Apple but I doesn't specify a stating point.

The example EvenBetterAuthorizationSample from Apple doesn't work.

The application is signed with an Apple ID.

Alin Golumbeanu
  • 579
  • 1
  • 7
  • 18
  • Possible duplicate of http://stackoverflow.com/questions/4050687/how-to-use-nstask-as-root – tsnorri Dec 08 '14 at 14:25
  • 1
    Yes you need to gain authorisation. Is that your question? – Droppy Dec 08 '14 at 14:25
  • Are you trying to run a command as root, or are you actually trying to use it via the `sudo` command? If you want to go through `sudo` you need to have permission for the user owning the process in `/etc/sudoers`. – par Dec 08 '14 at 14:27
  • I want to execute the command: "sudo discoveryutil udnsflushcaches" to clean the DNS cache. – Alin Golumbeanu Dec 08 '14 at 14:40
  • Yes I need to gain authorisation. But how do I use the authorisation to execute the command. – Alin Golumbeanu Dec 08 '14 at 14:41
  • I reviewed all the example at http://stackoverflow.com/questions/4050687/how-to-use-nstask-as-root, it is not a possible duplicate, non of the example work. – Alin Golumbeanu Dec 08 '14 at 14:43

1 Answers1

3

You should study the Authorization Services Programming Guide, but if you want to do this using sudo you can.

What sudo requires is a password to authorise the execution, it normally gets this from the terminal - that is not the same as standard input though in a command shell the standard input by default is also connected to the terminal. The -S option of sudo instructs it to read the password from the standard input.

Following your existing design you can:

1) Add -S to the sudo command

2) The prompt for the password and any error messages, such as invalid password, will be written by sudo to the standard error. Create a pipe and attached it to the tasks standardError, or attach your existing pipe to both standardOutput and standardError, to capture this output.

3) Create another pipe and attach it to the tasks standardInput. Write the password followed by a newline to that pipe. When the task runs sudo will read the password and execute your command. Of course if the command itself requires input that will also be read from the pipe - so you must write it to the pipe.

HTH

CRD
  • 52,522
  • 5
  • 70
  • 86
  • The guide starts with: "Important: The authorization services API is not supported within an app sandbox because it allows privilege escalation." My application is an sandbox. – Alin Golumbeanu Dec 08 '14 at 19:13
  • 1
    If you're in the sandbox you are out of luck - trying to invoke `sudo` should fail as any other application yours invokes inherits your applications sandbox limitations. You either need to not sandbox your app or find a non-priviledged way to accomplish your goal. – CRD Dec 08 '14 at 20:17