mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
314 lines
8.7 KiB
314 lines
8.7 KiB
/*++
|
|
|
|
Copyright (c) 1991 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
rexec.c
|
|
|
|
Abstract:
|
|
|
|
This module implements a routine to transmit commands to a remote
|
|
computer. This routine is used by the rexec program.
|
|
|
|
Author:
|
|
|
|
Mike Massa (mikemas) Sept 20, 1991
|
|
|
|
Revision History:
|
|
|
|
Who When What
|
|
-------- -------- ----------------------------------------------
|
|
mikemas 9-20-91 created
|
|
MuraliK 10-19-94 Fixing localization bug
|
|
MuraliK 06-27-95 on failure to connect it was sleeping for long time
|
|
(due to 1000*1000 millisecs time to sleep). Fixed!
|
|
|
|
Notes:
|
|
|
|
Exports:
|
|
rexec()
|
|
|
|
--*/
|
|
|
|
#ident "@(#)rexec.c 5.3 3/8/91"
|
|
|
|
/******************************************************************
|
|
*
|
|
* TCP/IP Library Utility
|
|
*
|
|
* Copyright 1990 Spider Systems Limited
|
|
*
|
|
* REXEC.C
|
|
*
|
|
* Remote execution library routine
|
|
*
|
|
******************************************************************/
|
|
|
|
|
|
/*
|
|
* /usr/projects/tcp/SCCS.rel3/rel/src/lib/net/0/s.rexec.c
|
|
* @(#)rexec.c 5.3
|
|
*
|
|
* Last delta created 14:11:32 3/4/91
|
|
* This file extracted 11:20:29 3/8/91
|
|
*
|
|
* Modifications:
|
|
*
|
|
* 1 June 1990 (RAE) Ported from Berkeley Version
|
|
*/
|
|
|
|
/*
|
|
* Copyright (c) 1980 Regents of the University of California.
|
|
* All rights reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms are permitted
|
|
* provided that the above copyright notice and this paragraph are
|
|
* duplicated in all such forms and that any documentation,
|
|
* advertising materials, and other materials related to such
|
|
* distribution and use acknowledge that the software was developed
|
|
* by the University of California, Berkeley. The name of the
|
|
* University may not be used to endorse or promote products derived
|
|
* from this software without specific prior written permission.
|
|
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
|
|
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
|
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
|
*/
|
|
/**************************************************************************/
|
|
|
|
#include "local.h"
|
|
# include "sockutil.h"
|
|
# include "nls.h"
|
|
|
|
#define bcopy(x,y,z) strncpy(y,x,z)
|
|
|
|
#define sleep(timeInMillisec) Sleep((timeInMillisec)) // pick up windows sleep
|
|
|
|
|
|
extern
|
|
void
|
|
ruserpass(
|
|
char *host,
|
|
char **aname,
|
|
char **apass
|
|
);
|
|
|
|
int rexecoptions;
|
|
|
|
/**************************************************************************/
|
|
SOCKET
|
|
rexec(
|
|
IN char **ahost,
|
|
IN unsigned short rport,
|
|
IN char *name,
|
|
IN char *pass,
|
|
IN char *cmd,
|
|
OUT SOCKET *fd2p OPTIONAL
|
|
)
|
|
/**************************************************************************/
|
|
{
|
|
struct sockaddr_in sin, sin2, lsin, from;
|
|
struct hostent *hp;
|
|
u_short port;
|
|
SOCKET s, s3;
|
|
int timo = 1;
|
|
char c;
|
|
unsigned long host_addr;
|
|
struct fd_set readfds, writefds, exceptfds;
|
|
|
|
host_addr = inet_addr(*ahost);
|
|
if (host_addr != INADDR_NONE) {
|
|
|
|
/* we have a valid IP address, so we can still continue */
|
|
sin.sin_family = AF_INET;
|
|
memcpy((caddr_t)&sin.sin_addr, &host_addr, 4);
|
|
|
|
} else {
|
|
|
|
hp = gethostbyname(*ahost);
|
|
if ( hp == NULL ) {
|
|
// fprintf(stderr, "%s: unknown host\n", *ahost);
|
|
//
|
|
// NlsEnabled ( MuraliK) 10-19-94
|
|
//
|
|
NlsPutMsg( STDERR, IDS_UNKNOWN_HOST, *ahost);
|
|
return (INVALID_SOCKET);
|
|
}
|
|
|
|
*ahost = hp->h_name;
|
|
sin.sin_family = (short) hp->h_addrtype;
|
|
memcpy((caddr_t)&sin.sin_addr, hp->h_addr, hp->h_length);
|
|
}
|
|
|
|
ruserpass(*ahost, &name, &pass);
|
|
|
|
retry:
|
|
s = socket(AF_INET, SOCK_STREAM, 0);
|
|
if (s == INVALID_SOCKET) {
|
|
perror("rexec: socket");
|
|
return (INVALID_SOCKET);
|
|
}
|
|
|
|
memset((char *)&lsin, 0, sizeof (lsin));
|
|
lsin.sin_family = (short) sin.sin_family;
|
|
|
|
if (bind(s, (struct sockaddr *) &lsin, sizeof (lsin)) < 0) {
|
|
if (GetLastError() == WSAENETDOWN) {
|
|
// fprintf(stderr, "The network is down\n");
|
|
//
|
|
// Nls Enabled ( MuraliK) 10-19-94
|
|
//
|
|
NlsPutMsg( STDERR, IDS_NETWORK_IS_DOWN);
|
|
} else {
|
|
// perror("rexec: bind");
|
|
//
|
|
// Nls Enabled ( MuraliK) 10-19-94
|
|
//
|
|
NlsPerror( IDS_BIND_FAILED, GetLastError() );
|
|
}
|
|
return ( INVALID_SOCKET);
|
|
}
|
|
|
|
sin.sin_port = rport;
|
|
|
|
if (connect(s, (struct sockaddr *) &sin, sizeof(sin)) < 0) {
|
|
if (GetLastError() == WSAECONNREFUSED && timo <= 16) {
|
|
closesocket(s);
|
|
sleep(timo * 1000);
|
|
timo *= 2;
|
|
goto retry;
|
|
}
|
|
perror("rexec:connect");
|
|
return ( INVALID_SOCKET);
|
|
}
|
|
|
|
if (fd2p == 0) {
|
|
(void) send(s, "", 1, 0);
|
|
port = 0;
|
|
} else {
|
|
char num[8];
|
|
SOCKET s2;
|
|
int sin2len;
|
|
|
|
s2 = socket(AF_INET, SOCK_STREAM, 0);
|
|
if (s2 == INVALID_SOCKET) {
|
|
closesocket(s);
|
|
return (INVALID_SOCKET);
|
|
}
|
|
|
|
memset((char *)&sin2, 0, sizeof (sin2));
|
|
sin2.sin_family = (short) sin.sin_family;
|
|
|
|
if (bind(s2, (struct sockaddr *)&sin2, sizeof (sin2)) < 0) {
|
|
if (GetLastError() == WSAENETDOWN) {
|
|
// fprintf(stderr, "The network is down\n");
|
|
//
|
|
// Nls Enabled ( MuraliK) 10-19-94
|
|
//
|
|
NlsPutMsg( STDERR, IDS_NETWORK_IS_DOWN);
|
|
} else {
|
|
// perror("rexec: bind");
|
|
//
|
|
// Nls Enabled ( MuraliK) 10-19-94
|
|
//
|
|
NlsPerror( IDS_BIND_FAILED, GetLastError());
|
|
}
|
|
return ( INVALID_SOCKET);
|
|
}
|
|
|
|
listen(s2, 1);
|
|
|
|
sin2len = sizeof (sin2);
|
|
|
|
if (getsockname(s2, (struct sockaddr *) &sin2, &sin2len) < 0 ||
|
|
sin2len != sizeof (sin2)) {
|
|
perror("rexec: getsockname");
|
|
closesocket(s2);
|
|
goto bad;
|
|
}
|
|
|
|
port = (u_short) ntohs( (u_short) sin2.sin_port );
|
|
(void) sprintf(num, "%u", port);
|
|
(void) send(s, num, strlen(num)+1, 0);
|
|
|
|
{
|
|
int len = sizeof (from);
|
|
|
|
FD_ZERO( &readfds );
|
|
FD_ZERO( &writefds );
|
|
FD_ZERO( &exceptfds );
|
|
FD_SET( s, &exceptfds ); // check for disconnects
|
|
FD_SET( s2, &readfds ); // check for connects
|
|
|
|
// wait for accept from remote host or disconect
|
|
// (some machines will just drop the connection if they
|
|
// can't resolve your host name - Suns in particular).
|
|
//
|
|
if (select(2, &readfds, &writefds, &exceptfds, NULL) < 0) {
|
|
errno = GetLastError();
|
|
perror("Select failed");
|
|
closesocket(s2);
|
|
port = 0;
|
|
goto bad;
|
|
}
|
|
|
|
if ( FD_ISSET( s2, &readfds ) ) {
|
|
// received a connect request from remote host
|
|
|
|
s3 = accept(s2, (struct sockaddr *)&from, &len);
|
|
closesocket(s2);
|
|
if (s3 == INVALID_SOCKET) {
|
|
perror("rexec: accept");
|
|
port = 0;
|
|
goto bad;
|
|
}
|
|
}
|
|
else {
|
|
if ( FD_ISSET( s, &exceptfds ) ) {
|
|
// The remote side disconnected before completing
|
|
// the connect of the second socket.
|
|
closesocket(s2);
|
|
port = 0;
|
|
goto bad;
|
|
}
|
|
else {
|
|
//
|
|
// if we ever get here, something is very wrong.
|
|
//
|
|
closesocket(s2);
|
|
port = 0;
|
|
goto bad;
|
|
}
|
|
}
|
|
}
|
|
*fd2p = s3;
|
|
}
|
|
(void) send(s, name, strlen(name) + 1, 0);
|
|
|
|
/*
|
|
* should public key encypt the password here
|
|
*/
|
|
(void) send(s, pass, strlen(pass) + 1, 0);
|
|
(void) send(s, cmd, strlen(cmd) + 1, 0);
|
|
if (recv(s, &c, 1, 0) != 1) {
|
|
perror(*ahost);
|
|
goto bad;
|
|
}
|
|
if (c != 0) {
|
|
_write(2, *ahost, strlen(*ahost));
|
|
_write(2, ": ", 2);
|
|
while (recv(s, &c, 1, 0) == 1) {
|
|
(void) _write(2, &c, 1);
|
|
if (c == '\n')
|
|
break;
|
|
}
|
|
goto bad;
|
|
}
|
|
return (s);
|
|
|
|
bad:
|
|
if (port)
|
|
closesocket(*fd2p);
|
|
closesocket(s);
|
|
return (INVALID_SOCKET);
|
|
}
|