Line data Source code
1 : // Copyright (c) 2021-2023 Made to Order Software Corp. All Rights Reserved 2 : // 3 : // https://snapwebsites.org/project/snapdev 4 : // contact@m2osw.com 5 : // 6 : // This program is free software: you can redistribute it and/or modify 7 : // it under the terms of the GNU General Public License as published by 8 : // the Free Software Foundation, either version 3 of the License, or 9 : // (at your option) any later version. 10 : // 11 : // This program is distributed in the hope that it will be useful, 12 : // but WITHOUT ANY WARRANTY; without even the implied warranty of 13 : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 : // GNU General Public License for more details. 15 : // 16 : // You should have received a copy of the GNU General Public License 17 : // along with this program. If not, see <https://www.gnu.org/licenses/>. 18 : #pragma once 19 : 20 : /** \file 21 : * \brief Read the list of groups a user is a part of. 22 : * 23 : * This function reads the list of groups a Unix user has been assigned to. 24 : * The results are saved in a standard container. 25 : */ 26 : 27 : // C++ 28 : // 29 : #include <set> 30 : #include <string> 31 : #include <vector> 32 : 33 : 34 : // C 35 : // 36 : #include <grp.h> 37 : #include <pwd.h> 38 : 39 : 40 : 41 : namespace snapdev 42 : { 43 : 44 : 45 : /** \brief Get the set of user group names. 46 : * 47 : * This function creates a set of group names a user is a part of. 48 : * 49 : * \tparam ContainterT The type of container used to output the tokens. 50 : * \param[in] user The name of the user. 51 : * 52 : * \return A set of strings with the group names. 53 : */ 54 : template<class ContainerT> 55 3 : ContainerT user_group_names(std::string const & user) 56 : { 57 3 : struct passwd * pw(getpwnam(user.c_str())); 58 3 : if(pw == nullptr) 59 : { 60 1 : return ContainerT(); 61 : } 62 : 63 2 : gid_t group(-1); 64 2 : int count(1); 65 2 : int r(getgrouplist( 66 : user.c_str() 67 : , pw->pw_gid 68 : , &group 69 : , &count)); 70 : 71 2 : if(count <= 0) 72 : { 73 : return ContainerT(); // LCOV_EXCL_LINE 74 : } 75 : 76 4 : std::vector<gid_t> group_list(count); 77 2 : r = getgrouplist( 78 : user.c_str() 79 : , pw->pw_gid 80 : , group_list.data() 81 : , &count); 82 2 : if(r != count) 83 : { 84 : return ContainerT(); // LCOV_EXCL_LINE 85 : } 86 : 87 2 : ContainerT result; 88 44 : for(auto const gid : group_list) 89 : { 90 42 : struct group * grp(getgrgid(gid)); 91 42 : if(grp == nullptr) // I don't think this can happen... although it could be deleted under our feet 92 : { 93 : // Note: only the root user could really do this 94 : // so that's why I had to exclude this line 95 : // 96 : result.insert(std::to_string(gid)); // LCOV_EXCL_LINE 97 : } 98 : else 99 : { 100 42 : result.insert(grp->gr_name); 101 : } 102 : } 103 : 104 2 : return result; 105 2 : } 106 : 107 : 108 : 109 : } // namespace snapdev 110 : // vim: ts=4 sw=4 et