コード例 #1
0
ファイル: trq_auth_daemon.c プロジェクト: dhill12/test
int load_config(
    char **ip,
    int *t_port,
    int *d_port)
  {
  int rc = PBSE_NONE;
  char *tmp_name = pbs_default();
  /* Assume TORQUE_HOME = /var/spool/torque */
  /* /var/spool/torque/server_name */
  if (tmp_name == NULL)
    rc = PBSE_BADHOST;
  else
    {
    /* Currently this only display's the port for the trq server
     * from the lib_ifl.h file or server_name file (The same way
     * the client utilities determine the pbs_server port)
     */
    printf("hostname: %s\n", tmp_name);
    *ip = tmp_name;
    PBS_get_server(tmp_name, (unsigned int *)t_port);
    if (*t_port == 0)
      *t_port = PBS_BATCH_SERVICE_PORT;
    *d_port = TRQ_AUTHD_SERVICE_PORT;
    }
  return rc;
  }
コード例 #2
0
ファイル: pbsD_connect.c プロジェクト: ansonl/torque
void get_port_from_server_name_file(unsigned int *server_name_file_port)
  {
  char *the_server = pbs_default();

  if (the_server != NULL)
    {
    PBS_get_server(the_server, server_name_file_port);
    }
  }
コード例 #3
0
ファイル: trq_auth_daemon.c プロジェクト: msbritt/torque
/* Get the name of the active pbs_server */
int load_trqauthd_config(

  char **default_server_name,
  int   *t_port,
  char **trqauthd_unix_domain_port)

  {
  int rc = PBSE_NONE;
  char *tmp_name = NULL;
  int  unix_domain_len;

  tmp_name = pbs_default();

  if ((tmp_name == NULL) ||
      (tmp_name[0] == '\0'))
    rc = PBSE_BADHOST;
  else
    {
    /* Currently this only display's the port for the trq server
     * from the lib_ifl.h file or server_name file (The same way
     * the client utilities determine the pbs_server port)
     */
    printf("hostname: %s\n", tmp_name);
    *default_server_name = tmp_name;
    PBS_get_server(tmp_name, (unsigned int *)t_port);
    if (*t_port == 0)
      *t_port = PBS_BATCH_SERVICE_PORT;

    unix_domain_len = strlen(TRQAUTHD_SOCK_DIR);
    unix_domain_len += strlen(TRQAUTHD_SOCK_NAME) + 2; /* on for the "/" and one for zero termination*/
    *trqauthd_unix_domain_port = (char *)malloc(unix_domain_len);
    if (*trqauthd_unix_domain_port == NULL)
      {
      fprintf(stderr, "could not allocate memory for unix domain port");
      return(PBSE_MEM_MALLOC);
      }

    strcpy(*trqauthd_unix_domain_port, TRQAUTHD_SOCK_DIR);
    strcat(*trqauthd_unix_domain_port, "/");
    strcat(*trqauthd_unix_domain_port, TRQAUTHD_SOCK_NAME);
    set_active_pbs_server(tmp_name, *t_port);
    }

  return rc;
  }
