blob: d0dc7598b03260a4960b1219327b94eb9b5a237d [file] [log] [blame]
// Copyright (c) 2009-2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef LOGIN_MANAGER_CHILD_JOB_H_
#define LOGIN_MANAGER_CHILD_JOB_H_
#include <gtest/gtest.h>
#include <time.h>
#include <unistd.h>
#include <base/basictypes.h>
#include <base/scoped_ptr.h>
#include "login_manager/file_checker.h"
class CommandLine;
namespace login_manager {
// SessionManager takes a ChildJob object, forks and then calls the ChildJob's
// Run() method. I've created this interface so that I can create mocks for
// unittesting SessionManager.
class ChildJob {
public:
ChildJob() {}
virtual ~ChildJob() {}
virtual bool ShouldRun() = 0;
// ShouldStop() is different from !ShouldRun(). If ShouldStop() returns
// true, this means that the parent should tear everything down.
virtual bool ShouldStop() = 0;
virtual void RecordTime() = 0;
// Wraps up all the logic of what the job is meant to do. Should NOT return.
virtual void Run() = 0;
// If the ChildJob contains a toggleable piece of state, toggle it.
virtual void Toggle() = 0;
virtual bool desired_uid_is_set() const {
return false;
}
virtual uid_t desired_uid() const {
return -1;
}
};
class SetUidExecJob : public ChildJob {
public:
SetUidExecJob(const CommandLine* command_line,
FileChecker* checker, // Takes ownership.
const bool add_flag);
virtual ~SetUidExecJob();
// The flag to pass to chrome to tell it to behave as the login manager.
static const char kLoginManagerFlag[];
// Potential exit codes for Run().
static const int kCantSetuid;
static const int kCantSetgid;
static const int kCantSetgroups;
static const int kCantExec;
static const int kRestartWindow;
bool ShouldRun();
bool ShouldStop();
void RecordTime();
void Run();
void Toggle() { include_login_flag_ = !include_login_flag_; }
bool desired_uid_is_set() const {
return desired_uid_is_set_;
}
uid_t desired_uid() const {
return desired_uid_is_set() ? desired_uid_ : -1;
}
void set_desired_uid(uid_t uid) {
desired_uid_ = uid;
desired_uid_is_set_ = true;
}
protected:
std::vector<std::string> ExtractArgvForTest();
// Pulls all loose args from |command_line|, converts them to ASCII, and
// puts them into an array that's ready to be used by exec().
// Might be able to remove this once Chromium's CommandLine class deals with
// wstrings is a saner way.
void PopulateArgv(const CommandLine* command_line);
void UseLoginManagerFlagIfNeeded();
// If the caller has provided a UID with set_desired_uid(), this method will:
// 1) try to setgid to that uid
// 2) try to setgroups to that uid
// 3) try to setuid to that uid
//
// Returns 0 on success, the appropriate exit code (defined above) if a
// call fails.
int SetIDs();
private:
scoped_ptr<FileChecker> checker_;
char const* *argv_;
uint32 num_args_passed_in_;
uid_t desired_uid_;
bool include_login_flag_; // This class' piece of toggleable state.
bool desired_uid_is_set_;
time_t last_start_;
FRIEND_TEST(SetUidExecJobTest, FlagAppendTest);
FRIEND_TEST(SetUidExecJobTest, NoFlagAppendTest);
FRIEND_TEST(SetUidExecJobTest, PopulateArgvTest);
DISALLOW_COPY_AND_ASSIGN(SetUidExecJob);
};
} // namespace login_manager
#endif // LOGIN_MANAGER_CHILD_JOB_H_