/* The software in this package is distributed under the GNU General Public License version 2 (with a special exception described below). A copy of GNU General Public License (GPL) is included in this distribution, in the file COPYING.GPL. As a special exception, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other works to produce a work based on this file, this file does not by itself cause the resulting work to be covered by the GNU General Public License. However the source code for this file must still be made available in accordance with section (3) of the GNU General Public License. This exception does not invalidate any other reasons why a work based on this file might be covered by the GNU General Public License. */ /** @file * @brief provides wrapper and tools for (system) user and group information. * * @copyright Intra2net AG * * @license commercial * * (c) Copyright 2007-2008 by Intra2net AG */ #include "userfunc.hpp" #include #include #include #include #include #include #include #include #include #include #include #include namespace I2n { namespace { /* ** tool functions */ bool copy_data ( struct passwd* from, User& to ) { to.clear(); if (!from) return false; to.Name = from->pw_name; to.Password = from->pw_passwd; to.Uid = from->pw_uid; to.Gid = from->pw_gid; to.Gecos = from->pw_gecos; to.Homedir = from->pw_dir; to.Shell = from->pw_shell; return true; } // eo copy_data(struct passwd*,Passwd&) bool copy_data ( struct group* from , Group& to) { to.clear(); if (!from) return false; to.Name = from->gr_name; to.Password = from->gr_passwd; to.Gid = from->gr_gid; to.Members.clear(); for ( char **ptr= from->gr_mem; ptr && *ptr; ++ptr) { to.Members.push_back ( *ptr ); } return true; } // eo copy_data(struct group*,Group&) } // eo namespace /*************************************************************************\ \*************************************************************************/ /* ** implementation of User */ User::User() : Uid ((uid_t)-1) , Gid ((gid_t)-1) { } // User::User() /** * @brief constructs and fills with user data. * @param name the name of the user to search for. */ User::User(const std::string& name) { get_user(name,*this); } // eo User::User(const std::string&) /** * @brief constructs and fills with user data. * @param name the name of the user to search for. */ User::User(const char* name) { get_user(std::string (name),*this); } // eo User::User(const char*) /** * @brief constructs and fills with user data. * @param uid the uid of the user to search for. */ User::User(uid_t uid) { get_user(uid,*this); this->Uid = uid; } // eo User::User(uid_t) /** * @brief clears the data. */ void User::clear() { Name.clear(); Password.clear(); Uid= (uid_t)-1; Gid= (gid_t)-1; Gecos.clear(); Homedir.clear(); Shell.clear(); } // eo User::clear() /** * @brief returns if the structure content looks ok. * @return @a true if the content looks ok. * * This functions checks if mandatory values are existing. * @note It does not check if content is consistent with any system database! */ bool User::is_valid() const { return (Uid != (uid_t)-1) and (Gid != (gid_t)-1) and not Name.empty() ; } // eo User::is_valid() const /* ** implementation of Group */ Group::Group() : Gid ((gid_t)-1) { } // eo Group::Group() /** * @brief constructs and fills with group data. * @param name the name of the group to search for. */ Group::Group(const std::string& name) { get_group(name,*this); } // eo group::Group(const std::strring&) /** * @brief constructs and fills with group data. * @param name the name of the group to search for. */ Group::Group(const char* name) { get_group(std::string (name),*this); } // eo group::Group(const char*) /** * @brief constructs and fills with group data. * @param gid the gid of the group to search for. */ Group::Group(gid_t gid) { get_group(gid,*this); this->Gid= gid; } // eo Group::Group(gid_t); /** * @brief clears the data. */ void Group::clear() { Name.clear(); Password.clear(); Gid= (gid_t)-1; Members.clear(); } // eo Group::clear() /** * @brief returns if the structure content looks ok. * @return @a true if the content looks ok. * * This functions checks if mandatory values are existing. * @note It does not check if content is consistent with any system database! */ bool Group::is_valid() const { return (Gid != (gid_t)-1) and not Name.empty(); } // eo Group::is_valid() const /** * @brief get the (system) user data by name. * @param[in] name the name of the user to search for. * @param[out] result the user info. * @return @a true iff the user was found and the result structure contains data. */ bool get_user(const std::string& name, User& result) { struct passwd pw; struct passwd *pw_ptr= NULL; size_t buffer_size= sysconf (_SC_GETPW_R_SIZE_MAX); boost::scoped_array< char > buffer ( new char[ buffer_size ] ); int res= ::getpwnam_r(name.c_str(), &pw, buffer.get(), buffer_size, &pw_ptr); if (not (0 == res) or not pw_ptr) { return false; } return copy_data(pw_ptr, result); } // eo get_user(const std::string&,User&) /** * @brief get the (system) user data by uid. * @param[in] uid the uid of the user to search for. * @param[out] result the user info. * @return @a true iff the user was found and the result structure contains data. */ bool get_user(uid_t uid, User& result) { struct passwd pw; struct passwd *pw_ptr= NULL; size_t buffer_size= sysconf (_SC_GETPW_R_SIZE_MAX); boost::scoped_array< char > buffer ( new char[ buffer_size ] ); int res= ::getpwuid_r(uid, &pw, buffer.get(), buffer_size, &pw_ptr); if (not (0 == res) or not pw_ptr) { return false; } return copy_data(pw_ptr, result); } // eo get_user(uid_t,User&) /** * @brief get user data by name. * @param name name of the user * @return the user data (invalid if user not found or on error). */ User get_user(const std::string& name) { User result; get_user(name,result); return result; } // eo get_user(const std::string&) /** * @brief get user data by uid. * @param uid uid of the user * @return the user data (invalid if user not found or on error). */ User get_user(uid_t uid) { User result; get_user(uid,result); return result; } // eo get_user(const std::string&) /** * @brief get the (system) group data by name. * @param[in] name the name of the group to search for. * @param[out] result the group info. * @return @a true iff the group was found and the result structure contains data. */ bool get_group (const std::string& name, Group& result) { struct group gr; struct group *gr_ptr= NULL; size_t buffer_size= sysconf (_SC_GETGR_R_SIZE_MAX); boost::scoped_array< char > buffer ( new char[ buffer_size ] ); int res= ::getgrnam_r(name.c_str(), &gr, buffer.get(), buffer_size, &gr_ptr); if (not (0 == res) or not gr_ptr) { return false; } return copy_data(gr_ptr, result); } // eo get_group(const std::string&,Group&) /** * @brief get the (system) group data by gid. * @param[in] gid the gid of the group to search for. * @param[out] result the group info. * @return @a true iff the group was found and the result structure contains data. */ bool get_group(gid_t gid, Group& result) { struct group gr; struct group *gr_ptr= NULL; size_t buffer_size= sysconf (_SC_GETGR_R_SIZE_MAX); boost::scoped_array< char > buffer ( new char[ buffer_size ] ); int res= ::getgrgid_r(gid, &gr, buffer.get(), buffer_size, &gr_ptr); if (not (0 == res) or not gr_ptr) { return false; } return copy_data(gr_ptr, result); } // eo get_group(const std::string&,Group&) /** * @brief get group data by name. * @param name name of the group * @return the group data (invalid if group not found or on error). */ Group get_group(const std::string& name) { Group result; get_group(name, result); return result; } // eo get_group(const std::string&) /** * @brief get group data by gid. * @param gid gid of the group * @return the group data (invalid if group not found or on error). */ Group get_group(gid_t gid) { Group result; get_group(gid, result); return result; } // eo get_group(const std::string&) } // eo namespace I2n