//
// $Id: AccessTokenProbe.cpp,v 1.6 2007/01/09 17:43:02 bakerj Exp $
//
//****************************************************************************************//
// Copyright (c) 2002-2007, The MITRE Corporation
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification, are
// permitted provided that the following conditions are met:
//
//     * Redistributions of source code must retain the above copyright notice, this list
//       of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above copyright notice, this 
//       list of conditions and the following disclaimer in the documentation and/or other
//       materials provided with the distribution.
//     * Neither the name of The MITRE Corporation nor the names of its contributors may be
//       used to endorse or promote products derived from this software without specific 
//       prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 
// SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
// OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
// TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
//****************************************************************************************//

#include "AccessTokenProbe.h"

//****************************************************************************************//
//								AccessTokenProbe Class										  //	
//****************************************************************************************//
AccessTokenProbe* AccessTokenProbe::instance = NULL;

AccessTokenProbe::AccessTokenProbe() : AbsProbe() {
	// -----------------------------------------------------------------------
	//	Abstract
	//
	//	Do nothing for now
	//
	// -----------------------------------------------------------------------
}

AccessTokenProbe::~AccessTokenProbe() {
	// -----------------------------------------------------------------------
	//
	//  ABSTRACT
	//
	//  Do nothing for now
	//
	// -----------------------------------------------------------------------
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  Public Members  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
AbsProbe* AccessTokenProbe::Instance() {
	// -----------------------------------------------------------------------
	//
	//  ABSTRACT
	//
	//	Ensure that the AccessTokenProbe is a singleton.
	// -----------------------------------------------------------------------

	// Use lazy initialization
	if(instance == NULL) 
		instance = new AccessTokenProbe();

	return instance;	
}

ItemVector* AccessTokenProbe::CollectItems(Object *object) {
	// -----------------------------------------------------------------------
	//
	//  ABSTRACT
	//
	//  Run the access token probe. Return a vector of Items
	//
	// -----------------------------------------------------------------------
	ItemVector *collectedItems = new ItemVector();

	// get the security_principle from the provided object
	ObjectEntity* securityPrinciple = object->GetElementByName("security_principle");

	// check datatypes - only allow string
	if(securityPrinciple->GetDatatype() != OvalEnum::STRING_TYPE) {
		throw ProbeException("Error: invalid data type specified on security_principle. Found: " + OvalEnum::DatatypeToString(securityPrinciple->GetDatatype()));
	}
	
	// check operation - only allow  equals, not equals and pattern match
	if(securityPrinciple->GetOperation() != OvalEnum::EQUALS_OPERATION && securityPrinciple->GetOperation() != OvalEnum::PATTERN_MATCH_OPERATION && securityPrinciple->GetOperation() != OvalEnum::NOT_EQUAL_OPERATION) {
		throw ProbeException("Error: invalid operation specified on security_principle. Found: securityPrinciple " + OvalEnum::OperationToString(securityPrinciple->GetOperation()));
	}
	
	// TODO - determine how to support behaviors.
	if(object->GetBehaviors()->size() != 0) {
		throw ProbeException("Error: (AccessTokenProbe) Behaviors are not supported."); 
	}

	// get the data
	if(securityPrinciple->GetVarRef() == NULL) {
		if(securityPrinciple->GetOperation() == OvalEnum::EQUALS_OPERATION) {
			Item* item = this->GetAccountInformation(securityPrinciple->GetValue());
			if(item != NULL)
				collectedItems->push_back(item);
		} else {

			bool isRegex = false;
			if(securityPrinciple->GetOperation() == OvalEnum::PATTERN_MATCH_OPERATION)
				isRegex = true;

			// Get all trustee_names on the system...
			StringVector* allTrusteeNames = WindowsCommon::GetAllTrusteeNames();
			
			// Get the set of trustee names that match the ItemEntity.
			StringVector::iterator iterator;
			for(iterator = allTrusteeNames->begin(); iterator != allTrusteeNames->end(); iterator++) {
				string curr = (*iterator);
				if(this->IsMatch(securityPrinciple->GetValue(), (*iterator), isRegex)) {
					Item* item = this->GetAccountInformation((*iterator));
					if(item != NULL)
						collectedItems->push_back(item);
				}
			}
		}

	} else {
		// Get all trustee_names on the system...
		StringVector* allTrusteeNames = WindowsCommon::GetAllTrusteeNames();

		// loop through all trustee names on the system
		// only keep those that match operation and value and var check
		StringVector::iterator it;
		ItemEntity* tmp = this->CreateItemEntity(securityPrinciple);
		for(it = allTrusteeNames->begin(); it != allTrusteeNames->end(); it++) {
			tmp->SetValue((*it));
			if(securityPrinciple->Analyze(tmp) == OvalEnum::TRUE_RESULT) {
				Item* item = this->GetAccountInformation((*it));
					if(item != NULL)
						collectedItems->push_back(item);
			}
		}
	}
	

	return collectedItems;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  Private Members  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
Item* AccessTokenProbe::CreateItem() {
	// -----------------------------------------------------------------------
	//
	//  ABSTRACT
	//
	//  Return a new Item created for storing registry information
	//
	// -----------------------------------------------------------------------

	Item* item = new Item(0, 
						"http://oval.mitre.org/XMLSchema/oval-system-characteristics-5#windows", 
						"win-sc", 
						"http://oval.mitre.org/XMLSchema/oval-system-characteristics-5#windows windows-system-characteristics-schema.xsd", 
						OvalEnum::ERROR_STATUS, 
						"accesstoken_item");

	return item;
}


Item* AccessTokenProbe::GetAccountInformation(string accountNameIn) {
	//------------------------------------------------------------------------------------//
	//
	//  ABSTRACT
	//
	//  Given an account name, gather information about it and insert this information
	//  into the database.
	//
	//------------------------------------------------------------------------------------//

	NTSTATUS nts;

	// Get a handle to the policy object.
	LSA_HANDLE polHandle;
	LSA_OBJECT_ATTRIBUTES ObjectAttributes;
	ZeroMemory(&ObjectAttributes, sizeof(ObjectAttributes));

	nts = LsaOpenPolicy(NULL, &ObjectAttributes, POLICY_LOOKUP_NAMES, &polHandle);
	if (nts != ERROR_SUCCESS) {
		LsaClose(polHandle);
		throw ProbeException("Error: (AccessTokenProbe) Unable to open a handle to the Policy object.");		
	}

	// Get the SID.
	PSID psid = WindowsCommon::GetSIDForTrusteeName(accountNameIn);

	// Enumerate Access Rights
	PLSA_UNICODE_STRING userRights = NULL;
	ULONG CountOfRights = 0;

	nts = LsaEnumerateAccountRights(polHandle, psid, &userRights, &CountOfRights);
	if (nts != ERROR_SUCCESS) {
		CountOfRights = 0;
	}

	// Create the item
	Item* item = this->CreateItem();
	item->SetStatus(OvalEnum::EXISTS_STATUS);
	item->AppendElement(new ItemEntity("security_principle", accountNameIn, OvalEnum::STRING_TYPE, true, OvalEnum::EXISTS_STATUS));

	// init all the rights
	ItemEntity* seassignprimarytokenprivilege = new ItemEntity("seassignprimarytokenprivilege", "0", OvalEnum::BOOLEAN_TYPE, false, OvalEnum::EXISTS_STATUS);
	item->AppendElement(seassignprimarytokenprivilege);
	ItemEntity* seauditprivilege = new ItemEntity("seauditprivilege", "0", OvalEnum::BOOLEAN_TYPE, false, OvalEnum::EXISTS_STATUS);
	item->AppendElement(seauditprivilege);
	ItemEntity* sebackupprivilege = new ItemEntity("sebackupprivilege", "0", OvalEnum::BOOLEAN_TYPE, false, OvalEnum::EXISTS_STATUS);
	item->AppendElement(sebackupprivilege);
	ItemEntity* sechangenotifyprivilege = new ItemEntity("sechangenotifyprivilege", "0", OvalEnum::BOOLEAN_TYPE, false, OvalEnum::EXISTS_STATUS);
	item->AppendElement(sechangenotifyprivilege);
	ItemEntity* secreateglobalprivilege = new ItemEntity("secreateglobalprivilege", "0", OvalEnum::BOOLEAN_TYPE, false, OvalEnum::EXISTS_STATUS);
	item->AppendElement(secreateglobalprivilege);
	ItemEntity* secreatepagefileprivilege = new ItemEntity("secreatepagefileprivilege", "0", OvalEnum::BOOLEAN_TYPE, false, OvalEnum::EXISTS_STATUS);
	item->AppendElement(secreatepagefileprivilege);
	ItemEntity* secreatepermanentprivilege = new ItemEntity("secreatepermanentprivilege", "0", OvalEnum::BOOLEAN_TYPE, false, OvalEnum::EXISTS_STATUS);
	item->AppendElement(secreatepermanentprivilege);
	ItemEntity* secreatetokenprivilege = new ItemEntity("secreatetokenprivilege", "0", OvalEnum::BOOLEAN_TYPE, false, OvalEnum::EXISTS_STATUS);
	item->AppendElement(secreatetokenprivilege);
	ItemEntity* sedebugprivilege = new ItemEntity("sedebugprivilege", "0", OvalEnum::BOOLEAN_TYPE, false, OvalEnum::EXISTS_STATUS);
	item->AppendElement(sedebugprivilege);
	ItemEntity* seenabledelegationprivilege = new ItemEntity("seenabledelegationprivilege", "0", OvalEnum::BOOLEAN_TYPE, false, OvalEnum::EXISTS_STATUS);
	item->AppendElement(seenabledelegationprivilege);
	ItemEntity* seimpersonateprivilege = new ItemEntity("seimpersonateprivilege", "0", OvalEnum::BOOLEAN_TYPE, false, OvalEnum::EXISTS_STATUS);
	item->AppendElement(seimpersonateprivilege);
	ItemEntity* seincreasebasepriorityprivilege = new ItemEntity("seincreasebasepriorityprivilege", "0", OvalEnum::BOOLEAN_TYPE, false, OvalEnum::EXISTS_STATUS);
	item->AppendElement(seincreasebasepriorityprivilege);
	ItemEntity* seincreasequotaprivilege = new ItemEntity("seincreasequotaprivilege", "0", OvalEnum::BOOLEAN_TYPE, false, OvalEnum::EXISTS_STATUS);
	item->AppendElement(seincreasequotaprivilege);
	ItemEntity* seloaddriverprivilege = new ItemEntity("seloaddriverprivilege", "0", OvalEnum::BOOLEAN_TYPE, false, OvalEnum::EXISTS_STATUS);
	item->AppendElement(seloaddriverprivilege);
	ItemEntity* selockmemoryprivilege = new ItemEntity("selockmemoryprivilege", "0", OvalEnum::BOOLEAN_TYPE, false, OvalEnum::EXISTS_STATUS);
	item->AppendElement(selockmemoryprivilege);
	ItemEntity* semachineaccountprivilege = new ItemEntity("semachineaccountprivilege", "0", OvalEnum::BOOLEAN_TYPE, false, OvalEnum::EXISTS_STATUS);
	item->AppendElement(semachineaccountprivilege);
	ItemEntity* semanagevolumeprivilege = new ItemEntity("semanagevolumeprivilege", "0", OvalEnum::BOOLEAN_TYPE, false, OvalEnum::EXISTS_STATUS);
	item->AppendElement(semanagevolumeprivilege);
	ItemEntity* seprofilesingleprocessprivilege = new ItemEntity("seprofilesingleprocessprivilege", "0", OvalEnum::BOOLEAN_TYPE, false, OvalEnum::EXISTS_STATUS);
	item->AppendElement(seprofilesingleprocessprivilege);
	ItemEntity* seremoteshutdownprivilege = new ItemEntity("seremoteshutdownprivilege", "0", OvalEnum::BOOLEAN_TYPE, false, OvalEnum::EXISTS_STATUS);
	item->AppendElement(seremoteshutdownprivilege);
	ItemEntity* serestoreprivilege = new ItemEntity("serestoreprivilege", "0", OvalEnum::BOOLEAN_TYPE, false, OvalEnum::EXISTS_STATUS);
	item->AppendElement(serestoreprivilege);
	ItemEntity* sesecurityprivilege = new ItemEntity("sesecurityprivilege", "0", OvalEnum::BOOLEAN_TYPE, false, OvalEnum::EXISTS_STATUS);
	item->AppendElement(sesecurityprivilege);
	ItemEntity* seshutdownprivilege = new ItemEntity("seshutdownprivilege", "0", OvalEnum::BOOLEAN_TYPE, false, OvalEnum::EXISTS_STATUS);
	item->AppendElement(seshutdownprivilege);
	ItemEntity* sesyncagentprivilege = new ItemEntity("sesyncagentprivilege", "0", OvalEnum::BOOLEAN_TYPE, false, OvalEnum::EXISTS_STATUS);
	item->AppendElement(sesyncagentprivilege);
	ItemEntity* sesystemenvironmentprivilege = new ItemEntity("sesystemenvironmentprivilege", "0", OvalEnum::BOOLEAN_TYPE, false, OvalEnum::EXISTS_STATUS);
	item->AppendElement(sesystemenvironmentprivilege);
	ItemEntity* sesystemprofileprivilege = new ItemEntity("sesystemprofileprivilege", "0", OvalEnum::BOOLEAN_TYPE, false, OvalEnum::EXISTS_STATUS);
	item->AppendElement(sesystemprofileprivilege);
	ItemEntity* sesystemtimeprivilege = new ItemEntity("sesystemtimeprivilege", "0", OvalEnum::BOOLEAN_TYPE, false, OvalEnum::EXISTS_STATUS);
	item->AppendElement(sesystemtimeprivilege);
	ItemEntity* setakeownershipprivilege = new ItemEntity("setakeownershipprivilege", "0", OvalEnum::BOOLEAN_TYPE, false, OvalEnum::EXISTS_STATUS);
	item->AppendElement(setakeownershipprivilege);
	ItemEntity* setcbprivilege = new ItemEntity("setcbprivilege", "0", OvalEnum::BOOLEAN_TYPE, false, OvalEnum::EXISTS_STATUS);
	item->AppendElement(setcbprivilege);
	ItemEntity* seundockprivilege = new ItemEntity("seundockprivilege", "0", OvalEnum::BOOLEAN_TYPE, false, OvalEnum::EXISTS_STATUS);
	item->AppendElement(seundockprivilege);
	ItemEntity* seunsolicitedinputprivilege = new ItemEntity("seunsolicitedinputprivilege", "0", OvalEnum::BOOLEAN_TYPE, false, OvalEnum::EXISTS_STATUS);
	item->AppendElement(seunsolicitedinputprivilege);
	ItemEntity* sebatchlogonright = new ItemEntity("sebatchlogonright", "0", OvalEnum::BOOLEAN_TYPE, false, OvalEnum::EXISTS_STATUS);
	item->AppendElement(sebatchlogonright);
	ItemEntity* seinteractivelogonright = new ItemEntity("seinteractivelogonright", "0", OvalEnum::BOOLEAN_TYPE, false, OvalEnum::EXISTS_STATUS);
	item->AppendElement(seinteractivelogonright);
	ItemEntity* senetworklogonright = new ItemEntity("senetworklogonright", "0", OvalEnum::BOOLEAN_TYPE, false, OvalEnum::EXISTS_STATUS);
	item->AppendElement(senetworklogonright);
	ItemEntity* seremoteinteractivelogonright = new ItemEntity("seremoteinteractivelogonright", "0", OvalEnum::BOOLEAN_TYPE, false, OvalEnum::EXISTS_STATUS);
	item->AppendElement(seremoteinteractivelogonright);
	ItemEntity* seservicelogonright = new ItemEntity("seservicelogonright", "0", OvalEnum::BOOLEAN_TYPE, false, OvalEnum::EXISTS_STATUS);
	item->AppendElement(seservicelogonright);
	ItemEntity* sedenybatchLogonright = new ItemEntity("sedenybatchLogonright", "0", OvalEnum::BOOLEAN_TYPE, false, OvalEnum::EXISTS_STATUS);
	item->AppendElement(sedenybatchLogonright);
	ItemEntity* sedenyinteractivelogonright = new ItemEntity("sedenyinteractivelogonright", "0", OvalEnum::BOOLEAN_TYPE, false, OvalEnum::EXISTS_STATUS);
	item->AppendElement(sedenyinteractivelogonright);
	ItemEntity* sedenynetworklogonright = new ItemEntity("sedenynetworklogonright", "0", OvalEnum::BOOLEAN_TYPE, false, OvalEnum::EXISTS_STATUS);
	item->AppendElement(sedenynetworklogonright);
	ItemEntity* sedenyremoteInteractivelogonright = new ItemEntity("sedenyremoteInteractivelogonright", "0", OvalEnum::BOOLEAN_TYPE, false, OvalEnum::EXISTS_STATUS);
	item->AppendElement(sedenyremoteInteractivelogonright);
	ItemEntity* sedenyservicelogonright = new ItemEntity("sedenyservicelogonright", "0", OvalEnum::BOOLEAN_TYPE, false, OvalEnum::EXISTS_STATUS);
	item->AppendElement(sedenyservicelogonright);

	// Alter the access mask to show the correct rights.
	char tmpPrivBuf[128];
	for (ULONG i=0; i<CountOfRights; i++) {
		ZeroMemory(tmpPrivBuf, 128);

		WideCharToMultiByte(CP_ACP,							// code page
							0,								// performance and mapping flags
							userRights[i].Buffer,			// wide-character string
							wcslen(userRights[i].Buffer),	// number of chars in string
							tmpPrivBuf,						// buffer for new string
							128,							// size of buffer
							NULL,							// default for unmappable chars
							NULL);							// set when default char used

		if (_strnicmp(tmpPrivBuf, "SeAssignPrimaryTokenPrivilege", 29) == 0)
			seassignprimarytokenprivilege->SetValue("1");
		else if (_strnicmp(tmpPrivBuf, "SeAuditPrivilege", 16) == 0)
			seauditprivilege->SetValue("1");
		else if (_strnicmp(tmpPrivBuf, "SeBackupPrivilege", 17) == 0)
			sebackupprivilege->SetValue("1");
		else if (_strnicmp(tmpPrivBuf, "SeChangeNotifyPrivilege", 23) == 0)
			sechangenotifyprivilege->SetValue("1");
		else if (_strnicmp(tmpPrivBuf, "SeCreateGlobalPrivilege", 23) == 0)
			secreateglobalprivilege->SetValue("1");
		else if (_strnicmp(tmpPrivBuf, "SeCreatePagefilePrivilege", 25) == 0)
			secreatepagefileprivilege->SetValue("1");
		else if (_strnicmp(tmpPrivBuf, "SeCreatePermanentPrivilege", 26) == 0)
			secreatepermanentprivilege->SetValue("1");
		else if (_strnicmp(tmpPrivBuf, "SeCreateTokenPrivilege", 22) == 0)
			secreatetokenprivilege->SetValue("1");
		else if (_strnicmp(tmpPrivBuf, "SeDebugPrivilege", 16) == 0)
			sedebugprivilege->SetValue("1");
		else if (_strnicmp(tmpPrivBuf, "SeEnableDelegationPrivilege", 27) == 0)
			seenabledelegationprivilege->SetValue("1");
		else if (_strnicmp(tmpPrivBuf, "SeImpersonatePrivilege", 22) == 0)
			seimpersonateprivilege->SetValue("1");
		else if (_strnicmp(tmpPrivBuf, "SeIncreaseBasePriorityPrivilege", 31) == 0)
			seincreasebasepriorityprivilege->SetValue("1");
		else if (_strnicmp(tmpPrivBuf, "SeIncreaseQuotaPrivilege", 24) == 0)
			seincreasequotaprivilege->SetValue("1");
		else if (_strnicmp(tmpPrivBuf, "SeLoadDriverPrivilege", 21) == 0)
			seloaddriverprivilege->SetValue("1");
		else if (_strnicmp(tmpPrivBuf, "SeLockMemoryPrivilege", 21) == 0)
			selockmemoryprivilege->SetValue("1");
		else if (_strnicmp(tmpPrivBuf, "SeMachineAccountPrivilege", 25) == 0)
			semachineaccountprivilege->SetValue("1");
		else if (_strnicmp(tmpPrivBuf, "SeManageVolumePrivilege", 23) == 0)
			semanagevolumeprivilege->SetValue("1");
		else if (_strnicmp(tmpPrivBuf, "SeProfileSingleProcessPrivilege", 31) == 0)
			seprofilesingleprocessprivilege->SetValue("1");
		else if (_strnicmp(tmpPrivBuf, "SeRemoteShutdownPrivilege", 25) == 0)
			seremoteshutdownprivilege->SetValue("1");
		else if (_strnicmp(tmpPrivBuf, "SeRestorePrivilege", 18) == 0)
			serestoreprivilege->SetValue("1");
		else if (_strnicmp(tmpPrivBuf, "SeSecurityPrivilege", 19) == 0)
			sesecurityprivilege->SetValue("1");
		else if (_strnicmp(tmpPrivBuf, "SeShutdownPrivilege", 19) == 0)
			seshutdownprivilege->SetValue("1");
		else if (_strnicmp(tmpPrivBuf, "SeSyncAgentPrivilege", 20) == 0)
			sesyncagentprivilege->SetValue("1");
		else if (_strnicmp(tmpPrivBuf, "SeSystemEnvironmentPrivilege", 28) == 0)
			sesystemenvironmentprivilege->SetValue("1");
		else if (_strnicmp(tmpPrivBuf, "SeSystemProfilePrivilege", 24) == 0)
			sesystemprofileprivilege->SetValue("1");
		else if (_strnicmp(tmpPrivBuf, "SeSystemtimePrivilege", 21) == 0)
			sesystemtimeprivilege->SetValue("1");
		else if (_strnicmp(tmpPrivBuf, "SeTakeOwnershipPrivilege", 24) == 0)
			setakeownershipprivilege->SetValue("1");
		else if (_strnicmp(tmpPrivBuf, "SeTcbPrivilege", 14) == 0)
			setcbprivilege->SetValue("1");
		else if (_strnicmp(tmpPrivBuf, "SeUndockPrivilege", 17) == 0)
			seundockprivilege->SetValue("1");
		else if (_strnicmp(tmpPrivBuf, "SeUnsolicitedInputPrivilege", 27) == 0)
			seunsolicitedinputprivilege->SetValue("1");
		else if (_strnicmp(tmpPrivBuf, "SeBatchLogonRight", 17) == 0)
			sebatchlogonright->SetValue("1");
		else if (_strnicmp(tmpPrivBuf, "SeDenyBatchLogonRight", 21) == 0)
			sedenybatchLogonright->SetValue("1");
		else if (_strnicmp(tmpPrivBuf, "SeDenyInteractiveLogonRight", 27) == 0)
			sedenyinteractivelogonright->SetValue("1");
		else if (_strnicmp(tmpPrivBuf, "SeDenyNetworkLogonRight", 23) == 0)
			sedenynetworklogonright->SetValue("1");
		else if (_strnicmp(tmpPrivBuf, "SeDenyServiceLogonRight", 23) == 0)
			sedenyservicelogonright->SetValue("1");
		else if (_strnicmp(tmpPrivBuf, "SeDenyRemoteInteractiveLogonRight", 33) == 0)
			sedenyremoteInteractivelogonright->SetValue("1");
		else if (_strnicmp(tmpPrivBuf, "SeInteractiveLogonRight", 23) == 0)
			seinteractivelogonright->SetValue("1");
		else if (_strnicmp(tmpPrivBuf, "SeNetworkLogonRight", 19) == 0)
			senetworklogonright->SetValue("1");
		else if (_strnicmp(tmpPrivBuf, "SeRemoteInteractiveLogonRight", 29) == 0)
			seremoteinteractivelogonright->SetValue("1");
		else if (_strnicmp(tmpPrivBuf, "SeServiceLogonRight", 19) == 0)
			seservicelogonright->SetValue("1");
		else { 
			delete item;
			LsaFreeMemory(userRights);
			LsaClose(polHandle);
			string errMsg = "Unknown account privilege: ";
			errMsg.append(tmpPrivBuf);
			throw ProbeException(errMsg);
		}
	}

	// Free memory.
	LsaFreeMemory(userRights);
	LsaClose(polHandle);

	return item;
}

