Leaked source code of windows server 2003
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.
 
 
 
 
 
 

521 lines
16 KiB

/*++
Copyright (c) 2001 Microsoft Corporation
Module Name:
namedpipes.cxx
Abstract:
namedpipes
Author:
Larry Zhu (LZhu) January 1, 2002 Created
Environment:
User Mode
Revision History:
--*/
#include "precomp.hxx"
#pragma hdrstop
#include "namedpipes.hxx"
PCTSTR g_pszPipeName = TEXT("pipetest");
HRESULT
GetClientImpToken(
IN ULONG ProcessId,
IN OPTIONAL PCWSTR pszS4uClientUpn,
IN OPTIONAL PCWSTR pszS4uClientRealm,
IN ULONG S4u2SelfFlags,
OUT HANDLE* phToken
)
{
THResult hRetval = S_OK;
UNICODE_STRING ClientUpn = {0};
UNICODE_STRING ClientRealm = {0};
UNICODE_STRING Password = {0}; // ignored
ULONG PackageId = 0;
HANDLE hLsa = NULL;
HANDLE hImpToken = NULL;
TPrivilege* pPriv = NULL;
*phToken = NULL;
if (ProcessId)
{
hRetval DBGCHK = GetProcessTokenByProcessId(ProcessId, &hImpToken);
}
else if (pszS4uClientRealm || pszS4uClientUpn)
{
RtlInitUnicodeString(&ClientRealm, pszS4uClientRealm);
RtlInitUnicodeString(&ClientUpn, pszS4uClientUpn);
pPriv = new TPrivilege(SE_TCB_PRIVILEGE, TRUE);
hRetval DBGCHK = pPriv ? pPriv->Validate() : E_OUTOFMEMORY;
if (SUCCEEDED(hRetval))
{
hRetval DBGCHK = GetLsaHandleAndPackageId(
MICROSOFT_KERBEROS_NAME_A,
&hLsa,
&PackageId
);
}
if (SUCCEEDED(hRetval))
{
hRetval DBGCHK = KrbLsaLogonUser(
hLsa,
PackageId,
Network, // this would cause S4u2self to be used
&ClientUpn,
&ClientRealm,
&Password, // ignored for s4u2self
S4u2SelfFlags, // Flags for s4u2self
&hImpToken
);
}
}
if (SUCCEEDED(hRetval))
{
*phToken = hImpToken;
hImpToken = NULL;
}
if (hImpToken)
{
CloseHandle(hImpToken);
}
if (pPriv)
{
delete pPriv;
}
if (hLsa)
{
LsaDeregisterLogonProcess(hLsa);
}
return hRetval;
}
DWORD WINAPI ClientThread(IN PVOID pvParam)
{
THResult hRetval = S_OK;
CHAR Request[MAX_PATH] = {0};
CHAR Reply[MAX_PATH] = {0};
ULONG cbRead = 0;
ULONG cbWritten = 0;
HANDLE hToken = NULL;
TImpersonation* pImper = NULL;
HANDLE hPipe = INVALID_HANDLE_VALUE;
SECURITY_ATTRIBUTES sa = {0};
TClientThreadParam* pClientParam = (TClientThreadParam *) pvParam;
SspiPrint(SSPI_LOG, TEXT("ClientThread entering processid %#x, pszPipeName %s, pszS4uClientRealm %s, pszS4uClientUpn %s, S4u2SelfFlags %#x, FlagsAndAttributes %#x\n"),
pClientParam->ProcessId, pClientParam->pszPipeName, pClientParam->pszS4uClientRealm, pClientParam->pszS4uClientUpn, pClientParam->S4u2SelfFlags, pClientParam->FlagsAndAttributes);
memset(Request, 0xef, sizeof(Request) - 1);
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.lpSecurityDescriptor = NULL; // default Dacl of caller
sa.bInheritHandle = TRUE;
hRetval DBGCHK = GetClientImpToken(
pClientParam->ProcessId,
pClientParam->pszS4uClientUpn,
pClientParam->pszS4uClientRealm,
pClientParam->S4u2SelfFlags,
&hToken
);
if (SUCCEEDED(hRetval) && hToken)
{
pImper = new TImpersonation(hToken);
hRetval DBGCHK = pImper ? pImper->Validate() : E_OUTOFMEMORY;
}
if (SUCCEEDED(hRetval))
{
SspiPrint(SSPI_LOG, TEXT("ClientPipeName %s\n"), pClientParam->pszPipeName);
hRetval DBGCHK = WaitNamedPipe(
pClientParam->pszPipeName,
60000
) ? S_OK : GetLastErrorAsHResult();
}
if (SUCCEEDED(hRetval))
{
hPipe = CreateFile(
pClientParam->pszPipeName,
GENERIC_WRITE | GENERIC_READ,
FILE_SHARE_WRITE | FILE_SHARE_READ,
&sa,
OPEN_EXISTING,
pClientParam->FlagsAndAttributes ? pClientParam->FlagsAndAttributes : (SECURITY_SQOS_PRESENT | SECURITY_IMPERSONATION),
NULL
);
hRetval DBGCHK = (INVALID_HANDLE_VALUE != hPipe) ? S_OK : GetLastErrorAsHResult();
}
if (SUCCEEDED(hRetval))
{
hRetval DBGCHK = WriteFile(
hPipe, // handle to pipe
Request, // buffer to write from
sizeof(Request) - 1, // number of bytes to write
&cbWritten, // number of bytes written
NULL // not overlapped I/O
) ? S_OK : GetLastErrorAsHResult();
}
if (SUCCEEDED(hRetval))
{
hRetval DBGCHK = ReadFile(
hPipe, // handle to pipe
Reply, // buffer to receive data
sizeof(Reply), // size of buffer
&cbRead, // number of bytes read
NULL // not overlapped I/O
) ? S_OK : GetLastErrorAsHResult();
}
if (SUCCEEDED(hRetval))
{
SspiPrintHex(SSPI_LOG, TEXT("Reply"), cbRead, Reply);
}
if (hToken)
{
CloseHandle(hToken);
}
if (hPipe != INVALID_HANDLE_VALUE)
{
CloseHandle(hPipe);
}
if (pImper)
{
delete pImper;
}
SspiPrint(SSPI_LOG, TEXT("ClientThread leaving %#x\n"), (HRESULT) hRetval);
return (HRESULT) hRetval;
}
DWORD WINAPI ServerWokerThread(IN PVOID pvParam)
{
THResult hRetval = S_OK;
CHAR Request[MAX_PATH] = {0};
CHAR Reply[MAX_PATH] = {0};
ULONG cbBytesRead = 0;
ULONG cbWritten = 0;
HANDLE hToken = NULL;
TServerWorkerThreadParam* pServerParam = (TServerWorkerThreadParam*) pvParam;
SspiPrint(SSPI_LOG, TEXT("ServerWokerThread entering ServerPipe is %p, pszCommandLine %s\n"), pServerParam->hPipe, pServerParam->pszCommandLine);
memset(Reply, 0xfe, sizeof(Reply) - 1);
hRetval DBGCHK = ImpersonateNamedPipeClient(pServerParam->hPipe) ? S_OK : GetLastErrorAsHResult();
if (SUCCEEDED(hRetval))
{
hRetval DBGCHK = ReadFile(
pServerParam->hPipe, // handle to pipe
Request, // buffer to receive data
sizeof(Request), // size of buffer
&cbBytesRead, // number of bytes read
NULL // not overlapped I/O
) ? S_OK : GetLastErrorAsHResult();
}
if (SUCCEEDED(hRetval))
{
SspiPrintHex(SSPI_LOG, TEXT("Request"), cbBytesRead, Request);
hRetval DBGCHK = WriteFile(
pServerParam->hPipe, // handle to pipe
Reply, // buffer to write from
sizeof(Reply) - 1, // number of bytes to write
&cbWritten, // number of bytes written
NULL // not overlapped I/O
) ? S_OK : GetLastErrorAsHResult();
}
if (SUCCEEDED(hRetval) && pServerParam->pszCommandLine)
{
hRetval DBGCHK = OpenThreadToken(
GetCurrentThread(),
MAXIMUM_ALLOWED,
TRUE,
&hToken
) ? S_OK : GetLastErrorAsHResult();
if (SUCCEEDED(hRetval))
{
hRetval DBGCHK = StartInteractiveClientProcessAsUser(
hToken,
pServerParam->pszCommandLine
);
}
}
RevertToSelf();
if (hToken)
{
CloseHandle(hToken);
}
FlushFileBuffers(pServerParam->hPipe);
DisconnectNamedPipe(pServerParam->hPipe);
CloseHandle(pServerParam->hPipe);
pServerParam->hPipe = INVALID_HANDLE_VALUE;
SspiPrint(SSPI_LOG, TEXT("ServerWokerThread leaving %#x\n"), (HRESULT) hRetval);
return (HRESULT) hRetval;
}
VOID
Usage(
IN PCTSTR pszProgram
)
{
SspiPrint(SSPI_ERROR,
TEXT("Usage: %s [-noclient] [-noserver] [-pipename <pipename>] [-application <application>]\n")
TEXT("[-s4uclientupn <clientupn>] [-s4uclientrealm <clientrealm>] [-s4u2selfflags <flags>]\n")
TEXT("[-clientprocessidtoimperonate <processid>] [-clientflagsandattributes <flagsandattributes>]\n"), pszProgram);
exit(-1);
}
VOID __cdecl
_tmain(
IN INT argc,
IN PTSTR argv[]
)
{
THResult hRetval = S_OK;
INT mark = 1;
BOOLEAN bStartClient = TRUE;
BOOLEAN bStartServer = TRUE;
PCTSTR pszPipeName = g_pszPipeName;
ULONG tid = 0;
HANDLE hClientThread = NULL;
HANDLE hServerWorkerThread = NULL;
TClientThreadParam ClientParam = {0};
TCHAR szClientPipeName[MAX_PATH] = {0};
TCHAR szServerPipeName[MAX_PATH] = {0};
PTSTR pszServerHost = NULL;
PTSTR pszCommandLine = NULL;
SECURITY_ATTRIBUTES sa = {0};
SECURITY_DESCRIPTOR sd = {0};
BYTE AclBuf[ 64 ] = {0};
DWORD cbAcl = sizeof(AclBuf);
PACL pAcl = (PACL)AclBuf;
argc--;
while (argc)
{
if (!lstrcmp(argv[mark], TEXT("-port")) && (argc > 1))
{
argc--; mark++;
pszPipeName = argv[mark];
argc--; mark++;
}
else if (!lstrcmp(argv[mark], TEXT("-application")) && (argc > 1))
{
argc--; mark++;
pszCommandLine = argv[mark];
argc--; mark++;
}
else if (!lstrcmp(argv[mark], TEXT("-su4clientupn")) && (argc > 1))
{
argc--; mark++;
ClientParam.pszS4uClientUpn = argv[mark];
argc--; mark++;
}
else if (!lstrcmp(argv[mark], TEXT("-clientflagsandattributes")) && (argc > 1))
{
argc--; mark++;
ClientParam.FlagsAndAttributes = lstrtol(argv[mark], NULL, 0);
argc--; mark++;
}
else if (!lstrcmp(argv[mark], TEXT("-su42selfflags")) && (argc > 1))
{
argc--; mark++;
ClientParam.S4u2SelfFlags = lstrtol(argv[mark], NULL, 0);
argc--; mark++;
}
else if (!lstrcmp(argv[mark], TEXT("-clientprocessidtoimperonate")) && (argc > 1))
{
argc--; mark++;
ClientParam.ProcessId = lstrtol(argv[mark], NULL, 0);
argc--; mark++;
}
else if (!lstrcmp(argv[mark], TEXT("-serverhost")) && (argc > 1))
{
argc--; mark++;
pszServerHost = argv[mark];
bStartServer = FALSE;
argc--; mark++;
}
else if (!lstrcmp(argv[mark], TEXT("-noclient")))
{
argc--; mark++;
bStartClient = FALSE;
}
else if (!lstrcmp(argv[mark],TEXT("-noserver")))
{
argc--; mark++;
bStartServer = FALSE;
}
else
{
Usage(argv[0]);
}
}
SspiLogOpen(TEXT("namedports.exe"), SSPI_LOG | SSPI_WARN | SSPI_ERROR);
if (bStartClient)
{
ClientParam.pszPipeName = szClientPipeName;
hRetval DBGCHK = _sntprintf(szClientPipeName, COUNTOF(szClientPipeName) - 1,
TEXT("\\\\%s\\pipe\\%s"),
pszServerHost ? pszServerHost : TEXT("."),
pszPipeName
) > 0 ? S_OK : E_INVALIDARG;
}
if (SUCCEEDED(hRetval) && bStartServer)
{
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.lpSecurityDescriptor = &sd;
sa.bInheritHandle = TRUE;
hRetval DBGCHK = BuildNamedPipeAcl(pAcl, &cbAcl) ? S_OK : GetLastErrorAsHResult();
if (SUCCEEDED(hRetval))
{
hRetval DBGCHK = InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION) ? S_OK : GetLastErrorAsHResult();
}
if (SUCCEEDED(hRetval))
{
hRetval DBGCHK = SetSecurityDescriptorDacl(&sd, TRUE, pAcl, FALSE) ? S_OK : GetLastErrorAsHResult();
}
if (SUCCEEDED(hRetval))
{
hRetval DBGCHK = _sntprintf(szServerPipeName, COUNTOF(szServerPipeName) - 1,
TEXT("\\\\.\\pipe\\%s"),
pszPipeName
) > 0 ? S_OK : E_INVALIDARG;
}
}
if (SUCCEEDED(hRetval) && bStartClient)
{
hClientThread = CreateThread(NULL, 0, ClientThread, &ClientParam, 0, &tid);
hRetval DBGCHK = hClientThread ? S_OK : GetLastErrorAsHResult();
}
while (SUCCEEDED(hRetval) && bStartServer)
{
TServerWorkerThreadParam ServerParam = {0};
SspiPrint(SSPI_LOG, TEXT("Server waiting on pipe %s\n"), szServerPipeName);
ServerParam.pszCommandLine = pszCommandLine;
ServerParam.hPipe = CreateNamedPipe(
szServerPipeName,
PIPE_ACCESS_DUPLEX,
PIPE_TYPE_BYTE | PIPE_WAIT,
1,
4096, // output buffer size
4096, // input buffer size
NMPWAIT_USE_DEFAULT_WAIT, // timeout interval
&sa
);
hRetval DBGCHK = (ServerParam.hPipe != INVALID_HANDLE_VALUE) ? S_OK : GetLastErrorAsHResult();
if (SUCCEEDED(hRetval))
{
hRetval DBGCHK = ConnectNamedPipe(
ServerParam.hPipe,
NULL // no overlapped structure
) ? S_OK : GetLastErrorAsHResult();
if (FAILED(hRetval) && (ERROR_PIPE_CONNECTED == HRESULT_CODE(hRetval)))
{
hRetval DBGCHK = S_OK;
}
}
if (SUCCEEDED(hRetval))
{
hServerWorkerThread = CreateThread(NULL, 0, ServerWokerThread, &ServerParam, 0, &tid);
hRetval DBGCHK = hServerWorkerThread ? S_OK : GetLastErrorAsHResult();
if (FAILED(hRetval))
{
CloseHandle(ServerParam.hPipe);
ServerParam.hPipe = INVALID_HANDLE_VALUE;
}
else
{
(VOID) WaitForSingleObject(hServerWorkerThread, INFINITE);
}
if (hServerWorkerThread)
{
CloseHandle(hServerWorkerThread);
}
}
else if (ServerParam.hPipe != INVALID_HANDLE_VALUE)
{
CloseHandle(ServerParam.hPipe);
}
}
if (SUCCEEDED(hRetval) && hClientThread)
{
(VOID) WaitForSingleObject(hClientThread, INFINITE);
}
if (hClientThread)
{
CloseHandle(hClientThread);
}
SspiLogClose();
}