157 #include "RConfigure.h"
169 #include <sys/types.h>
171 #include <sys/stat.h>
172 #include <sys/socket.h>
173 #include <sys/param.h>
174 #include <netinet/in.h>
175 #include <arpa/inet.h>
179 #include "snprintf.h"
181 #if defined(__CYGWIN__) && defined(__GNUC__)
187 #if defined(linux) || defined(__sun) || defined(__sgi) || \
188 defined(_AIX) || defined(__FreeBSD__) || defined(__APPLE__) || \
189 defined(__MACH__) || defined(cygwingcc) || defined(__OpenBSD__)
191 #include <sys/types.h>
193 #define ROOT_SIGNAL_INCLUDED
196 #if defined(__sgi) && !defined(__GNUG__) && (SGI_REL<62)
198 int seteuid(
int euid);
199 int setegid(
int egid);
206 int seteuid(uid_t euid);
207 int setegid(gid_t egid);
212 #if defined(R__SUNGCC3)
213 extern "C" int gethostname(
char *,
unsigned int);
245 using namespace ROOT;
251 void Err(
int level,
const char *msg,
int size)
253 Perror((
char *)msg, size);
258 void ErrFatal(
int level,
const char *msg,
int size)
260 Perror((
char *)msg, size);
266 void ErrSys(
int level,
const char *msg,
int size)
268 Perror((
char *)msg, size);
280 ErrorInfo(
"ProofdTerm: rootd.cxx: got a SIGTERM/SIGINT");
294 ErrorInfo(
"ProofdTerm: rootd.cxx: got a SIGTERM/SIGINT");
309 std::string conffile =
"proof.conf";
312 if (getenv(
"HOME")) {
313 conffile.insert(0,
"/.");
314 conffile.insert(0,getenv(
"HOME"));
317 conffile[conffile.length()] = 0;
319 if (!(proofconf = fopen(conffile.c_str(),
"r"))) {
324 conffile[conffile.length()] = 0;
326 if (proofconf || (proofconf = fopen(conffile.c_str(),
"r")) != 0) {
329 static char user_on_node[32];
336 strncpy(user_on_node,
"any", 32);
337 user_on_node[31] = 0;
339 while (fgets(line,
sizeof(line), proofconf) != 0) {
341 if (line[0] ==
'#')
continue;
343 int nword = sscanf(line,
"%63s %63s %63s %63s",
344 word[0], word[1], word[2], word[3]);
350 if (nword >= 2 && strcmp(word[0],
"node") == 0) {
351 if (gethostbyname(word[1]) != 0) {
353 if (strlen(word[1]) < 32) {
354 strncpy(node_name[nnodes], word[1], 32);
355 node_name[nnodes][31] = 0;
367 if (nword >= 4 && strcmp(word[0],
"user") == 0 &&
368 strcmp(word[1],
gUser.c_str()) == 0 &&
369 strcmp(word[2],
"on") == 0) {
371 if (strlen(word[3]) < 32) {
372 strncpy(user_on_node, word[3], 32);
373 user_on_node[31] = 0;
381 for (i = 0; i < nnodes; i++) {
382 if (strcmp(node_name[i], user_on_node) == 0) {
391 conffile =
gConfDir +
"/etc/next.node";
392 proofconf = fopen(conffile.c_str(),
"r");
394 if (fstat(fileno(proofconf), &statbuf) == 0 &&
395 difftime(time(0), statbuf.st_mtime) < 600) {
396 if (fgets(line,
sizeof(line), proofconf) != 0) {
397 strncpy(user_on_node, line, 32);
398 user_on_node[31] = 0;
399 for (i = 0; i < nnodes; i++) {
400 if (strcmp(node_name[i], user_on_node) == 0) {
421 if (RpdGetOffSet() > -1) {
422 if ((nrec = RpdSecureRecv(abuf)) < 0) {
423 ErrorInfo(
"RpdProofGetAuthSetup: sec: problems receiving buf");
430 if (
NetRecv(buflen, 20, kind) < 0) {
431 ErrorInfo(
"RpdProofGetAuthSetup: plain: problems receiving buf length");
434 int len = atoi(buflen);
437 *abuf =
new char[len + 1];
439 ErrorInfo(
"RpdProofGetAuthSetup: plain: problems receiving buf");
447 ErrorInfo(
"RpdProofGetAuthSetup: proto: %d len: %d",
448 RpdGetAuthProtocol(), nrec);
482 const char *node_name;
487 gethostname(host_name,
sizeof(host_name));
490 if (strcmp(host_name, node_name) != 0) {
491 struct hostent *host = gethostbyname(host_name);
492 struct hostent *node;
495 struct in_addr *host_addr = (
struct in_addr*)(host->h_addr);
497 if (strlen(inet_ntoa(*host_addr)) < 32) {
498 strncpy(host_numb, inet_ntoa(*host_addr), 32);
502 if ((node = gethostbyname(node_name)) != 0) {
503 struct in_addr *node_addr = (
struct in_addr*)(node->h_addr);
505 strncpy(node_numb, inet_ntoa(*node_addr), 32);
511 if (strcmp(host_numb, node_numb) != 0) {
512 msg = std::string(
"Reroute:").append(node_numb);
528 char *rootproofauthsetup =
new char[20 + strlen(authbuff)];
529 memset(rootproofauthsetup, 0, 20 + strlen(authbuff));
530 snprintf(rootproofauthsetup, 20 + strlen(authbuff),
"ROOTPROOFAUTHSETUP=%s", authbuff);
531 putenv(rootproofauthsetup);
532 }
else if (lab < 0) {
533 ErrorInfo(
"ProofdExec: problems receiving auth buffer");
535 if (authbuff)
delete[] authbuff;
538 if(RpdGetClientProtocol() >= 16) {
543 int rc = NetRecvAllocate(vb, len, kind);
546 ErrorInfo(
"ProofdExec: error receiving kPROOF_SETENV message");
551 ErrorInfo(
"ProofdExec: expecting kPROOF_SETENV, got %d", kind);
556 char *buf = (
char *) vb;
557 char *end = buf + len;
558 const char name[] =
"PROOF_ALLVARS=";
559 int alen = strlen(name)+len;
560 char *all =
new char[alen];
561 strlcpy(all, name, alen);
564 char *p = index(buf,
'=');
566 if (buf != (
char *) vb) strlcat(all,
",", alen);
567 strlcat(all, buf, alen);
570 buf += strlen(buf) + 1;
577 ErrorInfo(
"ProofdExec: send Okay (SockFd: %d)", sockFd);
581 if (sockFd == 0 || sockFd == 1 || sockFd == 2) {
584 for (fd = 3; fd < NOFILE; fd++) {
586 if (fstat(fd, &stbuf) == -1 &&
GetErrno() == EBADF) {
587 if (dup2(sockFd, fd) < 0)
588 ErrorInfo(
"ProofdExec: problems executing 'dup2' (errno: %d)", errno);
600 NetSend(
"Cannot start proofserver -- no free filedescriptor");
608 char *rootconf =
new char[13+
gConfDir.length()];
609 memset(rootconf, 0, 13 +
gConfDir.length());
610 snprintf(rootconf, 13 +
gConfDir.length(),
"ROOTCONFDIR=%s",
gConfDir.c_str());
613 ErrorInfo(
"ProofdExec: setting: %s", rootconf);
615 char *roottmp =
new char[12+
gTmpDir.length()];
616 memset(roottmp, 0, 12 +
gTmpDir.length());
617 snprintf(roottmp, 12+
gTmpDir.length(),
"ROOTTMPDIR=%s",
gTmpDir.c_str());
620 ErrorInfo(
"ProofdExec: setting: %s", roottmp);
622 char *rootentity =
new char[
gUser.length()+
gOpenHost.length()+33];
628 ErrorInfo(
"ProofdExec: setting: %s", rootentity);
630 char *rootopensock =
new char[33];
631 memset(rootopensock, 0, 33);
632 snprintf(rootopensock, 33,
"ROOTOPENSOCK=%d", sockFd);
633 putenv(rootopensock);
635 ErrorInfo(
"ProofdExec: setting: %s", rootopensock);
637 char *roothomeauthrc =
new char[20];
638 memset(roothomeauthrc, 0, 20);
639 snprintf(roothomeauthrc, 20,
"ROOTHOMEAUTHRC=%s",
gReadHomeAuthrc.c_str());
640 putenv(roothomeauthrc);
642 ErrorInfo(
"ProofdExec: setting: %s", roothomeauthrc);
646 char *shmidcred =
new char[25];
647 memset(shmidcred, 0, 25);
648 snprintf(shmidcred, 25,
"ROOTSHMIDCRED=%d", RpdGetShmIdCred());
651 ErrorInfo(
"ProofdExec: setting: %s", shmidcred);
656 argvv[0] = (
char *)arg0.c_str();
657 argvv[1] = (
char *)(
gMaster ?
"proofserv" :
"proofslave");
661 char *rootsys =
new char[9+
gConfDir.length()];
662 memset(rootsys, 0, 9 +
gConfDir.length());
666 ErrorInfo(
"ProofdExec: setting: %s", rootsys);
669 char *oldpath, *ldpath;
670 # if defined(__hpux) || defined(_HIUX_SOURCE)
671 if ((oldpath = getenv(
"SHLIB_PATH")) && strlen(oldpath) > 0) {
672 ldpath =
new char[32+
gConfDir.length()+strlen(oldpath)];
673 memset(ldpath, 0, 32+
gConfDir.length()+strlen(oldpath));
674 snprintf(ldpath, 32+
gConfDir.length()+strlen(oldpath),
675 "SHLIB_PATH=%s/lib:%s",
gConfDir.c_str(), oldpath);
677 ldpath =
new char[32+
gConfDir.length()];
678 memset(ldpath, 0, 32+
gConfDir.length());
679 snprintf(ldpath, 32+
gConfDir.length(),
"SHLIB_PATH=%s/lib",
gConfDir.c_str());
682 if ((oldpath = getenv(
"LIBPATH")) && strlen(oldpath) > 0) {
683 ldpath =
new char[32+
gConfDir.length()+strlen(oldpath)];
684 memset(ldpath, 0, 32+
gConfDir.length()+strlen(oldpath));
685 snprintf(ldpath, 32+
gConfDir.length()+strlen(oldpath),
686 "LIBPATH=%s/lib:%s",
gConfDir.c_str(), oldpath);
688 ldpath =
new char[32+
gConfDir.length()];
689 memset(ldpath, 0, 32+
gConfDir.length());
692 # elif defined(__APPLE__)
693 if ((oldpath = getenv(
"DYLD_LIBRARY_PATH")) && strlen(oldpath) > 0) {
694 ldpath =
new char[32+
gConfDir.length()+strlen(oldpath)];
695 memset(ldpath, 0, 32+
gConfDir.length()+strlen(oldpath));
696 snprintf(ldpath, 32+
gConfDir.length()+strlen(oldpath),
697 "DYLD_LIBRARY_PATH=%s/lib:%s",
gConfDir.c_str(), oldpath);
699 ldpath =
new char[32+
gConfDir.length()];
700 memset(ldpath, 0, 32+
gConfDir.length());
701 snprintf(ldpath, 32+
gConfDir.length(),
"DYLD_LIBRARY_PATH=%s/lib",
gConfDir.c_str());
704 if ((oldpath = getenv(
"LD_LIBRARY_PATH")) && strlen(oldpath) > 0) {
705 ldpath =
new char[32+
gConfDir.length()+strlen(oldpath)];
706 memset(ldpath, 0, 32+
gConfDir.length()+strlen(oldpath));
707 snprintf(ldpath, 32+
gConfDir.length()+strlen(oldpath),
708 "LD_LIBRARY_PATH=%s/lib:%s",
gConfDir.c_str(), oldpath);
710 ldpath =
new char[32+
gConfDir.length()];
711 memset(ldpath, 0, 32+
gConfDir.length());
712 snprintf(ldpath, 32+
gConfDir.length(),
"LD_LIBRARY_PATH=%s/lib",
gConfDir.c_str());
717 ErrorInfo(
"ProofdExec: setting: %s", ldpath);
727 authrc =
new char[15+
gAuthrc.length()];
728 memset(authrc, 0, 15 +
gAuthrc.length());
729 snprintf(authrc, 15+
gAuthrc.length(),
"ROOTAUTHRC=%s",
gAuthrc.c_str());
732 ErrorInfo(
"ProofdExec: setting: %s", authrc);
736 char *keyfile =
new char[15+strlen(RpdGetKeyRoot())];
737 memset(keyfile, 0, 15+strlen(RpdGetKeyRoot()));
738 snprintf(keyfile, 15+strlen(RpdGetKeyRoot()),
"ROOTKEYFILE=%s",RpdGetKeyRoot());
741 ErrorInfo(
"ProofdExec: setting: %s", keyfile);
744 ErrorInfo(
"ProofdExec: execv(%s, %s)", argvv[0], argvv[1]);
747 execv(arg0.c_str(), argvv);
750 msg =
"Cannot start PROOF server --- make sure " + arg0 +
" exists!";
759 fprintf(stderr,
"\nUsage: %s [options] [rootsys-dir]\n", name);
760 fprintf(stderr,
"\nOptions:\n");
761 fprintf(stderr,
"\t-A [<rootauthrc>] Use $HOME/.rootauthrc or specified file\n");
762 fprintf(stderr,
"\t (see documentation)\n");
763 fprintf(stderr,
"\t-b tcpwindowsize Specify the tcp window size in bytes\n");
765 fprintf(stderr,
"\t-C hostcertfile Specify the location of the Globus host certificate\n");
767 fprintf(stderr,
"\t-d level set debug level [0..3]\n");
768 fprintf(stderr,
"\t-D rootdaemonrc Use alternate rootdaemonrc file\n");
769 fprintf(stderr,
"\t (see documentation)\n");
770 fprintf(stderr,
"\t-E Ignored for backward compatibility\n");
771 fprintf(stderr,
"\t-f Run in foreground\n");
773 fprintf(stderr,
"\t-G gridmapfile Specify the location of th Globus gridmap\n");
775 fprintf(stderr,
"\t-i Running from inetd\n");
776 fprintf(stderr,
"\t-noauth Do not require client authentication\n");
777 fprintf(stderr,
"\t-p port# Specify a different port to listen on\n");
778 fprintf(stderr,
"\t-s sshd_port# Specify the port for the sshd daemon\n");
780 fprintf(stderr,
"\t-S keytabfile Use an alternate keytab file\n");
782 fprintf(stderr,
"\t-T <tmpdir> Use an alternate temp dir\n");
783 fprintf(stderr,
"\t-w Do not check /etc/hosts.equiv and $HOME/.rhosts\n");
790 int main(
int argc,
char **argv)
793 int checkhostsequiv = 1;
794 int tcpwindowsize = 65535;
798 int reuseallow = 0x1F;
799 int foregroundflag = 0;
800 std::string altSRPpass =
"";
801 std::string daemonrc =
"";
802 std::string rootetcdir =
"";
804 std::string gridmap =
"";
805 std::string hostcertconf =
"";
807 char *progname = argv[0];
822 for (i = 1; i < argc; i++) {
823 if (!strncmp(argv[i],
"-f",2))
825 if (!strncmp(argv[i],
"-i",2))
828 if (foregroundflag) {
829 if (isatty(0) && isatty(1)) {
831 ErrorInfo(
"main: running in foreground mode:"
832 " sending output to stderr");
842 while (--argc > 0 && (*++argv)[0] ==
'-')
843 for (s = argv[0]+1; *s != 0; s++)
850 if((*(argv+1)) && (*(argv+1))[0] !=
'-') {
851 gAuthrc = std::string(*(argv+1));
853 if (stat(
gAuthrc.c_str(),&st) == -1 || !S_ISREG(st.st_mode)) {
869 tcpwindowsize = atoi(*++argv);
875 " certificates file location");
877 hostcertconf = std::string(*++argv);
890 " for the file defining access rules");
892 daemonrc = std::string(*++argv);
897 " - ignored (see proofd/src/proofd.cxx for"
898 " additional details)");
913 gridmap = std::string(*++argv);
921 if (foregroundflag) {
928 if (!strncmp(argv[0]+1,
"noauth",6)) {
939 port1 = strtol(*++argv, &p, 10);
942 port2 = strtol(p, &p, 10);
943 }
else if (*p ==
'\0')
945 if (*p !=
'\0' || port2 < port1 || port2 < 0) {
956 altSRPpass = std::string(*++argv);
964 reuseallow = strtol(*++argv, (
char **)0, 16);
970 " number for the sshd daemon");
972 sshdport = atoi(*++argv);
979 RpdSetKeytabFile((
const char *)(*++argv));
985 " temporary files [/usr/tmp]");
987 gTmpDir = std::string(*++argv);
995 if (!foregroundflag) fprintf(stderr,
"\nUnknown command line option: %c\n", *s);
996 Error(0, -1,
"unknown command line option: %c", *s);
1003 if (access(
gTmpDir.c_str(), W_OK) == -1)
1011 if (getenv(
"ROOTSYS")) {
1014 ErrorInfo(
"main: no config directory specified using ROOTSYS (%s)",
1027 rootetcdir= ROOTETCDIR;
1035 std::string arg0 = std::string(
gRootBinDir).append(
"/proofserv");
1036 if (access(arg0.c_str(), X_OK) == -1) {
1037 Error(
ErrFatal,-1,
"main: incorrect config directory specified (%s)",
1048 if (!rootetcdir.length())
1049 rootetcdir = std::string(
gConfDir).append(
"/etc");
1051 if (rootetcdir.length()) {
1052 char *tmp =
new char[15 + rootetcdir.length()];
1053 snprintf(tmp, 15 + rootetcdir.length(),
"ROOTETCDIR=%s", rootetcdir.c_str());
1058 if (daemonrc.length()) {
1059 char *tmp =
new char[15+daemonrc.length()];
1060 snprintf(tmp, 15+daemonrc.length(),
"ROOTDAEMONRC=%s", daemonrc.c_str());
1065 if (gridmap.length()) {
1066 char *tmp =
new char[15+gridmap.length()];
1067 snprintf(tmp, 15+gridmap.length(),
"GRIDMAP=%s", gridmap.c_str());
1071 if (hostcertconf.length()) {
1072 char *tmp =
new char[15+hostcertconf.length()];
1073 snprintf(tmp, 15+hostcertconf.length(),
"ROOTHOSTCERT=%s", hostcertconf.c_str());
1079 int proofdparentid = -1;
1081 proofdparentid = getpid();
1083 proofdparentid = getppid();
1086 unsigned int options = kDMN_RQAUTH | kDMN_HOSTEQ | kDMN_SYSLOG ;
1089 options &= ~kDMN_RQAUTH;
1090 if (!checkhostsequiv)
1091 options &= ~kDMN_HOSTEQ;
1093 options &= ~kDMN_SYSLOG;
1095 reuseallow, sshdport,
1096 gTmpDir.c_str(),altSRPpass.c_str(),2);
1100 Error(
Err, -1,
"proofd: unable to generate local RSA keys");
1109 if (!foregroundflag)
1112 NetInit(
gService, port1, port2, tcpwindowsize);
1129 Error(
ErrFatal, -1,
"proofd: failure initializing session");
int GetErrno()
return errno
static std::string gConfDir
void Err(int level, const char *msg, int size)
Namespace for new ROOT classes and functions.
void ErrFatal(int level, const char *msg, int size)
void Usage(const char *name, int rc)
int NetGetSockFd()
return open socket descriptor
const char * RerouteUser()
Look if user should be rerouted to another server node.
int NetRecvRaw(void *buf, int len)
Receive a buffer of maximum len bytes.
void ErrorInfo(const char *va_(fmt),...)
Formats a string in a circular formatting buffer and prints the string.
static void ProofdTerm(int)
Termination upon receipt of a SIGTERM or SIGINT.
int NetRecv(char *msg, int max)
Receive a string of maximum length max.
void RpdInit(EService serv, int pid, int sproto, unsigned int opts, int rumsk, int sshp, const char *tmpd, const char *asrpp, int login=0)
void RpdSetErrorHandler(ErrorHandler_t Err, ErrorHandler_t Sys, ErrorHandler_t Fatal)
void RpdAuthCleanup(const char *sstr, int opt)
static std::string gReadHomeAuthrc
int RpdProofGetAuthSetup(char **abuf)
Receive buffer for final setup of authentication related stuff This is base 64 string to decoded by p...
void ResetErrno()
reset errno
static std::string gRootBinDir
int NetSend(int code, EMessageTypes kind)
Send integer. Message will be of type "kind".
void ErrSys(int level, const char *msg, int size)
static std::string gTmpDir
int main(int argc, char **argv)
void NetGetRemoteHost(std::string &openhost)
Return name of connected host.
void ProofdExec()
Authenticate the user and exec the proofserv program.
static std::string gAuthrc
static std::string gRpdAuthTab
void NetClose()
Empty call, for consistency.
static std::string gOpenHost
void ErrorInit(const char *ident)
void Perror(char *buf, int size)
Return in buf the message belonging to errno.
int RpdInitSession(int, std::string &, int &, int &, int &, std::string &)
void Error(ErrorHandler_t func, int code, const char *va_(fmt),...)
Write error message and call a handler, if required.