libmoost
/home/mhx/git/github/libmoost/include/moost/process/detail/ownership_posix.hpp
Go to the documentation of this file.
00001 /* vim:set ts=3 sw=3 sts=3 et: */
00028 #ifndef FM_LAST_MOOST_PROCESS_DETAIL_OWNERSHIP_POSIX_H_
00029 #define FM_LAST_MOOST_PROCESS_DETAIL_OWNERSHIP_POSIX_H_
00030 
00031 #include <string>
00032 #include <vector>
00033 #include <sys/types.h>
00034 #include <pwd.h>
00035 #include <grp.h>
00036 #include <unistd.h>
00037 #include <errno.h>
00038 #include <cstdlib>
00039 #include <boost/system/system_error.hpp>
00040 
00041 namespace moost { namespace process { namespace detail {
00042 
00043 class ownership
00044 {
00045 private:
00046    typedef std::vector<char> buffer_type;
00047 
00048 public:
00049    typedef int uid_type;
00050    typedef int gid_type;
00051 
00052    bool is_superuser() const
00053    {
00054       return get_uid() == 0 && get_gid() == 0;
00055    }
00056 
00057    bool lookup_user(std::string& name, const uid_type& uid) const
00058    {
00059       struct passwd pwd;
00060       buffer_type buf;
00061 
00062       if (lookup_user(uid, buf, &pwd))
00063       {
00064          name = pwd.pw_name;
00065          return true;
00066       }
00067 
00068       return false;
00069    }
00070 
00071    bool lookup_group(std::string& name, const gid_type& gid) const
00072    {
00073       struct group grp;
00074       buffer_type buf;
00075 
00076       if (lookup_group(gid, buf, &grp))
00077       {
00078          name = grp.gr_name;
00079          return true;
00080       }
00081 
00082       return false;
00083    }
00084 
00085    bool lookup_uid(uid_type& uid, const std::string& name) const
00086    {
00087       struct passwd pwd;
00088       buffer_type buf;
00089 
00090       if (lookup_user(name, buf, &pwd))
00091       {
00092          uid = pwd.pw_uid;
00093          return true;
00094       }
00095 
00096       return false;
00097    }
00098 
00099    bool lookup_uid(uid_type& uid, gid_type& gid, const std::string& name) const
00100    {
00101       struct passwd pwd;
00102       buffer_type buf;
00103 
00104       if (lookup_user(name, buf, &pwd))
00105       {
00106          uid = pwd.pw_uid;
00107          gid = pwd.pw_gid;
00108          return true;
00109       }
00110 
00111       return false;
00112    }
00113 
00114    bool lookup_gid(gid_type& gid, const std::string& name) const
00115    {
00116       struct group grp;
00117       buffer_type buf;
00118 
00119       if (lookup_group(name, buf, &grp))
00120       {
00121          gid = grp.gr_gid;
00122          return true;
00123       }
00124 
00125       return false;
00126    }
00127 
00128    bool lookup_gid(gid_type& gid, const uid_type& uid) const
00129    {
00130       struct passwd pwd;
00131       buffer_type buf;
00132 
00133       if (lookup_user(uid, buf, &pwd))
00134       {
00135          gid = pwd.pw_gid;
00136          return true;
00137       }
00138 
00139       return false;
00140    }
00141 
00142    void set_uid(uid_type uid)
00143    {
00144       if (setuid(uid) == -1)
00145       {
00146          boost::system::error_code ec(errno, boost::system::get_system_category());
00147          boost::system::system_error e(ec, "setuid");
00148          boost::throw_exception(e);
00149       }
00150    }
00151 
00152    void set_effective_uid(uid_type uid)
00153    {
00154       if (seteuid(uid) == -1)
00155       {
00156          boost::system::error_code ec(errno, boost::system::get_system_category());
00157          boost::system::system_error e(ec, "seteuid");
00158          boost::throw_exception(e);
00159       }
00160    }
00161 
00162    uid_type get_uid() const
00163    {
00164       return getuid();
00165    }
00166 
00167    uid_type get_effective_uid() const
00168    {
00169       return geteuid();
00170    }
00171 
00172    void set_gid(gid_type gid)
00173    {
00174       if (setgid(gid) == -1)
00175       {
00176          boost::system::error_code ec(errno, boost::system::get_system_category());
00177          boost::system::system_error e(ec, "setgid");
00178          boost::throw_exception(e);
00179       }
00180    }
00181 
00182    void set_effective_gid(gid_type gid)
00183    {
00184       if (setegid(gid) == -1)
00185       {
00186          boost::system::error_code ec(errno, boost::system::get_system_category());
00187          boost::system::system_error e(ec, "setegid");
00188          boost::throw_exception(e);
00189       }
00190    }
00191 
00192    gid_type get_gid() const
00193    {
00194       return getgid();
00195    }
00196 
00197    gid_type get_effective_gid() const
00198    {
00199       return getegid();
00200    }
00201 
00202 private:
00203    static void buffer_reserve(buffer_type& buf, int which)
00204    {
00205       long bufsize = sysconf(which);
00206 
00207       if (bufsize == -1)
00208       {
00209          bufsize = 4096;
00210       }
00211 
00212       buf.reserve(bufsize);
00213    }
00214 
00215    bool lookup_user(uid_type uid, buffer_type& buf, struct passwd* pwd) const
00216    {
00217       struct passwd *result;
00218       int rv;
00219 
00220       buffer_reserve(buf, _SC_GETPW_R_SIZE_MAX);
00221 
00222       rv = getpwuid_r(uid, pwd, &buf[0], buf.capacity(), &result);
00223 
00224       if (result == NULL)
00225       {
00226          if (rv == 0)
00227          {
00228             return false;
00229          }
00230          else
00231          {
00232             boost::system::error_code ec(rv, boost::system::get_system_category());
00233             boost::system::system_error e(ec, "getpwuid_r");
00234             boost::throw_exception(e);
00235          }
00236       }
00237 
00238       return true;
00239    }
00240 
00241    bool lookup_user(const std::string& name, buffer_type& buf, struct passwd* pwd) const
00242    {
00243       struct passwd *result;
00244       int rv;
00245 
00246       buffer_reserve(buf, _SC_GETPW_R_SIZE_MAX);
00247 
00248       rv = getpwnam_r(name.c_str(), pwd, &buf[0], buf.capacity(), &result);
00249 
00250       if (result == NULL)
00251       {
00252          if (rv == 0)
00253          {
00254             return false;
00255          }
00256          else
00257          {
00258             boost::system::error_code ec(rv, boost::system::get_system_category());
00259             boost::system::system_error e(ec, "getpwnam_r");
00260             boost::throw_exception(e);
00261          }
00262       }
00263 
00264       return true;
00265    }
00266 
00267    bool lookup_group(gid_type gid, buffer_type& buf, struct group* grp) const
00268    {
00269       struct group *result;
00270       int rv;
00271 
00272       buffer_reserve(buf, _SC_GETGR_R_SIZE_MAX);
00273 
00274       rv = getgrgid_r(gid, grp, &buf[0], buf.capacity(), &result);
00275 
00276       if (result == NULL)
00277       {
00278          if (rv == 0)
00279          {
00280             return false;
00281          }
00282          else
00283          {
00284             boost::system::error_code ec(rv, boost::system::get_system_category());
00285             boost::system::system_error e(ec, "getgrgid_r");
00286             boost::throw_exception(e);
00287          }
00288       }
00289 
00290       return true;
00291    }
00292 
00293    bool lookup_group(const std::string& name, buffer_type& buf, struct group* grp) const
00294    {
00295       struct group *result;
00296       int rv;
00297 
00298       buffer_reserve(buf, _SC_GETGR_R_SIZE_MAX);
00299 
00300       rv = getgrnam_r(name.c_str(), grp, &buf[0], buf.capacity(), &result);
00301 
00302       if (result == NULL)
00303       {
00304          if (rv == 0)
00305          {
00306             return false;
00307          }
00308          else
00309          {
00310             boost::system::error_code ec(rv, boost::system::get_system_category());
00311             boost::system::system_error e(ec, "getgrnam_r");
00312             boost::throw_exception(e);
00313          }
00314       }
00315 
00316       return true;
00317    }
00318 };
00319 
00320 } } }
00321 
00322 #endif