windows-nt/Source/XPSP1/NT/ds/security/tools/ksetup/realmflags.cxx

619 lines
14 KiB
C++
Raw Normal View History

2020-09-26 03:20:57 -05:00
/*++
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;
}