Source code of Windows XP (NT5)
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.
 
 
 
 
 
 

618 lines
16 KiB

//+---------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1992 - 1993.
//
// File: logon2.c
//
// Contents: Logon test app
//
// Classes:
//
// Functions:
//
// History: 6-20-94 richardw Created
//
//----------------------------------------------------------------------------
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <nt.h>
#include <ntrtl.h>
#include <nturtl.h>
#include <ntlsa.h>
#include <windows.h>
#define DUMP_TOKEN 1
#define DUMP_HEX 2
char *User = NULL;
char *Domain = NULL;
char *Password = NULL;
char *SecPackage = NULL;
char *Cmd = NULL;
DWORD fLogon = 0;
DWORD fMe = 0;
DWORD fService = 0;
DWORD fCookie = 0;
FILE * fOut;
DWORD Threads;
DWORD fDup = 0;
DWORD LogonType = LOGON32_LOGON_INTERACTIVE;
char * ImpLevels[] = { "Anonymous", "Identity", "Impersonation", "Delegation"};
char * LogonTypes[] = { "Invalid", "Invalid", "Interactive", "Network", "Batch", "Service", "Proxy" };
void DumpToken(HANDLE hToken);
void
DoArgs(int argc,
char **argv)
{
int i;
Threads = 1;
if (argc < 3)
{
fprintf( fOut,"usage: %s <name> <domain> [-p pw] [-f flags] [-s] [-d] [-x cmd]\n", argv[0]);
fprintf( fOut,"Tests logon path\n");
fprintf( fOut," -p \tOverride password\n");
fprintf( fOut," -D \tDump token\n");
fprintf( fOut," -d \tduplicate\n");
fprintf( fOut," -s \tLogon as service\n");
fprintf( fOut," -x cmd \tStart cmd as user\n");
fprintf( fOut," -o file\tSend output to file\n");
fprintf( fOut," -t # \tHit with # threads at once\n");
fprintf( fOut," -l type\tLogon type\n");
exit(1);
}
for (i = 1; i < argc ; i++ )
{
if (*argv[i] == '-')
{
switch (*(argv[i]+1))
{
case 'f':
fLogon = atoi(argv[++i]);
break;
case 'd':
fDup = 1;
break;
case 'D':
fMe |= DUMP_TOKEN;
break;
case 'x':
Cmd = argv[++i];
break;
case 'p':
Password = argv[++i];
break;
case 't':
Threads = atoi(argv[++i]);
break;
case 's':
LogonType = LOGON32_LOGON_SERVICE;
break;
case 'l':
++i;
if (argv[i] == NULL )
{
fprintf(fOut, "No logon type specified\n");
exit(1);
}
for (LogonType = 2 ;
LogonType < sizeof(LogonTypes) / sizeof(PSTR) ;
LogonType ++ )
{
if (_stricmp( LogonTypes[LogonType], argv[i]) == 0 )
{
break;
}
}
if (LogonType == (sizeof(LogonTypes) / sizeof(PSTR) ))
{
fprintf(fOut, "Invalid logon type '%s'\n", argv[i]);
exit(1);
}
break;
case 'o':
fOut = fopen(argv[++i], "w");
if (!fOut)
{
fOut = stderr;
}
break;
default:
fprintf( fOut,"Invalid switch %s\n", argv[i]);
exit(1);
}
}
else
{
if (!User)
User = argv[i];
else
if (!Domain)
Domain = argv[i];
}
}
if (!Password)
Password = User;
}
DWORD
DoIt(
PVOID pv)
{
NTSTATUS scRet, SubStatus, Status;
PISID pSid;
LUID Luid;
TOKEN_GROUPS TokenGroups;
STRING sMe;
HANDLE hToken;
HANDLE hImp;
HANDLE hDup;
STRING sPackage;
ULONG Package;
LUID LogonId;
TOKEN_SOURCE TokenSource;
char ImpersonateName[MAX_PATH];
DWORD cbImpersonateName = MAX_PATH;
STARTUPINFO si;
PROCESS_INFORMATION pi;
POBJECT_TYPE_INFORMATION pTypeInfo;
POBJECT_NAME_INFORMATION pNameInfo;
POBJECT_BASIC_INFORMATION pBasicInfo;
UCHAR Buffer[1024];
HANDLE hWait;
hWait = (HANDLE) pv;
if (hWait != NULL)
{
WaitForSingleObjectEx( hWait, INFINITE, FALSE );
}
fprintf( fOut,"Logging on %s to %s\n", User, Domain);
//
// Copy the strings into the right places:
//
if (!LogonUserA(User, Domain, Password,
LogonType,
LOGON32_PROVIDER_DEFAULT, &hToken))
{
fprintf( fOut,"FAILED to logon, GetLastError is %d\n", GetLastError());
}
else
{
if (fMe & DUMP_TOKEN)
DumpToken(hToken);
if (!ImpersonateLoggedOnUser(hToken))
{
fprintf( fOut, "FAILED to impersonate, GetLastError is %d\n", GetLastError());
}
GetUserName(ImpersonateName, &cbImpersonateName);
if (fDup)
{
if (OpenThreadToken( GetCurrentThread(),
MAXIMUM_ALLOWED,
TRUE,
&hImp))
{
DumpToken( hImp );
if (DuplicateTokenEx( hImp,
MAXIMUM_ALLOWED,
NULL,
SecurityImpersonation,
TokenPrimary,
&hDup ) )
{
fprintf( fOut, "Success! Duplicated that token!\n");
DumpToken( hToken );
CloseHandle( hToken );
}
else
{
fprintf( fOut, "DuplicateTokenEx FAILED, %d\n", GetLastError() );
}
CloseHandle( hImp );
}
else
{
fprintf( fOut, "OpenThreadToken FAILED, %d\n", GetLastError() );
}
}
RevertToSelf();
fprintf( fOut,"Hey look! I'm %s\n", ImpersonateName);
if (Cmd)
{
fprintf( fOut,"Starting '%s' as user\n", Cmd);
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
if (!CreateProcessAsUser(hToken, NULL, Cmd, NULL, NULL, FALSE,
CREATE_SEPARATE_WOW_VDM, NULL,
NULL, &si, &pi))
{
fprintf( fOut,"FAILED, %d\n", GetLastError());
}
fprintf( fOut,"Process Info:\n");
fprintf( fOut," Process Handle \t%x\n", pi.hProcess );
fprintf( fOut," Thread Handle \t%x\n", pi.hThread );
fprintf( fOut," Process Id \t%d\n", pi.dwProcessId );
fprintf( fOut," Thread Id \t%d\n", pi.dwThreadId );
ZeroMemory( Buffer, 1024 );
pTypeInfo = (POBJECT_TYPE_INFORMATION) Buffer;
pNameInfo = (POBJECT_NAME_INFORMATION) Buffer;
pBasicInfo = (POBJECT_BASIC_INFORMATION) Buffer;
Status = NtQueryObject( pi.hProcess, ObjectTypeInformation, pTypeInfo, 1024, NULL );
if (NT_SUCCESS(Status))
{
fprintf( fOut," Type \t%ws\n", pTypeInfo->TypeName.Buffer );
}
ZeroMemory( Buffer, 1024 );
Status = NtQueryObject(pi.hProcess, ObjectBasicInformation, pBasicInfo, 1024, NULL);
if (NT_SUCCESS(Status))
{
fprintf( fOut," Attributes \t%#x\n", pBasicInfo->Attributes );
fprintf( fOut," GrantedAccess\t%#x\n", pBasicInfo->GrantedAccess );
fprintf( fOut," HandleCount \t%d\n", pBasicInfo->HandleCount );
fprintf( fOut," PointerCount \t%d\n", pBasicInfo->PointerCount );
}
else
{
fprintf( fOut,"FAILED %x to query basic info\n", Status );
}
ZeroMemory( Buffer, 1024 );
Status = NtQueryObject( pi.hProcess, ObjectNameInformation, pNameInfo, 1024, NULL );
if (NT_SUCCESS(Status))
{
fprintf( fOut," Name \t%ws\n", pNameInfo->Name.Buffer);
}
else
{
fprintf( fOut,"FAILED %x to query name info\n", Status );
}
CloseHandle( pi.hProcess );
CloseHandle( pi.hThread );
}
CloseHandle(hToken);
}
return(0);
}
__cdecl
main (int argc, char *argv[])
{
HANDLE hWait;
DWORD i;
DWORD tid;
HANDLE hThreads[64];
fOut = stdout;
//
// Get params
//
DoArgs(argc, argv);
if (Threads == 1)
{
DoIt(NULL);
}
else
{
if (Threads > 64 )
{
Threads = 64;
}
hWait = CreateEvent( NULL, TRUE, FALSE, NULL );
for (i = 0; i < Threads ; i++ )
{
hThreads[i] = CreateThread( NULL, 0, DoIt, hWait, 0, &tid);
}
SetEvent( hWait );
WaitForMultipleObjectsEx( Threads, hThreads, TRUE, INFINITE, FALSE );
for ( i = 0 ; i < Threads ; i++ )
{
CloseHandle( hThreads[i] );
}
}
return( 0 );
}
#define SATYPE_USER 1
#define SATYPE_GROUP 2
#define SATYPE_PRIV 3
ULONG PID;
void
DumpSid(PSID pxSid)
{
PISID pSid = pxSid;
int i, j =0;
fprintf( fOut," S-%d-", pSid->Revision);
for (i = 0;i < 6 ; i++ )
{
if (j)
{
fprintf( fOut,"%x", pSid->IdentifierAuthority.Value[i]);
}
else
{
if (pSid->IdentifierAuthority.Value[i])
{
j = 1;
fprintf( fOut,"%x", pSid->IdentifierAuthority.Value[i]);
}
}
if (i==4)
{
j = 1;
}
}
for (i = 0; i < pSid->SubAuthorityCount ; i++ )
{
fprintf( fOut,(fMe & DUMP_HEX ? "-%x" : "-%lu"), pSid->SubAuthority[i]);
}
}
void
DumpSidAttr(PSID_AND_ATTRIBUTES pSA,
int SAType)
{
DumpSid(pSA->Sid);
if (SAType == SATYPE_GROUP)
{
fprintf( fOut,"\tAttributes - ");
if (pSA->Attributes & SE_GROUP_MANDATORY)
{
fprintf( fOut,"Mandatory ");
}
if (pSA->Attributes & SE_GROUP_ENABLED_BY_DEFAULT)
{
fprintf( fOut,"Default ");
}
if (pSA->Attributes & SE_GROUP_ENABLED)
{
fprintf( fOut,"Enabled ");
}
if (pSA->Attributes & SE_GROUP_OWNER)
{
fprintf( fOut,"Owner ");
}
if (pSA->Attributes & SE_GROUP_LOGON_ID)
{
fprintf( fOut,"LogonId ");
}
}
}
CHAR * GetPrivName(PLUID pPriv)
{
switch (pPriv->LowPart)
{
case SE_CREATE_TOKEN_PRIVILEGE:
return(SE_CREATE_TOKEN_NAME);
case SE_ASSIGNPRIMARYTOKEN_PRIVILEGE:
return(SE_ASSIGNPRIMARYTOKEN_NAME);
case SE_LOCK_MEMORY_PRIVILEGE:
return(SE_LOCK_MEMORY_NAME);
case SE_INCREASE_QUOTA_PRIVILEGE:
return(SE_INCREASE_QUOTA_NAME);
case SE_UNSOLICITED_INPUT_PRIVILEGE:
return(SE_UNSOLICITED_INPUT_NAME);
case SE_TCB_PRIVILEGE:
return(SE_TCB_NAME);
case SE_SECURITY_PRIVILEGE:
return(SE_SECURITY_NAME);
case SE_TAKE_OWNERSHIP_PRIVILEGE:
return(SE_TAKE_OWNERSHIP_NAME);
case SE_LOAD_DRIVER_PRIVILEGE:
return(SE_LOAD_DRIVER_NAME);
case SE_SYSTEM_PROFILE_PRIVILEGE:
return(SE_SYSTEM_PROFILE_NAME);
case SE_SYSTEMTIME_PRIVILEGE:
return(SE_SYSTEMTIME_NAME);
case SE_PROF_SINGLE_PROCESS_PRIVILEGE:
return(SE_PROF_SINGLE_PROCESS_NAME);
case SE_INC_BASE_PRIORITY_PRIVILEGE:
return(SE_INC_BASE_PRIORITY_NAME);
case SE_CREATE_PAGEFILE_PRIVILEGE:
return(SE_CREATE_PAGEFILE_NAME);
case SE_CREATE_PERMANENT_PRIVILEGE:
return(SE_CREATE_PERMANENT_NAME);
case SE_BACKUP_PRIVILEGE:
return(SE_BACKUP_NAME);
case SE_RESTORE_PRIVILEGE:
return(SE_RESTORE_NAME);
case SE_SHUTDOWN_PRIVILEGE:
return(SE_SHUTDOWN_NAME);
case SE_DEBUG_PRIVILEGE:
return(SE_DEBUG_NAME);
case SE_AUDIT_PRIVILEGE:
return(SE_AUDIT_NAME);
case SE_SYSTEM_ENVIRONMENT_PRIVILEGE:
return(SE_SYSTEM_ENVIRONMENT_NAME);
case SE_CHANGE_NOTIFY_PRIVILEGE:
return(SE_CHANGE_NOTIFY_NAME);
case SE_REMOTE_SHUTDOWN_PRIVILEGE:
return(SE_REMOTE_SHUTDOWN_NAME);
default:
return("Unknown Privilege");
}
}
void
DumpLuidAttr(PLUID_AND_ATTRIBUTES pLA,
int LAType)
{
char * PrivName;
fprintf( fOut,"0x%x%08x", pLA->Luid.HighPart, pLA->Luid.LowPart);
fprintf( fOut," %-32s", GetPrivName(&pLA->Luid));
if (LAType == SATYPE_PRIV)
{
fprintf( fOut," Attributes - ");
if (pLA->Attributes & SE_PRIVILEGE_ENABLED)
{
fprintf( fOut,"Enabled ");
}
if (pLA->Attributes & SE_PRIVILEGE_ENABLED_BY_DEFAULT)
{
fprintf( fOut,"Default ");
}
}
}
void
DumpToken(HANDLE hToken)
{
PTOKEN_USER pTUser;
PTOKEN_GROUPS pTGroups;
PTOKEN_PRIVILEGES pTPrivs;
PTOKEN_OWNER pTOwner;
PTOKEN_PRIMARY_GROUP pTPrimaryGroup;
TOKEN_STATISTICS TStats;
ULONG cbInfo;
ULONG cbRetInfo;
NTSTATUS status;
DWORD i;
pTUser = malloc(256);
status = GetTokenInformation( hToken,
TokenUser,
pTUser,
256,
&cbRetInfo);
if (!NT_SUCCESS(status))
{
fprintf( fOut,"FAILED querying token, %#x\n", status);
return;
}
fprintf( fOut,"User\n ");
DumpSidAttr(&pTUser->User, SATYPE_USER);
fprintf( fOut,"\nGroups");
pTGroups = malloc(4096);
status = GetTokenInformation( hToken,
TokenGroups,
pTGroups,
4096,
&cbRetInfo);
for (i = 0; i < pTGroups->GroupCount ; i++ )
{
fprintf( fOut,"\n %02d ", i);
DumpSidAttr(&pTGroups->Groups[i], SATYPE_GROUP);
}
pTPrimaryGroup = malloc(128);
status = GetTokenInformation( hToken,
TokenPrimaryGroup,
pTPrimaryGroup,
128,
&cbRetInfo);
fprintf( fOut,"\nPrimary Group:\n ");
DumpSid(pTPrimaryGroup->PrimaryGroup);
fprintf( fOut,"\nPrivs\n");
pTPrivs = malloc(4096);
status = GetTokenInformation( hToken,
TokenPrivileges,
pTPrivs,
4096,
&cbRetInfo);
for (i = 0; i < pTPrivs->PrivilegeCount ; i++ )
{
fprintf( fOut,"\n %02d ", i);
DumpLuidAttr(&pTPrivs->Privileges[i], SATYPE_PRIV);
}
status = GetTokenInformation( hToken,
TokenStatistics,
&TStats,
sizeof(TStats),
&cbRetInfo);
fprintf( fOut, "\n\nAuth ID %x:%x\n", TStats.AuthenticationId.HighPart, TStats.AuthenticationId.LowPart);
fprintf( fOut, "TokenId %x:%x\n", TStats.TokenId.HighPart, TStats.TokenId.LowPart);
fprintf( fOut, "TokenType %s\n", TStats.TokenType == TokenPrimary ? "Primary" : "Impersonation");
fprintf( fOut, "Imp Level %s\n", ImpLevels[ TStats.ImpersonationLevel ]);
}