librostlab
1.0.20
|
00001 /* 00002 Copyright (C) 2011 Laszlo Kajan, Technical University of Munich, Germany 00003 00004 This file is part of librostlab. 00005 00006 librostlab is free software: you can redistribute it and/or modify 00007 it under the terms of the GNU Lesser General Public License as published by 00008 the Free Software Foundation, either version 3 of the License, or 00009 (at your option) any later version. 00010 00011 This program is distributed in the hope that it will be useful, 00012 but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 GNU Lesser General Public License for more details. 00015 00016 You should have received a copy of the GNU Lesser General Public License 00017 along with this program. If not, see <http://www.gnu.org/licenses/>. 00018 */ 00019 #ifndef ROSTLAB_EUID_EGID 00020 #define ROSTLAB_EUID_EGID 1 00021 00022 #include <errno.h> 00023 #include <sstream> 00024 #include <stdexcept> 00025 #include <string.h> 00026 #include <sys/types.h> 00027 #include <unistd.h> 00028 00029 #include "rostlab/rostlab_stdexcept.h" 00030 00031 namespace rostlab { 00032 00033 class euid_egid_resource 00034 { 00035 private: 00036 uid_t _olduid; 00037 gid_t _oldgid; 00038 bool _changeduid; 00039 bool _changedgid; 00040 // this is a resource - disable copy contructor and copy assignment 00041 euid_egid_resource( const euid_egid_resource& ){}; 00042 euid_egid_resource& 00043 operator=(const euid_egid_resource&){return *this;}; 00044 00045 public: 00046 euid_egid_resource( uid_t __neweuid, gid_t __newegid ) : _changeduid(false), _changedgid(false) 00047 { 00048 _olduid = getuid(); 00049 _oldgid = getgid(); 00050 if( getegid() != __newegid ) 00051 { 00052 if( setregid( getegid(), __newegid ) ){ std::ostringstream s; s << "failed to setregid " << getegid() << ":" << __newegid << " : " << strerror( errno ); throw runtime_error( s.str() ); } 00053 _changedgid = true; 00054 } 00055 if( geteuid() != __neweuid ) 00056 { 00057 if( setreuid( geteuid(), __neweuid ) ){ std::ostringstream s; s << "failed to setreuid " << geteuid() << ":" << __neweuid << " : " << strerror( errno ); throw runtime_error( s.str() ); } 00058 _changeduid = true; 00059 } 00060 } 00061 00062 virtual ~euid_egid_resource() 00063 { 00064 if( _changeduid ) 00065 { 00066 if( setreuid( geteuid(), getuid() ) ){ std::ostringstream s; s << "failed revert setreuid to " << geteuid() << ":" << getuid() << " : " << strerror( errno ); throw runtime_error( s.str() ); } 00067 if( setreuid( _olduid, -1 ) ){ std::ostringstream s; s << "failed revert setreuid to " << _olduid << ":-1" << " : " << strerror( errno ); throw runtime_error( s.str() ); } 00068 } 00069 if( _changedgid ) 00070 { 00071 if( setregid( getegid(), getgid() ) ){ std::ostringstream s; s << "failed revert setregid to " << getegid() << ":" << getgid() << " : " << strerror( errno ); throw runtime_error( s.str() ); } 00072 if( setregid( _oldgid, -1 ) ){ std::ostringstream s; s << "failed revert setregid to " << _oldgid << ":-1" << " : " << strerror( errno ); throw runtime_error( s.str() ); } 00073 } 00074 } 00075 }; 00076 00077 }; 00078 00079 #endif // ROSTLAB_EUID_EGID 00080 // vim:et:ai:ts=2: