Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

253 lines
8.5 KiB

  1. // RidSave.cpp : Implementation of CGetRidsApp and DLL registration.
  2. #include "stdafx.h"
  3. #include "GetRids.h"
  4. #include "RidSave.h"
  5. #include "ARExt.h"
  6. #include "ARExt_i.c"
  7. #include <iads.h>
  8. #include <AdsHlp.h>
  9. #include "resstr.h"
  10. #include "TxtSid.h"
  11. #import "VarSet.tlb" no_namespace rename("property", "aproperty")
  12. #ifndef IADsPtr
  13. _COM_SMARTPTR_TYPEDEF(IADs, IID_IADs);
  14. #endif
  15. /////////////////////////////////////////////////////////////////////////////
  16. // RidSave
  17. StringLoader gString;
  18. DWORD __stdcall GetRidFromVariantSid(const _variant_t& vntSid);
  19. //---------------------------------------------------------------------------
  20. // Get and set methods for the properties.
  21. //---------------------------------------------------------------------------
  22. STDMETHODIMP RidSave::get_sName(BSTR *pVal)
  23. {
  24. *pVal = m_sName;
  25. return S_OK;
  26. }
  27. STDMETHODIMP RidSave::put_sName(BSTR newVal)
  28. {
  29. m_sName = newVal;
  30. return S_OK;
  31. }
  32. STDMETHODIMP RidSave::get_sDesc(BSTR *pVal)
  33. {
  34. *pVal = m_sDesc;
  35. return S_OK;
  36. }
  37. STDMETHODIMP RidSave::put_sDesc(BSTR newVal)
  38. {
  39. m_sDesc = newVal;
  40. return S_OK;
  41. }
  42. //---------------------------------------------------------------------------
  43. // PreProcessObject
  44. //---------------------------------------------------------------------------
  45. STDMETHODIMP RidSave::PreProcessObject(
  46. IUnknown *pSource, //in- Pointer to the source AD object
  47. IUnknown *pTarget, //in- Pointer to the target AD object
  48. IUnknown *pMainSettings, //in- Varset filled with the settings supplied by user
  49. IUnknown **ppPropsToSet, //in,out - Varset filled with Prop-Value pairs that will be set
  50. // once all extension objects are executed.
  51. EAMAccountStats* pStats
  52. )
  53. {
  54. IVarSetPtr pVs = pMainSettings;
  55. VARIANT var;
  56. _bstr_t sTemp;
  57. IADsPtr pAds;
  58. HRESULT hr = S_OK;
  59. DWORD rid = 0; // default to 0, if RID not found
  60. // We need to process users and groups only
  61. sTemp = pVs->get(GET_BSTR(DCTVS_CopiedAccount_Type));
  62. if (!sTemp.length())
  63. return HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY);
  64. if ( _wcsicmp((WCHAR*)sTemp,L"user") && _wcsicmp((WCHAR*)sTemp,L"inetOrgPerson") && _wcsicmp((WCHAR*)sTemp,L"group") )
  65. return S_OK;
  66. //Get the IADs pointer to manipulate properties
  67. pAds = pSource;
  68. if ( pAds )
  69. {
  70. VariantInit(&var);
  71. hr = pAds->Get(_bstr_t(L"objectSID"),&var);
  72. if ( SUCCEEDED(hr) )
  73. {
  74. // retrieve the RID
  75. rid = GetRidFromVariantSid(_variant_t(var, false));
  76. }
  77. }
  78. // save the RID
  79. pVs->put(GET_BSTR(DCTVS_CopiedAccount_SourceRID),(long)rid);
  80. return hr;
  81. }
  82. //---------------------------------------------------------------------------
  83. // ProcessObject
  84. //---------------------------------------------------------------------------
  85. STDMETHODIMP RidSave::ProcessObject(
  86. IUnknown *pSource, //in- Pointer to the source AD object
  87. IUnknown *pTarget, //in- Pointer to the target AD object
  88. IUnknown *pMainSettings, //in- Varset filled with the settings supplied by user
  89. IUnknown **ppPropsToSet, //in,out - Varset filled with Prop-Value pairs that will be set
  90. // once all extension objects are executed.
  91. EAMAccountStats* pStats
  92. )
  93. {
  94. IVarSetPtr pVs = pMainSettings;
  95. VARIANT var;
  96. _bstr_t sTemp;
  97. IADsPtr pAds;
  98. HRESULT hr = S_OK;
  99. DWORD rid = 0; // default to 0, if RID not found
  100. // We need to process users and groups only
  101. sTemp = pVs->get(GET_BSTR(DCTVS_CopiedAccount_Type));
  102. if ( _wcsicmp((WCHAR*)sTemp,L"user") && _wcsicmp((WCHAR*)sTemp,L"inetOrgPerson") && _wcsicmp((WCHAR*)sTemp,L"group") )
  103. {
  104. return S_OK;
  105. }
  106. //Get the IADs pointer to manipulate properties
  107. pAds = pTarget;
  108. if (pAds)
  109. {
  110. VariantInit(&var);
  111. hr = pAds->Get(_bstr_t(L"objectSID"),&var);
  112. if ( SUCCEEDED(hr) )
  113. {
  114. // retrieve the RID
  115. rid = GetRidFromVariantSid(_variant_t(var, false));
  116. }
  117. }
  118. // save the RID
  119. pVs->put(GET_BSTR(DCTVS_CopiedAccount_TargetRID),(long)rid);
  120. return hr;
  121. }
  122. //---------------------------------------------------------------------------
  123. // ProcessUndo
  124. //---------------------------------------------------------------------------
  125. STDMETHODIMP RidSave::ProcessUndo(
  126. IUnknown *pSource, //in- Pointer to the source AD object
  127. IUnknown *pTarget, //in- Pointer to the target AD object
  128. IUnknown *pMainSettings, //in- Varset filled with the settings supplied by user
  129. IUnknown **ppPropsToSet, //in,out - Varset filled with Prop-Value pairs that will be set
  130. // once all extension objects are executed.
  131. EAMAccountStats* pStats
  132. )
  133. {
  134. HRESULT hr = S_OK;
  135. IVarSetPtr spSettings(pMainSettings);
  136. if (spSettings)
  137. {
  138. //
  139. // Update RID for undo of intra-forest moves only as the
  140. // target object will receive a new RID in this case.
  141. //
  142. _bstr_t strIntraForest = spSettings->get(GET_BSTR(DCTVS_Options_IsIntraforest));
  143. if (strIntraForest == GET_BSTR(IDS_YES))
  144. {
  145. //
  146. // Update RID if target object exists.
  147. //
  148. IADsPtr spTarget(pTarget);
  149. if (spTarget)
  150. {
  151. //
  152. // Update RID only for user and group objects.
  153. //
  154. _bstr_t strType = spSettings->get(GET_BSTR(DCTVS_CopiedAccount_Type));
  155. PCWSTR pszType = strType;
  156. bool bTypeValid =
  157. pszType &&
  158. ((_wcsicmp(pszType, L"user") == 0) ||
  159. (_wcsicmp(pszType, L"inetOrgPerson") == 0) ||
  160. (_wcsicmp(pszType, L"group") == 0));
  161. if (bTypeValid)
  162. {
  163. //
  164. // Retrieve RID of object.
  165. //
  166. VARIANT var;
  167. VariantInit(&var);
  168. hr = spTarget->Get(_bstr_t(L"objectSID"), &var);
  169. if (SUCCEEDED(hr))
  170. {
  171. DWORD dwRid = GetRidFromVariantSid(_variant_t(var, false));
  172. spSettings->put(GET_BSTR(DCTVS_CopiedAccount_TargetRID), static_cast<long>(dwRid));
  173. }
  174. }
  175. }
  176. }
  177. }
  178. else
  179. {
  180. hr = E_INVALIDARG;
  181. }
  182. return hr;
  183. }
  184. //------------------------------------------------------------------------------
  185. // GetRidFromVariantSid Function
  186. //
  187. // Synopsis
  188. // Retrieves the final RID from a SID in variant form.
  189. //
  190. // Arguments
  191. // IN vntSid - SID as an array of bytes (this is the form received from ADSI)
  192. //
  193. // Return
  194. // The RID value if successful or zero if not.
  195. //------------------------------------------------------------------------------
  196. DWORD __stdcall GetRidFromVariantSid(const _variant_t& vntSid)
  197. {
  198. DWORD dwRid = 0;
  199. if ((V_VT(&vntSid) == (VT_ARRAY|VT_UI1)) && vntSid.parray)
  200. {
  201. PSID pSid = (PSID)vntSid.parray->pvData;
  202. if (IsValidSid(pSid))
  203. {
  204. PUCHAR puch = GetSidSubAuthorityCount(pSid);
  205. DWORD dwCount = static_cast<DWORD>(*puch);
  206. DWORD dwIndex = dwCount - 1;
  207. PDWORD pdw = GetSidSubAuthority(pSid, dwIndex);
  208. dwRid = *pdw;
  209. }
  210. }
  211. return dwRid;
  212. }