Adding a machine account to the Windows domain (Domain Controller)

 

 

Compiler: Visual C++ Express Edition 2005

Compiled on Platform: Windows 2003 Server (standard Edition)

Target platform: none, just for learning and fun

Header file: Standard and Windows

Additional library: [url=http://www.tenouk.com/clabworksheet/windowspsdk.html]Windows Platform SDK[/url]

Additional project setting: Set project to be compiled as C

Project -> your_project_name Properties -> Configuration Properties -> C/C++ -> Advanced -> Compiled As: Compiled as C Code (/TC)

Other info: non-CLR or unmanaged. Need to add netapi32.lib (netapi32.dll) to the project. Click the Project menu->Select the your_project_name Properties... sub menu->Expand the Configuration Properties folder on the left pane->Expand the Linker subfolder->Select the Input subfolder->Select the Additional Dependencies field on the right pane->Click the ... at the end of the field->Type in 'netapi32.lib' in the empty pane->Click the OK button->Click the OK button second time to close the project Properties dialog.

To do: How to add a machine account to the Windows domain (Domain Controller)

To show: Another various Win32 Windows domain user and group management C functions

 

//********* cplus.cpp *********

// Run on the domain machine

// For Win 2003 as a target

#define _WIN32_WINNT 0x0502

// Wide character/Unicode based program

#ifndef UNICODE

#define UNICODE

#endif

 

#include <windows.h>

#include <stdio.h>

#include <lm.h>

 

BOOL AddMachineAccount(LPWSTR wTargetComputer, LPWSTR MachineAccount, DWORD AccountType)

{

LPWSTR wAccount;

LPWSTR wPassword;

USER_INFO_1 ui;

DWORD cbAccount;

DWORD cbLength;

DWORD dwError;

 

// Ensure a valid computer account type was passed.

if(AccountType != UF_WORKSTATION_TRUST_ACCOUNT &&

AccountType != UF_SERVER_TRUST_ACCOUNT &&

AccountType != UF_INTERDOMAIN_TRUST_ACCOUNT)

{

SetLastError(ERROR_INVALID_PARAMETER);

return FALSE;

}

else

printf("Computer account type is valid.\n");

 

// Obtain the number of chars in computer account name.

cbLength = cbAccount = lstrlenW(MachineAccount);

 

// Ensure computer name doesn't exceed maximum length.

if(cbLength > MAX_COMPUTERNAME_LENGTH)

{

SetLastError(ERROR_INVALID_ACCOUNT_NAME);

return FALSE;

}

else

printf("Computer name length is valid.\n");

// Allocate storage to contain Unicode representation of computer account name + trailing $ + NULL.

wAccount = (LPWSTR)HeapAlloc(GetProcessHeap(), 0,

(cbAccount + 1 + 1) * sizeof(WCHAR) // Account + '$' + NULL

);

 

if(wAccount == NULL) return FALSE;

else printf("Memory allocation is OK.\n");

 

// Password is the computer account name converted to lowercase;

// you will convert the passed MachineAccount in place.

wPassword = MachineAccount;

 

// Copy MachineAccount to the wAccount buffer allocated while

// converting computer account name to uppercase. Convert password (in place) to lowercase.

while(cbAccount--) {

wAccount[cbAccount] = towupper(MachineAccount[cbAccount]);

wPassword[cbAccount] = towlower(wPassword[cbAccount]);

}

 

// Computer account names have a trailing Unicode '$'.

wAccount[cbLength] = L'$';

wAccount[cbLength + 1] = L'\0'; // terminate the string

 

// If the password is greater than the max allowed, truncate.

if(cbLength > LM20_PWLEN) wPassword[LM20_PWLEN] = L'\0';

else printf("No truncation was done to the password, the length is OK, max is 14.\n");

 

// Initialize the USER_INFO_1 structure.

ZeroMemory(&ui, sizeof(ui));

ui.usri1_name = wAccount;

ui.usri1_password = wPassword;

ui.usri1_flags = AccountType | UF_SCRIPT;

ui.usri1_priv = USER_PRIV_USER;

ui.usri1_comment = L"A virtual machine created by NetUserAdd()...";

 

dwError = NetUserAdd(

wTargetComputer, // target computer name

1, // info level

(LPBYTE) &ui, // buffer

NULL

);

 

// Release the allocated memory.

if(wAccount) HeapFree(GetProcessHeap(), 0, wAccount);

 

// Indicate whether the function was successful.

if(dwError == NO_ERROR)

{

printf("%S computer account successfully created on %S DC.\n", MachineAccount, wTargetComputer);

return TRUE;

}

else

{

SetLastError(dwError);

return FALSE;

}

}

 

// This program run at command prompt, receives 2 arguments: The target server and the machine account name.

int wmain(int argc, wchar_t *argv[])

{

BOOL Test;

DWORD AccountType;

 

if(argc != 3)

{

printf("Usage: %S <TargetComputer> <MachineAccount or machine\'s password>.\n", argv[0]);

printf("Example: %S myserver mymachine.\n", argv[0]);

exit (-1);

}

AccountType = UF_WORKSTATION_TRUST_ACCOUNT;

Test = AddMachineAccount(argv[1], argv[2], AccountType);

printf("The return value is: %u\n", Test);

return 0;

}

 

Output example:

(This program run at the command prompt)

 

F:\vc2005project\cplus\debug>cplus

Usage: cplus <TargetComputer> <MachineAccount or machine's password>.

Example: cplus myserver mymachine.

 

F:\vc2005project\cplus\debug>cplus mail anothertestmachine

Computer account type is valid.

The return value is: 0

 

F:\vc2005project\cplus\debug>cplus mail moremachine

Computer account type is valid.

Computer name length is valid.

Memory allocation is OK.

No truncation was done to the password, the length is OK, max is 14.

moremachine computer account successfully created on mail DC.

The return value is: 1

 

F:\vc2005project\cplus\debug>

 

Note: The program was run on Windows 2003 Server (Standard Edition) member server (LOGIN ON THE MEMBER SERVER AS DOMAIN ADMINISTRATOR. You can try using the local login credential) whereas the Domain Controller is mail (another Windows 2003 Server (Standard Edition) in the same domain). The 'moremachine' machine account is fictitious. The password is the lowercase of the machine account name. In this case the machine account and the password are similar.

 

 

C and C++ Programming Resources | C & C++ Code Example Index