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