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.

602 lines
14 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. if (wcslen(NewPassword) > NW_MAX_PASSWORD_LEN) {
  248. hr = E_INVALIDARG;
  249. BAIL_ON_FAILURE(hr);
  250. }
  251. wcscpy(szPasswordCopy, NewPassword);
  252. hr = ChangePassword(L"", szPasswordCopy);
  253. if (!FAILED(hr)) {
  254. SecureZeroMemory(szPasswordCopy, sizeof(szPasswordCopy));
  255. return hr;
  256. }
  257. hr = _pADs->get_ADsPath(
  258. &bstrADsPath
  259. );
  260. BAIL_ON_FAILURE(hr);
  261. hr = BuildNDSPathFromADsPath(
  262. bstrADsPath,
  263. &pszNDSPathName
  264. );
  265. BAIL_ON_FAILURE(hr);
  266. hr = BuildUserNameFromADsPath(
  267. bstrADsPath,
  268. szUserName
  269. );
  270. BAIL_ON_FAILURE(hr);
  271. dwStatus = ADsNwNdsOpenObject(
  272. pszNDSPathName,
  273. _Credentials,
  274. &hObject,
  275. NULL,
  276. NULL,
  277. NULL,
  278. NULL
  279. );
  280. CHECK_AND_SET_EXTENDED_ERROR(dwStatus, hr);
  281. dwObjID = NwNdsGetObjectId(hObject);
  282. hConn = NwNdsObjectHandleToConnHandle(hObject);
  283. if (hConn == NULL) {
  284. hr = HRESULT_FROM_WIN32(GetLastError());
  285. BAIL_ON_FAILURE(hr);
  286. }
  287. hr = NWApiSetUserPassword(
  288. hConn,
  289. dwObjID,
  290. szUserName,
  291. szPasswordCopy
  292. );
  293. NwNdsConnHandleFree(hConn);
  294. error:
  295. SecureZeroMemory(szPasswordCopy, sizeof(szPasswordCopy));
  296. if (hObject) {
  297. dwStatus = NwNdsCloseObject(hObject);
  298. }
  299. if (bstrADsPath) {
  300. ADsFreeString(bstrADsPath);
  301. }
  302. if (pszNDSPathName) {
  303. FreeADsStr(pszNDSPathName);
  304. }
  305. RRETURN_EXP_IF_ERR(hr);
  306. }
  307. HRESULT
  308. NWApiSetUserPassword(
  309. NWCONN_HANDLE hConn,
  310. DWORD dwUserObjID,
  311. LPWSTR pszUserName,
  312. LPWSTR pszPassword
  313. )
  314. {
  315. CHAR szOemUserName[NDS_MAX_NAME_CHARS + 1];
  316. CHAR szOemPassword[NW_MAX_PASSWORD_LEN + 1];
  317. CHAR Buffer[128];
  318. DWORD rc, err = 0;
  319. HRESULT hr = S_OK;
  320. NTSTATUS NtStatus;
  321. UCHAR ChallengeKey[8];
  322. UCHAR ucMoreFlag;
  323. UCHAR ucPropFlag;
  324. if ( !pszUserName ||
  325. !pszPassword ) {
  326. hr = E_INVALIDARG ;
  327. BAIL_ON_FAILURE(hr);
  328. }
  329. //
  330. // Convert UNICODE into OEM representation required by NW APIs.
  331. //
  332. rc = WideCharToMultiByte(
  333. CP_OEMCP,
  334. 0,
  335. pszUserName,
  336. -1,
  337. szOemUserName,
  338. sizeof(szOemUserName),
  339. NULL,
  340. NULL) ;
  341. if (rc == 0) {
  342. err = GetLastError() ;
  343. hr = HRESULT_FROM_WIN32(err);
  344. BAIL_ON_FAILURE(hr);
  345. }
  346. _wcsupr(pszPassword) ;
  347. rc = WideCharToMultiByte(
  348. CP_OEMCP,
  349. 0,
  350. pszPassword,
  351. -1,
  352. szOemPassword,
  353. sizeof(szOemPassword),
  354. NULL,
  355. NULL) ;
  356. if (rc == 0) {
  357. err = GetLastError() ;
  358. hr = HRESULT_FROM_WIN32(err);
  359. BAIL_ON_FAILURE(hr);
  360. }
  361. //
  362. // Get challenge key.
  363. //
  364. NtStatus = NWPGetChallengeKey(
  365. hConn,
  366. ChallengeKey
  367. );
  368. if (!NT_SUCCESS(NtStatus)) {
  369. err = ERROR_UNEXP_NET_ERR ;
  370. }
  371. if (!err) {
  372. //
  373. // The old password and object ID make up the 17-byte Vold. This is used
  374. // later to form the 17-byte Vc for changing password on the server.
  375. //
  376. UCHAR ValidationKey[8];
  377. UCHAR NewKeyedPassword[17];
  378. EncryptChangePassword(
  379. (PUCHAR) "",
  380. (PUCHAR) szOemPassword,
  381. dwUserObjID,
  382. ChallengeKey,
  383. ValidationKey,
  384. NewKeyedPassword
  385. );
  386. NtStatus = NWPChangeObjectPasswordEncrypted(
  387. hConn,
  388. szOemUserName,
  389. OT_USER,
  390. ValidationKey,
  391. NewKeyedPassword
  392. );
  393. if (!NT_SUCCESS(NtStatus)) {
  394. err = ERROR_NOT_SUPPORTED;
  395. }
  396. SecureZeroMemory(ValidationKey, sizeof(ValidationKey));
  397. SecureZeroMemory(NewKeyedPassword, sizeof(NewKeyedPassword));
  398. }
  399. //
  400. // Return.
  401. //
  402. hr = HRESULT_FROM_WIN32(err);
  403. error:
  404. SecureZeroMemory(szOemPassword, sizeof(szOemPassword));
  405. RRETURN(hr);
  406. }
  407. //+---------------------------------------------------------------------------
  408. // Function: Extract user name from ADs path
  409. //
  410. // Synopsis: This call attempts to extract a username from a NDS style
  411. // ADs path. The last component is assumed to be the username.
  412. //
  413. // Arguments: [LPTSTR szBuffer]
  414. // [LPVOID *ppObject]
  415. //
  416. // Returns: HRESULT
  417. //
  418. // Modifies: -
  419. //
  420. // History: 11-3-95 krishnag Created.
  421. //
  422. //----------------------------------------------------------------------------
  423. HRESULT
  424. BuildUserNameFromADsPath(
  425. LPWSTR pszADsPath,
  426. LPWSTR szUserName
  427. )
  428. {
  429. OBJECTINFO ObjectInfo;
  430. POBJECTINFO pObjectInfo = &ObjectInfo;
  431. LPWSTR pszSrcComp = NULL;
  432. LPWSTR pszSrcValue = NULL;
  433. DWORD dwNumComponents = 0;
  434. HRESULT hr = S_OK;
  435. CLexer Lexer(pszADsPath);
  436. memset(pObjectInfo, 0, sizeof(OBJECTINFO));
  437. hr = ADsObject(&Lexer, pObjectInfo);
  438. BAIL_ON_FAILURE(hr);
  439. dwNumComponents = pObjectInfo->NumComponents ;
  440. if (dwNumComponents) {
  441. //
  442. // take the last value
  443. //
  444. pszSrcComp = pObjectInfo->ComponentArray[dwNumComponents-1].szComponent;
  445. pszSrcValue = pObjectInfo->ComponentArray[dwNumComponents-1].szValue;
  446. if (pszSrcComp && pszSrcValue) {
  447. //
  448. // You have a CN = "MyUserName"
  449. // Then copy the szValue as your UserName
  450. //
  451. wcscpy(szUserName, pszSrcValue);
  452. }
  453. else if (pszSrcComp) {
  454. //
  455. // Simply MyUserName. For example: path
  456. // is "NDS://marsdev/mars/dev/MyUserName)"
  457. //
  458. wcscpy(szUserName, pszSrcComp);
  459. }
  460. }
  461. error:
  462. //
  463. // Clean up the parser object
  464. //
  465. FreeObjectInfo(pObjectInfo);
  466. RRETURN(hr);
  467. }