Re: Get local built-in administrator's name

Tech-Archive recommends: Repair Windows Errors & Optimize Windows Performance

From: David Lowndes (davidl_at_example.invalid)
Date: 02/16/04


Date: Mon, 16 Feb 2004 10:14:40 +0000


>I think you could do it by using GetUserName & LookupAccountName to
>get the user's SID, and then compare with WinBuiltinAdministratorsSid
>using IsWellKnownSid.

Use WinAccountAdministratorSid instead of WinBuiltinAdministratorsSid.

IsWellKnownSid is XP (and later) only, so here's an example that I
think should work and illustrates XP and 2000 methods (the 2000 code
also works on XP):

#include <windows.h>

#define DIM(x) (sizeof(x)/sizeof(x[0]))

#if WINVER < 0x0501
#include <lm.h>
#pragma comment( lib, "Netapi32.lib" )

BOOL GetSidFromRid( DWORD Rid, PSID & pSid )
{
    PUSER_MODALS_INFO_2 umi2;
    NET_API_STATUS nas;

    UCHAR SubAuthorityCount;
    BOOL bSuccess = FALSE; // assume failure

    // get the account domain Sid on the target machine
    // note: if you were looking up multiple sids based on the same
    // account domain, only need to call this once.

    nas = NetUserModalsGet(NULL, 2, (LPBYTE *)&umi2);

    if(nas != NERR_Success)
        {
        SetLastError(nas);
        return FALSE;
    }

    SubAuthorityCount =
*GetSidSubAuthorityCount(umi2->usrmod2_domain_id);

    //
    // allocate storage for new Sid. account domain Sid + account Rid
    //

    pSid = new BYTE [ GetSidLengthRequired( (UCHAR)(SubAuthorityCount
+ 1) ) ];

    if(pSid != NULL)
        {

        if (InitializeSid(
                pSid,
                GetSidIdentifierAuthority(umi2->usrmod2_domain_id),
                (BYTE)(SubAuthorityCount+1)
                ))
                {

            DWORD SubAuthIndex = 0;

            // copy existing subauthorities from account domain Sid
into new Sid
            for( ; SubAuthIndex < SubAuthorityCount ; SubAuthIndex++)
                        {
                *GetSidSubAuthority(pSid, SubAuthIndex) =
                *GetSidSubAuthority(umi2->usrmod2_domain_id,
                                    SubAuthIndex);
            }

            // append Rid to new Sid
            *GetSidSubAuthority(pSid, SubAuthorityCount) = Rid;

                        bSuccess = TRUE;

        }
    }

    NetApiBufferFree(umi2);

    return bSuccess;
}
#endif

int _tmain(int argc, _TCHAR* argv[])
{
        TCHAR szUser[100];

        if ( argc < 2 )
        {
                DWORD UserNameSize = DIM( szUser );

                GetUserName( szUser, &UserNameSize );
        }
        else
        {
                lstrcpyn( szUser, argv[1], DIM( szUser ) );
        }

        DWORD SidSize = 0;
        DWORD DomNameSize = 0;
        SID_NAME_USE snu;

        LookupAccountName( NULL, szUser, NULL, &SidSize, NULL,
&DomNameSize, &snu );
        PSID pSid = new BYTE [SidSize];
        LPTSTR pDomName = new char [DomNameSize];
        if ( LookupAccountName( NULL, szUser, pSid, &SidSize, pDomName,
&DomNameSize, &snu ) )
        {
#if WINVER >= 0x0501
                // XP and above method
                if ( IsWellKnownSid( pSid, WinBuiltinAdministratorsSid ) )
                {
                        printf( "It's me\n" );
                }
                else
                {
                        printf( "Not me\n" );
                }

                if ( IsWellKnownSid( pSid, WinAccountAdministratorSid ) )
                {
                        printf( "It's me\n" );
                }
                else
                {
                        printf( "Not me\n" );
                }
#else
                // Construct SID for Well-known user "Administrator"
                PSID pSidA;
                if ( GetSidFromRid( DOMAIN_USER_RID_ADMIN, pSidA ) )
                {
                        if ( EqualSid( pSid, pSidA ) )
                        {
                                printf( "It's me\n" );
                        }
                        else
                        {
                                printf( "Not me\n" );
                        }

                        delete [] pSidA;
                }
#endif

        }

        delete [] pSid;
        delete [] pDomName;

        return 0;
}

Dave

--
MVP VC++ FAQ: http://www.mvps.org/vcfaq


Relevant Pages

  • Re: Get local built-in administrators name
    ... Dave wrote, ... >Use WinAccountAdministratorSid instead of WinBuiltinAdministratorsSid. ... >IsWellKnownSid is XP only, so here's an example that I ...
    (microsoft.public.vc.language)
  • EqualSid
    ... How do I compare a given Sid to the Administartos sid or the System use ... I cannot use IsWellKnownSid() for my program runs on Windows2000. ...
    (microsoft.public.platformsdk.security)