/*
|
|
* This file is part of schlimm
|
|
* Copyright (C) 2019-2021 Moritz Strohm <ncc1988@posteo.de>
|
|
* and others (see the AUTHORS file).
|
|
*
|
|
* SLiM - Simple Login Manager
|
|
* Copyright (C) 1997, 1998 Per Liden
|
|
* Copyright (C) 2004-06 Simone Rota <sip@varlock.com>
|
|
* Copyright (C) 2004-06 Johannes Winkelmann <jw@tks6.net>
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*/
|
|
|
|
|
|
#include "SwitchUser.h"
|
|
|
|
|
|
using namespace Schlimm;
|
|
|
|
|
|
SwitchUser::SwitchUser(
|
|
struct passwd *pw,
|
|
std::shared_ptr<Config> c,
|
|
const std::string& display,
|
|
std::vector<std::string>& env
|
|
)
|
|
: cfg(c),
|
|
Pw(pw),
|
|
displayName(display),
|
|
env(env)
|
|
{
|
|
}
|
|
|
|
|
|
SwitchUser::~SwitchUser()
|
|
{
|
|
/* Never called */
|
|
//Then why is it defined?
|
|
}
|
|
|
|
|
|
void SwitchUser::Login(const char* cmd, const char* mcookie)
|
|
{
|
|
this->SetUserId();
|
|
this->SetClientAuth(mcookie);
|
|
this->Execute(cmd);
|
|
}
|
|
|
|
|
|
void SwitchUser::SetUserId()
|
|
{
|
|
if ((Pw == 0) ||
|
|
(initgroups(Pw->pw_name, Pw->pw_gid) != 0) ||
|
|
(setgid(Pw->pw_gid) != 0) ||
|
|
(setuid(Pw->pw_uid) != 0) ) {
|
|
Log::log("Could not switch user id!");
|
|
exit(ERR_EXIT);
|
|
}
|
|
}
|
|
|
|
|
|
void SwitchUser::Execute(const char* cmd)
|
|
{
|
|
char** c_env = new char*[this->env.size() + 1];
|
|
if (c_env == nullptr) {
|
|
Log::log("Could not allocate memory for environment variables!");
|
|
}
|
|
size_t i = 0;
|
|
for (auto envvar: this->env) {
|
|
c_env[i] = new char[envvar.size() + 1];
|
|
if (c_env[i] == nullptr) {
|
|
//TODO: throw an exception
|
|
return;
|
|
}
|
|
envvar.copy(c_env[i], envvar.length(), 0);
|
|
i++;
|
|
}
|
|
c_env[i] = nullptr;
|
|
chdir(Pw->pw_dir);
|
|
int result = execle(Pw->pw_shell, Pw->pw_shell, "-c", cmd, NULL, c_env);
|
|
if (result == -1) {
|
|
Log::log("Could not execute login command!");
|
|
}
|
|
}
|
|
|
|
|
|
void SwitchUser::SetClientAuth(const char* mcookie)
|
|
{
|
|
std::string home = std::string(Pw->pw_dir);
|
|
std::string authfile = home + "/.Xauthority";
|
|
remove(authfile.c_str());
|
|
::Util::add_mcookie(mcookie, ":0", cfg->getOption("xauth_path"), authfile);
|
|
}
|