Summary
Client (Windows XP SP3)
Server (Windows Vista Business SP1) / Running as LocalSystem Service
Api Sequence
Client – AcquireCredentialsHandle
Client – Initializesecuritycontext
Server – Acquirecredentialshandle
Server – AcceptSecurityContext
Client/Server – CompleteAuthnToken
Server – ImpersonateSecurityContext
Server – AccessCheckAndAuditAlarm (MAXIMUM_allowed)
Server – I then compare the access requested with the allowed accesses.
I call access check against a private security object created with createprivateobjectsecurityex. With Uac turned on I get success back from accesscheck, but none of the privledges are held. With uac turned off I get success back with all of the rights in the GantedAccess parameter
Details
The application has two componets to it, a client and a server. It
uses tcp to communicat over an unsecured network. To authentication
the incomming connections I use the sspi api's listed above, and
impersonate the calling user. Once the calling user is impersonated I
use Accesscheckandauditalarm, if this fails the i revert back to just
accesscheck. With UAC turned on I am getting success back from
accesscheckandauditalarm but none of the access rights are in the
grandedaccess paramter, but if uac is turned off it works as expected.
I have check the integrity level of the server process and it is set
to High, I have looked the integrity level of the impersonation token
used to impersonate the calling user and it is set to Medium. I have
tried setting the integrity level of the calling user to high, with
success but the access check still returns incorrrect results.
THinking I might have a linked token I tried the linked token with a
call to GetTOkenInformation(TokenLInkedToken) with a result of 0x520.
Any thoughts on what I might try next would be appreciated.
Code after authentication.
SECURITY_STATUS ss = SEC_E_OK;
HANDLE _hToken = NULL;
ss = QuerySecurityContextToken((PCtxtHandle)pContext,&_hToken);
if(SEC_E_OK != ss)
{
return ss;
}
CAccessToken impToken;
impToken.Attach(_hToken);
if(CWin32::IsVista())
{
/*TOKEN_LINKED_TOKEN linkedToken;
DWORD nLen = 0;
BOOL bRet = GetTokenInformation(_hToken,
(TOKEN_INFORMATION_CLASS)TokenLinkedToken,&linkedToken,sizeof(linkedToken), &nLen);
if(bRet)
{
CloseHandle(impToken.Detach());
impToken.Attach(linkedToken.LinkedToken);
}
else
{
TRACE(_T("GetTokenInfo Failed 0x%x\n"),GetLastError());
}*/
PSID pHighIntegritySid = NULL;
BOOL bConvertSid = FALSE;
bConvertSid = ConvertStringSidToSid(SDDL_ML_HIGH,
&pHighIntegritySid);
if (bConvertSid)
{
TOKEN_MANDATORY_LABEL TML = {0};
TML.Label.Attributes = SE_GROUP_INTEGRITY |
SE_GROUP_INTEGRITY_ENABLED;
TML.Label.Sid = pHighIntegritySid;
BOOL bSetTokenRet = SetTokenInformation(_hToken,
(TOKEN_INFORMATION_CLASS)TokenIntegrityLevel,&TML,sizeof(TML) +
GetLengthSid(pHighIntegritySid));
LocalFree(pHighIntegritySid);
if(!bSetTokenRet)
{
nReturn = GetLastError();
DBGOUT(DebugOut::LOG_COMP_AUTH_LAYER,DebugOut::LOG_DETAIL_ERROR,
_T("Failed to set Token information %x\n"),nReturn);
return nReturn;
}
}
}
bool bRet = impToken.Impersonate();
if(false == bRet)
{
return GetLastError();
}
_GetTokenSecurityLevel(impToken.GetHandle());
::MapGenericMask(&nRights, GetGENERIC_MAPPING());
DWORD nAccessGranted = 0;
BOOL bAccessStatus = FALSE;
BOOL bGenerateOnClose = FALSE;
BOOL bAccessCheckRet = FALSE;
bAccessCheckRet = ::AccessCheckAndAuditAlarm(_T("Purgos
Security"),impToken.GetHandle(),_T("Purgos"),m_csObjectName.GetBuffer(0),
const_cast<SECURITY_DESCRIPTOR*>(m_ObjectSD.GetPSECURITY_DESCRIPTOR())/
*privObjectSD.GetPSECURITY_DESCRIPTOR())*/,MAXIMUM_ALLOWED,GetGENERIC_MAPPI NG(),FALSE,&nAccessGranted,&bAccessStatus,&bGenerateOnClose);
Best Answer
Found the Solution to all interested parties.
The problem was that the user being authenticated was a local account, and by default local accounts have a filtered token with the BUILTIN\Administrators group having a deny ACL. And I was checking rights against the BUILTIN\Administrators group. So had to set a registry setting or use a domain account.
Ryan