Commit | Line | Data |
---|---|---|
0e23f538 TJ |
1 | /* |
2 | The software in this package is distributed under the GNU General | |
3 | Public License version 2 (with a special exception described below). | |
4 | ||
5 | A copy of GNU General Public License (GPL) is included in this distribution, | |
6 | in the file COPYING.GPL. | |
7 | ||
8 | As a special exception, if other files instantiate templates or use macros | |
9 | or inline functions from this file, or you compile this file and link it | |
10 | with other works to produce a work based on this file, this file | |
11 | does not by itself cause the resulting work to be covered | |
12 | by the GNU General Public License. | |
13 | ||
14 | However the source code for this file must still be made available | |
15 | in accordance with section (3) of the GNU General Public License. | |
16 | ||
17 | This exception does not invalidate any other reasons why a work based | |
18 | on this file might be covered by the GNU General Public License. | |
19 | */ | |
a85f4761 | 20 | /** @file |
2e19e724 RP |
21 | * @brief provides wrapper and tools for (system) user and group information. |
22 | * | |
23 | * @copyright Intra2net AG | |
24 | * | |
25 | * @license commercial | |
a85f4761 TJ |
26 | * |
27 | * (c) Copyright 2007-2008 by Intra2net AG | |
a85f4761 TJ |
28 | */ |
29 | ||
90246b4a | 30 | #include "userfunc.hpp" |
a85f4761 TJ |
31 | |
32 | #include <algorithm> | |
33 | #include <fstream> | |
34 | ||
35 | #include <unistd.h> | |
36 | #include <signal.h> | |
a85f4761 TJ |
37 | #include <sys/stat.h> |
38 | #include <sys/types.h> | |
39 | #include <dirent.h> | |
a85f4761 TJ |
40 | #include <pwd.h> |
41 | #include <grp.h> | |
42 | ||
43 | #include <boost/scoped_array.hpp> | |
44 | ||
2e19e724 RP |
45 | namespace I2n |
46 | { | |
a85f4761 | 47 | |
2e19e724 RP |
48 | namespace |
49 | { | |
a85f4761 TJ |
50 | |
51 | /* | |
52 | ** tool functions | |
53 | */ | |
54 | ||
2e19e724 | 55 | bool copy_data ( struct passwd* from, User& to ) |
a85f4761 | 56 | { |
2e19e724 RP |
57 | to.clear(); |
58 | if (!from) return false; | |
59 | to.Name = from->pw_name; | |
60 | to.Password = from->pw_passwd; | |
61 | to.Uid = from->pw_uid; | |
62 | to.Gid = from->pw_gid; | |
63 | to.Gecos = from->pw_gecos; | |
64 | to.Homedir = from->pw_dir; | |
65 | to.Shell = from->pw_shell; | |
66 | return true; | |
67 | } // eo copy_data(struct passwd*,Passwd&) | |
68 | ||
69 | ||
70 | bool copy_data ( struct group* from , Group& to) | |
a85f4761 | 71 | { |
2e19e724 RP |
72 | to.clear(); |
73 | if (!from) return false; | |
74 | to.Name = from->gr_name; | |
75 | to.Password = from->gr_passwd; | |
76 | to.Gid = from->gr_gid; | |
77 | to.Members.clear(); | |
78 | for ( char **ptr= from->gr_mem; | |
a85f4761 TJ |
79 | ptr && *ptr; |
80 | ++ptr) | |
2e19e724 RP |
81 | { |
82 | to.Members.push_back ( *ptr ); | |
83 | } | |
84 | return true; | |
85 | } // eo copy_data(struct group*,Group&) | |
a85f4761 TJ |
86 | |
87 | ||
88 | } // eo namespace <anonymous> | |
89 | ||
90 | ||
91 | /*************************************************************************\ | |
92 | \*************************************************************************/ | |
93 | ||
94 | /* | |
95 | ** implementation of User | |
96 | */ | |
97 | ||
98 | User::User() | |
4c1da7a3 TJ |
99 | : Uid ((uid_t)-1) |
100 | , Gid ((gid_t)-1) | |
a85f4761 TJ |
101 | { |
102 | } // User::User() | |
103 | ||
104 | ||
105 | /** | |
106 | * @brief constructs and fills with user data. | |
107 | * @param name the name of the user to search for. | |
108 | */ | |
9da858e3 | 109 | User::User(const std::string& name) |
a85f4761 | 110 | { |
9da858e3 | 111 | get_user(name,*this); |
a85f4761 TJ |
112 | } // eo User::User(const std::string&) |
113 | ||
114 | ||
115 | /** | |
116 | * @brief constructs and fills with user data. | |
117 | * @param name the name of the user to search for. | |
118 | */ | |
9da858e3 | 119 | User::User(const char* name) |
a85f4761 | 120 | { |
9da858e3 | 121 | get_user(std::string (name),*this); |
a85f4761 TJ |
122 | } // eo User::User(const char*) |
123 | ||
124 | ||
125 | /** | |
126 | * @brief constructs and fills with user data. | |
127 | * @param uid the uid of the user to search for. | |
128 | */ | |
9da858e3 | 129 | User::User(uid_t uid) |
a85f4761 | 130 | { |
9da858e3 | 131 | get_user(uid,*this); |
2e19e724 | 132 | this->Uid = uid; |
a85f4761 TJ |
133 | } // eo User::User(uid_t) |
134 | ||
135 | ||
136 | ||
137 | /** | |
138 | * @brief clears the data. | |
139 | */ | |
140 | void User::clear() | |
141 | { | |
2e19e724 RP |
142 | Name.clear(); |
143 | Password.clear(); | |
4c1da7a3 TJ |
144 | Uid= (uid_t)-1; |
145 | Gid= (gid_t)-1; | |
2e19e724 RP |
146 | Gecos.clear(); |
147 | Homedir.clear(); | |
148 | Shell.clear(); | |
a85f4761 TJ |
149 | } // eo User::clear() |
150 | ||
151 | ||
152 | /** | |
153 | * @brief returns if the structure content looks ok. | |
154 | * @return @a true if the content looks ok. | |
155 | * | |
156 | * This functions checks if mandatory values are existing. | |
157 | * @note It does not check if content is consistent with any system database! | |
158 | */ | |
2e19e724 | 159 | bool User::is_valid() const |
a85f4761 | 160 | { |
4c1da7a3 | 161 | return (Uid != (uid_t)-1) and (Gid != (gid_t)-1) |
2e19e724 RP |
162 | and not Name.empty() |
163 | ; | |
164 | } // eo User::is_valid() const | |
a85f4761 TJ |
165 | |
166 | ||
167 | /* | |
168 | ** implementation of Group | |
169 | */ | |
170 | ||
171 | ||
172 | Group::Group() | |
4c1da7a3 | 173 | : Gid ((gid_t)-1) |
a85f4761 TJ |
174 | { |
175 | } // eo Group::Group() | |
176 | ||
177 | ||
178 | /** | |
179 | * @brief constructs and fills with group data. | |
180 | * @param name the name of the group to search for. | |
181 | */ | |
9da858e3 | 182 | Group::Group(const std::string& name) |
a85f4761 | 183 | { |
9da858e3 | 184 | get_group(name,*this); |
a85f4761 TJ |
185 | } // eo group::Group(const std::strring&) |
186 | ||
187 | ||
188 | /** | |
189 | * @brief constructs and fills with group data. | |
190 | * @param name the name of the group to search for. | |
191 | */ | |
9da858e3 | 192 | Group::Group(const char* name) |
a85f4761 | 193 | { |
9da858e3 | 194 | get_group(std::string (name),*this); |
a85f4761 TJ |
195 | } // eo group::Group(const char*) |
196 | ||
197 | ||
198 | /** | |
199 | * @brief constructs and fills with group data. | |
200 | * @param gid the gid of the group to search for. | |
201 | */ | |
9da858e3 | 202 | Group::Group(gid_t gid) |
a85f4761 | 203 | { |
9da858e3 | 204 | get_group(gid,*this); |
2e19e724 | 205 | this->Gid= gid; |
a85f4761 TJ |
206 | } // eo Group::Group(gid_t); |
207 | ||
208 | ||
209 | /** | |
210 | * @brief clears the data. | |
211 | */ | |
212 | void Group::clear() | |
213 | { | |
2e19e724 RP |
214 | Name.clear(); |
215 | Password.clear(); | |
4c1da7a3 | 216 | Gid= (gid_t)-1; |
2e19e724 | 217 | Members.clear(); |
a85f4761 TJ |
218 | } // eo Group::clear() |
219 | ||
220 | ||
221 | /** | |
222 | * @brief returns if the structure content looks ok. | |
223 | * @return @a true if the content looks ok. | |
224 | * | |
225 | * This functions checks if mandatory values are existing. | |
226 | * @note It does not check if content is consistent with any system database! | |
227 | */ | |
2e19e724 | 228 | bool Group::is_valid() const |
a85f4761 | 229 | { |
4c1da7a3 | 230 | return (Gid != (gid_t)-1) and not Name.empty(); |
2e19e724 | 231 | } // eo Group::is_valid() const |
a85f4761 TJ |
232 | |
233 | /** | |
234 | * @brief get the (system) user data by name. | |
235 | * @param[in] name the name of the user to search for. | |
236 | * @param[out] result the user info. | |
237 | * @return @a true iff the user was found and the result structure contains data. | |
238 | */ | |
9da858e3 | 239 | bool get_user(const std::string& name, User& result) |
a85f4761 | 240 | { |
2e19e724 RP |
241 | struct passwd pw; |
242 | struct passwd *pw_ptr= NULL; | |
243 | size_t buffer_size= sysconf (_SC_GETPW_R_SIZE_MAX); | |
244 | boost::scoped_array< char > buffer ( new char[ buffer_size ] ); | |
245 | ||
9da858e3 | 246 | int res= ::getpwnam_r(name.c_str(), &pw, buffer.get(), buffer_size, &pw_ptr); |
2e19e724 RP |
247 | |
248 | if (not (0 == res) or not pw_ptr) | |
249 | { | |
250 | return false; | |
251 | } | |
252 | ||
9da858e3 | 253 | return copy_data(pw_ptr, result); |
2e19e724 | 254 | } // eo get_user(const std::string&,User&) |
a85f4761 TJ |
255 | |
256 | ||
257 | /** | |
258 | * @brief get the (system) user data by uid. | |
259 | * @param[in] uid the uid of the user to search for. | |
260 | * @param[out] result the user info. | |
261 | * @return @a true iff the user was found and the result structure contains data. | |
262 | */ | |
9da858e3 | 263 | bool get_user(uid_t uid, User& result) |
a85f4761 | 264 | { |
2e19e724 RP |
265 | struct passwd pw; |
266 | struct passwd *pw_ptr= NULL; | |
267 | size_t buffer_size= sysconf (_SC_GETPW_R_SIZE_MAX); | |
268 | boost::scoped_array< char > buffer ( new char[ buffer_size ] ); | |
269 | ||
9da858e3 | 270 | int res= ::getpwuid_r(uid, &pw, buffer.get(), buffer_size, &pw_ptr); |
2e19e724 RP |
271 | |
272 | if (not (0 == res) or not pw_ptr) | |
273 | { | |
274 | return false; | |
275 | } | |
276 | ||
9da858e3 | 277 | return copy_data(pw_ptr, result); |
2e19e724 | 278 | } // eo get_user(uid_t,User&) |
a85f4761 TJ |
279 | |
280 | ||
281 | /** | |
282 | * @brief get user data by name. | |
283 | * @param name name of the user | |
284 | * @return the user data (invalid if user not found or on error). | |
285 | */ | |
9da858e3 | 286 | User get_user(const std::string& name) |
a85f4761 | 287 | { |
2e19e724 | 288 | User result; |
9da858e3 | 289 | get_user(name,result); |
2e19e724 RP |
290 | return result; |
291 | } // eo get_user(const std::string&) | |
a85f4761 TJ |
292 | |
293 | ||
294 | /** | |
295 | * @brief get user data by uid. | |
296 | * @param uid uid of the user | |
297 | * @return the user data (invalid if user not found or on error). | |
298 | */ | |
9da858e3 | 299 | User get_user(uid_t uid) |
a85f4761 | 300 | { |
2e19e724 | 301 | User result; |
9da858e3 | 302 | get_user(uid,result); |
2e19e724 RP |
303 | return result; |
304 | } // eo get_user(const std::string&) | |
a85f4761 TJ |
305 | |
306 | ||
307 | ||
308 | /** | |
309 | * @brief get the (system) group data by name. | |
310 | * @param[in] name the name of the group to search for. | |
311 | * @param[out] result the group info. | |
312 | * @return @a true iff the group was found and the result structure contains data. | |
313 | */ | |
2e19e724 | 314 | bool get_group (const std::string& name, Group& result) |
a85f4761 | 315 | { |
2e19e724 RP |
316 | struct group gr; |
317 | struct group *gr_ptr= NULL; | |
318 | size_t buffer_size= sysconf (_SC_GETGR_R_SIZE_MAX); | |
319 | boost::scoped_array< char > buffer ( new char[ buffer_size ] ); | |
a85f4761 | 320 | |
9da858e3 | 321 | int res= ::getgrnam_r(name.c_str(), &gr, buffer.get(), buffer_size, &gr_ptr); |
a85f4761 | 322 | |
2e19e724 RP |
323 | if (not (0 == res) or not gr_ptr) |
324 | { | |
325 | return false; | |
326 | } | |
a85f4761 | 327 | |
9da858e3 | 328 | return copy_data(gr_ptr, result); |
2e19e724 | 329 | } // eo get_group(const std::string&,Group&) |
a85f4761 TJ |
330 | |
331 | ||
332 | /** | |
333 | * @brief get the (system) group data by gid. | |
334 | * @param[in] gid the gid of the group to search for. | |
335 | * @param[out] result the group info. | |
336 | * @return @a true iff the group was found and the result structure contains data. | |
337 | */ | |
9da858e3 | 338 | bool get_group(gid_t gid, Group& result) |
a85f4761 | 339 | { |
2e19e724 RP |
340 | struct group gr; |
341 | struct group *gr_ptr= NULL; | |
342 | size_t buffer_size= sysconf (_SC_GETGR_R_SIZE_MAX); | |
343 | boost::scoped_array< char > buffer ( new char[ buffer_size ] ); | |
344 | ||
9da858e3 | 345 | int res= ::getgrgid_r(gid, &gr, buffer.get(), buffer_size, &gr_ptr); |
2e19e724 RP |
346 | |
347 | if (not (0 == res) or not gr_ptr) | |
348 | { | |
349 | return false; | |
350 | } | |
351 | ||
9da858e3 | 352 | return copy_data(gr_ptr, result); |
2e19e724 | 353 | } // eo get_group(const std::string&,Group&) |
a85f4761 TJ |
354 | |
355 | ||
356 | /** | |
357 | * @brief get group data by name. | |
358 | * @param name name of the group | |
359 | * @return the group data (invalid if group not found or on error). | |
360 | */ | |
9da858e3 | 361 | Group get_group(const std::string& name) |
a85f4761 | 362 | { |
2e19e724 | 363 | Group result; |
9da858e3 | 364 | get_group(name, result); |
2e19e724 RP |
365 | return result; |
366 | } // eo get_group(const std::string&) | |
a85f4761 TJ |
367 | |
368 | ||
369 | /** | |
370 | * @brief get group data by gid. | |
371 | * @param gid gid of the group | |
372 | * @return the group data (invalid if group not found or on error). | |
373 | */ | |
9da858e3 | 374 | Group get_group(gid_t gid) |
a85f4761 | 375 | { |
2e19e724 | 376 | Group result; |
9da858e3 | 377 | get_group(gid, result); |
2e19e724 RP |
378 | return result; |
379 | } // eo get_group(const std::string&) | |
a85f4761 | 380 | |
2e19e724 | 381 | } // eo namespace I2n |