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.
902 lines
22 KiB
902 lines
22 KiB
/*++
|
|
|
|
Copyright (c) 1990 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
tmachine.c
|
|
|
|
Abstract:
|
|
|
|
This module tests the machine account creation facilities
|
|
of SAM.
|
|
|
|
Author:
|
|
|
|
Jim Kelly (JimK) 7-Feb-1994
|
|
|
|
Environment:
|
|
|
|
User Mode - Win32
|
|
|
|
Revision History:
|
|
|
|
|
|
--*/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
// //
|
|
// Includes //
|
|
// //
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
#include <stdio.h>
|
|
#include <nt.h>
|
|
#include <ntsam.h>
|
|
#include <ntsamp.h>
|
|
#include <ntlsa.h>
|
|
#include <ntrpcp.h> // prototypes for MIDL user functions
|
|
#include <seopaque.h>
|
|
#include <string.h>
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
// //
|
|
// Macros //
|
|
// //
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
#ifndef SHIFT
|
|
#define SHIFT(c,v) {c--; v++;}
|
|
#endif //SHIFT
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
// //
|
|
// Routines //
|
|
// //
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
NTSTATUS
|
|
TSampGetLsaDomainInfo(
|
|
IN PUNICODE_STRING ServerName,
|
|
OUT PPOLICY_ACCOUNT_DOMAIN_INFO *PolicyAccountDomainInfo
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine retrieves ACCOUNT domain information from the LSA
|
|
policy database.
|
|
|
|
|
|
Arguments:
|
|
|
|
ServerName - name of machine to get account domain information
|
|
from.
|
|
|
|
PolicyAccountDomainInfo - Receives a pointer to a
|
|
POLICY_ACCOUNT_DOMAIN_INFO structure containing the account
|
|
domain info.
|
|
|
|
|
|
Return Value:
|
|
|
|
STATUS_SUCCESS - Succeeded.
|
|
|
|
Other status values that may be returned from:
|
|
|
|
LsaOpenPolicy()
|
|
LsaQueryInformationPolicy()
|
|
--*/
|
|
|
|
{
|
|
NTSTATUS
|
|
NtStatus,
|
|
IgnoreStatus;
|
|
|
|
LSA_HANDLE
|
|
PolicyHandle;
|
|
|
|
OBJECT_ATTRIBUTES
|
|
PolicyObjectAttributes;
|
|
|
|
//
|
|
// Open the policy database
|
|
//
|
|
|
|
InitializeObjectAttributes( &PolicyObjectAttributes,
|
|
NULL, // Name
|
|
0, // Attributes
|
|
NULL, // Root
|
|
NULL ); // Security Descriptor
|
|
|
|
NtStatus = LsaOpenPolicy( ServerName,
|
|
&PolicyObjectAttributes,
|
|
POLICY_VIEW_LOCAL_INFORMATION,
|
|
&PolicyHandle );
|
|
|
|
if ( NT_SUCCESS(NtStatus) ) {
|
|
|
|
//
|
|
// Query the account domain information
|
|
//
|
|
|
|
NtStatus = LsaQueryInformationPolicy( PolicyHandle,
|
|
PolicyAccountDomainInformation,
|
|
(PVOID *)PolicyAccountDomainInfo );
|
|
|
|
|
|
IgnoreStatus = LsaClose( PolicyHandle );
|
|
ASSERT(NT_SUCCESS(IgnoreStatus));
|
|
}
|
|
|
|
return(NtStatus);
|
|
}
|
|
|
|
|
|
NTSTATUS
|
|
TSampConnectToServer(
|
|
IN PUNICODE_STRING ServerName,
|
|
IN ACCESS_MASK DomainAccess,
|
|
OUT PHANDLE ServerHandle,
|
|
OUT PHANDLE DomainHandle,
|
|
OUT PSID *DomainSid
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Open a handle to the SAM server on the specified server
|
|
and then open the account domain on that same server.
|
|
|
|
Arguments:
|
|
|
|
ServerName - Name of server to connect to.
|
|
|
|
DomainAccess - accesses needed to the account domain.
|
|
|
|
ServerHandle - Receives a handle to the SAM server on the specified
|
|
system.
|
|
|
|
DomainHandle - Receives a handle to the account domain.
|
|
|
|
DomainSid - Receives a pointer to the SID of the account domain.
|
|
|
|
|
|
Return Value:
|
|
|
|
|
|
|
|
|
|
--*/
|
|
{
|
|
NTSTATUS
|
|
NtStatus;
|
|
|
|
OBJECT_ATTRIBUTES
|
|
ObjectAttributes;
|
|
|
|
PPOLICY_ACCOUNT_DOMAIN_INFO
|
|
AccountDomainInfo;
|
|
|
|
//
|
|
// get account domain info
|
|
//
|
|
|
|
NtStatus = TSampGetLsaDomainInfo( ServerName,
|
|
&AccountDomainInfo);
|
|
|
|
if (!NT_SUCCESS(NtStatus)) {
|
|
printf("SAM TEST: Failed to get lsa domain info...\n"
|
|
" Completion status is 0x%lx\n", NtStatus);
|
|
return(NtStatus);
|
|
}
|
|
printf("SAM TEST: Target domain is %wZ\n", &AccountDomainInfo->DomainName);
|
|
|
|
(*DomainSid) = AccountDomainInfo->DomainSid;
|
|
|
|
InitializeObjectAttributes( &ObjectAttributes, NULL, 0, 0, NULL );
|
|
|
|
|
|
NtStatus = SamConnect(
|
|
ServerName,
|
|
ServerHandle,
|
|
SAM_SERVER_READ | SAM_SERVER_EXECUTE,
|
|
&ObjectAttributes
|
|
);
|
|
|
|
|
|
if (!NT_SUCCESS(NtStatus)) {
|
|
printf("SAM TEST: Failed to connect...\n"
|
|
" Completion status is 0x%lx\n", NtStatus);
|
|
return(NtStatus);
|
|
}
|
|
|
|
|
|
NtStatus = SamOpenDomain(
|
|
(*ServerHandle),
|
|
DomainAccess,
|
|
*DomainSid,
|
|
DomainHandle
|
|
);
|
|
|
|
if (!NT_SUCCESS(NtStatus)) {
|
|
printf("Failed account domain open\n"
|
|
" Completion status is 0x%lx\n", NtStatus);
|
|
return(NtStatus);
|
|
}
|
|
|
|
return(STATUS_SUCCESS);
|
|
|
|
|
|
}
|
|
|
|
|
|
BOOLEAN
|
|
TSampEnableMachinePrivilege( VOID )
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function enabled the SeMachineAccountPrivilege privilege.
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Value:
|
|
|
|
TRUE if privilege successfully enabled.
|
|
FALSE if not successfully enabled.
|
|
|
|
--*/
|
|
{
|
|
|
|
NTSTATUS Status;
|
|
HANDLE Token;
|
|
LUID SecurityPrivilege;
|
|
PTOKEN_PRIVILEGES NewState;
|
|
ULONG ReturnLength;
|
|
|
|
|
|
//
|
|
// Open our own token
|
|
//
|
|
|
|
Status = NtOpenProcessToken(
|
|
NtCurrentProcess(),
|
|
TOKEN_ADJUST_PRIVILEGES,
|
|
&Token
|
|
);
|
|
if (!NT_SUCCESS(Status)) {
|
|
printf("SAM TEST: Can't open process token to enable Privilege.\n"
|
|
" Completion status of NtOpenProcessToken() is: 0x%lx\n", Status);
|
|
return(FALSE);
|
|
}
|
|
|
|
|
|
//
|
|
// Initialize the adjustment structure
|
|
//
|
|
|
|
SecurityPrivilege =
|
|
RtlConvertLongToLargeInteger(SE_MACHINE_ACCOUNT_PRIVILEGE);
|
|
|
|
ASSERT( (sizeof(TOKEN_PRIVILEGES) + sizeof(LUID_AND_ATTRIBUTES)) < 100);
|
|
NewState = RtlAllocateHeap( RtlProcessHeap(), 0, 100 );
|
|
|
|
NewState->PrivilegeCount = 1;
|
|
NewState->Privileges[0].Luid = SecurityPrivilege;
|
|
NewState->Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
|
|
|
|
|
|
//
|
|
// Set the state of the privilege to ENABLED.
|
|
//
|
|
|
|
Status = NtAdjustPrivilegesToken(
|
|
Token, // TokenHandle
|
|
FALSE, // DisableAllPrivileges
|
|
NewState, // NewState
|
|
0, // BufferLength
|
|
NULL, // PreviousState (OPTIONAL)
|
|
&ReturnLength // ReturnLength
|
|
);
|
|
// don't use NT_SUCCESS here because STATUS_NOT_ALL_ASSIGNED is a success status
|
|
if (Status != STATUS_SUCCESS) {
|
|
return(FALSE);
|
|
}
|
|
|
|
|
|
//
|
|
// Clean up some stuff before returning
|
|
//
|
|
|
|
RtlFreeHeap( RtlProcessHeap(), 0, NewState );
|
|
Status = NtClose( Token );
|
|
ASSERT(NT_SUCCESS(Status));
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
NTSTATUS
|
|
TSampCreateMachine(
|
|
IN SAM_HANDLE DomainHandle,
|
|
IN PUNICODE_STRING AccountName
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine attempts to create a machine account.
|
|
|
|
One of two cases may be tested:
|
|
|
|
1) DomainHandle is open for DOMAIN_CREATE_USER,
|
|
or
|
|
2) DomainHandle is open for DOMAIN_LOOKUP and
|
|
the SeMachineAccountPrivilege privilege is
|
|
enabled.
|
|
|
|
It is the caller's responsibility to establish the
|
|
correct case criteria before calling.
|
|
|
|
Arguments:
|
|
|
|
DomainHandle - handle to domain to create account in.
|
|
|
|
AccountName - Name of the account to create.
|
|
|
|
|
|
Return Value:
|
|
|
|
--*/
|
|
|
|
{
|
|
NTSTATUS
|
|
NtStatus,
|
|
IgnoreStatus;
|
|
|
|
SAM_HANDLE
|
|
UserHandle;
|
|
|
|
ACCESS_MASK
|
|
GrantedAccess;
|
|
|
|
ULONG
|
|
Rid;
|
|
|
|
NtStatus = SamCreateUser2InDomain( DomainHandle,
|
|
AccountName,
|
|
USER_WORKSTATION_TRUST_ACCOUNT,
|
|
MAXIMUM_ALLOWED,
|
|
&UserHandle,
|
|
&GrantedAccess,
|
|
&Rid);
|
|
|
|
if (NT_SUCCESS(NtStatus)) {
|
|
IgnoreStatus = SamCloseHandle( UserHandle );
|
|
ASSERT(NT_SUCCESS(IgnoreStatus));
|
|
printf("SAM TEST: Machine account created.\n"
|
|
" GrantedAccess: 0x%lx\n"
|
|
" Rid: %d (0x%lx)\n",
|
|
GrantedAccess, Rid, Rid);
|
|
} else {
|
|
printf("SAM TEST: Machine account creation failed.\n"
|
|
" Status: 0x%lx\n", NtStatus);
|
|
}
|
|
|
|
|
|
return(NtStatus);
|
|
|
|
|
|
}
|
|
|
|
|
|
NTSTATUS
|
|
TSampSetPasswordMachine(
|
|
IN SAM_HANDLE DomainHandle,
|
|
IN PUNICODE_STRING AccountName,
|
|
IN PUNICODE_STRING Password
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine attempts to set the password of a machine account.
|
|
|
|
|
|
Arguments:
|
|
|
|
DomainHandle - handle to domain account is in.
|
|
|
|
AccountName - Name of the account to set password.
|
|
|
|
Password - New password.
|
|
|
|
Return Value:
|
|
|
|
--*/
|
|
|
|
{
|
|
NTSTATUS
|
|
NtStatus;
|
|
|
|
SAM_HANDLE
|
|
UserHandle;
|
|
|
|
PULONG
|
|
RelativeIds;
|
|
|
|
PSID_NAME_USE
|
|
Use;
|
|
|
|
USER_SET_PASSWORD_INFORMATION
|
|
PasswordInfo;
|
|
|
|
|
|
PasswordInfo.Password = (*Password);
|
|
PasswordInfo.PasswordExpired = FALSE;
|
|
|
|
NtStatus = SamLookupNamesInDomain( DomainHandle,
|
|
1,
|
|
AccountName,
|
|
&RelativeIds,
|
|
&Use);
|
|
if (!NT_SUCCESS(NtStatus)) {
|
|
printf("SAM TEST: Couldn't find account to set password.\n"
|
|
" Lookup status: 0x%lx\n", NtStatus);
|
|
return(NtStatus);
|
|
}
|
|
|
|
|
|
NtStatus = SamOpenUser( DomainHandle,
|
|
USER_FORCE_PASSWORD_CHANGE,
|
|
RelativeIds[0],
|
|
&UserHandle);
|
|
|
|
if (!NT_SUCCESS(NtStatus)) {
|
|
printf("SAM TEST: Couldn't open user account for FORCE_PASSWORD_CHANGE.\n"
|
|
" Lookup status: 0x%lx\n", NtStatus);
|
|
return(NtStatus);
|
|
}
|
|
|
|
NtStatus = SamSetInformationUser( UserHandle,
|
|
UserSetPasswordInformation,
|
|
&PasswordInfo
|
|
);
|
|
if (!NT_SUCCESS(NtStatus)) {
|
|
printf("SAM TEST: Couldn't set password on user account.\n"
|
|
" Set Info status: 0x%lx\n", NtStatus);
|
|
return(NtStatus);
|
|
}
|
|
|
|
|
|
return(STATUS_SUCCESS);
|
|
|
|
|
|
}
|
|
|
|
|
|
NTSTATUS
|
|
TSampDeleteMachine(
|
|
IN SAM_HANDLE DomainHandle,
|
|
IN PUNICODE_STRING AccountName
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine attempts to delete a machine account.
|
|
|
|
|
|
Arguments:
|
|
|
|
DomainHandle - handle to domain to delete account from.
|
|
|
|
AccountName - Name of the account to delete.
|
|
|
|
|
|
Return Value:
|
|
|
|
--*/
|
|
|
|
{
|
|
NTSTATUS
|
|
NtStatus;
|
|
|
|
SAM_HANDLE
|
|
UserHandle;
|
|
|
|
PULONG
|
|
RelativeIds;
|
|
|
|
PSID_NAME_USE
|
|
Use;
|
|
|
|
NtStatus = SamLookupNamesInDomain( DomainHandle,
|
|
1,
|
|
AccountName,
|
|
&RelativeIds,
|
|
&Use);
|
|
if (!NT_SUCCESS(NtStatus)) {
|
|
printf("SAM TEST: Couldn't find account to delete.\n"
|
|
" Lookup status: 0x%lx\n", NtStatus);
|
|
return(NtStatus);
|
|
}
|
|
|
|
|
|
NtStatus = SamOpenUser( DomainHandle,
|
|
DELETE,
|
|
RelativeIds[0],
|
|
&UserHandle);
|
|
|
|
if (!NT_SUCCESS(NtStatus)) {
|
|
printf("SAM TEST: Couldn't open user account for delete.\n"
|
|
" Open status: 0x%lx\n", NtStatus);
|
|
return(NtStatus);
|
|
}
|
|
|
|
NtStatus = SamDeleteUser( UserHandle );
|
|
if (!NT_SUCCESS(NtStatus)) {
|
|
printf("SAM TEST: Couldn't delete user account.\n"
|
|
" DeleteUser status: 0x%lx\n", NtStatus);
|
|
return(NtStatus);
|
|
}
|
|
|
|
|
|
return(STATUS_SUCCESS);
|
|
|
|
|
|
}
|
|
|
|
|
|
VOID
|
|
TSampPrintYesOrNo(
|
|
IN BOOLEAN b
|
|
)
|
|
{
|
|
if (b) {
|
|
printf("Yes\n");
|
|
} else {
|
|
printf("No\n");
|
|
}
|
|
}
|
|
|
|
|
|
|
|
VOID
|
|
TSampUsage( VOID )
|
|
{
|
|
|
|
printf("\n\n Command format:\n");
|
|
printf(" tmachine [/c] [/p] [/d] <account-name> <machine> [<password>]\n");
|
|
printf("\n");
|
|
printf(" Switches\n");
|
|
printf(" /c - create account\n");
|
|
printf(" /p - set password on account\n");
|
|
printf(" /d - delete account\n");
|
|
printf("\n");
|
|
printf(" if multiple switches are specified, they are attempted in\n");
|
|
printf(" the order listed above. An error in any attempt will prevent\n");
|
|
printf(" any further attempts.\n");
|
|
printf("\n");
|
|
return;
|
|
}
|
|
|
|
|
|
VOID
|
|
main (c,v)
|
|
int c;
|
|
char **v;
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This is the main entry routine for this test.
|
|
|
|
Arguments:
|
|
|
|
Argv[1] - account name to create or delete
|
|
|
|
Argv[2] - domain controller machine name
|
|
|
|
Argv[3] - 'D' to delete account, otherwise account is created.
|
|
|
|
|
|
|
|
Return Value:
|
|
|
|
|
|
|
|
|
|
--*/
|
|
{
|
|
NTSTATUS
|
|
NtStatus,
|
|
IgnoreStatus;
|
|
|
|
UNICODE_STRING
|
|
AccountName,
|
|
ControllerName,
|
|
Password;
|
|
|
|
WCHAR
|
|
AccountNameBuffer[80],
|
|
ControllerNameBuffer[80],
|
|
PasswordBuffer[80];
|
|
|
|
ANSI_STRING
|
|
AnsiString;
|
|
|
|
SAM_HANDLE
|
|
ServerHandle,
|
|
ServerHandle2,
|
|
DomainHandle,
|
|
DomainHandle2;
|
|
|
|
PSID
|
|
DomainSid;
|
|
|
|
BOOLEAN
|
|
Create = FALSE,
|
|
SetPassword = FALSE,
|
|
Delete = FALSE;
|
|
|
|
ULONG
|
|
ArgNum = 0;
|
|
|
|
PCHAR
|
|
p;
|
|
|
|
CHAR
|
|
ch;
|
|
|
|
AccountName.Length = 0;
|
|
ControllerName.Length = 0;
|
|
Password.Length = 0;
|
|
|
|
|
|
|
|
//
|
|
// Command format:
|
|
//
|
|
// tmachine [/c] [/p] [/d] <account-name> <machine> [<password>]
|
|
//
|
|
// Switches
|
|
// /c - create account
|
|
// /p - set password on account
|
|
// /d - delete account
|
|
//
|
|
// if multiple switches are specified, they are attempted in
|
|
// the order listed above. An error in any attempt will prevent
|
|
// any further attempts.
|
|
//
|
|
|
|
SHIFT (c,v);
|
|
while ((c > 0) && ((ch = *v[0]))) {
|
|
p = *v;
|
|
if (ch == '/') {
|
|
while (*++p != '\0') {
|
|
if ((*p == 'c') || (*p == 'C')) {
|
|
Create = TRUE;
|
|
// printf("Create\n");
|
|
} else if ((*p == 'p') || (*p == 'P')) {
|
|
SetPassword = TRUE;
|
|
// printf("SetPassword\n");
|
|
} else if ((*p == 'd') || (*p == 'D')) {
|
|
Delete = TRUE;
|
|
// printf("Delete\n");
|
|
} else {
|
|
TSampUsage();
|
|
return;
|
|
}
|
|
}
|
|
} else {
|
|
|
|
switch (ArgNum) {
|
|
case 0:
|
|
|
|
//
|
|
// collecting account name
|
|
//
|
|
|
|
AccountName.Buffer = AccountNameBuffer;
|
|
AccountName.MaximumLength = sizeof(AccountNameBuffer);
|
|
RtlInitAnsiString(&AnsiString, (*v));
|
|
RtlAnsiStringToUnicodeString(&AccountName, &AnsiString, FALSE);
|
|
|
|
// printf("account: %wZ\n", &AccountName);
|
|
break;
|
|
|
|
case 1:
|
|
|
|
//
|
|
// collecting machine name
|
|
//
|
|
|
|
ControllerName.Buffer = ControllerNameBuffer;
|
|
ControllerName.MaximumLength = sizeof(ControllerNameBuffer);
|
|
RtlInitAnsiString(&AnsiString, (*v));
|
|
RtlAnsiStringToUnicodeString(&ControllerName, &AnsiString, FALSE);
|
|
|
|
// printf("machine: %wZ\n", &ControllerName);
|
|
break;
|
|
|
|
|
|
case 2:
|
|
|
|
//
|
|
// collecting password name
|
|
//
|
|
|
|
Password.Buffer = PasswordBuffer;
|
|
Password.MaximumLength = sizeof(PasswordBuffer);
|
|
RtlInitAnsiString(&AnsiString, (*v));
|
|
RtlAnsiStringToUnicodeString(&Password, &AnsiString, FALSE);
|
|
|
|
// printf("password: %wZ\n", &Password);
|
|
break;
|
|
|
|
default:
|
|
|
|
//
|
|
// collecting garbage.
|
|
//
|
|
|
|
break;
|
|
}
|
|
|
|
ArgNum++;
|
|
}
|
|
SHIFT(c,v);
|
|
}
|
|
|
|
|
|
|
|
printf("parameters:\n");
|
|
printf(" Create Account: "); TSampPrintYesOrNo( Create );
|
|
printf(" Set Password : "); TSampPrintYesOrNo( SetPassword );
|
|
printf(" Delete Account: "); TSampPrintYesOrNo( Delete );
|
|
printf(" Account : *%wZ*\n", &AccountName);
|
|
printf(" Machine : *%wZ*\n", &ControllerName);
|
|
printf(" Password : *%wZ*\n", &Password);
|
|
|
|
|
|
//
|
|
// Make sure we don't have conflicting parameters
|
|
//
|
|
// Rules:
|
|
//
|
|
// 1) account name is always required.
|
|
// 2) password and machine are required if /P was specified.
|
|
// 3) machine is optional if /P not specified.
|
|
//
|
|
//
|
|
|
|
if ( (AccountName.Length == 0) ||
|
|
( SetPassword && (ControllerName.Length == 0) ) ||
|
|
( SetPassword && (Password.Length == 0) ) ) {
|
|
TSampUsage();
|
|
return;
|
|
}
|
|
|
|
|
|
//
|
|
// Open the server and the account domain
|
|
//
|
|
|
|
NtStatus = TSampConnectToServer(&ControllerName,
|
|
DOMAIN_LOOKUP | DOMAIN_READ_PASSWORD_PARAMETERS,
|
|
&ServerHandle,
|
|
&DomainHandle,
|
|
&DomainSid);
|
|
|
|
|
|
if (Create) {
|
|
//
|
|
// try to create the machine account with privilege.
|
|
//
|
|
|
|
|
|
printf("SAM TEST: Creating machine account with privilege.\n");
|
|
TSampEnableMachinePrivilege();
|
|
NtStatus = TSampCreateMachine( DomainHandle, &AccountName );
|
|
if (NT_SUCCESS(NtStatus)) {
|
|
printf(" Status: successful\n");
|
|
} else {
|
|
|
|
if (NtStatus == STATUS_ACCESS_DENIED) {
|
|
//
|
|
// We didn't have the privilege, and didn't have
|
|
// the domain open so that it would work without
|
|
// the privilege.
|
|
//
|
|
|
|
printf(" Couldn't create account with privilege (0x%lx)\n"
|
|
" Attempting normal creation (without privilege)\n"
|
|
, NtStatus);
|
|
NtStatus = TSampConnectToServer(&ControllerName,
|
|
DOMAIN_LOOKUP |
|
|
DOMAIN_READ_PASSWORD_PARAMETERS |
|
|
DOMAIN_CREATE_USER,
|
|
&ServerHandle2,
|
|
&DomainHandle2,
|
|
&DomainSid);
|
|
if (!NT_SUCCESS(NtStatus)) {
|
|
printf(" Can't open domain for CREATE_USER access (0x%lx)\n", NtStatus);
|
|
} else {
|
|
NtStatus = TSampCreateMachine( DomainHandle2,
|
|
&AccountName );
|
|
if (NT_SUCCESS(NtStatus)) {
|
|
printf(" Status: successful\n");
|
|
} else {
|
|
printf(" Failed: 0x%lx\n", NtStatus);
|
|
}
|
|
|
|
IgnoreStatus = SamCloseHandle( DomainHandle2 );
|
|
|
|
}
|
|
}
|
|
if (!NT_SUCCESS(NtStatus)) {
|
|
printf(" Status: 0x%lx", NtStatus);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
if (SetPassword) {
|
|
|
|
//
|
|
// Try to set the password on the account
|
|
//
|
|
|
|
printf("SAM TEST: Setting password of account ...\n");
|
|
NtStatus = TSampSetPasswordMachine( DomainHandle, &AccountName, &Password );
|
|
if (NT_SUCCESS(NtStatus)) {
|
|
printf(" Status: successful\n");
|
|
} else {
|
|
printf(" Status: 0x%lx", NtStatus);
|
|
return;
|
|
}
|
|
}
|
|
|
|
|
|
if (Delete) {
|
|
|
|
printf("SAM TEST: Deleting account ...\n");
|
|
NtStatus = TSampDeleteMachine( DomainHandle, &AccountName );
|
|
if (NT_SUCCESS(NtStatus)) {
|
|
printf(" Status: successful\n");
|
|
} else {
|
|
printf(" Status: 0x%lx", NtStatus);
|
|
return;
|
|
}
|
|
}
|
|
|
|
|
|
return;
|
|
}
|
|
|