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.

2200 lines
47 KiB

  1. //---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1996
  5. //
  6. // File: cuser.cxx
  7. //
  8. // Contents: Host user object code
  9. //
  10. // History: Feb-14-96 t-ptam Created.
  11. //
  12. //----------------------------------------------------------------------------
  13. #include "NWCOMPAT.hxx"
  14. #pragma hdrstop
  15. //
  16. // Macro-ized implementation.
  17. //
  18. DEFINE_IDispatch_Implementation(CNWCOMPATUser)
  19. DEFINE_IADs_TempImplementation(CNWCOMPATUser)
  20. DEFINE_IADs_PutGetImplementation(CNWCOMPATUser, UserClass, gdwUserTableSize)
  21. DEFINE_IADsPropertyList_Implementation(CNWCOMPATUser, UserClass, gdwUserTableSize)
  22. //----------------------------------------------------------------------------
  23. //
  24. // Function: CNWCOMPATUser::CNWCOMPATUser()
  25. //
  26. // Synopsis:
  27. //
  28. //----------------------------------------------------------------------------
  29. CNWCOMPATUser::CNWCOMPATUser():
  30. _pDispMgr(NULL),
  31. _pPropertyCache(NULL),
  32. _ParentType(0),
  33. _ServerName(NULL),
  34. _szHostServerName(NULL),
  35. _hConn(NULL)
  36. {
  37. ENLIST_TRACKING(CNWCOMPATUser);
  38. }
  39. //----------------------------------------------------------------------------
  40. //
  41. // Function: CNWCOMPATUser::CreateUser
  42. //
  43. // Synopsis:
  44. //
  45. //----------------------------------------------------------------------------
  46. HRESULT
  47. CNWCOMPATUser::CreateUser(
  48. BSTR Parent,
  49. ULONG ParentType,
  50. BSTR ServerName,
  51. BSTR UserName,
  52. CCredentials &Credentials,
  53. DWORD dwObjectState,
  54. REFIID riid,
  55. void **ppvObj
  56. )
  57. {
  58. CNWCOMPATUser FAR * pUser = NULL;
  59. HRESULT hr = S_OK;
  60. hr = AllocateUserObject(&pUser);
  61. BAIL_ON_FAILURE(hr);
  62. hr = pUser->InitializeCoreObject(
  63. Parent,
  64. UserName,
  65. USER_CLASS_NAME,
  66. USER_SCHEMA_NAME,
  67. CLSID_NWCOMPATUser,
  68. dwObjectState
  69. );
  70. BAIL_ON_FAILURE(hr);
  71. hr = ADsAllocString( ServerName , &pUser->_ServerName);
  72. BAIL_ON_FAILURE(hr);
  73. hr = ADsAllocString( ServerName, &pUser->_szHostServerName);
  74. BAIL_ON_FAILURE(hr);
  75. pUser->_Credentials = Credentials;
  76. //
  77. // Get a handle to the bindery this object resides on.
  78. //
  79. hr = NWApiGetBinderyHandle(
  80. &pUser->_hConn,
  81. pUser->_ServerName,
  82. pUser->_Credentials
  83. );
  84. BAIL_ON_FAILURE(hr);
  85. hr = pUser->QueryInterface(riid, ppvObj);
  86. BAIL_ON_FAILURE(hr);
  87. pUser->Release();
  88. RRETURN(hr);
  89. error:
  90. delete pUser;
  91. NW_RRETURN_EXP_IF_ERR(hr);
  92. }
  93. //----------------------------------------------------------------------------
  94. //
  95. // Function: CNWCOMPATUser::~CNWCOMPATUser
  96. //
  97. // Synopsis:
  98. //
  99. //----------------------------------------------------------------------------
  100. CNWCOMPATUser::~CNWCOMPATUser( )
  101. {
  102. ADsFreeString(_ServerName);
  103. ADsFreeString(_szHostServerName);
  104. delete _pDispMgr;
  105. delete _pPropertyCache;
  106. if (_hConn)
  107. NWApiReleaseBinderyHandle(_hConn);
  108. }
  109. //----------------------------------------------------------------------------
  110. //
  111. // Function: CNWCOMPATUser::QueryInterface
  112. //
  113. // Synopsis:
  114. //
  115. //----------------------------------------------------------------------------
  116. STDMETHODIMP
  117. CNWCOMPATUser::QueryInterface(
  118. REFIID iid,
  119. LPVOID FAR* ppv
  120. )
  121. {
  122. if (ppv == NULL) {
  123. RRETURN(E_POINTER);
  124. }
  125. if (IsEqualIID(iid, IID_IUnknown))
  126. {
  127. *ppv = (IADsUser FAR *) this;
  128. }
  129. else if (IsEqualIID(iid, IID_IADsUser))
  130. {
  131. *ppv = (IADsUser FAR *) this;
  132. }
  133. else if (IsEqualIID(iid, IID_IADs))
  134. {
  135. *ppv = (IADsUser FAR *) this;
  136. }
  137. else if (IsEqualIID(iid, IID_IDispatch))
  138. {
  139. *ppv = (IADsUser FAR *) this;
  140. }
  141. else if (IsEqualIID(iid, IID_ISupportErrorInfo))
  142. {
  143. *ppv = (ISupportErrorInfo FAR *) this;
  144. }
  145. else if (IsEqualIID(iid, IID_IADsPropertyList))
  146. {
  147. *ppv = (IADsPropertyList FAR *) this;
  148. }
  149. else
  150. {
  151. *ppv = NULL;
  152. return E_NOINTERFACE;
  153. }
  154. AddRef();
  155. return NOERROR;
  156. }
  157. /* ISupportErrorInfo method */
  158. //----------------------------------------------------------------------------
  159. //
  160. // Function: CNWCOMPATUser::InterfaceSupportsErrorInfo
  161. //
  162. // Synopsis:
  163. //
  164. //----------------------------------------------------------------------------
  165. STDMETHODIMP
  166. CNWCOMPATUser::InterfaceSupportsErrorInfo(
  167. THIS_ REFIID riid
  168. )
  169. {
  170. if (IsEqualIID(riid, IID_IADs) ||
  171. IsEqualIID(riid, IID_IADsUser) ||
  172. IsEqualIID(riid, IID_IADsPropertyList)) {
  173. RRETURN(S_OK);
  174. } else {
  175. RRETURN(S_FALSE);
  176. }
  177. }
  178. /* IADs methods */
  179. //----------------------------------------------------------------------------
  180. //
  181. // Function: CNWCOMPATUser::SetInfo
  182. //
  183. // Synopsis:
  184. //
  185. //----------------------------------------------------------------------------
  186. STDMETHODIMP
  187. CNWCOMPATUser::SetInfo(THIS)
  188. {
  189. HRESULT hr = S_OK;
  190. POBJECTINFO pObjectInfo = NULL;
  191. NW_USER_INFO NwUserInfo = {NULL, NULL, NULL, NULL};
  192. //
  193. // Bind an object to a real tangible resource if it is not bounded already.
  194. //
  195. if (GetObjectState() == ADS_OBJECT_UNBOUND) {
  196. hr = BuildObjectInfo(
  197. _Parent,
  198. _Name,
  199. &pObjectInfo
  200. );
  201. BAIL_ON_FAILURE(hr);
  202. hr = NWApiMakeUserInfo(
  203. pObjectInfo->ComponentArray[0],
  204. pObjectInfo->ComponentArray[1],
  205. L"", // empty password initially,
  206. _Credentials,
  207. &NwUserInfo
  208. );
  209. BAIL_ON_FAILURE(hr);
  210. hr = NWApiCreateUser(
  211. &NwUserInfo
  212. );
  213. BAIL_ON_FAILURE(hr);
  214. SetObjectState(ADS_OBJECT_BOUND);
  215. }
  216. //
  217. // Persist changes.
  218. //
  219. hr = SetInfo(USER_WILD_CARD_ID);
  220. BAIL_ON_FAILURE(hr);
  221. error:
  222. if (pObjectInfo) {
  223. FreeObjectInfo(pObjectInfo);
  224. }
  225. (void) NWApiFreeUserInfo(&NwUserInfo) ;
  226. NW_RRETURN_EXP_IF_ERR(hr);
  227. }
  228. //----------------------------------------------------------------------------
  229. //
  230. // Function: CNWCOMPATUser::GetInfo
  231. //
  232. // Synopsis:
  233. //
  234. //----------------------------------------------------------------------------
  235. STDMETHODIMP
  236. CNWCOMPATUser::GetInfo(THIS)
  237. {
  238. _pPropertyCache->flushpropcache();
  239. RRETURN(GetInfo(
  240. TRUE,
  241. USER_WILD_CARD_ID
  242. ));
  243. }
  244. //----------------------------------------------------------------------------
  245. //
  246. // Function: CNWCOMPATUser::AllocateUserObject
  247. //
  248. // Synopsis:
  249. //
  250. //----------------------------------------------------------------------------
  251. HRESULT
  252. CNWCOMPATUser::AllocateUserObject(
  253. CNWCOMPATUser ** ppUser
  254. )
  255. {
  256. CNWCOMPATUser FAR * pUser = NULL;
  257. CDispatchMgr FAR * pDispMgr = NULL;
  258. CPropertyCache FAR * pPropertyCache = NULL;
  259. HRESULT hr = S_OK;
  260. //
  261. // Allocate memory for a User object.
  262. //
  263. pUser = new CNWCOMPATUser();
  264. if (pUser == NULL) {
  265. hr = E_OUTOFMEMORY;
  266. }
  267. BAIL_ON_FAILURE(hr);
  268. //
  269. // Create dispatch manager.
  270. //
  271. pDispMgr = new CDispatchMgr;
  272. if (pDispMgr == NULL) {
  273. hr = E_OUTOFMEMORY;
  274. }
  275. BAIL_ON_FAILURE(hr);
  276. //
  277. // Load type info.
  278. //
  279. hr = LoadTypeInfoEntry(
  280. pDispMgr,
  281. LIBID_ADs,
  282. IID_IADsUser,
  283. (IADsUser *)pUser,
  284. DISPID_REGULAR
  285. );
  286. BAIL_ON_FAILURE(hr);
  287. hr = LoadTypeInfoEntry(
  288. pDispMgr,
  289. LIBID_ADs,
  290. IID_IADsPropertyList,
  291. (IADsPropertyList *)pUser,
  292. DISPID_VALUE
  293. );
  294. BAIL_ON_FAILURE(hr);
  295. hr = CPropertyCache::createpropertycache(
  296. UserClass,
  297. gdwUserTableSize,
  298. (CCoreADsObject *)pUser,
  299. &pPropertyCache
  300. );
  301. BAIL_ON_FAILURE(hr);
  302. //
  303. // Return.
  304. //
  305. pUser->_pPropertyCache = pPropertyCache;
  306. pUser->_pDispMgr = pDispMgr;
  307. *ppUser = pUser;
  308. RRETURN(hr);
  309. error:
  310. delete pDispMgr;
  311. delete pPropertyCache;
  312. delete pUser;
  313. RRETURN(hr);
  314. }
  315. //----------------------------------------------------------------------------
  316. //
  317. // Function: CNWCOMPATUser::SetInfo
  318. //
  319. // Synopsis:
  320. //
  321. //----------------------------------------------------------------------------
  322. STDMETHODIMP
  323. CNWCOMPATUser::SetInfo(THIS_ DWORD dwPropertyID)
  324. {
  325. HRESULT hr = S_OK;
  326. //
  327. // Persist changes in cache.
  328. //
  329. hr = SetBusinessInfo(_hConn);
  330. if (hr == E_ADS_PROPERTY_NOT_FOUND) {
  331. // not a real failure, but a missing attrib
  332. // BUGBUG: should create if missing
  333. hr = S_OK;
  334. }
  335. BAIL_ON_FAILURE(hr);
  336. hr = SetAccountRestrictions(_hConn);
  337. if (hr == E_ADS_PROPERTY_NOT_FOUND) {
  338. // not a real failure, but a missing attrib
  339. // BUGBUG: should create if missing
  340. hr = S_OK;
  341. }
  342. BAIL_ON_FAILURE(hr);
  343. error:
  344. NW_RRETURN_EXP_IF_ERR(hr);
  345. }
  346. //----------------------------------------------------------------------------
  347. //
  348. // Function: CNWCOMPATUser::SetBusinessInfo
  349. //
  350. // Synopsis:
  351. //
  352. //----------------------------------------------------------------------------
  353. HRESULT
  354. CNWCOMPATUser::SetBusinessInfo(
  355. NWCONN_HANDLE hConn
  356. )
  357. {
  358. LPWSTR lpszRightSize = NULL;
  359. LPWSTR pszFullName = NULL;
  360. CHAR szData[MAX_FULLNAME_LEN + 1];
  361. HRESULT hr = S_OK;
  362. //
  363. // Set FullName.
  364. //
  365. hr = GetLPTSTRPropertyFromCache(
  366. _pPropertyCache,
  367. TEXT("FullName"),
  368. &pszFullName
  369. );
  370. if (SUCCEEDED(hr)) {
  371. //
  372. // Cut the FullName down to no more than MAX_FULLNAME_LEN of characters.
  373. //
  374. lpszRightSize = (LPWSTR) AllocADsMem(
  375. sizeof(WCHAR) * (MAX_FULLNAME_LEN + 1)
  376. );
  377. if (!lpszRightSize) {
  378. NW_RRETURN_EXP_IF_ERR(E_OUTOFMEMORY);
  379. }
  380. lpszRightSize[MAX_FULLNAME_LEN] = 0;
  381. wcsncpy(
  382. lpszRightSize,
  383. pszFullName,
  384. MAX_FULLNAME_LEN
  385. );
  386. //
  387. // Convert bstr in ANSI string.
  388. //
  389. UnicodeToAnsiString(
  390. lpszRightSize,
  391. szData,
  392. 0
  393. );
  394. //
  395. // Commit change.
  396. //
  397. hr = NWApiWriteProperty(
  398. hConn,
  399. _Name,
  400. OT_USER,
  401. NW_PROP_IDENTIFICATION,
  402. (LPBYTE) szData
  403. );
  404. BAIL_ON_FAILURE(hr);
  405. FreeADsMem(lpszRightSize);
  406. }
  407. error:
  408. if (pszFullName) {
  409. FreeADsStr(pszFullName);
  410. }
  411. RRETURN(S_OK);
  412. }
  413. //----------------------------------------------------------------------------
  414. //
  415. // Function: CNWCOMPATUser::SetAccountRestrictions
  416. //
  417. // Synopsis:
  418. //
  419. //----------------------------------------------------------------------------
  420. HRESULT
  421. CNWCOMPATUser::SetAccountRestrictions(
  422. NWCONN_HANDLE hConn
  423. )
  424. {
  425. BOOL fModified = FALSE;
  426. DATE daDate = 0;
  427. DWORD dwNumSegment;
  428. HRESULT hr = S_OK;
  429. LC_STRUCTURE LoginCtrl;
  430. LONG lData = 0;
  431. LP_RPLY_SGMT_LST lpReplySegment = NULL;
  432. LP_RPLY_SGMT_LST lpTemp = NULL;
  433. SYSTEMTIME SysTime;
  434. USER_DEFAULT UserDefault;
  435. BOOL fBool;
  436. WORD wDay = 0;
  437. WORD wMonth = 0;
  438. WORD wYear = 0;
  439. WCHAR szTemp[MAX_PATH];
  440. BYTE byDateTime[6];
  441. BOOL fAccntLckModified;
  442. hr = NWApiGetLOGIN_CONTROL(
  443. hConn,
  444. _Name,
  445. &LoginCtrl
  446. );
  447. BAIL_ON_FAILURE(hr);
  448. //
  449. // SET AccountDisabled.
  450. //
  451. hr = GetBOOLPropertyFromCache(
  452. _pPropertyCache,
  453. TEXT("AccountDisabled"),
  454. &fBool
  455. );
  456. if (SUCCEEDED(hr)) {
  457. LoginCtrl.byAccountDisabled = (BYTE) fBool;
  458. fModified = TRUE;
  459. }
  460. //
  461. // SET AccountExpirationDate.
  462. //
  463. memset(byDateTime, 0, 6);
  464. hr = GetNw312DATEPropertyFromCache(
  465. _pPropertyCache,
  466. TEXT("AccountExpirationDate"),
  467. byDateTime
  468. );
  469. if (SUCCEEDED(hr)) {
  470. LoginCtrl.byAccountExpires[0] = (BYTE) byDateTime[0];
  471. LoginCtrl.byAccountExpires[1] = (BYTE) byDateTime[1];
  472. LoginCtrl.byAccountExpires[2] = (BYTE) byDateTime[2];
  473. fModified = TRUE;
  474. }
  475. //
  476. // SET AccountCanExpire.
  477. //
  478. hr = GetBOOLPropertyFromCache(
  479. _pPropertyCache,
  480. TEXT("AccountCanExpire"),
  481. &fBool
  482. );
  483. if (SUCCEEDED(hr)) {
  484. if (fBool == FALSE) {
  485. LoginCtrl.byAccountExpires[0] = 0;
  486. LoginCtrl.byAccountExpires[1] = 0;
  487. LoginCtrl.byAccountExpires[2] = 0;
  488. fModified = TRUE;
  489. }
  490. }
  491. //
  492. // SET GraceLoginsAllowed.
  493. //
  494. hr = GetDWORDPropertyFromCache(
  495. _pPropertyCache,
  496. TEXT("GraceLoginsAllowed"),
  497. (PDWORD)&lData
  498. );
  499. if (SUCCEEDED(hr)) {
  500. LoginCtrl.byGraceLoginReset = (BYTE) lData;
  501. fModified = TRUE;
  502. }
  503. //
  504. // SET GraceLoginsRemaining.
  505. //
  506. hr = GetDWORDPropertyFromCache(
  507. _pPropertyCache,
  508. TEXT("GraceLoginsRemaining"),
  509. (PDWORD)&lData
  510. );
  511. if (SUCCEEDED(hr)) {
  512. LoginCtrl.byGraceLogins = (BYTE) lData;
  513. fModified = TRUE;
  514. }
  515. //
  516. // SET IsAccountLocked.
  517. //
  518. //
  519. // if this property not modified in cache, no need to set on svr
  520. //
  521. hr = _pPropertyCache->propertyismodified(
  522. TEXT("IsAccountLocked"),
  523. &fAccntLckModified
  524. );
  525. if ( SUCCEEDED(hr) && fAccntLckModified==TRUE ) {
  526. hr = GetBOOLPropertyFromCache(
  527. _pPropertyCache,
  528. TEXT("IsAccountLocked"),
  529. &fBool
  530. );
  531. if (SUCCEEDED(hr)) {
  532. //
  533. // If fBool is changed from TRUE to FALSE, set wBadLogins
  534. // back to 0 -> this will unlock account on nw svr
  535. //
  536. if (fBool == FALSE) {
  537. LoginCtrl.wBadLogins = 0;
  538. fModified = TRUE;
  539. }else {
  540. //
  541. // Reset it to FALSE if it is changed to TRUE.
  542. // -> cannot lock an account on nwsvr thru' adsi
  543. //
  544. fBool = FALSE;
  545. hr = SetBOOLPropertyInCache(
  546. _pPropertyCache,
  547. TEXT("IsAccountLocked"),
  548. fBool,
  549. TRUE
  550. );
  551. BAIL_ON_FAILURE(hr);
  552. }
  553. }
  554. }
  555. //
  556. // SET IsAdmin.
  557. //
  558. hr = GetBOOLPropertyFromCache(
  559. _pPropertyCache,
  560. TEXT("IsAdmin"),
  561. &fBool
  562. );
  563. if (SUCCEEDED(hr)) {
  564. hr = NWApiUserAsSupervisor(
  565. hConn,
  566. _Name,
  567. fBool
  568. );
  569. //
  570. // For beta, disabling the bail. It does not work in the user not
  571. // supervisor mode.
  572. //
  573. // BAIL_ON_FAILURE(hr);
  574. }
  575. //
  576. // SET MaxLogins.
  577. //
  578. hr = GetDWORDPropertyFromCache(
  579. _pPropertyCache,
  580. TEXT("MaxLogins"),
  581. (PDWORD)&lData
  582. );
  583. if (SUCCEEDED(hr)) {
  584. LoginCtrl.wMaxConnections = NWApiReverseWORD(
  585. (WORD) lData
  586. );
  587. fModified = TRUE;
  588. }
  589. //
  590. // SET PasswordExpirationDate.
  591. //
  592. memset(byDateTime, 0, 6);
  593. hr = GetNw312DATEPropertyFromCache(
  594. _pPropertyCache,
  595. TEXT("PasswordExpirationDate"),
  596. byDateTime
  597. );
  598. if (SUCCEEDED(hr)) {
  599. LoginCtrl.byPasswordExpires[0] = (BYTE) byDateTime[0];
  600. LoginCtrl.byPasswordExpires[1] = (BYTE) byDateTime[1];
  601. LoginCtrl.byPasswordExpires[2] = (BYTE) byDateTime[2];
  602. fModified = TRUE;
  603. }
  604. //
  605. // SET PasswordCanExpire.
  606. //
  607. hr = GetBOOLPropertyFromCache(
  608. _pPropertyCache,
  609. TEXT("PasswordCanExpire"),
  610. &fBool
  611. );
  612. if (SUCCEEDED(hr)) {
  613. if (fBool == FALSE) {
  614. //
  615. // If passowrd cannot expire, set password expiration date to zero.
  616. // This is what SysCon does.
  617. //
  618. LoginCtrl.byPasswordExpires[0] = 0;
  619. LoginCtrl.byPasswordExpires[1] = 0;
  620. LoginCtrl.byPasswordExpires[2] = 0;
  621. fModified = TRUE;
  622. }
  623. }
  624. //
  625. // SET PasswordMinimumLength.
  626. //
  627. hr = GetDWORDPropertyFromCache(
  628. _pPropertyCache,
  629. TEXT("PasswordMinimumLength"),
  630. (PDWORD)&lData
  631. );
  632. if (SUCCEEDED(hr)) {
  633. LoginCtrl.byMinPasswordLength = (BYTE) lData;
  634. fModified = TRUE;
  635. }
  636. //
  637. // SET PasswordRequired. The section below must goes before "Set
  638. // PasswordMinimumLength" for it to make sense.
  639. //
  640. hr = GetBOOLPropertyFromCache(
  641. _pPropertyCache,
  642. TEXT("PasswordRequired"),
  643. &fBool
  644. );
  645. if (SUCCEEDED(hr)) {
  646. //
  647. // If Password is required, set PasswordMinimumLength to default value.
  648. //
  649. //
  650. // If Password is not required, set PasswordMinimumLength to 0. Again,
  651. // this is what SysCon does.
  652. //
  653. if (fBool) {
  654. if (!LoginCtrl.byMinPasswordLength) {
  655. LoginCtrl.byMinPasswordLength = DEFAULT_MIN_PSWD_LEN;
  656. }
  657. }else{
  658. LoginCtrl.byMinPasswordLength = 0;
  659. }
  660. fModified = TRUE;
  661. }
  662. //
  663. // Set LoginHours
  664. //
  665. OctetString octString;
  666. hr = GetOctetPropertyFromCache(
  667. _pPropertyCache,
  668. TEXT("LoginHours"),
  669. &octString
  670. );
  671. if (SUCCEEDED(hr)) {
  672. memcpy(LoginCtrl.byLoginTimes, octString.pByte, octString.dwSize);
  673. FreeADsMem(octString.pByte);
  674. fModified = TRUE;
  675. }
  676. //
  677. // Set RequireUniquePassword.
  678. //
  679. hr = GetBOOLPropertyFromCache(
  680. _pPropertyCache,
  681. TEXT("RequireUniquePassword"),
  682. &fBool
  683. );
  684. if (SUCCEEDED(hr)) {
  685. LoginCtrl.byRestrictions = fBool ? REQUIRE_UNIQUE_PSWD : 0;
  686. fModified = TRUE;
  687. }
  688. //
  689. // Commit changes of the properties associated with LOGIN_CONTROL.
  690. //
  691. if (fModified == TRUE) {
  692. hr = NWApiWriteProperty(
  693. hConn,
  694. _Name,
  695. OT_USER,
  696. NW_PROP_LOGIN_CONTROL,
  697. (LPBYTE) &LoginCtrl
  698. );
  699. }
  700. else {
  701. hr = S_OK;
  702. }
  703. error:
  704. if (lpReplySegment) {
  705. DELETE_LIST(lpReplySegment);
  706. }
  707. NW_RRETURN_EXP_IF_ERR(hr);
  708. }
  709. //----------------------------------------------------------------------------
  710. //
  711. // Function: CNWCOMPATUser::GetInfo
  712. //
  713. // Synopsis:
  714. //
  715. //----------------------------------------------------------------------------
  716. STDMETHODIMP
  717. CNWCOMPATUser::GetInfo(
  718. BOOL fExplicit,
  719. DWORD dwPropertyID
  720. )
  721. {
  722. HRESULT hr = S_OK;
  723. if (GetObjectState() == ADS_OBJECT_UNBOUND) {
  724. NW_RRETURN_EXP_IF_ERR(E_ADS_OBJECT_UNBOUND);
  725. }
  726. //
  727. // Fill in all property caches with values - explicit, or return the
  728. // indicated property - implicit.
  729. //
  730. if (fExplicit) {
  731. hr = ExplicitGetInfo(_hConn, fExplicit);
  732. BAIL_ON_FAILURE(hr);
  733. }
  734. else {
  735. hr = ImplicitGetInfo(_hConn, dwPropertyID, fExplicit);
  736. BAIL_ON_FAILURE(hr);
  737. }
  738. error:
  739. //
  740. // Release handle.
  741. //
  742. NW_RRETURN_EXP_IF_ERR(hr);
  743. }
  744. //----------------------------------------------------------------------------
  745. //
  746. // Function: CNWCOMPATUser::ExplicitGetInfo
  747. //
  748. // Synopsis:
  749. //
  750. //----------------------------------------------------------------------------
  751. HRESULT
  752. CNWCOMPATUser::ExplicitGetInfo(
  753. NWCONN_HANDLE hConn,
  754. BOOL fExplicit
  755. )
  756. {
  757. HRESULT hr = S_OK;
  758. LC_STRUCTURE LoginCtrlStruct;
  759. //
  760. // Get BusinessInfo functional set.
  761. //
  762. hr = GetProperty_FullName(
  763. hConn,
  764. fExplicit
  765. );
  766. if (hr == E_ADS_PROPERTY_NOT_FOUND) {
  767. // not a real failure, we ignore it and treat it as a missing attrib
  768. hr = S_OK;
  769. }
  770. BAIL_ON_FAILURE(hr);
  771. // Is it an admin? This is part of the AccountRestriction functional set, but is
  772. // independent of LOGIN_CONTROL, so it needs to go here.
  773. hr = GetProperty_IsAdmin(
  774. hConn,
  775. fExplicit
  776. );
  777. if (hr == E_ADS_PROPERTY_NOT_FOUND) {
  778. // not a real failure, we ignore it and treat it as a missing attrib
  779. hr = S_OK;
  780. }
  781. BAIL_ON_FAILURE(hr);
  782. //
  783. // Get LOGIN_CONTROL, which is used in AccountRestriction functional set &
  784. // AccountStatistics functional set.
  785. //
  786. hr = NWApiGetLOGIN_CONTROL(
  787. hConn,
  788. _Name,
  789. &LoginCtrlStruct
  790. );
  791. if (hr == E_ADS_PROPERTY_NOT_FOUND) {
  792. // not a real failure, we ignore it and treat it as a missing attrib,
  793. // and skip the LOGIN_CONTROL-dependent code
  794. hr = S_OK;
  795. }
  796. else
  797. {
  798. BAIL_ON_FAILURE(hr);
  799. //
  800. // Get AccountRestriction functional set.
  801. //
  802. hr = GetProperty_LoginHours(
  803. hConn,
  804. LoginCtrlStruct,
  805. fExplicit
  806. );
  807. BAIL_ON_FAILURE(hr);
  808. hr = GetProperty_AccountDisabled(
  809. hConn,
  810. LoginCtrlStruct,
  811. fExplicit
  812. );
  813. BAIL_ON_FAILURE(hr);
  814. hr = GetProperty_AccountExpirationDate(
  815. hConn,
  816. LoginCtrlStruct,
  817. fExplicit
  818. );
  819. BAIL_ON_FAILURE(hr);
  820. hr = GetProperty_CanAccountExpire(
  821. hConn,
  822. LoginCtrlStruct,
  823. fExplicit
  824. );
  825. BAIL_ON_FAILURE(hr);
  826. hr = GetProperty_GraceLoginsAllowed(
  827. hConn,
  828. LoginCtrlStruct,
  829. fExplicit
  830. );
  831. BAIL_ON_FAILURE(hr);
  832. hr = GetProperty_GraceLoginsRemaining(
  833. hConn,
  834. LoginCtrlStruct,
  835. fExplicit
  836. );
  837. BAIL_ON_FAILURE(hr);
  838. hr = GetProperty_IsAccountLocked(
  839. hConn,
  840. LoginCtrlStruct,
  841. fExplicit
  842. );
  843. BAIL_ON_FAILURE(hr);
  844. hr = GetProperty_MaxLogins(
  845. hConn,
  846. LoginCtrlStruct,
  847. fExplicit
  848. );
  849. BAIL_ON_FAILURE(hr);
  850. hr = GetProperty_CanPasswordExpire(
  851. hConn,
  852. LoginCtrlStruct,
  853. fExplicit
  854. );
  855. BAIL_ON_FAILURE(hr);
  856. hr = GetProperty_PasswordExpirationDate(
  857. hConn,
  858. LoginCtrlStruct,
  859. fExplicit
  860. );
  861. BAIL_ON_FAILURE(hr);
  862. hr = GetProperty_PasswordMinimumLength(
  863. hConn,
  864. LoginCtrlStruct,
  865. fExplicit
  866. );
  867. BAIL_ON_FAILURE(hr);
  868. hr = GetProperty_PasswordRequired(
  869. hConn,
  870. LoginCtrlStruct,
  871. fExplicit
  872. );
  873. BAIL_ON_FAILURE(hr);
  874. hr = GetProperty_RequireUniquePassword(
  875. hConn,
  876. LoginCtrlStruct,
  877. fExplicit
  878. );
  879. BAIL_ON_FAILURE(hr);
  880. //
  881. // Get AccountStatistics functional set.
  882. //
  883. hr = GetProperty_BadLoginAddress(
  884. hConn,
  885. LoginCtrlStruct,
  886. fExplicit
  887. );
  888. BAIL_ON_FAILURE(hr);
  889. hr = GetProperty_LastLogin(
  890. hConn,
  891. LoginCtrlStruct,
  892. fExplicit
  893. );
  894. BAIL_ON_FAILURE(hr);
  895. }
  896. error:
  897. RRETURN(hr);
  898. }
  899. //----------------------------------------------------------------------------
  900. //
  901. // Function: CNWCOMPATUser::ImplicitGetInfo
  902. //
  903. // Synopsis:
  904. //
  905. //----------------------------------------------------------------------------
  906. HRESULT
  907. CNWCOMPATUser::ImplicitGetInfo(
  908. NWCONN_HANDLE hConn,
  909. DWORD dwPropertyID,
  910. BOOL fExplicit
  911. )
  912. {
  913. HRESULT hr = S_OK;
  914. if (dwPropertyID < 100) {
  915. hr = GetBusinessInfo(
  916. hConn,
  917. dwPropertyID,
  918. fExplicit
  919. );
  920. }
  921. else if (dwPropertyID < 200) {
  922. hr = GetAccountRestrictions(
  923. hConn,
  924. dwPropertyID,
  925. fExplicit
  926. );
  927. }
  928. else if (dwPropertyID < 300) {
  929. hr = GetAccountStatistics(
  930. hConn,
  931. dwPropertyID,
  932. fExplicit
  933. );
  934. }
  935. RRETURN(hr);
  936. }
  937. //----------------------------------------------------------------------------
  938. //
  939. // Function: CNWCOMPATUser::GetBusinessInfo
  940. //
  941. // Synopsis:
  942. //
  943. //----------------------------------------------------------------------------
  944. HRESULT
  945. CNWCOMPATUser::GetBusinessInfo(
  946. NWCONN_HANDLE hConn,
  947. DWORD dwPropertyID,
  948. BOOL fExplicit
  949. )
  950. {
  951. HRESULT hr = S_OK;
  952. switch (dwPropertyID) {
  953. case USER_FULLNAME_ID:
  954. hr = GetProperty_FullName(
  955. hConn,
  956. fExplicit
  957. );
  958. break;
  959. }
  960. RRETURN(hr);
  961. }
  962. //----------------------------------------------------------------------------
  963. //
  964. // Function: CNWCOMPATUser::GetAccountRestrictions
  965. //
  966. // Synopsis:
  967. //
  968. //----------------------------------------------------------------------------
  969. HRESULT
  970. CNWCOMPATUser::GetAccountRestrictions(
  971. NWCONN_HANDLE hConn,
  972. DWORD dwPropertyID,
  973. BOOL fExplicit
  974. )
  975. {
  976. HRESULT hr = S_OK;
  977. LC_STRUCTURE LoginCtrlStruct;
  978. //
  979. // Get LOGIN_CONTROL.
  980. //
  981. hr = NWApiGetLOGIN_CONTROL(
  982. hConn,
  983. _Name,
  984. &LoginCtrlStruct
  985. );
  986. BAIL_ON_FAILURE(hr);
  987. //
  988. // Get property.
  989. //
  990. switch (dwPropertyID) {
  991. case USER_ACCOUNTDISABLED_ID:
  992. hr = GetProperty_AccountDisabled(
  993. hConn,
  994. LoginCtrlStruct,
  995. fExplicit
  996. );
  997. break;
  998. case USER_ACCOUNTEXPIRATIONDATE_ID:
  999. hr = GetProperty_AccountExpirationDate(
  1000. hConn,
  1001. LoginCtrlStruct,
  1002. fExplicit
  1003. );
  1004. break;
  1005. case USER_CANACCOUNTEXPIRE_ID:
  1006. hr = GetProperty_CanAccountExpire(
  1007. hConn,
  1008. LoginCtrlStruct,
  1009. fExplicit
  1010. );
  1011. break;
  1012. case USER_GRACELOGINSALLOWED_ID:
  1013. hr = GetProperty_GraceLoginsAllowed(
  1014. hConn,
  1015. LoginCtrlStruct,
  1016. fExplicit
  1017. );
  1018. break;
  1019. case USER_GRACELOGINSREMAINING_ID:
  1020. hr = GetProperty_GraceLoginsRemaining(
  1021. hConn,
  1022. LoginCtrlStruct,
  1023. fExplicit
  1024. );
  1025. break;
  1026. case USER_ISACCOUNTLOCKED_ID:
  1027. hr = GetProperty_IsAccountLocked(
  1028. hConn,
  1029. LoginCtrlStruct,
  1030. fExplicit
  1031. );
  1032. break;
  1033. case USER_ISADMIN_ID:
  1034. hr = GetProperty_IsAdmin(
  1035. hConn,
  1036. fExplicit
  1037. );
  1038. break;
  1039. case USER_MAXLOGINS_ID:
  1040. hr = GetProperty_MaxLogins(
  1041. hConn,
  1042. LoginCtrlStruct,
  1043. fExplicit
  1044. );
  1045. break;
  1046. case USER_CANPASSWORDEXPIRE_ID:
  1047. hr = GetProperty_CanPasswordExpire(
  1048. hConn,
  1049. LoginCtrlStruct,
  1050. fExplicit
  1051. );
  1052. break;
  1053. case USER_PASSWORDEXPIRATIONDATE_ID:
  1054. hr = GetProperty_PasswordExpirationDate(
  1055. hConn,
  1056. LoginCtrlStruct,
  1057. fExplicit
  1058. );
  1059. break;
  1060. case USER_PASSWORDMINIMUMLENGTH_ID:
  1061. hr = GetProperty_PasswordMinimumLength(
  1062. hConn,
  1063. LoginCtrlStruct,
  1064. fExplicit
  1065. );
  1066. break;
  1067. case USER_PASSWORDREQUIRED_ID:
  1068. hr = GetProperty_PasswordRequired(
  1069. hConn,
  1070. LoginCtrlStruct,
  1071. fExplicit
  1072. );
  1073. break;
  1074. case USER_REQUIREUNIQUEPASSWORD_ID:
  1075. hr = GetProperty_RequireUniquePassword(
  1076. hConn,
  1077. LoginCtrlStruct,
  1078. fExplicit
  1079. );
  1080. break;
  1081. case USER_LOGINHOURS_ID:
  1082. hr = GetProperty_LoginHours(
  1083. hConn,
  1084. LoginCtrlStruct,
  1085. fExplicit
  1086. );
  1087. break;
  1088. }
  1089. error:
  1090. NW_RRETURN_EXP_IF_ERR(hr);
  1091. }
  1092. //----------------------------------------------------------------------------
  1093. //
  1094. // Function: CNWCOMPATUser::GetAccountStatistics
  1095. //
  1096. // Synopsis:
  1097. //
  1098. //----------------------------------------------------------------------------
  1099. HRESULT
  1100. CNWCOMPATUser::GetAccountStatistics(
  1101. NWCONN_HANDLE hConn,
  1102. DWORD dwPropertyID,
  1103. BOOL fExplicit
  1104. )
  1105. {
  1106. HRESULT hr = S_OK;
  1107. LC_STRUCTURE LoginCtrlStruct;
  1108. //
  1109. // Get LOGIN_CONTROL.
  1110. //
  1111. hr = NWApiGetLOGIN_CONTROL(
  1112. hConn,
  1113. _Name,
  1114. &LoginCtrlStruct
  1115. );
  1116. BAIL_ON_FAILURE(hr);
  1117. //
  1118. // Get property.
  1119. //
  1120. switch (dwPropertyID) {
  1121. case USER_BADLOGINADDRESS_ID:
  1122. hr = GetProperty_BadLoginAddress(
  1123. hConn,
  1124. LoginCtrlStruct,
  1125. fExplicit
  1126. );
  1127. break;
  1128. case USER_LASTLOGIN_ID:
  1129. hr = GetProperty_LastLogin(
  1130. hConn,
  1131. LoginCtrlStruct,
  1132. fExplicit
  1133. );
  1134. break;
  1135. }
  1136. error:
  1137. RRETURN(hr);
  1138. }
  1139. //----------------------------------------------------------------------------
  1140. //
  1141. // Function: CNWCOMPATUser::GetProperty_FullName
  1142. //
  1143. // Synopsis:
  1144. //
  1145. //----------------------------------------------------------------------------
  1146. HRESULT
  1147. CNWCOMPATUser::GetProperty_FullName(
  1148. NWCONN_HANDLE hConn,
  1149. BOOL fExplicit
  1150. )
  1151. {
  1152. LPWSTR lpszFullName = NULL;
  1153. CHAR szFullName[MAX_FULLNAME_LEN + 1];
  1154. DWORD dwNumSegment = 0;
  1155. HRESULT hr = S_OK;
  1156. LP_RPLY_SGMT_LST lpReplySegment = NULL;
  1157. LP_RPLY_SGMT_LST lpTemp = NULL; // Used by DELETE_LIST macro below
  1158. //
  1159. // Get IDENTIFICATIOIN. This property contains the full name of an object.
  1160. //
  1161. hr = NWApiGetProperty(
  1162. _Name,
  1163. NW_PROP_IDENTIFICATION,
  1164. OT_USER,
  1165. hConn,
  1166. &lpReplySegment,
  1167. &dwNumSegment
  1168. );
  1169. //
  1170. // There was a bug marked on this code because NWApiGetProperty would fail with
  1171. // an error if the property didn't exist (raid #34833), and the temp patch was
  1172. // simply to hide all errors and always return S_OK when GetProperty_FullName
  1173. // returned. Now NWApiGetProperty will return E_ADS_PROPERTY_NOT_FOUND.
  1174. //
  1175. BAIL_ON_FAILURE(hr);
  1176. //
  1177. // Convert result into a UNICODE string.
  1178. //
  1179. strcpy(szFullName, lpReplySegment->Segment);
  1180. lpszFullName = (LPWSTR) AllocADsMem(
  1181. (strlen(szFullName)+1) * sizeof(WCHAR)
  1182. );
  1183. AnsiToUnicodeString(
  1184. szFullName,
  1185. lpszFullName,
  1186. 0
  1187. );
  1188. //
  1189. // Unmarshall.
  1190. //
  1191. hr = SetLPTSTRPropertyInCache(
  1192. _pPropertyCache,
  1193. TEXT("FullName"),
  1194. (LPWSTR)lpszFullName,
  1195. fExplicit
  1196. );
  1197. BAIL_ON_FAILURE(hr);
  1198. error:
  1199. if (lpszFullName) {
  1200. FreeADsMem(lpszFullName);
  1201. }
  1202. if (lpReplySegment) {
  1203. DELETE_LIST(lpReplySegment);
  1204. }
  1205. RRETURN(hr);
  1206. }
  1207. //----------------------------------------------------------------------------
  1208. //
  1209. // Function: CNWCOMPATUser::GetProperty_AccountDisabled
  1210. //
  1211. // Synopsis:
  1212. //
  1213. //----------------------------------------------------------------------------
  1214. HRESULT
  1215. CNWCOMPATUser::GetProperty_AccountDisabled(
  1216. NWCONN_HANDLE hConn,
  1217. LC_STRUCTURE LoginCtrlStruct,
  1218. BOOL fExplicit
  1219. )
  1220. {
  1221. BOOL dwBool = TRUE;
  1222. HRESULT hr = S_OK;
  1223. //
  1224. // Put value into a variant.
  1225. //
  1226. dwBool = (BOOL) LoginCtrlStruct.byAccountDisabled;
  1227. //
  1228. // Unmarshall.
  1229. //
  1230. hr = SetBOOLPropertyInCache(
  1231. _pPropertyCache,
  1232. TEXT("AccountDisabled"),
  1233. dwBool,
  1234. fExplicit
  1235. );
  1236. RRETURN(hr);
  1237. }
  1238. //----------------------------------------------------------------------------
  1239. //
  1240. // Function: CNWCOMPATUser::GetProperty_AccountExpirationDate
  1241. //
  1242. // Synopsis:
  1243. //
  1244. //----------------------------------------------------------------------------
  1245. HRESULT
  1246. CNWCOMPATUser::GetProperty_AccountExpirationDate(
  1247. NWCONN_HANDLE hConn,
  1248. LC_STRUCTURE LoginCtrlStruct,
  1249. BOOL fExplicit
  1250. )
  1251. {
  1252. HRESULT hr = S_OK;
  1253. BYTE byDateTime[6];
  1254. BYTE byNoDateTime[6];
  1255. memset(byNoDateTime, 0, 6);
  1256. memset(byDateTime, 0, 6);
  1257. memcpy(byDateTime, LoginCtrlStruct.byAccountExpires, 3);
  1258. //
  1259. // LoginCtrlSturct.byAccountExpires == 000 indicates no expired date
  1260. //
  1261. if (memcmp(byDateTime, byNoDateTime, 3)!=0) {
  1262. hr = SetNw312DATEPropertyInCache(
  1263. _pPropertyCache,
  1264. TEXT("AccountExpirationDate"),
  1265. byDateTime,
  1266. fExplicit
  1267. );
  1268. BAIL_ON_FAILURE(hr);
  1269. }
  1270. error:
  1271. RRETURN(hr);
  1272. }
  1273. //----------------------------------------------------------------------------
  1274. //
  1275. // Function: CNWCOMPATUser::GetProperty_CanAccountExpire
  1276. //
  1277. // Synopsis:
  1278. //
  1279. //----------------------------------------------------------------------------
  1280. HRESULT
  1281. CNWCOMPATUser::GetProperty_CanAccountExpire(
  1282. NWCONN_HANDLE hConn,
  1283. LC_STRUCTURE LoginCtrlStruct,
  1284. BOOL fExplicit
  1285. )
  1286. {
  1287. BOOL dwBool = TRUE;
  1288. HRESULT hr = S_OK;
  1289. //
  1290. // Account cannot expire if there is no expiration date.
  1291. //
  1292. if ((LoginCtrlStruct.byAccountExpires[0] == 0) &&
  1293. (LoginCtrlStruct.byAccountExpires[1] == 0) &&
  1294. (LoginCtrlStruct.byAccountExpires[2] == 0)) {
  1295. dwBool = FALSE;
  1296. }
  1297. //
  1298. // Unmarshall.
  1299. //
  1300. hr = SetBOOLPropertyInCache(
  1301. _pPropertyCache,
  1302. TEXT("AccountCanExpire"),
  1303. dwBool,
  1304. fExplicit
  1305. );
  1306. RRETURN(hr);
  1307. }
  1308. //----------------------------------------------------------------------------
  1309. //
  1310. // Function: CNWCOMPATUser::GetProperty_GraceLoginsAllowed
  1311. //
  1312. // Synopsis:
  1313. //
  1314. //----------------------------------------------------------------------------
  1315. HRESULT
  1316. CNWCOMPATUser::GetProperty_GraceLoginsAllowed(
  1317. NWCONN_HANDLE hConn,
  1318. LC_STRUCTURE LoginCtrlStruct,
  1319. BOOL fExplicit
  1320. )
  1321. {
  1322. HRESULT hr = S_OK;
  1323. LONG lGraceLoginsAllowed = 0;
  1324. //
  1325. // Get "byGraceLoginReset". The property is not meaningful when it equals
  1326. // to 0xff.
  1327. //
  1328. if (LoginCtrlStruct.byGraceLoginReset != 0xff) {
  1329. lGraceLoginsAllowed = (LONG) LoginCtrlStruct.byGraceLoginReset;
  1330. }
  1331. //
  1332. // Unmarshall.
  1333. //
  1334. hr = SetDWORDPropertyInCache(
  1335. _pPropertyCache,
  1336. TEXT("GraceLoginsAllowed"),
  1337. (DWORD)lGraceLoginsAllowed,
  1338. fExplicit
  1339. );
  1340. RRETURN(hr);
  1341. }
  1342. //----------------------------------------------------------------------------
  1343. //
  1344. // Function: CNWCOMPATUser::GetProperty_GraceLoginsRemaining
  1345. //
  1346. // Synopsis:
  1347. //
  1348. //----------------------------------------------------------------------------
  1349. HRESULT
  1350. CNWCOMPATUser::GetProperty_GraceLoginsRemaining(
  1351. NWCONN_HANDLE hConn,
  1352. LC_STRUCTURE LoginCtrlStruct,
  1353. BOOL fExplicit
  1354. )
  1355. {
  1356. HRESULT hr = S_OK;
  1357. LONG lGraceLoginsRemaining = 0;
  1358. //
  1359. // Get "byGraceLogins". The property is not meaningful when it equals to
  1360. // 0xff.
  1361. //
  1362. if (LoginCtrlStruct.byGraceLogins != 0xff) {
  1363. lGraceLoginsRemaining = (LONG) LoginCtrlStruct.byGraceLogins;
  1364. }
  1365. //
  1366. // Unmarshall.
  1367. //
  1368. hr = SetDWORDPropertyInCache(
  1369. _pPropertyCache,
  1370. TEXT("GraceLoginsRemaining"),
  1371. (DWORD)lGraceLoginsRemaining,
  1372. fExplicit
  1373. );
  1374. RRETURN(hr);
  1375. }
  1376. //----------------------------------------------------------------------------
  1377. //
  1378. // Function: CNWCOMPATUser::GetProperty_IsAccountLocked
  1379. //
  1380. // Synopsis:
  1381. //
  1382. //----------------------------------------------------------------------------
  1383. HRESULT
  1384. CNWCOMPATUser::GetProperty_IsAccountLocked(
  1385. NWCONN_HANDLE hConn,
  1386. LC_STRUCTURE LoginCtrlStruct,
  1387. BOOL fExplicit
  1388. )
  1389. {
  1390. BOOL dwBool = FALSE;
  1391. HRESULT hr = S_OK;
  1392. //
  1393. // Account is locked when wBadLogins = 0xffff.
  1394. //
  1395. if (LoginCtrlStruct.wBadLogins == 0xffff) {
  1396. dwBool = TRUE;
  1397. }
  1398. //
  1399. // Unmarshall.
  1400. //
  1401. hr = SetBOOLPropertyInCache(
  1402. _pPropertyCache,
  1403. TEXT("IsAccountLocked"),
  1404. dwBool,
  1405. fExplicit
  1406. );
  1407. RRETURN(hr);
  1408. }
  1409. //----------------------------------------------------------------------------
  1410. //
  1411. // Function: CNWCOMPATUser::GetProperty_IsAdmin
  1412. //
  1413. // Synopsis:
  1414. //
  1415. //----------------------------------------------------------------------------
  1416. HRESULT
  1417. CNWCOMPATUser::GetProperty_IsAdmin(
  1418. NWCONN_HANDLE hConn,
  1419. BOOL fExplicit
  1420. )
  1421. {
  1422. BOOL dwBool = TRUE;
  1423. HRESULT hr = S_OK;
  1424. //
  1425. // Check if this user has the same security as the supervisor. If it does,
  1426. // then it is an admin.
  1427. //
  1428. hr = NWApiIsObjectInSet(
  1429. hConn,
  1430. _Name,
  1431. OT_USER,
  1432. NW_PROP_SECURITY_EQUALS,
  1433. NW_PROP_SUPERVISOR,
  1434. OT_USER
  1435. );
  1436. //
  1437. // BUGBUG - for now, any failure is assumed to be "No such object.". Fix
  1438. // this after bug #33322 is fixed.
  1439. //
  1440. if (FAILED(hr)) {
  1441. dwBool = FALSE;
  1442. }
  1443. //
  1444. // Unmarshall.
  1445. //
  1446. hr = SetBOOLPropertyInCache(
  1447. _pPropertyCache,
  1448. TEXT("IsAdmin"),
  1449. dwBool,
  1450. fExplicit
  1451. );
  1452. //
  1453. // BUGBUG - replace S_OK with hr (see above).
  1454. //
  1455. RRETURN(S_OK);
  1456. }
  1457. //----------------------------------------------------------------------------
  1458. //
  1459. // Function: CNWCOMPATUser::GetProperty_MaxLogins
  1460. //
  1461. // Synopsis:
  1462. //
  1463. //----------------------------------------------------------------------------
  1464. HRESULT
  1465. CNWCOMPATUser::GetProperty_MaxLogins(
  1466. NWCONN_HANDLE hConn,
  1467. LC_STRUCTURE LoginCtrlStruct,
  1468. BOOL fExplicit
  1469. )
  1470. {
  1471. HRESULT hr = S_OK;
  1472. LONG lMaxLogins = 0;
  1473. //
  1474. // Get "wMaxConnections".
  1475. //
  1476. lMaxLogins = (LONG) NWApiReverseWORD(
  1477. LoginCtrlStruct.wMaxConnections
  1478. );
  1479. //
  1480. // Unmarshall.
  1481. //
  1482. hr = SetDWORDPropertyInCache(
  1483. _pPropertyCache,
  1484. TEXT("MaxLogins"),
  1485. (DWORD)lMaxLogins,
  1486. fExplicit
  1487. );
  1488. RRETURN(hr);
  1489. }
  1490. //----------------------------------------------------------------------------
  1491. //
  1492. // Function: CNWCOMPATUser::GetProperty_CanPasswordExpire
  1493. //
  1494. // Synopsis:
  1495. //
  1496. //----------------------------------------------------------------------------
  1497. HRESULT
  1498. CNWCOMPATUser::GetProperty_CanPasswordExpire(
  1499. NWCONN_HANDLE hConn,
  1500. LC_STRUCTURE LoginCtrlStruct,
  1501. BOOL fExplicit
  1502. )
  1503. {
  1504. BOOL dwBool = TRUE;
  1505. HRESULT hr = S_OK;
  1506. //
  1507. // Password cannot expire if there is no expiration date.
  1508. //
  1509. if ((LoginCtrlStruct.byPasswordExpires[0] == 0) &&
  1510. (LoginCtrlStruct.byPasswordExpires[1] == 0) &&
  1511. (LoginCtrlStruct.byPasswordExpires[2] == 0)) {
  1512. dwBool = FALSE;
  1513. }
  1514. //
  1515. // Unmarshall.
  1516. //
  1517. hr = SetBOOLPropertyInCache(
  1518. _pPropertyCache,
  1519. TEXT("PasswordCanExpire"),
  1520. dwBool,
  1521. fExplicit
  1522. );
  1523. RRETURN(hr);
  1524. }
  1525. //----------------------------------------------------------------------------
  1526. //
  1527. // Function: CNWCOMPATUser::GetProperty_PasswordExpirationDate
  1528. //
  1529. // Synopsis:
  1530. //
  1531. //----------------------------------------------------------------------------
  1532. HRESULT
  1533. CNWCOMPATUser::GetProperty_PasswordExpirationDate(
  1534. NWCONN_HANDLE hConn,
  1535. LC_STRUCTURE LoginCtrlStruct,
  1536. BOOL fExplicit
  1537. )
  1538. {
  1539. HRESULT hr = S_OK;
  1540. BYTE byDateTime[6];
  1541. memset(byDateTime, 0, 6);
  1542. memcpy(byDateTime, LoginCtrlStruct.byPasswordExpires, 3);
  1543. hr = SetNw312DATEPropertyInCache(
  1544. _pPropertyCache,
  1545. TEXT("PasswordExpirationDate"),
  1546. byDateTime,
  1547. fExplicit
  1548. );
  1549. RRETURN(hr);
  1550. }
  1551. //----------------------------------------------------------------------------
  1552. //
  1553. // Function: CNWCOMPATUser::GetProperty_PasswordMinimumLength
  1554. //
  1555. // Synopsis:
  1556. //
  1557. //----------------------------------------------------------------------------
  1558. HRESULT
  1559. CNWCOMPATUser::GetProperty_PasswordMinimumLength(
  1560. NWCONN_HANDLE hConn,
  1561. LC_STRUCTURE LoginCtrlStruct,
  1562. BOOL fExplicit
  1563. )
  1564. {
  1565. HRESULT hr = S_OK;
  1566. LONG lMinimumLength = 0;
  1567. //
  1568. // Get "byMinPasswordLength".
  1569. //
  1570. lMinimumLength = (LONG) LoginCtrlStruct.byMinPasswordLength;
  1571. //
  1572. // Unmarshall.
  1573. //
  1574. hr = SetDWORDPropertyInCache(
  1575. _pPropertyCache,
  1576. TEXT("PasswordMinimumLength"),
  1577. (DWORD)lMinimumLength,
  1578. fExplicit
  1579. );
  1580. RRETURN(hr);
  1581. }
  1582. //----------------------------------------------------------------------------
  1583. //
  1584. // Function: CNWCOMPATUser::GetProperty_PasswordRequired
  1585. //
  1586. // Synopsis:
  1587. //
  1588. //----------------------------------------------------------------------------
  1589. HRESULT
  1590. CNWCOMPATUser::GetProperty_PasswordRequired(
  1591. NWCONN_HANDLE hConn,
  1592. LC_STRUCTURE LoginCtrlStruct,
  1593. BOOL fExplicit
  1594. )
  1595. {
  1596. BOOL dwBool = TRUE;
  1597. HRESULT hr = S_OK;
  1598. //
  1599. // Password is not required if "byMinPasswordLength" is 0.
  1600. //
  1601. if (LoginCtrlStruct.byMinPasswordLength == 0) {
  1602. dwBool = FALSE;
  1603. }
  1604. //
  1605. // Unmarshall.
  1606. //
  1607. hr = SetBOOLPropertyInCache(
  1608. _pPropertyCache,
  1609. TEXT("PasswordRequired"),
  1610. dwBool,
  1611. fExplicit
  1612. );
  1613. RRETURN(hr);
  1614. }
  1615. //----------------------------------------------------------------------------
  1616. //
  1617. // Function: CNWCOMPATUser::GetProperty_RequireUniquePassword
  1618. //
  1619. // Synopsis:
  1620. //
  1621. //----------------------------------------------------------------------------
  1622. HRESULT
  1623. CNWCOMPATUser::GetProperty_RequireUniquePassword(
  1624. NWCONN_HANDLE hConn,
  1625. LC_STRUCTURE LoginCtrlStruct,
  1626. BOOL fExplicit
  1627. )
  1628. {
  1629. BOOL dwBool = TRUE;
  1630. HRESULT hr = S_OK;
  1631. //
  1632. // If byRestrictions = 0, "RequireUniquePassword" = FALSE.
  1633. //
  1634. if (LoginCtrlStruct.byRestrictions == 0) {
  1635. dwBool = FALSE;
  1636. }
  1637. //
  1638. // Unmarshall.
  1639. //
  1640. hr = SetBOOLPropertyInCache(
  1641. _pPropertyCache,
  1642. TEXT("RequireUniquePassword"),
  1643. dwBool,
  1644. fExplicit
  1645. );
  1646. RRETURN(hr);
  1647. }
  1648. HRESULT
  1649. CNWCOMPATUser::GetProperty_LoginHours(
  1650. NWCONN_HANDLE hConn,
  1651. LC_STRUCTURE LoginCtrlStruct,
  1652. BOOL fExplicit
  1653. )
  1654. {
  1655. BOOL dwBool = TRUE;
  1656. HRESULT hr = S_OK;
  1657. //
  1658. // Unmarshall.
  1659. //
  1660. hr = SetOctetPropertyInCache(
  1661. _pPropertyCache,
  1662. TEXT("LoginHours"),
  1663. (BYTE*)LoginCtrlStruct.byLoginTimes,
  1664. 42,
  1665. fExplicit
  1666. );
  1667. RRETURN(hr);
  1668. }
  1669. //----------------------------------------------------------------------------
  1670. //
  1671. // Function: CNWCOMPATUser::GetProperty_BadLoginAddress
  1672. //
  1673. // Synopsis:
  1674. //
  1675. //----------------------------------------------------------------------------
  1676. HRESULT
  1677. CNWCOMPATUser::GetProperty_BadLoginAddress(
  1678. NWCONN_HANDLE hConn,
  1679. LC_STRUCTURE LoginCtrlStruct,
  1680. BOOL fExplicit
  1681. )
  1682. {
  1683. HRESULT hr = S_OK;
  1684. LPWSTR lpszTemp = NULL;
  1685. //
  1686. // Put address together in the format described in spec.
  1687. //
  1688. lpszTemp = (LPWSTR) AllocADsMem((NET_ADDRESS_NUM_CHAR+1)*sizeof(WCHAR));
  1689. if (!lpszTemp) {
  1690. RRETURN(E_OUTOFMEMORY);
  1691. }
  1692. wsprintf(
  1693. lpszTemp,
  1694. L"%s:%02X%02X%02X%02X.%02X%02X%02X%02X%02X%02X.%02X%02X",
  1695. bstrAddressTypeString,
  1696. LoginCtrlStruct.byBadLoginAddr[10],
  1697. LoginCtrlStruct.byBadLoginAddr[11],
  1698. LoginCtrlStruct.byBadLoginAddr[0],
  1699. LoginCtrlStruct.byBadLoginAddr[1],
  1700. LoginCtrlStruct.byBadLoginAddr[2],
  1701. LoginCtrlStruct.byBadLoginAddr[3],
  1702. LoginCtrlStruct.byBadLoginAddr[4],
  1703. LoginCtrlStruct.byBadLoginAddr[5],
  1704. LoginCtrlStruct.byBadLoginAddr[6],
  1705. LoginCtrlStruct.byBadLoginAddr[7],
  1706. LoginCtrlStruct.byBadLoginAddr[8],
  1707. LoginCtrlStruct.byBadLoginAddr[9]
  1708. );
  1709. //
  1710. // Unmarshall.
  1711. //
  1712. hr = SetLPTSTRPropertyInCache(
  1713. _pPropertyCache,
  1714. TEXT("BadLoginAddress"),
  1715. (LPWSTR)lpszTemp,
  1716. fExplicit
  1717. );
  1718. BAIL_ON_FAILURE(hr);
  1719. error:
  1720. if (lpszTemp) {
  1721. FreeADsMem(lpszTemp);
  1722. }
  1723. RRETURN(hr);
  1724. }
  1725. //----------------------------------------------------------------------------
  1726. //
  1727. // Function: CNWCOMPATUser::GetProperty_LastLogin
  1728. //
  1729. // Synopsis:
  1730. //
  1731. //----------------------------------------------------------------------------
  1732. HRESULT
  1733. CNWCOMPATUser::GetProperty_LastLogin(
  1734. NWCONN_HANDLE hConn,
  1735. LC_STRUCTURE LoginCtrlStruct,
  1736. BOOL fExplicit
  1737. )
  1738. {
  1739. HRESULT hr = S_OK;
  1740. BYTE byNoDateTime[6];
  1741. memset(byNoDateTime, 0, 6);
  1742. //
  1743. // LastLogin==000000 indicates no or unknown LastLogin
  1744. //
  1745. if (memcmp(LoginCtrlStruct.byLastLogin, byNoDateTime, 6) != 0) {
  1746. hr = SetNw312DATEPropertyInCache(
  1747. _pPropertyCache,
  1748. TEXT("LastLogin"),
  1749. LoginCtrlStruct.byLastLogin,
  1750. fExplicit
  1751. );
  1752. }
  1753. RRETURN(hr);
  1754. }
  1755. HRESULT
  1756. ConvertNW312DateToVariant(
  1757. BYTE byDateTime[],
  1758. PDATE pDate
  1759. )
  1760. {
  1761. HRESULT hr = S_OK;
  1762. WORD wYear;
  1763. //
  1764. // Subtract 80 from wYear for NWApiMakeVariantTime.
  1765. //
  1766. wYear = (WORD)byDateTime[0];
  1767. if (wYear != 0) {
  1768. wYear -= 80;
  1769. }
  1770. //
  1771. // Convert into Variant Time.
  1772. //
  1773. hr = NWApiMakeVariantTime(
  1774. pDate,
  1775. (WORD)byDateTime[2],
  1776. (WORD)byDateTime[1],
  1777. wYear,
  1778. 0,0,0
  1779. );
  1780. RRETURN(hr);
  1781. }
  1782. HRESULT
  1783. ConvertVariantToNW312Date(
  1784. DATE daDate,
  1785. BYTE byDateTime[]
  1786. )
  1787. {
  1788. WORD wDay;
  1789. WORD wYear;
  1790. WORD wMonth;
  1791. HRESULT hr = S_OK;
  1792. hr = NWApiBreakVariantTime(
  1793. daDate,
  1794. &wDay,
  1795. &wMonth,
  1796. &wYear
  1797. );
  1798. BAIL_ON_FAILURE(hr);
  1799. byDateTime[0] = (BYTE)wYear;
  1800. byDateTime[1] = (BYTE)wMonth;
  1801. byDateTime[2] = (BYTE)wDay;
  1802. byDateTime[3] = 0;
  1803. byDateTime[4] = 0;
  1804. byDateTime[5] = 0;
  1805. error:
  1806. RRETURN(hr);
  1807. }