Working with Security Identifiers in win32

The win32 GetUserName() function fetches the name of the user associated with the current thread. The GetUserName() function takes two arguments, a char buffer to hold the username, and a pointer to a DWORD value indicating the size of the buffer. The function returns a Boolean value indicating whether or not it succeeded in acquiring the username.

#include <Windows.h>
#include <stdlib.h>
#include <stdio.h>

int _tmain(int argc, _TCHAR* argv[])
{
	TCHAR tchBuffer[256];
	//_tcslen used in place of strlen
	DWORD dwBufferSize = _tcslen(tchBuffer);

	if(GetUserName(tchBuffer, &dwBufferSize)){
		printf("Username acquired.\n");
	} else {
		printf("Failed to acquire the username.\n");
		exit(EXIT_FAILURE);
	}

	_tprintf(_T("The username is: %s\n"), tchBuffer);

	return 0;
}

The CreateWellKnownSid() function creates a SID for the predefined aliases specified by the WELL_KNOWN_SID_TYPE enumeration. The CreateWellKnownSid() function has four parameters. The first parameter is a value from the WELL_KNOWN_SID_TYPE enumeration. The second parameter is a pointer to a SID to specify what domain to create the SID in; we will put NULL here, to default to the local machine. The third parameter is a pointer to a SID type that will store the new SID, which is a binary value. The fourth value is a pointer to a DWORD value that specifies the amount of storage available in the SID pointed to by the third parameter.

#include <Windows.h>
#include <stdlib.h>
#include <stdio.h>

int _tmain(int argc, _TCHAR* argv[])
{
	BOOL boolReturnVal;
	BYTE bTheSID[SECURITY_MAX_SID_SIZE];
	DWORD dwSIDSize = SECURITY_MAX_SID_SIZE;

	boolReturnVal = CreateWellKnownSid(WinLocalSystemSid, NULL, bTheSID, &dwSIDSize);

	if(boolReturnVal==FALSE){
		printf("Could not create well-known SID.\n");
		printf("Error %d.\n", GetLastError());
		exit(EXIT_FAILURE);
	} else {
		printf("Well-known SID created.\n");
	}

	return 0;
}

The constant SECURITY_MAX_SID_SIZE defines the maximum size of a SID.

Since the SID is binary data, we need to use a function call to convert it into displayable data. The ConvertSidToString() function converts a security identifier to string format.

#include <Windows.h>
#include <stdlib.h>
#include <stdio.h>
#include <sddl.h>

int _tmain(int argc, _TCHAR* argv[])
{
	BOOL boolRVal;
	BYTE bSID[SECURITY_MAX_SID_SIZE];
	LPWSTR pSid = _T("");
	DWORD dwSize = SECURITY_MAX_SID_SIZE;

	boolRVal = CreateWellKnownSid(
		WinLocalSystemSid,
		NULL, //use this system
		bSID,
		&dwSize
		);

	if(!boolRVal){
		printf("Error creating SID: %d\n", GetLastError());
		exit(EXIT_FAILURE);
	}

	boolRVal = ConvertSidToStringSid(bSID, &pSid);

	if(boolRVal){
		printf("The SID is %ls.\n", pSid);
	}

	return 0;
}

Please note the inclusion of the sddl.h header file.

The LookupAccountName() function gets us the security identifier for the account name and system name we provide the function as arguments. A security identifier, usually called a SID, is a pseudo-kernel object that describes a user account.

The LookupAccountName() function takes a whopping seven arguments. The first argument provided to LookupAccountName() is a null-terminated character string that indicates the name of the system; if we enter NULL here, the function uses the system name of the current system. The second argument is also a null-terminated string indicating the user account name.

The third and fourth arguments define a buffer that will store the SID returned from the function. The third argument is the buffer itself, and the fourth argument is the length of that buffer.

The fifth and sixth arguments define a char buffer that will store the domain name.

The seventh and final argument is the type of sid, indicated by the enumerated type SID_NAME_USE.

#include <Windows.h>
#include <stdlib.h>
#include <sddl.h>
#include <stdio.h>

int _tmain(int argc, _TCHAR* argv[])
{
	BYTE bSID[SECURITY_MAX_SID_SIZE];
	BOOL bRVal;
	DWORD dwSidSize = SECURITY_MAX_SID_SIZE;
	
	LPTSTR szSID = NULL;

	TCHAR szUserName[256], szDomainName[256];
	DWORD dwUserSize = _tcslen(szUserName);
	DWORD dwDomainSize = _tcslen(szDomainName);
	
	SID_NAME_USE snu = SidTypeInvalid;

	//find the current user's name
	if(!(GetUserName(szUserName, &dwUserSize))){
		printf("Error getting username.\n");
		exit(EXIT_FAILURE);
	} else {
		printf("Username acquired.\n");
	}

	bRVal = LookupAccountName(
		NULL, //use this system
		szUserName, //the user to look up
		bSID, //the returned SID
		&dwSidSize, //the size of the SID returned
		szDomainName, //the returned domain name
		&dwDomainSize, //the size of the domain name
		&snu //the type of sid
		);

	bRVal = ConvertSidToStringSid(bSID, &szSID);

	//output values
	_tprintf(_T("SID %ls for %s in %s domain.\n"), szSID, szUserName, szDomainName);

	//clean up
	LocalFree(szSID);
	szSID = NULL;

	return 0;
}


The SID we get from the code above is valuable, since it uniquely identifies the account running the process.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s