home *** CD-ROM | disk | FTP | other *** search
/ io Programmo 9 / IOPROG_9.ISO / contrib / iis4 / iis4_07.cab / Auth.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1997-09-05  |  10.8 KB  |  409 lines

  1. // Auth.cpp : Implementation of CIISAuth
  2. #include "stdafx.h"
  3. #include "NetAuth.h"
  4. #include "Auth.h"
  5. #include "LM.h"
  6. #include "initguid.h"
  7.  
  8. /////////////////////////////////////////////////////////////////////////////
  9. // CIISAuth ctor
  10. CIISAuth::CIISAuth()
  11. {
  12.     m_pRequest = NULL;
  13.     m_bstrAuthMethod = "";
  14.     m_bstrHTTPS = "";
  15.  
  16.     BuildUserDetails();
  17.     InitInterfaces();
  18.     GetServerVariables();
  19. }
  20.  
  21. CIISAuth::~CIISAuth()
  22. {
  23.     DestroyInterfaces();
  24. }
  25.  
  26. /////////////////////////////////////////////////////////////////////////////
  27. // get_Username
  28. // Returns the name of the user
  29. // pstrUserName is the return parameter
  30. STDMETHODIMP CIISAuth::get_Username(BSTR *pstrUserName)
  31. {
  32.     AtlTrace(L"->In CIISAuth::get_Username()\n");
  33.     *pstrUserName = m_bstrUserName.Copy();
  34.     return S_OK;
  35. }
  36.  
  37. /////////////////////////////////////////////////////////////////////////////
  38. // put_Username
  39. // Set the name of a user
  40. // strUserName is the name of the user to set
  41. STDMETHODIMP CIISAuth::put_Username(BSTR strUserName)
  42. {
  43.     AtlTrace(L"->In CIISAuth::put_Username()\n");
  44.     m_bstrUserName = strUserName;
  45.     BuildUserDetails();    // now we have a new user build up his/her details
  46.     return S_OK;
  47. }
  48.  
  49. /////////////////////////////////////////////////////////////////////////////
  50. // get_Domain
  51. // Return the domain in which the user was authenticated
  52. // pbstrDomain is the return param for the domain
  53. STDMETHODIMP CIISAuth::get_Domain(BSTR *pbstrDomain)
  54. {
  55.     AtlTrace(L"->In CIISAuth::get_Domain()\n");
  56.     *pbstrDomain=m_bstrDomainName.Copy();
  57.     return S_OK;
  58. }
  59.  
  60. /////////////////////////////////////////////////////////////////////////////
  61. // get__NewEnum
  62. // Enumerator method (used by For Each in VB) to return all 
  63. // the groups the user belongs to
  64. STDMETHODIMP CIISAuth::get__NewEnum(IUnknown **retval)
  65. {
  66.     AtlTrace(L"->In CIISAuth::get__NewEnum()\n");
  67.  
  68.     if (retval == NULL)
  69.         return E_POINTER;
  70.  
  71.     *retval = NULL;
  72.  
  73.     typedef CComObject<CComEnum<IEnumVARIANT, &IID_IEnumVARIANT, VARIANT,_Copy<VARIANT> > > enumVar;
  74.     HRESULT hRes = S_OK;
  75.     
  76.     enumVar* p = new enumVar;
  77.     if (p == NULL)
  78.         hRes = E_OUTOFMEMORY;
  79.     else 
  80.     {
  81.         BuildGroupList();
  82.  
  83.         hRes = p->FinalConstruct();
  84.         if (hRes == S_OK)
  85.         {
  86.             hRes = p->Init(&m_varGroups[0], &m_varGroups[m_cGroups], NULL, AtlFlagCopy);
  87.             if (hRes == S_OK)
  88.                 hRes = p->QueryInterface(IID_IUnknown, (void**)retval);
  89.         }
  90.     }
  91.  
  92.     if (hRes != S_OK)
  93.         delete p;
  94.  
  95.     return hRes;
  96.  
  97.     return S_OK;
  98. }
  99.  
  100. /////////////////////////////////////////////////////////////////////////////
  101. // get_AuthMethod
  102. // Returns the IIS authentication method ("", "NTLM" or "BASIC")
  103. // pbstrMethod is the return parameter
  104. STDMETHODIMP CIISAuth::get_AuthMethod(BSTR *pbstrMethod)
  105. {
  106.     AtlTrace(L"->In CIISAuth::get_AuthMethod()\n");
  107.     *pbstrMethod = m_bstrAuthMethod.Copy();
  108.     return S_OK;
  109. }
  110.  
  111. /////////////////////////////////////////////////////////////////////////////
  112. // get_UsingHTTPS
  113. // Returns "off" if HTTPS is not being used on this page or "on" if it is
  114. // pbstrUsingHTTPS is the return parameter
  115. STDMETHODIMP CIISAuth::get_UsingHTTPS(BSTR *pbstrUsingHTTPS)
  116. {
  117.     AtlTrace(L"->In CIISAuth::get_UsingHTTPS()\n");
  118.     *pbstrUsingHTTPS = m_bstrHTTPS.Copy();
  119.     return S_OK;
  120. }
  121.  
  122. /////////////////////////////////////////////////////////////////////////////
  123. // get_IsAdmin
  124. // Is this user in the Administrators local group? 
  125. // pfIsAdmin = TRUE if the user is, FALSE otherwise
  126. STDMETHODIMP CIISAuth::get_IsAdmin(BOOL *pfIsAdmin)
  127. {
  128.     AtlTrace(L"->In CIISAuth::get_IsAdmin()\n");
  129.     CComBSTR bstrAdm(L"Administrators");
  130.     *pfIsAdmin = IsInGroup(bstrAdm);
  131.     return S_OK;
  132. }
  133.  
  134. /////////////////////////////////////////////////////////////////////////////
  135. // get_IsInGroup
  136. // Returns TRUE if the user is in the group specified, FALSE otherwise 
  137. // bstrGroupName is the name ofthe group
  138. // pfIsInGroup is the return parameter
  139. STDMETHODIMP CIISAuth::get_IsInGroup(BSTR bstrGroupName, BOOL *pfIsInGroup)
  140. {
  141.     AtlTrace(L"->In CIISAuth::get_IsInGroup()\n");
  142.     *pfIsInGroup = IsInGroup(bstrGroupName);
  143.     return S_OK;
  144. }
  145.  
  146. ///////////////////////////////////////////////////////////////////////////////////
  147. //
  148. // Helper Functions
  149. //
  150. ///////////////////////////////////////////////////////////////////////////////////
  151.  
  152. /////////////////////////////////////////////////////////////////////////////
  153. // BuildGroupList
  154. // Function to build the list of groups the current user belongs to
  155. void CIISAuth::BuildGroupList()
  156. {
  157.     AtlTrace(L"->In CIISAuth::BuildGroupList()\n");
  158.  
  159.     LPBYTE     lpBuffer;
  160.     DWORD     dwEntriesRead,dwTotalEntries,dwResumeHandle=0;
  161.     LPWSTR  szUserW=m_bstrUserName;
  162.     
  163.     m_cGroups = 0;
  164.  
  165.     // Local Groups
  166.     const DWORD PREFMAXLEN = 8192;
  167.     NET_API_STATUS nErr = 
  168.         NetUserGetLocalGroups(NULL,szUserW,0,0,&lpBuffer,PREFMAXLEN,&dwEntriesRead,&dwTotalEntries);
  169.  
  170.     if (nErr==NERR_Success)
  171.     {
  172.         for (DWORD i=0; i<dwEntriesRead; i++)
  173.         {
  174.             LPBYTE lpTemp=lpBuffer+(sizeof(LOCALGROUP_USERS_INFO_0)*i);
  175.             LPLOCALGROUP_USERS_INFO_0 lgrp = (LPLOCALGROUP_USERS_INFO_0)lpTemp;
  176.             LPWSTR grpName = lgrp->lgrui0_name;
  177.             m_varGroups[m_cGroups] = grpName;
  178.             m_cGroups++;
  179.         }
  180.  
  181.         NetApiBufferFree(lpBuffer);
  182.     }
  183.  
  184.     // Global Groups
  185.     nErr = NetUserGetGroups(NULL,szUserW,0,&lpBuffer,PREFMAXLEN,&dwEntriesRead,&dwTotalEntries);
  186.  
  187.     if (nErr==NERR_Success)
  188.     {
  189.         for (DWORD i=0; i<dwEntriesRead; i++)
  190.         {
  191.             LPBYTE lpTemp=lpBuffer+(sizeof(GROUP_USERS_INFO_0)*i);
  192.             LPGROUP_USERS_INFO_0 lgrp = (LPGROUP_USERS_INFO_0)lpTemp;
  193.             LPWSTR grpName = lgrp->grui0_name;
  194.             m_varGroups[m_cGroups] = _wcsupr(grpName);
  195.             m_cGroups++;
  196.         }
  197.  
  198.         NetApiBufferFree(lpBuffer);
  199.     }
  200. }
  201.  
  202. /////////////////////////////////////////////////////////////////////////////
  203. // BuildUserDetails
  204. // Gets the user and domain info
  205. void CIISAuth::BuildUserDetails()
  206. {
  207.     AtlTrace(L"->In CIISAuth::BuildUserDetails()\n");
  208.  
  209.     m_bstrUserName = "";
  210.     m_bstrDomainName = "";
  211.     
  212.     WCHAR szUserName[64];
  213.     DWORD cbUserName = sizeof(szUserName);    
  214.     if (::GetUserName(szUserName,&cbUserName))
  215.     {
  216.         m_bstrUserName = szUserName;
  217.  
  218.         SID sid;
  219.         WCHAR szDomain[64];
  220.         DWORD cbSid,cbDomain=sizeof szDomain;
  221.         SID_NAME_USE snu=SidTypeUser;
  222.         if (LookupAccountName(NULL,szUserName,&sid,&cbSid,szDomain,&cbDomain,&snu))
  223.             m_bstrDomainName = szDomain;
  224.  
  225.         BuildGroupList();
  226.     }
  227. }
  228.  
  229. /////////////////////////////////////////////////////////////////////////////
  230. // IsInGroup
  231. // Walks the list of groups built by BuildGroupList() to check if the user
  232. // is in the list. Note, this function is case-sensitive
  233. BOOL CIISAuth::IsInGroup(BSTR bstrGroupName)
  234. {
  235.     BOOL fInGroup = FALSE;
  236.     LPWSTR szwGroupName = reinterpret_cast<LPWSTR>(bstrGroupName);
  237.     AtlTrace(L"->In CIISAuth::IsInGroup('%s'), #groups = %d\n",szwGroupName,m_cGroups);
  238.         
  239.     for (DWORD i=0; i < m_cGroups; i++)
  240.     {
  241.         CComVariant vGroupName(bstrGroupName);
  242.         if (m_varGroups[i] == vGroupName)
  243.         {
  244.             fInGroup = TRUE;
  245.             break;
  246.         }
  247.     }
  248.     
  249.     return fInGroup;
  250. }
  251.  
  252. /////////////////////////////////////////////////////////////////////////////
  253. // InitInterfaces
  254. // Initializes the ASP interfaces. 
  255. // You should consider using this (along with GetIntrinsic()) as 
  256. // 'cookie-cutter' code in your own ASP/C++ COM components
  257. HRESULT CIISAuth::InitInterfaces()
  258. {
  259.     AtlTrace(L"->In CIISAuth::InitInterfaces()\n");
  260.     IObjectContext* pObjContext = NULL;
  261.  
  262.     // Get the Object Context from Microsoft Transaction Server
  263.     HRESULT hr = GetObjectContext(&pObjContext);
  264.     if (FAILED(hr))
  265.     {
  266.         AtlTrace(L"CIISAuth::InitInterfaces() -> GetObjectContext() failed (hr=%d)",hr);
  267.         return hr;
  268.     }
  269.  
  270.     // Get the context properties from MTS
  271.     IGetContextProperties *pProperties = NULL;
  272.     hr = pObjContext->QueryInterface(IID_IGetContextProperties, (void**) &pProperties);
  273.     if (FAILED(hr))
  274.     {
  275.         AtlTrace(L"CIISAuth::InitInterfaces() -> QI(IID_IGetContextProperties) failed (hr=%d)", hr);
  276.         return hr;
  277.     }
  278.  
  279.     // We are only interested in the Request interface
  280.     hr = GetIntrinsic(pProperties,L"Request",IID_IRequest,(void **)&m_pRequest);
  281.     if (FAILED(hr))
  282.     {
  283.         AtlTrace(L"CIISAuth::InitInterfaces::GetIntrinsic('Request') failed (hr=%d)",hr);
  284.         return hr;
  285.     }
  286.  
  287.     // Clean up
  288.     if(pObjContext)
  289.         pObjContext->Release();
  290.  
  291.     if(pProperties)
  292.         pProperties->Release();
  293.  
  294.     return hr;
  295. }
  296.  
  297. /////////////////////////////////////////////////////////////////////////////
  298. // GetIntrinsic
  299. // Wrapper function to get an interface pointer to a requested ASP intrinsic
  300. HRESULT CIISAuth::GetIntrinsic(IGetContextProperties *pProps, 
  301.                                WCHAR *szName, 
  302.                                REFIID iid, 
  303.                                void **ppv)
  304. {
  305.     AtlTrace(L"->In CIISAuth::GetIntrinsic('%s')\n",szName);
  306.  
  307.     HRESULT hr = S_OK;
  308.         
  309.     CComBSTR bstrName(szName);
  310.     
  311.     if (bstrName == NULL)
  312.     {
  313.         hr = E_OUTOFMEMORY;
  314.         return hr;
  315.     }
  316.  
  317.     CComVariant v;
  318.  
  319.     if (SUCCEEDED(hr))
  320.     {
  321.         hr = pProps->GetProperty(bstrName, &v);
  322.         if (FAILED(hr))
  323.             return hr;
  324.     }
  325.  
  326.     IDispatch *pDisp = NULL;
  327.  
  328.     if (SUCCEEDED(hr))
  329.     {
  330.         if (V_VT(&v) == VT_DISPATCH)
  331.             pDisp = V_DISPATCH(&v);
  332.  
  333.         if (pDisp == NULL)
  334.         {
  335.             hr = E_POINTER;
  336.             return hr;
  337.         }
  338.     }
  339.  
  340.     if (SUCCEEDED(hr))
  341.     {
  342.         hr = pDisp->QueryInterface(iid, ppv);
  343.         if (FAILED(hr))
  344.             return hr;
  345.     }
  346.  
  347.     return hr;
  348. }
  349.  
  350. /////////////////////////////////////////////////////////////////////////////
  351. // DestroyInterfaces
  352. // Clean up all intrinsic interface pointers
  353. void CIISAuth::DestroyInterfaces()
  354. {
  355.     if(m_pRequest)
  356.         m_pRequest->Release();
  357. }
  358.  
  359. /////////////////////////////////////////////////////////////////////////////
  360. // GetServerVariables
  361. // Returns the server variables we're interested in. In this case the 
  362. // authentication methods and whether we're using HTTPS.
  363. HRESULT CIISAuth::GetServerVariables()
  364. {                                                                      
  365.     AtlTrace(L"->In CIISAuth::GetServerVariables()\n");
  366.  
  367.     IRequestDictionary *pDict = NULL;
  368.     HRESULT hr = m_pRequest->get_ServerVariables(&pDict);
  369.  
  370.     // Get Authentication method
  371.     CComBSTR bstrAuth(L"AUTH_TYPE");
  372.     CComVariant vAuth(bstrAuth), vRetAuth;
  373.     hr = pDict->get_Item(vAuth,&vRetAuth);
  374.     if (SUCCEEDED(hr))
  375.     {
  376.         vRetAuth.ChangeType(VT_BSTR);
  377.         m_bstrAuthMethod = vRetAuth.bstrVal;
  378.         AtlTrace(L"    ->GetServerVariables, AUTH_TYPE=%s\n",(LPWSTR)(BSTR)m_bstrAuthMethod);
  379.     }
  380.  
  381.     // Get HTTPS status
  382.     CComBSTR bstrHTTPS(L"HTTPS");
  383.     CComVariant vHTTPS(bstrHTTPS), vRetHTTPS;
  384.     hr = pDict->get_Item(vHTTPS,&vRetHTTPS);
  385.     if (SUCCEEDED(hr))
  386.     {
  387.         vRetHTTPS.ChangeType(VT_BSTR);
  388.         m_bstrHTTPS = vRetHTTPS.bstrVal;
  389.         AtlTrace(L"    ->GetServerVariables, HTTPS=%s\n",(LPWSTR)(BSTR)m_bstrHTTPS);
  390.     }
  391.  
  392.     return hr;
  393. }
  394.  
  395. /////////////////////////////////////////////////////////////////////////////
  396. // GetCertificateDetails
  397. // DATA NOT YET USED - HERE AS AN EXAMPLE ONLY
  398. // Returns the certificate info we're interested in.
  399. HRESULT CIISAuth::GetCertificateDetails()
  400. {
  401.     AtlTrace(L"->In CIISAuth::GetCertificateDetails()\n");
  402.  
  403.     IRequestDictionary *pDict = NULL;
  404.     HRESULT hr = m_pRequest->get_ClientCertificate(&pDict);
  405.  
  406.     return hr;
  407. }
  408.  
  409.