#include <windows.h>
#include <stdio.h>
#include <lm.h>
#pragma hdrstop



#pragma comment( lib, "netapi32.lib" )



// My thanks to Jerry Coffin (jcoffin@taeus.com)
// for this much simpler method.
bool jerry_coffin_method()
{
	bool result;
	DWORD rc;
	wchar_t user_name[256];
	USER_INFO_1 *info;
	DWORD size = sizeof( user_name );

	GetUserNameW( user_name, &size);

	rc = NetUserGetInfo( NULL, user_name, 1, (byte **) &info );
	if ( rc != NERR_Success )
		return false;

	result = info->usri1_priv == USER_PRIV_ADMIN;

	NetApiBufferFree( info );
	return result;
}



bool look_at_token_method()
{
	int found;
	DWORD i, l;
	HANDLE hTok;
	PSID pAdminSid;
	SID_IDENTIFIER_AUTHORITY ntAuth = SECURITY_NT_AUTHORITY;

	byte rawGroupList[4096];
	TOKEN_GROUPS& groupList = *( (TOKEN_GROUPS *) rawGroupList );

	if ( ! OpenThreadToken( GetCurrentThread(), TOKEN_QUERY, FALSE, &hTok ) )
	{
		printf( "Cannot open thread token, trying process token [%lu].\n",
			GetLastError() );
		if ( ! OpenProcessToken( GetCurrentProcess(), TOKEN_QUERY, &hTok ) )
		{
			printf( "Cannot open process token, quitting [%lu].\n",
				GetLastError() );
			return 1;
		}
	}

	// normally, I should get the size of the group list first, but ...
	l = sizeof rawGroupList;
	if ( ! GetTokenInformation( hTok, TokenGroups, &groupList, l, &l ) )
	{
		printf( "Cannot get group list from token [%lu].\n",
			GetLastError() );
		return 1;
	}

	// here, we cobble up a SID for the Administrators group, to compare to.
	if ( ! AllocateAndInitializeSid( &ntAuth, 2, SECURITY_BUILTIN_DOMAIN_RID,
		DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &pAdminSid ) )
	{
		printf( "Cannot create SID for Administrators [%lu].\n",
			GetLastError() );
		return 1;
	}

	// now, loop through groups in token and compare
	found = 0;
	for ( i = 0; i < groupList.GroupCount; ++ i )
	{
		if ( EqualSid( pAdminSid, groupList.Groups[i].Sid ) )
		{
			found = 1;
			break;
		}
	}

	FreeSid( pAdminSid );
	CloseHandle( hTok );
	return !!found;
}

int main()
{
	bool j, l;

	j = jerry_coffin_method();
	l = look_at_token_method();

	printf( "NetUserGetInfo(): The current user is %san Administrator.\n",
		j? "": "not " );
	printf( "Process token: The current user is %sa member of the Administrators group.\n",
		l? "": "not " );

	return 0;
}


