windows-nt/Source/XPSP1/NT/base/cluster/utils/compobj/compobj.cpp
2020-09-26 16:20:57 +08:00

530 lines
19 KiB
C++

/*++
Copyright (c) 1999 Microsoft Corporation
Module Name:
compobj.c
Abstract:
GetComputerObjectName utility.
Author:
Charlie Wickham (charlwi) 22-Jul-1999
Environment:
User mode
Revision History:
--*/
#define UNICODE 1
#define _UNICODE 1
//#define COBJMACROS
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <lm.h>
#include <lmaccess.h>
#include <objbase.h>
#include <iads.h>
#include <adshlp.h>
#include <adserr.h>
#define SECURITY_WIN32
#include <security.h>
#include "clusvmsg.h"
#include "clusrtl.h"
#define ADD 1
#define DEL 2
#define QUERY 3
#define GUID 4
struct _NAMES {
PWCHAR Title;
EXTENDED_NAME_FORMAT Code;
} Names[] = {
L"FQDN\t\t", NameFullyQualifiedDN,
L"SAM\t\t", NameSamCompatible,
L"Display\t\t", NameDisplay,
L"UID\t\t", NameUniqueId,
L"Canonical\t", NameCanonical,
L"UserPrin\t\t", NameUserPrincipal,
L"Can EX\t\t", NameCanonicalEx,
L"SPN\t\t", NameServicePrincipal
};
PCHAR ADSTypeNames[] = {
"INVALID",
"DN_STRING",
"CASE_EXACT_STRING",
"CASE_IGNORE_STRING",
"PRINTABLE_STRING",
"NUMERIC_STRING",
"BOOLEAN",
"INTEGER",
"OCTET_STRING",
"UTC_TIME",
"LARGE_INTEGER",
"PROV_SPECIFIC",
"OBJECT_CLASS",
"CASEIGNORE_LIST",
"OCTET_LIST",
"PATH",
"POSTALADDRESS",
"TIMESTAMP",
"BACKLINK",
"TYPEDNAME",
"HOLD",
"NETADDRESS",
"REPLICAPOINTER",
"FAXNUMBER",
"EMAIL",
"NT_SECURITY_DESCRIPTOR",
"UNKNOWN",
"DN_WITH_BINARY",
"DN_WITH_STRING"
};
int __cdecl
wmain(
int argc,
WCHAR *argv[]
)
/*++
Routine Description:
main routine for utility
Arguments:
standard command line args
Return Value:
0 if it worked successfully
--*/
{
WCHAR buffer[512];
DWORD bufSize;
BOOL success;
DWORD i;
USER_INFO_1 netUI1;
DWORD badParam;
DWORD status;
PWCHAR dcName = argv[2];
PWCHAR machineName = NULL;
DWORD opCode;
WCHAR bindingString[512];
HRESULT hr;
if ( argc == 1 ){
printf("%ws -add dcName nodename pwd\n", argv[0]);
printf("%ws -del dcName nodename\n", argv[0]);
printf("%ws -query domain [nodename]\n", argv[0]);
printf("%ws -guid objectGUID attr [attr ...]\n", argv[0]);
return 0;
}
if ( _wcsnicmp( argv[1], L"-add", 4 ) == 0 ) {
if ( argc < 5 ) {
printf("%ws -add dcName nodename pwd\n", argv[0]);
return 0;
}
opCode = ADD;
dcName = argv[2];
machineName = argv[3];
}
else if ( _wcsnicmp( argv[1], L"-del", 4 ) == 0 ) {
if ( argc < 4 ) {
printf("%ws -del dcName nodename\n", argv[0]);
return 0;
}
opCode = DEL;
dcName = argv[2];
machineName = argv[3];
}
else if ( _wcsnicmp( argv[1], L"-query", 6 ) == 0 ) {
opCode = QUERY;
if ( argc > 3 ) {
machineName = argv[3];
}
}
else if ( _wcsnicmp( argv[1], L"-guid", 5 ) == 0 ) {
if ( argc < 4 ) {
printf("%ws -guid objectGUID attr [attr ...]\n", argv[0]);
return 0;
}
opCode = GUID;
}
else {
printf("%ws -add dcName nodename pwd\n", argv[0]);
printf("%ws -del dcName nodename\n", argv[0]);
printf("%ws -query domain [nodename attr [attr ...]]\n", argv[0]);
printf("%ws -guid objectGUID attr [attr ...]\n", argv[0]);
return 0;
}
if ( opCode == ADD ) {
PWCHAR machinePwd = argv[4];
RtlZeroMemory( &netUI1, sizeof( netUI1 ) );
//
// Initialize it..
//
netUI1.usri1_name = machineName;
netUI1.usri1_password = machinePwd;
netUI1.usri1_flags = UF_WORKSTATION_TRUST_ACCOUNT | UF_SCRIPT;
netUI1.usri1_priv = USER_PRIV_USER;
netUI1.usri1_comment = L"Server cluster virtual network name";
status = NetUserAdd( dcName, 1, (PBYTE)&netUI1, &badParam );
if ( status == NERR_Success ) {
printf("NetUserAdd is successful.\n");
} else {
printf( "NetUserAdd on '%ws' for '%ws' failed: 0x%X - params = %d\n",
dcName, machineName, status, badParam );
return status;
}
}
else if ( opCode == DEL ) {
status = NetUserDel( dcName, machineName );
if ( status == NERR_Success ) {
printf("NetUserDel is successful.\n");
} else {
printf( "NetUserDel on '%ws' for '%ws' failed: 0x%X\n", dcName, machineName, status );
return status;
}
}
else if ( opCode == QUERY ) {
dcName = argv[2];
printf("Output from GetComputerObjectName()\n");
for ( i = 0; i < sizeof(Names)/sizeof(struct _NAMES); ++i ) {
//
// loop through the different name variants, printing the associated result
//
bufSize = 512;
success = GetComputerObjectName(Names[i].Code,
buffer, &bufSize);
if ( success ) {
printf("%ws%ws\n\n", Names[i].Title, buffer );
} else {
printf("\nFAILED: %.*ws (%d)\n\n",
(wcschr(Names[i].Title, L'\t') - Names[i].Title),
Names[i].Title,
GetLastError());
}
}
if ( machineName != NULL ) {
WCHAR compName[ 256 ];
BOOL success;
DWORD compNameSize = sizeof( compName ) / sizeof( WCHAR );
printf("IADs_Computer output\n\n");
if ( machineName == NULL ) {
success = GetComputerName( compName, &compNameSize );
if ( success ) {
machineName = compName;
} else {
printf("GetComputerName failed - %u\n", status = GetLastError() );
return status;
}
}
hr = CoInitializeEx( NULL, COINIT_APARTMENTTHREADED );
if ( SUCCEEDED( hr )) {
IADsComputer *pComp;
wsprintf( bindingString, L"WinNT://%ws/%ws,computer", dcName, machineName );
printf("Connecting to: %ws\n", bindingString );
hr = ADsGetObject( bindingString, IID_IADsComputer, (void **)&pComp );
if ( SUCCEEDED( hr )) {
BSTR bstr;
IADs *pADs;
hr = pComp->QueryInterface(IID_IADs, (void**) &pADs);
if ( SUCCEEDED( hr )) {
if( S_OK == pADs->get_Name(&bstr) ) {
printf("Object Name: %S\n",bstr);
}
if( S_OK == pADs->get_GUID(&bstr) ) {
printf("Object GUID: %S\n",bstr);
}
if( S_OK == pADs->get_ADsPath(&bstr) ) {
printf("Object path: %S\n",bstr);
}
if( S_OK == pADs->get_Class(&bstr) ) {
printf("Object class: %S\n",bstr);
}
if( S_OK == pADs->get_Schema(&bstr) ) {
printf("Schema: %S\n",bstr);
}
IADsClass *pCls;
hr = ADsGetObject(bstr,IID_IADsClass, (void**)&pCls);
if ( hr == S_OK) {
if( S_OK == pCls->get_Name(&bstr) ) {
printf("Class name is %S\n", bstr);
}
pCls->Release();
}
hr = pComp->get_ComputerID( &bstr);
if ( SUCCEEDED( hr )) {
printf("Computer ID: %S\n",bstr);
SysFreeString(bstr);
} else {
printf("Computer ID: error = %X\n",hr);
}
hr = pComp->get_Description( &bstr );
if ( SUCCEEDED( hr )) {
printf("Description: %S\n",bstr);
SysFreeString(bstr);
} else {
printf("Description: error = %X\n",hr);
}
hr = pComp->get_OperatingSystem( &bstr );
if ( SUCCEEDED( hr )) {
printf("OS: %S\n",bstr);
SysFreeString(bstr);
} else {
printf("Description: error = %X\n",hr);
}
hr = pComp->get_OperatingSystemVersion( &bstr );
if ( SUCCEEDED( hr )) {
printf("OS Version: %S\n",bstr);
SysFreeString(bstr);
} else {
printf("Description: error = %X\n",hr);
}
hr = pComp->get_Role( &bstr );
if ( SUCCEEDED( hr )) {
printf("Role: %S\n",bstr);
SysFreeString(bstr);
} else {
printf("Role: error = %X\n",hr);
}
pADs->Release();
}
pComp->Release();
} else {
printf("ADsGetObject(IADs_Computer) failed for %ws - 0x%X\n", bindingString, hr );
}
//
// now bind to the Directory Object for this computer object
// and get attributes passed in through the cmd line that are
// not available through IComputer.
//
IDirectoryObject * pDir ;
DWORD dwNumAttr = argc - 4;
if ( dwNumAttr > 0 ) {
printf("\nIDirectoryObject output\n\n" );
bufSize = 512;
if ( GetComputerObjectName(NameFullyQualifiedDN, buffer, &bufSize)) {
wsprintf( bindingString, L"LDAP://%ws", buffer );
printf("Connecting to: %ws\n", bindingString );
hr = ADsGetObject( bindingString, IID_IDirectoryObject, (void **)&pDir );
if ( SUCCEEDED( hr )) {
ADS_ATTR_INFO * pAttrInfo=NULL;
DWORD dwReturn;
LPWSTR * pAttrNames = &argv[4];
hr = pDir->GetObjectAttributes( pAttrNames,
dwNumAttr,
&pAttrInfo,
&dwReturn );
if ( SUCCEEDED(hr) ) {
for(DWORD idx=0; idx < dwReturn;idx++, pAttrInfo++ ) {
printf( "Attr Name: %ws\n", pAttrInfo->pszAttrName );
printf( "Attr Type: %s (%u)\n",
ADSTypeNames[pAttrInfo->dwADsType],
pAttrInfo->dwADsType );
printf( "Attr Num Values: %u\n", pAttrInfo->dwNumValues );
if ( pAttrInfo->dwADsType == ADSTYPE_CASE_EXACT_STRING ||
pAttrInfo->dwADsType == ADSTYPE_DN_STRING ||
pAttrInfo->dwADsType == ADSTYPE_CASE_IGNORE_STRING ||
pAttrInfo->dwADsType == ADSTYPE_PRINTABLE_STRING ||
pAttrInfo->dwADsType == ADSTYPE_NUMERIC_STRING)
{
for (DWORD val=0; val < pAttrInfo->dwNumValues; val++, pAttrInfo->pADsValues++)
printf(" %ws\n", pAttrInfo->pADsValues->CaseIgnoreString);
}
else if ( pAttrInfo->dwADsType == ADSTYPE_BOOLEAN ) {
printf(" %ws\n", pAttrInfo->pADsValues->Boolean ? L"TRUE" : L"FALSE");
}
else if ( pAttrInfo->dwADsType == ADSTYPE_INTEGER ) {
printf(" %u\n", pAttrInfo->pADsValues->Integer );
}
else if ( pAttrInfo->dwADsType == ADSTYPE_OBJECT_CLASS ) {
printf(" %ws\n", pAttrInfo->pADsValues->ClassName );
}
else if ( pAttrInfo->dwADsType == ADSTYPE_NT_SECURITY_DESCRIPTOR ) {
PSECURITY_DESCRIPTOR pSD = pAttrInfo->pADsValues->SecurityDescriptor.lpValue;
DWORD sdLength = pAttrInfo->pADsValues->SecurityDescriptor.dwLength;
if ( IsValidSecurityDescriptor( pSD )) {
ClRtlExamineSD( pSD, " " );
} else {
printf(" SD is invalid\n" );
}
}
}
}
pDir->Release();
} else {
printf("ADsGetObject(IDirectoryObject) failed for %ws - 0x%X\n", bindingString, hr );
}
} else {
printf("GetComputerObjectName failed - %u\n", GetLastError());
}
}
} else {
printf("CoInitializeEx failed - %X\n", hr );
}
}
}
else if ( opCode == GUID ) {
IDirectoryObject * pDir = NULL;
LPWSTR objectGuid = argv[2];
DWORD dwNumAttr = argc - 3;
LPWSTR * pAttrNames = &argv[3];
IADs * pADs;
hr = CoInitializeEx( NULL, COINIT_APARTMENTTHREADED );
if ( SUCCEEDED( hr )) {
//
// GUID bindings are of the form with or without hyphens. With
// hyphens uses the standard notation and observes the byte
// ordering approprite for that format. Without hyphens is a
// stream of bytes, i.e., the first 4 bytes are in reverse order
// as compared to the hypenated version
//
// Without hyphens: 2deb53aa57a6d211bbcd00105a24d6db
// With hyphens: aa53eb2d-a657-11d2-bbcd-00105a24d6db
//
wsprintf( bindingString, L"LDAP://<GUID=%ws>", objectGuid );
printf("Connecting to: %ws\n", bindingString );
hr = ADsGetObject( bindingString, IID_IDirectoryObject, (void **)&pDir );
if ( SUCCEEDED( hr )) {
ADS_ATTR_INFO * pAttrInfo=NULL;
DWORD dwReturn;
hr = pDir->GetObjectAttributes( pAttrNames,
dwNumAttr,
&pAttrInfo,
&dwReturn );
if ( SUCCEEDED(hr) ) {
for(DWORD idx=0; idx < dwReturn;idx++, pAttrInfo++ ) {
printf( "Attr Name: %ws\n", pAttrInfo->pszAttrName );
printf( "Attr Type: %s (%u)\n",
ADSTypeNames[pAttrInfo->dwADsType],
pAttrInfo->dwADsType );
printf( "Attr Num Values: %u\n", pAttrInfo->dwNumValues );
if ( pAttrInfo->dwADsType == ADSTYPE_CASE_EXACT_STRING ||
pAttrInfo->dwADsType == ADSTYPE_DN_STRING ||
pAttrInfo->dwADsType == ADSTYPE_CASE_IGNORE_STRING ||
pAttrInfo->dwADsType == ADSTYPE_PRINTABLE_STRING ||
pAttrInfo->dwADsType == ADSTYPE_NUMERIC_STRING)
{
for (DWORD val=0; val < pAttrInfo->dwNumValues; val++, pAttrInfo->pADsValues++)
printf(" %ws\n", pAttrInfo->pADsValues->CaseIgnoreString);
}
else if ( pAttrInfo->dwADsType == ADSTYPE_BOOLEAN ) {
printf(" %ws\n", pAttrInfo->pADsValues->Boolean ? L"TRUE" : L"FALSE");
}
else if ( pAttrInfo->dwADsType == ADSTYPE_INTEGER ) {
printf(" %u\n", pAttrInfo->pADsValues->Integer );
}
else if ( pAttrInfo->dwADsType == ADSTYPE_OBJECT_CLASS ) {
printf(" %ws\n", pAttrInfo->pADsValues->ClassName );
}
else if ( pAttrInfo->dwADsType == ADSTYPE_NT_SECURITY_DESCRIPTOR ) {
PSECURITY_DESCRIPTOR pSD = pAttrInfo->pADsValues->SecurityDescriptor.lpValue;
DWORD sdLength = pAttrInfo->pADsValues->SecurityDescriptor.dwLength;
if ( IsValidSecurityDescriptor( pSD )) {
ClRtlExamineSD( pSD, " " );
} else {
printf(" SD is invalid\n" );
}
}
}
}
hr = pDir->QueryInterface(IID_IADs, (void**) &pADs);
if ( SUCCEEDED( hr )) {
BSTR bstr;
if( S_OK == pADs->get_Name(&bstr) ) {
printf("Object Name: %S\n",bstr);
}
if( S_OK == pADs->get_GUID(&bstr) ) {
printf("Object GUID: %S\n",bstr);
}
if( S_OK == pADs->get_ADsPath(&bstr) ) {
printf("Object path: %S\n",bstr);
}
if( S_OK == pADs->get_Class(&bstr) ) {
printf("Object class: %S\n",bstr);
}
if( S_OK == pADs->get_Schema(&bstr) ) {
printf("Schema: %S\n",bstr);
}
pADs->Release();
}
pDir->Release();
} else {
printf("ADsGetObject(IADs) failed for %ws - 0x%X\n", bindingString, hr );
}
}
}
} // wmain
/* end compobj.c */