コード例 #4
0
ファイル: pbsD_connect.c プロジェクト: ansonl/torque
int pbs_original_connect(

  char *server)  /* I (FORMAT:  NULL | '\0' | HOSTNAME | HOSTNAME:PORT )*/

  {
  struct sockaddr_in   server_addr;
  char                *if_name;
  struct addrinfo     *addr_info;
  int                  out;
  int                  i;
  int                  opt_value = 1;
  int                  rc = PBSE_NONE;
  int                  local_errno;

  struct sockaddr      preferred_addr; /* set if TRQ_IFNAME set in torque.cfg */
  struct passwd       *pw;
  int                  use_unixsock = 0;
  uid_t                pbs_current_uid;
  long                 sockflags;
  int                  retry = 1;

#ifdef ENABLE_UNIX_SOCKETS
  struct sockaddr_un  unserver_addr;
  char                hnamebuf[256];
#endif

  char               *ptr;

  memset(&server_addr, 0, sizeof(server_addr));

  /* Read the timeout from the environment */
  if ((ptr = getenv("PBSAPITIMEOUT")) != NULL)
    {
    pbs_tcp_timeout = strtol(ptr, NULL, 0);

    if (pbs_tcp_timeout <= 0)
      pbs_tcp_timeout = 300;

    if (pbs_tcp_timeout > 2)
      retry = 0;
    }
  else
    pbs_tcp_timeout = 300;

  /* reserve a connection state record */

  out = -1;

  for (i = 1;i < NCONNECTS;i++)
    {
    if (connection[i].ch_mutex == NULL)
      {
      connection[i].ch_mutex = (pthread_mutex_t *)calloc(1, sizeof(pthread_mutex_t));
      pthread_mutex_init(connection[i].ch_mutex,NULL);
      }

    pthread_mutex_lock(connection[i].ch_mutex);

    if (connection[i].ch_inuse == FALSE)
      {
      out = i;
      
      connection[out].ch_inuse  = TRUE;
      connection[out].ch_errno  = 0;
      connection[out].ch_socket = -1;
      connection[out].ch_errtxt = NULL;

      break;

      }

    pthread_mutex_unlock(connection[i].ch_mutex);
    }

  if (out < 0)
    {
    if (getenv("PBSDEBUG"))
      fprintf(stderr, "ALERT:  cannot locate free channel\n");

    /* FAILURE */
    /* no need to unlock mutex here - in this case no connection was found */

    return(PBSE_NOCONNECTS * -1);
    }

  /* get server host and port */

  server = PBS_get_server(server, &server_port);

  if (server == NULL)
    {
    connection[out].ch_inuse = FALSE;

    pthread_mutex_unlock(connection[out].ch_mutex);

    if (getenv("PBSDEBUG"))
      fprintf(stderr, "ALERT:  PBS_get_server() failed\n");

    rc = PBSE_NOSERVER * -1;
    goto cleanup_conn_lite;
    }

  /* determine who we are */

  pbs_current_uid = getuid();

  if ((pw = getpwuid(pbs_current_uid)) == NULL)
    {
    if (getenv("PBSDEBUG"))
      {
      fprintf(stderr, "ALERT:  cannot get password info for uid %ld\n",
              (long)pbs_current_uid);
      }

    rc = PBSE_NOSERVER * -1;
    goto cleanup_conn_lite;
    }

  snprintf(pbs_current_user, PBS_MAXUSER, "%s", pw->pw_name);

  pbs_server = server;    /* set for error messages from commands */


#ifdef ENABLE_UNIX_SOCKETS
  /* determine if we want to use unix domain socket */

  if (!strcmp(server, "localhost"))
    use_unixsock = 1;
  else if ((gethostname(hnamebuf, sizeof(hnamebuf) - 1) == 0) && !strcmp(hnamebuf, server))
    use_unixsock = 1;

  /* NOTE: if any part of using unix domain sockets fails,
   * we just cleanup and try again with inet sockets */

  /* get socket */

  if (use_unixsock)
    {
    connection[out].ch_socket = socket(AF_UNIX, SOCK_STREAM, 0);

    if (connection[out].ch_socket < 0)
      {
      if (getenv("PBSDEBUG"))
        {
        fprintf(stderr, "ERROR:  cannot create socket:  errno=%d (%s)\n",
                errno,
                strerror(errno));
        }

      connection[out].ch_inuse = FALSE;

      local_errno = PBSE_PROTOCOL;

      use_unixsock = 0;
      }
    }

  /* and connect... */

  if (use_unixsock)
    {
    unserver_addr.sun_family = AF_UNIX;
    strcpy(unserver_addr.sun_path, TSOCK_PATH);

    if (connect(
          connection[out].ch_socket,
          (struct sockaddr *)&unserver_addr,
          (strlen(unserver_addr.sun_path) + sizeof(unserver_addr.sun_family))) < 0)
      {
      close(connection[out].ch_socket);

      connection[out].ch_inuse = FALSE;
      local_errno = errno;

      if (getenv("PBSDEBUG"))
        {
        fprintf(stderr, "ERROR:  cannot connect to server, errno=%d (%s)\n",
                errno,
                strerror(errno));
        }

      use_unixsock = 0;  /* will try again with inet socket */
      }
    }

  if (use_unixsock)
    {
    if (!send_unix_creds(connection[out].ch_socket))
      {
      if (getenv("PBSDEBUG"))
        {
        fprintf(stderr, "ERROR:  cannot send unix creds to pbs_server:  errno=%d (%s)\n",
                errno,
                strerror(errno));
        }

      close(connection[out].ch_socket);

      connection[out].ch_inuse = FALSE;
      local_errno = PBSE_PROTOCOL;

      use_unixsock = 0;  /* will try again with inet socket */
      }
    }

#endif /* END ENABLE_UNIX_SOCKETS */

  if (!use_unixsock)
    {
    int         retries = 0;
    std::string err_msg;
    /* at this point, either using unix sockets failed, or we determined not to
     * try */
    do
      {
      connection[out].ch_socket = socket(AF_INET, SOCK_STREAM, 0);

      if (connection[out].ch_socket < 0)
        {
        if (getenv("PBSDEBUG"))
          {
          if (!retry || retries >= MAX_RETRIES)
            fprintf(stderr, "ERROR:  cannot connect to server \"%s\", errno=%d (%s)\n",
                  server,
                  errno,
                  strerror(errno));
          }

          retries++;

        if (!retry || retries >= MAX_RETRIES)
          {
          rc = PBSE_SYSTEM * -1;
          goto cleanup_conn;
          }
        else
          {
          connection[out].ch_inuse = FALSE;
          pthread_mutex_unlock(connection[out].ch_mutex);

          usleep(1000);
          continue;
          }
        }

      if (setsockopt(connection[out].ch_socket, SOL_SOCKET, SO_REUSEADDR, &opt_value, sizeof(opt_value)))
        perror("Couldn't set socket option");

      /* This is probably an IPv4 solution for the if_name and preferred_addr
         We need to see what ioctl call we need for IPv6 */
      if_name = trq_get_if_name();
      if (if_name)
        {
        rc = trq_set_preferred_network_interface(if_name, &preferred_addr);
        if (rc != PBSE_NONE)
          {
          if (!retry || retries >= MAX_RETRIES)
            fprintf(stderr, "could not set preferred network interface (%s): %d\n",
                  if_name, rc);

          if (if_name)
            free(if_name);

          retries++;

          if (!retry || retries >= MAX_RETRIES)
            {
            rc = rc * -1;
            goto cleanup_conn;
            }
          else
            {
            connection[out].ch_inuse = FALSE;
            pthread_mutex_unlock(connection[out].ch_mutex);

            usleep(1000);
            continue;
            }
          }

        rc = bind(connection[out].ch_socket, &preferred_addr, sizeof(struct sockaddr));
        if (rc < 0)
          {
          if (!retry || retries >= MAX_RETRIES)
            fprintf(stderr, "ERROR: could not bind preferred network interface (%s): errno: %d",
                  if_name, errno);

          if (if_name)
            free(if_name);

          retries++;

          if (!retry || retries >= MAX_RETRIES)
            {
            rc = PBSE_SYSTEM * -1;
            goto cleanup_conn;
            }
          else
            {
            close(connection[out].ch_socket);
            connection[out].ch_inuse = FALSE;

            usleep(1000);
            continue;
            }
          }
        }

      /* we are done with if_name at this point. trq_get_if_name allocated
         space for it. We need to free it */
      if (if_name)
        free(if_name);

      server_addr.sin_family = AF_INET;

      if ((rc = pbs_getaddrinfo(server, NULL, &addr_info)) != 0)
        {
        if (getenv("PBSDEBUG"))
          {
          if (!retry || retries >= MAX_RETRIES)
            fprintf(stderr, "ERROR:  cannot get servername (%s) errno=%d (%s)\n",
                  server,
                  errno,
                  strerror(errno));
          }

        retries++;
        if (!retry || retries >= MAX_RETRIES)
          {
          rc = PBSE_BADHOST * -1;
          goto cleanup_conn;
          }
        else
          {
          close(connection[out].ch_socket);
          connection[out].ch_inuse = FALSE;

          usleep(1000);
          continue;
          }
        }

      server_addr.sin_addr = ((struct sockaddr_in *)addr_info->ai_addr)->sin_addr;
      server_addr.sin_port = htons(server_port);

      /* Set the socket to non-blocking mode so we can timeout */
      if ((sockflags = fcntl(connection[out].ch_socket, F_GETFL, NULL)) < 0)
        {
        retries++;
        if (!retry || retries >= MAX_RETRIES)
          {
          if (getenv("PBSDEBUG"))
            fprintf(stderr, "ERROR:  getting socket flags failed\n");

          rc = errno * -1;
          goto cleanup_conn;
          }
        else
          {
          close(connection[out].ch_socket);
          connection[out].ch_inuse = FALSE;

          rc = sockflags;
          usleep(1000);
          continue;
          }
        }
      
      sockflags |= O_NONBLOCK;

      if ((rc = fcntl(connection[out].ch_socket, F_SETFL, sockflags)) < 0)
        {
        retries++;
        if (!retry || retries >= MAX_RETRIES)
          {
          if (getenv("PBSDEBUG"))
            fprintf(stderr, "ERROR:  setting socket flags failed\n");

          rc = errno * -1;
          goto cleanup_conn;
          }
        else
          {
          close(connection[out].ch_socket);
          connection[out].ch_inuse = FALSE;

          usleep(1000);
          continue;
          }
        }

      int sock = connection[out].ch_socket;
      int conn_retries = 0;

      while (((rc = connect(sock, (struct sockaddr *)&server_addr, sizeof(server_addr))) != 0) &&
             (conn_retries < MAX_RETRIES))
        {
        rc = socket_wait_for_write(sock);

        if (rc == PERMANENT_SOCKET_FAIL)
          {
          rc = errno;
          break;
          }

        conn_retries++;
        }

      if (rc != 0)
        {
        close(sock);
        retries++;
        continue;
        }

      // if we are at this point, connect has succeeded, proceed to authorize
      /* Set the socket back to blocking so read()s actually work */
      sockflags &= (~O_NONBLOCK);
      
      if ((rc = fcntl(connection[out].ch_socket, F_SETFL, sockflags)) < 0)
        {
        if (getenv("PBSDEBUG"))
          fprintf(stderr, "ERROR: setting socket flags failed\n");

        retries++;
        if (!retry || retries >= MAX_RETRIES)
          {
          rc = PBSE_SOCKET_FAULT * -1;
          goto cleanup_conn;
          }
        else
          {
          close(connection[out].ch_socket);
          connection[out].ch_inuse = FALSE;
          
          usleep(1000);
          continue;
          }
        }

    /* FIXME: is this necessary?  Contributed by one user that fixes a problem,
       but doesn't fix the same problem for another user! */
#if 0
#if defined(__hpux)
    /*HP-UX : avoiding socket caching */
    send(connection[out].ch_socket, '?', 1, MSG_OOB);

#endif
#endif

#ifdef MUNGE_AUTH
      rc = PBSD_munge_authenticate(connection[out].ch_socket, out);
      if (rc != 0)
        {

        if (rc == PBSE_MUNGE_NOT_FOUND)
          {
          local_errno = PBSE_MUNGE_NOT_FOUND;
          
          if (getenv("PBSDEBUG"))
            {
            fprintf(stderr, "ERROR:  cannot find munge executable\n");
            }

          rc = -1 * local_errno;
          goto cleanup_conn;
          }
        else
          {
          retries++;
          if (!retry || retries >= MAX_RETRIES)
            {
            local_errno = PBSE_PERM;
            
            if (getenv("PBSDEBUG"))
              {
              fprintf(stderr, "ERROR:  cannot authenticate connection to server \"%s\", errno=%d (%s)\n",
                server,
                errno,
                strerror(errno));
              }
            
            rc = -1 * local_errno;
            goto cleanup_conn;
            }
          else
            {
            close(connection[out].ch_socket);
            connection[out].ch_inuse = FALSE;
            
            usleep(1000);
            continue;
            }
          }
        }
#else  
      /* new version of iff using daemon */
      if ((ENABLE_TRUSTED_AUTH == FALSE) &&
          ((rc = validate_socket(connection[out].ch_socket, err_msg)) != PBSE_NONE))
        {
        if (!retry || retries >= MAX_RETRIES)
          {
          if (getenv("PBSDEBUG"))
            {
            const char *tmp_err_msg = "";

            if (rc > 0)
              tmp_err_msg = pbs_strerror(rc);

            fprintf(stderr, 
              "ERROR:  cannot authenticate connection to server \"%s\", errno=%d (%s)\n",
              server, rc, tmp_err_msg);
            }

          local_errno = PBSE_SOCKET_FAULT;
          rc = -1 * local_errno;
          goto cleanup_conn;
          }
        else
          {
          close(connection[out].ch_socket);
          connection[out].ch_inuse = FALSE;

          retries++;
          usleep(1000);
          continue;
          }
        }
#endif /* ifdef MUNGE_AUTH */
      } while ((rc != PBSE_NONE) && (retries < MAX_RETRIES));

    if (rc != PBSE_NONE)
      {
      fprintf(stderr, "%s\n", err_msg.c_str());
      goto cleanup_conn;
      }
    } /* END if !use_unixsock */

  pthread_mutex_unlock(connection[out].ch_mutex);

  return(out);

cleanup_conn:
  
  if (connection[out].ch_socket >= 0)
    close(connection[out].ch_socket);

cleanup_conn_lite:
  connection[out].ch_inuse = FALSE;
  pthread_mutex_unlock(connection[out].ch_mutex);

  return(rc < 0 ? rc : rc * -1);
  }  /* END pbs_original_connect() */
