34#include "blocxx/BLOCXX_config.h"
42#ifdef BLOCXX_HAVE_DIRENT_H
50#ifdef BLOCXX_HAVE_PWD_H
53#ifdef BLOCXX_HAVE_SYS_PARAM_H
58#ifdef BLOCXX_HAVE_UNISTD_H
75#if defined(BLOCXX_NO_SETRESGID_PROTO) && defined(BLOCXX_HAVE_SETRESGID)
76extern "C" {
int setresgid(gid_t rgid, gid_t egid, gid_t sgid); }
79#if defined(BLOCXX_NO_SETRESUID_PROTO) && defined(BLOCXX_HAVE_SETRESUID)
80extern "C" {
int setresuid(uid_t ruid, uid_t euid, uid_t suid); }
83using namespace blocxx;
85#define THRBLOCXX_IF(tst, ExceptionClass, msg) \
90 BLOCXX_THROW(ExceptionClass, (msg)); \
94#define THRBLOCXX_ERRNO_IF(tst, ExceptionClass, msg) \
99 BLOCXX_THROW_ERRNO_MSG(ExceptionClass, (msg)); \
103#define ABORT_IF(tst, msg) THRBLOCXX_IF((tst), Secure::ProcessAbortException, (msg))
105#define ABORT_ERRNO_IF(tst, msg) \
106 THRBLOCXX_ERRNO_IF((tst), Secure::ProcessAbortException, (msg))
110#if !defined(BLOCXX_HAVE_SETEUID) && defined(BLOCXX_HAVE_SETREUID)
111int seteuid(uid_t euid)
113 return (setreuid(-1, euid));
118#if !defined(BLOCXX_HAVE_SETEGID) && defined(BLOCXX_HAVE_SETRESGID)
119int setegid(uid_t egid)
121 return(setresgid(-1, egid, -1));
140#pragma message(Reminder "TODO: implement it for Win!")
146 if (newgid == ::gid_t(-1))
150 ::gid_t oldegid = ::getegid();
151 ::gid_t oldgid = ::getgid();
152 if (newuid == ::uid_t(-1))
156 ::uid_t oldeuid = ::geteuid();
157 ::uid_t olduid = ::getuid();
166 struct passwd *newuser(NULL);
169 newuser = ::getpwuid(newuid);
173 ::initgroups(newuser->pw_name, newgid);
177 ::setgroups(1, &newgid);
181 if (newgid != oldegid)
183#if defined(BLOCXX_HAVE_SETRESGID) && !defined(BLOCXX_BROKEN_SETRESGID)
184 ABORT_ERRNO_IF(::setresgid(newgid, newgid, newgid) == -1,
"drop_privileges [1]");
185#elif defined(BLOCXX_HAVE_SETREGID) && !defined(BLOCXX_BROKEN_SETREGID)
186 ABORT_ERRNO_IF(::setregid(newgid, newgid) == -1,
"drop_privileges [1]");
193 if (newuid != oldeuid)
195#if defined(BLOCXX_HAVE_SETRESUID) && !defined(BLOCXX_BROKEN_SETRESUID)
196 ABORT_ERRNO_IF(::setresuid(newuid, newuid, newuid) == -1,
"drop_privileges [2]");
197#elif defined(BLOCXX_HAVE_SETREUID) && !defined(BLOCXX_BROKEN_SETREUID)
198 ABORT_ERRNO_IF(::setreuid(newuid, newuid) == -1,
"drop_privileges [2]");
200#if !defined(BLOCXX_SETEUID_BREAKS_SETUID)
209 ABORT_IF(::getgid() != newgid || ::getegid() != newgid,
"drop_privileges [3]");
213 newuid != 0 && newgid != oldegid &&
214#
if defined(BLOCXX_HAVE_SETRESGID) && !defined(BLOCXX_BROKEN_SETRESGID)
215 (::setresgid(oldegid, oldegid, oldegid) != -1 || ::setgid(oldgid) != -1),
216#elif defined(BLOCXX_HAVE_SETREGID) && !defined(BLOCXX_BROKEN_SETREGID)
217 (::setregid(oldegid, oldegid) != -1 || ::setgid(oldgid) != -1),
219 (::setegid(oldegid) != -1 || ::setgid(oldgid) != -1),
221 "drop_privileges [4]"
225 ABORT_IF(::getuid() != newuid || ::geteuid() != newuid,
"drop_privileges [5]");
229 newuid != 0 && newuid != oldeuid &&
230#
if defined(BLOCXX_HAVE_SETRESUID) && !defined(BLOCXX_BROKEN_SETRESUID)
231 (::setresuid(oldeuid, oldeuid, oldeuid) != -1 || ::setuid(olduid) != -1),
232#elif defined(BLOCXX_HAVE_SETREUID) && !defined(BLOCXX_BROKEN_SETREUID)
233 (::setreuid(oldeuid, oldeuid) != -1 || ::setuid(olduid) != -1),
235 (::seteuid(oldeuid) != -1 || ::setuid(olduid) != -1),
237 "drop_privileges [6]"
248 char const default_odmdir[] =
"ODMDIR=/etc/objrepos";
255 for (s = line.
c_str(); (c = *s) && !std::isspace(c); ++s)
263 return default_odmdir;
272 return default_odmdir;
282 while (std::isspace(*s))
291 return default_odmdir;
296 String retval(default_odmdir);
297 std::ifstream is(
"/etc/environment");
301 if (s.startsWith(
"ODMDIR="))
303 retval = check_line(s);
311 NonRecursiveMutexLock lock(envMutex);
314 odmdir = setODMDIR();
321 void addPlatformSpecificEnvVars(
StringArray &absEnvironment)
324 char*
const lpInheritedEnvironment = GetEnvironmentStrings();
325 char* lpInheritedEnvIterator = lpInheritedEnvironment;
326 if (lpInheritedEnvironment && *lpInheritedEnvironment && lpInheritedEnvironment[1])
328 for ( ; *lpInheritedEnvIterator; lpInheritedEnvIterator++)
330 absEnvironment.push_back( String( lpInheritedEnvIterator ) );
331 lpInheritedEnvIterator += lstrlen(lpInheritedEnvIterator);
333 FreeEnvironmentStrings( (LPTCH)lpInheritedEnvironment );
340 struct MinimalEnvironmentConstructor
345 retval->push_back(
"IFS= \t\n");
347 char * tzstr = ::getenv(
"TZ");
350 retval->push_back(String(
"TZ=") + tzstr);
352 addPlatformSpecificEnvVars(*retval);
353 return retval.release();
362 return g_minimalEnvironment;
368#pragma message(Reminder "TODO: implement it for Win!")
370 ABORT_IF(!username,
"null user name");
371 ABORT_IF(*username ==
'\0',
"empty user name");
372 ABORT_IF(::getuid() != 0 || ::geteuid() != 0,
"non-root user calling runAs");
374 struct passwd * pwent = ::getpwnam(username);
377 ABORT_IF(!pwent,
Format(
"user name (%1) not found", username).c_str());
378 int rc = ::chdir(
"/");
BLOCXX_IMPORT char ** environ
#define BLOCXX_DEFINE_EXCEPTION(NAME)
Define a new exception class named <NAME>Exception that derives from Exception.
#define BLOCXX_LAZY_GLOBAL_INIT(...)
Statically initialize a LazyGlobal instance.
#define ABORT_IF(tst, msg)
#define ABORT_ERRNO_IF(tst, msg)
Note that descriptions of what exceptions may be thrown assumes that object is used correctly,...
This String class is an abstract data type that represents as NULL terminated string of characters.
const char * c_str() const
static String getLine(std::istream &istr)
Reads from in input stream until a newline is encountered.
String & trim()
Strip all leading and trailing space characters (as defined by the C function isspace()) from this St...
StringArray minimalEnvironment()
@ E_SOURCE_EXTENDED_GROUPS
void dropPrivilegesPermanently(::uid_t newuid, ::gid_t newgid, EChildGroupAction extendedGroupAction)
void runAs(char const *username, EChildGroupAction extendedGroupAction)
Look up user ID and group ID for username in password file, chdir to "/", then drop privileges and ru...
Array< String > StringArray