Logo Search packages:      
Sourcecode: bayonne version File versions  Download package

wrapper.cpp

// Copyright (C) 2000-2001 Open Source Telecom Corporation.
//  
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
// 
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
// 
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software 
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.

#ifdef  __FreeBSD__
#define getopt(a, b, c) getopt()
#include <unistd.h>
#undef getopt
#endif

#include <cc++/config.h>
extern "C" {
#include <getopt.h>
#include <sys/wait.h>
#include <pwd.h>
};
#include "server.h"

#ifdef      CCXX_NAMESPACES
namespace ost {
using namespace std;
#endif

static bool root = false;
static char *permit = NULL;

#ifndef     HAVE_SETENV
static void setenv(char *name, const char *value, int overwrite)
{
      char strbuf[256];

      snprintf(strbuf, sizeof(strbuf), "%s=%s", name, value);
      putenv(strbuf);
}
#endif

class KeyPolicies : public Keydata
{
public:
      KeyPolicies();
} keypolicies;

class KeyDriver : public Keydata
{
public:
      KeyDriver();
      const char *getDriverName(void);
} keydriver;

class KeyWrapper : public Keydata
{
public:
      KeyWrapper();
} keywrapper;

KeyPaths keypaths;

KeyPolicies::KeyPolicies() :
Keydata("/bayonne/trunks")
{
};

KeyDriver::KeyDriver() :
Keydata("/bayonne/plugins")
{
};

KeyWrapper::KeyWrapper() :
Keydata("/bayonne/wrapper")
{
};


KeyServer::KeyServer() :
Keydata("/bayonne/server")
{
      static Keydata::Define defkeys[] = {
            {"user", "bayonne"},
            {"token", "&"},
            {"nodes", "1"},
            {NULL, NULL}};

      char *cp;
      char prefix[256];
      struct passwd *pwd;

      if(!getLast("node"))
      {
            gethostname(prefix, sizeof(prefix) - 1);
            cp = strchr(prefix, '.');
            if(cp)
                  *cp = 0;
            setValue("node", prefix);
      }
      load(defkeys);

      uid = getuid();
      gid = getgid();

      if(!geteuid() && getuid())
      {
            root = true;
            if(getenv("CONFIG_KEYDATA"))
            {
                  slog(Slog::levelError) << "wrapper: suid: config redirect denied" << endl;
                  exit(-1);
            }
            pwd = getpwuid(uid);
            if(!pwd)
            {
                  slog(Slog::levelError) << "wrapper: suid: unknwon user" << endl;
                  exit(-1);
            }
            if(pwd->pw_uid == geteuid())
            {
                  root = false;
                  setuid(pwd->pw_uid);
                  setgid(pwd->pw_gid);
            }
      }

      if(root)
      {
            if(pwd)
                  permit = (char *)keywrapper.getLast(pwd->pw_name);
            else
                  permit = NULL;
            if(!permit)
            {
                  slog(Slog::levelError) << "wrapper: suid: " << pwd->pw_name << ": not permitted" << endl;
                  exit(-1);
            }
      }

      pwd = getpwnam(getLast("user"));
      if(pwd && !geteuid())
      {
            gid = pwd->pw_gid;
            uid = pwd->pw_uid;
            setenv("HOME", pwd->pw_dir, 1);
      }

      endpwent();
      strcpy(prefix, getenv("HOME"));
      strcat(prefix, "/.bayonne");
      altdir = strdup(prefix);
}

KeyPaths::KeyPaths() :
Keydata("/bayonne/paths")
{
        static Keydata::Define defpaths[] = {
        {"libpath", "/usr/lib/bayonne"},
        {"libexec", "/usr/libexec/bayonne"},
        {"tgipath", "/usr/libexec/bayonne:/bin:/usr/bin"},
        {"datafiles", "/var/lib/bayonne"},
        {"scripts", "/usr/share/aascripts"},
        {"prompts", "/usr/share/aaprompts"},
      {"wrappers", "/usr/share/aawrappers"},
        {"spool", "/var/spool/bayonne"},
        {"runfiles", "/var/run/bayonne"},
        {"cache", "/var/cache/bayonne"},
        {"config", "bayonne runtime configuration"},
        {NULL, NULL}};

      load(defpaths);

}

void KeyServer::setUid(void)
{
      setuid(uid);
      uid = getuid();
}

void KeyServer::setGid(void)
{
      setgid(gid);
      gid = getgid();
}

extern "C" int main(int argc, char **argv)
{
      static char *enva[] = {
            "SERVER_SOFTWARE",
            "SERVER_NAME",
            "GATEWAY_INTERFACE",
            "SERVER_PROTOCOL",
            "SERVER_PORT",
            "REQUEST_METHOD",
            "PATH_INFO",
            "PATH_TRANSLATED",
            "SCRIPT_NAME",
            "QUERY_STRING",
            "REMOTE_HOST",
            "REMOTE_ADDR",
            "AUTH_TYPE",
            "REMOTE_USER",
            "REMOTE_IDENT",
            "CONTENT_TYPE",
            "CONTENT_LENGTH",
            NULL};
      char **env = enva;
      char *interp = NULL;
      KeyServer keyserver;
      char buffer[256];
      const char *ev;
      char *cp;
      int fd, len;
      bool wrapper = true;
      char *execdir="BAYONNE_LIBEXEC";
      char *ssh[65];

      keyserver.setGid();
      keyserver.setUid();

      chdir(keypaths.getDatafiles());
      slog.open("bayonne", Slog::classDaemon);

      setenv("BAYONNE_SOFTWARE", "bayonne", 1);
      setenv("BAYONNE_POLICIES", keypolicies.getLast("groups"), 1);
      setenv("BAYONNE_PROTOCOL", "2.2", 1);
      setenv("BAYONNE_VERSION", VERPATH, 1);
      setenv("BAYONNE_PLATFORM", keydriver.getLast("driver"), 1);
      setenv("BAYONNE_TOKEN", keyserver.getLast("token"), 1);
      setenv("BAYONNE_NODE", keyserver.getLast("node"), 1);
      setenv("BAYONNE_CONFIG", ETC_PREFIX, 1);

      sprintf(buffer, "%s/.bayonne", getenv("HOME"));
      setenv("BAYONNE_CONTROL", buffer, 1);

      strcpy(buffer, keypaths.getRunfiles());
      strcat(buffer, "/bayonne.ctrl");
      if(canModify(buffer))
      {
            strcpy(buffer, keypaths.getRunfiles());
            strcat(buffer, "/bayonne");
            setenv("BAYONNE_CONTROL", buffer, 1);
      }

      cp = strchr(*argv, '/');
      if(cp)
            ++cp;
      else
            cp = *argv;

      if(argc < 2 && !stricmp(cp, "bayonne_wrapper"))
      {
            cout << "BAYONNE_SOFTWARE=bayonne" << endl;
            cout << "BAYONNE_POLICIES=" << getenv("BAYONNE_POLICIES") << endl;
            cout << "BAYONNE_PROTOCOL=" << getenv("BAYONNE_PROTOCOL") << endl;
            cout << "BAYONNE_VERSION=" << getenv("BAYONNE_VERSION") << endl;
            cout << "BAYONNE_PLATFORM=" << getenv("BAYONNE_PLATFORM") << endl;
            cout << "BAYONNE_TOKEN=" << getenv("BAYONNE_TOKEN") << endl;
            cout << "BAYONNE_CONFIG=" << getenv("BAYONNE_CONFIG") << endl;
            cout << "BAYONNE_CONTROL=" << getenv("BAYONNE_CONTROL") << endl;
            cout << "BAYONNE_NODE=" << getenv("BAYONNE_NODE") << endl;
            cout << "BAYONNE_HOME=" << getenv("HOME") << endl;
            exit(0);
      }

      if(argc > 1)
            ++argv;

      if(**argv == '-')
      {
            interp = *argv;
            ++interp;
            ++argv;
            cp = strchr(*argv, '/');
            if(*cp)
                  *argv = ++cp;
      }

      if(**argv == '+')
      {
            wrapper = false;
            ++*argv;
      }
      else if(!wrapper)
      {
            sprintf(buffer, "%s.ctrl", getenv("BAYONNE_CONTROL"));
            fd = open(buffer, O_WRONLY);
            if(fd < 0)
            {
                  slog(Slog::levelError) << "wrapper: " << buffer << ": cannot open fifo" << endl;
                  exit(-1);
            }
            dup2(fd, 1);
            close(fd);
      }

      if(!wrapper)
      {
            execdir="BAYONNE_LIBEXEC";
            setenv(execdir, keypaths.getLibexec(), 1);
            setenv("PATH", keypaths.getTgipath(), 1);
      }
      else
      {
            execdir="BAYONNE_WRAPPERS";
            setenv(execdir, keypaths.getWrappers(), 1);
            strcpy(buffer, keypaths.getWrappers());
            strcat(buffer, ":");
            strcat(buffer, getenv("PATH"));
            setenv("PATH", buffer, 1);
      }


      if(root)
      {
            cp = strtok(permit, ";:,\r\n \t");
            while(cp)
            {
                  if(!stricmp(cp, *argv))
                        break;
                  cp = strtok(NULL, ";:,\r\n \t");
            }
            if(!cp)
            {
                  slog(Slog::levelError) << "wrapper: suid: " << *argv << ": not permitted for this user" << endl;
                  exit(-1);
            }
            sprintf(buffer, "%s/%s", getenv(execdir), *argv);
            *argv = buffer;
            if(wrapper && !isDir(getenv(execdir)))
            {
                  ssh[0] = "ssh";
                  ssh[1] = getenv("BAYONNE_NODE");
                  argc = 1;

                  while(*env)
                  {
                        ev = getenv(*env);
                        if(ev)
                        {
                              len = strlen(ev) + strlen(*env) + 3;
                              cp = new char[len];
                              strcpy(cp, *env);
                              strcat(cp, "=");
                              strcat(cp, ev);
                              ssh[++argc] = cp;
                        }
                        ++env;
                  }

                  ssh[++argc] = "bayonne_wrapper";

                  if(interp)
                        ssh[++argc] = interp;

                  while(argc < 63 && ssh[argc])
                        ssh[++argc] = *(argv++);
                  ssh[argc] = NULL;
                  argv = ssh;
            }
      }
      if(interp)
      {
            --argv;
            *argv = interp;
      }
      execvp(*argv, argv);

      slog(Slog::levelError) << "wrapper: " << *argv << ": cannot execute" << endl;
      exit(-1);
}

#ifdef      CCXX_NAMESPACES
};
#endif

Generated by  Doxygen 1.6.0   Back to index