コード例 #5
0
ファイル: pbsD_connect.c プロジェクト: CESNET/torque
int pbs_original_connect(

  char *server)  /* I (FORMAT:  NULL | '\0' | HOSTNAME | HOSTNAME:PORT )*/

  {
  struct sockaddr_in server_addr;

  struct hostent *hp;
  int out;
  int i;
#ifdef GSSAPI
  int neediff = 0;
#endif
  int auth;

  struct passwd *pw;
  int use_unixsock = 0;
#ifdef ENABLE_UNIX_SOCKETS

  struct sockaddr_un unserver_addr;
  char hnamebuf[256];
#endif

  char  *ptr;

  /* reserve a connection state record */

  out = -1;

  for (i = 1;i < NCONNECTS;i++)
    {
    if (connection[i].ch_inuse)
      continue;

    out = i;

    connection[out].ch_inuse  = 1;

    connection[out].ch_errno  = 0;

    connection[out].ch_socket = -1;

    connection[out].ch_errtxt = NULL;

    break;
    }

  if (out < 0)
    {
    pbs_errno = PBSE_NOCONNECTS;

    if (getenv("PBSDEBUG"))
      fprintf(stderr, "ALERT:  cannot locate free channel\n");

    /* FAILURE */

    return(-1);
    }

  /* get server host and port */

  server = PBS_get_server(server, &server_port);

  if (server == NULL)
    {
    connection[out].ch_inuse = 0;
    pbs_errno = PBSE_NOSERVER;

    if (getenv("PBSDEBUG"))
      fprintf(stderr, "ALERT:  PBS_get_server() failed\n");

    return(-1);
    }

  /* determine who we are */

  pbs_current_uid = getuid();

  if ((pw = getpwuid(pbs_current_uid)) == NULL)
    {
    pbs_errno = PBSE_SYSTEM;

    if (getenv("PBSDEBUG"))
      {
      fprintf(stderr, "ALERT:  cannot get password info for uid %ld\n",
              (long)pbs_current_uid);
      }

    return(-1);
    }

  strcpy(pbs_current_user, pw->pw_name);

  pbs_server = server;    /* set for error messages from commands */


#ifdef ENABLE_UNIX_SOCKETS
  /* determine if we want to use unix domain socket */

  if (!strcmp(server, "localhost"))
    use_unixsock = 1;
  else if ((gethostname(hnamebuf, sizeof(hnamebuf) - 1) == 0) && !strcmp(hnamebuf, server))
    use_unixsock = 1;

  /* NOTE: if any part of using unix domain sockets fails,
   * we just cleanup and try again with inet sockets */

  /* get socket */

  if (use_unixsock)
    {
    connection[out].ch_socket = socket(AF_UNIX, SOCK_STREAM, 0);

    if (connection[out].ch_socket < 0)
      {
      if (getenv("PBSDEBUG"))
        {
        fprintf(stderr, "ERROR:  cannot create socket:  errno=%d (%s)\n",
                errno,
                strerror(errno));
        }

      connection[out].ch_inuse = 0;

      pbs_errno = PBSE_PROTOCOL;

      use_unixsock = 0;
      }
    }

  /* and connect... */

  if (use_unixsock)
    {
    unserver_addr.sun_family = AF_UNIX;
    strcpy(unserver_addr.sun_path, TSOCK_PATH);

    if (connect(
          connection[out].ch_socket,
          (struct sockaddr *)&unserver_addr,
          (strlen(unserver_addr.sun_path) + sizeof(unserver_addr.sun_family))) < 0)
      {
      close(connection[out].ch_socket);

      connection[out].ch_inuse = 0;
      pbs_errno = errno;

      if (getenv("PBSDEBUG"))
        {
        fprintf(stderr, "ERROR:  cannot connect to server, errno=%d (%s)\n",
                errno,
                strerror(errno));
        }

      use_unixsock = 0;  /* will try again with inet socket */
      }
    }

  if (use_unixsock)
    {
    if (!send_unix_creds(connection[out].ch_socket))
      {
      if (getenv("PBSDEBUG"))
        {
        fprintf(stderr, "ERROR:  cannot send unix creds to pbs_server:  errno=%d (%s)\n",
                errno,
                strerror(errno));
        }

      close(connection[out].ch_socket);

      connection[out].ch_inuse = 0;
      pbs_errno = PBSE_PROTOCOL;

      use_unixsock = 0;  /* will try again with inet socket */
      }
    }

#endif /* END ENABLE_UNIX_SOCKETS */

  if (!use_unixsock)
    {

    /* at this point, either using unix sockets failed, or we determined not to
     * try */

    connection[out].ch_socket = socket(AF_INET, SOCK_STREAM, 0);

    if (connection[out].ch_socket < 0)
      {
      if (getenv("PBSDEBUG"))
        {
        fprintf(stderr, "ERROR:  cannot connect to server \"%s\", errno=%d (%s)\n",
                server,
                errno,
                strerror(errno));
        }

      connection[out].ch_inuse = 0;

      pbs_errno = PBSE_PROTOCOL;

      return(-1);
      }

    /* connection succeeded re-mark as used */
    connection[out].ch_inuse = 1;

    server_addr.sin_family = AF_INET;

    hp = NULL;
    hp = gethostbyname(server);
  /* setup DIS support routines for following pbs_* calls */

    if (hp == NULL)
      {
      close(connection[out].ch_socket);
      connection[out].ch_inuse = 0;
      pbs_errno = PBSE_BADHOST;

      if (getenv("PBSDEBUG"))
        {
        fprintf(stderr, "ERROR:  cannot get servername (%s) errno=%d (%s)\n",
                (server != NULL) ? server : "NULL",
                errno,
                strerror(errno));
        }

      return(-1);
      }

    memcpy((char *)&server_addr.sin_addr, hp->h_addr_list[0], hp->h_length);

    server_addr.sin_port = htons(server_port);

    if (connect(
          connection[out].ch_socket,
          (struct sockaddr *)&server_addr,
          sizeof(server_addr)) < 0)
      {
      close(connection[out].ch_socket);

      connection[out].ch_inuse = 0;
      pbs_errno = errno;

      if (getenv("PBSDEBUG"))
        {
        fprintf(stderr, "ERROR:  cannot connect to server, errno=%d (%s)\n",
                errno,
                strerror(errno));
        }

      return(-1);
      }

  DIS_tcp_setup(connection[out].ch_socket);

  if ((ptr = getenv("PBSAPITIMEOUT")) != NULL)
    {
    pbs_tcp_timeout = strtol(ptr,NULL,0);	

    if (pbs_tcp_timeout <= 0)
      {
      pbs_tcp_timeout = 10800;      /* set for 3 hour time out */
      }
    }
  else
    {
    pbs_tcp_timeout = 10800;      /* set for 3 hour time out */
    }


  /* If we have GSSAPI, then try gssapi authentication first.  If that fails, fall back to iff.
     If there's no GSSAPI, then just use iff.
   */
#ifdef GSSAPI
  if (!getenv("TORQUE_IGNORE_KERBEROS") &&
      !ignore_kerberos_for_connection &&
      pbsgss_can_get_creds())
    {
    if (encode_DIS_ReqHdr(connection[out].ch_socket, PBS_BATCH_GSSAuthenUser, pbs_current_user) ||
        encode_DIS_ReqExtend(connection[out].ch_socket,0))
      {
      if (getenv("PBSDEBUG"))
        {
        fprintf(stderr,"ERROR:  cannot authenticate connection with gssapi, errno=%d (%s)\n", errno, strerror(errno));
        }
      neediff = 1;
      }
    else
      {
      DIS_tcp_wflush(connection[out].ch_socket);
      if (pbsgss_client_authenticate(server,connection[out].ch_socket,1,1) != 0)
        {
        neediff = 1;
        if (getenv("PBSDEBUG"))
          {
          fprintf(stderr,"ERROR:  cannot authenticate connection, errno=%d (%s)\n", errno, strerror(errno));
          }
        }
      }
    }
  else
    {
    neediff = 1;
    }

  if (neediff)
    {
#endif

    /* FIXME: is this necessary?  Contributed by one user that fixes a problem,
       but doesn't fix the same problem for another user! */
#if 0
#if defined(__hpux)
    /*HP-UX : avoiding socket caching */
    send(connection[out].ch_socket, '?', 1, MSG_OOB);

#endif
#endif

    /* Have pbs_iff authenticate connection */

    if ((ENABLE_TRUSTED_AUTH == FALSE) && ((auth = PBSD_authenticate(connection[out].ch_socket)) != 0))
      {
      close(connection[out].ch_socket);

      connection[out].ch_inuse = 0;

      if (auth == ENOENT)
        {
        pbs_errno = ENOENT;
        
        if (getenv("PBSDEBUG"))
          {
          fprintf(stderr, "ERROR:  cannot find pbs_iif executable\n");
          }
        }
      else
        {
      pbs_errno = PBSE_PERM;

      if (getenv("PBSDEBUG"))
        {
        fprintf(stderr, "ERROR:  cannot authenticate connection to server \"%s\", errno=%d (%s)\n",
                server,
                errno,
                strerror(errno));
        }
        }

      return(-1);
      }
#ifdef GSSAPI
    } /* END if neediff */
#endif

    } /* END !useunix */

  DIS_tcp_setup(connection[out].ch_socket);

  if ((ptr = getenv("PBSAPITIMEOUT")) != NULL)
    {
    pbs_tcp_timeout = strtol(ptr, NULL, 0);

    if (pbs_tcp_timeout <= 0)
      {
      pbs_tcp_timeout = 10800;      /* set for 3 hour time out */
      }
    }
  else
    {
    pbs_tcp_timeout = 10800;      /* set for 3 hour time out */
    }

  return(out);
  }  /* END pbs_original_connect() */
