/*
 * Copyright (C) 2018 The Android Open Source Project
 *
 * 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.
 */

#include "common/libs/utils/users.h"

#include <cerrno>
#include <cstring>
#include <sys/types.h>
#include <unistd.h>
#include <grp.h>

#include <algorithm>
#include <vector>

#include <android-base/logging.h>

namespace {
gid_t GroupIdFromName(const std::string& group_name) {
  struct group grp{};
  struct group* grp_p{};
  std::vector<char> buffer(100);
  int result = 0;
  while(true) {
    result = getgrnam_r(group_name.c_str(), &grp, buffer.data(), buffer.size(),
                        &grp_p);
    if (result != ERANGE) {
      break;
    }
    buffer.resize(2*buffer.size());
  }
  if (result == 0) {
    if (grp_p != nullptr) {
      return grp.gr_gid;
    } else {
      LOG(ERROR) << "Group " << group_name << " does not exist";
      return -1;
    }
  } else {
    LOG(ERROR) << "Unable to get group id for group " << group_name << ": "
               << std::strerror(result);
    return -1;
  }
}

std::vector<gid_t> GetSuplementaryGroups() {
  int num_groups = getgroups(0, nullptr);
  if (num_groups < 0) {
    LOG(ERROR) << "Unable to get number of suplementary groups: "
               << std::strerror(errno);
    return {};
  }
  std::vector<gid_t> groups(num_groups + 1);
  int retval = getgroups(groups.size(), groups.data());
  if (retval < 0) {
    LOG(ERROR) << "Error obtaining list of suplementary groups (list size: "
               << groups.size() << "): " << std::strerror(errno);
    return {};
  }
  return groups;
}
}  // namespace

bool cvd::InGroup(const std::string& group) {
  auto gid = GroupIdFromName(group);
  if (gid == static_cast<gid_t>(-1)) {
    return false;
  }

  if (gid == getegid()) {
    return true;
  }

  auto groups = GetSuplementaryGroups();

  if (std::find(groups.cbegin(), groups.cend(), gid) != groups.cend()) {
    return true;
  }
  return false;
}