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.

1023 lines
22 KiB

  1. krishna says this file should be removed
  2. //---------------------------------------------------------------------------
  3. //
  4. //
  5. // Microsoft Windows
  6. // Copyright (C) Microsoft Corporation, 1992 - 1996
  7. //
  8. // File: cdomain.cxx
  9. //
  10. // Contents: Windows NT 3.5
  11. //
  12. //
  13. // History: 09-23-96 yihsins Created.
  14. //
  15. //----------------------------------------------------------------------------
  16. #include "ldap.hxx"
  17. #pragma hdrstop
  18. DECLARE_INFOLEVEL( Domain );
  19. DECLARE_DEBUG( Domain );
  20. #define DomainDebugOut(x) DomainInlineDebugOut x
  21. struct _propmap
  22. {
  23. LPTSTR pszADsProp;
  24. LPTSTR pszLDAPProp;
  25. } aDomainPropMapping[] =
  26. { { TEXT("MinPasswordLength"), TEXT("minPwdLength") },
  27. { TEXT("MinPasswordAge"), TEXT("minPwdAge") },
  28. { TEXT("MaxPasswordAge"), TEXT("maxPwdAge") },
  29. { TEXT("MaxBadPasswordsAllowed"), TEXT("lockoutThreshold") },
  30. { TEXT("PasswordHistoryLength"), TEXT("pwdHistoryLength") },
  31. { TEXT("PasswordAttributes"), TEXT("pwdProperties") },
  32. { TEXT("AutoUnlockInterval"), TEXT("lockoutDuration") },
  33. { TEXT("LockoutObservationInterval"), TEXT("lockOutObservationWindow") },
  34. // { TEXT("IsWorkgroup"), TEXT("IsWorkgroup") }, // ???
  35. };
  36. //
  37. // Class CLDAPDomain
  38. //
  39. DEFINE_IDispatch_Implementation(CLDAPDomain)
  40. DEFINE_CONTAINED_IADs_Implementation(CLDAPDomain)
  41. DEFINE_CONTAINED_IADsContainer_Implementation(CLDAPDomain)
  42. DEFINE_CONTAINED_IDirectoryObject_Implementation(CLDAPDomain)
  43. DEFINE_CONTAINED_IDirectorySearch_Implementation(CLDAPDomain)
  44. DEFINE_CONTAINED_IDirectorySchemaMgmt_Implementation(CLDAPDomain)
  45. DEFINE_CONTAINED_IADsPutGet_Implementation(CLDAPDomain, aDomainPropMapping)
  46. DEFINE_CONTAINED_IADsPropertyList_Implementation(CLDAPDomain)
  47. CLDAPDomain::CLDAPDomain()
  48. : _pADs(NULL),
  49. _pADsContainer(NULL),
  50. _pDSObject(NULL),
  51. _pDSSearch(NULL),
  52. _pDispMgr(NULL),
  53. _pDSSchMgmt(NULL),
  54. _pADsPropList(NULL)
  55. {
  56. ENLIST_TRACKING(CLDAPDomain);
  57. }
  58. HRESULT
  59. CLDAPDomain::CreateDomain(
  60. IADs *pADs,
  61. REFIID riid,
  62. void **ppvObj
  63. )
  64. {
  65. CLDAPDomain FAR * pDomain = NULL;
  66. HRESULT hr = S_OK;
  67. hr = AllocateDomainObject( pADs, &pDomain);
  68. BAIL_ON_FAILURE(hr);
  69. hr = pDomain->QueryInterface( riid, ppvObj);
  70. BAIL_ON_FAILURE(hr);
  71. pDomain->Release();
  72. RRETURN(hr);
  73. error:
  74. *ppvObj = NULL;
  75. delete pDomain;
  76. RRETURN(hr);
  77. }
  78. CLDAPDomain::~CLDAPDomain( )
  79. {
  80. if ( _pADs )
  81. _pADs->Release();
  82. if ( _pADsContainer )
  83. _pADsContainer->Release();
  84. if ( _pDSObject )
  85. _pDSObject->Release();
  86. if ( _pDSSearch )
  87. _pDSSearch->Release();
  88. if ( _pDSSchMgmt )
  89. _pDSSchMgmt->Release();
  90. if (_pADsPropList) {
  91. _pADsPropList->Release();
  92. }
  93. delete _pDispMgr;
  94. }
  95. STDMETHODIMP
  96. CLDAPDomain::QueryInterface(
  97. REFIID iid,
  98. LPVOID FAR* ppv
  99. )
  100. {
  101. if (IsEqualIID(iid, IID_IUnknown))
  102. {
  103. *ppv = (IADsDomain FAR *) this;
  104. }
  105. else if (IsEqualIID(iid, IID_IADsDomain))
  106. {
  107. *ppv = (IADsDomain FAR *) this;
  108. }
  109. else if (IsEqualIID(iid, IID_IADsContainer) && _pADsContainer )
  110. {
  111. *ppv = (IADsContainer FAR *) this;
  112. }
  113. else if (IsEqualIID(iid, IID_IDirectoryObject) && _pDSObject )
  114. {
  115. *ppv = (IDirectoryObject FAR *) this;
  116. }
  117. else if (IsEqualIID(iid, IID_IDirectorySearch) && _pDSSearch )
  118. {
  119. *ppv = (IDirectorySearch FAR *) this;
  120. }
  121. else if (IsEqualIID(iid, IID_IDirectorySchemaMgmt) && _pDSSchMgmt )
  122. {
  123. *ppv = (IDirectorySchemaMgmt FAR *) this;
  124. }
  125. else if (IsEqualIID(iid, IID_IADsPropertyList) && _pADsPropList )
  126. {
  127. *ppv = (IADsPropertyList FAR *) this;
  128. }
  129. else if (IsEqualIID(iid, IID_IADs))
  130. {
  131. *ppv = (IADs FAR *) this;
  132. }
  133. else if (IsEqualIID(iid, IID_IDispatch))
  134. {
  135. *ppv = (IADs FAR *) this;
  136. }
  137. else
  138. {
  139. *ppv = NULL;
  140. return E_NOINTERFACE;
  141. }
  142. AddRef();
  143. return NOERROR;
  144. }
  145. HRESULT
  146. CLDAPDomain::AllocateDomainObject(
  147. IADs *pADs,
  148. CLDAPDomain **ppDomain
  149. )
  150. {
  151. CLDAPDomain FAR * pDomain = NULL;
  152. CAggregateeDispMgr FAR * pDispMgr = NULL;
  153. HRESULT hr = S_OK;
  154. IADsContainer FAR * pADsContainer = NULL;
  155. IDirectoryObject FAR * pDSObject = NULL;
  156. IDirectorySearch FAR * pDSSearch= NULL;
  157. IDirectorySchemaMgmt FAR * pDSSchMgmt= NULL;
  158. IADsPropertyList FAR * pADsPropList = NULL;
  159. IDispatch *pDispatch = NULL;
  160. pDomain = new CLDAPDomain();
  161. if (pDomain == NULL) {
  162. hr = E_OUTOFMEMORY;
  163. }
  164. BAIL_ON_FAILURE(hr);
  165. pDispMgr = new CAggregateeDispMgr;
  166. if (pDispMgr == NULL) {
  167. hr = E_OUTOFMEMORY;
  168. }
  169. BAIL_ON_FAILURE(hr);
  170. hr = pDispMgr->LoadTypeInfoEntry(
  171. LIBID_ADs,
  172. IID_IADsDomain,
  173. (IADsDomain *)pDomain,
  174. DISPID_REGULAR
  175. );
  176. BAIL_ON_FAILURE(hr);
  177. hr = pDispMgr->LoadTypeInfoEntry(
  178. LIBID_ADs,
  179. IID_IADsContainer,
  180. (IADsContainer *)pDomain,
  181. DISPID_NEWENUM
  182. );
  183. BAIL_ON_FAILURE(hr);
  184. hr = pDispMgr->LoadTypeInfoEntry(
  185. LIBID_ADs,
  186. IID_IADsPropertyList,
  187. (IADsPropertyList *)pADsPropList,
  188. DISPID_VALUE
  189. );
  190. BAIL_ON_FAILURE(hr);
  191. hr = pADs->QueryInterface(IID_IDispatch, (void **)&pDispatch);
  192. BAIL_ON_FAILURE(hr);
  193. pDispMgr->RegisterBaseDispatchPtr(pDispatch);
  194. //
  195. // Store a pointer to the Container interface
  196. //
  197. hr = pADs->QueryInterface(
  198. IID_IADsContainer,
  199. (void **)&pADsContainer
  200. );
  201. BAIL_ON_FAILURE(hr);
  202. pDomain->_pADsContainer = pADsContainer;
  203. //
  204. // Store a pointer to the DSObject interface
  205. //
  206. hr = pADs->QueryInterface(
  207. IID_IDirectoryObject,
  208. (void **)&pDSObject
  209. );
  210. BAIL_ON_FAILURE(hr);
  211. pDomain->_pDSObject = pDSObject;
  212. //
  213. // Store a pointer to the DSSearch interface
  214. //
  215. hr = pADs->QueryInterface(
  216. IID_IDirectorySearch,
  217. (void **)&pDSSearch
  218. );
  219. BAIL_ON_FAILURE(hr);
  220. pDomain->_pDSSearch= pDSSearch;
  221. hr = pADs->QueryInterface(
  222. IID_IADsPropertyList,
  223. (void **)&pADsPropList
  224. );
  225. BAIL_ON_FAILURE(hr);
  226. pDomain->_pADsPropList = pADsPropList;
  227. //
  228. // Store a pointer to the DSSchMgmt interface
  229. //
  230. hr = pADs->QueryInterface(
  231. IID_IDirectorySchemaMgmt,
  232. (void **)&pDSSchMgmt
  233. );
  234. BAIL_ON_FAILURE(hr);
  235. pDomain->_pDSSchMgmt= pDSSchMgmt;
  236. //
  237. // Store the pointer to the internal generic object
  238. // AND add ref this pointer
  239. //
  240. pDomain->_pADs = pADs;
  241. pADs->AddRef();
  242. pDomain->_pDispMgr = pDispMgr;
  243. *ppDomain = pDomain;
  244. RRETURN(hr);
  245. error:
  246. delete pDispMgr;
  247. delete pDomain;
  248. RRETURN(hr);
  249. }
  250. /* IADsContainer methods */
  251. #if 0
  252. STDMETHODIMP
  253. CLDAPDomain::get__NewEnum(
  254. THIS_ IUnknown * FAR* retval
  255. )
  256. {
  257. HRESULT hr;
  258. IUnknown FAR* punkEnum=NULL;
  259. IEnumVARIANT * penum = NULL;
  260. *retval = NULL;
  261. hr = CLDAPDomainEnum::Create(
  262. (CLDAPDomainEnum **)&penum,
  263. _ADsPath,
  264. _Name,
  265. _vFilter
  266. );
  267. BAIL_ON_FAILURE(hr);
  268. hr = penum->QueryInterface(
  269. IID_IUnknown,
  270. (VOID FAR* FAR*)retval
  271. );
  272. BAIL_ON_FAILURE(hr);
  273. if (penum) {
  274. penum->Release();
  275. }
  276. RRETURN(NOERROR);
  277. error:
  278. if (penum) {
  279. delete penum;
  280. }
  281. RRETURN(hr);
  282. }
  283. STDMETHODIMP
  284. CLDAPDomain::Create(
  285. THIS_ BSTR ClassName,
  286. BSTR RelativeName,
  287. IUnknown * FAR* ppObject
  288. )
  289. {
  290. ULONG ObjectType = 0;
  291. HRESULT hr;
  292. POBJECTINFO pObjectInfo = NULL;
  293. hr = GetObjectType(
  294. gpFilters,
  295. gdwMaxFilters,
  296. ClassName,
  297. (PDWORD)&ObjectType
  298. );
  299. BAIL_ON_FAILURE(hr);
  300. hr = BuildObjectInfo(
  301. _ADsPath,
  302. RelativeName,
  303. &pObjectInfo
  304. );
  305. BAIL_ON_FAILURE(hr);
  306. hr = ValidateObject(
  307. ObjectType,
  308. pObjectInfo
  309. );
  310. if (SUCCEEDED(hr)) {
  311. hr = HRESULT_FROM_WIN32(NERR_ResourceExists);
  312. BAIL_ON_FAILURE(hr);
  313. }
  314. switch (ObjectType) {
  315. case WINNT_USER_ID:
  316. hr = CWinNTUser::CreateUser(
  317. _ADsPath,
  318. WINNT_DOMAIN_ID,
  319. _Name,
  320. NULL,
  321. RelativeName,
  322. ADS_OBJECT_UNBOUND,
  323. IID_IUnknown,
  324. (void **)ppObject
  325. );
  326. BAIL_ON_FAILURE(hr);
  327. break;
  328. case WINNT_GROUP_ID:
  329. hr = CWinNTGroup::CreateGroup(
  330. _ADsPath,
  331. WINNT_DOMAIN_ID,
  332. _Name,
  333. NULL,
  334. RelativeName,
  335. WINNT_GROUP_GLOBAL,
  336. ADS_OBJECT_UNBOUND,
  337. IID_IUnknown,
  338. (void **)ppObject
  339. );
  340. BAIL_ON_FAILURE(hr);
  341. break;
  342. case WINNT_COMPUTER_ID:
  343. hr = E_NOTIMPL;
  344. /*hr = CWinNTComputer::CreateComputer(
  345. _ADsPath,
  346. _Name,
  347. RelativeName,
  348. ADS_OBJECT_UNBOUND,
  349. IID_IUnknown,
  350. (void **)ppObject
  351. );*/
  352. BAIL_ON_FAILURE(hr);
  353. break;
  354. default:
  355. RRETURN(E_ADS_UNKNOWN_OBJECT);
  356. }
  357. error:
  358. RRETURN(hr);
  359. }
  360. STDMETHODIMP
  361. CLDAPDomain::Delete(
  362. BSTR bstrClassName,
  363. BSTR bstrSourceName
  364. )
  365. {
  366. ULONG ObjectType = 0;
  367. POBJECTINFO pObjectInfo = NULL;
  368. BOOL fStatus = FALSE;
  369. HRESULT hr = S_OK;
  370. WCHAR szUncServerName[MAX_PATH];
  371. hr = GetObjectType(gpFilters,
  372. gdwMaxFilters,
  373. bstrClassName,
  374. (PDWORD)&ObjectType
  375. );
  376. BAIL_ON_FAILURE(hr);
  377. hr = BuildObjectInfo(
  378. _ADsPath,
  379. bstrSourceName,
  380. &pObjectInfo
  381. );
  382. BAIL_ON_FAILURE(hr);
  383. switch (ObjectType) {
  384. case WINNT_USER_ID:
  385. hr = WinNTDeleteUser(pObjectInfo);
  386. BAIL_ON_FAILURE(hr);
  387. break;
  388. case WINNT_GROUP_ID:
  389. hr = WinNTDeleteGroup(pObjectInfo);
  390. BAIL_ON_FAILURE(hr);
  391. break;
  392. case WINNT_COMPUTER_ID:
  393. hr = WinNTDeleteComputer(pObjectInfo);
  394. BAIL_ON_FAILURE(hr);
  395. break;
  396. default:
  397. hr = E_ADS_UNKNOWN_OBJECT;
  398. BAIL_ON_FAILURE(hr);
  399. }
  400. RRETURN(hr);
  401. error:
  402. if (pObjectInfo) {
  403. FreeObjectInfo(pObjectInfo);
  404. }
  405. RRETURN(hr);
  406. }
  407. #endif
  408. /* IADsDomain methods */
  409. STDMETHODIMP
  410. CLDAPDomain::get_IsWorkgroup(THIS_ VARIANT_BOOL FAR* retval)
  411. {
  412. RRETURN(E_NOTIMPL);
  413. }
  414. STDMETHODIMP
  415. CLDAPDomain::get_MinPasswordLength(THIS_ long FAR* retval)
  416. {
  417. GET_PROPERTY_LONG((IADsDomain *)this, MinPasswordLength);
  418. }
  419. STDMETHODIMP
  420. CLDAPDomain::put_MinPasswordLength(THIS_ long lMinPasswordLength)
  421. {
  422. PUT_PROPERTY_LONG((IADsDomain *)this, MinPasswordLength);
  423. }
  424. STDMETHODIMP
  425. CLDAPDomain::get_MinPasswordAge(THIS_ long FAR* retval)
  426. {
  427. GET_PROPERTY_LONG((IADsDomain *)this, MinPasswordAge);
  428. }
  429. STDMETHODIMP CLDAPDomain::put_MinPasswordAge(THIS_ long lMinPasswordAge)
  430. {
  431. PUT_PROPERTY_LONG((IADsDomain *)this, MinPasswordAge);
  432. }
  433. STDMETHODIMP CLDAPDomain::get_MaxPasswordAge(THIS_ long FAR* retval)
  434. {
  435. GET_PROPERTY_LONG((IADsDomain *)this, MaxPasswordAge);
  436. }
  437. STDMETHODIMP CLDAPDomain::put_MaxPasswordAge(THIS_ long lMaxPasswordAge)
  438. {
  439. PUT_PROPERTY_LONG((IADsDomain *)this, MaxPasswordAge);
  440. }
  441. STDMETHODIMP CLDAPDomain::get_MaxBadPasswordsAllowed(THIS_ long FAR* retval)
  442. {
  443. GET_PROPERTY_LONG((IADsDomain *)this, MaxBadPasswordsAllowed);
  444. }
  445. STDMETHODIMP CLDAPDomain::put_MaxBadPasswordsAllowed(THIS_ long lMaxBadPasswordsAllowed)
  446. {
  447. PUT_PROPERTY_LONG((IADsDomain *)this, MaxBadPasswordsAllowed);
  448. }
  449. STDMETHODIMP CLDAPDomain::get_PasswordHistoryLength(THIS_ long FAR* retval)
  450. {
  451. GET_PROPERTY_LONG((IADsDomain *)this, PasswordHistoryLength);
  452. }
  453. STDMETHODIMP CLDAPDomain::put_PasswordHistoryLength(THIS_ long lPasswordHistoryLength)
  454. {
  455. PUT_PROPERTY_LONG((IADsDomain *)this, PasswordHistoryLength);
  456. }
  457. STDMETHODIMP CLDAPDomain::get_PasswordAttributes(THIS_ long FAR* retval)
  458. {
  459. GET_PROPERTY_LONG((IADsDomain *)this, PasswordAttributes);
  460. }
  461. STDMETHODIMP CLDAPDomain::put_PasswordAttributes(THIS_ long lPasswordAttributes)
  462. {
  463. PUT_PROPERTY_LONG((IADsDomain *)this, PasswordAttributes);
  464. }
  465. STDMETHODIMP CLDAPDomain::get_AutoUnlockInterval(THIS_ long FAR* retval)
  466. {
  467. GET_PROPERTY_LONG((IADsDomain *)this, AutoUnlockInterval);
  468. }
  469. STDMETHODIMP CLDAPDomain::put_AutoUnlockInterval(THIS_ long lAutoUnlockInterval)
  470. {
  471. PUT_PROPERTY_LONG((IADsDomain *)this, AutoUnlockInterval);
  472. }
  473. STDMETHODIMP CLDAPDomain::get_LockoutObservationInterval(THIS_ long FAR* retval)
  474. {
  475. GET_PROPERTY_LONG((IADsDomain *)this, LockoutObservationInterval);
  476. }
  477. STDMETHODIMP CLDAPDomain::put_LockoutObservationInterval(THIS_ long lLockoutObservationInterval)
  478. {
  479. PUT_PROPERTY_LONG((IADsDomain *)this, LockoutObservationInterval);
  480. }
  481. #if 0
  482. STDMETHODIMP
  483. CLDAPDomain::SetInfo(THIS)
  484. {
  485. HRESULT hr;
  486. hr = SetInfo(0);
  487. hr = SetInfo(2);
  488. hr = SetInfo(3);
  489. RRETURN(hr);
  490. }
  491. STDMETHODIMP
  492. CLDAPDomain::GetInfo(THIS)
  493. {
  494. HRESULT hr;
  495. hr = GetInfo(0, TRUE);
  496. hr = GetInfo(2, TRUE);
  497. hr = GetInfo(3, TRUE);
  498. RRETURN(hr);
  499. }
  500. STDMETHODIMP
  501. CLDAPDomain::GetInfo(
  502. THIS_ DWORD dwApiLevel,
  503. BOOL fExplicit
  504. )
  505. {
  506. NET_API_STATUS nasStatus;
  507. LPBYTE lpBuffer = NULL;
  508. HRESULT hr;
  509. WCHAR szPDCName[MAX_PATH];
  510. hr = WinNTGetCachedPDCName(
  511. _Name,
  512. szPDCName
  513. );
  514. BAIL_ON_FAILURE(hr);
  515. nasStatus = NetUserModalsGet(
  516. szPDCName,
  517. dwApiLevel,
  518. &lpBuffer
  519. );
  520. hr = HRESULT_FROM_WIN32(nasStatus);
  521. BAIL_ON_FAILURE(hr);
  522. hr = UnMarshall(lpBuffer, dwApiLevel, fExplicit);
  523. BAIL_ON_FAILURE(hr);
  524. error:
  525. if (lpBuffer) {
  526. NetApiBufferFree(lpBuffer);
  527. }
  528. RRETURN(hr);
  529. }
  530. HRESULT
  531. CLDAPDomain::UnMarshall(
  532. LPBYTE lpBuffer,
  533. DWORD dwApiLevel,
  534. BOOL fExplicit
  535. )
  536. {
  537. ADsAssert(lpBuffer);
  538. switch (dwApiLevel) {
  539. case 0:
  540. RRETURN(UnMarshall_Level0(fExplicit, (LPUSER_MODALS_INFO_0)lpBuffer));
  541. break;
  542. case 2:
  543. RRETURN(UnMarshall_Level2(fExplicit, (LPUSER_MODALS_INFO_2)lpBuffer));
  544. break;
  545. case 3:
  546. RRETURN(UnMarshall_Level3(fExplicit, (LPUSER_MODALS_INFO_3)lpBuffer));
  547. break;
  548. default:
  549. RRETURN(E_FAIL);
  550. }
  551. }
  552. HRESULT
  553. CLDAPDomain::UnMarshall_Level0(
  554. BOOL fExplicit,
  555. LPUSER_MODALS_INFO_0 pUserInfo0
  556. )
  557. {
  558. HRESULT hr = S_OK;
  559. hr = SetDWORDPropertyInCache(
  560. _pPropertyCache,
  561. TEXT("MinPasswordLength"),
  562. pUserInfo0->usrmod0_min_passwd_len,
  563. fExplicit
  564. );
  565. hr = SetDWORDPropertyInCache(
  566. _pPropertyCache,
  567. TEXT("MaxPasswordAge"),
  568. pUserInfo0->usrmod0_max_passwd_age,
  569. fExplicit
  570. );
  571. hr = SetDWORDPropertyInCache(
  572. _pPropertyCache,
  573. TEXT("MinPasswordAge"),
  574. pUserInfo0->usrmod0_min_passwd_age,
  575. fExplicit
  576. );
  577. hr = SetDWORDPropertyInCache(
  578. _pPropertyCache,
  579. TEXT("PasswordHistoryLength"),
  580. pUserInfo0->usrmod0_password_hist_len,
  581. fExplicit
  582. );
  583. RRETURN(S_OK);
  584. }
  585. HRESULT
  586. CLDAPDomain::UnMarshall_Level2(
  587. BOOL fExplicit,
  588. LPUSER_MODALS_INFO_2 pUserInfo2
  589. )
  590. {
  591. RRETURN(S_OK);
  592. }
  593. HRESULT
  594. CLDAPDomain::UnMarshall_Level3(
  595. BOOL fExplicit,
  596. LPUSER_MODALS_INFO_3 pUserInfo3
  597. )
  598. {
  599. HRESULT hr = S_OK;
  600. hr = SetDWORDPropertyInCache(
  601. _pPropertyCache,
  602. TEXT("AutoUnlockInterval"),
  603. pUserInfo3->usrmod3_lockout_duration,
  604. fExplicit
  605. );
  606. hr = SetDWORDPropertyInCache(
  607. _pPropertyCache,
  608. TEXT("LockoutObservationInterval"),
  609. pUserInfo3->usrmod3_lockout_observation_window,
  610. fExplicit
  611. );
  612. hr = SetDWORDPropertyInCache(
  613. _pPropertyCache,
  614. TEXT("MaxBadPasswordsAllowed"),
  615. pUserInfo3->usrmod3_lockout_threshold,
  616. fExplicit
  617. );
  618. RRETURN(S_OK);
  619. }
  620. STDMETHODIMP
  621. CLDAPDomain::SetInfo(THIS_ DWORD dwApiLevel)
  622. {
  623. NET_API_STATUS nasStatus;
  624. HRESULT hr;
  625. LPBYTE lpBuffer = NULL;
  626. DWORD dwParamErr = 0;
  627. WCHAR szPDCName[MAX_PATH];
  628. hr = WinNTGetCachedPDCName(
  629. _Name,
  630. szPDCName
  631. );
  632. BAIL_ON_FAILURE(hr);
  633. nasStatus = NetUserModalsGet(
  634. szPDCName,
  635. dwApiLevel,
  636. &lpBuffer
  637. );
  638. hr = HRESULT_FROM_WIN32(nasStatus);
  639. BAIL_ON_FAILURE(hr);
  640. hr = MarshallAndSet(szPDCName, lpBuffer, dwApiLevel);
  641. BAIL_ON_FAILURE(hr);
  642. error:
  643. if (lpBuffer) {
  644. NetApiBufferFree(lpBuffer);
  645. }
  646. RRETURN(hr);
  647. }
  648. HRESULT
  649. CLDAPDomain::MarshallAndSet(
  650. LPWSTR szServerName,
  651. LPBYTE lpBuffer,
  652. DWORD dwApiLevel
  653. )
  654. {
  655. ADsAssert(lpBuffer);
  656. switch (dwApiLevel) {
  657. case 0:
  658. RRETURN(Marshall_Set_Level0(
  659. szServerName,
  660. (LPUSER_MODALS_INFO_0)lpBuffer
  661. ));
  662. break;
  663. case 2:
  664. RRETURN(Marshall_Set_Level2(
  665. szServerName,
  666. (LPUSER_MODALS_INFO_2)lpBuffer
  667. ));
  668. break;
  669. case 3:
  670. RRETURN(Marshall_Set_Level3(
  671. szServerName,
  672. (LPUSER_MODALS_INFO_3)lpBuffer
  673. ));
  674. break;
  675. default:
  676. RRETURN(E_FAIL);
  677. }
  678. }
  679. HRESULT
  680. CLDAPDomain::Marshall_Set_Level0(
  681. LPWSTR szServerName,
  682. LPUSER_MODALS_INFO_0 pUserInfo0)
  683. {
  684. NET_API_STATUS nasStatus;
  685. DWORD dwParamErr = 0;
  686. HRESULT hr = S_OK;
  687. DWORD dwMinPasswdLen = 0;
  688. DWORD dwMaxPasswdAge = 0;
  689. DWORD dwMinPasswdAge = 0;
  690. DWORD dwPasswdHistLen = 0;
  691. hr = GetDWORDPropertyFromCache(
  692. _pPropertyCache,
  693. TEXT("MinPasswordLength"),
  694. &dwMinPasswdLen
  695. );
  696. if (SUCCEEDED(hr)) {
  697. pUserInfo0->usrmod0_min_passwd_len = dwMinPasswdLen;
  698. }
  699. hr = GetDWORDPropertyFromCache(
  700. _pPropertyCache,
  701. TEXT("MaxPasswordAge"),
  702. &dwMaxPasswdAge
  703. );
  704. if (SUCCEEDED(hr)) {
  705. pUserInfo0->usrmod0_max_passwd_age = dwMaxPasswdAge;
  706. }
  707. hr = GetDWORDPropertyFromCache(
  708. _pPropertyCache,
  709. TEXT("MinPasswordAge"),
  710. &dwMinPasswdAge
  711. );
  712. if (SUCCEEDED(hr)) {
  713. pUserInfo0->usrmod0_min_passwd_age = dwMinPasswdAge;
  714. }
  715. hr = GetDWORDPropertyFromCache(
  716. _pPropertyCache,
  717. TEXT("PasswordHistoryLength"),
  718. &dwPasswdHistLen
  719. );
  720. if (SUCCEEDED(hr)) {
  721. pUserInfo0->usrmod0_password_hist_len = dwPasswdHistLen;
  722. }
  723. //
  724. // Now Set this Data. Remember that the property store
  725. // returns to us data in its own format. It is the caller's
  726. // responsibility to free all buffers for bstrs, variants
  727. // etc
  728. //
  729. nasStatus = NetUserModalsSet(
  730. szServerName,
  731. 0,
  732. (LPBYTE)pUserInfo0,
  733. &dwParamErr
  734. );
  735. hr = HRESULT_FROM_WIN32(nasStatus);
  736. BAIL_ON_FAILURE(hr);
  737. error:
  738. RRETURN(hr);
  739. }
  740. HRESULT
  741. CLDAPDomain::Marshall_Set_Level2(
  742. LPWSTR szServerName,
  743. LPUSER_MODALS_INFO_2 pUserInfo2
  744. )
  745. {
  746. RRETURN(S_OK);
  747. }
  748. HRESULT
  749. CLDAPDomain::Marshall_Set_Level3(
  750. LPWSTR szServerName,
  751. LPUSER_MODALS_INFO_3 pUserInfo3
  752. )
  753. {
  754. NET_API_STATUS nasStatus;
  755. HRESULT hr;
  756. DWORD dwParamErr = 0;
  757. DWORD dwAutoUnlockIntrvl = 0;
  758. DWORD dwLockoutObsIntrvl = 0;
  759. DWORD dwMaxBadPasswdsAllowed = 0;
  760. hr = GetDWORDPropertyFromCache(
  761. _pPropertyCache,
  762. TEXT("AutoUnlockInterval"),
  763. &dwAutoUnlockIntrvl
  764. );
  765. if (SUCCEEDED(hr)) {
  766. pUserInfo3->usrmod3_lockout_duration = dwAutoUnlockIntrvl;
  767. }
  768. hr = GetDWORDPropertyFromCache(
  769. _pPropertyCache,
  770. TEXT("LockoutObservationInterval"),
  771. &dwLockoutObsIntrvl
  772. );
  773. if (SUCCEEDED(hr)) {
  774. pUserInfo3->usrmod3_lockout_observation_window = dwLockoutObsIntrvl;
  775. }
  776. hr = GetDWORDPropertyFromCache(
  777. _pPropertyCache,
  778. TEXT("MaxBadPasswordsAllowed"),
  779. &dwMaxBadPasswdsAllowed
  780. );
  781. if (SUCCEEDED(hr)) {
  782. pUserInfo3->usrmod3_lockout_threshold = dwMaxBadPasswdsAllowed;
  783. }
  784. //
  785. // Now Set this Data. Remember that the property store
  786. // returns to us data in its own format. It is the caller's
  787. // responsibility to free all buffers for bstrs, variants
  788. // etc
  789. //
  790. nasStatus = NetUserModalsSet(
  791. szServerName,
  792. 3,
  793. (LPBYTE)pUserInfo3,
  794. &dwParamErr
  795. );
  796. hr = HRESULT_FROM_WIN32(nasStatus);
  797. BAIL_ON_FAILURE(hr);
  798. error:
  799. RRETURN(hr);
  800. }
  801. #endif