コード例 #6
0
ファイル: pbsD_connect.c プロジェクト: dhill12/test
int pbs_original_connect(

  char *server)  /* I (FORMAT:  NULL | '\0' | HOSTNAME | HOSTNAME:PORT )*/

  {
  struct sockaddr_in server_addr;
  char *if_name;
  struct addrinfo *addr_info;
  int out;
  int i;
  int rc;
  int local_errno;

  struct sockaddr preferred_addr; /* set if TRQ_IFNAME set in torque.cfg */
  struct passwd *pw;
  int use_unixsock = 0;
  uid_t pbs_current_uid;

#ifdef ENABLE_UNIX_SOCKETS
  struct sockaddr_un unserver_addr;
  char hnamebuf[256];
#endif

  char  *ptr;

  /* reserve a connection state record */

  out = -1;

  for (i = 1;i < NCONNECTS;i++)
    {
    if (connection[i].ch_mutex == NULL)
      {
      connection[i].ch_mutex = calloc(1, sizeof(pthread_mutex_t));
      pthread_mutex_init(connection[i].ch_mutex,NULL);
      }

    pthread_mutex_lock(connection[i].ch_mutex);

    if (connection[i].ch_inuse == FALSE)
      {
      out = i;
      
      connection[out].ch_inuse  = TRUE;
      connection[out].ch_errno  = 0;
      connection[out].ch_socket = -1;
      connection[out].ch_errtxt = NULL;

      break;
      }

    pthread_mutex_unlock(connection[i].ch_mutex);
    }

  if (out < 0)
    {
    if (getenv("PBSDEBUG"))
      fprintf(stderr, "ALERT:  cannot locate free channel\n");

    /* FAILURE */
    /* no need to unlock mutex here - in this case no connection was found */

    return(PBSE_NOCONNECTS * -1);
    }

  /* get server host and port */

  server = PBS_get_server(server, &server_port);

  if (server == NULL)
    {
    connection[out].ch_inuse = FALSE;

    pthread_mutex_unlock(connection[out].ch_mutex);

    if (getenv("PBSDEBUG"))
      fprintf(stderr, "ALERT:  PBS_get_server() failed\n");

    return(PBSE_NOSERVER * -1);
    }

  /* determine who we are */

  pbs_current_uid = getuid();

  if ((pw = getpwuid(pbs_current_uid)) == NULL)
    {
    if (getenv("PBSDEBUG"))
      {
      fprintf(stderr, "ALERT:  cannot get password info for uid %ld\n",
              (long)pbs_current_uid);
      }

    pthread_mutex_unlock(connection[out].ch_mutex);

    return(PBSE_SYSTEM * -1);
    }

  strcpy(pbs_current_user, pw->pw_name);

  pbs_server = server;    /* set for error messages from commands */


#ifdef ENABLE_UNIX_SOCKETS
  /* determine if we want to use unix domain socket */

  if (!strcmp(server, "localhost"))
    use_unixsock = 1;
  else if ((gethostname(hnamebuf, sizeof(hnamebuf) - 1) == 0) && !strcmp(hnamebuf, server))
    use_unixsock = 1;

  /* NOTE: if any part of using unix domain sockets fails,
   * we just cleanup and try again with inet sockets */

  /* get socket */

  if (use_unixsock)
    {
    connection[out].ch_socket = socket(AF_UNIX, SOCK_STREAM, 0);

    if (connection[out].ch_socket < 0)
      {
      if (getenv("PBSDEBUG"))
        {
        fprintf(stderr, "ERROR:  cannot create socket:  errno=%d (%s)\n",
                errno,
                strerror(errno));
        }

      connection[out].ch_inuse = FALSE;

      local_errno = PBSE_PROTOCOL;

      use_unixsock = 0;
      }
    }

  /* and connect... */

  if (use_unixsock)
    {
    unserver_addr.sun_family = AF_UNIX;
    strcpy(unserver_addr.sun_path, TSOCK_PATH);

    if (connect(
          connection[out].ch_socket,
          (struct sockaddr *)&unserver_addr,
          (strlen(unserver_addr.sun_path) + sizeof(unserver_addr.sun_family))) < 0)
      {
      close(connection[out].ch_socket);

      connection[out].ch_inuse = FALSE;
      local_errno = errno;

      if (getenv("PBSDEBUG"))
        {
        fprintf(stderr, "ERROR:  cannot connect to server, errno=%d (%s)\n",
                errno,
                strerror(errno));
        }

      use_unixsock = 0;  /* will try again with inet socket */
      }
    }

  if (use_unixsock)
    {
    if (!send_unix_creds(connection[out].ch_socket))
      {
      if (getenv("PBSDEBUG"))
        {
        fprintf(stderr, "ERROR:  cannot send unix creds to pbs_server:  errno=%d (%s)\n",
                errno,
                strerror(errno));
        }

      close(connection[out].ch_socket);

      connection[out].ch_inuse = FALSE;
      local_errno = PBSE_PROTOCOL;

      use_unixsock = 0;  /* will try again with inet socket */
      }
    }

#endif /* END ENABLE_UNIX_SOCKETS */

  if (!use_unixsock)
    {

    /* at this point, either using unix sockets failed, or we determined not to
     * try */

    connection[out].ch_socket = socket(AF_INET, SOCK_STREAM, 0);

    if (connection[out].ch_socket < 0)
      {
      if (getenv("PBSDEBUG"))
        {
        fprintf(stderr, "ERROR:  cannot connect to server \"%s\", errno=%d (%s)\n",
                server,
                errno,
                strerror(errno));
        }

      connection[out].ch_inuse = FALSE;

      pthread_mutex_unlock(connection[out].ch_mutex);

      return(PBSE_PROTOCOL * -1);
      }

    /* This is probably an IPv4 solution for the if_name and preferred_addr
       We need to see what ioctl call we need for IPv6 */
    if_name = trq_get_if_name();
    if (if_name)
      {
      rc = trq_set_preferred_network_interface(if_name, &preferred_addr);
      if (rc != PBSE_NONE)
        {
        fprintf(stderr, "could not set preferred network interface (%s): %d\n",
                if_name, rc);
        if(if_name)
          free(if_name);
        return(rc);
        }

      rc = bind(connection[out].ch_socket, &preferred_addr, sizeof(struct sockaddr));
      if (rc < 0)
        {
        fprintf(stderr, "ERROR: could not bind preferred network interface (%s): errno: %d",
                if_name, errno);
        if (if_name)
          free(if_name);
        return(PBSE_SYSTEM * -1);
        }
      }

    /* we are done with if_name at this point. trq_get_if_name allocated
       space for it. We need to free it */
    if (if_name)
      free(if_name);

    server_addr.sin_family = AF_INET;

    if (getaddrinfo(server, NULL, NULL, &addr_info) != 0)
      {
      close(connection[out].ch_socket);
      connection[out].ch_inuse = FALSE;

      if (getenv("PBSDEBUG"))
        {
        fprintf(stderr, "ERROR:  cannot get servername (%s) errno=%d (%s)\n",
                (server != NULL) ? server : "NULL",
                errno,
                strerror(errno));
        }

      pthread_mutex_unlock(connection[out].ch_mutex);

      return(PBSE_BADHOST * -1);
      }

    server_addr.sin_addr = ((struct sockaddr_in *)addr_info->ai_addr)->sin_addr;
    freeaddrinfo(addr_info);

    server_addr.sin_port = htons(server_port);

    if (connect(
          connection[out].ch_socket,
          (struct sockaddr *)&server_addr,
          sizeof(server_addr)) < 0)
      {
      close(connection[out].ch_socket);

      connection[out].ch_inuse = FALSE;

      if (getenv("PBSDEBUG"))
        {
        fprintf(stderr, "ERROR:  cannot connect to server, errno=%d (%s)\n",
                errno,
                strerror(errno));
        }

      pthread_mutex_unlock(connection[out].ch_mutex);

      return(errno * -1);
      }

    /* FIXME: is this necessary?  Contributed by one user that fixes a problem,
       but doesn't fix the same problem for another user! */
#if 0
#if defined(__hpux)
    /*HP-UX : avoiding socket caching */
    send(connection[out].ch_socket, '?', 1, MSG_OOB);

#endif
#endif

#ifdef MUNGE_AUTH
    rc = PBSD_munge_authenticate(connection[out].ch_socket, out);

    if (rc != 0)
      {
      close(connection[out].ch_socket);

      connection[out].ch_inuse = FALSE;

      if (rc == PBSE_MUNGE_NOT_FOUND)
        {
        local_errno = PBSE_MUNGE_NOT_FOUND;
        
        if (getenv("PBSDEBUG"))
          {
          fprintf(stderr, "ERROR:  cannot find munge executable\n");
          }
        }
      else
        {
        local_errno = PBSE_PERM;
        
        if (getenv("PBSDEBUG"))
          {
          fprintf(stderr, "ERROR:  cannot authenticate connection to server \"%s\", errno=%d (%s)\n",
            server,
            errno,
            strerror(errno));
          }
        }

      pthread_mutex_unlock(connection[out].ch_mutex);

      return(-1 * local_errno);
      }
    
    
#else  
    /* new version of iff using daemon */
    if ((ENABLE_TRUSTED_AUTH == FALSE) && ((rc = validate_socket(connection[out].ch_socket)) != PBSE_NONE))
      {
      close(connection[out].ch_socket);

      connection[out].ch_inuse = FALSE;

      if (getenv("PBSDEBUG"))
        {
        fprintf(stderr, "ERROR:  cannot authenticate connection to server \"%s\", errno=%d (%s)\n",
                server, rc, pbs_strerror(rc));
        }
      
      local_errno = PBSE_SOCKET_FAULT;

      pthread_mutex_unlock(connection[out].ch_mutex);

      return(-1 * local_errno);
      }
#endif /* ifdef MUNGE_AUTH */

    } /* END if !use_unixsock */

  /* setup DIS support routines for following pbs_* calls */

  if ((ptr = getenv("PBSAPITIMEOUT")) != NULL)
    {
    pbs_tcp_timeout = strtol(ptr, NULL, 0);

    if (pbs_tcp_timeout <= 0)
      {
      pbs_tcp_timeout = 10800;      /* set for 3 hour time out */
      }
    }
  else
    {
    pbs_tcp_timeout = 10800;      /* set for 3 hour time out */
    }

  pthread_mutex_unlock(connection[out].ch_mutex);

  return(out);
  }  /* END pbs_original_connect() */
