/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
 * Copyright (c) 2014-2018,  Regents of the University of California,
 *                           Arizona Board of Regents,
 *                           Colorado State University,
 *                           University Pierre & Marie Curie, Sorbonne University,
 *                           Washington University in St. Louis,
 *                           Beijing Institute of Technology,
 *                           The University of Memphis.
 *
 * This file is part of NFD (Named Data Networking Forwarding Daemon).
 * See AUTHORS.md for complete list of NFD authors and contributors.
 *
 * NFD 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 3 of the License, or (at your option) any later version.
 *
 * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
 * PURPOSE.  See the GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along with
 * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "privilege-helper.hpp"
#include "core/logger.hpp"

#include <pwd.h>
#include <grp.h>

namespace nfd {

NFD_LOG_INIT(PrivilegeHelper);

#ifdef HAVE_PRIVILEGE_DROP_AND_ELEVATE
uid_t PrivilegeHelper::s_normalUid = ::geteuid();
gid_t PrivilegeHelper::s_normalGid = ::getegid();

uid_t PrivilegeHelper::s_privilegedUid = ::geteuid();
gid_t PrivilegeHelper::s_privilegedGid = ::getegid();
#endif // HAVE_PRIVILEGE_DROP_AND_ELEVATE

void
PrivilegeHelper::initialize(const std::string& userName, const std::string& groupName)
{
#ifdef HAVE_PRIVILEGE_DROP_AND_ELEVATE
  static const size_t MAX_GROUP_BUFFER_SIZE = 16384; // 16 KiB
  static const size_t MAX_PASSWD_BUFFER_SIZE = 16384;

  static const size_t FALLBACK_GROUP_BUFFER_SIZE = 1024;
  static const size_t FALLBACK_PASSWD_BUFFER_SIZE = 1024;

  NFD_LOG_TRACE("initializing with user \"" << userName << "\""
                << " group \"" << groupName << "\"");

  // workflow from man getpwnam_r

  if (!groupName.empty()) {
    static long groupSize = ::sysconf(_SC_GETGR_R_SIZE_MAX);

    if (groupSize == -1)
      groupSize = FALLBACK_GROUP_BUFFER_SIZE;

    std::vector<char> groupBuffer(static_cast<size_t>(groupSize));
    struct group group;
    struct group* groupResult = nullptr;

    int errorCode = getgrnam_r(groupName.data(), &group,
                               groupBuffer.data(), groupBuffer.size(), &groupResult);

    while (errorCode == ERANGE) {
      if (groupBuffer.size() * 2 > MAX_GROUP_BUFFER_SIZE)
        throw Error("Cannot allocate large enough buffer for struct group");

      groupBuffer.resize(groupBuffer.size() * 2);
      errorCode = getgrnam_r(groupName.data(), &group,
                             groupBuffer.data(), groupBuffer.size(), &groupResult);
    }

    if (errorCode != 0 || !groupResult)
      throw Error("Failed to get gid for \"" + groupName + "\"");

    s_normalGid = group.gr_gid;
  }

  if (!userName.empty()) {
    static long passwdSize = ::sysconf(_SC_GETPW_R_SIZE_MAX);

    if (passwdSize == -1)
      passwdSize = FALLBACK_PASSWD_BUFFER_SIZE;

    std::vector<char> passwdBuffer(static_cast<size_t>(passwdSize));
    struct passwd passwd;
    struct passwd* passwdResult = nullptr;

    int errorCode = getpwnam_r(userName.data(), &passwd,
                               passwdBuffer.data(), passwdBuffer.size(), &passwdResult);

    while (errorCode == ERANGE) {
      if (passwdBuffer.size() * 2 > MAX_PASSWD_BUFFER_SIZE)
        throw Error("Cannot allocate large enough buffer for struct passwd");

      passwdBuffer.resize(passwdBuffer.size() * 2);
      errorCode = getpwnam_r(userName.data(), &passwd,
                             passwdBuffer.data(), passwdBuffer.size(), &passwdResult);
    }

    if (errorCode != 0 || !passwdResult)
      throw Error("Failed to get uid for \"" + userName + "\"");

    s_normalUid = passwd.pw_uid;
  }
#else
  if (!userName.empty() || !groupName.empty()) {
    throw Error("Dropping and raising privileges is not supported on this platform");
  }
#endif // HAVE_PRIVILEGE_DROP_AND_ELEVATE
}

void
PrivilegeHelper::drop()
{
  if (::geteuid() == s_normalUid && ::getegid() == s_normalGid)
    return;

#ifdef HAVE_PRIVILEGE_DROP_AND_ELEVATE
  NFD_LOG_TRACE("dropping to effective gid=" << s_normalGid);
  if (::setegid(s_normalGid) != 0)
    throw Error("Failed to drop to effective gid=" + to_string(s_normalGid));

  NFD_LOG_TRACE("dropping to effective uid=" << s_normalUid);
  if (::seteuid(s_normalUid) != 0)
    throw Error("Failed to drop to effective uid=" + to_string(s_normalUid));

  NFD_LOG_INFO("dropped to effective uid=" << ::geteuid() << " gid=" << ::getegid());
#else
  NFD_LOG_WARN("Dropping privileges is not supported on this platform");
#endif // HAVE_PRIVILEGE_DROP_AND_ELEVATE
}

void
PrivilegeHelper::raise()
{
  if (::geteuid() == s_privilegedUid && ::getegid() == s_privilegedGid)
    return;

#ifdef HAVE_PRIVILEGE_DROP_AND_ELEVATE
  NFD_LOG_TRACE("elevating to effective uid=" << s_privilegedUid);
  if (::seteuid(s_privilegedUid) != 0)
    throw Error("Failed to elevate to effective uid=" + to_string(s_privilegedUid));

  NFD_LOG_TRACE("elevating to effective gid=" << s_privilegedGid);
  if (::setegid(s_privilegedGid) != 0)
    throw Error("Failed to elevate to effective gid=" + to_string(s_privilegedGid));

  NFD_LOG_INFO("elevated to effective uid=" << ::geteuid() << " gid=" << ::getegid());
#else
  NFD_LOG_WARN("Elevating privileges is not supported on this platform");
#endif // HAVE_PRIVILEGE_DROP_AND_ELEVATE
}

} // namespace nfd
