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.

618 lines
15 KiB

  1. /*++
  2. REALMFLAGS.CXX
  3. Copyright (C) 1999 Microsoft Corporation, all rights reserved.
  4. DESCRIPTION: realm-flag manipulation code.
  5. Created, Jan 10, 2000 by DavidCHR.
  6. CONTENTS: CompareFlagIds
  7. VerboselyPrintAndRemoveFlagsById
  8. LookupRealmFlagByName
  9. PrintAndRemoveFlagNames
  10. SearchRealmFlagListByAttribute
  11. CompareFlagNames
  12. --*/
  13. #include "everything.hxx"
  14. typedef struct {
  15. ULONG Id; // from kerberos\client2\mitutil.h
  16. LPWSTR Name; // short string identifier
  17. LPSTR Explanation; // what this flag does.
  18. LPSTR MoreExplanation; // if you have to run to the next line.
  19. } KERB_REALM_FLAG_MAPPING, *PKERB_REALM_FLAG_MAPPING;
  20. /* These flags are defined in kerberos\client2\mitutil.h.
  21. However, there's other gunk in there that I'd rather not
  22. copy out so I'll just duplicate them.
  23. I'd consider auto-generating code fragments from the file
  24. to keep this file instantly up-to-date, but it wouldn't
  25. be guaranteed to provide human readable information */
  26. KERB_REALM_FLAG_MAPPING
  27. KerbRealmFlagMappings[] = {
  28. /* The order of "none" in the list is important. It must be
  29. before any of the other flags so that code that handles
  30. multiple flags as a mask will not hit this unless the
  31. whole mask is zero. */
  32. { 0x0,
  33. L"None",
  34. "No Realm Flags"
  35. },
  36. { 0x1,
  37. L"SendAddress",
  38. "Include IP numbers within tickets.",
  39. "Useful for solving SOME compatibility issues."
  40. },
  41. { 0x2,
  42. L"TcpSupported",
  43. "Indicates that this realm supports TCP.",
  44. "(as opposed to just UDP)" },
  45. { 0x4,
  46. L"Delegate",
  47. "Everyone in this realm is trusted for delegation" },
  48. { 0x8,
  49. L"NcSupported",
  50. "This realm supports Name Canonicalization" },
  51. };
  52. ULONG
  53. RealmFlagCount = ( sizeof( KerbRealmFlagMappings ) /
  54. sizeof( KerbRealmFlagMappings[ 0 ] ) );
  55. /* NOTES on REALMLISTCOMPAREFUNCTION:
  56. If your REALMLISTCOMPAREFUNCTION is designed to return multiple
  57. mappings or interpret multiple mappings (e.g. as a mask), then
  58. you must special case "None" in the array above. Otherwise,
  59. your output may include "none", which doesn't make any sense. */
  60. typedef BOOL REALMLISTCOMPAREFUNCTION( IN PVOID, // pvAttribute
  61. IN PKERB_REALM_FLAG_MAPPING );
  62. /*++**************************************************************
  63. NAME: CompareFlagIds
  64. compares a flag map to a flag id.
  65. pvAttribute is a pointer to the desired flag id.
  66. RETURNS: TRUE if this is the correct flagid
  67. FALSE otherwise.
  68. CREATED: Jan 10, 2000
  69. CALLED BY: SearchRealmFlagListByAttribute
  70. FREE WITH: n/a -- no resources are allocated
  71. **************************************************************--*/
  72. BOOL // REALMLISTCOMPAREFUNCTION
  73. CompareFlagIds( IN PVOID pvAttribute,
  74. IN PKERB_REALM_FLAG_MAPPING pMap ) {
  75. return ( pMap->Id == *(( PULONG ) pvAttribute) );
  76. }
  77. /*++**************************************************************
  78. NAME: CompareFlagNames
  79. Compares a mapping to a string for the flagname.
  80. RETURNS: TRUE if this mapping corresponds to the given string
  81. FALSE otherwise.
  82. CREATED: Jan 10, 2000
  83. CALLED BY: SearchRealmFlagListByAttribute
  84. FREE WITH: n/a -- no resources are allocated
  85. **************************************************************--*/
  86. BOOL // REALMLISTCOMPAREFUNCTION
  87. CompareFlagNames( IN PVOID pvAttribute,
  88. IN PKERB_REALM_FLAG_MAPPING pMap ) {
  89. return ( 0 == _wcsicmp( (LPWSTR) pvAttribute,
  90. pMap->Name ) );
  91. }
  92. /*++**************************************************************
  93. NAME: PrintAndRemoveFlagsById
  94. if the flag id matches, it is removed from the passed-in value,
  95. and the flagname is printed.
  96. MODIFIES: pvAttribute -- may be stripped of a bit
  97. TAKES: pvAttribute -- flagId to check
  98. pMap -- table entry to check against
  99. RETURNS: TRUE if pvAttribute is zero (stop searching)
  100. FALSE otherwise (keep searching)
  101. CREATED: Jan 10, 2000
  102. CALLED BY: SearchRealmFlagListByAttribute
  103. FREE WITH: n/a -- no resources are allocated
  104. **************************************************************--*/
  105. BOOL
  106. PrintAndRemoveFlagsById( IN PVOID pvAttribute,
  107. IN PKERB_REALM_FLAG_MAPPING pMap ) {
  108. if ( !pMap->Id ) {
  109. /* We special-case "none" so that we only print it
  110. if there are no other flags-- if other flags exist,
  111. "none" will be skipped over in the array */
  112. if ( !*(( PULONG ) pvAttribute ) ) {
  113. printf( " %ws",
  114. pMap->Name );
  115. return TRUE;
  116. } else {
  117. return FALSE;
  118. }
  119. }
  120. if ( ( *(( PULONG ) pvAttribute) & pMap->Id )
  121. == pMap->Id ) {
  122. *( (PULONG) pvAttribute ) &= ~pMap->Id;
  123. printf( " %ws",
  124. pMap->Name );
  125. }
  126. return *( (PULONG) pvAttribute ) == 0;
  127. }
  128. /*++**************************************************************
  129. NAME: VerboselyPrintAndRemoveFlagsById
  130. like PrintAndRemoveFlagsById, but it also dumps the
  131. flag id and explanation field.
  132. LOGGING: lots of it.
  133. CREATED: Jan 10, 2000
  134. CALLED BY: SearchRealmFlagListByAttribute
  135. FREE WITH: n/a -- no resources are allocated
  136. **************************************************************--*/
  137. BOOL
  138. VerboselyPrintAndRemoveFlagsById( IN PVOID pvAttribute,
  139. IN PKERB_REALM_FLAG_MAPPING pMap ) {
  140. #if 0
  141. if ( !pMap->Id ) {
  142. /* We special-case "none" so that we only print it
  143. if there are no other flags-- if other flags exist,
  144. "none" will be skipped over in the array */
  145. if ( !*(( PULONG ) pvAttribute ) ) {
  146. printf( "0x%02x %ws \t%hs\n",
  147. pMap->Id,
  148. pMap->Name,
  149. pMap->Explanation );
  150. return TRUE;
  151. } else {
  152. return FALSE;
  153. }
  154. }
  155. #endif
  156. if ( ( *(( PULONG ) pvAttribute) & pMap->Id )
  157. == pMap->Id ) {
  158. *( (PULONG) pvAttribute ) &= ~pMap->Id;
  159. printf( "0x%02x %-12ws %hs\n",
  160. pMap->Id,
  161. pMap->Name,
  162. pMap->Explanation );
  163. if ( pMap->MoreExplanation ) {
  164. printf( "%-17hs %hs\n",
  165. "",
  166. pMap->MoreExplanation );
  167. }
  168. }
  169. return *( (PULONG) pvAttribute ) == 0;
  170. }
  171. /*++**************************************************************
  172. NAME: SearchRealmFlagListByAttribute
  173. searches the realmlist for a particular attribute.
  174. MODIFIES: ppMapping -- receives the given mapping.
  175. TAKES: pvAttribute -- attribute value to search for
  176. pFunc -- function to use to find it
  177. RETURNS: TRUE if the value could be found
  178. FALSE otherwise.
  179. LASTERROR: not set
  180. LOGGING: none
  181. CREATED: Jan 10, 2000
  182. LOCKING: none
  183. CALLED BY: anyone
  184. FREE WITH: n/a -- no resources are allocated
  185. **************************************************************--*/
  186. BOOL
  187. SearchRealmFlagListByAttribute( IN PVOID pvAttribute,
  188. IN REALMLISTCOMPAREFUNCTION *pFunc,
  189. OUT PKERB_REALM_FLAG_MAPPING *ppMapping ) {
  190. ULONG i;
  191. PKERB_REALM_FLAG_MAPPING pMapping = &KerbRealmFlagMappings[ 0 ];
  192. for ( i = 0 ;
  193. i < RealmFlagCount ;
  194. i ++, pMapping++ ) {
  195. if ( pFunc( pvAttribute,
  196. pMapping ) ) {
  197. if ( ppMapping ) *ppMapping = pMapping;
  198. return TRUE;
  199. }
  200. }
  201. return FALSE;
  202. }
  203. /*++**************************************************************
  204. NAME: LookupRealmFlagByName
  205. given a name, maps it to a realm flag mapping structure
  206. MODIFIES: ppMapping -- receives the entry pointer
  207. TAKES: RealmFlagName -- name for which to search
  208. RETURNS: TRUE if the realmflag could be found.
  209. FALSE otherwise.
  210. LASTERROR:
  211. LOGGING:
  212. CREATED: Jan 10, 2000
  213. LOCKING:
  214. CALLED BY: anyone
  215. FREE WITH: n/a -- no resources are allocated
  216. **************************************************************--*/
  217. BOOL
  218. LookupRealmFlagByName( IN LPWSTR RealmFlagName,
  219. OUT PKERB_REALM_FLAG_MAPPING *ppMapping ) {
  220. return SearchRealmFlagListByAttribute( RealmFlagName,
  221. CompareFlagNames,
  222. ppMapping );
  223. }
  224. VOID
  225. PrintRealmFlags( IN ULONG RealmFlags ) {
  226. ULONG i;
  227. ULONG ioFlags = RealmFlags;
  228. if ( RealmFlags == 0 ) {
  229. printf( " none" );
  230. } else {
  231. if ( !SearchRealmFlagListByAttribute( &ioFlags,
  232. PrintAndRemoveFlagsById,
  233. NULL ) ) {
  234. printf( " [unknown" );
  235. if ( ioFlags != RealmFlags ) {
  236. printf( ": 0x%x",
  237. ioFlags );
  238. }
  239. printf( "]" );
  240. }
  241. }
  242. }
  243. NTSTATUS
  244. ListRealmFlags( LPWSTR * Ignored) {
  245. ULONG RealmFlags = ~0;
  246. printf( "\n"
  247. "Ksetup knows the following realm flags: \n" );
  248. SearchRealmFlagListByAttribute( &RealmFlags,
  249. VerboselyPrintAndRemoveFlagsById,
  250. NULL );
  251. printf( "\n" );
  252. exit( 0 ); /* Jump out. */
  253. return STATUS_SUCCESS;
  254. }
  255. NTSTATUS
  256. GetRealmFlags( IN LPWSTR RealmName,
  257. OUT PULONG pulRealmFlags ) {
  258. HKEY hKey;
  259. NTSTATUS N = STATUS_UNSUCCESSFUL;
  260. DWORD dwErr, Type, Len = sizeof( *pulRealmFlags );
  261. dwErr = OpenSubKey( &RealmName,
  262. &hKey );
  263. if ( dwErr == ERROR_SUCCESS ) {
  264. dwErr = RegQueryValueEx( hKey,
  265. KERB_DOMAIN_REALM_FLAGS_VALUE,
  266. NULL, // mbz
  267. &Type,
  268. (LPBYTE) pulRealmFlags,
  269. &Len );
  270. switch ( dwErr ) {
  271. case ERROR_SUCCESS:
  272. N = STATUS_SUCCESS;
  273. break;
  274. case ERROR_FILE_NOT_FOUND:
  275. case ERROR_PATH_NOT_FOUND:
  276. /* 453545: if the realm flags aren't specified,
  277. don't complain about it. */
  278. N = STATUS_SUCCESS;
  279. *pulRealmFlags = 0;
  280. break;
  281. default:
  282. printf( "Failed to query %ws for %ws: 0x%x\n",
  283. KERB_DOMAIN_REALM_FLAGS_VALUE,
  284. RealmName,
  285. dwErr );
  286. }
  287. RegCloseKey( hKey );
  288. } // else error has already been printed.
  289. return N;
  290. }
  291. NTSTATUS
  292. SetRealmFlags( IN LPWSTR RealmName,
  293. IN ULONG ulRealmFlags ) {
  294. HKEY hKey;
  295. NTSTATUS N = STATUS_UNSUCCESSFUL;
  296. DWORD dwErr, Len = sizeof( ulRealmFlags );
  297. dwErr = OpenSubKey( &RealmName,
  298. &hKey );
  299. if ( dwErr == ERROR_SUCCESS ) {
  300. dwErr = RegSetValueEx( hKey,
  301. KERB_DOMAIN_REALM_FLAGS_VALUE,
  302. NULL, // mbz
  303. REG_DWORD,
  304. (LPBYTE) &ulRealmFlags,
  305. Len );
  306. switch ( dwErr ) {
  307. case ERROR_SUCCESS:
  308. DEBUGPRINT( DEBUG_REGISTRY,
  309. ( "Set Realm Flags for %ws to 0x%x\n",
  310. RealmName,
  311. ulRealmFlags ) ) ;
  312. N = STATUS_SUCCESS;
  313. break;
  314. default:
  315. printf( "Failed to write %ws for %ws: 0x%x\n",
  316. KERB_DOMAIN_REALM_FLAGS_VALUE,
  317. RealmName,
  318. dwErr );
  319. }
  320. RegCloseKey( hKey );
  321. } // else error has already been printed.
  322. return N;
  323. }
  324. NTSTATUS
  325. ResolveRealmFlags( IN LPWSTR *Params,
  326. IN OUT PULONG pulFlags ) {
  327. ULONG id;
  328. LPWSTR Cursor, *pFlagCursor = Params;
  329. PKERB_REALM_FLAG_MAPPING pMap;
  330. NTSTATUS N = STATUS_SUCCESS;
  331. do {
  332. DEBUGPRINT( DEBUG_OPTIONS,
  333. ( "Checking realmflag \"%ws\"...\n",
  334. *pFlagCursor ) );
  335. // first, try to convert to hex.
  336. id = wcstoul( *pFlagCursor,
  337. &Cursor,
  338. 0 ); // use defaults
  339. if ( *Cursor != '\0' ) {
  340. if ( !LookupRealmFlagByName( *pFlagCursor,
  341. &pMap ) ) {
  342. printf( "Unknown Realm Flag: \"%ws\"\n",
  343. *pFlagCursor );
  344. N = STATUS_INVALID_PARAMETER;
  345. break;
  346. } else {
  347. id = pMap->Id;
  348. }
  349. } // otherwise, the work's already been done.
  350. pFlagCursor++;
  351. *pulFlags |= id;
  352. } while( *pFlagCursor != NULL );
  353. return N;
  354. }
  355. NTSTATUS
  356. SetRealmFlags( IN LPWSTR *Params ) {
  357. LPWSTR RealmName = Params[ 0 ];
  358. ULONG RealmFlags = 0;
  359. NTSTATUS N = STATUS_SUCCESS; // 279621: this was uninitialized.
  360. if( Params[1] != NULL )
  361. {
  362. N = ResolveRealmFlags( Params+1,
  363. &RealmFlags );
  364. if ( NT_SUCCESS( N ) )
  365. {
  366. N = SetRealmFlags( RealmName,
  367. RealmFlags );
  368. }
  369. }
  370. else // Clear all realm flags
  371. {
  372. SetRealmFlags( RealmName, 0 );
  373. }
  374. return N;
  375. }
  376. NTSTATUS
  377. AddRealmFlags( IN LPWSTR *Params ) {
  378. LPWSTR RealmName = Params[ 0 ];
  379. ULONG RealmFlags = 0;
  380. NTSTATUS N;
  381. N = GetRealmFlags( RealmName,
  382. &RealmFlags );
  383. if ( NT_SUCCESS( N ) ) {
  384. N = ResolveRealmFlags( Params+1,
  385. &RealmFlags );
  386. if ( NT_SUCCESS( N ) ) {
  387. N = SetRealmFlags( RealmName,
  388. RealmFlags );
  389. }
  390. }
  391. return N;
  392. }
  393. NTSTATUS
  394. DelRealmFlags( IN LPWSTR *Params ) {
  395. LPWSTR RealmName = Params[ 0 ];
  396. ULONG RealmFlags = 0;
  397. ULONG DeleteFlags = 0;
  398. NTSTATUS N;
  399. N = GetRealmFlags( RealmName,
  400. &RealmFlags );
  401. if ( NT_SUCCESS( N ) ) {
  402. N = ResolveRealmFlags( Params+1,
  403. &DeleteFlags );
  404. if ( NT_SUCCESS( N ) ) {
  405. N = SetRealmFlags( RealmName,
  406. RealmFlags &~ DeleteFlags );
  407. }
  408. }
  409. return N;
  410. }