コード例 #7
0
ファイル: trq_auth.c プロジェクト: adaptivecomputing/torque
/* validate_server:
 *
 * This function tries to find the currently active
 * pbs_server. If no server can be found the default 
 * server is made the active server */ 
int validate_server(

  char  *active_server_name,
  int    t_server_port,
  char  *ssh_key,
  char **sign_key)

  {
  int rc = PBSE_NONE;
  int sd;
  char server_name_list[PBS_MAXSERVERNAME*3+1];
  char current_name[PBS_MAXSERVERNAME+1];
  char *tp;
  char  log_buf[LOCAL_LOG_BUF_SIZE];

  /* First we try to connect to the pbs_server as 
     indicated in active_server_name. If that fails
     we go through the server list. If that fails
     we stick with the active_server_name. If 
     another server in teh server_name_list responds 
     that will become the active_pbs_server */
  if (active_server_name != NULL)
    rc = trq_simple_connect(active_server_name, t_server_port, &sd);
  else
    rc = PBSE_UNKREQ; /* If we don't have a server name we want to process everyting. */

  if ( rc != PBSE_NONE)
    {
    int           list_len;
    int           i;
    unsigned int  port;
    char         *tmp_server;

    snprintf(server_name_list, sizeof(server_name_list), "%s", pbs_get_server_list());
    list_len = csv_length(server_name_list);

    for (i = 0; i < list_len; i++)  /* Try all server names in the list. */
      {
      tp = csv_nth(server_name_list, i);

      if (tp && tp[0])
        {
        /* Trim any leading space */
        while(isspace(*tp)) tp++; 
        
        memset(current_name, 0, sizeof(current_name));
        snprintf(current_name, sizeof(current_name), "%s", tp);

        if (getenv("PBSDEBUG"))
          {
          fprintf(stderr, "pbs_connect attempting connection to server \"%s\"\n", current_name);
          }

        tmp_server = PBS_get_server(current_name, &port);

        rc = trq_simple_connect(tmp_server, port, &sd);
        if ( rc == PBSE_NONE)
          {
          trq_simple_disconnect(sd);
          fprintf(stderr, "changing active server to %s port %d\n", tmp_server, port);
          snprintf(active_pbs_server, sizeof(active_pbs_server), "%s", tmp_server);
          active_pbs_server_port = port;
          sprintf(log_buf, "Changing active server to %s port %d\n", tmp_server, port);
          log_event(PBSEVENT_CLIENTAUTH | PBSEVENT_FORCE, PBS_EVENTCLASS_TRQAUTHD, __func__, log_buf);
          break;
          }
        }
      }
    }
  else
    trq_simple_disconnect(sd);

  if (rc != PBSE_NONE) /* This only indicates no server is currently active. Go to default */
    {
    fprintf(stderr, "Currently no servers active. Default server will be listed as active server. Error % d\n", rc);
    rc = PBSE_NONE;
    }

  fprintf(stderr, "Active server name: %s  pbs_server port is: %d\n", active_pbs_server, active_pbs_server_port);

  return(rc);
  } /* END validate_server() */
