47#define kMAXPATHLEN 4096 
   49int assertdir(
const std::string &path, uid_t u, gid_t 
g, 
unsigned int mode);
 
   50int changeown(
const std::string &path, uid_t u, gid_t 
g);
 
   52int loginuser(
const std::string &home, 
const std::string &user, uid_t u, gid_t 
g);
 
   53int mvfile(
const std::string &from, 
const std::string &to, uid_t u, gid_t 
g, 
unsigned int mode);
 
   54int completercfile(
const std::string &rcfile, 
const std::string &sessdir,
 
   55                   const std::string &stag, 
const std::string &adminpath);
 
   57                  const std::string &creds, 
const std::string &dsrcs,
 
   58                  const std::string &ddir, 
const std::string &ddiro,
 
   59                  const std::string &ord, 
const std::string &stag);
 
   61                    const std::string &logfile, 
const std::string &rcfile);
 
   74   va_start(ap,
va_(fmt));
 
   75   vsnprintf(buf, 
sizeof(buf), fmt, ap);
 
   79      fprintf(
gLogger, 
"proofexecv: %s\n", buf);
 
   81      fprintf(stderr, 
"proofexecv: %s\n", buf);
 
   89int main(
int argc, 
char **argv)
 
   94      Info(
"argc=%d: at least 2 additional argument (the process type and debug level) are required - exit",
 
   98   if ((
gType = atoi(argv[1])) < 0) {
 
   99      Info(
"ERROR: invalid process type %d (must be > 0) - exit", 
gType);
 
  108   } 
else if (
gType == 20) {
 
  110      Info(
"ERROR: 'rootd' has been removed from ROOT");
 
  113      Info(
"ERROR: process type %d not yet implemented", 
gType);
 
  127      Info(
"argc=%d: at least 5 additional arguments required - exit", argc);
 
  145   std::string errlog(argv[6]);
 
  146   if (!(
gLogger = fopen(errlog.c_str(), 
"a"))) {
 
  147      Info(
"FATAL: could not open '%s' for error logging - errno: %d",
 
  148           errlog.c_str(), (
int) errno);
 
  154   snprintf(spid, 20, 
"%d", (
int)getpid());
 
  157   std::string user = argv[3];
 
  158   struct passwd *pw = getpwnam(user.c_str());
 
  160      Info(
"ERROR: could noy get identity info for '%s' - errno: %d", user.c_str(), (
int) errno);
 
  166   std::string::size_type loc = 0;
 
  170   std::string sessdir(argv[4]), logfile(argv[4]), tenvfile, trcfile;
 
  173      if ((loc = sessdir.rfind(
'/')) != std::string::npos) sessdir.erase(loc, std::string::npos);
 
  178      if ((loc = sessdir.rfind(
'/')) != std::string::npos) sessdir.erase(loc, std::string::npos);
 
  180   if ((loc = tenvfile.rfind(
"<pid>")) != std::string::npos) tenvfile.erase(loc, std::string::npos);
 
  183   trcfile += 
".rootrc";
 
  186   if ((loc = sessdir.find(
"<pid>")) != std::string::npos) sessdir.replace(loc, 5, spid);
 
  187   if (
assertdir(sessdir, uid, gid, 0755) != 0) {
 
  188      Info(
"ERROR: could not assert dir '%s'", sessdir.c_str());
 
  191   Info(
"session dir: %s", sessdir.c_str());
 
  194   while ((loc = logfile.find(
"<pid>")) != std::string::npos) { logfile.replace(loc, 5, spid); }
 
  195   std::string stag(logfile), envfile(logfile), userdir(logfile), rcfile(logfile);
 
  201   if (
assertdir(userdir, uid, gid, 0755) != 0) {
 
  202      Info(
"ERROR: could not assert dir '%s'", userdir.c_str());
 
  207   if ((loc = stag.rfind(
'/')) != std::string::npos) stag.erase(0, loc);
 
  208   if ((loc = stag.find(
'-')) != std::string::npos) loc = stag.find(
'-', loc+1);
 
  209   if (loc != std::string::npos) stag.erase(0, loc+1);
 
  210   Info(
"session tag: %s", stag.c_str());
 
  213   std::string sockpath = argv[5];
 
  214   rpdunix *uconn = 
new rpdunix(sockpath.c_str());
 
  215   if (!uconn || (uconn && !uconn->isvalid(0))) {
 
  216      Info(
"ERROR: failure calling back parent on '%s'", sockpath.c_str());
 
  217      if (uconn) 
delete uconn;
 
  223   if ((rcc = uconn->send((
int) getpid())) != 0) {
 
  224      Info(
"ERROR: failure sending pid to parent (errno: %d)", -rcc);
 
  231   if ((rcc = uconn->recv(msg)) != 0) {
 
  232      Info(
"ERROR: failure receiving admin path and executable from parent (errno: %d)", -rcc);
 
  237   std::string srvadmin, adminpath, pspath;
 
  238   msg >> srvadmin >> adminpath >> pspath >> ppid;
 
  239   Info(
"srv admin path: %s", srvadmin.c_str());
 
  240   Info(
"partial admin path: %s", adminpath.c_str());
 
  241   Info(
"executable: %s", pspath.c_str());
 
  242   Info(
"parent pid: %d", ppid);
 
  246   if ((rcc = uconn->recv(msg)) != 0) {
 
  247      Info(
"ERROR: failure receiving information about dataset and data dir(s) from parent (errno: %d)", -rcc);
 
  252   std::string 
group, creds, ord, datadir, ddiropts, datasetsrcs;
 
  253   msg >> euid >> 
group >> creds >> ord >> datadir >> ddiropts >> datasetsrcs;
 
  254   Info(
"euid at startup: %d", euid);
 
  255   Info(
"group, ord: %s, %s", 
group.c_str(), ord.c_str());
 
  256   Info(
"datadir: %s", datadir.c_str());
 
  257   Info(
"datasetsrcs: %s", datasetsrcs.c_str());
 
  262      Info(
"ERROR: problems setting relevant user ownerships");
 
  268   if (
mvfile(tenvfile, envfile, uid, gid, 0644) != 0) {
 
  269      Info(
"ERROR: problems renaming '%s' to '%s' (errno: %d)",
 
  270           tenvfile.c_str(), envfile.c_str(), errno);
 
  275   if (
mvfile(trcfile, rcfile, uid, gid, 0644) != 0) {
 
  276      Info(
"ERROR: problems renaming '%s' to '%s' (errno: %d)",
 
  277           trcfile.c_str(), rcfile.c_str(), errno);
 
  284      Info(
"ERROR: problems completing '%s'", rcfile.c_str());
 
  290      Info(
"ERROR: problems setting environment from '%s'", envfile.c_str());
 
  297      Info(
"ERROR: problems exporting file descriptor");
 
  304   if (
loginuser(userdir, user, uid, gid) != 0) {
 
  305      Info(
"ERROR: problems login user '%s' in", user.c_str());
 
  312      Info(
"ERROR: problems redirecting logs to '%s'", logfile.c_str());
 
  318   char *argvv[6] = {0};
 
  321   if (adminpath.length() > 0) {
 
  323      int len = srvadmin.length() + strlen(
"xpdpath:") + 1;
 
  324      sxpd = 
new char[len];
 
  325      snprintf(sxpd, len, 
"xpdpath:%s", adminpath.c_str());
 
  337   argvv[0] = (
char *) pspath.c_str();
 
  338   argvv[1] = (
char *)((
gType == 0) ? 
"proofslave" : 
"proofserv");
 
  339   argvv[2] = (
char *)
"xpd";
 
  340   argvv[3] = (
char *)sxpd;
 
  341   argvv[4] = (
char *)slog;
 
  347   sigaddset(&myset, SIGUSR1);
 
  348   sigaddset(&myset, SIGUSR2);
 
  349   pthread_sigmask(SIG_UNBLOCK, &myset, 0);
 
  351   Info(
"%d: uid: %d, euid: %d", (
int)getpid(), getuid(), geteuid());
 
  352   Info(
"argvv: '%s' '%s' '%s' '%s' '%s'", argvv[0],  argvv[1], argvv[2], argvv[3],  argvv[4]);
 
  355   execv(pspath.c_str(), argvv);
 
  358   Info(
"ERROR: returned from execv: bad, bad sign !!!");
 
  365int loginuser(
const std::string &home, 
const std::string &user, uid_t uid, gid_t gid)
 
  367   if (chdir(home.c_str()) != 0) {
 
  368      Info(
"loginuser: ERROR: can't change directory to %s, euid: %d, uid: %d; errno: %d",
 
  369           home.c_str(), geteuid(), getuid(), errno);
 
  374   size_t len = home.length() + 8;
 
  375   char *
h = 
new char[len];
 
  376   snprintf(
h, len, 
"HOME=%s", home.c_str());
 
  381   char *u = 
new char[len];
 
  382   snprintf(u, len, 
"USER=%s", user.c_str());
 
  384   if (
gDebug > 0) 
Info(
"loginuser: set '%s'", u);
 
  388   if (geteuid() != uid) {
 
  389      rpdprivguard pguard((uid_t)0, (gid_t)0);
 
  390      if (rpdbadpguard(pguard, uid)) {
 
  391         Info(
"loginuser: ERROR: could not get required privileges");
 
  394      initgroups(user.c_str(), gid);
 
  399      Info(
"loginuser: acquiring target user identity (%d,%d)", uid, gid);
 
  400   if (rpdpriv::changeperm(uid, gid) != 0) {
 
  401      Info(
"loginuser: ERROR: can't acquire '%s' identity", user.c_str());
 
  414int assertdir(
const std::string &path, uid_t u, gid_t 
g, 
unsigned int mode)
 
  416   if (path.length() <= 0) 
return -1;
 
  418   rpdprivguard pguard((uid_t)0, (gid_t)0);
 
  419   if (rpdbadpguard(pguard, u)) {
 
  420      Info(
"assertdir: ERROR: could not get privileges (errno: %d)", errno);
 
  425   if (mkdir(path.c_str(), mode) != 0 && (errno != EEXIST)) {
 
  426      Info(
"assertdir: ERROR: unable to create path: %s (errno: %d)", path.c_str(), errno);
 
  430   if (chown(path.c_str(), u, 
g) == -1) {
 
  431      Info(
"assertdir: ERROR: unable to set ownership on path: %s (errno: %d)", path.c_str(), errno);
 
  444int mvfile(
const std::string &from, 
const std::string &to, uid_t u, gid_t 
g, 
unsigned int mode)
 
  446   if (from.length() <= 0 || to.length() <= 0) 
return -1;
 
  448   rpdprivguard pguard((uid_t)0, (gid_t)0);
 
  449   if (rpdbadpguard(pguard, u)) {
 
  450      Info(
"mvfile: ERROR: could not get privileges (errno: %d)", errno);
 
  455   if (rename(from.c_str(), to.c_str()) != 0) {
 
  456      Info(
"mvfile: ERROR: unable to rename '%s' to '%s' (errno: %d)", from.c_str(), to.c_str(), errno);
 
  461   if (chmod(to.c_str(), mode) == -1) {
 
  462      Info(
"mvfile: ERROR: unable to set mode %o on path: %s (errno: %d)", mode, to.c_str(), errno);
 
  467   if (chown(to.c_str(), u, 
g) == -1) {
 
  468      Info(
"mvfile: ERROR: unable to set ownership on path: %s (errno: %d)", to.c_str(), errno);
 
  480                   const std::string &stag, 
const std::string &adminpath)
 
  482   FILE *frc = fopen(rcfile.c_str(), 
"a");
 
  484      Info(
"completercfile: ERROR: unable to open rc file: '%s' (errno: %d)", rcfile.c_str(), errno);
 
  488   fprintf(frc, 
"# The session working dir\n");
 
  489   fprintf(frc, 
"ProofServ.SessionDir: %s\n", sessdir.c_str());
 
  491   fprintf(frc, 
"# Session tag\n");
 
  492   fprintf(frc, 
"ProofServ.SessionTag: %s\n", stag.c_str());
 
  494   fprintf(frc, 
"# Admin path\n");
 
  495   fprintf(frc, 
"ProofServ.AdminPath: %s%d.status\n", adminpath.c_str(), (
int)getpid());
 
  507                    const std::string &logfile, 
const std::string &rcfile)
 
  509   if (envfile.length() <= 0) 
return -1;
 
  514   len = logfile.length() + strlen(
"ROOTPROOFLOGFILE") + 4;
 
  515   h = 
new char[len + 1];
 
  516   snprintf(
h, len + 1, 
"ROOTPROOFLOGFILE=%s", logfile.c_str());
 
  519      Info(
"setproofservenv: set '%s'", 
h);
 
  521   len = rcfile.length() + strlen(
"ROOTRCFILE") + 4;
 
  522   h = 
new char[len + 1];
 
  523   snprintf(
h, len + 1, 
"ROOTRCFILE=%s", rcfile.c_str());
 
  526      Info(
"setproofservenv: set '%s'", 
h);
 
  528   std::fstream fin(envfile.c_str(), std::ios::in);
 
  530      Info(
"setproofservenv: ERROR: unable to open env file: %s (errno: %d)", envfile.c_str(), errno);
 
  536      std::getline(fin, 
line);
 
  538      if (
line.length() > 0) {
 
  539         h = 
new char[
line.length() + 1];
 
  543            Info(
"setproofservenv: set '%s'", 
h);
 
  560   if (!conn || (conn && !conn->isvalid(0))) {
 
  561      Info(
"exportsock: ERROR: connection is %s", (conn ? 
"invalid" : 
"undefined"));
 
  566   int d = conn->exportfd();
 
  569   if (
d == 0 || 
d == 1 || 
d == 2) {
 
  572      while (natt > 0 && (fd = dup(
d)) <= 2) {
 
  573         if (fd >= 0 && fd != 
d) 
close(fd);
 
  577      if (natt <= 0 && fd <= 2) {
 
  578         Info(
"exportsock: ERROR: no free filedescriptor!");
 
  590   char *rootopensock = 
new char[33];
 
  591   snprintf(rootopensock, 33, 
"ROOTOPENSOCK=%d", 
d);
 
  592   putenv(rootopensock);
 
  605      Info(
"redirectoutput: enter: %s", logfile.c_str());
 
  607   if (logfile.length() <= 0) {
 
  608      Info(
"redirectoutput: ERROR:  logfile path undefined");
 
  613      Info(
"redirectoutput: reopen %s", logfile.c_str());
 
  614   FILE *flog = freopen(logfile.c_str(), 
"a", stdout);
 
  616      Info(
"redirectoutput: ERROR:  could not freopen stdout (errno: %d)", errno);
 
  621      Info(
"redirectoutput: dup2 ...");
 
  622   if ((dup2(fileno(stdout), fileno(stderr))) < 0) {
 
  623      Info(
"redirectoutput: ERROR:  could not redirect stderr (errno: %d)", errno);
 
  632   int len = strlen(
"ROOTPROOFDONOTREDIR=2");
 
  633   char *notredir = 
new char[len + 1];
 
  634   snprintf(notredir, len+1, 
"ROOTPROOFDONOTREDIR=2");
 
  638      Info(
"redirectoutput: done!");
 
  648                  const std::string &creds, 
const std::string &dsrcs,
 
  649                  const std::string &ddir, 
const std::string &ddiro,
 
  650                  const std::string &ord, 
const std::string &stag)
 
  653   struct passwd *pwad, *pwus;
 
  654   if (!(pwad = getpwuid(euid))) {
 
  655      Info(
"setownerships: ERROR: problems getting 'struct passwd' for" 
  656                                " uid: %d (errno: %d)", euid, (
int)errno);
 
  659   if (!(pwus = getpwnam(
us.c_str()))) {
 
  660      Info(
"setownerships: ERROR: problems getting 'struct passwd' for" 
  661                                " user: '%s' (errno: %d)", 
us.c_str(), (
int)errno);
 
  667   if (dsrcs.length() > 0) {
 
  668      std::string dsrc(dsrcs);
 
  669      std::string::size_type loc = dsrcs.find(
',', 0);
 
  671         if (loc != std::string::npos) dsrc.erase(loc, std::string::npos);
 
  672         if (dsrc.length() > 0) {
 
  679                  Info(
"setownerships: ERROR: problems asserting '%s' in mode 0755" 
  680                                     " (errno: %d)", 
d.c_str(), (
int)errno);
 
  683               Info(
"setownerships: ERROR: problems asserting '%s' in mode 0777" 
  684                                  " (errno: %d)", 
d.c_str(), (
int)errno);
 
  687         dsrc.assign(dsrcs, loc + 1, dsrcs.length() - loc);
 
  689      } 
while ((loc = dsrcs.find(
',', loc)) != std::string::npos);
 
  694   if (ddir.length() > 0 && ord.length() > 0 && stag.length() > 0) {
 
  695      std::string dgr(ddir);
 
  696      dgr += 
"/"; dgr += 
gr;
 
  699         unsigned int mode = 0755;
 
  700         if (ddiro.find(
'g') != std::string::npos) mode = 0775;
 
  701         if (ddiro.find(
'a') != std::string::npos ||
 
  702             ddiro.find(
'o') != std::string::npos) mode = 0777;
 
  703         std::string dus(dgr);
 
  704         dus += 
"/"; dus += 
us;
 
  706            dus += 
"/"; dus += ord;
 
  708               dus += 
"/"; dus += stag;
 
  713            Info(
"setownerships: ERROR: problems asserting '%s' in mode %o" 
  714                               " (errno: %d)", dus.c_str(), mode, (
int)errno);
 
  716         Info(
"setownerships: ERROR: problems asserting '%s' in mode 0777" 
  717                              " (errno: %d)", dgr.c_str(), (
int)errno);
 
  722   if (creds.length() > 0) {
 
  724         Info(
"setownerships: ERROR: problems changing owenership of '%s'", creds.c_str());
 
  740   if (path.length() <= 0) 
return -1;
 
  743   DIR *dir = opendir(path.c_str());
 
  746      std::string proot(path);
 
  747      if (!(proot.rfind(
'/') !=  proot.length() - 1)) proot += 
"/";
 
  749      struct dirent *ent = 0;
 
  750      while ((ent = readdir(dir))) {
 
  751         if (ent->d_name[0] == 
'.' || !strcmp(ent->d_name, 
"..")) 
continue;
 
  752         std::string fn(proot);
 
  757            Info(
"changeown: ERROR: problems changing recursively ownership of '%s'",
 
  768      if (errno != 0 && (errno != ENOTDIR)) {
 
  769         Info(
"changeown: ERROR: problems opening '%s' (errno: %d)",
 
  770              path.c_str(), (
int)errno);
 
  774      rpdprivguard pguard((uid_t)0, (gid_t)0);
 
  775      if (rpdbadpguard(pguard, u)) {
 
  776         Info(
"changeown: ERROR: could not get privileges (errno: %d)", errno);
 
  780      if (chown(path.c_str(), u, 
g) == -1) {
 
  781         Info(
"changeown: ERROR: cannot set user ownership on path '%s' (errno: %d)",
 
  782               path.c_str(), errno);
 
static constexpr double us
 
int exportsock(rpdunix *conn)
Export the descriptor of 'conn' so that it can used in the execv application.
 
int main(int argc, char **argv)
Program executed via system starting proofserv instances.
 
int setownerships(int euid, const std::string &us, const std::string &gr, const std::string &creds, const std::string &dsrcs, const std::string &ddir, const std::string &ddiro, const std::string &ord, const std::string &stag)
Set user ownerships on some critical files or directories.
 
int completercfile(const std::string &rcfile, const std::string &sessdir, const std::string &stag, const std::string &adminpath)
Finalize the rc file with the missing pieces.
 
int setproofservenv(const std::string &envfile, const std::string &logfile, const std::string &rcfile)
Initialize the environment following the content of 'envfile'.
 
int redirectoutput(const std::string &logfile)
Redirect stdout to 'logfile' On success return 0.
 
int assertdir(const std::string &path, uid_t u, gid_t g, unsigned int mode)
Make sure that 'path' exists, it is owned by the entity described by {u,g} and its mode is 'mode'.
 
int mvfile(const std::string &from, const std::string &to, uid_t u, gid_t g, unsigned int mode)
Move file form 'from' to 'to', making sure that it is owned by the entity described by {u,...
 
int loginuser(const std::string &home, const std::string &user, uid_t u, gid_t g)
Login the user in its space.
 
void start_ps(int argc, char **argv)
Process a request to start a proofserv process.
 
int changeown(const std::string &path, uid_t u, gid_t g)
Change the ownership of 'path' to the entity described by {u,g}.
 
void Info(const char *va_(fmt),...)
Write info message to syslog.