Le roukin
Le roukin

Reputation: 95

AuthorizationExecuteWithPrivileges() as root Error

I am a beginner in cocoa...

I just want to start Apache and other process in my Cocoa App.

Here is my code :

    OSStatus myStatus;
    AuthorizationFlags myFlags = kAuthorizationFlagDefaults;
    AuthorizationRef myAuthorizationRef;
    FILE *pipe = NULL;
    myStatus = AuthorizationCreate(NULL, kAuthorizationEmptyEnvironment, myFlags, &myAuthorizationRef);
    AuthorizationItem myItems = {kAuthorizationRightExecute, 0, NULL, 0};
    AuthorizationRights myRights = {1, &myItems};
    myFlags = kAuthorizationFlagDefaults | 
    kAuthorizationFlagInteractionAllowed |
    kAuthorizationFlagPreAuthorize |
    kAuthorizationFlagExtendRights;
    myStatus = AuthorizationCopyPrivilegedReference (&myAuthorizationRef,kAuthorizationFlagDefaults);
    myStatus = AuthorizationCopyRights (myAuthorizationRef,&myRights, NULL, myFlags, NULL ); 

    char *tool = "/usr/sbin/apachectl";
    char *args[] = { "start",NULL} ;    

    myStatus = AuthorizationExecuteWithPrivileges(myAuthorizationRef, tool, kAuthorizationFlagDefaults, args, &pipe);
    char c[100];
    int n=fread(c,1,100,pipe);
    c[n] = '\0';
    NSLog(@"%s\n",c);

theResult : This operation requires root
When I run a 'whoami', I'm 'root' but when I run a getuid(), I'm '501'...

I try to use setuid(0); But it doesn't set !!
Can you help me?
Thanks

Upvotes: 3

Views: 4448

Answers (3)

koush
koush

Reputation: 2962

I had this exact same problem. AuthorizationExecuteWithPrivileges allows you escalate your permission to root, but does not do it automatically (I guess to preserve the user session or whatever).

I ended up making a generic executable that would be run via AuthorizationExecuteWithPrivileges, and then that executable would setuid to root, and then exec the process you actually want to run as root.

Here's the source for the setuid wrapper executable:

#include <stdio.h>

int main(int argc, char** argv) {
  if (argc < 2) {
    printf("not enough arguments\n");
    return -1;
  }
  if (0 != setuid(0)) {
    printf("setuid failed.\n");
    return -3;
  }
  int i;
  char** argvz = (char**)malloc(sizeof(char*) * (argc - 1));
  for (i = 1; i < argc; i++) {
    argvz[i - 1] = argv[i];
  }

  execv(argv[1], argvz);
  printf("execv returned?\n");
  return -2;
}

Then, basically run (calling it via AuthorizationExecuteWithPrivileges) it as:

setuid my-program-to-run and arguments to pass

It will setuid as root, and then run the program in question with the args given.

Note that you must call setuid from AuthorizationExecuteWithPrivileges As only the pid that was created by AuthorizationExecuteWithPrivileges will have escalated privileges (and setuid will exec and replace the process with your own).

Upvotes: 14

pldwan
pldwan

Reputation: 1

I'm facing exactly the same problem ! This is insane that a whoami returns "root" and a root command returns "root required" !! The sudoers solution may works but I think we would have to search around the setuid bit, as written here https://github.com/notbrien/OSXSlightlyBetterAuth/blob/master/OSXSlightlyBetterAuth.m#L94

Upvotes: 0

Michał Šrajer
Michał Šrajer

Reputation: 31182

I would define access for user with uid=501 access to /usr/sbin/apachectl in /etc/sudoers, and execute "sudo /usr/sbin/apachectl" instead of /usr/sbin/apachectl in the code.

Upvotes: 0

Related Questions