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.
 
 
 
 
 
 

1273 lines
30 KiB

//+---------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1992 - 1993.
//
// File: ticktest.cxx
//
// Contents: KDC Ticket granting service test code.
//
// Classes:
//
// Functions:
//
// History: 19-Aug-93 WadeR Created
//
//----------------------------------------------------------------------------
#include <secpch2.hxx>
#pragma hdrstop
#include <stdio.h>
#include <stdlib.h>
#include <kerbcomm.h>
#include <kerbcred.h>
extern "C"
{
#include <dsgetdc.h>
#include <kdcdbg.h>
}
UNICODE_STRING ClientName;
UNICODE_STRING ServiceName;
UNICODE_STRING ClientRealm;
UNICODE_STRING ServiceRealm;
UNICODE_STRING ClientPassword;
UNICODE_STRING ServicePassword;
UNICODE_STRING KdcName;
WCHAR KdcNameString[100];
ULONG AddressType = DS_NETBIOS_ADDRESS;
ULONG CryptType = KERB_ETYPE_RC4_MD4;
PVOID KdcBinding;
BOOLEAN
BindToKdc()
{
ULONG NetStatus;
PDOMAIN_CONTROLLER_INFO DcInfo = NULL;
if (KdcName.Buffer == NULL)
{
//
// No kdc specified, use DSGetDCName
//
NetStatus = DsGetDcName(
NULL,
ClientRealm.Buffer,
NULL,
NULL,
DS_KDC_REQUIRED,
&DcInfo
);
if (NetStatus != NO_ERROR)
{
printf("DsGetDcName returned %d\n",NetStatus);
return(FALSE);
}
RtlInitUnicodeString(
&KdcName,
DcInfo->DomainControllerAddress+2
);
AddressType = DcInfo->DomainControllerAddressType;
}
return(TRUE);
}
BOOLEAN
GetAnAsTicket(
IN PUNICODE_STRING ServerName,
OUT PKERB_TICKET Ticket,
OUT PKERB_ENCRYPTED_KDC_REPLY * ReplyBody,
OUT PKERB_KDC_REPLY * Reply
)
{
KERBERR KerbErr = KDC_ERR_NONE;
NTSTATUS Status = STATUS_SUCCESS;
KERB_ENCRYPTION_KEY UserKey;
KERB_MESSAGE_BUFFER InputMessage;
KERB_MESSAGE_BUFFER OutputMessage;
KERB_KDC_REQUEST Request;
PKERB_KDC_REQUEST_BODY RequestBody;
ULONG CryptArray[KERB_MAX_CRYPTO_SYSTEMS];
ULONG CryptArraySize;
UNICODE_STRING FullServiceName;
UNICODE_STRING FullClientName;
PKERB_ERROR ErrorMessage = NULL;
LARGE_INTEGER TempTime;
ULONG KdcFlagOptions = 0;
ULONG KdcOptions = 0;
BOOLEAN DoingSomething = FALSE;
RtlZeroMemory(
&OutputMessage,
sizeof(KERB_MESSAGE_BUFFER)
);
RtlZeroMemory(
&InputMessage,
sizeof(KERB_MESSAGE_BUFFER)
);
//
// Build the request
//
RtlZeroMemory(
&Request,
sizeof( KERB_KDC_REQUEST )
);
RequestBody = &Request.request_body;
KdcOptions =
KERB_KDC_OPTIONS_forwardable |
KERB_KDC_OPTIONS_proxiable |
KERB_KDC_OPTIONS_renewable |
KERB_KDC_OPTIONS_renewable_ok;
KdcFlagOptions = KerbConvertUlongToFlagUlong(KdcOptions);
RequestBody->kdc_options.value = (PUCHAR) &KdcFlagOptions ;
RequestBody->kdc_options.length = sizeof(ULONG) * 8;
RequestBody->nonce = 3;
TempTime.QuadPart = 0;
KerbConvertLargeIntToGeneralizedTime(
&RequestBody->KERB_KDC_REQUEST_BODY_starttime,
NULL,
&TempTime
);
TempTime.LowPart = 0xffffffff;
TempTime.HighPart = 0x7fffffff;
KerbConvertLargeIntToGeneralizedTime(
&RequestBody->KERB_KDC_REQUEST_BODY_renew_until,
NULL,
&TempTime
);
RequestBody->bit_mask |= KERB_KDC_REQUEST_BODY_renew_until_present;
TempTime.QuadPart = 0;
KerbConvertLargeIntToGeneralizedTime(
&RequestBody->endtime,
NULL,
&TempTime
);
//
// Build crypt vector.
//
CryptArraySize = KERB_MAX_CRYPTO_SYSTEMS;
CDBuildVect( &CryptArraySize, CryptArray );
KerbErr = KerbConvertArrayToCryptList(
&RequestBody->encryption_type,
CryptArray,
CryptArraySize
);
if (!KERB_SUCCESS(KerbErr))
{
printf("Failed to convert array to crypt list: 0x%x\n",KerbErr);
goto Cleanup;
}
//
// BUGBUG: don't build pre-auth data
//
KerbBuildFullServiceName(
&ClientRealm,
ServerName,
&FullServiceName
);
KerbErr = KerbConvertStringToPrincipalName(
&RequestBody->KERB_KDC_REQUEST_BODY_server_name,
&FullServiceName,
KRB_NT_MS_PRINCIPAL
);
if (!KERB_SUCCESS(KerbErr))
{
printf("Failed to convert string to principal name: 0x%x\n",KerbErr);
goto Cleanup;
}
RequestBody->bit_mask |= KERB_KDC_REQUEST_BODY_server_name_present;
KerbBuildFullServiceName(
&ClientRealm,
&ClientName,
&FullClientName
);
KerbErr = KerbConvertStringToPrincipalName(
&RequestBody->KERB_KDC_REQUEST_BODY_client_name,
&FullClientName,
KRB_NT_MS_PRINCIPAL
);
if (!KERB_SUCCESS(KerbErr))
{
printf("Failed to convert string to principal name: 0x%x\n",KerbErr);
goto Cleanup;
}
RequestBody->bit_mask |= KERB_KDC_REQUEST_BODY_client_name_present;
KerbErr = KerbConvertUnicodeStringToRealm(
&RequestBody->realm,
&ClientRealm
);
if (!KERB_SUCCESS(KerbErr))
{
printf("Failed to convert unicde string to realm: 0x%x\n",KerbErr);
goto Cleanup;
}
Request.version = KERBEROS_VERSION;
Request.message_type = KRB_AS_REQ;
KerbErr = KerbPackAsRequest(
&Request,
&InputMessage.BufferSize,
&InputMessage.Buffer
);
if (!KERB_SUCCESS(KerbErr))
{
printf("Failed to pack KDC request: 0x%x\n",KerbErr);
goto Cleanup;
}
Status = KerbCallKdc(
&KdcName,
AddressType,
10,
TRUE,
&InputMessage,
&OutputMessage
);
if (!NT_SUCCESS(Status))
{
printf("KerbCallKdc failed: 0x%x\n",Status);
KerbErr = KRB_ERR_GENERIC;
goto Cleanup;
}
KerbErr = KerbUnpackAsReply(
OutputMessage.Buffer,
OutputMessage.BufferSize,
Reply
);
if (!KERB_SUCCESS(KerbErr))
{
printf("Failed to unpack KDC reply: 0x%x\n",KerbErr);
KerbErr = KerbUnpackKerbError(
OutputMessage.Buffer,
OutputMessage.BufferSize,
&ErrorMessage
);
if (KERB_SUCCESS(KerbErr))
{
printf("Failed to get AS ticket: 0x%x\n",ErrorMessage->error_code);
KerbErr = (KERBERR) ErrorMessage->error_code;
}
goto Cleanup;
}
KerbErr = KerbHashPassword(
&ClientPassword,
(*Reply)->encrypted_part.encryption_type,
&UserKey
);
if (!KERB_SUCCESS(KerbErr))
{
printf("Failed to hash password with 0x%x alg\n",(*Reply)->encrypted_part.encryption_type);
goto Cleanup;
}
KerbErr = KerbUnpackKdcReplyBody(
&(*Reply)->encrypted_part,
&UserKey,
KERB_ENCRYPTED_AS_REPLY_PDU,
ReplyBody
);
if (!KERB_SUCCESS(KerbErr))
{
printf("Failed to unpack KDC reply body: 0x%x\n",KerbErr);
goto Cleanup;
}
*Ticket = (*Reply)->ticket;
Cleanup:
//
// BUGBUG: memory leak here
//
if (KERB_SUCCESS(KerbErr))
{
return(TRUE);
}
else
{
return(FALSE);
}
}
BOOLEAN
GetATgsTicket(
IN PKERB_TICKET TicketGrantingTicket,
IN PKERB_ENCRYPTED_KDC_REPLY TgtReplyBody,
IN PKERB_KDC_REPLY TgtReply,
IN BOOLEAN Renew,
OUT PKERB_TICKET Ticket,
OUT PKERB_ENCRYPTED_KDC_REPLY * ReplyBody,
OUT PKERB_KDC_REPLY * Reply
)
{
KERB_KDC_REQUEST Request;
PKERB_KDC_REQUEST_BODY RequestBody = &Request.request_body;
UNICODE_STRING FullServiceName;
PKERB_INTERNAL_NAME FullClientName;
KERBERR KerbErr;
KERB_PA_DATA_LIST PaData;
ULONG CryptArray[KERB_MAX_CRYPTO_SYSTEMS];
ULONG CryptArraySize = 0;
LARGE_INTEGER TempTime;
KERB_MESSAGE_BUFFER InputMessage;
KERB_MESSAGE_BUFFER OutputMessage;
PKERB_ERROR ErrorMessage = NULL;
ULONG NameType;
ULONG KdcFlagOptions = 0;
ULONG KdcOptions = 0;
//
// Build the request
//
RtlZeroMemory( &Request, sizeof( KERB_KDC_REQUEST ) );
KdcOptions = KERB_KDC_OPTIONS_forwardable |
KERB_KDC_OPTIONS_proxiable |
KERB_KDC_OPTIONS_renewable |
KERB_KDC_OPTIONS_renewable_ok;
if (Renew)
{
KdcOptions |= KERB_KDC_OPTIONS_renew;
}
KdcFlagOptions = KerbConvertUlongToFlagUlong(KdcOptions);
RequestBody->kdc_options.value = (PUCHAR) &KdcFlagOptions ;
RequestBody->kdc_options.length = sizeof(ULONG) * 8;
RequestBody->nonce = 4;
//
// Build an AP request inside an encrypted data structure.
//
KerbConvertPrincipalNameToKdcName(
&FullClientName,
&TgtReply->client_name
);
PaData.next = NULL;
PaData.value.preauth_data_type = KRB5_PADATA_TGS_REQ;
KerbErr = KerbCreateApRequest(
FullClientName,
&ClientRealm,
&TgtReplyBody->session_key,
NULL, // no sub session key
5, // nonce
TicketGrantingTicket,
0, // AP options
NULL, // gss checksum
NULL, // server time
TRUE, // KDC request
(PULONG) &PaData.value.preauth_data.length,
&PaData.value.preauth_data.value
);
if (!KERB_SUCCESS(KerbErr))
{
printf("Failed to create AP request: 0x%x\n",KerbErr);
goto Cleanup;
}
Request.KERB_KDC_REQUEST_preauth_data = &PaData;
Request.bit_mask |= KERB_KDC_REQUEST_preauth_data_present;
//
// Build crypt vector.
//
CDBuildVect( &CryptArraySize, CryptArray );
KerbErr = KerbConvertArrayToCryptList(
&RequestBody->encryption_type,
CryptArray,
CryptArraySize
);
if (!KERB_SUCCESS(KerbErr))
{
printf("Failed to convert array to crypt list: 0x%x\n",KerbErr);
goto Cleanup;
}
KerbErr = KerbDuplicatePrincipalName(
&RequestBody->KERB_KDC_REQUEST_BODY_client_name,
&TgtReply->client_name
);
if (!KERB_SUCCESS(KerbErr))
{
goto Cleanup;
}
RequestBody->bit_mask |= KERB_KDC_REQUEST_BODY_client_name_present;
KerbErr = KerbConvertUnicodeStringToRealm(
&RequestBody->realm,
&ClientRealm
);
if (!KERB_SUCCESS(KerbErr))
{
goto Cleanup;
}
KerbErr = KerbConvertStringToPrincipalName(
&RequestBody->KERB_KDC_REQUEST_BODY_server_name,
&ServiceName,
KRB_NT_MS_PRINCIPAL
);
if (!KERB_SUCCESS(KerbErr))
{
goto Cleanup;
}
RequestBody->bit_mask |= KERB_KDC_REQUEST_BODY_server_name_present;
TempTime.QuadPart = 0;
KerbConvertLargeIntToGeneralizedTime(
&RequestBody->KERB_KDC_REQUEST_BODY_starttime,
NULL,
&TempTime
);
TempTime.LowPart = 0xffffffff;
TempTime.HighPart = 0x7fffffff;
KerbConvertLargeIntToGeneralizedTime(
&RequestBody->KERB_KDC_REQUEST_BODY_renew_until,
NULL,
&TempTime
);
RequestBody->bit_mask |= KERB_KDC_REQUEST_BODY_renew_until_present;
TempTime.LowPart = 0xffffffff;
TempTime.HighPart = 0x7fffffff;
KerbConvertLargeIntToGeneralizedTime(
&RequestBody->endtime,
NULL,
&TempTime
);
Request.version = KERBEROS_VERSION;
Request.message_type = KRB_TGS_REQ;
KerbErr = KerbPackTgsRequest(
&Request,
&InputMessage.BufferSize,
&InputMessage.Buffer
);
if (!KERB_SUCCESS(KerbErr))
{
printf("Failed to pack KDC request: 0x%x\n",KerbErr);
goto Cleanup;
}
//
// Get the ticket.
//
OutputMessage.Buffer = NULL;
OutputMessage.BufferSize = 0;
KerbErr = (KERBERR) KerbCallKdc(
&KdcName,
AddressType,
10,
TRUE,
&InputMessage,
&OutputMessage
);
if (!KERB_SUCCESS(KerbErr))
{
printf("KerbCallKdc failed: 0x%x\n",KerbErr);
goto Cleanup;
}
KerbErr = KerbUnpackTgsReply(
OutputMessage.Buffer,
OutputMessage.BufferSize,
Reply
);
if (!KERB_SUCCESS(KerbErr))
{
printf("Failed to unpack KDC reply: 0x%x\n",KerbErr);
KerbErr = KerbUnpackKerbError(
OutputMessage.Buffer,
OutputMessage.BufferSize,
&ErrorMessage
);
if (KERB_SUCCESS(KerbErr))
{
printf("Failed to get TGS ticket: 0x%x\n",ErrorMessage->error_code);
KerbErr = (KERBERR) ErrorMessage->error_code;
}
goto Cleanup;
}
KerbErr = KerbUnpackKdcReplyBody(
&(*Reply)->encrypted_part,
&TgtReplyBody->session_key,
KERB_ENCRYPTED_TGS_REPLY_PDU,
ReplyBody
);
if (!KERB_SUCCESS(KerbErr))
{
printf("Failed to unpack KDC reply body: 0x%x\n",KerbErr);
goto Cleanup;
}
*Ticket = (*Reply)->ticket;
Cleanup:
//
// BUGBUG: memory leak here
//
if (KERB_SUCCESS(KerbErr))
{
return(TRUE);
}
else
{
return(FALSE);
}
}
BOOLEAN
UStringFromAnsi(
OUT PUNICODE_STRING UnicodeString,
IN LPSTR String
)
{
STRING AnsiString;
RtlInitString(
&AnsiString,
String
);
if (!NT_SUCCESS(RtlAnsiStringToUnicodeString(
UnicodeString,
&AnsiString,
TRUE
)))
{
return(FALSE);
}
else
{
return(TRUE);
}
}
void
SetDefaultOpts()
{
UNICODE_STRING TempString;
STRING AnsiString;
LPSTR String;
KerbInitializeSockets(0x0101,5);
//
// Username
//
String = getenv( "USERNAME" );
if (String == NULL)
{
String = "mikesw";
}
UStringFromAnsi(
&ClientName,
String
);
String = getenv( "USERDOMAIN" );
if (String == NULL)
{
String = "NTDS";
}
UStringFromAnsi(
&ClientRealm,
String
);
UStringFromAnsi(
&ServiceRealm,
String
);
}
VOID
SetPassword(
IN PUNICODE_STRING UserName,
IN PUNICODE_STRING PrincipalName,
IN PUNICODE_STRING Password,
IN BOOLEAN UnixOnly
)
{
NTSTATUS Status;
DWORD sc;
LPTSTR pszBinding;
RPC_IF_HANDLE ifh = KdcDebug_ClientIfHandle;
handle_t hBinding;
sc = RpcStringBindingCompose(0, L"ncalrpc",L"",NULL,
0, &pszBinding);
if (sc) {
printf("error:rpcstringbindingcompose\n" );
return;
}
sc = RpcBindingFromStringBinding(pszBinding, &hBinding);
(void) RpcStringFree(&pszBinding);
if (sc) {
printf("error:rpcbindingfromstringbinding\n" );
return;
}
sc = RpcEpResolveBinding(hBinding, ifh);
if (sc) {
printf("error:rpcepresolvebinding\n" );
return;
}
Status = KDC_SetPassword(
hBinding,
UserName,
PrincipalName,
Password,
UnixOnly ? KERB_PRIMARY_CRED_RFC1510_ONLY : 0
);
RpcBindingFree(&hBinding);
printf("SetPassword returned 0x%x\n",Status);
}
BOOLEAN
BindToKdcRpc(
handle_t * hBinding
)
{
DWORD sc;
LPTSTR pszBinding;
RPC_IF_HANDLE ifh = KdcDebug_ClientIfHandle;
if (KdcName.Buffer == NULL)
{
sc = RpcStringBindingCompose(0, L"ncalrpc",L"",NULL,
0, &pszBinding);
}
else
{
sc = RpcStringBindingCompose(0, L"ncacn_ip_tcp",KdcNameString,NULL,
0, &pszBinding);
}
if (sc) {
printf("error:rpcstringbindingcompose\n" );
return FALSE;
}
sc = RpcBindingFromStringBinding(pszBinding, hBinding);
(void) RpcStringFree(&pszBinding);
if (sc) {
printf("error:rpcbindingfromstringbinding\n" );
return FALSE;
}
sc = RpcEpResolveBinding(*hBinding, ifh);
if (sc) {
printf("error:rpcepresolvebinding\n" );
return FALSE;
}
return TRUE;
}
VOID
DumpKdc(
VOID
)
{
NTSTATUS Status;
DWORD sc;
LPTSTR pszBinding;
RPC_IF_HANDLE ifh = KdcDebug_ClientIfHandle;
handle_t hBinding;
sc = RpcStringBindingCompose(0, L"ncalrpc",L"",NULL,
0, &pszBinding);
if (sc) {
printf("error:rpcstringbindingcompose\n" );
return;
}
sc = RpcBindingFromStringBinding(pszBinding, &hBinding);
(void) RpcStringFree(&pszBinding);
if (sc) {
printf("error:rpcbindingfromstringbinding\n" );
return;
}
sc = RpcEpResolveBinding(hBinding, ifh);
if (sc) {
printf("error:rpcepresolvebinding\n" );
return;
}
Status = KDC_Dump(
hBinding
);
RpcBindingFree(&hBinding);
}
VOID
DumpKdcDomains( VOID )
{
NTSTATUS Status;
PKDC_DBG_DOMAIN_LIST DomainList = NULL;
ULONG Index;
handle_t hBinding = NULL;
if (!BindToKdcRpc(&hBinding))
{
printf("Failed to bind to kdc\n");
return;
}
Status = KDC_GetDomainList(
hBinding,
&DomainList
);
if (!NT_SUCCESS(Status))
{
printf("Failed toget domain list: 0x%x\n",Status);
}
else
{
for (Index = 0; Index < DomainList->Count ; Index++ )
{
printf("Domain %d:\n",Index);
printf("\tDnsName = %wZ\n",&DomainList->Domains[Index].DnsName);
printf("\tNetbiosName = %wZ\n",&DomainList->Domains[Index].NetbiosName);
printf("\tClosestRoute = %wZ\n",&DomainList->Domains[Index].ClosestRoute);
printf("\tType = 0x%x, Attributes = 0x%x\n",DomainList->Domains[Index].Type, DomainList->Domains[Index].Attributes);
}
}
}
VOID
KdcNormalize(
ULONG Flags,
PKERB_DBG_INTERNAL_NAME Name
)
{
NTSTATUS Status;
PKDC_DBG_DOMAIN_LIST DomainList = NULL;
ULONG Index;
handle_t hBinding = NULL;
if (!BindToKdcRpc(&hBinding))
{
printf("Failed to bind to kdc\n");
return;
}
Status = KDC_Normalize(
hBinding,
Name,
Flags
);
if (!NT_SUCCESS(Status))
{
printf("Failed toget domain list: 0x%x\n",Status);
}
else
{
printf("Success\n");
}
}
VOID
KdcSetState(
ULONG Lifetime,
ULONG RenewTime
)
{
NTSTATUS Status;
LARGE_INTEGER FudgeFactor = {0};
handle_t hBinding = NULL;
if (!BindToKdcRpc(&hBinding))
{
printf("Failed to bind to kdc\n");
return;
}
Status = KDC_SetState(
hBinding,
0, // no flags
Lifetime,
RenewTime,
FudgeFactor
);
if (!NT_SUCCESS(Status))
{
printf("Failed to set kdc options: 0x%x\n",Status);
}
else
{
printf("Success\n");
}
}
void
Usage(char * Name)
{
printf("%s\n",Name);
printf("-cname, -sname : set client & service names\n");
printf("-crealm, -srealm : set client & service realms\n");
printf("-cpass, -spass : set client & service passwords\n");
printf("-crypt : set encryption type\n");
printf("-gettgt : get a TGT in client's realm, incompat. with -getas\n");
printf("-getas : get an AS ticket to a service, incompat. with -gettgt\n");
printf("-gettgs : get a TGS ticket to a service, requires a TGT\n");
printf("-renew : renew last ticket acquired\n");
printf("-dump : dump kdc heap trace\n");
printf("-kdc : set kdc name\n");
printf("-norm 0xFlags type name1 name2 name3 ... : normalize a name\n");
printf("-domains : dump domain list\n");
printf("-setstate lifespan renewspan : set ticket lifetime\n");
printf("\n");
printf("-setpass username principalname password : sets KRB5 password\n");
}
void
__cdecl main(int argc, char *argv[])
{
int Index;
BOOLEAN GetAsTicket = FALSE;
BOOLEAN GetTgsTicket = FALSE;
BOOLEAN GetTgt = FALSE;
BOOLEAN RenewTicket = FALSE;
BOOLEAN SetPass = FALSE;
BOOLEAN Dump = FALSE;
BOOLEAN Normalize= FALSE;
BOOLEAN DumpDomains = FALSE;
BOOLEAN SetState = FALSE;
ULONG Lifespan = 0;
ULONG RenewSpan = 0;
UNICODE_STRING UserName;
UNICODE_STRING PrincipalName;
UNICODE_STRING Password;
STRING AnsiString;
UNICODE_STRING AsServerName;
PKERB_ENCRYPTED_KDC_REPLY AsReplyBody = NULL;
PKERB_KDC_REPLY AsReply = NULL;
KERB_TICKET AsTicket;
PKERB_ENCRYPTED_KDC_REPLY TgsReplyBody = NULL;
PKERB_KDC_REPLY TgsReply = NULL;
KERB_TICKET TgsTicket;
BOOLEAN UnixOnly = FALSE;
KERB_DBG_INTERNAL_NAME Name = {0};
ULONG Flags;
UNICODE_STRING NameParts[20];
WCHAR NameBuffers[20][100];
ULONG Index2;
SetDefaultOpts();
for (Index = 1; Index < argc ; Index++ )
{
//
// First the principal name features
//
if (!_stricmp(argv[Index],"-crealm"))
{
if (Index+1 == argc)
{
goto Usage;
}
UStringFromAnsi(
&ClientRealm,
argv[++Index]
);
} else
if (!_stricmp(argv[Index],"-srealm"))
{
if (Index+1 == argc)
{
goto Usage;
}
UStringFromAnsi(
&ServiceRealm,
argv[++Index]
);
} else
if (!_stricmp(argv[Index],"-cname"))
{
if (Index+1 == argc)
{
goto Usage;
}
UStringFromAnsi(
&ClientName,
argv[++Index]
);
} else
if (!_stricmp(argv[Index],"-sname"))
{
if (Index+1 == argc)
{
goto Usage;
}
UStringFromAnsi(
&ServiceName,
argv[++Index]
);
} else
if (!_stricmp(argv[Index],"-cpass"))
{
if (Index+1 == argc)
{
goto Usage;
}
UStringFromAnsi(
&ClientPassword,
argv[++Index]
);
} else
if (!_stricmp(argv[Index],"-spass"))
{
if (Index+1 == argc)
{
goto Usage;
}
UStringFromAnsi(
&ServicePassword,
argv[++Index]
);
} else
if (!_stricmp(argv[Index],"-crypt"))
{
if (Index+1 == argc)
{
goto Usage;
}
sscanf(argv[++Index],"%d",&CryptType);
} else
if (!_stricmp(argv[Index],"-gettgt"))
{
GetTgt = TRUE;
} else
if (!_stricmp(argv[Index],"-getas"))
{
GetAsTicket = TRUE;
} else
if (!_stricmp(argv[Index],"-gettgs"))
{
GetTgsTicket = TRUE;
} else
if (!_stricmp(argv[Index],"-renew"))
{
RenewTicket = TRUE;
}
else if (!_stricmp(argv[Index],"-setpass"))
{
if (Index+4 > argc)
{
printf("Not enough args: %d instead of %d\n", argc, Index+3);
goto Usage;
}
SetPass = TRUE;
UStringFromAnsi(
&UserName,
argv[++Index]
);
UStringFromAnsi(
&PrincipalName,
argv[++Index]
);
UStringFromAnsi(
&Password,
argv[++Index]
);
}
else if (!_stricmp(argv[Index],"-dump"))
{
Dump = TRUE;
}
else if (!_stricmp(argv[Index],"-unix"))
{
UnixOnly = TRUE;
}
else if (!_stricmp(argv[Index],"-kdc"))
{
if (Index+2 > argc)
{
goto Usage;
}
mbstowcs(KdcNameString,argv[++Index],100);
RtlInitUnicodeString(
&KdcName,
KdcNameString
);
}
else if (!_stricmp(argv[Index],"-norm"))
{
Normalize = TRUE;
if (Index+4 > argc)
{
goto Usage;
}
sscanf(argv[++Index],"0x%x",&Flags);
sscanf(argv[++Index],"%d",&Name.NameType);
Name.NameCount = 0;
Name.References = 0;
Name.Names = NameParts;
Index2 = 0;
while (Index < argc-1)
{
mbstowcs(NameBuffers[Index2],argv[++Index],100);
RtlInitUnicodeString(
&NameParts[Index2],
NameBuffers[Index2]
);
Index2++;
Name.NameCount++;
}
}
else if (!_stricmp(argv[Index],"-domains"))
{
DumpDomains = TRUE;
}
else if (!_stricmp(argv[Index],"-setstate"))
{
if (Index+3 > argc)
{
goto Usage;
}
sscanf(argv[++Index],"%d",&Lifespan);
sscanf(argv[++Index],"%d",&RenewSpan);
SetState = TRUE;
}
else {
goto Usage;
}
}
if (GetTgsTicket && !GetTgt)
{
printf("ERROR: Can't get a TGS ticket without a TGT\n");
goto Usage;
}
if (GetAsTicket && GetTgt)
{
printf("ERROR: Can't get both an AS ticket and a TGT\n");
goto Usage;
}
if (SetPass)
{
SetPassword( &UserName, &PrincipalName, &Password, UnixOnly );
goto Cleanup;
}
if (Dump)
{
DumpKdc();
goto Cleanup;
}
if (DumpDomains)
{
DumpKdcDomains();
goto Cleanup;
}
if (SetState)
{
KdcSetState(
Lifespan,
RenewSpan
);
goto Cleanup;
}
if (Normalize)
{
KdcNormalize(
Flags,
&Name
);
goto Cleanup;
}
//
// Bind to the KDC
//
if (!BindToKdc())
{
printf("ERROR: Failed to bind to KDC\n");
goto Cleanup;
}
//
// Now try to get the AS ticket
//
if (GetAsTicket)
{
AsServerName = ServiceName;
}
else if (GetTgt)
{
RtlInitUnicodeString(
&AsServerName,
KDC_PRINCIPAL_NAME
);
}
if (!GetAnAsTicket(
&AsServerName,
&AsTicket,
&AsReplyBody,
&AsReply
))
{
printf("ERROR: Failed to get AS ticket\n");
goto Cleanup;
}
else
{
printf("SUCCESS: got an AS ticket\n");
}
if (GetTgsTicket)
{
if (!GetATgsTicket(
&AsTicket,
AsReplyBody,
AsReply,
FALSE, // don't renew
&TgsTicket,
&TgsReplyBody,
&TgsReply))
{
printf("ERROR: Failed to get TGS ticket\n");
goto Cleanup;
}
else
{
printf("SUCCESS: got a TGS ticket\n");
}
}
if (Dump)
{
DumpKdc();
}
goto Cleanup;
Usage:
Usage(argv[0]);
Cleanup:
KerbCleanupTickets();
return;
}
void *
MIDL_user_allocate( size_t cb )
{
return LocalAlloc( 0, ROUND_UP_COUNT(cb,8) );
}
void
MIDL_user_free( void * pv )
{
LocalFree( pv );
}