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

Side by Side Diff: platform.cc

Issue 6729012: cryptohome: Add new platform functions (Closed) Base URL: ssh://git@gitrw.chromium.org:9222/cryptohome.git@master
Patch Set: . Created 9 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 | Annotate | Revision Log
« no previous file with comments | « platform.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2009-2010 The Chromium OS Authors. All rights reserved. 1 // Copyright (c) 2011 The Chromium OS 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 // Contains the implementation of class Platform 5 // Contains the implementation of class Platform
6 6
7 #include "platform.h" 7 #include "platform.h"
8 8
9 #include <errno.h> 9 #include <errno.h>
10 #include <grp.h>
10 #include <limits.h> 11 #include <limits.h>
11 #include <pwd.h> 12 #include <pwd.h>
12 #include <signal.h> 13 #include <signal.h>
13 #include <sys/mount.h> 14 #include <sys/mount.h>
14 #include <sys/stat.h> 15 #include <sys/stat.h>
15 #include <sys/statvfs.h> 16 #include <sys/statvfs.h>
16 #include <sys/types.h> 17 #include <sys/types.h>
18 #include <sys/wait.h>
17 19
18 #include <base/file_util.h> 20 #include <base/file_util.h>
19 #include <base/string_util.h> 21 #include <base/string_util.h>
20 22
21 // Included last to avoid redefinition problems 23 // Included last to avoid redefinition problems
22 extern "C" { 24 extern "C" {
23 #include <keyutils.h> 25 #include <keyutils.h>
24 } 26 }
25 27
26 using std::string; 28 using std::string;
(...skipping 303 matching lines...) Expand 10 before | Expand all | Expand 10 after
330 } 332 }
331 uid_t check_uid = static_cast<uid_t>(atoi(value.c_str())); 333 uid_t check_uid = static_cast<uid_t>(atoi(value.c_str()));
332 if (check_uid == uid) { 334 if (check_uid == uid) {
333 pids->push_back(pid); 335 pids->push_back(pid);
334 break; 336 break;
335 } 337 }
336 } 338 }
337 } 339 }
338 } 340 }
339 341
340 bool Platform::SetOwnership(const std::string& directory, uid_t user_id, 342 bool Platform::SetOwnership(const std::string& path, uid_t user_id,
341 gid_t group_id) { 343 gid_t group_id) {
342 if (chown(directory.c_str(), user_id, group_id)) { 344 if (chown(path.c_str(), user_id, group_id)) {
343 return false; 345 return false;
344 } 346 }
345 return true; 347 return true;
346 } 348 }
347 349
350 bool Platform::SetOwnershipRecursive(const std::string& directory,
351 uid_t user_id,
352 gid_t group_id) {
353 std::vector<std::string> to_recurse;
354 to_recurse.push_back(directory);
355 while (to_recurse.size()) {
356 std::string current_dir = to_recurse.back();
357 to_recurse.pop_back();
358
359 FilePath next_path;
360
361 // Push the subdirectories to the back of the vector
362 file_util::FileEnumerator dir_enumerator(
363 FilePath(current_dir),
364 false, // do not recurse into subdirectories.
365 file_util::FileEnumerator::DIRECTORIES);
366 while (!(next_path = dir_enumerator.Next()).empty()) {
367 to_recurse.push_back(next_path.value());
368 }
369
370 // Handle the files
371 file_util::FileEnumerator file_enumerator(FilePath(current_dir), false,
372 file_util::FileEnumerator::FILES);
373 while (!(next_path = file_enumerator.Next()).empty()) {
374 if (!SetOwnership(next_path.value(), user_id, group_id)) {
375 LOG(ERROR) << "Couldn't change owner (" << user_id << ":" << group_id
376 << ") of path: " << next_path.value().c_str();
377 return false;
378 }
379 }
380
381 // Set permissions on the directory itself
382 if (!SetOwnership(current_dir, user_id, group_id)) {
383 LOG(ERROR) << "Couldn't change owner (" << user_id << ":" << group_id
384 << ") of path: " << current_dir.c_str();
385 return false;
386 }
387 }
388 return true;
389 }
390
348 int Platform::SetMask(int new_mask) { 391 int Platform::SetMask(int new_mask) {
349 return umask(new_mask); 392 return umask(new_mask);
350 } 393 }
351 394
352 bool Platform::GetUserId(const std::string& user, uid_t* user_id, 395 bool Platform::GetUserId(const std::string& user, uid_t* user_id,
353 gid_t* group_id) { 396 gid_t* group_id) {
354 // Load the passwd entry 397 // Load the passwd entry
355 long user_name_length = sysconf(_SC_GETPW_R_SIZE_MAX); 398 long user_name_length = sysconf(_SC_GETPW_R_SIZE_MAX);
356 if(user_name_length == -1) { 399 if (user_name_length == -1) {
357 user_name_length = kDefaultPwnameLength; 400 user_name_length = kDefaultPwnameLength;
358 } 401 }
359 struct passwd user_info, *user_infop; 402 struct passwd user_info, *user_infop;
360 std::vector<char> user_name_buf(user_name_length); 403 std::vector<char> user_name_buf(user_name_length);
361 if (getpwnam_r(user.c_str(), &user_info, &user_name_buf[0], 404 if (getpwnam_r(user.c_str(), &user_info, &user_name_buf[0],
362 user_name_length, &user_infop)) { 405 user_name_length, &user_infop)) {
363 return false; 406 return false;
364 } 407 }
365 *user_id = user_info.pw_uid; 408 *user_id = user_info.pw_uid;
366 *group_id = user_info.pw_gid; 409 *group_id = user_info.pw_gid;
367 return true; 410 return true;
368 } 411 }
369 412
413 bool Platform::GetGroupId(const std::string& group, gid_t* group_id) {
414 // Load the group entry
415 long group_name_length = sysconf(_SC_GETGR_R_SIZE_MAX);
416 if (group_name_length == -1) {
417 group_name_length = kDefaultPwnameLength;
418 }
419 struct group group_info, *group_infop;
420 std::vector<char> group_name_buf(group_name_length);
421 if (getgrnam_r(group.c_str(), &group_info, &group_name_buf[0],
422 group_name_length, &group_infop)) {
423 return false;
424 }
425 *group_id = group_info.gr_gid;
426 return true;
427 }
428
370 int64 Platform::AmountOfFreeDiskSpace(const string& path) const { 429 int64 Platform::AmountOfFreeDiskSpace(const string& path) const {
371 struct statvfs stats; 430 struct statvfs stats;
372 if (statvfs(path.c_str(), &stats) != 0) { 431 if (statvfs(path.c_str(), &stats) != 0) {
373 return -1; 432 return -1;
374 } 433 }
375 return static_cast<int64>(stats.f_bavail) * stats.f_frsize; 434 return static_cast<int64>(stats.f_bavail) * stats.f_frsize;
376 } 435 }
377 436
378 void Platform::ClearUserKeyring() { 437 void Platform::ClearUserKeyring() {
379 keyctl(KEYCTL_CLEAR, KEY_SPEC_USER_KEYRING); 438 keyctl(KEYCTL_CLEAR, KEY_SPEC_USER_KEYRING);
380 } 439 }
381 440
441 bool Platform::Symlink(const std::string& from, const std::string& to) {
442 int rc = symlink(from.c_str(), to.c_str());
443 if (rc && rc != EEXIST) {
444 PLOG(ERROR) << "Error creating symbolic link from " << from << " to " << to
445 << ".";
446 return false;
447 }
448 return true;
449 }
450
451 bool Platform::Exec(const std::string& command,
452 const std::vector<std::string>& args,
453 uid_t uid,
454 gid_t gid) {
455 pid_t child_pid = -1;
456 child_pid = vfork();
457 if (child_pid == 0) {
458 if (gid != static_cast<gid_t>(-1)) {
459 if (setresgid(gid, gid, gid)) {
460 _exit(2);
461 }
462 }
463 if (uid != static_cast<uid_t>(-1)) {
464 if (setresuid(uid, uid, uid)) {
465 _exit(1);
466 }
467 }
468 const char** local_args = (const char**) calloc(args.size() + 1,
469 sizeof(char*));
470 int index = 0;
471 std::vector<std::string>::const_iterator it;
472 for (it = args.begin(); it != args.end(); ++it, ++index) {
473 local_args[index] = const_cast<char*>(it->c_str());
474 }
475 execve(command.c_str(), const_cast<char* const*>(local_args), NULL);
476 PLOG(ERROR) << "Couldn't start the command subprocess.";
477 _exit(3);
478 } else if (child_pid != -1) {
479 int status = 0;
480 do {
481 pid_t term_pid = waitpid(child_pid, &status, WUNTRACED | WCONTINUED);
482 if (term_pid == -1) {
483 return false;
484 }
485 } while (!WIFEXITED(status) && !WIFSIGNALED(status));
486 if (WIFEXITED(status) && WEXITSTATUS(status) == 0) {
487 return true;
488 }
489 PLOG(ERROR) << "Command subprocess exited with a non-zero status. ("
490 << "status = " << WEXITSTATUS(status) << " )";
491 }
492 else {
493 PLOG(ERROR) << "Couldn't spawn a subprocess for command execution.";
494 }
495 return false;
496 }
497
382 } // namespace cryptohome 498 } // namespace cryptohome
OLDNEW
« no previous file with comments | « platform.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698