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