Line data Source code
1 : // Copyright (c) 2016-2022 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 2 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 along
17 : // with this program; if not, write to the Free Software Foundation, Inc.,
18 : // 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 : #pragma once
20 :
21 : // C++ lib
22 : //
23 : #include <string>
24 : #include <stdexcept>
25 :
26 :
27 : // C lib
28 : //
29 : #include <grp.h>
30 : #include <pwd.h>
31 : #include <unistd.h>
32 :
33 :
34 :
35 : namespace snapdev
36 : {
37 :
38 :
39 : /** \brief Set the owner and group of a file or directory.
40 : *
41 : * This function determines the user identifier and group identifier
42 : * from the specified names and use them to call chown().
43 : *
44 : * The function can fail if an identifier for the user or group names
45 : * cannot be determined.
46 : *
47 : * The function may fail if the path is invalid or permissions do not
48 : * allow for ownership modifications.
49 : *
50 : * \param[in] path The path to the file or directory to change.
51 : * \param[in] user_name The name of the user.
52 : * \param[in] group_name The name of the group.
53 : *
54 : * \return 0 if chown succeeded,
55 : * -1 if an error occurs (i.e. permissions denied, unknown user/group)
56 : * and errno is set accordingly.
57 : */
58 12 : inline int chownnm(
59 : std::string const & path
60 : , std::string const & user_name
61 : , std::string const & group_name)
62 : {
63 12 : if(path.empty())
64 : {
65 0 : throw std::invalid_argument("the path cannot be empty in snap::chownnm()");
66 : }
67 :
68 12 : uid_t uid(-1);
69 12 : gid_t gid(-1);
70 :
71 : // user name specified?
72 : //
73 12 : if(!user_name.empty())
74 : {
75 0 : struct passwd const * pwd(getpwnam(user_name.c_str()));
76 0 : if(pwd == nullptr)
77 : {
78 0 : return -1;
79 : }
80 0 : uid = pwd->pw_uid;
81 : }
82 :
83 : // group name specified?
84 : //
85 12 : if(!group_name.empty())
86 : {
87 2 : struct group const * grp(getgrnam(group_name.c_str()));
88 2 : if(grp == nullptr)
89 : {
90 0 : return -1;
91 : }
92 2 : gid = grp->gr_gid;
93 : }
94 :
95 12 : if(uid != static_cast<uid_t>(-1)
96 12 : || gid != static_cast<gid_t>(-1))
97 : {
98 2 : return chown(path.c_str(), uid, gid);
99 : }
100 :
101 : // in case both are undefined (it happens in the mkdir_p() function)
102 : //
103 10 : return 0;
104 : }
105 :
106 :
107 :
108 : } // namespace snapdev
109 : // vim: ts=4 sw=4 et
|