Map Windows system account to Linux root user

This commit is contained in:
FAREAST\chezhang 2018-02-02 00:57:33 +08:00
Родитель d90f79e8da
Коммит 77567a7b0d
5 изменённых файлов: 84 добавлений и 54 удалений

Просмотреть файл

@ -582,6 +582,11 @@ namespace hpc
"Fixed a bug that root user may fail in mutual trust in mpi docker task",
}
},
{ "2.3.3.0",
{
"Modified user mapping logic",
}
},
};
return versionHistory;

Просмотреть файл

@ -2,6 +2,7 @@
#include <memory>
#include <boost/uuid/string_generator.hpp>
#include <boost/uuid/uuid_io.hpp>
#include <boost/algorithm/string.hpp>
#include "RemoteExecutor.h"
#include "HttpReporter.h"
@ -51,32 +52,55 @@ pplx::task<json::value> RemoteExecutor::StartJobAndTask(StartJobAndTaskArgs&& ar
const auto& envi = args.StartInfo.EnvironmentVariables;
auto isAdminIt = envi.find("CCP_ISADMIN");
bool isAdmin = isAdminIt != envi.end() && isAdminIt->second == "1";
auto mapAdminUserIt = envi.find("CCP_MAP_ADMIN_USER");
bool mapAdminUser = mapAdminUserIt != envi.end() && mapAdminUserIt->second == "1";
const std::string WindowsSystemUser = "NT AUTHORITY\\SYSTEM";
bool mapAdminToRoot = isAdmin && !mapAdminUser;
bool mapAdminToUser = isAdmin && mapAdminUser;
bool isWindowsSystemAccount = boost::iequals(args.UserName, WindowsSystemUser);
// If is admin, we won't create the user, default to root.
// If username is empty, this is the old image, we use root.
if ((mapAdminUser || !isAdmin) && !args.UserName.empty())
std::string userName;
bool existed;
// Use root user in 3 scenarios:
// 1. This is old image, username is empty, we use root.
// 2. User is Windows or HPC Administrator and CCP_MAP_ADMIN_USER is not set
// 3. User is Windows local system account, which is mapped to Linux root user.
if (args.UserName.empty() || mapAdminToRoot || isWindowsSystemAccount)
{
userName = "root";
existed = true;
}
else
{
auto preserveDomainIt = envi.find("CCP_PRESERVE_DOMAIN");
bool preserveDomain = preserveDomainIt != envi.end() && preserveDomainIt->second == "1";
std::string userName = preserveDomain ? args.UserName : String::GetUserName(args.UserName);
userName = preserveDomain ? args.UserName : String::GetUserName(args.UserName);
if (userName == "root") { userName = "hpc_faked_root"; }
int ret = System::CreateUser(userName, args.Password);
bool existed = ret == 9;
int ret = System::CreateUser(userName, args.Password, isAdmin);
existed = ret == 9;
if (ret != 0 && ret != 9)
{
throw std::runtime_error(
String::Join(" ", "Create user", userName, "failed with error code", ret));
}
Logger::Debug(args.JobId, args.TaskId, this->UnknowId, "Create user {0} return code: {1}.", userName, ret);
}
bool privateKeyAdded = false;
bool publicKeyAdded = false;
bool authKeyAdded = false;
// Set SSH keys in 3 scenarios:
// 1. User is not a Windows or HPC Administrator.
// 2. User is Windows or HPC Administrator and it is mapped to non-root user in Linux.
// 3. User is Windows local system account, which is mapped to Linux root user.
if (!isAdmin || mapAdminToUser || isWindowsSystemAccount)
{
std::string privateKeyFile;
bool privateKeyAdded = 0 == System::AddSshKey(userName, args.PrivateKey, "id_rsa", "600", privateKeyFile);
privateKeyAdded = 0 == System::AddSshKey(userName, args.PrivateKey, "id_rsa", "600", privateKeyFile);
if (privateKeyAdded && args.PublicKey.empty())
{
@ -88,43 +112,34 @@ pplx::task<json::value> RemoteExecutor::StartJobAndTask(StartJobAndTaskArgs&& ar
}
std::string publicKeyFile;
bool publicKeyAdded = privateKeyAdded && (0 == System::AddSshKey(userName, args.PublicKey, "id_rsa.pub", "644", publicKeyFile));
publicKeyAdded = privateKeyAdded && (0 == System::AddSshKey(userName, args.PublicKey, "id_rsa.pub", "644", publicKeyFile));
std::string userAuthKeyFile;
bool authKeyAdded = privateKeyAdded && publicKeyAdded && (0 == System::AddAuthorizedKey(userName, args.PublicKey, "600", userAuthKeyFile));
authKeyAdded = privateKeyAdded && publicKeyAdded && (0 == System::AddAuthorizedKey(userName, args.PublicKey, "600", userAuthKeyFile));
Logger::Debug(args.JobId, args.TaskId, this->UnknowId,
"Create user {0} result: ret {1}, private {2}, public {3}, auth {4}",
userName, ret, privateKeyAdded, publicKeyAdded, authKeyAdded);
"Add ssh key for user {0} result: private {1}, public {2}, auth {3}",
userName, privateKeyAdded, publicKeyAdded, authKeyAdded);
}
if (this->jobUsers.find(args.JobId) == this->jobUsers.end())
{
Logger::Debug(args.JobId, args.TaskId, this->UnknowId,
"Create user: jobUsers entry added.");
if (this->jobUsers.find(args.JobId) == this->jobUsers.end())
{
Logger::Debug(args.JobId, args.TaskId, this->UnknowId,
"Create user: jobUsers entry added.");
this->jobUsers[args.JobId] =
std::tuple<std::string, bool, bool, bool, bool, std::string>(userName, existed, privateKeyAdded, publicKeyAdded, authKeyAdded, args.PublicKey);
}
this->jobUsers[args.JobId] =
std::tuple<std::string, bool, bool, bool, bool, std::string>(userName, existed, privateKeyAdded, publicKeyAdded, authKeyAdded, args.PublicKey);
}
auto it = this->userJobs.find(userName);
auto it = this->userJobs.find(userName);
if (it != this->userJobs.end())
{
it->second.insert(args.JobId);
}
else
{
this->userJobs[userName] = { args.JobId };
}
if (it != this->userJobs.end())
{
it->second.insert(args.JobId);
}
else
{
// run as root
Logger::Debug(args.JobId, args.TaskId, this->UnknowId,
"Run the job as root.");
this->jobUsers[args.JobId] =
std::tuple<std::string, bool, bool, bool, bool, std::string>("root", true, false, false, false, "");
this->userJobs[userName] = { args.JobId };
}
}

