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

Side by Side Diff: chrome/installer/gcapi_mac/gcapi.mm

Issue 10834102: mac: Let gcapi install chrome as the CGSession owner (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: foo Created 8 years, 4 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/installer/gcapi_mac/gcapi.h" 5 #include "chrome/installer/gcapi_mac/gcapi.h"
6 6
7 #import <Cocoa/Cocoa.h> 7 #import <Cocoa/Cocoa.h>
8 #include <pwd.h>
8 #include <sys/stat.h> 9 #include <sys/stat.h>
9 #include <sys/types.h> 10 #include <sys/types.h>
10 #include <sys/utsname.h> 11 #include <sys/utsname.h>
11 12
12 namespace { 13 namespace {
13 14
15 // The "~~" prefixes are replaced with the home directory of the
16 // console owner (i.e. not the home directory of the euid).
14 NSString* const kChromeInstallPath = @"/Applications/Google Chrome.app"; 17 NSString* const kChromeInstallPath = @"/Applications/Google Chrome.app";
15 18
16 NSString* const kBrandKey = @"KSBrandID"; 19 NSString* const kBrandKey = @"KSBrandID";
17 NSString* const kSystemBrandPath = @"/Library/Google/Google Chrome Brand.plist"; 20 NSString* const kSystemBrandPath = @"/Library/Google/Google Chrome Brand.plist";
Mark Mentovai 2012/08/13 13:14:42 Provided we’re just letting Chrome set up a user t
Nico 2012/08/13 14:52:57 Done.
18 NSString* const kUserBrandPath = @"~/Library/Google/Google Chrome Brand.plist"; 21 NSString* const kUserBrandPath = @"~~/Library/Google/Google Chrome Brand.plist";
19 22
20 NSString* const kSystemKsadminPath = 23 NSString* const kSystemKsadminPath =
21 @"/Library/Google/GoogleSoftwareUpdate/GoogleSoftwareUpdate.bundle/" 24 @"/Library/Google/GoogleSoftwareUpdate/GoogleSoftwareUpdate.bundle/"
22 "Contents/MacOS/ksadmin"; 25 "Contents/MacOS/ksadmin";
23 26
24 NSString* const kUserKsadminPath = 27 NSString* const kUserKsadminPath =
25 @"~/Library/Google/GoogleSoftwareUpdate/GoogleSoftwareUpdate.bundle/" 28 @"~~/Library/Google/GoogleSoftwareUpdate/GoogleSoftwareUpdate.bundle/"
26 "Contents/MacOS/ksadmin"; 29 "Contents/MacOS/ksadmin";
27 30
28 NSString* const kSystemMasterPrefsPath = 31 NSString* const kSystemMasterPrefsPath =
29 @"/Library/Google/Google Chrome Master Preferences"; 32 @"/Library/Google/Google Chrome Master Preferences";
30 NSString* const kUserMasterPrefsPath = 33 NSString* const kUserMasterPrefsPath =
31 @"~/Library/Application Support/Google/Google Chrome Master Preferences"; 34 @"~~/Library/Application Support/Google/Google Chrome Master Preferences";
32 35
33 NSString* const kChannelKey = @"KSChannelID"; 36 NSString* const kChannelKey = @"KSChannelID";
34 NSString* const kVersionKey = @"KSVersion"; 37 NSString* const kVersionKey = @"KSVersion";
35 38
36 // Condensed from chromium's base/mac/mac_util.mm. 39 // Condensed from chromium's base/mac/mac_util.mm.
37 bool IsOSXVersionSupported() { 40 bool IsOSXVersionSupported() {
38 // On 10.6, Gestalt() was observed to be able to spawn threads (see 41 // On 10.6, Gestalt() was observed to be able to spawn threads (see
39 // http://crbug.com/53200). Don't call Gestalt(). 42 // http://crbug.com/53200). Don't call Gestalt().
40 struct utsname uname_info; 43 struct utsname uname_info;
41 if (uname(&uname_info) != 0) 44 if (uname(&uname_info) != 0)
(...skipping 11 matching lines...) Expand all
53 56
54 // The Darwin major version is always 4 greater than the Mac OS X minor 57 // The Darwin major version is always 4 greater than the Mac OS X minor
55 // version for Darwin versions beginning with 6, corresponding to Mac OS X 58 // version for Darwin versions beginning with 6, corresponding to Mac OS X
56 // 10.2. 59 // 10.2.
57 int mac_os_x_minor_version = darwin_major_version - 4; 60 int mac_os_x_minor_version = darwin_major_version - 4;
58 61
59 // Chrome is known to work on 10.6 - 10.8. 62 // Chrome is known to work on 10.6 - 10.8.
60 return mac_os_x_minor_version >= 6 && mac_os_x_minor_version <= 8; 63 return mac_os_x_minor_version >= 6 && mac_os_x_minor_version <= 8;
61 } 64 }
62 65
66 // Returns the pid/gid of the logged-in user, even if getuid() claims that the
67 // current user is root.
68 // Returns NULL on error.
69 passwd* GetRealUserId() {
70 CFDictionaryRef sessionInfoDict = CGSessionCopyCurrentDictionary();
71 if (!sessionInfoDict)
72 return NULL; // Possibly no screen plugged in.
73
74 CFNumberRef userUID = (CFNumberRef)CFDictionaryGetValue(sessionInfoDict,
Mark Mentovai 2012/08/13 13:14:42 Can you use something like CFCast here?
Nico 2012/08/13 15:42:15 Doneish.
75 kCGSessionUserIDKey);
76 uid_t uid;
77 BOOL success = CFNumberGetValue(userUID, kCFNumberSInt32Type, &uid);
78 CFRelease(sessionInfoDict);
79 if (!success)
80 return NULL;
81
82 return getpwuid(uid);
83 }
84
63 enum TicketKind { 85 enum TicketKind {
64 kSystemTicket, kUserTicket 86 kSystemTicket, kUserTicket
65 }; 87 };
66 88
67 BOOL HasChromeTicket(TicketKind kind) { 89 // Replaces "~~" with |homedir|.
90 NSString* AdjustHomedir(NSString* s, const char* homedir) {
91 NSString* homeDir = [NSString stringWithUTF8String:homedir];
Mark Mentovai 2012/08/13 13:14:42 Naming nit: home_dir
Nico 2012/08/13 14:52:57 Done.
92 return [s stringByReplacingOccurrencesOfString:@"~~"
Mark Mentovai 2012/08/13 13:14:42 I’d be a little more comfortable if this only oper
Nico 2012/08/13 14:52:57 Done.
93 withString:homeDir];
94 }
95
96 BOOL HasChromeTicket(TicketKind kind, const char* homedir) {
68 // Don't use Objective-C 2 loop syntax, in case an installer runs on 10.4. 97 // Don't use Objective-C 2 loop syntax, in case an installer runs on 10.4.
69 NSMutableArray* keystonePaths = 98 NSMutableArray* keystonePaths =
Mark Mentovai 2012/08/13 13:14:42 Naming nit: keystone_paths. Line 109 too.
Nico 2012/08/13 14:52:57 Done.
70 [NSMutableArray arrayWithObject:kSystemKsadminPath]; 99 [NSMutableArray arrayWithObject:kSystemKsadminPath];
71 if (kind == kUserTicket && geteuid() != 0) 100 if (kind == kUserTicket != 0) {
72 [keystonePaths insertObject:kUserKsadminPath atIndex:0]; 101 [keystonePaths insertObject:AdjustHomedir(kUserKsadminPath, homedir)
102 atIndex:0];
103 }
73 NSEnumerator* e = [keystonePaths objectEnumerator]; 104 NSEnumerator* e = [keystonePaths objectEnumerator];
74 id ksPath; 105 id ksPath;
75 while ((ksPath = [e nextObject])) { 106 while ((ksPath = [e nextObject])) {
76 NSTask* task = nil; 107 NSTask* task = nil;
77 NSString* string = nil; 108 NSString* string = nil;
78 bool ksadminRanSuccessfully = false; 109 bool ksadminRanSuccessfully = false;
79 110
80 @try { 111 @try {
112 // XXX does this need to run as other user? or can admin read the user sto re?
Mark Mentovai 2012/08/13 13:14:42 What do you mean? That you want to check the conso
Nico 2012/08/13 14:13:33 Right, I imagine this code will usually run with e
Mark Mentovai 2012/08/13 15:04:34 Nico wrote:
Nico 2012/08/13 15:42:16 Done.
113 // it should be able to, so I think this is fine as is?
81 task = [[NSTask alloc] init]; 114 task = [[NSTask alloc] init];
82 [task setLaunchPath:ksPath]; 115 [task setLaunchPath:ksPath];
83 116
84 NSArray* arguments = @[ 117 NSArray* arguments = @[
85 kind == kUserTicket ? @"--user-store" : @"--system-store", 118 kind == kUserTicket ? @"--user-store" : @"--system-store",
86 @"--print-tickets", 119 @"--print-tickets",
87 @"--productid", 120 @"--productid",
88 @"com.google.Chrome", 121 @"com.google.Chrome",
89 ]; 122 ];
90 [task setArguments:arguments]; 123 [task setArguments:arguments];
(...skipping 22 matching lines...) Expand all
113 } 146 }
114 147
115 return NO; 148 return NO;
116 } 149 }
117 150
118 // Returns the file permission mask for files created by gcapi. 151 // Returns the file permission mask for files created by gcapi.
119 mode_t Permissions() { 152 mode_t Permissions() {
120 return 0755; 153 return 0755;
121 } 154 }
122 155
123 BOOL CreatePathToFile(NSString* path) { 156 BOOL CreatePathToFile(NSString* path, const passwd* user) {
124 path = [path stringByDeletingLastPathComponent]; 157 path = [path stringByDeletingLastPathComponent];
125 158
126 // Default owner, group, permissions: 159 // Default owner, group, permissions:
127 // * Permissions are set according to the umask of the current process. For 160 // * Permissions are set according to the umask of the current process. For
128 // more information, see umask. 161 // more information, see umask.
129 // * The owner ID is set to the effective user ID of the process. 162 // * The owner ID is set to the effective user ID of the process.
130 // * The group ID is set to that of the parent directory. 163 // * The group ID is set to that of the parent directory.
131 // The default group ID is fine. Owner ID is fine too, since user directory 164 // The default group ID is fine. Owner ID is fine if creating a system path,
132 // paths won't be created if euid is 0. Do set permissions explicitly; for 165 // but when creating a user path explicitly set the owner in case euid is 0.
133 // admin paths all admins can write, for user paths just the owner may. 166 // Do set permissions explicitly; for admin paths all admins can write, for
Mark Mentovai 2012/08/13 13:14:42 You haven’t made this so that all admins can write
Nico 2012/08/13 14:52:57 For admins, the group is set to wheel and permissi
Mark Mentovai 2012/08/13 15:04:34 Nico wrote:
Nico 2012/08/13 15:42:16 Done. (?)
167 // user paths just the owner may.
134 NSMutableDictionary* attributes = [NSMutableDictionary 168 NSMutableDictionary* attributes = [NSMutableDictionary
135 dictionaryWithObject:[NSNumber numberWithShort:Permissions()] 169 dictionaryWithObject:[NSNumber numberWithShort:Permissions()]
136 forKey:NSFilePosixPermissions]; 170 forKey:NSFilePosixPermissions];
137 if (geteuid() == 0) 171 if (user) {
172 [attributes setObject:[NSNumber numberWithInt:user->pw_uid]
173 forKey:NSFileOwnerAccountID];
174 // XXX do this? not needed i think?
175 //[attributes setObject:[NSNumber numberWithInt:user->pw_gid]
176 //forKey:NSFileGroupOwnerAccountID];
177 } else {
138 [attributes setObject:@"wheel" forKey:NSFileGroupOwnerAccountName]; 178 [attributes setObject:@"wheel" forKey:NSFileGroupOwnerAccountName];
179 }
139 180
140 NSFileManager* manager = [NSFileManager defaultManager]; 181 NSFileManager* manager = [NSFileManager defaultManager];
141 return [manager createDirectoryAtPath:path 182 return [manager createDirectoryAtPath:path
142 withIntermediateDirectories:YES 183 withIntermediateDirectories:YES
143 attributes:attributes 184 attributes:attributes
144 error:nil]; 185 error:nil];
145 } 186 }
146 187
147 // Tries to write |data| at |system_path| or if that fails and geteuid() is not 188 // Tries to write |data| at |system_path| or if that fails at |user_path|.
148 // 0 at |user_path|. Returns the path where it wrote, or nil on failure. 189 // Returns the path where it wrote, or nil on failure.
149 NSString* WriteData(NSData* data, NSString* system_path, NSString* user_path) { 190 NSString* WriteData(NSData* data,
191 NSString* system_path,
192 NSString* user_path,
193 const passwd* user) {
194 // XXX do we still want to try to write this to a system path? probably?
Mark Mentovai 2012/08/13 13:14:42 Brand file, no. The brand file should only be writ
Nico 2012/08/13 14:52:57 Done.
195
150 // Try system first. 196 // Try system first.
151 if (CreatePathToFile(system_path) && 197 if (CreatePathToFile(system_path, NULL) &&
152 [data writeToFile:system_path atomically:YES]) { 198 [data writeToFile:system_path atomically:YES]) {
153 // files are created with group of parent dir (good), owner of euid (good). 199 // files are created with group of parent dir (good), owner of euid (good).
154 chmod([system_path fileSystemRepresentation], Permissions() & ~0111); 200 chmod([system_path fileSystemRepresentation], Permissions() & ~0111);
155 return system_path; 201 return system_path;
156 } 202 }
157 203
158 // Failed, try user. 204 // Failed, try user.
159 // -stringByExpandingTildeInPath returns root's home directory if this is run 205 user_path = AdjustHomedir(user_path, user->pw_dir);
160 // setuid root, and in that case the kSystemBrandPath path above should have 206 if (CreatePathToFile(user_path, user) &&
161 // worked anyway. So only try user if geteuid() isn't root. 207 [data writeToFile:user_path atomically:YES]) {
162 if (geteuid() != 0) { 208 chmod([user_path fileSystemRepresentation], Permissions() & ~0111);
163 user_path = [user_path stringByExpandingTildeInPath]; 209 chown([user_path fileSystemRepresentation], user->pw_uid, user->pw_gid);
164 if (CreatePathToFile(user_path) && 210 return user_path;
165 [data writeToFile:user_path atomically:YES]) {
166 chmod([user_path fileSystemRepresentation], Permissions() & ~0111);
167 return user_path;
168 }
169 } 211 }
170 return nil; 212 return nil;
171 } 213 }
172 214
173 NSString* WriteBrandCode(const char* brand_code) { 215 NSString* WriteBrandCode(const char* brand_code, const passwd* user) {
174 NSDictionary* brand_dict = @{ 216 NSDictionary* brand_dict = @{
175 kBrandKey: [NSString stringWithUTF8String:brand_code], 217 kBrandKey: [NSString stringWithUTF8String:brand_code],
176 }; 218 };
177 NSData* contents = [NSPropertyListSerialization 219 NSData* contents = [NSPropertyListSerialization
178 dataFromPropertyList:brand_dict 220 dataFromPropertyList:brand_dict
179 format:NSPropertyListBinaryFormat_v1_0 221 format:NSPropertyListBinaryFormat_v1_0
180 errorDescription:nil]; 222 errorDescription:nil];
181 223
182 return WriteData(contents, kSystemBrandPath, kUserBrandPath); 224 return WriteData(contents, kSystemBrandPath, kUserBrandPath, user);
183 } 225 }
184 226
185 BOOL WriteMasterPrefs(const char* master_prefs_contents, 227 BOOL WriteMasterPrefs(const char* master_prefs_contents,
186 size_t master_prefs_contents_size) { 228 size_t master_prefs_contents_size,
229 const passwd* user) {
187 NSData* contents = [NSData dataWithBytes:master_prefs_contents 230 NSData* contents = [NSData dataWithBytes:master_prefs_contents
188 length:master_prefs_contents_size]; 231 length:master_prefs_contents_size];
189 return 232 return WriteData(
190 WriteData(contents, kSystemMasterPrefsPath, kUserMasterPrefsPath) != nil; 233 contents, kSystemMasterPrefsPath, kUserMasterPrefsPath, user) != nil;
191 } 234 }
192 235
193 NSString* PathToFramework(NSString* app_path, NSDictionary* info_plist) { 236 NSString* PathToFramework(NSString* app_path, NSDictionary* info_plist) {
194 NSString* version = [info_plist objectForKey:@"CFBundleShortVersionString"]; 237 NSString* version = [info_plist objectForKey:@"CFBundleShortVersionString"];
195 if (!version) 238 if (!version)
196 return nil; 239 return nil;
197 return [[[app_path 240 return [[[app_path
198 stringByAppendingPathComponent:@"Contents/Versions"] 241 stringByAppendingPathComponent:@"Contents/Versions"]
199 stringByAppendingPathComponent:version] 242 stringByAppendingPathComponent:version]
200 stringByAppendingPathComponent:@"Google Chrome Framework.framework"]; 243 stringByAppendingPathComponent:@"Google Chrome Framework.framework"];
201 } 244 }
202 245
203 NSString* PathToInstallScript(NSString* app_path, NSDictionary* info_plist) { 246 NSString* PathToInstallScript(NSString* app_path, NSDictionary* info_plist) {
204 return [PathToFramework(app_path, info_plist) stringByAppendingPathComponent: 247 return [PathToFramework(app_path, info_plist) stringByAppendingPathComponent:
205 @"Resources/install.sh"]; 248 @"Resources/install.sh"];
206 } 249 }
207 250
208 bool isbrandchar(int c) { 251 bool isbrandchar(int c) {
209 // Always four upper-case alpha chars. 252 // Always four upper-case alpha chars.
210 return c >= 'A' && c <= 'Z'; 253 return c >= 'A' && c <= 'Z';
211 } 254 }
212 255
213 } // namespace 256 } // namespace
214 257
215 int GoogleChromeCompatibilityCheck(unsigned* reasons) { 258 int GoogleChromeCompatibilityCheck(unsigned* reasons) {
259 passwd* user = GetRealUserId();
260
216 unsigned local_reasons = 0; 261 unsigned local_reasons = 0;
217 262
218 NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; 263 NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
219 264
220 if (!IsOSXVersionSupported()) 265 if (!IsOSXVersionSupported())
221 local_reasons |= GCCC_ERROR_OSNOTSUPPORTED; 266 local_reasons |= GCCC_ERROR_OSNOTSUPPORTED;
222 267
223 if (HasChromeTicket(kSystemTicket)) 268 if (HasChromeTicket(kSystemTicket, user->pw_dir))
224 local_reasons |= GCCC_ERROR_SYSTEMLEVELALREADYPRESENT; 269 local_reasons |= GCCC_ERROR_SYSTEMLEVELALREADYPRESENT;
225 270
226 if (geteuid() != 0 && HasChromeTicket(kUserTicket)) 271 if (HasChromeTicket(kUserTicket, user->pw_dir))
227 local_reasons |= GCCC_ERROR_USERLEVELALREADYPRESENT; 272 local_reasons |= GCCC_ERROR_USERLEVELALREADYPRESENT;
228 273
229 if (![[NSFileManager defaultManager] isWritableFileAtPath:@"/Applications"]) 274 if (![[NSFileManager defaultManager] isWritableFileAtPath:@"/Applications"])
230 local_reasons |= GCCC_ERROR_ACCESSDENIED; 275 local_reasons |= GCCC_ERROR_ACCESSDENIED;
231 276
277 if (!local_reasons && [[NSFileManager defaultManager]
278 fileExistsAtPath:@"/Applications/Google Chrome.app"]) {
279 local_reasons |= GCCC_ERROR_ACCESSDENIED;
Mark Mentovai 2012/08/13 13:14:42 Is this the right “reason” or should you add a new
Nico 2012/08/13 14:52:57 How would the new reason be called? Or should the
Mark Mentovai 2012/08/13 15:04:34 Nico wrote:
Nico 2012/08/13 15:42:16 Done.
280 }
281
232 [pool drain]; 282 [pool drain];
233 283
234 // Done. Copy/return results. 284 // Done. Copy/return results.
235 if (reasons != NULL) 285 if (reasons != NULL)
236 *reasons = local_reasons; 286 *reasons = local_reasons;
237 287
238 return local_reasons == 0; 288 return local_reasons == 0;
239 } 289 }
240 290
241 int InstallGoogleChrome(const char* source_path, 291 int InstallGoogleChrome(const char* source_path,
242 const char* brand_code, 292 const char* brand_code,
243 const char* master_prefs_contents, 293 const char* master_prefs_contents,
244 unsigned master_prefs_contents_size) { 294 unsigned master_prefs_contents_size) {
245 if (!GoogleChromeCompatibilityCheck(NULL)) 295 if (!GoogleChromeCompatibilityCheck(NULL))
246 return 0; 296 return 0;
247 297
298 passwd* user = GetRealUserId();
299
248 @autoreleasepool { 300 @autoreleasepool {
249 NSString* app_path = [NSString stringWithUTF8String:source_path]; 301 NSString* app_path = [NSString stringWithUTF8String:source_path];
250 NSString* info_plist_path = 302 NSString* info_plist_path =
251 [app_path stringByAppendingPathComponent:@"Contents/Info.plist"]; 303 [app_path stringByAppendingPathComponent:@"Contents/Info.plist"];
252 NSDictionary* info_plist = 304 NSDictionary* info_plist =
253 [NSDictionary dictionaryWithContentsOfFile:info_plist_path]; 305 [NSDictionary dictionaryWithContentsOfFile:info_plist_path];
254 306
255 // Use install.sh from the Chrome app bundle to copy Chrome to its 307 // Use install.sh from the Chrome app bundle to copy Chrome to its
256 // destination. 308 // destination.
257 NSString* install_script = PathToInstallScript(app_path, info_plist); 309 NSString* install_script = PathToInstallScript(app_path, info_plist);
258 if (!install_script) { 310 if (!install_script) {
259 return 0; 311 return 0;
260 } 312 }
261 313
262 @try { 314 @try {
315 // install.sh tries to make the installed app admin-writable, but
316 // only when it's not run as root.
317 NSString* run_as = [NSString stringWithUTF8String:user->pw_name];
263 NSTask* task = [[[NSTask alloc] init] autorelease]; 318 NSTask* task = [[[NSTask alloc] init] autorelease];
264 [task setLaunchPath:install_script]; 319 [task setLaunchPath:@"/usr/bin/sudo"];
265 [task setArguments:@[app_path, kChromeInstallPath]]; 320 [task setArguments:
321 @[@"-u", run_as, install_script, app_path, kChromeInstallPath]];
266 [task launch]; 322 [task launch];
267 [task waitUntilExit]; 323 [task waitUntilExit];
268 if ([task terminationStatus] != 0) { 324 if ([task terminationStatus] != 0) {
269 return 0; 325 return 0;
270 } 326 }
271 } 327 }
272 @catch (id exception) { 328 @catch (id exception) {
273 return 0; 329 return 0;
274 } 330 }
275 331
276 // Set brand code. If Chrome's Info.plist contains a brand code, use that. 332 // Set brand code. If Chrome's Info.plist contains a brand code, use that.
277 NSString* info_plist_brand = [info_plist objectForKey:kBrandKey]; 333 NSString* info_plist_brand = [info_plist objectForKey:kBrandKey];
278 if (info_plist_brand && 334 if (info_plist_brand &&
279 [info_plist_brand respondsToSelector:@selector(UTF8String)]) 335 [info_plist_brand respondsToSelector:@selector(UTF8String)])
280 brand_code = [info_plist_brand UTF8String]; 336 brand_code = [info_plist_brand UTF8String];
281 337
282 BOOL valid_brand_code = brand_code && strlen(brand_code) == 4 && 338 BOOL valid_brand_code = brand_code && strlen(brand_code) == 4 &&
283 isbrandchar(brand_code[0]) && isbrandchar(brand_code[1]) && 339 isbrandchar(brand_code[0]) && isbrandchar(brand_code[1]) &&
284 isbrandchar(brand_code[2]) && isbrandchar(brand_code[3]); 340 isbrandchar(brand_code[2]) && isbrandchar(brand_code[3]);
285 341
286 NSString* brand_path = nil; 342 NSString* brand_path = nil;
287 if (valid_brand_code) 343 if (valid_brand_code)
288 brand_path = WriteBrandCode(brand_code); 344 brand_path = WriteBrandCode(brand_code, user);
289 345
290 // Write master prefs. 346 // Write master prefs.
291 if (master_prefs_contents) 347 if (master_prefs_contents)
292 WriteMasterPrefs(master_prefs_contents, master_prefs_contents_size); 348 WriteMasterPrefs(master_prefs_contents, master_prefs_contents_size, user);
293 349
294 // TODO Set default browser if requested. Will be tricky when running as 350 // TODO Set default browser if requested.
295 // root.
296 } 351 }
297 return 1; 352 return 1;
298 } 353 }
299 354
300 int LaunchGoogleChrome() { 355 int LaunchGoogleChrome() {
356 //passwd* user = GetRealUserId();
357
301 @autoreleasepool { 358 @autoreleasepool {
359 // NSWorkspace launches processes as the current console owner,
360 // even when running with euid of 0.
302 return [[NSWorkspace sharedWorkspace] launchApplication:kChromeInstallPath]; 361 return [[NSWorkspace sharedWorkspace] launchApplication:kChromeInstallPath];
303 } 362 }
304 } 363 }
OLDNEW
« chrome/installer/gcapi_mac/OWNERS ('K') | « chrome/installer/gcapi_mac/OWNERS ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698