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.

332 lines
11 KiB

  1. // P3Users.cpp : Implementation of CP3Users
  2. #include "stdafx.h"
  3. #include "P3Admin.h"
  4. #include "P3Users.h"
  5. #include "P3UserEnum.h"
  6. #include "P3User.h"
  7. #include <mailbox.h>
  8. #include <AuthID.h>
  9. //////////////////////////////////////////////////////////////////////
  10. // Construction/Destruction
  11. //////////////////////////////////////////////////////////////////////
  12. CP3Users::CP3Users() :
  13. m_pIUnk(NULL), m_pAdminX(NULL), m_hfSearch(INVALID_HANDLE_VALUE)
  14. {
  15. ZeroMemory( m_sDomainName, sizeof(m_sDomainName));
  16. }
  17. CP3Users::~CP3Users()
  18. {
  19. if(INVALID_HANDLE_VALUE!=m_hfSearch)
  20. {
  21. FindClose(m_hfSearch);
  22. }
  23. if ( NULL != m_pIUnk )
  24. m_pIUnk->Release();
  25. }
  26. //////////////////////////////////////////////////////////////////////
  27. // IP3Users
  28. //////////////////////////////////////////////////////////////////////
  29. STDMETHODIMP CP3Users::get__NewEnum(IEnumVARIANT* *ppIEnumVARIANT)
  30. {
  31. if ( NULL == ppIEnumVARIANT ) return E_INVALIDARG;
  32. if ( NULL == m_pAdminX ) return E_POINTER;
  33. HRESULT hr = S_OK;
  34. LPUNKNOWN pIUnk;
  35. CComObject<CP3UserEnum>* p;
  36. *ppIEnumVARIANT = NULL;
  37. if SUCCEEDED( hr )
  38. {
  39. hr = CComObject<CP3UserEnum>::CreateInstance(&p); // Reference count still 0
  40. if SUCCEEDED( hr )
  41. {
  42. // Increment the reference count on the source object and pass it to the new enumerator
  43. hr = m_pIUnk->QueryInterface(IID_IUnknown, reinterpret_cast<LPVOID*>( &pIUnk ));
  44. if SUCCEEDED( hr )
  45. {
  46. hr = p->Init( pIUnk, m_pAdminX, m_sDomainName );
  47. if SUCCEEDED( hr )
  48. hr = p->QueryInterface( IID_IEnumVARIANT, reinterpret_cast<LPVOID*>( ppIEnumVARIANT ));
  49. }
  50. if FAILED( hr )
  51. delete p;
  52. }
  53. }
  54. return hr;
  55. }
  56. STDMETHODIMP CP3Users::get_Count(long *pVal)
  57. {
  58. if ( NULL == m_pAdminX ) return E_POINTER;
  59. return m_pAdminX->GetUserCount( m_sDomainName, pVal );
  60. }
  61. #define E_USERNOTFOUND 0x800708ad
  62. STDMETHODIMP CP3Users::get_Item(VARIANT vIndex, IP3User **ppIUser)
  63. {
  64. VARIANT *pv = &vIndex;
  65. if ( NULL == ppIUser ) return E_INVALIDARG;
  66. if ( (VT_VARIANT|VT_BYREF) == V_VT( pv ))
  67. pv = V_VARIANTREF( pv );
  68. if ( VT_BSTR != V_VT( pv ) && VT_I4 != V_VT( pv ))
  69. return E_INVALIDARG;
  70. if ( VT_BSTR == V_VT( pv ) && NULL == V_BSTR( pv ))
  71. return E_INVALIDARG;
  72. if ( NULL == m_pAdminX ) return E_POINTER;
  73. HRESULT hr;
  74. WCHAR sMailbox[POP3_MAX_ADDRESS_LENGTH];
  75. WCHAR sBuffer[POP3_MAX_PATH];
  76. CMailBox mailboxX;
  77. hr = m_pAdminX->MailboxSetRemote();
  78. // Find the requested item
  79. if ( VT_BSTR == V_VT( pv ))
  80. { // Find by Name
  81. if ( sizeof( sMailbox )/sizeof(WCHAR) > wcslen( V_BSTR( pv )) + wcslen( m_sDomainName ) + 1 )
  82. {
  83. wcscpy( sMailbox, V_BSTR( pv ));
  84. wcscat( sMailbox, L"@" );
  85. wcscat( sMailbox, m_sDomainName );
  86. if ( mailboxX.OpenMailBox( sMailbox ))
  87. mailboxX.CloseMailBox();
  88. else
  89. hr = E_USERNOTFOUND;
  90. if ( sizeof( sBuffer )/sizeof(WCHAR) > wcslen( V_BSTR( pv ) ))
  91. wcscpy( sBuffer, V_BSTR( pv ));
  92. else
  93. hr = E_UNEXPECTED;
  94. }
  95. }
  96. if ( VT_I4 == V_VT( pv ))
  97. { // Find by Index
  98. int iIndex = V_I4( pv );
  99. if ( iIndex < m_iCur )
  100. {
  101. hr = m_pAdminX->InitFindFirstUser( m_hfSearch, m_sDomainName, sBuffer, sizeof( sBuffer )/sizeof(WCHAR) );
  102. m_iCur = 1;
  103. }
  104. while ( (S_OK == hr) && (iIndex > m_iCur) )
  105. {
  106. hr = m_pAdminX->GetNextUser( m_hfSearch, m_sDomainName, sBuffer, sizeof( sBuffer )/sizeof(WCHAR) );
  107. m_iCur++;
  108. }
  109. if ( S_OK == hr )
  110. {
  111. if ( sizeof( sMailbox )/sizeof(WCHAR) > wcslen( sBuffer ) + wcslen( m_sDomainName ) + 1 )
  112. {
  113. wcscpy( sMailbox, sBuffer );
  114. wcscat( sMailbox, L"@" );
  115. wcscat( sMailbox, m_sDomainName );
  116. if ( mailboxX.OpenMailBox( sMailbox ))
  117. mailboxX.CloseMailBox();
  118. else
  119. hr = E_USERNOTFOUND;
  120. }
  121. }
  122. }
  123. m_pAdminX->MailboxResetRemote();
  124. // Wrap it with COM
  125. if SUCCEEDED( hr )
  126. {
  127. LPUNKNOWN pIUnk;
  128. CComObject<CP3User> *p;
  129. hr = CComObject<CP3User>::CreateInstance( &p ); // Reference count still 0
  130. if SUCCEEDED( hr )
  131. {
  132. hr = m_pIUnk->QueryInterface(IID_IUnknown, reinterpret_cast<LPVOID*>( &pIUnk ));
  133. if SUCCEEDED( hr )
  134. {
  135. hr = p->Init( pIUnk, m_pAdminX, m_sDomainName, sBuffer );
  136. if SUCCEEDED( hr )
  137. hr = p->QueryInterface(IID_IP3User, reinterpret_cast<void**>( ppIUser ));
  138. }
  139. if FAILED( hr )
  140. delete p; // Release
  141. }
  142. }
  143. return hr;
  144. }
  145. STDMETHODIMP CP3Users::Add(BSTR bstrUserName)
  146. {
  147. if ( NULL == m_pAdminX ) return E_POINTER;
  148. // Associate email address with user, if this fails the user does not exist
  149. // This will always fail in the MD5 case because we need a password! Thus the user must use the /createuser flag
  150. HRESULT hr;
  151. CComPtr<IAuthMethod> spIAuthMethod;
  152. WCHAR sEmailAddr[POP3_MAX_ADDRESS_LENGTH];
  153. _bstr_t _bstrEmailAddr;
  154. hr = m_pAdminX->GetCurrentAuthentication( &spIAuthMethod );
  155. if ( S_OK == hr )
  156. hr = m_pAdminX->BuildEmailAddr( m_sDomainName, bstrUserName, sEmailAddr, sizeof( sEmailAddr )/sizeof(WCHAR) );
  157. if ( S_OK == hr )
  158. {
  159. _bstrEmailAddr = sEmailAddr;
  160. hr = spIAuthMethod->AssociateEmailWithUser( _bstrEmailAddr );
  161. }
  162. if ( S_OK == hr )
  163. {
  164. hr = m_pAdminX->AddUser( m_sDomainName, bstrUserName );
  165. if ( S_OK != hr )
  166. { // Unassociate the user with the mailbox
  167. spIAuthMethod->UnassociateEmailWithUser( _bstrEmailAddr ); // Don't want to overwrite the error code
  168. }
  169. }
  170. if ( S_OK == hr ) // Create Quota SID File - won't revert from this operation
  171. {
  172. BSTR bstrAuthType = NULL;
  173. hr = spIAuthMethod->get_ID( &bstrAuthType );
  174. if ( S_OK == hr )
  175. {
  176. if ( 0 == _wcsicmp( bstrAuthType, SZ_AUTH_ID_DOMAIN_AD )) // In AD case use the UPN name instead of the SAM name
  177. hr = m_pAdminX->CreateQuotaSIDFile( m_sDomainName, bstrUserName, bstrAuthType, NULL, sEmailAddr );
  178. else if ( 0 == _wcsicmp( bstrAuthType, SZ_AUTH_ID_LOCAL_SAM ))
  179. hr = m_pAdminX->CreateQuotaSIDFile( m_sDomainName, bstrUserName, bstrAuthType, NULL, bstrUserName );
  180. SysFreeString( bstrAuthType );
  181. }
  182. }
  183. return hr;
  184. }
  185. STDMETHODIMP CP3Users::AddEx(BSTR bstrUserName, BSTR bstrPassword)
  186. {
  187. if ( NULL == bstrUserName ) return E_INVALIDARG;
  188. if ( NULL == bstrPassword ) return E_INVALIDARG;
  189. if ( NULL == m_pAdminX ) return E_POINTER;
  190. HRESULT hr;
  191. CComPtr<IAuthMethod> spIAuthMethod;
  192. WCHAR sEmailAddr[POP3_MAX_ADDRESS_LENGTH];
  193. _bstr_t _bstrAccount;
  194. _variant_t _vPassword;
  195. BSTR bstrAuthType = NULL;
  196. // Add to our store
  197. hr = m_pAdminX->AddUser( m_sDomainName, bstrUserName );
  198. if ( S_OK == hr ) // Add to the Authentication source
  199. {
  200. hr = m_pAdminX->GetCurrentAuthentication( &spIAuthMethod );
  201. if ( S_OK == hr )
  202. hr = spIAuthMethod->get_ID( &bstrAuthType );
  203. if ( S_OK == hr )
  204. hr = m_pAdminX->BuildEmailAddr( m_sDomainName, bstrUserName, sEmailAddr, sizeof( sEmailAddr )/sizeof(WCHAR) );
  205. if ( S_OK == hr )
  206. {
  207. _bstrAccount = sEmailAddr;
  208. _vPassword = bstrPassword;
  209. hr = spIAuthMethod->CreateUser( _bstrAccount, _vPassword );
  210. }
  211. if ( S_OK != hr ) // Failed let's revert the Add to our store
  212. m_pAdminX->RemoveUser( m_sDomainName, bstrUserName );
  213. }
  214. if ( S_OK == hr ) // Create Quota SID File
  215. {
  216. if ( 0 == _wcsicmp( bstrAuthType, SZ_AUTH_ID_DOMAIN_AD )) // In AD case use the UPN name instead of the SAM name
  217. hr = m_pAdminX->CreateQuotaSIDFile( m_sDomainName, bstrUserName, bstrAuthType, NULL, sEmailAddr );
  218. else if ( 0 == _wcsicmp( bstrAuthType, SZ_AUTH_ID_LOCAL_SAM ))
  219. hr = m_pAdminX->CreateQuotaSIDFile( m_sDomainName, bstrUserName, bstrAuthType, NULL, bstrUserName );
  220. }
  221. if ( NULL != bstrAuthType )
  222. SysFreeString( bstrAuthType );
  223. return hr;
  224. }
  225. STDMETHODIMP CP3Users::Remove(BSTR bstrUserName)
  226. {
  227. if ( NULL == m_pAdminX ) return E_POINTER;
  228. // Associate email address with user, if this fails the user does not exist
  229. // This will always fail in the MD5 case because we need a password! Thus the user must use the /createuser flag
  230. CComPtr<IAuthMethod> spIAuthMethod;
  231. WCHAR sEmailAddr[POP3_MAX_ADDRESS_LENGTH];
  232. _bstr_t _bstrEmailAddr;
  233. HRESULT hr = m_pAdminX->GetCurrentAuthentication( &spIAuthMethod );
  234. if ( S_OK == hr )
  235. hr = m_pAdminX->BuildEmailAddr( m_sDomainName, bstrUserName, sEmailAddr, sizeof( sEmailAddr )/sizeof(WCHAR) );
  236. if ( S_OK == hr )
  237. {
  238. _bstrEmailAddr = sEmailAddr;
  239. hr = spIAuthMethod->UnassociateEmailWithUser( _bstrEmailAddr );
  240. }
  241. if ( S_OK == hr )
  242. {
  243. hr = m_pAdminX->RemoveUser( m_sDomainName, bstrUserName );
  244. if ( S_OK != hr )
  245. { // Unassociate the user with the mailbox
  246. spIAuthMethod->AssociateEmailWithUser( _bstrEmailAddr ); // Don't want to overwrite the error code
  247. }
  248. }
  249. return hr;
  250. }
  251. STDMETHODIMP CP3Users::RemoveEx(BSTR bstrUserName)
  252. {
  253. if ( NULL == bstrUserName ) return E_INVALIDARG;
  254. if ( NULL == m_pAdminX ) return E_POINTER;
  255. HRESULT hr = m_pAdminX->RemoveUser( m_sDomainName, bstrUserName );
  256. if ( S_OK == hr )
  257. {
  258. CComPtr<IAuthMethod> spIAuthMethod;
  259. WCHAR sEmailAddr[POP3_MAX_ADDRESS_LENGTH];
  260. _bstr_t _bstrAccount;
  261. hr = m_pAdminX->GetCurrentAuthentication( &spIAuthMethod );
  262. if ( S_OK == hr )
  263. hr = m_pAdminX->BuildEmailAddr( m_sDomainName, bstrUserName, sEmailAddr, sizeof( sEmailAddr )/sizeof(WCHAR) );
  264. if ( S_OK == hr )
  265. {
  266. _bstrAccount = sEmailAddr;
  267. hr = spIAuthMethod->DeleteUser( _bstrAccount );
  268. if ( S_FALSE == hr )
  269. hr = S_OK;
  270. }
  271. }
  272. return hr;
  273. }
  274. //////////////////////////////////////////////////////////////////////
  275. // Implementation: public
  276. //////////////////////////////////////////////////////////////////////
  277. HRESULT CP3Users::Init(IUnknown *pIUnk, CP3AdminWorker *p, LPWSTR psDomainName )
  278. {
  279. if ( NULL == pIUnk ) return E_INVALIDARG;
  280. if ( NULL == p ) return E_INVALIDARG;
  281. if ( NULL == psDomainName ) return E_INVALIDARG;
  282. m_pIUnk = pIUnk;
  283. m_pAdminX = p;
  284. wcsncpy( m_sDomainName, psDomainName, sizeof(m_sDomainName)/sizeof(WCHAR)-1);
  285. return S_OK;
  286. }
  287. //////////////////////////////////////////////////////////////////////
  288. // Implementation: protected
  289. //////////////////////////////////////////////////////////////////////