<commit_before>////////////////////////////////////////////////////////////////////////////////
/// DISCLAIMER
///
/// Copyright 2016 ArangoDB GmbH, Cologne, Germany
///
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
///
///     http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// See the License for the specific language governing permissions and
/// limitations under the License.
///
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
///
/// @author Dr. <NAME>
////////////////////////////////////////////////////////////////////////////////

#include "PrivilegeFeature.h"

#ifdef ARANGODB_HAVE_GETGRGID
#include <grp.h>
#endif

#ifdef ARANGODB_HAVE_GETPWUID
#include <pwd.h>
#endif

#include "Basics/conversions.h"
#include "Logger/Logger.h"
#include "ProgramOptions/ProgramOptions.h"
#include "ProgramOptions/Section.h"

using namespace arangodb::basics;
using namespace arangodb::options;

namespace arangodb {

PrivilegeFeature::PrivilegeFeature(
    application_features::ApplicationServer& server
)
    : ApplicationFeature(server, "Privilege"),
      _numericUid(0), _numericGid(0) {
  setOptional(true);
  startsAfter("GreetingsPhase");
}

void PrivilegeFeature::collectOptions(std::shared_ptr<ProgramOptions> options) {
  options->addSection("server", "Server features");

#ifdef ARANGODB_HAVE_SETUID
  options->addHiddenOption("--uid",
                           "switch to user-id after reading config files",
                           new StringParameter(&_uid));

  options->addHiddenOption("--server.uid",
                           "switch to user-id after reading config files",
                           new StringParameter(&_uid));
#endif

#ifdef ARANGODB_HAVE_SETGID
  options->addHiddenOption("--gid",
                           "switch to group-id after reading config files",
                           new StringParameter(&_gid));

  options->addHiddenOption("--server.gid",
                           "switch to group-id after reading config files",
                           new StringParameter(&_gid));
#endif
}

void PrivilegeFeature::prepare() {
  extractPrivileges();
}

void PrivilegeFeature::extractPrivileges() {
#ifdef ARANGODB_HAVE_SETGID
  if (_gid.empty()) {
    _numericGid = getgid();
  } else {
    int gidNumber = TRI_Int32String(_gid.c_str());

    if (TRI_errno() == TRI_ERROR_NO_ERROR && gidNumber >= 0) {
#ifdef ARANGODB_HAVE_GETGRGID
      group* g = getgrgid(gidNumber);

      if (g == nullptr) {
        LOG_TOPIC(FATAL, arangodb::Logger::FIXME) << "unknown numeric gid '" << _gid << "'";
        FATAL_ERROR_EXIT();
      }
#endif
    } else {
#ifdef ARANGODB_HAVE_GETGRNAM
      std::string name = _gid;
      group* g = getgrnam(name.c_str());

      if (g != nullptr) {
        gidNumber = g->gr_gid;
      } else {
        LOG_TOPIC(FATAL, arangodb::Logger::FIXME) << "cannot convert groupname '" << _gid
                   << "' to numeric gid";
        FATAL_ERROR_EXIT();
      }
#else
      LOG_TOPIC(FATAL, arangodb::Logger::FIXME) << "cannot convert groupname '" << _gid << "' to numeric gid";
      FATAL_ERROR_EXIT();
#endif
    }

    _numericGid = gidNumber;
  }
#endif

#ifdef ARANGODB_HAVE_SETUID
  if (_uid.empty()) {
    _numericUid = getuid();
  } else {
    int uidNumber = TRI_Int32String(_uid.c_str());<commit_msg>add error message<commit_after>////////////////////////////////////////////////////////////////////////////////
/// DISCLAIMER
///
/// Copyright 2016 ArangoDB GmbH, Cologne, Germany
///
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
///
///     http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// See the License for the specific language governing permissions and
/// limitations under the License.
///
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
///
/// @author Dr. <NAME>
////////////////////////////////////////////////////////////////////////////////

#include "PrivilegeFeature.h"

#ifdef ARANGODB_HAVE_GETGRGID
#include <grp.h>
#endif

#ifdef ARANGODB_HAVE_GETPWUID
#include <pwd.h>
#endif

#include "Basics/conversions.h"
#include "Logger/Logger.h"
#include "ProgramOptions/ProgramOptions.h"
#include "ProgramOptions/Section.h"

using namespace arangodb::basics;
using namespace arangodb::options;

namespace arangodb {

PrivilegeFeature::PrivilegeFeature(
    application_features::ApplicationServer& server
)
    : ApplicationFeature(server, "Privilege"),
      _numericUid(0), _numericGid(0) {
  setOptional(true);
  startsAfter("GreetingsPhase");
}

void PrivilegeFeature::collectOptions(std::shared_ptr<ProgramOptions> options) {
  options->addSection("server", "Server features");

#ifdef ARANGODB_HAVE_SETUID
  options->addHiddenOption("--uid",
                           "switch to user-id after reading config files",
                           new StringParameter(&_uid));

  options->addHiddenOption("--server.uid",
                           "switch to user-id after reading config files",
                           new StringParameter(&_uid));
#endif

#ifdef ARANGODB_HAVE_SETGID
  options->addHiddenOption("--gid",
                           "switch to group-id after reading config files",
                           new StringParameter(&_gid));

  options->addHiddenOption("--server.gid",
                           "switch to group-id after reading config files",
                           new StringParameter(&_gid));
#endif
}

void PrivilegeFeature::prepare() {
  extractPrivileges();
}

void PrivilegeFeature::extractPrivileges() {
#ifdef ARANGODB_HAVE_SETGID
  if (_gid.empty()) {
    _numericGid = getgid();
  } else {
    int gidNumber = TRI_Int32String(_gid.c_str());

    if (TRI_errno() == TRI_ERROR_NO_ERROR && gidNumber >= 0) {
#ifdef ARANGODB_HAVE_GETGRGID
      group* g = getgrgid(gidNumber);

      if (g == nullptr) {
        LOG_TOPIC(FATAL, arangodb::Logger::FIXME) << "unknown numeric gid '" << _gid << "'";
        FATAL_ERROR_EXIT();
      }
#endif
    } else {
#ifdef ARANGODB_HAVE_GETGRNAM
      std::string name = _gid;
      group* g = getgrnam(name.c_str());

      if (g != nullptr) {
        gidNumber = g->gr_gid;
      } else {
        TRI_set_errno(TRI_ERROR_SYS_ERROR);
        LOG_TOPIC(FATAL, arangodb::Logger::FIXME) << "cannot convert groupname '" << _gid
                   << "' to numeric gid: " << TRI_last_error();
        FATAL_ERROR_EXIT();
      }
#else
      LOG_TOPIC(FATAL, arangodb::Logger::FIXME) << "cannot convert groupname '" << _gid << "' to numeric gid";
      FATAL_ERROR_EXIT();
#endif
    }

    _numericGid = gidNumber;
  }
#endif

#ifdef ARANGODB_HAVE_SETUID
  if (_uid.empty()) {
    _numericUid = getuid();
  } else {
    int uidNumber = TRI_Int32String(_uid.c_str());
{'fraction_non_alphanumeric': 0.16363636363636364, 'fraction_numerical': 0.004070556309362279, 'mean_word_length': 2.511672224868985, 'pattern_counts': {'":': 0, '<': 49, '<?xml version=': 0, '>': 25, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6429486', 'n_tokens_mistral': 2294, 'n_tokens_neox': 2166, 'n_words': 549}