|
|
/*++
REALMFLAGS.CXX
Copyright (C) 1999 Microsoft Corporation, all rights reserved.
DESCRIPTION: realm-flag manipulation code.
Created, Jan 10, 2000 by DavidCHR.
CONTENTS: CompareFlagIds VerboselyPrintAndRemoveFlagsById LookupRealmFlagByName PrintAndRemoveFlagNames SearchRealmFlagListByAttribute CompareFlagNames
--*/
#include "everything.hxx"
typedef struct {
ULONG Id; // from kerberos\client2\mitutil.h
LPWSTR Name; // short string identifier
LPSTR Explanation; // what this flag does.
LPSTR MoreExplanation; // if you have to run to the next line.
} KERB_REALM_FLAG_MAPPING, *PKERB_REALM_FLAG_MAPPING;
/* These flags are defined in kerberos\client2\mitutil.h.
However, there's other gunk in there that I'd rather not copy out so I'll just duplicate them.
I'd consider auto-generating code fragments from the file to keep this file instantly up-to-date, but it wouldn't be guaranteed to provide human readable information */
KERB_REALM_FLAG_MAPPING KerbRealmFlagMappings[] = {
/* The order of "none" in the list is important. It must be
before any of the other flags so that code that handles multiple flags as a mask will not hit this unless the whole mask is zero. */
{ 0x0, L"None", "No Realm Flags" },
{ 0x1, L"SendAddress", "Include IP numbers within tickets.", "Useful for solving SOME compatibility issues." },
{ 0x2, L"TcpSupported", "Indicates that this realm supports TCP.", "(as opposed to just UDP)" },
{ 0x4, L"Delegate", "Everyone in this realm is trusted for delegation" },
{ 0x8, L"NcSupported", "This realm supports Name Canonicalization" },
};
ULONG RealmFlagCount = ( sizeof( KerbRealmFlagMappings ) / sizeof( KerbRealmFlagMappings[ 0 ] ) );
/* NOTES on REALMLISTCOMPAREFUNCTION:
If your REALMLISTCOMPAREFUNCTION is designed to return multiple mappings or interpret multiple mappings (e.g. as a mask), then you must special case "None" in the array above. Otherwise, your output may include "none", which doesn't make any sense. */
typedef BOOL REALMLISTCOMPAREFUNCTION( IN PVOID, // pvAttribute
IN PKERB_REALM_FLAG_MAPPING );
/*++**************************************************************
NAME: CompareFlagIds
compares a flag map to a flag id. pvAttribute is a pointer to the desired flag id.
RETURNS: TRUE if this is the correct flagid FALSE otherwise. CREATED: Jan 10, 2000 CALLED BY: SearchRealmFlagListByAttribute FREE WITH: n/a -- no resources are allocated **************************************************************--*/
BOOL // REALMLISTCOMPAREFUNCTION
CompareFlagIds( IN PVOID pvAttribute, IN PKERB_REALM_FLAG_MAPPING pMap ) {
return ( pMap->Id == *(( PULONG ) pvAttribute) );
}
/*++**************************************************************
NAME: CompareFlagNames
Compares a mapping to a string for the flagname.
RETURNS: TRUE if this mapping corresponds to the given string FALSE otherwise. CREATED: Jan 10, 2000 CALLED BY: SearchRealmFlagListByAttribute FREE WITH: n/a -- no resources are allocated **************************************************************--*/
BOOL // REALMLISTCOMPAREFUNCTION
CompareFlagNames( IN PVOID pvAttribute, IN PKERB_REALM_FLAG_MAPPING pMap ) {
return ( 0 == _wcsicmp( (LPWSTR) pvAttribute, pMap->Name ) ); }
/*++**************************************************************
NAME: PrintAndRemoveFlagsById
if the flag id matches, it is removed from the passed-in value, and the flagname is printed.
MODIFIES: pvAttribute -- may be stripped of a bit
TAKES: pvAttribute -- flagId to check pMap -- table entry to check against
RETURNS: TRUE if pvAttribute is zero (stop searching) FALSE otherwise (keep searching)
CREATED: Jan 10, 2000 CALLED BY: SearchRealmFlagListByAttribute FREE WITH: n/a -- no resources are allocated **************************************************************--*/
BOOL PrintAndRemoveFlagsById( IN PVOID pvAttribute, IN PKERB_REALM_FLAG_MAPPING pMap ) {
if ( !pMap->Id ) {
/* We special-case "none" so that we only print it
if there are no other flags-- if other flags exist, "none" will be skipped over in the array */
if ( !*(( PULONG ) pvAttribute ) ) { printf( " %ws", pMap->Name );
return TRUE; } else { return FALSE; } }
if ( ( *(( PULONG ) pvAttribute) & pMap->Id ) == pMap->Id ) {
*( (PULONG) pvAttribute ) &= ~pMap->Id; printf( " %ws", pMap->Name );
}
return *( (PULONG) pvAttribute ) == 0;
}
/*++**************************************************************
NAME: VerboselyPrintAndRemoveFlagsById
like PrintAndRemoveFlagsById, but it also dumps the flag id and explanation field.
LOGGING: lots of it. CREATED: Jan 10, 2000 CALLED BY: SearchRealmFlagListByAttribute FREE WITH: n/a -- no resources are allocated **************************************************************--*/
BOOL VerboselyPrintAndRemoveFlagsById( IN PVOID pvAttribute, IN PKERB_REALM_FLAG_MAPPING pMap ) {
#if 0
if ( !pMap->Id ) {
/* We special-case "none" so that we only print it
if there are no other flags-- if other flags exist, "none" will be skipped over in the array */
if ( !*(( PULONG ) pvAttribute ) ) { printf( "0x%02x %ws \t%hs\n", pMap->Id, pMap->Name, pMap->Explanation ); return TRUE; } else { return FALSE; } } #endif
if ( ( *(( PULONG ) pvAttribute) & pMap->Id ) == pMap->Id ) {
*( (PULONG) pvAttribute ) &= ~pMap->Id; printf( "0x%02x %-12ws %hs\n", pMap->Id, pMap->Name, pMap->Explanation );
if ( pMap->MoreExplanation ) {
printf( "%-17hs %hs\n", "", pMap->MoreExplanation ); }
}
return *( (PULONG) pvAttribute ) == 0;
}
/*++**************************************************************
NAME: SearchRealmFlagListByAttribute
searches the realmlist for a particular attribute.
MODIFIES: ppMapping -- receives the given mapping.
TAKES: pvAttribute -- attribute value to search for pFunc -- function to use to find it
RETURNS: TRUE if the value could be found FALSE otherwise. LASTERROR: not set
LOGGING: none CREATED: Jan 10, 2000 LOCKING: none CALLED BY: anyone FREE WITH: n/a -- no resources are allocated **************************************************************--*/
BOOL SearchRealmFlagListByAttribute( IN PVOID pvAttribute, IN REALMLISTCOMPAREFUNCTION *pFunc, OUT PKERB_REALM_FLAG_MAPPING *ppMapping ) {
ULONG i; PKERB_REALM_FLAG_MAPPING pMapping = &KerbRealmFlagMappings[ 0 ];
for ( i = 0 ; i < RealmFlagCount ; i ++, pMapping++ ) {
if ( pFunc( pvAttribute, pMapping ) ) {
if ( ppMapping ) *ppMapping = pMapping; return TRUE;
} }
return FALSE;
}
/*++**************************************************************
NAME: LookupRealmFlagByName
given a name, maps it to a realm flag mapping structure
MODIFIES: ppMapping -- receives the entry pointer TAKES: RealmFlagName -- name for which to search
RETURNS: TRUE if the realmflag could be found. FALSE otherwise. LASTERROR:
LOGGING: CREATED: Jan 10, 2000 LOCKING: CALLED BY: anyone FREE WITH: n/a -- no resources are allocated **************************************************************--*/
BOOL LookupRealmFlagByName( IN LPWSTR RealmFlagName, OUT PKERB_REALM_FLAG_MAPPING *ppMapping ) {
return SearchRealmFlagListByAttribute( RealmFlagName, CompareFlagNames, ppMapping );
}
VOID PrintRealmFlags( IN ULONG RealmFlags ) {
ULONG i; ULONG ioFlags = RealmFlags;
if ( RealmFlags == 0 ) {
printf( " none" );
} else {
if ( !SearchRealmFlagListByAttribute( &ioFlags, PrintAndRemoveFlagsById, NULL ) ) { printf( " [unknown" );
if ( ioFlags != RealmFlags ) {
printf( ": 0x%x", ioFlags );
}
printf( "]" );
}
} }
NTSTATUS ListRealmFlags( LPWSTR * Ignored) {
ULONG RealmFlags = ~0;
printf( "\n" "Ksetup knows the following realm flags: \n" ); SearchRealmFlagListByAttribute( &RealmFlags, VerboselyPrintAndRemoveFlagsById, NULL ); printf( "\n" );
exit( 0 ); /* Jump out. */
return STATUS_SUCCESS;
}
NTSTATUS GetRealmFlags( IN LPWSTR RealmName, OUT PULONG pulRealmFlags ) {
HKEY hKey; NTSTATUS N = STATUS_UNSUCCESSFUL; DWORD dwErr, Type, Len = sizeof( *pulRealmFlags );
dwErr = OpenSubKey( &RealmName, &hKey );
if ( dwErr == ERROR_SUCCESS ) {
dwErr = RegQueryValueEx( hKey, KERB_DOMAIN_REALM_FLAGS_VALUE, NULL, // mbz
&Type, (LPBYTE) pulRealmFlags, &Len );
switch ( dwErr ) {
case ERROR_SUCCESS: N = STATUS_SUCCESS; break;
case ERROR_FILE_NOT_FOUND: case ERROR_PATH_NOT_FOUND:
/* 453545: if the realm flags aren't specified,
don't complain about it. */
N = STATUS_SUCCESS; *pulRealmFlags = 0; break;
default: printf( "Failed to query %ws for %ws: 0x%x\n", KERB_DOMAIN_REALM_FLAGS_VALUE, RealmName, dwErr ); }
RegCloseKey( hKey );
} // else error has already been printed.
return N; }
NTSTATUS SetRealmFlags( IN LPWSTR RealmName, IN ULONG ulRealmFlags ) {
HKEY hKey; NTSTATUS N = STATUS_UNSUCCESSFUL; DWORD dwErr, Len = sizeof( ulRealmFlags );
dwErr = OpenSubKey( &RealmName, &hKey );
if ( dwErr == ERROR_SUCCESS ) {
dwErr = RegSetValueEx( hKey, KERB_DOMAIN_REALM_FLAGS_VALUE, NULL, // mbz
REG_DWORD, (LPBYTE) &ulRealmFlags, Len ); switch ( dwErr ) {
case ERROR_SUCCESS:
DEBUGPRINT( DEBUG_REGISTRY, ( "Set Realm Flags for %ws to 0x%x\n", RealmName, ulRealmFlags ) ) ; N = STATUS_SUCCESS; break;
default: printf( "Failed to write %ws for %ws: 0x%x\n", KERB_DOMAIN_REALM_FLAGS_VALUE, RealmName, dwErr ); }
RegCloseKey( hKey );
} // else error has already been printed.
return N; }
NTSTATUS ResolveRealmFlags( IN LPWSTR *Params, IN OUT PULONG pulFlags ) {
ULONG id; LPWSTR Cursor, *pFlagCursor = Params; PKERB_REALM_FLAG_MAPPING pMap; NTSTATUS N = STATUS_SUCCESS;
do {
DEBUGPRINT( DEBUG_OPTIONS, ( "Checking realmflag \"%ws\"...\n", *pFlagCursor ) );
// first, try to convert to hex.
id = wcstoul( *pFlagCursor, &Cursor, 0 ); // use defaults
if ( *Cursor != '\0' ) {
if ( !LookupRealmFlagByName( *pFlagCursor, &pMap ) ) {
printf( "Unknown Realm Flag: \"%ws\"\n", *pFlagCursor );
N = STATUS_INVALID_PARAMETER; break;
} else {
id = pMap->Id;
}
} // otherwise, the work's already been done.
pFlagCursor++; *pulFlags |= id;
} while( *pFlagCursor != NULL );
return N;
}
NTSTATUS SetRealmFlags( IN LPWSTR *Params ) {
LPWSTR RealmName = Params[ 0 ]; ULONG RealmFlags = 0; NTSTATUS N = STATUS_SUCCESS; // 279621: this was uninitialized.
if( Params[1] != NULL ) { N = ResolveRealmFlags( Params+1, &RealmFlags );
if ( NT_SUCCESS( N ) ) { N = SetRealmFlags( RealmName, RealmFlags ); } } else // Clear all realm flags
{ SetRealmFlags( RealmName, 0 ); } return N;
}
NTSTATUS AddRealmFlags( IN LPWSTR *Params ) {
LPWSTR RealmName = Params[ 0 ]; ULONG RealmFlags = 0; NTSTATUS N;
N = GetRealmFlags( RealmName, &RealmFlags );
if ( NT_SUCCESS( N ) ) { N = ResolveRealmFlags( Params+1, &RealmFlags );
if ( NT_SUCCESS( N ) ) { N = SetRealmFlags( RealmName, RealmFlags );
} }
return N;
}
NTSTATUS DelRealmFlags( IN LPWSTR *Params ) {
LPWSTR RealmName = Params[ 0 ]; ULONG RealmFlags = 0; ULONG DeleteFlags = 0; NTSTATUS N;
N = GetRealmFlags( RealmName, &RealmFlags ); if ( NT_SUCCESS( N ) ) { N = ResolveRealmFlags( Params+1, &DeleteFlags );
if ( NT_SUCCESS( N ) ) { N = SetRealmFlags( RealmName, RealmFlags &~ DeleteFlags );
} }
return N;
}
|