[email protected] | ef12d1e6 | 2012-03-21 20:55:05 | [diff] [blame] | 1 | // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
[email protected] | 7d79165 | 2010-12-01 16:34:49 | [diff] [blame] | 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
| 4 | |
[email protected] | ef12d1e6 | 2012-03-21 20:55:05 | [diff] [blame] | 5 | #ifndef BASE_MAC_AUTHORIZATION_UTIL_H_ |
| 6 | #define BASE_MAC_AUTHORIZATION_UTIL_H_ |
[email protected] | 7d79165 | 2010-12-01 16:34:49 | [diff] [blame] | 7 | |
| 8 | // AuthorizationExecuteWithPrivileges fork()s and exec()s the tool, but it |
| 9 | // does not wait() for it. It also doesn't provide the caller with access to |
| 10 | // the forked pid. If used irresponsibly, zombie processes will accumulate. |
| 11 | // |
| 12 | // Apple's really gotten us between a rock and a hard place, here. |
| 13 | // |
| 14 | // Fortunately, AuthorizationExecuteWithPrivileges does give access to the |
| 15 | // tool's stdout (and stdin) via a FILE* pipe. The tool can output its pid |
| 16 | // to this pipe, and the main program can read it, and then have something |
| 17 | // that it can wait() for. |
| 18 | // |
| 19 | // The contract is that any tool executed by the wrappers declared in this |
| 20 | // file must print its pid to stdout on a line by itself before doing anything |
| 21 | // else. |
| 22 | // |
[email protected] | 5716ac6c | 2011-03-30 15:02:37 | [diff] [blame] | 23 | // http://developer.apple.com/library/mac/#samplecode/BetterAuthorizationSample/Listings/BetterAuthorizationSampleLib_c.html |
[email protected] | 7d79165 | 2010-12-01 16:34:49 | [diff] [blame] | 24 | // (Look for "What's This About Zombies?") |
| 25 | |
| 26 | #include <CoreFoundation/CoreFoundation.h> |
| 27 | #include <Security/Authorization.h> |
| 28 | #include <stdio.h> |
| 29 | #include <sys/types.h> |
| 30 | |
[email protected] | 6d26d7c | 2012-03-28 04:43:47 | [diff] [blame] | 31 | #include "base/base_export.h" |
| 32 | |
[email protected] | ef12d1e6 | 2012-03-21 20:55:05 | [diff] [blame] | 33 | namespace base { |
| 34 | namespace mac { |
[email protected] | 7d79165 | 2010-12-01 16:34:49 | [diff] [blame] | 35 | |
[email protected] | 429a6e0 | 2013-10-23 18:40:48 | [diff] [blame] | 36 | // Obtains an AuthorizationRef for the rights indicated by |rights|. If |
| 37 | // necessary, prompts the user for authentication. If the user is prompted, |
[email protected] | 7d79165 | 2010-12-01 16:34:49 | [diff] [blame] | 38 | // |prompt| will be used as the prompt string and an icon appropriate for the |
[email protected] | 429a6e0 | 2013-10-23 18:40:48 | [diff] [blame] | 39 | // application will be displayed in a prompt dialog. Note that the system |
| 40 | // appends its own text to the prompt string. |extraFlags| will be ORed |
| 41 | // together with the default flags. Returns NULL on failure. |
| 42 | BASE_EXPORT |
| 43 | AuthorizationRef GetAuthorizationRightsWithPrompt( |
| 44 | AuthorizationRights* rights, |
| 45 | CFStringRef prompt, |
| 46 | AuthorizationFlags extraFlags); |
| 47 | |
| 48 | // Obtains an AuthorizationRef (using |GetAuthorizationRightsWithPrompt|) that |
| 49 | // can be used to run commands as root. |
[email protected] | 6d26d7c | 2012-03-28 04:43:47 | [diff] [blame] | 50 | BASE_EXPORT |
[email protected] | 7d79165 | 2010-12-01 16:34:49 | [diff] [blame] | 51 | AuthorizationRef AuthorizationCreateToRunAsRoot(CFStringRef prompt); |
| 52 | |
| 53 | // Calls straight through to AuthorizationExecuteWithPrivileges. If that |
| 54 | // call succeeds, |pid| will be set to the pid of the executed tool. If the |
| 55 | // pid can't be determined, |pid| will be set to -1. |pid| must not be NULL. |
| 56 | // |pipe| may be NULL, but the tool will always be executed with a pipe in |
| 57 | // order to read the pid from its stdout. |
[email protected] | 3705af0 | 2012-04-21 01:22:30 | [diff] [blame] | 58 | BASE_EXPORT |
[email protected] | 7d79165 | 2010-12-01 16:34:49 | [diff] [blame] | 59 | OSStatus ExecuteWithPrivilegesAndGetPID(AuthorizationRef authorization, |
| 60 | const char* tool_path, |
| 61 | AuthorizationFlags options, |
| 62 | const char** arguments, |
| 63 | FILE** pipe, |
| 64 | pid_t* pid); |
| 65 | |
| 66 | // Calls ExecuteWithPrivilegesAndGetPID, and if that call succeeds, calls |
| 67 | // waitpid() to wait for the process to exit. If waitpid() succeeds, the |
| 68 | // exit status is placed in |exit_status|, otherwise, -1 is stored. |
| 69 | // |exit_status| may be NULL and this function will still wait for the process |
| 70 | // to exit. |
[email protected] | 6d26d7c | 2012-03-28 04:43:47 | [diff] [blame] | 71 | BASE_EXPORT |
[email protected] | 7d79165 | 2010-12-01 16:34:49 | [diff] [blame] | 72 | OSStatus ExecuteWithPrivilegesAndWait(AuthorizationRef authorization, |
| 73 | const char* tool_path, |
| 74 | AuthorizationFlags options, |
| 75 | const char** arguments, |
| 76 | FILE** pipe, |
| 77 | int* exit_status); |
| 78 | |
[email protected] | ef12d1e6 | 2012-03-21 20:55:05 | [diff] [blame] | 79 | } // namespace mac |
| 80 | } // namespace base |
[email protected] | 7d79165 | 2010-12-01 16:34:49 | [diff] [blame] | 81 | |
[email protected] | ef12d1e6 | 2012-03-21 20:55:05 | [diff] [blame] | 82 | #endif // BASE_MAC_AUTHORIZATION_UTIL_H_ |