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.

592 lines
13 KiB

  1. //---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1995
  5. //
  6. // File: cuar.cxx
  7. //
  8. // Contents: Account Restrictions Propset for the User object
  9. //
  10. // History: 11-1-95 krishnag Created.
  11. // 8-5-96 ramv Modified to be consistent with spec
  12. //
  13. // PROPERTY_RW(AccountDisabled, boolean, 1) I
  14. // PROPERTY_RW(AccountExpirationDate, DATE, 2) I
  15. // PROPERTY_RW(GraceLoginsAllowed, long, 5) NI
  16. // PROPERTY_RW(GraceLoginsRemaining, long, 6) NI
  17. // PROPERTY_RW(IsAccountLocked, boolean, 7) I
  18. // PROPERTY_RW(IsAdmin, boolean, 8) I
  19. // PROPERTY_RW(LoginHours, VARIANT, 9) I
  20. // PROPERTY_RW(LoginWorkstations, VARIANT, 10) I
  21. // PROPERTY_RW(MaxLogins, long, 11) I
  22. // PROPERTY_RW(MaxStorage, long, 12) I
  23. // PROPERTY_RW(PasswordExpirationDate, DATE, 13) I
  24. // PROPERTY_RW(PasswordRequired, boolean, 14) I
  25. // PROPERTY_RW(RequireUniquePassword,boolean, 15) I
  26. //
  27. //
  28. //----------------------------------------------------------------------------
  29. #include "nds.hxx"
  30. #pragma hdrstop
  31. // Class CNDSUser
  32. STDMETHODIMP
  33. CNDSUser::get_AccountDisabled(THIS_ VARIANT_BOOL FAR* retval)
  34. {
  35. GET_PROPERTY_VARIANT_BOOL((IADsUser *)this, AccountDisabled);
  36. }
  37. STDMETHODIMP
  38. CNDSUser::put_AccountDisabled(THIS_ VARIANT_BOOL fAccountDisabled)
  39. {
  40. PUT_PROPERTY_VARIANT_BOOL((IADsUser *)this, AccountDisabled);
  41. }
  42. STDMETHODIMP
  43. CNDSUser::get_AccountExpirationDate(THIS_ DATE FAR* retval)
  44. {
  45. GET_PROPERTY_DATE((IADsUser *)this, AccountExpirationDate);
  46. }
  47. STDMETHODIMP
  48. CNDSUser::put_AccountExpirationDate(THIS_ DATE daAccountExpirationDate)
  49. {
  50. PUT_PROPERTY_DATE((IADsUser *)this, AccountExpirationDate);
  51. }
  52. STDMETHODIMP
  53. CNDSUser::get_GraceLoginsAllowed(THIS_ long FAR* retval)
  54. {
  55. GET_PROPERTY_LONG((IADsUser *)this, GraceLoginsAllowed);
  56. }
  57. STDMETHODIMP
  58. CNDSUser::put_GraceLoginsAllowed(THIS_ long lGraceLoginsAllowed)
  59. {
  60. PUT_PROPERTY_LONG((IADsUser *)this, GraceLoginsAllowed);
  61. }
  62. STDMETHODIMP
  63. CNDSUser::get_GraceLoginsRemaining(THIS_ long FAR* retval)
  64. {
  65. GET_PROPERTY_LONG((IADsUser *)this, GraceLoginsRemaining);
  66. }
  67. STDMETHODIMP
  68. CNDSUser::put_GraceLoginsRemaining(THIS_ long lGraceLoginsRemaining)
  69. {
  70. PUT_PROPERTY_LONG((IADsUser *)this, GraceLoginsRemaining);
  71. }
  72. STDMETHODIMP
  73. CNDSUser::get_IsAccountLocked(THIS_ VARIANT_BOOL FAR* retval)
  74. {
  75. HRESULT hr;
  76. hr = get_VARIANT_BOOL_Property(
  77. (IADs *)this,
  78. TEXT("Locked By Intruder"),
  79. retval
  80. );
  81. RRETURN_EXP_IF_ERR(hr);
  82. }
  83. STDMETHODIMP
  84. CNDSUser::put_IsAccountLocked(THIS_ VARIANT_BOOL fIsAccountLocked)
  85. {
  86. HRESULT hr;
  87. hr = put_VARIANT_BOOL_Property(
  88. (IADs *)this,
  89. TEXT("Locked By Intruder"),
  90. fIsAccountLocked
  91. );
  92. RRETURN_EXP_IF_ERR(hr);
  93. }
  94. STDMETHODIMP
  95. CNDSUser::get_LoginHours(THIS_ VARIANT FAR* retval)
  96. {
  97. GET_PROPERTY_VARIANT((IADsUser *)this,LoginHours);
  98. }
  99. STDMETHODIMP
  100. CNDSUser::put_LoginHours(THIS_ VARIANT vLoginHours)
  101. {
  102. PUT_PROPERTY_VARIANT((IADsUser *)this,LoginHours);
  103. }
  104. STDMETHODIMP
  105. CNDSUser::get_LoginWorkstations(THIS_ VARIANT FAR* retval)
  106. {
  107. GET_PROPERTY_VARIANT((IADsUser *)this,LoginWorkstations);
  108. }
  109. STDMETHODIMP
  110. CNDSUser::put_LoginWorkstations(THIS_ VARIANT vLoginWorkstations)
  111. {
  112. PUT_PROPERTY_VARIANT((IADsUser *)this,LoginWorkstations);
  113. }
  114. STDMETHODIMP
  115. CNDSUser::get_MaxLogins(THIS_ long FAR* retval)
  116. {
  117. GET_PROPERTY_LONG((IADsUser *)this, MaxLogins);
  118. }
  119. STDMETHODIMP
  120. CNDSUser::put_MaxLogins(THIS_ long lMaxLogins)
  121. {
  122. PUT_PROPERTY_LONG((IADsUser *)this, MaxLogins);
  123. }
  124. STDMETHODIMP
  125. CNDSUser::get_MaxStorage(THIS_ long FAR* retval)
  126. {
  127. GET_PROPERTY_LONG((IADsUser *)this, MaxStorage);
  128. }
  129. STDMETHODIMP
  130. CNDSUser::put_MaxStorage(THIS_ long lMaxStorage)
  131. {
  132. PUT_PROPERTY_LONG((IADsUser *)this, MaxStorage);
  133. }
  134. STDMETHODIMP
  135. CNDSUser::get_PasswordExpirationDate(THIS_ DATE FAR* retval)
  136. {
  137. GET_PROPERTY_DATE((IADsUser *)this, PasswordExpirationDate);
  138. }
  139. STDMETHODIMP
  140. CNDSUser::put_PasswordExpirationDate(THIS_ DATE daPasswordExpirationDate)
  141. {
  142. PUT_PROPERTY_DATE((IADsUser *)this, PasswordExpirationDate);
  143. }
  144. STDMETHODIMP
  145. CNDSUser::get_PasswordRequired(THIS_ VARIANT_BOOL FAR* retval)
  146. {
  147. GET_PROPERTY_VARIANT_BOOL((IADsUser *)this, PasswordRequired);
  148. }
  149. STDMETHODIMP
  150. CNDSUser::put_PasswordRequired(THIS_ VARIANT_BOOL fPasswordRequired)
  151. {
  152. PUT_PROPERTY_VARIANT_BOOL((IADsUser *)this, PasswordRequired);
  153. }
  154. STDMETHODIMP
  155. CNDSUser::get_PasswordMinimumLength(THIS_ LONG FAR* retval)
  156. {
  157. GET_PROPERTY_LONG((IADsUser *)this, PasswordMinimumLength);
  158. }
  159. STDMETHODIMP
  160. CNDSUser::put_PasswordMinimumLength(THIS_ LONG lPasswordMinimumLength)
  161. {
  162. PUT_PROPERTY_LONG((IADsUser *)this, PasswordMinimumLength);
  163. }
  164. STDMETHODIMP
  165. CNDSUser::get_RequireUniquePassword(THIS_ VARIANT_BOOL FAR* retval)
  166. {
  167. GET_PROPERTY_VARIANT_BOOL((IADsUser *)this, RequireUniquePassword);
  168. }
  169. STDMETHODIMP
  170. CNDSUser::put_RequireUniquePassword(THIS_ VARIANT_BOOL fRequireUniquePassword)
  171. {
  172. PUT_PROPERTY_VARIANT_BOOL((IADsUser *)this, RequireUniquePassword);
  173. }
  174. STDMETHODIMP
  175. CNDSUser::ChangePassword(
  176. THIS_ BSTR bstrOldPassword,
  177. BSTR bstrNewPassword
  178. )
  179. {
  180. HANDLE hObject = NULL;
  181. LPWSTR pszNDSPathName = NULL;
  182. DWORD dwStatus;
  183. HRESULT hr = S_OK;
  184. BSTR bstrADsPath = NULL;
  185. hr = _pADs->get_ADsPath(
  186. &bstrADsPath
  187. );
  188. BAIL_ON_FAILURE(hr);
  189. hr = BuildNDSPathFromADsPath(
  190. bstrADsPath,
  191. &pszNDSPathName
  192. );
  193. BAIL_ON_FAILURE(hr);
  194. dwStatus = ADsNwNdsOpenObject(
  195. pszNDSPathName,
  196. _Credentials,
  197. &hObject,
  198. NULL,
  199. NULL,
  200. NULL,
  201. NULL
  202. );
  203. CHECK_AND_SET_EXTENDED_ERROR(dwStatus, hr);
  204. dwStatus = NwNdsChangeUserPassword(
  205. hObject,
  206. bstrOldPassword,
  207. bstrNewPassword
  208. );
  209. CHECK_AND_SET_EXTENDED_ERROR(dwStatus, hr);
  210. error:
  211. if (hObject) {
  212. dwStatus = NwNdsCloseObject(hObject);
  213. }
  214. if (bstrADsPath) {
  215. ADsFreeString(bstrADsPath);
  216. }
  217. if (pszNDSPathName) {
  218. FreeADsStr(pszNDSPathName);
  219. }
  220. RRETURN_EXP_IF_ERR(hr);
  221. }
  222. HRESULT
  223. NWApiSetUserPassword(
  224. NWCONN_HANDLE hConn,
  225. DWORD dwUserObjID,
  226. LPWSTR pszUserName,
  227. LPWSTR pszPassword
  228. );
  229. HRESULT
  230. BuildUserNameFromADsPath(
  231. LPWSTR pszADsPath,
  232. LPWSTR szUserName
  233. );
  234. #define NW_MAX_PASSWORD_LEN 256
  235. STDMETHODIMP
  236. CNDSUser::SetPassword(THIS_ BSTR NewPassword)
  237. {
  238. HANDLE hObject = NULL;
  239. LPWSTR pszNDSPathName = NULL;
  240. DWORD dwStatus;
  241. HRESULT hr = S_OK;
  242. BSTR bstrADsPath = NULL;
  243. WCHAR szUserName[NDS_MAX_NAME_CHARS+1];
  244. WCHAR szPasswordCopy[NW_MAX_PASSWORD_LEN + 1];
  245. DWORD dwObjID;
  246. NWCONN_HANDLE hConn = NULL;
  247. wcscpy(szPasswordCopy, NewPassword);
  248. hr = ChangePassword(L"", szPasswordCopy);
  249. if (!FAILED(hr)) {
  250. return hr;
  251. }
  252. hr = _pADs->get_ADsPath(
  253. &bstrADsPath
  254. );
  255. BAIL_ON_FAILURE(hr);
  256. hr = BuildNDSPathFromADsPath(
  257. bstrADsPath,
  258. &pszNDSPathName
  259. );
  260. BAIL_ON_FAILURE(hr);
  261. hr = BuildUserNameFromADsPath(
  262. bstrADsPath,
  263. szUserName
  264. );
  265. BAIL_ON_FAILURE(hr);
  266. dwStatus = ADsNwNdsOpenObject(
  267. pszNDSPathName,
  268. _Credentials,
  269. &hObject,
  270. NULL,
  271. NULL,
  272. NULL,
  273. NULL
  274. );
  275. CHECK_AND_SET_EXTENDED_ERROR(dwStatus, hr);
  276. dwObjID = NwNdsGetObjectId(hObject);
  277. hConn = NwNdsObjectHandleToConnHandle(hObject);
  278. if (hConn == NULL) {
  279. hr = HRESULT_FROM_WIN32(GetLastError());
  280. BAIL_ON_FAILURE(hr);
  281. }
  282. hr = NWApiSetUserPassword(
  283. hConn,
  284. dwObjID,
  285. szUserName,
  286. szPasswordCopy
  287. );
  288. NwNdsConnHandleFree(hConn);
  289. error:
  290. if (hObject) {
  291. dwStatus = NwNdsCloseObject(hObject);
  292. }
  293. if (bstrADsPath) {
  294. ADsFreeString(bstrADsPath);
  295. }
  296. if (pszNDSPathName) {
  297. FreeADsStr(pszNDSPathName);
  298. }
  299. RRETURN_EXP_IF_ERR(hr);
  300. }
  301. HRESULT
  302. NWApiSetUserPassword(
  303. NWCONN_HANDLE hConn,
  304. DWORD dwUserObjID,
  305. LPWSTR pszUserName,
  306. LPWSTR pszPassword
  307. )
  308. {
  309. CHAR szOemUserName[NDS_MAX_NAME_CHARS + 1];
  310. CHAR szOemPassword[NW_MAX_PASSWORD_LEN + 1];
  311. CHAR Buffer[128];
  312. DWORD rc, err = 0;
  313. HRESULT hr = S_OK;
  314. NTSTATUS NtStatus;
  315. UCHAR ChallengeKey[8];
  316. UCHAR ucMoreFlag;
  317. UCHAR ucPropFlag;
  318. if ( !pszUserName ||
  319. !pszPassword ) {
  320. hr = E_INVALIDARG ;
  321. BAIL_ON_FAILURE(hr);
  322. }
  323. //
  324. // Convert UNICODE into OEM representation required by NW APIs.
  325. //
  326. rc = WideCharToMultiByte(
  327. CP_OEMCP,
  328. 0,
  329. pszUserName,
  330. -1,
  331. szOemUserName,
  332. sizeof(szOemUserName),
  333. NULL,
  334. NULL) ;
  335. if (rc == 0) {
  336. err = GetLastError() ;
  337. hr = HRESULT_FROM_WIN32(err);
  338. BAIL_ON_FAILURE(hr);
  339. }
  340. _wcsupr(pszPassword) ;
  341. rc = WideCharToMultiByte(
  342. CP_OEMCP,
  343. 0,
  344. pszPassword,
  345. -1,
  346. szOemPassword,
  347. sizeof(szOemPassword),
  348. NULL,
  349. NULL) ;
  350. if (rc == 0) {
  351. err = GetLastError() ;
  352. hr = HRESULT_FROM_WIN32(err);
  353. BAIL_ON_FAILURE(hr);
  354. }
  355. //
  356. // Get challenge key.
  357. //
  358. NtStatus = NWPGetChallengeKey(
  359. hConn,
  360. ChallengeKey
  361. );
  362. if (!NT_SUCCESS(NtStatus)) {
  363. err = ERROR_UNEXP_NET_ERR ;
  364. }
  365. if (!err) {
  366. //
  367. // The old password and object ID make up the 17-byte Vold. This is used
  368. // later to form the 17-byte Vc for changing password on the server.
  369. //
  370. UCHAR ValidationKey[8];
  371. UCHAR NewKeyedPassword[17];
  372. EncryptChangePassword(
  373. (PUCHAR) "",
  374. (PUCHAR) szOemPassword,
  375. dwUserObjID,
  376. ChallengeKey,
  377. ValidationKey,
  378. NewKeyedPassword
  379. );
  380. NtStatus = NWPChangeObjectPasswordEncrypted(
  381. hConn,
  382. szOemUserName,
  383. OT_USER,
  384. ValidationKey,
  385. NewKeyedPassword
  386. );
  387. if (!NT_SUCCESS(NtStatus)) {
  388. err = ERROR_NOT_SUPPORTED;
  389. }
  390. }
  391. //
  392. // Return.
  393. //
  394. hr = HRESULT_FROM_WIN32(err);
  395. error:
  396. RRETURN(hr);
  397. }
  398. //+---------------------------------------------------------------------------
  399. // Function: Extract user name from ADs path
  400. //
  401. // Synopsis: This call attempts to extract a username from a NDS style
  402. // ADs path. The last component is assumed to be the username.
  403. //
  404. // Arguments: [LPTSTR szBuffer]
  405. // [LPVOID *ppObject]
  406. //
  407. // Returns: HRESULT
  408. //
  409. // Modifies: -
  410. //
  411. // History: 11-3-95 krishnag Created.
  412. //
  413. //----------------------------------------------------------------------------
  414. HRESULT
  415. BuildUserNameFromADsPath(
  416. LPWSTR pszADsPath,
  417. LPWSTR szUserName
  418. )
  419. {
  420. OBJECTINFO ObjectInfo;
  421. POBJECTINFO pObjectInfo = &ObjectInfo;
  422. LPWSTR pszSrcComp = NULL;
  423. LPWSTR pszSrcValue = NULL;
  424. DWORD dwNumComponents = 0;
  425. HRESULT hr = S_OK;
  426. CLexer Lexer(pszADsPath);
  427. memset(pObjectInfo, 0, sizeof(OBJECTINFO));
  428. hr = ADsObject(&Lexer, pObjectInfo);
  429. BAIL_ON_FAILURE(hr);
  430. dwNumComponents = pObjectInfo->NumComponents ;
  431. if (dwNumComponents) {
  432. //
  433. // take the last value
  434. //
  435. pszSrcComp = pObjectInfo->ComponentArray[dwNumComponents-1].szComponent;
  436. pszSrcValue = pObjectInfo->ComponentArray[dwNumComponents-1].szValue;
  437. if (pszSrcComp && pszSrcValue) {
  438. //
  439. // You have a CN = "MyUserName"
  440. // Then copy the szValue as your UserName
  441. //
  442. wcscpy(szUserName, pszSrcValue);
  443. }
  444. else if (pszSrcComp) {
  445. //
  446. // Simply MyUserName. For example: path
  447. // is "NDS://marsdev/mars/dev/MyUserName)"
  448. //
  449. wcscpy(szUserName, pszSrcComp);
  450. }
  451. }
  452. error:
  453. //
  454. // Clean up the parser object
  455. //
  456. FreeObjectInfo(pObjectInfo);
  457. RRETURN(hr);
  458. }