#include #include #include #include #pragma hdrstop #pragma comment( lib, "advapi32.lib" ) #define gle GetLastError() int main( int argc, char *argv[] ); void err( const char *msg, NTSTATUS nts, bool isNtStatus = true ); void err( const char *msg, NTSTATUS nts, bool isNtStatus /* = true */ ) { DWORD e; if ( nts == 0 ) return; if ( isNtStatus ) { e = LsaNtStatusToWinError( nts ); printf( "%s: ntstatus %lu [%lXh], gle %lu\n", msg, nts, nts, e ); } else { printf( "%s: gle %lu\n", msg, nts ); } exit( 1 ); } const char *SidToText( PSID psid ) { // S-rev- + SIA + subauthlen*maxsubauth + terminator static char buf[15 + 12 + 12*SID_MAX_SUB_AUTHORITIES + 1]; char *p = &buf[0]; PSID_IDENTIFIER_AUTHORITY psia; DWORD numSubAuths, i; // Validate the binary SID. if ( ! IsValidSid( psid ) ) return FALSE; psia = GetSidIdentifierAuthority( psid ); p = buf; p += _snprintf( p, &buf[sizeof buf] - p, "S-%lu-", 0x0f & *( (byte *) psid ) ); if ( ( psia->Value[0] != 0 ) || ( psia->Value[1] != 0 ) ) p += _snprintf( p, &buf[sizeof buf] - p, "0x%02hx%02hx%02hx%02hx%02hx%02hx", (USHORT) psia->Value[0], (USHORT) psia->Value[1], (USHORT) psia->Value[2], (USHORT) psia->Value[3], (USHORT) psia->Value[4], (USHORT) psia->Value[5] ); else p += _snprintf( p, &buf[sizeof buf] - p, "%lu", (ULONG) ( psia->Value[5] ) + (ULONG) ( psia->Value[4] << 8 ) + (ULONG) ( psia->Value[3] << 16 ) + (ULONG) ( psia->Value[2] << 24 ) ); // Add SID subauthorities to the string. numSubAuths = *GetSidSubAuthorityCount( psid ); for ( i = 0; i < numSubAuths; ++ i ) p += _snprintf( p, &buf[sizeof buf] - p, "-%lu", *GetSidSubAuthority( psid, i ) ); return buf; } int main( int argc, char *argv[] ) { if ( argc != 2 ) { puts( "Usage: lsa_lqip \\\\server" ); return 1; } // open the policy object on the target computer static SECURITY_QUALITY_OF_SERVICE sqos = { sizeof SECURITY_QUALITY_OF_SERVICE, SecurityImpersonation, SECURITY_DYNAMIC_TRACKING, FALSE }; static LSA_OBJECT_ATTRIBUTES lsaOA = { sizeof LSA_OBJECT_ATTRIBUTES, NULL, NULL, 0, NULL, &sqos }; NTSTATUS nts; LSA_HANDLE polHandle; LSA_UNICODE_STRING sysname; sysname.Length = strlen( argv[1] ) * 2; sysname.MaximumLength = sysname.Length + 2; sysname.Buffer = (wchar_t *) malloc( sysname.MaximumLength ); mbstowcs( sysname.Buffer, argv[1], strlen( argv[1] ) ); POLICY_PRIMARY_DOMAIN_INFO *pd = 0; POLICY_ACCOUNT_DOMAIN_INFO *ad = 0; nts = LsaOpenPolicy( &sysname, &lsaOA, GENERIC_READ | GENERIC_EXECUTE, &polHandle ); err( "LOP()", nts ); nts = LsaQueryInformationPolicy( polHandle, PolicyPrimaryDomainInformation, (void **) &pd ); err( "LQIP(primary)", nts ); printf( "Primary domain name: %.*S\n", pd->Name.Length, pd->Name.Buffer ); printf( "Primary domain SID: %s\n\n", pd->Sid == 0? "*null*": SidToText( pd->Sid ) ); nts = LsaQueryInformationPolicy( polHandle, PolicyAccountDomainInformation, (void **) &ad ); err( "LQIP(account)", nts ); printf( "Account domain name: %.*S\n", ad->DomainName.Length, ad->DomainName.Buffer ); printf( "Account domain SID: %s\n\n", ad->DomainSid == 0? "*null*": SidToText( ad->DomainSid ) ); if ( pd->Sid == 0 ) printf( "%s is a member of workgroup %.*S\n", argv[1], pd->Name.Length, pd->Name.Buffer ); else { if ( EqualSid( ad->DomainSid, pd->Sid ) ) printf( "%s is a domain controller for domain %.*S\n", argv[1], pd->Name.Length, pd->Name.Buffer ); else printf( "%s is a member of domain %.*S\n", argv[1], pd->Name.Length, pd->Name.Buffer ); } LsaClose( polHandle ); free( sysname.Buffer ); return 0; }