コード例 #8
0
ファイル: pbsD_connect.c プロジェクト: Bhagat-Rajput/pbspro
/**
 * @brief
 *	Open a connection with a pbs server.
 *	Do not allow TCP to block us if Server host is down
 *	At this point, this does not attempt to find a fail_over Server
 *
 * @param[in]   server - specifies the server to which to connect
 * @param[in]   tout - timeout value for select
 *
 * @return int
 * @retval >= 0	index to the internal connection table representing the
 *		connection made.
 * @retval -1	error encountered in getting index
 */
int
pbs_connect_noblk(char *server, int tout)
{
	int out;
	int i;
	pbs_socklen_t l;
	int n;
	struct timeval tv;
	fd_set fdset;
	struct batch_reply *reply;
	char server_name[PBS_MAXSERVERNAME+1];
	unsigned int server_port;
	struct addrinfo *aip, *pai;
	struct addrinfo hints;
	struct sockaddr_in *inp;
	short int connect_err = 0;

	struct sockaddr_in sockname;
	pbs_socklen_t	 socknamelen;

#ifdef WIN32
	int     non_block = 1;
	struct sockaddr_in to_sock;
	struct sockaddr_in from_sock;
#endif

#ifndef WIN32
	int nflg;
	int oflg;
#endif

	/* initialize the thread context data, if not already initialized */
	if (pbs_client_thread_init_thread_context() != 0)
		return -1;

	if (pbs_loadconf(0) == 0)
		return -1;

	/* get server host and port	*/

	server = PBS_get_server(server, server_name, &server_port);
	if (server == NULL) {
		pbs_errno = PBSE_NOSERVER;
		return -1;
	}

	/* Reserve a connection state record */
	if (pbs_client_thread_lock_conntable() != 0)
		return -1;

	out = -1;
	for (i=1;i<NCONNECTS;i++) {
		if (connection[i].ch_inuse) continue;
		out = i;
		connection[out].ch_inuse = 1;
		connection[out].ch_errno = 0;
		connection[out].ch_socket= -1;
		connection[out].ch_errtxt = NULL;
		break;
	}

	if (pbs_client_thread_unlock_conntable() != 0)
		return -1; /* pbs_errno set by the function */

	if (out < 0) {
		pbs_errno = PBSE_NOCONNECTS;
		return -1;
	}


	/* get socket	*/

#ifdef WIN32
	/* the following lousy hack is needed since the socket call needs */
	/* SYSTEMROOT env variable properly set! */
	if (getenv("SYSTEMROOT") == NULL) {
		setenv("SYSTEMROOT", "C:\\WINNT", 1);
		setenv("SystemRoot", "C:\\WINNT", 1);
	}
	connection[out].ch_socket = socket(AF_INET, SOCK_STREAM, 0);
	if (connection[out].ch_socket < 0) {
		setenv("SYSTEMROOT", "C:\\WINDOWS", 1);
		setenv("SystemRoot", "C:\\WINDOWS", 1);
		connection[out].ch_socket = socket(AF_INET, SOCK_STREAM, 0);
	}
#else
	connection[out].ch_socket = socket(AF_INET, SOCK_STREAM, 0);
#endif
	if (connection[out].ch_socket < 0) {
		connection[out].ch_inuse = 0;
		pbs_errno = ERRORNO;
		return -1;
	}

	/* set socket non-blocking */

#ifdef WIN32
	if (ioctlsocket(connection[out].ch_socket, FIONBIO, &non_block) == SOCKET_ERROR)
#else
	oflg = fcntl(connection[out].ch_socket, F_GETFL) & ~O_ACCMODE;
	nflg = oflg | O_NONBLOCK;
	if (fcntl(connection[out].ch_socket, F_SETFL, nflg) == -1)
#endif
		goto err;

	/* and connect... */

	strcpy(pbs_server, server);    /* set for error messages from commands */
	memset(&hints, 0, sizeof(struct addrinfo));
	/*
	 *      Why do we use AF_UNSPEC rather than AF_INET?  Some
	 *      implementations of getaddrinfo() will take an IPv6
	 *      address and map it to an IPv4 one if we ask for AF_INET
	 *      only.  We don't want that - we want only the addresses
	 *      that are genuinely, natively, IPv4 so we start with
	 *      AF_UNSPEC and filter ai_family below.
	 */
	hints.ai_family = AF_UNSPEC;
	hints.ai_socktype = SOCK_STREAM;
	hints.ai_protocol = IPPROTO_TCP;

	if (getaddrinfo(server, NULL, &hints, &pai) != 0) {
		CLOSESOCKET(connection[out].ch_socket);
		connection[out].ch_inuse = 0;
		pbs_errno = PBSE_BADHOST;
		return -1;
	}
	for (aip = pai; aip != NULL; aip = aip->ai_next) {
		/* skip non-IPv4 addresses */
		if (aip->ai_family == AF_INET) {
			inp = (struct sockaddr_in *) aip->ai_addr;
			break;
		}
	}
	if (aip == NULL) {
		/* treat no IPv4 addresses as getaddrinfo() failure */
		CLOSESOCKET(connection[out].ch_socket);
		connection[out].ch_inuse = 0;
		pbs_errno = PBSE_BADHOST;
		freeaddrinfo(pai);
		return -1;
	} else
		inp->sin_port = htons(server_port);
	if (connect(connection[out].ch_socket,
		aip->ai_addr,
		aip->ai_addrlen) < 0) {
		connect_err = 1;
	}
	if (connect_err == 1)
	{
		/* connect attempt failed */
		pbs_errno = ERRORNO;
		switch (pbs_errno) {
#ifdef WIN32
			case WSAEWOULDBLOCK:
#else
			case EINPROGRESS:
			case EWOULDBLOCK:
#endif
				while (1) {
					FD_ZERO(&fdset);
					FD_SET(connection[out].ch_socket, &fdset);
					tv.tv_sec = tout;
					tv.tv_usec = 0;
					n = select(connection[out].ch_socket+1, NULL, &fdset, NULL, &tv);
					if (n > 0) {
						pbs_errno = 0;
						l = sizeof(pbs_errno);
						(void)getsockopt(connection[out].ch_socket,
							SOL_SOCKET, SO_ERROR,
							&pbs_errno, &l);
						if (pbs_errno == 0)
							break;
						else
							goto err;
					} if ((n < 0) &&
#ifdef WIN32
						(ERRORNO == WSAEINTR)
#else
						(ERRORNO == EINTR)
#endif
						) {
						continue;
					} else {
						goto err;
					}
				}
				break;

			default:
err:
				CLOSESOCKET(connection[out].ch_socket);
				connection[out].ch_inuse = 0;
				freeaddrinfo(pai);
				return -1;	/* cannot connect */

		}
	}
	freeaddrinfo(pai);

	/* reset socket blocking */
#ifdef WIN32
	non_block = 0;
	if (ioctlsocket(connection[out].ch_socket, FIONBIO, &non_block) == SOCKET_ERROR)
#else
	if (fcntl(connection[out].ch_socket, F_SETFL, oflg) < 0)
#endif
		goto err;

	/*
	 * multiple threads cant get the same connection id above,
	 * so no need to lock this piece of code
	 */
	/* setup connection level thread context */
	if (pbs_client_thread_init_connect_context(out) != 0) {
		CLOSESOCKET(connection[out].ch_socket);
		connection[out].ch_inuse = 0;
		/* pbs_errno set by the pbs_connect_init_context routine */
		return -1;
	}
	/*
	 * even though the following is communication with server on
	 * a connection handle, it does not need to be lock since
	 * this connection handle has not be returned back yet to the client
	 * so others threads cannot use it
	 */

	/* send "dummy" connect message */
	DIS_tcp_setup(connection[out].ch_socket);
	if ((i = encode_DIS_ReqHdr(connection[out].ch_socket,
		PBS_BATCH_Connect, pbs_current_user)) ||
		(i = encode_DIS_ReqExtend(connection[out].ch_socket,
		NULL))) {
		pbs_errno = PBSE_SYSTEM;
		return -1;
	}
	if (DIS_tcp_wflush(connection[out].ch_socket)) {
		pbs_errno = PBSE_SYSTEM;
		return -1;
	}
	reply = PBSD_rdrpy(out);
	PBSD_FreeReply(reply);

	/*do configured authentication (kerberos, pbs_iff, whatever)*/

	/*Get the socket port for engage_authentication()*/
	socknamelen = sizeof(sockname);
	if (getsockname(connection[out].ch_socket, (struct sockaddr *)&sockname, &socknamelen))
		return -1;
	if (engage_authentication(connection[out].ch_socket,
		server,
		server_port,
		&sockname) == -1) {
		CLOSESOCKET(connection[out].ch_socket);
		connection[out].ch_inuse = 0;
		pbs_errno = PBSE_PERM;
		return -1;
	}

	/* setup DIS support routines for following pbs_* calls */
	DIS_tcp_setup(connection[out].ch_socket);
	pbs_tcp_timeout = PBS_DIS_TCP_TIMEOUT_VLONG;	/* set for 3 hours */

	return out;
}
コード例 #9
0
ファイル: pbsD_connect.c プロジェクト: Bhagat-Rajput/pbspro
/**
 * @brief
 *	Makes a PBS_BATCH_Connect request to 'server'.
 *
 * @param[in]   server - the hostname of the pbs server to connect to.
 * @param[in]   extend_data - a string to send as "extend" data.
 *
 * @return int
 * @retval >= 0	index to the internal connection table representing the
 *		connection made.
 * @retval -1	error encountered setting up the connection.
 */
