Windows NT 4.0 source code leak
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

/*++
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);
}