libmoost
|
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