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