SCODE ParseAuthorityUserArgs(BSTR & AuthArg, BSTR & UserArg,BSTR & Authority,BSTR & User) { // Determine the connection type by examining the Authority string if(!(Authority == NULL || wcslen(Authority) == 0 || !_wcsnicmp(Authority, L"NTLMDOMAIN:",11))) return E_INVALIDARG; // The ntlm case is more complex. There are four cases // 1) Authority = NTLMDOMAIN:name" and User = "User" // 2) Authority = NULL and User = "User" // 3) Authority = "NTLMDOMAIN:" User = "domain\user" // 4) Authority = NULL and User = "domain\user" // first step is to determine if there is a backslash in the user name somewhere between the // second and second to last character WCHAR * pSlashInUser = NULL; if(User) { WCHAR * pEnd = User + wcslen(User) - 1; for(pSlashInUser = User; pSlashInUser <= pEnd; pSlashInUser++) if(*pSlashInUser == L'\\') // do not think forward slash is allowed! break; if(pSlashInUser > pEnd) pSlashInUser = NULL; } if(Authority && wcslen(Authority) > 11) { if(pSlashInUser) return E_INVALIDARG; AuthArg = SysAllocString(Authority + 11); if(User) UserArg = SysAllocString(User); return S_OK; } else if(pSlashInUser) { int iDomLen = pSlashInUser-User; WCHAR cTemp[MAX_PATH]; wcsncpy(cTemp, User, iDomLen); cTemp[iDomLen] = 0; AuthArg = SysAllocString(cTemp); if(wcslen(pSlashInUser+1)) UserArg = SysAllocString(pSlashInUser+1); } else if(User) UserArg = SysAllocString(User); return S_OK; } // HRESULT SetInterfaceSecurity(IUnknown * pInterface, LPWSTR pAuthority, LPWSTR pUser, LPWSTR pPassword, bool bAuthenticate) {
SCODE sc; if(pInterface == NULL) return E_INVALIDARG; // If we are lowering the security, no need to deal with the identification info
if(!bAuthenticate) return CoSetProxyBlanket(pInterface, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, NULL, RPC_C_AUTHN_LEVEL_NONE, RPC_C_IMP_LEVEL_IDENTIFY, NULL, EOAC_NONE); // If we are doing trivial case, just pass in a null authentication structure which is used // if the current logged in user's credentials are OK. if((pAuthority == NULL || wcslen(pAuthority) < 1) && (pUser == NULL || wcslen(pUser) < 1) && (pPassword == NULL || wcslen(pPassword) < 1)) return CoSetProxyBlanket(pInterface, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, NULL, RPC_C_AUTHN_LEVEL_CONNECT, RPC_C_IMP_LEVEL_IDENTIFY, NULL, EOAC_NONE); // If user, or Authority was passed in, the we need to create an authority argument for the login
{ // Determine the connection type by examining the Authority string if(!(Authority == NULL || wcslen(Authority) == 0 || !_wcsnicmp(Authority, L"NTLMDOMAIN:",11)))
return E_INVALIDARG; // The ntlm case is more complex. There are four cases
// 1) Authority = NTLMDOMAIN:name" and User = "User"
// 2) Authority = NULL and User = "User"
// 3) Authority = "NTLMDOMAIN:" User = "domain\user"
// 4) Authority = NULL and User = "domain\user" // first step is to determine if there is a backslash in the user name somewhere between the
// second and second to last character WCHAR * pSlashInUser = NULL;
if(User)
{
WCHAR * pEnd = User + wcslen(User) - 1;
for(pSlashInUser = User; pSlashInUser <= pEnd; pSlashInUser++)
if(*pSlashInUser == L'\\') // do not think forward slash is allowed!
break;
if(pSlashInUser > pEnd)
pSlashInUser = NULL;
} if(Authority && wcslen(Authority) > 11)
{
if(pSlashInUser)
return E_INVALIDARG; AuthArg = SysAllocString(Authority + 11);
if(User) UserArg = SysAllocString(User);
return S_OK;
}
else if(pSlashInUser)
{
int iDomLen = pSlashInUser-User;
WCHAR cTemp[MAX_PATH];
wcsncpy(cTemp, User, iDomLen);
cTemp[iDomLen] = 0;
AuthArg = SysAllocString(cTemp);
if(wcslen(pSlashInUser+1))
UserArg = SysAllocString(pSlashInUser+1);
}
else
if(User) UserArg = SysAllocString(User); return S_OK;
}
//
HRESULT SetInterfaceSecurity(IUnknown * pInterface, LPWSTR pAuthority, LPWSTR pUser,
LPWSTR pPassword, bool bAuthenticate)
{
SCODE sc;
if(pInterface == NULL)
return E_INVALIDARG; // If we are lowering the security, no need to deal with the identification info
if(!bAuthenticate)
return CoSetProxyBlanket(pInterface, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, NULL,
RPC_C_AUTHN_LEVEL_NONE, RPC_C_IMP_LEVEL_IDENTIFY, NULL, EOAC_NONE); // If we are doing trivial case, just pass in a null authentication structure which is used
// if the current logged in user's credentials are OK. if((pAuthority == NULL || wcslen(pAuthority) < 1) &&
(pUser == NULL || wcslen(pUser) < 1) &&
(pPassword == NULL || wcslen(pPassword) < 1))
return CoSetProxyBlanket(pInterface, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, NULL,
RPC_C_AUTHN_LEVEL_CONNECT, RPC_C_IMP_LEVEL_IDENTIFY, NULL, EOAC_NONE); // If user, or Authority was passed in, the we need to create an authority argument for the login
COAUTHIDENTITY authident;
BSTR AuthArg = NULL, UserArg = NULL;
sc = ParseAuthorityUserArgs(AuthArg, UserArg, pAuthority, pUser);
if(sc != S_OK)
return sc; memset((void *)&authident,0,sizeof(COAUTHIDENTITY));
if(bIsNT())
{
if(UserArg)
{
authident.UserLength = wcslen(UserArg);
authident.User = (LPWSTR)UserArg;
}
if(AuthArg)
{
authident.DomainLength = wcslen(AuthArg);
authident.Domain = (LPWSTR)AuthArg;
}
if(pPassword)
{
authident.PasswordLength = wcslen(pPassword);
authident.Password = (LPWSTR)pPassword;
}
authident.Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE;
}
else
{
char szUser[MAX_PATH], szAuthority[MAX_PATH], szPassword[MAX_PATH]; // Fill in the identity structure if(UserArg)
{
wcstombs(szUser, UserArg, MAX_PATH);
authident.UserLength = strlen(szUser);
authident.User = (LPWSTR)szUser;
}
if(AuthArg)
{
wcstombs(szAuthority, AuthArg, MAX_PATH);
authident.DomainLength = strlen(szAuthority);
authident.Domain = (LPWSTR)szAuthority;
}
if(pPassword)
{
wcstombs(szPassword, pPassword, MAX_PATH);
authident.PasswordLength = strlen(szPassword);
authident.Password = (LPWSTR)szPassword;
}
authident.Flags = SEC_WINNT_AUTH_IDENTITY_ANSI;
} HRESULT hr;
DWORD dwAuthnSvc, dwAuthzSvc, dwAuthLvl, dwCaps; // Get the current proxy settings
hr = CoQueryProxyBlanket(pInterface, &dwAuthnSvc, &dwAuthzSvc, NULL, &dwAuthLvl,
NULL, NULL, &dwCaps); if(SUCCEEDED(hr))
{
hr = CoSetProxyBlanket(pInterface, dwAuthnSvc, dwAuthzSvc, NULL, dwAuthLvl,
RPC_C_IMP_LEVEL_IMPERSONATE, &authident, dwCaps);
} // old method
/*hr = CoSetProxyBlanket(pInterface, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, NULL,
RPC_C_AUTHN_LEVEL_CONNECT, RPC_C_IMP_LEVEL_IDENTIFY, &authident, EOAC_NONE);*/ if(UserArg)
SysFreeString(UserArg);
if(AuthArg)
SysFreeString(AuthArg);
return hr;
}