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.

529 lines
19 KiB

  1. /*++
  2. Copyright (c) 1999 Microsoft Corporation
  3. Module Name:
  4. compobj.c
  5. Abstract:
  6. GetComputerObjectName utility.
  7. Author:
  8. Charlie Wickham (charlwi) 22-Jul-1999
  9. Environment:
  10. User mode
  11. Revision History:
  12. --*/
  13. #define UNICODE 1
  14. #define _UNICODE 1
  15. //#define COBJMACROS
  16. #include <windows.h>
  17. #include <stdio.h>
  18. #include <stdlib.h>
  19. #include <lm.h>
  20. #include <lmaccess.h>
  21. #include <objbase.h>
  22. #include <iads.h>
  23. #include <adshlp.h>
  24. #include <adserr.h>
  25. #define SECURITY_WIN32
  26. #include <security.h>
  27. #include "clusvmsg.h"
  28. #include "clusrtl.h"
  29. #define ADD 1
  30. #define DEL 2
  31. #define QUERY 3
  32. #define GUID 4
  33. struct _NAMES {
  34. PWCHAR Title;
  35. EXTENDED_NAME_FORMAT Code;
  36. } Names[] = {
  37. L"FQDN\t\t", NameFullyQualifiedDN,
  38. L"SAM\t\t", NameSamCompatible,
  39. L"Display\t\t", NameDisplay,
  40. L"UID\t\t", NameUniqueId,
  41. L"Canonical\t", NameCanonical,
  42. L"UserPrin\t\t", NameUserPrincipal,
  43. L"Can EX\t\t", NameCanonicalEx,
  44. L"SPN\t\t", NameServicePrincipal
  45. };
  46. PCHAR ADSTypeNames[] = {
  47. "INVALID",
  48. "DN_STRING",
  49. "CASE_EXACT_STRING",
  50. "CASE_IGNORE_STRING",
  51. "PRINTABLE_STRING",
  52. "NUMERIC_STRING",
  53. "BOOLEAN",
  54. "INTEGER",
  55. "OCTET_STRING",
  56. "UTC_TIME",
  57. "LARGE_INTEGER",
  58. "PROV_SPECIFIC",
  59. "OBJECT_CLASS",
  60. "CASEIGNORE_LIST",
  61. "OCTET_LIST",
  62. "PATH",
  63. "POSTALADDRESS",
  64. "TIMESTAMP",
  65. "BACKLINK",
  66. "TYPEDNAME",
  67. "HOLD",
  68. "NETADDRESS",
  69. "REPLICAPOINTER",
  70. "FAXNUMBER",
  71. "EMAIL",
  72. "NT_SECURITY_DESCRIPTOR",
  73. "UNKNOWN",
  74. "DN_WITH_BINARY",
  75. "DN_WITH_STRING"
  76. };
  77. int __cdecl
  78. wmain(
  79. int argc,
  80. WCHAR *argv[]
  81. )
  82. /*++
  83. Routine Description:
  84. main routine for utility
  85. Arguments:
  86. standard command line args
  87. Return Value:
  88. 0 if it worked successfully
  89. --*/
  90. {
  91. WCHAR buffer[512];
  92. DWORD bufSize;
  93. BOOL success;
  94. DWORD i;
  95. USER_INFO_1 netUI1;
  96. DWORD badParam;
  97. DWORD status;
  98. PWCHAR dcName = argv[2];
  99. PWCHAR machineName = NULL;
  100. DWORD opCode;
  101. WCHAR bindingString[512];
  102. HRESULT hr;
  103. if ( argc == 1 ){
  104. printf("%ws -add dcName nodename pwd\n", argv[0]);
  105. printf("%ws -del dcName nodename\n", argv[0]);
  106. printf("%ws -query domain [nodename]\n", argv[0]);
  107. printf("%ws -guid objectGUID attr [attr ...]\n", argv[0]);
  108. return 0;
  109. }
  110. if ( _wcsnicmp( argv[1], L"-add", 4 ) == 0 ) {
  111. if ( argc < 5 ) {
  112. printf("%ws -add dcName nodename pwd\n", argv[0]);
  113. return 0;
  114. }
  115. opCode = ADD;
  116. dcName = argv[2];
  117. machineName = argv[3];
  118. }
  119. else if ( _wcsnicmp( argv[1], L"-del", 4 ) == 0 ) {
  120. if ( argc < 4 ) {
  121. printf("%ws -del dcName nodename\n", argv[0]);
  122. return 0;
  123. }
  124. opCode = DEL;
  125. dcName = argv[2];
  126. machineName = argv[3];
  127. }
  128. else if ( _wcsnicmp( argv[1], L"-query", 6 ) == 0 ) {
  129. opCode = QUERY;
  130. if ( argc > 3 ) {
  131. machineName = argv[3];
  132. }
  133. }
  134. else if ( _wcsnicmp( argv[1], L"-guid", 5 ) == 0 ) {
  135. if ( argc < 4 ) {
  136. printf("%ws -guid objectGUID attr [attr ...]\n", argv[0]);
  137. return 0;
  138. }
  139. opCode = GUID;
  140. }
  141. else {
  142. printf("%ws -add dcName nodename pwd\n", argv[0]);
  143. printf("%ws -del dcName nodename\n", argv[0]);
  144. printf("%ws -query domain [nodename attr [attr ...]]\n", argv[0]);
  145. printf("%ws -guid objectGUID attr [attr ...]\n", argv[0]);
  146. return 0;
  147. }
  148. if ( opCode == ADD ) {
  149. PWCHAR machinePwd = argv[4];
  150. RtlZeroMemory( &netUI1, sizeof( netUI1 ) );
  151. //
  152. // Initialize it..
  153. //
  154. netUI1.usri1_name = machineName;
  155. netUI1.usri1_password = machinePwd;
  156. netUI1.usri1_flags = UF_WORKSTATION_TRUST_ACCOUNT | UF_SCRIPT;
  157. netUI1.usri1_priv = USER_PRIV_USER;
  158. netUI1.usri1_comment = L"Server cluster virtual network name";
  159. status = NetUserAdd( dcName, 1, (PBYTE)&netUI1, &badParam );
  160. if ( status == NERR_Success ) {
  161. printf("NetUserAdd is successful.\n");
  162. } else {
  163. printf( "NetUserAdd on '%ws' for '%ws' failed: 0x%X - params = %d\n",
  164. dcName, machineName, status, badParam );
  165. return status;
  166. }
  167. }
  168. else if ( opCode == DEL ) {
  169. status = NetUserDel( dcName, machineName );
  170. if ( status == NERR_Success ) {
  171. printf("NetUserDel is successful.\n");
  172. } else {
  173. printf( "NetUserDel on '%ws' for '%ws' failed: 0x%X\n", dcName, machineName, status );
  174. return status;
  175. }
  176. }
  177. else if ( opCode == QUERY ) {
  178. dcName = argv[2];
  179. printf("Output from GetComputerObjectName()\n");
  180. for ( i = 0; i < sizeof(Names)/sizeof(struct _NAMES); ++i ) {
  181. //
  182. // loop through the different name variants, printing the associated result
  183. //
  184. bufSize = 512;
  185. success = GetComputerObjectName(Names[i].Code,
  186. buffer, &bufSize);
  187. if ( success ) {
  188. printf("%ws%ws\n\n", Names[i].Title, buffer );
  189. } else {
  190. printf("\nFAILED: %.*ws (%d)\n\n",
  191. (wcschr(Names[i].Title, L'\t') - Names[i].Title),
  192. Names[i].Title,
  193. GetLastError());
  194. }
  195. }
  196. if ( machineName != NULL ) {
  197. WCHAR compName[ 256 ];
  198. BOOL success;
  199. DWORD compNameSize = sizeof( compName ) / sizeof( WCHAR );
  200. printf("IADs_Computer output\n\n");
  201. if ( machineName == NULL ) {
  202. success = GetComputerName( compName, &compNameSize );
  203. if ( success ) {
  204. machineName = compName;
  205. } else {
  206. printf("GetComputerName failed - %u\n", status = GetLastError() );
  207. return status;
  208. }
  209. }
  210. hr = CoInitializeEx( NULL, COINIT_APARTMENTTHREADED );
  211. if ( SUCCEEDED( hr )) {
  212. IADsComputer *pComp;
  213. wsprintf( bindingString, L"WinNT://%ws/%ws,computer", dcName, machineName );
  214. printf("Connecting to: %ws\n", bindingString );
  215. hr = ADsGetObject( bindingString, IID_IADsComputer, (void **)&pComp );
  216. if ( SUCCEEDED( hr )) {
  217. BSTR bstr;
  218. IADs *pADs;
  219. hr = pComp->QueryInterface(IID_IADs, (void**) &pADs);
  220. if ( SUCCEEDED( hr )) {
  221. if( S_OK == pADs->get_Name(&bstr) ) {
  222. printf("Object Name: %S\n",bstr);
  223. }
  224. if( S_OK == pADs->get_GUID(&bstr) ) {
  225. printf("Object GUID: %S\n",bstr);
  226. }
  227. if( S_OK == pADs->get_ADsPath(&bstr) ) {
  228. printf("Object path: %S\n",bstr);
  229. }
  230. if( S_OK == pADs->get_Class(&bstr) ) {
  231. printf("Object class: %S\n",bstr);
  232. }
  233. if( S_OK == pADs->get_Schema(&bstr) ) {
  234. printf("Schema: %S\n",bstr);
  235. }
  236. IADsClass *pCls;
  237. hr = ADsGetObject(bstr,IID_IADsClass, (void**)&pCls);
  238. if ( hr == S_OK) {
  239. if( S_OK == pCls->get_Name(&bstr) ) {
  240. printf("Class name is %S\n", bstr);
  241. }
  242. pCls->Release();
  243. }
  244. hr = pComp->get_ComputerID( &bstr);
  245. if ( SUCCEEDED( hr )) {
  246. printf("Computer ID: %S\n",bstr);
  247. SysFreeString(bstr);
  248. } else {
  249. printf("Computer ID: error = %X\n",hr);
  250. }
  251. hr = pComp->get_Description( &bstr );
  252. if ( SUCCEEDED( hr )) {
  253. printf("Description: %S\n",bstr);
  254. SysFreeString(bstr);
  255. } else {
  256. printf("Description: error = %X\n",hr);
  257. }
  258. hr = pComp->get_OperatingSystem( &bstr );
  259. if ( SUCCEEDED( hr )) {
  260. printf("OS: %S\n",bstr);
  261. SysFreeString(bstr);
  262. } else {
  263. printf("Description: error = %X\n",hr);
  264. }
  265. hr = pComp->get_OperatingSystemVersion( &bstr );
  266. if ( SUCCEEDED( hr )) {
  267. printf("OS Version: %S\n",bstr);
  268. SysFreeString(bstr);
  269. } else {
  270. printf("Description: error = %X\n",hr);
  271. }
  272. hr = pComp->get_Role( &bstr );
  273. if ( SUCCEEDED( hr )) {
  274. printf("Role: %S\n",bstr);
  275. SysFreeString(bstr);
  276. } else {
  277. printf("Role: error = %X\n",hr);
  278. }
  279. pADs->Release();
  280. }
  281. pComp->Release();
  282. } else {
  283. printf("ADsGetObject(IADs_Computer) failed for %ws - 0x%X\n", bindingString, hr );
  284. }
  285. //
  286. // now bind to the Directory Object for this computer object
  287. // and get attributes passed in through the cmd line that are
  288. // not available through IComputer.
  289. //
  290. IDirectoryObject * pDir ;
  291. DWORD dwNumAttr = argc - 4;
  292. if ( dwNumAttr > 0 ) {
  293. printf("\nIDirectoryObject output\n\n" );
  294. bufSize = 512;
  295. if ( GetComputerObjectName(NameFullyQualifiedDN, buffer, &bufSize)) {
  296. wsprintf( bindingString, L"LDAP://%ws", buffer );
  297. printf("Connecting to: %ws\n", bindingString );
  298. hr = ADsGetObject( bindingString, IID_IDirectoryObject, (void **)&pDir );
  299. if ( SUCCEEDED( hr )) {
  300. ADS_ATTR_INFO * pAttrInfo=NULL;
  301. DWORD dwReturn;
  302. LPWSTR * pAttrNames = &argv[4];
  303. hr = pDir->GetObjectAttributes( pAttrNames,
  304. dwNumAttr,
  305. &pAttrInfo,
  306. &dwReturn );
  307. if ( SUCCEEDED(hr) ) {
  308. for(DWORD idx=0; idx < dwReturn;idx++, pAttrInfo++ ) {
  309. printf( "Attr Name: %ws\n", pAttrInfo->pszAttrName );
  310. printf( "Attr Type: %s (%u)\n",
  311. ADSTypeNames[pAttrInfo->dwADsType],
  312. pAttrInfo->dwADsType );
  313. printf( "Attr Num Values: %u\n", pAttrInfo->dwNumValues );
  314. if ( pAttrInfo->dwADsType == ADSTYPE_CASE_EXACT_STRING ||
  315. pAttrInfo->dwADsType == ADSTYPE_DN_STRING ||
  316. pAttrInfo->dwADsType == ADSTYPE_CASE_IGNORE_STRING ||
  317. pAttrInfo->dwADsType == ADSTYPE_PRINTABLE_STRING ||
  318. pAttrInfo->dwADsType == ADSTYPE_NUMERIC_STRING)
  319. {
  320. for (DWORD val=0; val < pAttrInfo->dwNumValues; val++, pAttrInfo->pADsValues++)
  321. printf(" %ws\n", pAttrInfo->pADsValues->CaseIgnoreString);
  322. }
  323. else if ( pAttrInfo->dwADsType == ADSTYPE_BOOLEAN ) {
  324. printf(" %ws\n", pAttrInfo->pADsValues->Boolean ? L"TRUE" : L"FALSE");
  325. }
  326. else if ( pAttrInfo->dwADsType == ADSTYPE_INTEGER ) {
  327. printf(" %u\n", pAttrInfo->pADsValues->Integer );
  328. }
  329. else if ( pAttrInfo->dwADsType == ADSTYPE_OBJECT_CLASS ) {
  330. printf(" %ws\n", pAttrInfo->pADsValues->ClassName );
  331. }
  332. else if ( pAttrInfo->dwADsType == ADSTYPE_NT_SECURITY_DESCRIPTOR ) {
  333. PSECURITY_DESCRIPTOR pSD = pAttrInfo->pADsValues->SecurityDescriptor.lpValue;
  334. DWORD sdLength = pAttrInfo->pADsValues->SecurityDescriptor.dwLength;
  335. if ( IsValidSecurityDescriptor( pSD )) {
  336. ClRtlExamineSD( pSD, " " );
  337. } else {
  338. printf(" SD is invalid\n" );
  339. }
  340. }
  341. }
  342. }
  343. pDir->Release();
  344. } else {
  345. printf("ADsGetObject(IDirectoryObject) failed for %ws - 0x%X\n", bindingString, hr );
  346. }
  347. } else {
  348. printf("GetComputerObjectName failed - %u\n", GetLastError());
  349. }
  350. }
  351. } else {
  352. printf("CoInitializeEx failed - %X\n", hr );
  353. }
  354. }
  355. }
  356. else if ( opCode == GUID ) {
  357. IDirectoryObject * pDir = NULL;
  358. LPWSTR objectGuid = argv[2];
  359. DWORD dwNumAttr = argc - 3;
  360. LPWSTR * pAttrNames = &argv[3];
  361. IADs * pADs;
  362. hr = CoInitializeEx( NULL, COINIT_APARTMENTTHREADED );
  363. if ( SUCCEEDED( hr )) {
  364. //
  365. // GUID bindings are of the form with or without hyphens. With
  366. // hyphens uses the standard notation and observes the byte
  367. // ordering approprite for that format. Without hyphens is a
  368. // stream of bytes, i.e., the first 4 bytes are in reverse order
  369. // as compared to the hypenated version
  370. //
  371. // Without hyphens: 2deb53aa57a6d211bbcd00105a24d6db
  372. // With hyphens: aa53eb2d-a657-11d2-bbcd-00105a24d6db
  373. //
  374. wsprintf( bindingString, L"LDAP://<GUID=%ws>", objectGuid );
  375. printf("Connecting to: %ws\n", bindingString );
  376. hr = ADsGetObject( bindingString, IID_IDirectoryObject, (void **)&pDir );
  377. if ( SUCCEEDED( hr )) {
  378. ADS_ATTR_INFO * pAttrInfo=NULL;
  379. DWORD dwReturn;
  380. hr = pDir->GetObjectAttributes( pAttrNames,
  381. dwNumAttr,
  382. &pAttrInfo,
  383. &dwReturn );
  384. if ( SUCCEEDED(hr) ) {
  385. for(DWORD idx=0; idx < dwReturn;idx++, pAttrInfo++ ) {
  386. printf( "Attr Name: %ws\n", pAttrInfo->pszAttrName );
  387. printf( "Attr Type: %s (%u)\n",
  388. ADSTypeNames[pAttrInfo->dwADsType],
  389. pAttrInfo->dwADsType );
  390. printf( "Attr Num Values: %u\n", pAttrInfo->dwNumValues );
  391. if ( pAttrInfo->dwADsType == ADSTYPE_CASE_EXACT_STRING ||
  392. pAttrInfo->dwADsType == ADSTYPE_DN_STRING ||
  393. pAttrInfo->dwADsType == ADSTYPE_CASE_IGNORE_STRING ||
  394. pAttrInfo->dwADsType == ADSTYPE_PRINTABLE_STRING ||
  395. pAttrInfo->dwADsType == ADSTYPE_NUMERIC_STRING)
  396. {
  397. for (DWORD val=0; val < pAttrInfo->dwNumValues; val++, pAttrInfo->pADsValues++)
  398. printf(" %ws\n", pAttrInfo->pADsValues->CaseIgnoreString);
  399. }
  400. else if ( pAttrInfo->dwADsType == ADSTYPE_BOOLEAN ) {
  401. printf(" %ws\n", pAttrInfo->pADsValues->Boolean ? L"TRUE" : L"FALSE");
  402. }
  403. else if ( pAttrInfo->dwADsType == ADSTYPE_INTEGER ) {
  404. printf(" %u\n", pAttrInfo->pADsValues->Integer );
  405. }
  406. else if ( pAttrInfo->dwADsType == ADSTYPE_OBJECT_CLASS ) {
  407. printf(" %ws\n", pAttrInfo->pADsValues->ClassName );
  408. }
  409. else if ( pAttrInfo->dwADsType == ADSTYPE_NT_SECURITY_DESCRIPTOR ) {
  410. PSECURITY_DESCRIPTOR pSD = pAttrInfo->pADsValues->SecurityDescriptor.lpValue;
  411. DWORD sdLength = pAttrInfo->pADsValues->SecurityDescriptor.dwLength;
  412. if ( IsValidSecurityDescriptor( pSD )) {
  413. ClRtlExamineSD( pSD, " " );
  414. } else {
  415. printf(" SD is invalid\n" );
  416. }
  417. }
  418. }
  419. }
  420. hr = pDir->QueryInterface(IID_IADs, (void**) &pADs);
  421. if ( SUCCEEDED( hr )) {
  422. BSTR bstr;
  423. if( S_OK == pADs->get_Name(&bstr) ) {
  424. printf("Object Name: %S\n",bstr);
  425. }
  426. if( S_OK == pADs->get_GUID(&bstr) ) {
  427. printf("Object GUID: %S\n",bstr);
  428. }
  429. if( S_OK == pADs->get_ADsPath(&bstr) ) {
  430. printf("Object path: %S\n",bstr);
  431. }
  432. if( S_OK == pADs->get_Class(&bstr) ) {
  433. printf("Object class: %S\n",bstr);
  434. }
  435. if( S_OK == pADs->get_Schema(&bstr) ) {
  436. printf("Schema: %S\n",bstr);
  437. }
  438. pADs->Release();
  439. }
  440. pDir->Release();
  441. } else {
  442. printf("ADsGetObject(IADs) failed for %ws - 0x%X\n", bindingString, hr );
  443. }
  444. }
  445. }
  446. } // wmain
  447. /* end compobj.c */