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.

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