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
54 #include <sys/param.h>
56 #include <sys/types.h>
58 #ifdef BLOCXX_HAVE_UNISTD_H
75 #if defined(BLOCXX_NO_SETRESGID_PROTO) && defined(BLOCXX_HAVE_SETRESGID)
76 extern "C" {
int setresgid(gid_t rgid, gid_t egid, gid_t sgid); }
79 #if defined(BLOCXX_NO_SETRESUID_PROTO) && defined(BLOCXX_HAVE_SETRESUID)
80 extern "C" {
int setresuid(uid_t ruid, uid_t euid, uid_t suid); }
83 using 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)
111 int seteuid(uid_t euid)
113 return (setreuid(-1, euid));
118 #if !defined(BLOCXX_HAVE_SETEGID) && defined(BLOCXX_HAVE_SETRESGID)
119 int setegid(uid_t egid)
121 return(setresgid(-1, egid, -1));
127 namespace BLOCXX_NAMESPACE
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");
300 String s = String::getLine(is).trim();
301 if (s.startsWith(
"ODMDIR="))
303 retval = check_line(s);
309 void addPlatformSpecificEnvVars(
StringArray & environ)
311 NonRecursiveMutexLock lock(envMutex);
314 odmdir = setODMDIR();
316 environ.push_back(odmdir);
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(
"/");