Replace inet_aton() with inet_pton() to parse IPs correctly (#8825)
[libi2ncommon] / src / userfunc.cpp
... / ...
CommitLineData
1/*
2The software in this package is distributed under the GNU General
3Public License version 2 (with a special exception described below).
4
5A copy of GNU General Public License (GPL) is included in this distribution,
6in the file COPYING.GPL.
7
8As a special exception, if other files instantiate templates or use macros
9or inline functions from this file, or you compile this file and link it
10with other works to produce a work based on this file, this file
11does not by itself cause the resulting work to be covered
12by the GNU General Public License.
13
14However the source code for this file must still be made available
15in accordance with section (3) of the GNU General Public License.
16
17This exception does not invalidate any other reasons why a work based
18on this file might be covered by the GNU General Public License.
19*/
20/** @file
21 * @brief provides wrapper and tools for (system) user and group information.
22 *
23 * @copyright Intra2net AG
24 *
25 * @license commercial
26 *
27 * (c) Copyright 2007-2008 by Intra2net AG
28 */
29
30#include "userfunc.hpp"
31
32#include <algorithm>
33#include <fstream>
34
35#include <unistd.h>
36#include <signal.h>
37#include <sys/stat.h>
38#include <sys/types.h>
39#include <dirent.h>
40#include <pwd.h>
41#include <grp.h>
42
43#include <boost/scoped_array.hpp>
44
45namespace I2n
46{
47
48namespace
49{
50
51/*
52** tool functions
53*/
54
55bool copy_data ( struct passwd* from, User& to )
56{
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
70bool copy_data ( struct group* from , Group& to)
71{
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;
79 ptr && *ptr;
80 ++ptr)
81 {
82 to.Members.push_back ( *ptr );
83 }
84 return true;
85} // eo copy_data(struct group*,Group&)
86
87
88} // eo namespace <anonymous>
89
90
91/*************************************************************************\
92\*************************************************************************/
93
94/*
95** implementation of User
96*/
97
98User::User()
99: Uid ((uid_t)-1)
100, Gid ((gid_t)-1)
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 */
109User::User(const std::string& name)
110{
111 get_user(name,*this);
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 */
119User::User(const char* name)
120{
121 get_user(std::string (name),*this);
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 */
129User::User(uid_t uid)
130{
131 get_user(uid,*this);
132 this->Uid = uid;
133} // eo User::User(uid_t)
134
135
136
137/**
138 * @brief clears the data.
139 */
140void User::clear()
141{
142 Name.clear();
143 Password.clear();
144 Uid= (uid_t)-1;
145 Gid= (gid_t)-1;
146 Gecos.clear();
147 Homedir.clear();
148 Shell.clear();
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 */
159bool User::is_valid() const
160{
161 return (Uid != (uid_t)-1) and (Gid != (gid_t)-1)
162 and not Name.empty()
163 ;
164} // eo User::is_valid() const
165
166
167/*
168** implementation of Group
169*/
170
171
172Group::Group()
173: Gid ((gid_t)-1)
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 */
182Group::Group(const std::string& name)
183{
184 get_group(name,*this);
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 */
192Group::Group(const char* name)
193{
194 get_group(std::string (name),*this);
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 */
202Group::Group(gid_t gid)
203{
204 get_group(gid,*this);
205 this->Gid= gid;
206} // eo Group::Group(gid_t);
207
208
209/**
210 * @brief clears the data.
211 */
212void Group::clear()
213{
214 Name.clear();
215 Password.clear();
216 Gid= (gid_t)-1;
217 Members.clear();
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 */
228bool Group::is_valid() const
229{
230 return (Gid != (gid_t)-1) and not Name.empty();
231} // eo Group::is_valid() const
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 */
239bool get_user(const std::string& name, User& result)
240{
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
246 int res= ::getpwnam_r(name.c_str(), &pw, buffer.get(), buffer_size, &pw_ptr);
247
248 if (not (0 == res) or not pw_ptr)
249 {
250 return false;
251 }
252
253 return copy_data(pw_ptr, result);
254} // eo get_user(const std::string&,User&)
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 */
263bool get_user(uid_t uid, User& result)
264{
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
270 int res= ::getpwuid_r(uid, &pw, buffer.get(), buffer_size, &pw_ptr);
271
272 if (not (0 == res) or not pw_ptr)
273 {
274 return false;
275 }
276
277 return copy_data(pw_ptr, result);
278} // eo get_user(uid_t,User&)
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 */
286User get_user(const std::string& name)
287{
288 User result;
289 get_user(name,result);
290 return result;
291} // eo get_user(const std::string&)
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 */
299User get_user(uid_t uid)
300{
301 User result;
302 get_user(uid,result);
303 return result;
304} // eo get_user(const std::string&)
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 */
314bool get_group (const std::string& name, Group& result)
315{
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 ] );
320
321 int res= ::getgrnam_r(name.c_str(), &gr, buffer.get(), buffer_size, &gr_ptr);
322
323 if (not (0 == res) or not gr_ptr)
324 {
325 return false;
326 }
327
328 return copy_data(gr_ptr, result);
329} // eo get_group(const std::string&,Group&)
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 */
338bool get_group(gid_t gid, Group& result)
339{
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
345 int res= ::getgrgid_r(gid, &gr, buffer.get(), buffer_size, &gr_ptr);
346
347 if (not (0 == res) or not gr_ptr)
348 {
349 return false;
350 }
351
352 return copy_data(gr_ptr, result);
353} // eo get_group(const std::string&,Group&)
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 */
361Group get_group(const std::string& name)
362{
363 Group result;
364 get_group(name, result);
365 return result;
366} // eo get_group(const std::string&)
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 */
374Group get_group(gid_t gid)
375{
376 Group result;
377 get_group(gid, result);
378 return result;
379} // eo get_group(const std::string&)
380
381} // eo namespace I2n