Here is the second version of my patch, containing all the features agreed so far.
Cheers, Chris
--- gk.h.orig Thu Sep 18 00:12:10 2003 +++ gk.h Thu Sep 18 00:13:43 2003 @@ -67,6 +67,9 @@ /** do some routines **/ void HouseKeeping(void); + /** Sets the process's user and group **/ + static BOOL SetUserAndGroup(const PString &username); + //@} }; --- gk.cxx.orig Wed Dec 11 07:30:52 2002 +++ gk.cxx Thu Sep 18 00:41:12 2003 @@ -23,6 +23,7 @@ #endif #ifndef WIN32 +#define HAS_SETUSERNAME #include <signal.h> #endif #include "gk.h" @@ -210,7 +211,41 @@ return ExitFlag = true; } +inline BOOL Gatekeeper::SetUserAndGroup(const PString &username) +{ + return false; +} + #else +# include <pwd.h> + +BOOL Gatekeeper::SetUserAndGroup(const PString &username) +{ +#if defined(P_PTHREADS) && !defined(P_THREAD_SAFE_CLIB) + static const size_t MAX_PASSWORD_BUFSIZE = 1024; + + struct passwd userdata; + struct passwd *userptr; + char buffer[MAX_PASSWORD_BUFSIZE]; + +#if defined (P_LINUX) || defined (P_AIX) || defined(P_IRIX) || (__GNUC__>=3 && defined(P_SOLARIS)) || defined(P_RTEMS) + ::getpwnam_r(username, + &userdata, + buffer, + sizeof(buffer), + &userptr); +#else + userptr = ::getpwnam_r(username, &userdata, buffer, sizeof(buffer)); +#endif +#else + struct passwd *userptr = ::getpwnam(username); +#endif + + return (userptr != NULL) && + (userptr->pw_name != NULL) && + (::setgid(userptr->pw_gid) == 0) && + (::setuid(userptr->pw_uid) == 0); +} void UnixShutdownHandler(int sig) { @@ -259,6 +294,7 @@ "i-interface:" "l-timetolive:" "b-bandwidth:" + "u-user:" #if PTRACING "t-trace." "o-output:" @@ -363,6 +399,7 @@ " -i --interface IP : The IP that the gatekeeper listen to\n" " -l --timetolive n : Time to live for client registration\n" " -b --bandwidth n : Specify the total bandwidth\n" + " -u --user name : Run as this user\n" #if PTRACING " -t --trace : Set trace verbosity\n" " -o --output file : Write trace to this file\n" @@ -394,6 +431,19 @@ { PArgList & args = GetArguments(); args.Parse(GetArgumentsParseString()); + +#ifdef HAS_SETUSERNAME + if (args.HasOption('u')) { + const PString username = args.GetOptionString('u'); + + if ( !SetUserAndGroup(username) ) { + cout << "GNU Gatekeeper could not run as user " + << username + << endl; + return; + } + } +#endif PIPSocket::Address GKHome = INADDR_ANY;