Source code of Windows XP (NT5)
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.

296 lines
7.6 KiB

  1. /******************************************************************************
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. Accounts.cpp
  5. Abstract:
  6. This file contains the implementation of the CPCHAccounts class,
  7. which is used to represent and manage user/group accounts.
  8. Revision History:
  9. Davide Massarenti (Dmassare) 03/26/2000
  10. created
  11. ******************************************************************************/
  12. #include "StdAfx.h"
  13. #include <Lmapibuf.h>
  14. #include <Lmaccess.h>
  15. #include <Lmerr.h>
  16. ////////////////////////////////////////////////////////////////////////////////
  17. CPCHAccounts::CPCHAccounts()
  18. {
  19. }
  20. CPCHAccounts::~CPCHAccounts()
  21. {
  22. CleanUp();
  23. }
  24. void CPCHAccounts::CleanUp()
  25. {
  26. }
  27. ////////////////////////////////////////////////////////////////////////////////
  28. HRESULT CPCHAccounts::CreateGroup( /*[in]*/ LPCWSTR szGroup ,
  29. /*[in]*/ LPCWSTR szComment )
  30. {
  31. __HCP_FUNC_ENTRY( "CPCHAccounts::CreateGroup" );
  32. HRESULT hr;
  33. NET_API_STATUS dwRes;
  34. LOCALGROUP_INFO_1 group; ::ZeroMemory( &group, sizeof(group) );
  35. group.lgrpi1_name = (LPWSTR)szGroup;
  36. group.lgrpi1_comment = (LPWSTR)szComment;
  37. dwRes = ::NetLocalGroupAdd( NULL, 1, (LPBYTE)&group, NULL );
  38. if(dwRes != NERR_Success &&
  39. dwRes != NERR_GroupExists &&
  40. dwRes != ERROR_ALIAS_EXISTS )
  41. {
  42. __MPC_SET_WIN32_ERROR_AND_EXIT(hr, dwRes);
  43. }
  44. hr = S_OK;
  45. __HCP_FUNC_CLEANUP;
  46. __HCP_FUNC_EXIT(hr);
  47. }
  48. HRESULT CPCHAccounts::CreateUser( /*[in]*/ LPCWSTR szUser ,
  49. /*[in]*/ LPCWSTR szPassword ,
  50. /*[in]*/ LPCWSTR szFullName ,
  51. /*[in]*/ LPCWSTR szComment )
  52. {
  53. __HCP_FUNC_ENTRY( "CPCHAccounts::CreateUser" );
  54. HRESULT hr;
  55. NET_API_STATUS dwRes;
  56. MPC::wstring strGroupName;
  57. LOCALGROUP_MEMBERS_INFO_3 group; ::ZeroMemory( &group, sizeof(group) );
  58. USER_INFO_2 user; ::ZeroMemory( &user , sizeof(user ) );
  59. LPUSER_INFO_10 userExisting = NULL;
  60. __MPC_EXIT_IF_METHOD_FAILS(hr, MPC::LocalizeString( IDS_HELPSVC_GROUPNAME, strGroupName ));
  61. user.usri2_name = (LPWSTR)szUser;
  62. user.usri2_password = (LPWSTR)szPassword;
  63. // user.usri2_password_age
  64. user.usri2_priv = USER_PRIV_USER;
  65. // user.usri2_home_dir
  66. user.usri2_comment = (LPWSTR)szComment;
  67. user.usri2_flags = UF_SCRIPT | UF_PASSWD_CANT_CHANGE | UF_DONT_EXPIRE_PASSWD;
  68. // user.usri2_script_path
  69. // user.usri2_auth_flags
  70. user.usri2_full_name = (LPWSTR)szFullName;
  71. // user.usri2_usr_comment
  72. // user.usri2_parms
  73. // user.usri2_workstations
  74. // user.usri2_last_logon
  75. // user.usri2_last_logoff
  76. user.usri2_acct_expires = TIMEQ_FOREVER;
  77. user.usri2_max_storage = USER_MAXSTORAGE_UNLIMITED;
  78. // user.usri2_units_per_week
  79. // user.usri2_logon_hours
  80. // user.usri2_bad_pw_count
  81. // user.usri2_num_logons
  82. // user.usri2_logon_server
  83. // user.usri2_country_code
  84. // user.usri2_code_page
  85. dwRes = ::NetUserAdd( NULL, 2, (LPBYTE)&user, NULL );
  86. //
  87. // If the user already exists but its "FullName" field matches the requested one, it's the same user, so simply set the password.
  88. //
  89. if(dwRes == NERR_UserExists)
  90. {
  91. if(::NetUserGetInfo( NULL, szUser, 10, (LPBYTE*)&userExisting ) == NERR_Success)
  92. {
  93. if(!MPC::StrICmp( userExisting->usri10_full_name, szFullName ))
  94. {
  95. USER_INFO_1003 userChgPwd; ::ZeroMemory( &userChgPwd, sizeof(userChgPwd) );
  96. userChgPwd.usri1003_password = (LPWSTR)szPassword;
  97. dwRes = ::NetUserSetInfo( NULL, szUser, 1003, (LPBYTE)&userChgPwd, NULL );
  98. }
  99. }
  100. }
  101. if(dwRes != NERR_Success)
  102. {
  103. __MPC_SET_WIN32_ERROR_AND_EXIT(hr, dwRes);
  104. }
  105. ////////////////////////////////////////
  106. group.lgrmi3_domainandname = (LPWSTR)szUser;
  107. dwRes = ::NetLocalGroupAddMembers( NULL, strGroupName.c_str(), 3, (LPBYTE)&group, 1 );
  108. if(dwRes != NERR_Success &&
  109. dwRes != ERROR_MEMBER_IN_ALIAS )
  110. {
  111. __MPC_SET_WIN32_ERROR_AND_EXIT(hr, dwRes);
  112. }
  113. __MPC_EXIT_IF_METHOD_FAILS(hr, CPCHSecurityDescriptorDirect::AddPrivilege( szUser, SE_BATCH_LOGON_NAME ));
  114. __MPC_EXIT_IF_METHOD_FAILS(hr, CPCHSecurityDescriptorDirect::AddPrivilege( szUser, SE_DENY_NETWORK_LOGON_NAME ));
  115. __MPC_EXIT_IF_METHOD_FAILS(hr, CPCHSecurityDescriptorDirect::AddPrivilege( szUser, SE_DENY_INTERACTIVE_LOGON_NAME ));
  116. hr = S_OK;
  117. __HCP_FUNC_CLEANUP;
  118. if(userExisting) ::NetApiBufferFree( userExisting );
  119. __HCP_FUNC_EXIT(hr);
  120. }
  121. HRESULT CPCHAccounts::DeleteGroup( /*[in]*/ LPCWSTR szGroup )
  122. {
  123. __HCP_FUNC_ENTRY( "CPCHAccounts::DeleteGroup" );
  124. HRESULT hr;
  125. NET_API_STATUS dwRes;
  126. dwRes = ::NetLocalGroupDel( NULL, szGroup );
  127. if(dwRes != NERR_Success )
  128. {
  129. __MPC_SET_WIN32_ERROR_AND_EXIT(hr, dwRes);
  130. }
  131. hr = S_OK;
  132. __HCP_FUNC_CLEANUP;
  133. __HCP_FUNC_EXIT(hr);
  134. }
  135. HRESULT CPCHAccounts::DeleteUser( /*[in]*/ LPCWSTR szUser )
  136. {
  137. __HCP_FUNC_ENTRY( "CPCHAccounts::DeleteUser" );
  138. HRESULT hr;
  139. NET_API_STATUS dwRes;
  140. dwRes = ::NetUserDel( NULL, szUser );
  141. if(dwRes != NERR_Success )
  142. {
  143. __MPC_SET_WIN32_ERROR_AND_EXIT(hr, dwRes);
  144. }
  145. hr = S_OK;
  146. __HCP_FUNC_CLEANUP;
  147. __HCP_FUNC_EXIT(hr);
  148. }
  149. HRESULT CPCHAccounts::ChangeUserStatus( /*[in]*/ LPCWSTR szUser ,
  150. /*[in]*/ bool fEnable )
  151. {
  152. __HCP_FUNC_ENTRY( "CPCHAccounts::ChangeUserStatus" );
  153. HRESULT hr;
  154. NET_API_STATUS dwRes;
  155. LPUSER_INFO_2 pinfo2 = NULL;
  156. USER_INFO_1008 info1008;
  157. dwRes = ::NetUserGetInfo( NULL, szUser, 2, (LPBYTE*)&pinfo2 );
  158. if(dwRes != NERR_Success)
  159. {
  160. __MPC_SET_WIN32_ERROR_AND_EXIT(hr, dwRes);
  161. }
  162. if(pinfo2)
  163. {
  164. info1008.usri1008_flags = pinfo2->usri2_flags;
  165. if(fEnable) info1008.usri1008_flags &= ~UF_ACCOUNTDISABLE;
  166. else info1008.usri1008_flags |= UF_ACCOUNTDISABLE;
  167. dwRes = ::NetUserSetInfo( NULL, szUser, 1008, (LPBYTE)&info1008, NULL );
  168. if(dwRes != NERR_Success)
  169. {
  170. __MPC_SET_WIN32_ERROR_AND_EXIT(hr, dwRes);
  171. }
  172. }
  173. hr = S_OK;
  174. __HCP_FUNC_CLEANUP;
  175. if(pinfo2) ::NetApiBufferFree( pinfo2 );
  176. __HCP_FUNC_EXIT(hr);
  177. }
  178. HRESULT CPCHAccounts::LogonUser( /*[in ]*/ LPCWSTR szUser ,
  179. /*[in ]*/ LPCWSTR szPassword ,
  180. /*[out]*/ HANDLE& hToken )
  181. {
  182. __HCP_FUNC_ENTRY( "CPCHAccounts::LogonUser" );
  183. HRESULT hr;
  184. GUID guidPassword;
  185. WCHAR rgPassword[128];
  186. LPOLESTR szGuid = NULL;
  187. //
  188. // If no password is supplied, generate a new password on the fly and change the old one with it.
  189. //
  190. if(szPassword == NULL)
  191. {
  192. USER_INFO_1003 userChgPwd; ::ZeroMemory( &userChgPwd, sizeof(userChgPwd) );
  193. DWORD dwRes;
  194. //
  195. // This generates a random password.
  196. //
  197. __MPC_EXIT_IF_METHOD_FAILS(hr, ::CoCreateGuid( &guidPassword ));
  198. (void)::StringFromGUID2( guidPassword, rgPassword, MAXSTRLEN(rgPassword) );
  199. userChgPwd.usri1003_password = rgPassword;
  200. dwRes = ::NetUserSetInfo( NULL, szUser, 1003, (LPBYTE)&userChgPwd, NULL );
  201. if(dwRes != NERR_Success)
  202. {
  203. __MPC_SET_WIN32_ERROR_AND_EXIT(hr, dwRes);
  204. }
  205. szPassword = rgPassword;
  206. }
  207. __MPC_EXIT_IF_CALL_RETURNS_FALSE(hr, ::LogonUserW( (LPWSTR)szUser, L".", (LPWSTR)szPassword, LOGON32_LOGON_BATCH, LOGON32_PROVIDER_DEFAULT, &hToken ));
  208. hr = S_OK;
  209. __HCP_FUNC_CLEANUP;
  210. __HCP_FUNC_EXIT(hr);
  211. }