Switch license from Intranator license to GPLv2 + linking exception (ACKed by Steffen)
[libi2ncommon] / src / userfunc.cpp
CommitLineData
0e23f538
TJ
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*/
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
47namespace I2n
48{
a85f4761 49
2e19e724
RP
50namespace
51{
a85f4761
TJ
52
53/*
54** tool functions
55*/
56
2e19e724 57bool 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
72bool 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
100User::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 111User::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 121User::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 131User::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 */
142void 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 161bool 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
174Group::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 184Group::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 194Group::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 204Group::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 */
214void 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 230bool 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 241bool 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 265bool 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 288User 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 301User 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 316bool 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 340bool 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 363Group 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 376Group 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