Просмотреть файл

@ -127,7 +127,7 @@ a8lxTKnZCsRXU1HexqZs+DSc+30tz50bNqLdido/l5B4EJnQP03ciO0=\
System::DeleteUser(userName);
std::string publicKey = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDEkoEAGGc6wT16d4Ye+yN2hcqigdTGlMcjUlW6cAmRWYXLwkKoW3WlX3xAK0oQdMLqRDu2PVRPY3qfHURj0EEellpydeaSekp1fg27Rw2VKmEumu6Wxwo9HddXORPAQXTQ4yI0lWSerypckXVPeVjHetbkSci2foLedCbeBA9c/RyRgIUl227/pJKDNX2Rpqly0sY82nVWN/0p4NAyslexA0fGdBx+IgKnbU2JQKJeiwOomtEB/N492XRfCw2eCi7Ly3R8+U1KeBm+zH6Q8aH8ApqQohhLRw71bcWZ1g1bxd6HORxXOu0mFTzHbWFcZ9ILtXRl4Pt0x5Mve1AJXEKb hpclabsa@longhaulLN5-033\n";
int ret = System::CreateUser(userName, password);
int ret = System::CreateUser(userName, password, false);
if (ret != 0) return false;
std::string keyFileName;
@ -220,7 +220,7 @@ a8lxTKnZCsRXU1HexqZs+DSc+30tz50bNqLdido/l5B4EJnQP03ciO0=\
std::string publicKey = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDEkoEAGGc6wT16d4Ye+yN2hcqigdTGlMcjUlW6cAmRWYXLwkKoW3WlX3xAK0oQdMLqRDu2PVRPY3qfHURj0EEellpydeaSekp1fg27Rw2VKmEumu6Wxwo9HddXORPAQXTQ4yI0lWSerypckXVPeVjHetbkSci2foLedCbeBA9c/RyRgIUl227/pJKDNX2Rpqly0sY82nVWN/0p4NAyslexA0fGdBx+IgKnbU2JQKJeiwOomtEB/N492XRfCw2eCi7Ly3R8+U1KeBm+zH6Q8aH8ApqQohhLRw71bcWZ1g1bxd6HORxXOu0mFTzHbWFcZ9ILtXRl4Pt0x5Mve1AJXEKb hpclabsa@longhaulLN5-033\n";
System::DeleteUser(userName);
int ret = System::CreateUser(userName, password);
int ret = System::CreateUser(userName, password, false);
if (ret != 0) return false;
std::string keyFileName;
@ -313,7 +313,7 @@ a8lxTKnZCsRXU1HexqZs+DSc+30tz50bNqLdido/l5B4EJnQP03ciO0=\
std::string publicKey = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDEkoEAGGc6wT16d4Ye+yN2hcqigdTGlMcjUlW6cAmRWYXLwkKoW3WlX3xAK0oQdMLqRDu2PVRPY3qfHURj0EEellpydeaSekp1fg27Rw2VKmEumu6Wxwo9HddXORPAQXTQ4yI0lWSerypckXVPeVjHetbkSci2foLedCbeBA9c/RyRgIUl227/pJKDNX2Rpqly0sY82nVWN/0p4NAyslexA0fGdBx+IgKnbU2JQKJeiwOomtEB/N492XRfCw2eCi7Ly3R8+U1KeBm+zH6Q8aH8ApqQohhLRw71bcWZ1g1bxd6HORxXOu0mFTzHbWFcZ9ILtXRl4Pt0x5Mve1AJXEKb hpclabsa@longhaulLN5-033\n";
System::DeleteUser(userName);
int ret = System::CreateUser(userName, password);
int ret = System::CreateUser(userName, password, false);
if (ret != 0) return false;
std::string keyFileName;

