/* * 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 #include #include #include #include #include #include #include namespace cuttlefish { namespace { gid_t GroupIdFromName(const std::string& group_name) { struct group grp{}; struct group* grp_p{}; std::vector 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 { // Caller may be checking with non-existent group name return -1; } } else { LOG(ERROR) << "Unable to get group id for group " << group_name << ": " << std::strerror(result); return -1; } } std::vector 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 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 InGroup(const std::string& group) { auto gid = GroupIdFromName(group); if (gid == static_cast(-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; } } // namespace cuttlefish