Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1468)

Side by Side Diff: chrome/browser/mac/authorization_util.mm

Issue 9764013: Move authorization_util files into base/mac. (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Fix license headers Created 8 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « chrome/browser/mac/authorization_util.h ('k') | chrome/browser/mac/install_from_dmg.mm » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/browser/mac/authorization_util.h"
6
7 #import <Foundation/Foundation.h>
8 #include <sys/wait.h>
9
10 #include <string>
11
12 #include "base/basictypes.h"
13 #include "base/eintr_wrapper.h"
14 #include "base/logging.h"
15 #include "base/mac/bundle_locations.h"
16 #include "base/mac/mac_logging.h"
17 #import "base/mac/mac_util.h"
18 #include "base/string_number_conversions.h"
19 #include "base/string_util.h"
20 #include "chrome/browser/mac/scoped_authorizationref.h"
21
22 namespace authorization_util {
23
24 AuthorizationRef AuthorizationCreateToRunAsRoot(CFStringRef prompt) {
25 // Create an empty AuthorizationRef.
26 ScopedAuthorizationRef authorization;
27 OSStatus status = AuthorizationCreate(NULL,
28 kAuthorizationEmptyEnvironment,
29 kAuthorizationFlagDefaults,
30 &authorization);
31 if (status != errAuthorizationSuccess) {
32 OSSTATUS_LOG(ERROR, status) << "AuthorizationCreate";
33 return NULL;
34 }
35
36 // Specify the "system.privilege.admin" right, which allows
37 // AuthorizationExecuteWithPrivileges to run commands as root.
38 AuthorizationItem right_items[] = {
39 {kAuthorizationRightExecute, 0, NULL, 0}
40 };
41 AuthorizationRights rights = {arraysize(right_items), right_items};
42
43 // product_logo_32.png is used instead of app.icns because Authorization
44 // Services can't deal with .icns files.
45 NSString* icon_path =
46 [base::mac::FrameworkBundle() pathForResource:@"product_logo_32"
47 ofType:@"png"];
48 const char* icon_path_c = [icon_path fileSystemRepresentation];
49 size_t icon_path_length = icon_path_c ? strlen(icon_path_c) : 0;
50
51 // The OS will append " Type an administrator's name and password to allow
52 // <CFBundleDisplayName> to make changes."
53 NSString* prompt_ns = base::mac::CFToNSCast(prompt);
54 const char* prompt_c = [prompt_ns UTF8String];
55 size_t prompt_length = prompt_c ? strlen(prompt_c) : 0;
56
57 AuthorizationItem environment_items[] = {
58 {kAuthorizationEnvironmentIcon, icon_path_length, (void*)icon_path_c, 0},
59 {kAuthorizationEnvironmentPrompt, prompt_length, (void*)prompt_c, 0}
60 };
61
62 AuthorizationEnvironment environment = {arraysize(environment_items),
63 environment_items};
64
65 AuthorizationFlags flags = kAuthorizationFlagDefaults |
66 kAuthorizationFlagInteractionAllowed |
67 kAuthorizationFlagExtendRights |
68 kAuthorizationFlagPreAuthorize;
69
70 status = AuthorizationCopyRights(authorization,
71 &rights,
72 &environment,
73 flags,
74 NULL);
75 if (status != errAuthorizationSuccess) {
76 if (status != errAuthorizationCanceled) {
77 OSSTATUS_LOG(ERROR, status) << "AuthorizationCopyRights";
78 }
79 return NULL;
80 }
81
82 return authorization.release();
83 }
84
85 OSStatus ExecuteWithPrivilegesAndGetPID(AuthorizationRef authorization,
86 const char* tool_path,
87 AuthorizationFlags options,
88 const char** arguments,
89 FILE** pipe,
90 pid_t* pid) {
91 // pipe may be NULL, but this function needs one. In that case, use a local
92 // pipe.
93 FILE* local_pipe;
94 FILE** pipe_pointer;
95 if (pipe) {
96 pipe_pointer = pipe;
97 } else {
98 pipe_pointer = &local_pipe;
99 }
100
101 // AuthorizationExecuteWithPrivileges wants |char* const*| for |arguments|,
102 // but it doesn't actually modify the arguments, and that type is kind of
103 // silly and callers probably aren't dealing with that. Put the cast here
104 // to make things a little easier on callers.
105 OSStatus status = AuthorizationExecuteWithPrivileges(authorization,
106 tool_path,
107 options,
108 (char* const*)arguments,
109 pipe_pointer);
110 if (status != errAuthorizationSuccess) {
111 return status;
112 }
113
114 int line_pid = -1;
115 size_t line_length = 0;
116 char* line_c = fgetln(*pipe_pointer, &line_length);
117 if (line_c) {
118 if (line_length > 0 && line_c[line_length - 1] == '\n') {
119 // line_c + line_length is the start of the next line if there is one.
120 // Back up one character.
121 --line_length;
122 }
123 std::string line(line_c, line_length);
124 if (!base::StringToInt(line, &line_pid)) {
125 // StringToInt may have set line_pid to something, but if the conversion
126 // was imperfect, use -1.
127 LOG(ERROR) << "ExecuteWithPrivilegesAndGetPid: funny line: " << line;
128 line_pid = -1;
129 }
130 } else {
131 LOG(ERROR) << "ExecuteWithPrivilegesAndGetPid: no line";
132 }
133
134 if (!pipe) {
135 fclose(*pipe_pointer);
136 }
137
138 if (pid) {
139 *pid = line_pid;
140 }
141
142 return status;
143 }
144
145 OSStatus ExecuteWithPrivilegesAndWait(AuthorizationRef authorization,
146 const char* tool_path,
147 AuthorizationFlags options,
148 const char** arguments,
149 FILE** pipe,
150 int* exit_status) {
151 pid_t pid;
152 OSStatus status = ExecuteWithPrivilegesAndGetPID(authorization,
153 tool_path,
154 options,
155 arguments,
156 pipe,
157 &pid);
158 if (status != errAuthorizationSuccess) {
159 return status;
160 }
161
162 // exit_status may be NULL, but this function needs it. In that case, use a
163 // local version.
164 int local_exit_status;
165 int* exit_status_pointer;
166 if (exit_status) {
167 exit_status_pointer = exit_status;
168 } else {
169 exit_status_pointer = &local_exit_status;
170 }
171
172 if (pid != -1) {
173 pid_t wait_result = HANDLE_EINTR(waitpid(pid, exit_status_pointer, 0));
174 if (wait_result != pid) {
175 PLOG(ERROR) << "waitpid";
176 *exit_status_pointer = -1;
177 }
178 } else {
179 *exit_status_pointer = -1;
180 }
181
182 return status;
183 }
184
185 } // namespace authorization_util
OLDNEW
« no previous file with comments | « chrome/browser/mac/authorization_util.h ('k') | chrome/browser/mac/install_from_dmg.mm » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698