예제 #1
0
/**
 * @brief
 *	Makes a connection to the server, returning the pbs_connect() result.
 *
 * @param[in]	server	- hostname of the pbs server to connect to
 * @param[in]	extend  - extend data to send along with the connection.
 *
 * @return	int
 * @retval	connection	success
 * @retval	0		fail
 */
int
cnt2server_extend(char *server, char *extend)
{
	int connect;

#if defined(PBS_SECURITY) && (PBS_SECURITY == KRB5)
	if (!getenv("PBSPRO_IGNORE_KERBEROS") && !pbsgss_can_get_creds()) {
		fprintf(stderr, "No Kerberos credentials found. Set \"PBSPRO_IGNORE_KERBEROS\" environment variable to skip this check.\n");
		exit(1);
	}
#endif
	
	connect = pbs_connect_extend(server, extend);
	if (connect <= 0) {
		if (pbs_errno > PBSE_) {
			switch (pbs_errno) {

				case PBSE_BADHOST:
					fprintf(stderr, "Unknown Host.\n");
					break;

				case PBSE_NOCONNECTS:
					fprintf(stderr, "Too many open connections.\n");
					break;

				case PBSE_NOSERVER:
					fprintf(stderr, "No default server name.\n");
					break;

				case PBSE_SYSTEM:
					fprintf(stderr, "System call failure.\n");
					break;

				case PBSE_PERM:
					fprintf(stderr, "No Permission.\n");
					break;

				case PBSE_PROTOCOL:
					fprintf(stderr, "Communication failure.\n");
					break;

			}
		} else if (errno != 0)
			perror(NULL);

		return (connect);
	}

	/*
	 * Disable Nagle's algorithm on the TCP connection to server.
	 * Nagle's algorithm is hurting cmd-server communication.
	 */
	if (pbs_connection_set_nodelay(connect) == -1) {
		fprintf(stderr, "Cannot set nodelay on connection %d (errno=%d)\n",
			connect, pbs_errno);
		return (PBSE_SYSTEM);
	}

	return (connect);
}
예제 #2
0
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() */