Просмотреть файл

@ -414,22 +414,13 @@ int System::QueryGpuInfo(System::GpuInfoList& gpuInfo)
int System::CreateUser(
const std::string& userName,
const std::string& password)
const std::string& password,
bool isAdmin)
{
std::string output;
int ret = System::ExecuteCommandOut(output, "useradd", userName, "-m", "-s /bin/bash");
if (ret != 0)
{
Logger::Warn("useradd {0} -m error code {1}", userName, ret);
if (ret != 9) // exist
{
return ret;
}
}
if (ret != 9)
if (ret == 0)
{
std::string input = String::Join("", password, "\n", password, "\n");
ret = System::ExecuteCommandIn(input, "passwd", userName);
@ -438,6 +429,24 @@ int System::CreateUser(
Logger::Error("passwd {0} error code {1}", userName, ret);
return ret;
}
if (isAdmin)
{
ret = System::ExecuteCommandOut(output, "usermod", "-aG sudo", userName); // add user to group sudo on Ubuntu
if (ret == 6) // group sudo does not exist
{
ret = System::ExecuteCommandOut(output, "usermod", "-aG wheel", userName); // add user to group wheel on CentOS/Redhat/Suse
}
if (ret != 0)
{
Logger::Error("Add user {0} to group sudo/wheel failed. Command usermod, error code {1}", userName, ret);
}
}
}
else
{
Logger::Warn("useradd {0} -m error code {1}", userName, ret);
}
return ret;

Просмотреть файл

@ -100,7 +100,8 @@ namespace hpc
static int CreateUser(
const std::string& userName,
const std::string& password);
const std::string& password,
bool isAdmin);
static int AddSshKey(
const std::string& userName,