int
__pbs_connect_extend(char *server, char *extend_data)
{
	struct sockaddr_in server_addr;
	struct sockaddr_in my_sockaddr;
	int out;
	int i;
	int f;
	char  *altservers[2];
	int    have_alt = 0;
	struct batch_reply	*reply;
	char server_name[PBS_MAXSERVERNAME+1];
	unsigned int server_port;
	struct sockaddr_in sockname;
	pbs_socklen_t	 socknamelen;
#ifdef WIN32
	struct sockaddr_in to_sock;
	struct sockaddr_in from_sock;
#endif

#ifndef WIN32
	char   pbsrc[_POSIX_PATH_MAX];
	struct stat sb;
	int    using_secondary = 0;
#endif  /* not WIN32 */

	/* initialize the thread context data, if not already initialized */
	if (pbs_client_thread_init_thread_context() != 0)
		return -1;

	if (pbs_loadconf(0) == 0)
		return -1;

	/* get server host and port	*/

	server = PBS_get_server(server, server_name, &server_port);
	if (server == NULL) {
		pbs_errno = PBSE_NOSERVER;
		return -1;
	}

	if (pbs_conf.pbs_primary && pbs_conf.pbs_secondary) {
		/* failover configuered ...   */
		if (hostnmcmp(server, pbs_conf.pbs_primary) == 0) {
			have_alt = 1;
			/* We want to try the one last seen as "up" first to not   */
			/* have connection delays.   If the primary was up, there  */
			/* is no .pbsrc.NAME file.  If the last command connected  */
			/* to the Secondary, then it created the .pbsrc.USER file. */

			/* see if already seen Primary down */
#ifdef WIN32
			/* due to windows quirks, all try both in same order */
			altservers[0] = pbs_conf.pbs_primary;
			altservers[1] = pbs_conf.pbs_secondary;
#else
			(void)snprintf(pbsrc, _POSIX_PATH_MAX, "%s/.pbsrc.%s", pbs_conf.pbs_tmpdir, pbs_current_user);
			if (stat(pbsrc, &sb) == -1) {
				/* try primary first */
				altservers[0] = pbs_conf.pbs_primary;
				altservers[1] = pbs_conf.pbs_secondary;
				using_secondary = 0;
			} else {
				/* try secondary first */
				altservers[0] = pbs_conf.pbs_secondary;
				altservers[1] = pbs_conf.pbs_primary;
				using_secondary = 1;
			}
#endif
		}
	}

	/* if specific host name declared for the host on which */
	/* this client is running,  get its address */
	if (pbs_conf.pbs_public_host_name) {
		if (get_hostsockaddr(pbs_conf.pbs_public_host_name, &my_sockaddr) != 0)
			return -1; /* pbs_errno was set */
	}

	/* Reserve a connection state record */
	if (pbs_client_thread_lock_conntable() != 0)
		return -1;

	out = -1;
	for (i=1;i<NCONNECTS;i++) {
		if (connection[i].ch_inuse) continue;
		out = i;
		connection[out].ch_errno = 0;
		connection[out].ch_socket= -1;
		connection[out].ch_errtxt = NULL;
		connection[out].ch_inuse = 1; /* reserve the socket */
		break;
	}

	if (pbs_client_thread_unlock_conntable() != 0)
		return -1; /* pbs_errno set by the function */

	if (out < 0) {
		pbs_errno = PBSE_NOCONNECTS;
		return -1;
	}

	/*
	 * connect to server ...
	 * If attempt to connect fails and if Failover configured and
	 *   if attempting to connect to Primary,  try the Secondary
	 *   if attempting to connect to Secondary, try the Primary
	 */
	for (i=0; i<(have_alt+1); ++i) {

		/* get socket	*/

#ifdef WIN32
		/* the following lousy hack is needed since the socket call needs */
		/* SYSTEMROOT env variable properly set! */
		if (getenv("SYSTEMROOT") == NULL) {
			setenv("SYSTEMROOT", "C:\\WINNT", 1);
			setenv("SystemRoot", "C:\\WINNT", 1);
		}
		connection[out].ch_socket = socket(AF_INET, SOCK_STREAM, 0);
		if (connection[out].ch_socket < 0) {
			setenv("SYSTEMROOT", "C:\\WINDOWS", 1);
			setenv("SystemRoot", "C:\\WINDOWS", 1);
			connection[out].ch_socket = socket(AF_INET, SOCK_STREAM, 0);

		}
#else
		connection[out].ch_socket = socket(AF_INET, SOCK_STREAM, 0);
#endif
		if (connection[out].ch_socket < 0) {
			connection[out].ch_inuse = 0;
			pbs_errno = errno;
			return -1;
		}

		/* and connect... */

		if (have_alt) {
			server = altservers[i];
		}
		strcpy(pbs_server, server); /* set for error messages from commands */

		/* If a specific host name is defined which the client should use */

		if (pbs_conf.pbs_public_host_name) {
			/* my address will be in my_sockaddr,  bind the socket to it */
			my_sockaddr.sin_port = 0;
			if (bind(connection[out].ch_socket, (struct sockaddr *)&my_sockaddr, sizeof(my_sockaddr)) != 0) {
				return -1;
			}
		}

		if (get_hostsockaddr(server, &server_addr) != 0)
			return -1;

		server_addr.sin_port = htons(server_port);
		if (connect(connection[out].ch_socket,
			(struct sockaddr *)&server_addr,
			sizeof(struct sockaddr)) == 0) {

				break;
		} else {
			/* connect attempt failed */
			CLOSESOCKET(connection[out].ch_socket);
			pbs_errno = errno;
		}
	}
	if (i >= (have_alt+1)) {
		connection[out].ch_inuse = 0;
		return -1; 		/* cannot connect */
	}

#ifndef WIN32
	if (have_alt && (i == 1)) {
		/* had to use the second listed server ... */
		if (using_secondary == 1) {
			/* remove file that causes trying the Secondary first */
			unlink(pbsrc);
		} else {
			/* create file that causes trying the Primary first   */
			f = open(pbsrc, O_WRONLY|O_CREAT, 0200);
			if (f != -1)
				(void)close(f);
		}
	}
#endif

	/* setup connection level thread context */
	if (pbs_client_thread_init_connect_context(out) != 0) {
		CLOSESOCKET(connection[out].ch_socket);
		connection[out].ch_inuse = 0;
		/* pbs_errno set by the pbs_connect_init_context routine */
		return -1;
	}

	/*
	 * No need for global lock now on, since rest of the code
	 * is only communication on a connection handle.
	 * But we dont need to lock the connection handle, since this
	 * connection handle is not yet been returned to the client
	 */

	/* The following code was originally  put in for HPUX systems to deal
	 * with the issue where returning from the connect() call doesn't
	 * mean the connection is complete.  However, this has also been
	 * experienced in some Linux ppc64 systems like js-2. Decision was
	 * made to enable this harmless code for all architectures.
	 * FIX: Need to use the socket to send
	 * a message to complete the process.  For IFF authentication there is
	 * no leading authentication message needing to be sent on the client
	 * socket, so will send a "dummy" message and discard the replyback.
	 */

#if !defined(PBS_SECURITY ) || (PBS_SECURITY == STD )

	DIS_tcp_setup(connection[out].ch_socket);
	if ((i = encode_DIS_ReqHdr(connection[out].ch_socket,
		PBS_BATCH_Connect, pbs_current_user)) ||
		(i = encode_DIS_ReqExtend(connection[out].ch_socket,
		extend_data))) {
		pbs_errno = PBSE_SYSTEM;
		return -1;
	}
	if (DIS_tcp_wflush(connection[out].ch_socket)) {
		pbs_errno = PBSE_SYSTEM;
		return -1;
	}

	reply = PBSD_rdrpy(out);
	PBSD_FreeReply(reply);

#endif	/* PBS_SECURITY ... */

	/*do configured authentication (kerberos, pbs_iff, whatever)*/

	/*Get the socket port for engage_authentication() */
	socknamelen = sizeof(sockname);
	if (getsockname(connection[out].ch_socket, (struct sockaddr *)&sockname, &socknamelen))
		return -1;

	if (engage_authentication(connection[out].ch_socket,
		server,
		server_port,
		&sockname) == -1) {
		CLOSESOCKET(connection[out].ch_socket);
		connection[out].ch_inuse = 0;
		pbs_errno = PBSE_PERM;
		return -1;
	}

	/* setup DIS support routines for following pbs_* calls */

	DIS_tcp_setup(connection[out].ch_socket);
	pbs_tcp_timeout = PBS_DIS_TCP_TIMEOUT_VLONG;	/* set for 3 hours */

	/*
	 * Disable Nagle's algorithm on the TCP connection to server.
	 * Nagle's algorithm is hurting cmd-server communication.
	 */
	if (pbs_connection_set_nodelay(out) == -1) {
		CLOSESOCKET(connection[out].ch_socket);
		connection[out].ch_inuse = 0;
		pbs_errno = PBSE_SYSTEM;
		return -1;
	}

	return out;
}