home *** CD-ROM | disk | FTP | other *** search
- // Auth.cpp : Implementation of CIISAuth
- #include "stdafx.h"
- #include "NetAuth.h"
- #include "Auth.h"
- #include "LM.h"
- #include "initguid.h"
-
- /////////////////////////////////////////////////////////////////////////////
- // CIISAuth ctor
- CIISAuth::CIISAuth()
- {
- m_pRequest = NULL;
- m_bstrAuthMethod = "";
- m_bstrHTTPS = "";
-
- BuildUserDetails();
- InitInterfaces();
- GetServerVariables();
- }
-
- CIISAuth::~CIISAuth()
- {
- DestroyInterfaces();
- }
-
- /////////////////////////////////////////////////////////////////////////////
- // get_Username
- // Returns the name of the user
- // pstrUserName is the return parameter
- STDMETHODIMP CIISAuth::get_Username(BSTR *pstrUserName)
- {
- AtlTrace(L"->In CIISAuth::get_Username()\n");
- *pstrUserName = m_bstrUserName.Copy();
- return S_OK;
- }
-
- /////////////////////////////////////////////////////////////////////////////
- // put_Username
- // Set the name of a user
- // strUserName is the name of the user to set
- STDMETHODIMP CIISAuth::put_Username(BSTR strUserName)
- {
- AtlTrace(L"->In CIISAuth::put_Username()\n");
- m_bstrUserName = strUserName;
- BuildUserDetails(); // now we have a new user build up his/her details
- return S_OK;
- }
-
- /////////////////////////////////////////////////////////////////////////////
- // get_Domain
- // Return the domain in which the user was authenticated
- // pbstrDomain is the return param for the domain
- STDMETHODIMP CIISAuth::get_Domain(BSTR *pbstrDomain)
- {
- AtlTrace(L"->In CIISAuth::get_Domain()\n");
- *pbstrDomain=m_bstrDomainName.Copy();
- return S_OK;
- }
-
- /////////////////////////////////////////////////////////////////////////////
- // get__NewEnum
- // Enumerator method (used by For Each in VB) to return all
- // the groups the user belongs to
- STDMETHODIMP CIISAuth::get__NewEnum(IUnknown **retval)
- {
- AtlTrace(L"->In CIISAuth::get__NewEnum()\n");
-
- if (retval == NULL)
- return E_POINTER;
-
- *retval = NULL;
-
- typedef CComObject<CComEnum<IEnumVARIANT, &IID_IEnumVARIANT, VARIANT,_Copy<VARIANT> > > enumVar;
- HRESULT hRes = S_OK;
-
- enumVar* p = new enumVar;
- if (p == NULL)
- hRes = E_OUTOFMEMORY;
- else
- {
- BuildGroupList();
-
- hRes = p->FinalConstruct();
- if (hRes == S_OK)
- {
- hRes = p->Init(&m_varGroups[0], &m_varGroups[m_cGroups], NULL, AtlFlagCopy);
- if (hRes == S_OK)
- hRes = p->QueryInterface(IID_IUnknown, (void**)retval);
- }
- }
-
- if (hRes != S_OK)
- delete p;
-
- return hRes;
-
- return S_OK;
- }
-
- /////////////////////////////////////////////////////////////////////////////
- // get_AuthMethod
- // Returns the IIS authentication method ("", "NTLM" or "BASIC")
- // pbstrMethod is the return parameter
- STDMETHODIMP CIISAuth::get_AuthMethod(BSTR *pbstrMethod)
- {
- AtlTrace(L"->In CIISAuth::get_AuthMethod()\n");
- *pbstrMethod = m_bstrAuthMethod.Copy();
- return S_OK;
- }
-
- /////////////////////////////////////////////////////////////////////////////
- // get_UsingHTTPS
- // Returns "off" if HTTPS is not being used on this page or "on" if it is
- // pbstrUsingHTTPS is the return parameter
- STDMETHODIMP CIISAuth::get_UsingHTTPS(BSTR *pbstrUsingHTTPS)
- {
- AtlTrace(L"->In CIISAuth::get_UsingHTTPS()\n");
- *pbstrUsingHTTPS = m_bstrHTTPS.Copy();
- return S_OK;
- }
-
- /////////////////////////////////////////////////////////////////////////////
- // get_IsAdmin
- // Is this user in the Administrators local group?
- // pfIsAdmin = TRUE if the user is, FALSE otherwise
- STDMETHODIMP CIISAuth::get_IsAdmin(BOOL *pfIsAdmin)
- {
- AtlTrace(L"->In CIISAuth::get_IsAdmin()\n");
- CComBSTR bstrAdm(L"Administrators");
- *pfIsAdmin = IsInGroup(bstrAdm);
- return S_OK;
- }
-
- /////////////////////////////////////////////////////////////////////////////
- // get_IsInGroup
- // Returns TRUE if the user is in the group specified, FALSE otherwise
- // bstrGroupName is the name ofthe group
- // pfIsInGroup is the return parameter
- STDMETHODIMP CIISAuth::get_IsInGroup(BSTR bstrGroupName, BOOL *pfIsInGroup)
- {
- AtlTrace(L"->In CIISAuth::get_IsInGroup()\n");
- *pfIsInGroup = IsInGroup(bstrGroupName);
- return S_OK;
- }
-
- ///////////////////////////////////////////////////////////////////////////////////
- //
- // Helper Functions
- //
- ///////////////////////////////////////////////////////////////////////////////////
-
- /////////////////////////////////////////////////////////////////////////////
- // BuildGroupList
- // Function to build the list of groups the current user belongs to
- void CIISAuth::BuildGroupList()
- {
- AtlTrace(L"->In CIISAuth::BuildGroupList()\n");
-
- LPBYTE lpBuffer;
- DWORD dwEntriesRead,dwTotalEntries,dwResumeHandle=0;
- LPWSTR szUserW=m_bstrUserName;
-
- m_cGroups = 0;
-
- // Local Groups
- const DWORD PREFMAXLEN = 8192;
- NET_API_STATUS nErr =
- NetUserGetLocalGroups(NULL,szUserW,0,0,&lpBuffer,PREFMAXLEN,&dwEntriesRead,&dwTotalEntries);
-
- if (nErr==NERR_Success)
- {
- for (DWORD i=0; i<dwEntriesRead; i++)
- {
- LPBYTE lpTemp=lpBuffer+(sizeof(LOCALGROUP_USERS_INFO_0)*i);
- LPLOCALGROUP_USERS_INFO_0 lgrp = (LPLOCALGROUP_USERS_INFO_0)lpTemp;
- LPWSTR grpName = lgrp->lgrui0_name;
- m_varGroups[m_cGroups] = grpName;
- m_cGroups++;
- }
-
- NetApiBufferFree(lpBuffer);
- }
-
- // Global Groups
- nErr = NetUserGetGroups(NULL,szUserW,0,&lpBuffer,PREFMAXLEN,&dwEntriesRead,&dwTotalEntries);
-
- if (nErr==NERR_Success)
- {
- for (DWORD i=0; i<dwEntriesRead; i++)
- {
- LPBYTE lpTemp=lpBuffer+(sizeof(GROUP_USERS_INFO_0)*i);
- LPGROUP_USERS_INFO_0 lgrp = (LPGROUP_USERS_INFO_0)lpTemp;
- LPWSTR grpName = lgrp->grui0_name;
- m_varGroups[m_cGroups] = _wcsupr(grpName);
- m_cGroups++;
- }
-
- NetApiBufferFree(lpBuffer);
- }
- }
-
- /////////////////////////////////////////////////////////////////////////////
- // BuildUserDetails
- // Gets the user and domain info
- void CIISAuth::BuildUserDetails()
- {
- AtlTrace(L"->In CIISAuth::BuildUserDetails()\n");
-
- m_bstrUserName = "";
- m_bstrDomainName = "";
-
- WCHAR szUserName[64];
- DWORD cbUserName = sizeof(szUserName);
- if (::GetUserName(szUserName,&cbUserName))
- {
- m_bstrUserName = szUserName;
-
- SID sid;
- WCHAR szDomain[64];
- DWORD cbSid,cbDomain=sizeof szDomain;
- SID_NAME_USE snu=SidTypeUser;
- if (LookupAccountName(NULL,szUserName,&sid,&cbSid,szDomain,&cbDomain,&snu))
- m_bstrDomainName = szDomain;
-
- BuildGroupList();
- }
- }
-
- /////////////////////////////////////////////////////////////////////////////
- // IsInGroup
- // Walks the list of groups built by BuildGroupList() to check if the user
- // is in the list. Note, this function is case-sensitive
- BOOL CIISAuth::IsInGroup(BSTR bstrGroupName)
- {
- BOOL fInGroup = FALSE;
- LPWSTR szwGroupName = reinterpret_cast<LPWSTR>(bstrGroupName);
- AtlTrace(L"->In CIISAuth::IsInGroup('%s'), #groups = %d\n",szwGroupName,m_cGroups);
-
- for (DWORD i=0; i < m_cGroups; i++)
- {
- CComVariant vGroupName(bstrGroupName);
- if (m_varGroups[i] == vGroupName)
- {
- fInGroup = TRUE;
- break;
- }
- }
-
- return fInGroup;
- }
-
- /////////////////////////////////////////////////////////////////////////////
- // InitInterfaces
- // Initializes the ASP interfaces.
- // You should consider using this (along with GetIntrinsic()) as
- // 'cookie-cutter' code in your own ASP/C++ COM components
- HRESULT CIISAuth::InitInterfaces()
- {
- AtlTrace(L"->In CIISAuth::InitInterfaces()\n");
- IObjectContext* pObjContext = NULL;
-
- // Get the Object Context from Microsoft Transaction Server
- HRESULT hr = GetObjectContext(&pObjContext);
- if (FAILED(hr))
- {
- AtlTrace(L"CIISAuth::InitInterfaces() -> GetObjectContext() failed (hr=%d)",hr);
- return hr;
- }
-
- // Get the context properties from MTS
- IGetContextProperties *pProperties = NULL;
- hr = pObjContext->QueryInterface(IID_IGetContextProperties, (void**) &pProperties);
- if (FAILED(hr))
- {
- AtlTrace(L"CIISAuth::InitInterfaces() -> QI(IID_IGetContextProperties) failed (hr=%d)", hr);
- return hr;
- }
-
- // We are only interested in the Request interface
- hr = GetIntrinsic(pProperties,L"Request",IID_IRequest,(void **)&m_pRequest);
- if (FAILED(hr))
- {
- AtlTrace(L"CIISAuth::InitInterfaces::GetIntrinsic('Request') failed (hr=%d)",hr);
- return hr;
- }
-
- // Clean up
- if(pObjContext)
- pObjContext->Release();
-
- if(pProperties)
- pProperties->Release();
-
- return hr;
- }
-
- /////////////////////////////////////////////////////////////////////////////
- // GetIntrinsic
- // Wrapper function to get an interface pointer to a requested ASP intrinsic
- HRESULT CIISAuth::GetIntrinsic(IGetContextProperties *pProps,
- WCHAR *szName,
- REFIID iid,
- void **ppv)
- {
- AtlTrace(L"->In CIISAuth::GetIntrinsic('%s')\n",szName);
-
- HRESULT hr = S_OK;
-
- CComBSTR bstrName(szName);
-
- if (bstrName == NULL)
- {
- hr = E_OUTOFMEMORY;
- return hr;
- }
-
- CComVariant v;
-
- if (SUCCEEDED(hr))
- {
- hr = pProps->GetProperty(bstrName, &v);
- if (FAILED(hr))
- return hr;
- }
-
- IDispatch *pDisp = NULL;
-
- if (SUCCEEDED(hr))
- {
- if (V_VT(&v) == VT_DISPATCH)
- pDisp = V_DISPATCH(&v);
-
- if (pDisp == NULL)
- {
- hr = E_POINTER;
- return hr;
- }
- }
-
- if (SUCCEEDED(hr))
- {
- hr = pDisp->QueryInterface(iid, ppv);
- if (FAILED(hr))
- return hr;
- }
-
- return hr;
- }
-
- /////////////////////////////////////////////////////////////////////////////
- // DestroyInterfaces
- // Clean up all intrinsic interface pointers
- void CIISAuth::DestroyInterfaces()
- {
- if(m_pRequest)
- m_pRequest->Release();
- }
-
- /////////////////////////////////////////////////////////////////////////////
- // GetServerVariables
- // Returns the server variables we're interested in. In this case the
- // authentication methods and whether we're using HTTPS.
- HRESULT CIISAuth::GetServerVariables()
- {
- AtlTrace(L"->In CIISAuth::GetServerVariables()\n");
-
- IRequestDictionary *pDict = NULL;
- HRESULT hr = m_pRequest->get_ServerVariables(&pDict);
-
- // Get Authentication method
- CComBSTR bstrAuth(L"AUTH_TYPE");
- CComVariant vAuth(bstrAuth), vRetAuth;
- hr = pDict->get_Item(vAuth,&vRetAuth);
- if (SUCCEEDED(hr))
- {
- vRetAuth.ChangeType(VT_BSTR);
- m_bstrAuthMethod = vRetAuth.bstrVal;
- AtlTrace(L" ->GetServerVariables, AUTH_TYPE=%s\n",(LPWSTR)(BSTR)m_bstrAuthMethod);
- }
-
- // Get HTTPS status
- CComBSTR bstrHTTPS(L"HTTPS");
- CComVariant vHTTPS(bstrHTTPS), vRetHTTPS;
- hr = pDict->get_Item(vHTTPS,&vRetHTTPS);
- if (SUCCEEDED(hr))
- {
- vRetHTTPS.ChangeType(VT_BSTR);
- m_bstrHTTPS = vRetHTTPS.bstrVal;
- AtlTrace(L" ->GetServerVariables, HTTPS=%s\n",(LPWSTR)(BSTR)m_bstrHTTPS);
- }
-
- return hr;
- }
-
- /////////////////////////////////////////////////////////////////////////////
- // GetCertificateDetails
- // DATA NOT YET USED - HERE AS AN EXAMPLE ONLY
- // Returns the certificate info we're interested in.
- HRESULT CIISAuth::GetCertificateDetails()
- {
- AtlTrace(L"->In CIISAuth::GetCertificateDetails()\n");
-
- IRequestDictionary *pDict = NULL;
- HRESULT hr = m_pRequest->get_ClientCertificate(&pDict);
-
- return hr;
- }
-
-