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.

421 lines
10 KiB

  1. #include "stdafx.h"
  2. #include "Pop3Auth.h"
  3. #include "AuthLocalAccount.h"
  4. CAuthLocalAccount::CAuthLocalAccount()
  5. {
  6. m_bstrServerName=NULL;
  7. }
  8. CAuthLocalAccount::~CAuthLocalAccount()
  9. {
  10. if(m_bstrServerName!=NULL)
  11. {
  12. SysFreeString(m_bstrServerName);
  13. m_bstrServerName=NULL;
  14. }
  15. }
  16. STDMETHODIMP CAuthLocalAccount::Authenticate(/*[in]*/BSTR bstrUserName,/*[in]*/VARIANT vPassword)
  17. {
  18. WCHAR *pAt=NULL;
  19. if(vPassword.vt != VT_BSTR)
  20. {
  21. return E_INVALIDARG;
  22. }
  23. if(NULL==bstrUserName)
  24. {
  25. return E_POINTER;
  26. }
  27. HANDLE hToken;
  28. pAt=wcschr(bstrUserName, L'@');
  29. if(NULL!=pAt)
  30. {
  31. *pAt=0;
  32. }
  33. if( LogonUser(bstrUserName,
  34. LOCAL_DOMAIN,
  35. vPassword.bstrVal,
  36. LOGON32_LOGON_NETWORK,
  37. LOGON32_PROVIDER_DEFAULT,
  38. &hToken))
  39. {
  40. CloseHandle(hToken);
  41. return S_OK;
  42. }
  43. return E_FAIL;
  44. }
  45. STDMETHODIMP CAuthLocalAccount::get_Name(/*[out]*/BSTR *pVal)
  46. {
  47. WCHAR wszBuffer[MAX_PATH+1];
  48. if(NULL==pVal)
  49. {
  50. return E_POINTER;
  51. }
  52. if(LoadString(_Module.GetResourceInstance(), IDS_AUTH_LOCAL_ACCOUNT, wszBuffer, MAX_PATH))
  53. {
  54. *pVal=SysAllocString(wszBuffer);
  55. if(NULL==*pVal)
  56. {
  57. return E_OUTOFMEMORY;
  58. }
  59. else
  60. {
  61. return S_OK;
  62. }
  63. }
  64. else
  65. {
  66. return E_FAIL;
  67. }
  68. }
  69. STDMETHODIMP CAuthLocalAccount::get_ID(/*[out]*/BSTR *pVal)
  70. {
  71. if(NULL==pVal)
  72. {
  73. return E_POINTER;
  74. }
  75. *pVal=SysAllocString(SZ_AUTH_ID_LOCAL_SAM);
  76. if(NULL==*pVal)
  77. {
  78. return E_OUTOFMEMORY;
  79. }
  80. else
  81. {
  82. return S_OK;
  83. }
  84. }
  85. STDMETHODIMP CAuthLocalAccount::Get(/*[in]*/BSTR bstrName, /*[out]*/VARIANT *pVal)
  86. {
  87. return E_NOTIMPL;
  88. }
  89. STDMETHODIMP CAuthLocalAccount::Put(/*[in]*/BSTR bstrName, /*[in]*/VARIANT vVal)
  90. {
  91. if(NULL == bstrName)
  92. {
  93. return E_INVALIDARG;
  94. }
  95. if(0==wcscmp(bstrName,SZ_SERVER_NAME ))
  96. {
  97. if( (vVal.vt!=VT_BSTR) ||
  98. (vVal.bstrVal==NULL ) )
  99. {
  100. return E_INVALIDARG;
  101. }
  102. else
  103. {
  104. if(m_bstrServerName!=NULL)
  105. {
  106. SysFreeString(m_bstrServerName);
  107. m_bstrServerName=NULL;
  108. }
  109. m_bstrServerName = SysAllocString(vVal.bstrVal);
  110. if(NULL == m_bstrServerName)
  111. {
  112. return E_OUTOFMEMORY;
  113. }
  114. return S_OK;
  115. }
  116. }
  117. return S_FALSE;
  118. }
  119. STDMETHODIMP CAuthLocalAccount::CreateUser(/*[in]*/BSTR bstrUserName,/*[in]*/VARIANT vPassword)
  120. {
  121. DWORD dwRt;
  122. WCHAR *pAt=NULL;
  123. HRESULT hr=S_OK;
  124. if( NULL == bstrUserName )
  125. {
  126. return E_POINTER;
  127. }
  128. if( vPassword.vt!= VT_BSTR )
  129. {
  130. return E_INVALIDARG;
  131. }
  132. dwRt=CheckPop3UserGroup();
  133. if( NERR_Success != dwRt )
  134. {
  135. return HRESULT_FROM_WIN32(dwRt);
  136. }
  137. pAt=wcschr(bstrUserName, L'@');
  138. if(pAt)
  139. {
  140. *pAt=NULL;
  141. }
  142. if(wcslen(bstrUserName) > MAX_USER_NAME_LENGTH)
  143. {
  144. hr=HRESULT_FROM_WIN32(WSAENAMETOOLONG);
  145. }
  146. else
  147. {
  148. USER_INFO_1 UserInfoBuf;
  149. UserInfoBuf.usri1_name=bstrUserName;
  150. UserInfoBuf.usri1_password=vPassword.bstrVal;
  151. UserInfoBuf.usri1_priv=USER_PRIV_USER;
  152. UserInfoBuf.usri1_home_dir=NULL;
  153. UserInfoBuf.usri1_comment=NULL;
  154. UserInfoBuf.usri1_flags=UF_NORMAL_ACCOUNT;
  155. UserInfoBuf.usri1_script_path=NULL;
  156. dwRt=NetUserAdd(m_bstrServerName,
  157. 1,
  158. (LPBYTE)(&UserInfoBuf),
  159. NULL);
  160. if(NERR_Success==dwRt)
  161. {
  162. LOCALGROUP_MEMBERS_INFO_3 lgmInfo;
  163. lgmInfo.lgrmi3_domainandname=bstrUserName;
  164. dwRt=NetLocalGroupAddMembers(m_bstrServerName, WSZ_POP3_USERS_GROUP, 3, (LPBYTE)(&lgmInfo), 1);
  165. if(NERR_Success!=dwRt)
  166. { //Delete the account just created if can not add to the group
  167. NetUserDel(m_bstrServerName, bstrUserName);
  168. }
  169. }
  170. else
  171. {
  172. hr=HRESULT_FROM_WIN32(dwRt);
  173. }
  174. }
  175. if(pAt)
  176. {
  177. *pAt=L'@';
  178. }
  179. return hr;
  180. }
  181. STDMETHODIMP CAuthLocalAccount::DeleteUser(/*[in]*/BSTR bstrUserName)
  182. {
  183. DWORD dwRt;
  184. WCHAR *pAt=NULL;
  185. if( NULL == bstrUserName)
  186. {
  187. return E_POINTER;
  188. }
  189. pAt=wcschr(bstrUserName, L'@');
  190. if(pAt)
  191. {
  192. *pAt=NULL;
  193. }
  194. dwRt=NetUserDel(m_bstrServerName, bstrUserName);
  195. if(NERR_Success==dwRt)
  196. {
  197. return S_OK;
  198. }
  199. if(pAt)
  200. {
  201. *pAt=L'@';
  202. }
  203. return HRESULT_FROM_WIN32(dwRt);
  204. }
  205. STDMETHODIMP CAuthLocalAccount::ChangePassword(/*[in]*/BSTR bstrUserName,/*[in]*/VARIANT vNewPassword,/*[in]*/VARIANT vOldPassword)
  206. {
  207. DWORD dwRt;
  208. WCHAR *pAt=NULL;
  209. BOOL bServerName=FALSE;
  210. if( NULL == bstrUserName)
  211. {
  212. return E_POINTER;
  213. }
  214. if( vNewPassword.vt!= VT_BSTR )
  215. {
  216. return E_INVALIDARG;
  217. }
  218. USER_INFO_1 * pUserInfo=NULL;
  219. pAt=wcschr(bstrUserName, L'@');
  220. if(pAt)
  221. {
  222. *pAt=0;
  223. }
  224. dwRt=NetUserGetInfo(m_bstrServerName,
  225. bstrUserName,
  226. 1,
  227. ( LPBYTE *)&pUserInfo);
  228. if(NERR_Success==dwRt)
  229. {
  230. pUserInfo->usri1_password=vNewPassword.bstrVal;
  231. dwRt=NetUserSetInfo(m_bstrServerName,
  232. bstrUserName,
  233. 1,
  234. (LPBYTE)pUserInfo,
  235. NULL);
  236. pUserInfo->usri1_password=NULL;
  237. NetApiBufferFree(pUserInfo);
  238. }
  239. if(pAt)
  240. {
  241. *pAt=L'@';
  242. }
  243. if(NERR_Success==dwRt)
  244. {
  245. return S_OK;
  246. }
  247. return HRESULT_FROM_WIN32(dwRt);
  248. }
  249. //To check if the POP3 Users group exists
  250. //if not, create the group.
  251. //Return 0 if the group exists or is created
  252. //Return error code if failed to create the group
  253. DWORD CAuthLocalAccount::CheckPop3UserGroup()
  254. {
  255. LPBYTE pBuffer=NULL;
  256. DWORD dwRt;
  257. WCHAR wszBuffer[MAXCOMMENTSZ];
  258. dwRt=NetLocalGroupGetInfo(m_bstrServerName,
  259. WSZ_POP3_USERS_GROUP,
  260. 1,
  261. &pBuffer);
  262. if(NERR_Success == dwRt )
  263. {
  264. NetApiBufferFree(pBuffer);
  265. return NO_ERROR;
  266. }
  267. if(NERR_GroupNotFound == dwRt)
  268. {
  269. //Create the group
  270. //Load the comments to the group
  271. if(LoadString(_Module.GetResourceInstance(), IDS_AUTH_POP3_GROUP, wszBuffer, MAXCOMMENTSZ))
  272. {
  273. GROUP_INFO_1 GroupInfo={WSZ_POP3_USERS_GROUP, wszBuffer};
  274. dwRt=NetLocalGroupAdd(m_bstrServerName,
  275. 1,
  276. (LPBYTE)(&GroupInfo),
  277. NULL);
  278. if(NERR_Success != dwRt )
  279. {
  280. return dwRt;
  281. }
  282. //Now the group is created, set the local logon policy
  283. //So that members of the group can not log on interactively
  284. dwRt=SetLogonPolicy();
  285. if(0!=dwRt)
  286. {
  287. NetLocalGroupDel(m_bstrServerName, WSZ_POP3_USERS_GROUP );
  288. return dwRt;
  289. }
  290. }
  291. else
  292. {
  293. dwRt=GetLastError();
  294. }
  295. }
  296. return dwRt;
  297. }
  298. DWORD CAuthLocalAccount::SetLogonPolicy()
  299. {
  300. //First get the sid of the POP3 Users group
  301. char pSid[LSA_WIN_STANDARD_BUFFER_SIZE];
  302. DWORD dwSizeSid=LSA_WIN_STANDARD_BUFFER_SIZE;
  303. WCHAR wszDomainName[MAX_PATH];
  304. DWORD cbDomainName=sizeof(wszDomainName);
  305. SID_NAME_USE sidType=SidTypeGroup;
  306. if(!LookupAccountName(NULL,
  307. WSZ_POP3_USERS_GROUP,
  308. (PSID)pSid,
  309. &dwSizeSid,
  310. wszDomainName,
  311. &cbDomainName,
  312. &sidType))
  313. {
  314. return GetLastError();
  315. }
  316. //Then set the logon policy
  317. NTSTATUS Status;
  318. LSA_HANDLE PolicyHandle = NULL;
  319. LSA_OBJECT_ATTRIBUTES ObjectAttributes;
  320. ZeroMemory( &ObjectAttributes, sizeof( ObjectAttributes ) );
  321. Status = LsaOpenPolicy(NULL, &ObjectAttributes ,POLICY_WRITE|POLICY_LOOKUP_NAMES,&PolicyHandle);
  322. if ( ERROR_SUCCESS !=Status )
  323. {
  324. return Status;
  325. }
  326. LSA_UNICODE_STRING PrivilegeString;
  327. PrivilegeString.Length=wcslen(SE_DENY_INTERACTIVE_LOGON_NAME)*sizeof(WCHAR);//Count in bytes
  328. PrivilegeString.MaximumLength=PrivilegeString.Length+sizeof(WCHAR);//Plus the last \0
  329. PrivilegeString.Buffer=SE_DENY_INTERACTIVE_LOGON_NAME;
  330. Status=LsaAddAccountRights( PolicyHandle, // open policy handle
  331. (PSID)pSid, // target SID
  332. &PrivilegeString, // privileges
  333. 1); // privilege count
  334. LsaClose(PolicyHandle);
  335. return Status;
  336. }
  337. STDMETHODIMP CAuthLocalAccount::AssociateEmailWithUser(/*[in]*/BSTR bstrEmailAddr)
  338. {
  339. //Make sure the user account exist
  340. DWORD dwRt;
  341. WCHAR *pAt=NULL;
  342. if( NULL == bstrEmailAddr)
  343. {
  344. return E_POINTER;
  345. }
  346. USER_INFO_1 * pUserInfo=NULL;
  347. pAt=wcschr(bstrEmailAddr, L'@');
  348. if(pAt)
  349. {
  350. *pAt=0;
  351. }
  352. dwRt=NetUserGetInfo(m_bstrServerName,
  353. bstrEmailAddr,
  354. 1,
  355. ( LPBYTE *)&pUserInfo);
  356. if(pAt)
  357. {
  358. *pAt=L'@';
  359. }
  360. if(NERR_Success==dwRt)
  361. {
  362. NetApiBufferFree(pUserInfo);
  363. return S_OK;
  364. }
  365. return HRESULT_FROM_WIN32(dwRt);
  366. }
  367. STDMETHODIMP CAuthLocalAccount::UnassociateEmailWithUser(/*[in]*/BSTR bstrEmailAddr)
  368. {
  369. // Do the same as Associate: Make sure the account exists
  370. return AssociateEmailWithUser( bstrEmailAddr );
  371. }