Line data Source code
1 : // Copyright (c) 2021 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 <vector>
22 :
23 :
24 : // C lib
25 : //
26 : #include <grp.h>
27 : #include <pwd.h>
28 :
29 :
30 :
31 : namespace snap
32 : {
33 :
34 :
35 : /** \brief Get the set of user group names.
36 : *
37 : * This function creates a set of group names a user is a part of.
38 : *
39 : * \tparam ContainterT The type of container used to output the tokens.
40 : * \param[in] user The name of the user.
41 : *
42 : * \return A set of strings with the group names.
43 : */
44 : template<class ContainerT>
45 3 : ContainerT user_group_names(std::string const & user)
46 : {
47 3 : struct passwd * pw(getpwnam(user.c_str()));
48 3 : if(pw == nullptr)
49 : {
50 1 : return ContainerT();
51 : }
52 :
53 2 : gid_t group(-1);
54 2 : int count(1);
55 2 : int r(getgrouplist(
56 : user.c_str()
57 : , pw->pw_gid
58 : , &group
59 : , &count));
60 :
61 2 : if(count <= 0)
62 : {
63 : return ContainerT(); // LCOV_EXCL_LINE
64 : }
65 :
66 4 : std::vector<gid_t> group_list(count);
67 2 : r = getgrouplist(
68 : user.c_str()
69 : , pw->pw_gid
70 : , group_list.data()
71 : , &count);
72 2 : if(r != count)
73 : {
74 : return ContainerT(); // LCOV_EXCL_LINE
75 : }
76 :
77 4 : ContainerT result;
78 44 : for(auto const gid : group_list)
79 : {
80 42 : struct group * grp(getgrgid(gid));
81 42 : if(grp == nullptr) // I don't think this can happen... although it could be deleted under our feet
82 : {
83 : // Note: only the root user could really do this
84 : // so that's why I had to exclude this line
85 : //
86 : result.insert(std::to_string(gid)); // LCOV_EXCL_LINE
87 : }
88 : else
89 : {
90 42 : result.insert(grp->gr_name);
91 : }
92 : }
93 :
94 2 : return result;
95 : }
96 :
97 :
98 :
99 : } // snap namespace
100 : // vim: ts=4 sw=4 et
|