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.

4302 lines
112 KiB

  1. //---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1995
  5. //
  6. // File: getobj.cxx
  7. //
  8. // Contents: Windows NT 3.5 GetObject functionality
  9. //
  10. // History:
  11. //----------------------------------------------------------------------------
  12. #include "winnt.hxx"
  13. #pragma hdrstop
  14. extern WCHAR * szWinNTPrefix;
  15. //+---------------------------------------------------------------------------
  16. // Function: GetObject
  17. //
  18. // Synopsis: Called by ResolvePathName to return an object
  19. //
  20. // Arguments: [LPWSTR szBuffer]
  21. // [LPVOID *ppObject]
  22. //
  23. // Returns: HRESULT
  24. //
  25. // Modifies: -
  26. //
  27. // History: 11-3-95 krishnag Created.
  28. //
  29. //----------------------------------------------------------------------------
  30. HRESULT
  31. GetObject(
  32. LPWSTR szBuffer,
  33. LPVOID *ppObject,
  34. CWinNTCredentials& Credentials
  35. )
  36. {
  37. OBJECTINFO ObjectInfo;
  38. POBJECTINFO pObjectInfo = &ObjectInfo;
  39. CLexer Lexer(szBuffer);
  40. HRESULT hr;
  41. memset(pObjectInfo, 0, sizeof(OBJECTINFO));
  42. hr = Object(&Lexer, pObjectInfo);
  43. BAIL_IF_ERROR(hr);
  44. hr = ValidateProvider(pObjectInfo);
  45. BAIL_IF_ERROR(hr);
  46. switch (pObjectInfo->ObjectType) {
  47. case TOKEN_DOMAIN:
  48. hr = GetDomainObject(pObjectInfo, ppObject, Credentials);
  49. break;
  50. case TOKEN_USER:
  51. hr = GetUserObject(pObjectInfo, ppObject, Credentials);
  52. break;
  53. case TOKEN_COMPUTER:
  54. hr = GetComputerObject(pObjectInfo, ppObject, Credentials);
  55. break;
  56. case TOKEN_PRINTER:
  57. hr = GetPrinterObject(pObjectInfo, ppObject, Credentials);
  58. break;
  59. case TOKEN_SERVICE:
  60. hr = GetServiceObject(pObjectInfo, ppObject, Credentials);
  61. break;
  62. case TOKEN_FILESERVICE:
  63. hr = GetFileServiceObject(pObjectInfo, ppObject, Credentials);
  64. break;
  65. case TOKEN_GROUP:
  66. hr = GetGroupObject(pObjectInfo, ppObject, Credentials);
  67. break;
  68. case TOKEN_LOCALGROUP:
  69. hr = E_ADS_BAD_PATHNAME;
  70. //hr = GetLocalGroupObject(pObjectInfo, ppObject, Credentials);
  71. break;
  72. case TOKEN_GLOBALGROUP:
  73. hr = E_ADS_BAD_PATHNAME;
  74. //hr = GetGlobalGroupObject(pObjectInfo, ppObject, Credentials);
  75. break;
  76. case TOKEN_FILESHARE:
  77. hr = GetFileShareObject(pObjectInfo, ppObject, Credentials);
  78. break;
  79. case TOKEN_SCHEMA:
  80. hr = GetSchemaObject(pObjectInfo, ppObject, Credentials);
  81. break;
  82. case TOKEN_CLASS:
  83. hr = GetClassObject(pObjectInfo, ppObject, Credentials);
  84. break;
  85. case TOKEN_PROPERTY:
  86. hr = GetPropertyObject(pObjectInfo, ppObject, Credentials);
  87. break;
  88. case TOKEN_SYNTAX:
  89. hr = GetSyntaxObject(pObjectInfo, ppObject, Credentials);
  90. break;
  91. case TOKEN_WORKGROUP:
  92. hr = GetWorkGroupObject(pObjectInfo, ppObject, Credentials);
  93. break;
  94. default:
  95. hr = HeuristicGetObject(pObjectInfo, ppObject, Credentials);
  96. break;
  97. }
  98. cleanup:
  99. FreeObjectInfo( &ObjectInfo, TRUE );
  100. RRETURN(hr);
  101. }
  102. //+---------------------------------------------------------------------------
  103. // Function: GetDomainObject
  104. //
  105. // Synopsis: called by GetObject
  106. //
  107. // Arguments: [POBJECTINFO pObjectInfo]
  108. // [LPVOID * ppObject]
  109. //
  110. // Returns: HRESULT
  111. //
  112. // Modifies: -
  113. //
  114. // History: 11-3-95 krishnag Created.
  115. //
  116. //----------------------------------------------------------------------------
  117. HRESULT
  118. GetNamespaceObject(
  119. POBJECTINFO pObjectInfo,
  120. LPVOID * ppObject,
  121. CWinNTCredentials& Credentials
  122. )
  123. {
  124. HRESULT hr;
  125. hr = ValidateNamespaceObject(
  126. pObjectInfo
  127. );
  128. BAIL_ON_FAILURE(hr);
  129. // check if the call is from UMI
  130. if(Credentials.GetFlags() & ADS_AUTH_RESERVED) {
  131. hr = CWinNTNamespace::CreateNamespace(
  132. L"ADs:",
  133. L"WinNT:",
  134. ADS_OBJECT_BOUND,
  135. IID_IUnknown,
  136. Credentials,
  137. ppObject
  138. );
  139. }
  140. else { // came in through ADSI
  141. hr = CoCreateInstance(CLSID_WinNTNamespace,
  142. NULL,
  143. CLSCTX_INPROC_SERVER,
  144. IID_IUnknown,
  145. (void **)ppObject );
  146. }
  147. error:
  148. RRETURN(hr);
  149. }
  150. //+---------------------------------------------------------------------------
  151. // Function: GetDomainObject
  152. //
  153. // Synopsis: called by GetObject
  154. //
  155. // Arguments: [POBJECTINFO pObjectInfo]
  156. // [LPVOID * ppObject]
  157. //
  158. // Returns: HRESULT
  159. //
  160. // Modifies: -
  161. //
  162. // History: 11-3-95 krishnag Created.
  163. //
  164. //----------------------------------------------------------------------------
  165. HRESULT
  166. GetDomainObject(
  167. POBJECTINFO pObjectInfo,
  168. LPVOID * ppObject,
  169. CWinNTCredentials& Credentials
  170. )
  171. {
  172. HRESULT hr;
  173. IUnknown *pUnknown = NULL;
  174. IADs *pADs = NULL;
  175. NET_API_STATUS nasStatus;
  176. WCHAR szHostServerName[MAX_PATH];
  177. WCHAR ADsParent[MAX_ADS_PATH];
  178. WCHAR szSAMName[MAX_ADS_PATH];
  179. szSAMName[0] = L'\0';
  180. *ppObject = NULL;
  181. if (pObjectInfo->NumComponents != 1) {
  182. RRETURN(E_ADS_INVALID_DOMAIN_OBJECT);
  183. }
  184. //
  185. // Verify that this object is really a domain
  186. //
  187. // We can try and ref the domain here but it will
  188. // anyway end up in WinNTGetCachedDCName call in
  189. // CWinNTCredentials::RefDomain, so there is no point in
  190. // doing that
  191. hr = WinNTGetCachedDCName(
  192. pObjectInfo->ComponentArray[0],
  193. szHostServerName,
  194. Credentials.GetFlags()
  195. );
  196. BAIL_ON_FAILURE(hr);
  197. if (szSAMName[0] != L'\0') {
  198. if (pObjectInfo->ComponentArray[0]) {
  199. FreeADsStr(pObjectInfo->ComponentArray[0]);
  200. }
  201. pObjectInfo->ComponentArray[0] = AllocADsStr(szSAMName);
  202. if (!pObjectInfo) {
  203. BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
  204. }
  205. }
  206. hr = BuildParent(
  207. pObjectInfo,
  208. ADsParent
  209. );
  210. BAIL_ON_FAILURE(hr);
  211. hr = CWinNTDomain::CreateDomain(
  212. ADsParent,
  213. pObjectInfo->ComponentArray[0],
  214. ADS_OBJECT_BOUND,
  215. IID_IUnknown,
  216. Credentials,
  217. (void **)&pUnknown
  218. );
  219. BAIL_ON_FAILURE(hr);
  220. *ppObject = pUnknown;
  221. error:
  222. RRETURN(hr);
  223. }
  224. //+---------------------------------------------------------------------------
  225. // Function: GetWorkgroupObject
  226. //
  227. // Synopsis: called by GetObject.
  228. // Note: We really don't have a workgroup object. But we
  229. // need to support a syntax such as @WinNT!workstation to
  230. // allow for IADsContainer interface methods. There is
  231. // no authentication that needs to done.
  232. //
  233. // Arguments: [POBJECTINFO pObjectInfo]
  234. // [LPVOID * ppObject]
  235. //
  236. // Returns: HRESULT
  237. //
  238. // Modifies: -
  239. //
  240. // History: 05-23-96 RamV Created.
  241. //
  242. //----------------------------------------------------------------------------
  243. HRESULT
  244. GetWorkGroupObject(
  245. POBJECTINFO pObjectInfo,
  246. LPVOID * ppObject,
  247. CWinNTCredentials& Credentials
  248. )
  249. {
  250. HRESULT hr;
  251. IUnknown *pUnknown = NULL;
  252. IADs *pADs = NULL;
  253. WCHAR ADsParent[MAX_ADS_PATH];
  254. WCHAR szName[MAX_PATH];
  255. *ppObject = NULL;
  256. if (pObjectInfo->NumComponents != 1) {
  257. RRETURN(E_ADS_INVALID_DOMAIN_OBJECT);
  258. }
  259. //
  260. // any single component oleds path can be validated as a workgroup
  261. //
  262. hr = BuildParent(
  263. pObjectInfo,
  264. ADsParent
  265. );
  266. BAIL_ON_FAILURE(hr);
  267. hr = CWinNTDomain::CreateDomain(
  268. ADsParent,
  269. pObjectInfo->ComponentArray[0],
  270. ADS_OBJECT_BOUND,
  271. IID_IUnknown,
  272. Credentials,
  273. (void **)&pUnknown
  274. );
  275. BAIL_ON_FAILURE(hr);
  276. *ppObject = pUnknown;
  277. error:
  278. RRETURN(hr);
  279. }
  280. //+---------------------------------------------------------------------------
  281. // Function: GetUserObject
  282. //
  283. // Synopsis:
  284. //
  285. // Arguments:
  286. //
  287. // Returns:
  288. //
  289. // Modifies:
  290. //
  291. // History: 11-3-95 krishnag Created.
  292. // 8-8-96 ramv Modified.
  293. //
  294. //----------------------------------------------------------------------------
  295. HRESULT
  296. GetUserObject(
  297. POBJECTINFO pObjectInfo,
  298. LPVOID * ppObject,
  299. CWinNTCredentials& Credentials
  300. )
  301. {
  302. LPUNKNOWN pUnknown = NULL;
  303. WCHAR ADsParent[MAX_ADS_PATH];
  304. HRESULT hr = S_OK;
  305. LPWSTR szServerName = NULL;
  306. LPWSTR szDomainName = NULL;
  307. LPWSTR szUserName = NULL;
  308. DWORD dwParentId = 0;
  309. WCHAR szComputerParent[MAX_PATH];
  310. POBJECTINFO pUserObjectInfo = NULL;
  311. hr = ValidateUserObject(
  312. pObjectInfo,
  313. &dwParentId,
  314. Credentials
  315. );
  316. BAIL_ON_FAILURE(hr);
  317. switch (pObjectInfo->NumComponents) {
  318. case 2:
  319. //
  320. // could be user in computer or user in domain
  321. //
  322. if(dwParentId == WINNT_DOMAIN_ID){
  323. szDomainName = pObjectInfo->ComponentArray[0];
  324. szUserName = pObjectInfo->ComponentArray[1];
  325. szServerName = NULL;
  326. hr = BuildParent(pObjectInfo, ADsParent);
  327. BAIL_ON_FAILURE(hr);
  328. } else {
  329. //
  330. // user in a computer
  331. //
  332. hr = ConstructFullObjectInfo(pObjectInfo,
  333. &pUserObjectInfo,
  334. Credentials );
  335. if (SUCCEEDED(hr)) {
  336. hr = BuildParent(pUserObjectInfo, ADsParent);
  337. BAIL_ON_FAILURE(hr);
  338. szDomainName = pUserObjectInfo->ComponentArray[0];
  339. szServerName = pUserObjectInfo->ComponentArray[1];
  340. szUserName = pUserObjectInfo->ComponentArray[2];
  341. }
  342. else if (hr == HRESULT_FROM_WIN32(NERR_WkstaNotStarted)) {
  343. // We alread know that the object is valid,
  344. // So we should set appropriate values and proceed to
  345. // create the object
  346. hr = BuildParent(pObjectInfo, ADsParent);
  347. BAIL_ON_FAILURE(hr);
  348. szDomainName = NULL;
  349. szServerName = pObjectInfo->ComponentArray[0];
  350. szUserName = pObjectInfo->ComponentArray[1];
  351. }
  352. }
  353. break;
  354. case 3:
  355. szDomainName = pObjectInfo->ComponentArray[0];
  356. szServerName = pObjectInfo->ComponentArray[1];
  357. szUserName = pObjectInfo->ComponentArray[2];
  358. hr = BuildParent(pObjectInfo, ADsParent);
  359. BAIL_ON_FAILURE(hr);
  360. break;
  361. }
  362. hr = CWinNTUser::CreateUser(ADsParent,
  363. dwParentId,
  364. szDomainName,
  365. szServerName,
  366. szUserName,
  367. ADS_OBJECT_BOUND,
  368. IID_IUnknown,
  369. Credentials,
  370. (void **)&pUnknown
  371. );
  372. BAIL_ON_FAILURE(hr);
  373. *ppObject = pUnknown;
  374. FreeObjectInfo(pUserObjectInfo);
  375. RRETURN(hr);
  376. error:
  377. if (pUnknown) {
  378. pUnknown->Release();
  379. }
  380. *ppObject = NULL;
  381. FreeObjectInfo(pUserObjectInfo);
  382. RRETURN(hr);
  383. }
  384. //+---------------------------------------------------------------------------
  385. // Function: GetUserObject
  386. //
  387. // Synopsis:
  388. //
  389. // Arguments:
  390. //
  391. // Returns:
  392. //
  393. // Modifies:
  394. //
  395. // History: 8-8-96 ramv Created.
  396. //
  397. //----------------------------------------------------------------------------
  398. HRESULT
  399. GetUserObjectInDomain(
  400. LPWSTR pszHostServerName,
  401. POBJECTINFO pObjectInfo,
  402. LPVOID * ppObject,
  403. CWinNTCredentials& Credentials
  404. )
  405. {
  406. LPUNKNOWN pUnknown = NULL;
  407. WCHAR ADsParent[MAX_ADS_PATH];
  408. HRESULT hr = S_OK;
  409. LPWSTR szServerName = NULL;
  410. LPWSTR szDomainName = NULL;
  411. LPWSTR szUserName = NULL;
  412. DWORD dwParentId = WINNT_DOMAIN_ID;
  413. LPUSER_INFO_20 lpUI = NULL;
  414. NET_API_STATUS nasStatus;
  415. BOOL fRefAdded = FALSE;
  416. LPUSER_INFO_0 lpUI_0 = NULL;
  417. DWORD dwLevelUsed = 20;
  418. // At this point a \\ has been prepended to the host
  419. // we need to get rid of it.
  420. hr = Credentials.RefServer(pszHostServerName+2);
  421. if (SUCCEEDED(hr)) {
  422. fRefAdded = TRUE;
  423. }
  424. nasStatus = NetUserGetInfo(pszHostServerName,
  425. pObjectInfo->ComponentArray[1],
  426. 20,
  427. (LPBYTE *)&lpUI);
  428. if (nasStatus == ERROR_ACCESS_DENIED) {
  429. // try and drop down to level 0 as that may work
  430. dwLevelUsed = 0;
  431. nasStatus = NetUserGetInfo(
  432. pszHostServerName,
  433. pObjectInfo->ComponentArray[1],
  434. 0,
  435. (LPBYTE *)&lpUI_0
  436. );
  437. }
  438. // deref if necessary, note no error recovery possible
  439. if (fRefAdded) {
  440. Credentials.DeRefServer();
  441. fRefAdded = FALSE;
  442. }
  443. hr = HRESULT_FROM_WIN32(nasStatus);
  444. BAIL_ON_FAILURE(hr);
  445. // Need to use the name returned by the call as opposed
  446. // to the name given in the ADsPath
  447. if (dwLevelUsed == 20) {
  448. if (pObjectInfo->ComponentArray[1] && lpUI->usri20_name) {
  449. FreeADsStr(pObjectInfo->ComponentArray[1]);
  450. pObjectInfo->ComponentArray[1] = AllocADsStr(lpUI->usri20_name);
  451. }
  452. if (!pObjectInfo->ComponentArray[1])
  453. BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
  454. }
  455. // if it is not a level 20 call then we will just use
  456. // whatever the user gave us
  457. szDomainName = pObjectInfo->ComponentArray[0];
  458. szUserName = pObjectInfo->ComponentArray[1];
  459. szServerName = NULL;
  460. hr = BuildParent(pObjectInfo, ADsParent);
  461. BAIL_ON_FAILURE(hr);
  462. hr = CWinNTUser::CreateUser(ADsParent,
  463. dwParentId,
  464. szDomainName,
  465. szServerName,
  466. szUserName,
  467. ADS_OBJECT_BOUND,
  468. IID_IUnknown,
  469. Credentials,
  470. (void **)&pUnknown
  471. );
  472. BAIL_ON_FAILURE(hr);
  473. *ppObject = pUnknown;
  474. error:
  475. if (FAILED(hr) && pUnknown) {
  476. pUnknown->Release();
  477. *ppObject = NULL;
  478. }
  479. if (lpUI)
  480. NetApiBufferFree((LPBYTE)lpUI);
  481. if (lpUI_0) {
  482. NetApiBufferFree((LPBYTE)lpUI_0);
  483. }
  484. RRETURN(hr);
  485. }
  486. //+---------------------------------------------------------------------------
  487. // Function: GetUserObject
  488. //
  489. // Synopsis:
  490. //
  491. // Arguments:
  492. //
  493. // Returns:
  494. //
  495. // Modifies:
  496. //
  497. // History: 11-3-95 krishnag Created.
  498. // 8-8-96 ramv Modified.
  499. //
  500. //----------------------------------------------------------------------------
  501. HRESULT
  502. GetUserObjectInComputer(
  503. LPWSTR pszHostServerName, // pdc name
  504. POBJECTINFO pObjectInfo,
  505. LPVOID * ppObject,
  506. CWinNTCredentials& Credentials
  507. )
  508. {
  509. LPUNKNOWN pUnknown = NULL;
  510. WCHAR ADsParent[MAX_ADS_PATH];
  511. HRESULT hr = S_OK;
  512. LPWSTR szServerName = NULL;
  513. LPWSTR szDomainName = NULL;
  514. LPWSTR szUserName = NULL;
  515. DWORD dwParentId = WINNT_COMPUTER_ID;
  516. WCHAR szComputerParent[MAX_PATH];
  517. POBJECTINFO pUserObjectInfo = NULL;
  518. WCHAR lpszUncName[MAX_PATH];
  519. NET_API_STATUS nasStatus;
  520. LPBYTE lpUI = NULL;
  521. BOOL fRefAdded = FALSE;
  522. switch (pObjectInfo->NumComponents) {
  523. case 2:
  524. //
  525. // could be user in computer
  526. //
  527. //
  528. // first validate user
  529. //
  530. hr = Credentials.RefServer(pObjectInfo->ComponentArray[0]);
  531. if (SUCCEEDED(hr)) {
  532. fRefAdded = TRUE;
  533. }
  534. MakeUncName(pObjectInfo->ComponentArray[0],
  535. lpszUncName);
  536. nasStatus = NetUserGetInfo(lpszUncName,
  537. pObjectInfo->ComponentArray[1],
  538. 20,
  539. &lpUI);
  540. if (fRefAdded) {
  541. Credentials.DeRefServer();
  542. fRefAdded = FALSE;
  543. }
  544. hr = HRESULT_FROM_WIN32(nasStatus);
  545. BAIL_ON_FAILURE(hr);
  546. // Need to use the name returned by the call as opposed
  547. // to the name given in the ADsPath
  548. if (pObjectInfo->ComponentArray[1]
  549. && ((LPUSER_INFO_20)lpUI)->usri20_name) {
  550. FreeADsStr(pObjectInfo->ComponentArray[1]);
  551. pObjectInfo->ComponentArray[1]
  552. = AllocADsStr(((LPUSER_INFO_20)lpUI)->usri20_name);
  553. }
  554. if (!pObjectInfo->ComponentArray[1])
  555. BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
  556. // This call will add the domain information to the
  557. // objectInfo blob, so that the ComponentArray[2] is valid
  558. hr = ConstructFullObjectInfo(pObjectInfo,
  559. &pUserObjectInfo,
  560. Credentials );
  561. BAIL_ON_FAILURE(hr);
  562. hr = BuildParent(pUserObjectInfo, ADsParent);
  563. BAIL_ON_FAILURE(hr);
  564. szDomainName = pUserObjectInfo->ComponentArray[0];
  565. szServerName = pUserObjectInfo->ComponentArray[1];
  566. szUserName = pUserObjectInfo->ComponentArray[2];
  567. break;
  568. case 3:
  569. //
  570. // ValidateComputerParent and validate user in computer
  571. //
  572. hr = ValidateComputerParent(pObjectInfo->ComponentArray[0],
  573. pObjectInfo->ComponentArray[1],
  574. Credentials);
  575. BAIL_ON_FAILURE(hr);
  576. hr = Credentials.RefServer(pObjectInfo->ComponentArray[1]);
  577. if (SUCCEEDED(hr)) {
  578. fRefAdded = TRUE;
  579. }
  580. MakeUncName(pObjectInfo->ComponentArray[1],
  581. lpszUncName);
  582. nasStatus = NetUserGetInfo(lpszUncName,
  583. pObjectInfo->ComponentArray[2],
  584. 20,
  585. (LPBYTE *)&lpUI);
  586. if (fRefAdded) {
  587. Credentials.DeRefServer();
  588. fRefAdded = FALSE;
  589. }
  590. hr = HRESULT_FROM_WIN32(nasStatus);
  591. BAIL_ON_FAILURE(hr);
  592. // Need to use the name returned by the call as opposed
  593. // to the name given in the ADsPath
  594. if (pObjectInfo->ComponentArray[2]
  595. && ((LPUSER_INFO_20)lpUI)->usri20_name) {
  596. FreeADsStr(pObjectInfo->ComponentArray[2]);
  597. pObjectInfo->ComponentArray[2]
  598. = AllocADsStr(((LPUSER_INFO_20)lpUI)->usri20_name);
  599. }
  600. if (!pObjectInfo->ComponentArray[2])
  601. BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
  602. hr = BuildParent(pObjectInfo, ADsParent);
  603. BAIL_ON_FAILURE(hr);
  604. szDomainName = pObjectInfo->ComponentArray[0];
  605. szServerName = pObjectInfo->ComponentArray[1];
  606. szUserName = pObjectInfo->ComponentArray[2];
  607. break;
  608. }
  609. hr = CWinNTUser::CreateUser(ADsParent,
  610. dwParentId,
  611. szDomainName,
  612. szServerName,
  613. szUserName,
  614. ADS_OBJECT_BOUND,
  615. IID_IUnknown,
  616. Credentials,
  617. (void **)&pUnknown
  618. );
  619. error:
  620. if (FAILED(hr)) {
  621. if (pUnknown) {
  622. pUnknown->Release();
  623. }
  624. *ppObject = NULL;
  625. }
  626. else {
  627. *ppObject = pUnknown;
  628. }
  629. if (lpUI) {
  630. NetApiBufferFree(lpUI);
  631. }
  632. FreeObjectInfo(pUserObjectInfo);
  633. RRETURN(hr);
  634. }
  635. //+---------------------------------------------------------------------------
  636. // Function: GetComputerObject
  637. //
  638. // Synopsis:
  639. //
  640. // Arguments:
  641. //
  642. // Returns:
  643. //
  644. // Modifies:
  645. //
  646. // History: 11-3-95 krishnag Created.
  647. //
  648. //----------------------------------------------------------------------------
  649. HRESULT
  650. GetComputerObject(
  651. POBJECTINFO pObjectInfo,
  652. LPVOID * ppObject,
  653. CWinNTCredentials& Credentials
  654. )
  655. {
  656. HRESULT hr = S_OK;
  657. WCHAR ADsParent[MAX_ADS_PATH];
  658. TCHAR szUncName[MAX_PATH];
  659. NET_API_STATUS nasStatus;
  660. POBJECTINFO pComputerObjectInfo = NULL;
  661. BOOL fNoWksta = FALSE;
  662. WCHAR szCompName[MAX_PATH];
  663. DWORD dwSize = MAX_PATH;
  664. //
  665. // The following function call merely checks to see if the domain is
  666. // correct. If not, we can assume that the computer does not belong to
  667. // a domain.
  668. //
  669. hr = ValidateComputerObject(pObjectInfo, Credentials);
  670. if (hr == HRESULT_FROM_WIN32(NERR_WkstaNotStarted))
  671. fNoWksta = TRUE;
  672. else
  673. BAIL_ON_FAILURE(hr);
  674. // Normall we can expect that the workstation service will
  675. // be started. This will not be the case for minimum installs
  676. if (!fNoWksta) {
  677. if(pObjectInfo->NumComponents == 1){
  678. //
  679. // we need to supply the workgroup name for this computer
  680. // This is needed because EnumLocalGroups requires the
  681. // workgroup name to function properly
  682. //
  683. hr = ConstructFullObjectInfo(pObjectInfo,
  684. &pComputerObjectInfo,
  685. Credentials );
  686. BAIL_ON_FAILURE(hr);
  687. hr = BuildParent(pComputerObjectInfo, ADsParent);
  688. BAIL_ON_FAILURE(hr);
  689. hr = CWinNTComputer::CreateComputer(
  690. ADsParent,
  691. pComputerObjectInfo->ComponentArray[0],
  692. pComputerObjectInfo->ComponentArray[1],
  693. ADS_OBJECT_BOUND,
  694. IID_IUnknown,
  695. Credentials,
  696. ppObject
  697. );
  698. } else if(pObjectInfo->NumComponents == 2) {
  699. hr = BuildParent(pObjectInfo, ADsParent);
  700. BAIL_ON_FAILURE(hr);
  701. hr = CWinNTComputer::CreateComputer(
  702. ADsParent,
  703. pObjectInfo->ComponentArray[0],
  704. pObjectInfo->ComponentArray[1],
  705. ADS_OBJECT_BOUND,
  706. IID_IUnknown,
  707. Credentials,
  708. ppObject);
  709. }
  710. } else {
  711. // Else clause for if(!fWksta)
  712. // This means that workstation services were not
  713. // started, we need to verify that the host computer
  714. // is the one they are interested in.
  715. if ((pObjectInfo->NumComponents != 1) || (!GetComputerName(szCompName, &dwSize))) {
  716. // We cannot get the computer name so bail
  717. BAIL_ON_FAILURE(hr);
  718. }
  719. // Compare the names before we continue
  720. #ifdef WIN95
  721. if (_wcsicmp(szCompName, pObjectInfo->ComponentArray[0])) {
  722. #else
  723. if (CompareStringW(
  724. LOCALE_SYSTEM_DEFAULT,
  725. NORM_IGNORECASE,
  726. szCompName,
  727. -1,
  728. pObjectInfo->ComponentArray[0],
  729. -1
  730. ) != CSTR_EQUAL ) {
  731. #endif
  732. // names do not match
  733. BAIL_ON_FAILURE(hr);
  734. }
  735. hr = CWinNTComputer::CreateComputer(
  736. L"WinNT:",
  737. NULL,
  738. pObjectInfo->ComponentArray[0],
  739. ADS_OBJECT_BOUND,
  740. IID_IUnknown,
  741. Credentials,
  742. ppObject
  743. );
  744. BAIL_ON_FAILURE(hr);
  745. }
  746. error:
  747. if(pComputerObjectInfo){
  748. FreeObjectInfo(pComputerObjectInfo);
  749. }
  750. RRETURN(hr);
  751. }
  752. //+---------------------------------------------------------------------------
  753. // Function: GetPrinterObject
  754. //
  755. // Synopsis:
  756. //
  757. // Arguments:
  758. //
  759. // Returns:
  760. //
  761. // Modifies:
  762. //
  763. // History: 01/03/96 Ramv Created.
  764. //
  765. //----------------------------------------------------------------------------
  766. HRESULT
  767. GetPrinterObject(
  768. POBJECTINFO pObjectInfo,
  769. LPVOID * ppObject,
  770. CWinNTCredentials& Credentials
  771. )
  772. {
  773. LPUNKNOWN pUnknown = NULL;
  774. WCHAR szADsParent[MAX_ADS_PATH];
  775. HRESULT hr = S_OK;
  776. LPWSTR szDomainName = NULL;
  777. LPWSTR szServerName = NULL;
  778. LPWSTR szPrinterName = NULL;
  779. DWORD dwParentId = 0;
  780. LPWSTR szComputerParent[MAX_PATH];
  781. POBJECTINFO pPrinterObjectInfo = NULL;
  782. if (!(pObjectInfo->NumComponents == 3 ||pObjectInfo->NumComponents == 2)){
  783. RRETURN(E_ADS_BAD_PATHNAME);
  784. }
  785. // check to see that the printer is a valid one
  786. hr = ValidatePrinterObject(pObjectInfo, Credentials);
  787. BAIL_ON_FAILURE(hr);
  788. dwParentId = WINNT_COMPUTER_ID;
  789. if(pObjectInfo->NumComponents == 3) {
  790. hr = BuildParent(pObjectInfo, szADsParent);
  791. BAIL_ON_FAILURE(hr);
  792. szDomainName = pObjectInfo->ComponentArray[0];
  793. szServerName = pObjectInfo->ComponentArray[1];
  794. szPrinterName= pObjectInfo->ComponentArray[2];
  795. } else if (pObjectInfo->NumComponents == 2){
  796. hr = ConstructFullObjectInfo(pObjectInfo,
  797. &pPrinterObjectInfo,
  798. Credentials );
  799. BAIL_ON_FAILURE(hr);
  800. hr = BuildParent(pPrinterObjectInfo, szADsParent);
  801. BAIL_ON_FAILURE(hr);
  802. szDomainName = pPrinterObjectInfo->ComponentArray[0];
  803. szServerName = pPrinterObjectInfo->ComponentArray[1];
  804. szPrinterName= pPrinterObjectInfo->ComponentArray[2];
  805. }
  806. hr = CWinNTPrintQueue::CreatePrintQueue(
  807. szADsParent,
  808. dwParentId,
  809. szDomainName,
  810. szServerName,
  811. szPrinterName,
  812. ADS_OBJECT_BOUND,
  813. IID_IUnknown,
  814. Credentials,
  815. (void **)&pUnknown
  816. );
  817. BAIL_ON_FAILURE(hr);
  818. *ppObject = pUnknown;
  819. FreeObjectInfo(pPrinterObjectInfo);
  820. RRETURN(hr);
  821. error:
  822. if (pUnknown) {
  823. pUnknown->Release();
  824. }
  825. *ppObject = NULL;
  826. FreeObjectInfo(pPrinterObjectInfo);
  827. RRETURN(hr);
  828. }
  829. //+---------------------------------------------------------------------------
  830. // Function: GetServiceObject
  831. //
  832. // Synopsis:
  833. //
  834. // Arguments:
  835. //
  836. // Returns:
  837. //
  838. // Modifies:
  839. //
  840. // History: 01/03/96 Ramv Created.
  841. //
  842. //----------------------------------------------------------------------------
  843. HRESULT
  844. GetServiceObject(
  845. POBJECTINFO pObjectInfo,
  846. LPVOID * ppObject,
  847. CWinNTCredentials& Credentials
  848. )
  849. {
  850. LPUNKNOWN pUnknown = NULL;
  851. WCHAR szADsParent[MAX_ADS_PATH];
  852. HRESULT hr = S_OK;
  853. LPWSTR szDomainName = NULL;
  854. LPWSTR szServerName = NULL;
  855. LPWSTR szServiceName = NULL;
  856. DWORD dwParentId = 0;
  857. POBJECTINFO pServiceObjectInfo = NULL;
  858. //
  859. // check to see that the printer is in a valid server(computer) object
  860. //
  861. if(!(pObjectInfo->NumComponents == 3 ||
  862. pObjectInfo->NumComponents == 2))
  863. {
  864. RRETURN(E_ADS_BAD_PATHNAME);
  865. }
  866. hr = ValidateServiceObject(pObjectInfo, Credentials);
  867. BAIL_ON_FAILURE(hr);
  868. dwParentId = WINNT_COMPUTER_ID;
  869. if(pObjectInfo->NumComponents == 3) {
  870. hr = BuildParent(pObjectInfo, szADsParent);
  871. BAIL_ON_FAILURE(hr);
  872. szDomainName = pObjectInfo->ComponentArray[0];
  873. szServerName = pObjectInfo->ComponentArray[1];
  874. szServiceName= pObjectInfo->ComponentArray[2];
  875. hr = CWinNTService::Create(szADsParent,
  876. szDomainName,
  877. szServerName,
  878. szServiceName,
  879. ADS_OBJECT_BOUND,
  880. IID_IUnknown,
  881. Credentials,
  882. (void **)&pUnknown);
  883. BAIL_ON_FAILURE(hr);
  884. } else if (pObjectInfo->NumComponents == 2) {
  885. hr = ConstructFullObjectInfo(pObjectInfo,
  886. &pServiceObjectInfo,
  887. Credentials );
  888. BAIL_ON_FAILURE(hr);
  889. hr = BuildParent(pServiceObjectInfo, szADsParent);
  890. BAIL_ON_FAILURE(hr);
  891. szServerName = pServiceObjectInfo->ComponentArray[1];
  892. szServiceName= pServiceObjectInfo->ComponentArray[2];
  893. hr = CWinNTService::Create(szADsParent,
  894. pServiceObjectInfo->ComponentArray[0],
  895. szServerName,
  896. szServiceName,
  897. ADS_OBJECT_BOUND,
  898. IID_IUnknown,
  899. Credentials,
  900. (void **)&pUnknown);
  901. BAIL_ON_FAILURE(hr);
  902. }
  903. *ppObject = pUnknown;
  904. if(pServiceObjectInfo){
  905. FreeObjectInfo(pServiceObjectInfo);
  906. }
  907. RRETURN(hr);
  908. error:
  909. if(pServiceObjectInfo){
  910. FreeObjectInfo(pServiceObjectInfo);
  911. }
  912. if (pUnknown) {
  913. pUnknown->Release();
  914. }
  915. *ppObject = NULL;
  916. RRETURN(hr);
  917. }
  918. //+---------------------------------------------------------------------------
  919. // Function: GetFileServiceObject
  920. //
  921. // Synopsis:
  922. //
  923. // Arguments:
  924. //
  925. // Returns:
  926. //
  927. // Modifies:
  928. //
  929. // History: 01/15/96 Ramv Created.
  930. //
  931. //----------------------------------------------------------------------------
  932. HRESULT
  933. GetFileServiceObject(
  934. POBJECTINFO pObjectInfo,
  935. LPVOID * ppObject,
  936. CWinNTCredentials& Credentials
  937. )
  938. {
  939. LPUNKNOWN pUnknown = NULL;
  940. WCHAR szADsParent[MAX_ADS_PATH];
  941. HRESULT hr = S_OK;
  942. LPWSTR szDomainName = NULL;
  943. LPWSTR szServerName = NULL;
  944. LPWSTR szFileServiceName = NULL;
  945. DWORD dwParentId = 0;
  946. POBJECTINFO pFileServiceObjectInfo = NULL;
  947. //
  948. // check to see that the service is in a valid server(computer) object
  949. //
  950. if (!(pObjectInfo->NumComponents == 3 || pObjectInfo->NumComponents == 2))
  951. RRETURN(E_ADS_BAD_PATHNAME);
  952. hr = ValidateFileServiceObject(pObjectInfo, Credentials);
  953. BAIL_ON_FAILURE(hr);
  954. if (pObjectInfo->NumComponents == 3){
  955. szDomainName = pObjectInfo->ComponentArray[0];
  956. szServerName = pObjectInfo->ComponentArray[1];
  957. szFileServiceName= pObjectInfo->ComponentArray[2];
  958. hr = BuildParent(pObjectInfo, szADsParent);
  959. BAIL_ON_FAILURE(hr);
  960. }
  961. if (pObjectInfo->NumComponents == 2){
  962. hr = ConstructFullObjectInfo(pObjectInfo,
  963. &pFileServiceObjectInfo,
  964. Credentials );
  965. BAIL_ON_FAILURE(hr);
  966. hr = BuildParent(pFileServiceObjectInfo, szADsParent);
  967. BAIL_ON_FAILURE(hr);
  968. szDomainName = pFileServiceObjectInfo->ComponentArray[0];
  969. szServerName = pFileServiceObjectInfo->ComponentArray[1];
  970. szFileServiceName= pFileServiceObjectInfo->ComponentArray[2];
  971. }
  972. dwParentId = WINNT_COMPUTER_ID;
  973. if(_tcsicmp(szFileServiceName,TEXT("LanmanServer")) == 0) {
  974. hr = CWinNTFileService::CreateFileService(szADsParent,
  975. dwParentId,
  976. szDomainName,
  977. szServerName,
  978. szFileServiceName,
  979. ADS_OBJECT_BOUND,
  980. IID_IUnknown,
  981. Credentials,
  982. (void **)&pUnknown);
  983. BAIL_ON_FAILURE(hr);
  984. }
  985. else if(_tcsicmp(szFileServiceName,TEXT("FPNW")) == 0) {
  986. hr = CFPNWFileService::CreateFileService(szADsParent,
  987. dwParentId,
  988. szDomainName,
  989. szServerName,
  990. szFileServiceName,
  991. ADS_OBJECT_BOUND,
  992. IID_IUnknown,
  993. Credentials,
  994. (void **)&pUnknown);
  995. BAIL_ON_FAILURE(hr);
  996. }
  997. *ppObject = pUnknown;
  998. if(pFileServiceObjectInfo){
  999. FreeObjectInfo(pFileServiceObjectInfo);
  1000. }
  1001. RRETURN(hr);
  1002. error:
  1003. if(pFileServiceObjectInfo){
  1004. FreeObjectInfo(pFileServiceObjectInfo);
  1005. }
  1006. if (pUnknown) {
  1007. pUnknown->Release();
  1008. }
  1009. *ppObject = NULL;
  1010. RRETURN(hr);
  1011. }
  1012. //+---------------------------------------------------------------------------
  1013. // Function: GetFileShareObject
  1014. //
  1015. // Synopsis:
  1016. //
  1017. // Arguments:
  1018. //
  1019. // Returns:
  1020. //
  1021. // Modifies:
  1022. //
  1023. // History: 01/15/96 Ramv Created.
  1024. //
  1025. //----------------------------------------------------------------------------
  1026. HRESULT
  1027. GetFileShareObject(
  1028. POBJECTINFO pObjectInfo,
  1029. LPVOID * ppObject,
  1030. CWinNTCredentials& Credentials
  1031. )
  1032. {
  1033. LPUNKNOWN pUnknown = NULL;
  1034. WCHAR szADsParent[MAX_ADS_PATH];
  1035. HRESULT hr = S_OK;
  1036. LPTSTR szDomainName = NULL;
  1037. LPTSTR szServerName = NULL;
  1038. LPTSTR szFileServiceName = NULL;
  1039. LPTSTR szFileShareName = NULL;
  1040. DWORD dwParentId = 0;
  1041. POBJECTINFO pFileShareObjectInfo = NULL;
  1042. WCHAR lpszUncName[MAX_PATH];
  1043. BOOL fRefAdded = FALSE;
  1044. //
  1045. // check to see that the share is in a valid fileservice
  1046. //
  1047. if (!(pObjectInfo->NumComponents == 4 ||
  1048. pObjectInfo->NumComponents == 3)) {
  1049. RRETURN(E_ADS_BAD_PATHNAME);
  1050. }
  1051. // The server is ref'ed in this routine.
  1052. hr = ValidateFileShareObject(pObjectInfo, Credentials);
  1053. BAIL_ON_FAILURE(hr);
  1054. dwParentId = WINNT_SERVICE_ID;
  1055. if(pObjectInfo->NumComponents == 4){
  1056. hr = BuildParent(pObjectInfo, szADsParent);
  1057. BAIL_ON_FAILURE(hr);
  1058. szServerName = pObjectInfo->ComponentArray[1];
  1059. szFileServiceName= pObjectInfo->ComponentArray[2];
  1060. szFileShareName = pObjectInfo ->ComponentArray[3];
  1061. } else if (pObjectInfo->NumComponents == 3){
  1062. hr = ConstructFullObjectInfo(pObjectInfo,
  1063. &pFileShareObjectInfo,
  1064. Credentials );
  1065. BAIL_ON_FAILURE(hr);
  1066. hr = BuildParent(pFileShareObjectInfo, szADsParent);
  1067. BAIL_ON_FAILURE(hr);
  1068. szServerName = pObjectInfo->ComponentArray[0];
  1069. szFileServiceName= pObjectInfo->ComponentArray[1];
  1070. szFileShareName = pObjectInfo ->ComponentArray[2];
  1071. }
  1072. if(_tcsicmp(szFileServiceName,TEXT("LanmanServer")) == 0){
  1073. hr = CWinNTFileShare::Create(szADsParent,
  1074. szServerName,
  1075. szFileServiceName,
  1076. szFileShareName,
  1077. ADS_OBJECT_BOUND,
  1078. IID_IUnknown,
  1079. Credentials,
  1080. (void **)&pUnknown);
  1081. BAIL_ON_FAILURE(hr);
  1082. }
  1083. else {
  1084. //
  1085. // we have validated it already, it *has* to be an FPNW server
  1086. //
  1087. hr = CFPNWFileShare::Create(szADsParent,
  1088. szServerName,
  1089. szFileServiceName,
  1090. szFileShareName,
  1091. ADS_OBJECT_BOUND,
  1092. IID_IUnknown,
  1093. Credentials,
  1094. (void **)&pUnknown);
  1095. BAIL_ON_FAILURE(hr);
  1096. }
  1097. *ppObject = pUnknown;
  1098. if(pFileShareObjectInfo){
  1099. FreeObjectInfo(pFileShareObjectInfo);
  1100. }
  1101. RRETURN(hr);
  1102. error:
  1103. if (pUnknown) {
  1104. pUnknown->Release();
  1105. }
  1106. if(pFileShareObjectInfo){
  1107. FreeObjectInfo(pFileShareObjectInfo);
  1108. }
  1109. *ppObject = NULL;
  1110. RRETURN(hr);
  1111. }
  1112. //+---------------------------------------------------------------------------
  1113. // Function: GetGroupObject
  1114. //
  1115. // Synopsis:
  1116. //
  1117. // Arguments:
  1118. //
  1119. // Returns:
  1120. //
  1121. // Modifies:
  1122. //
  1123. // History: 11-3-95 krishnag Created.
  1124. //
  1125. //----------------------------------------------------------------------------
  1126. HRESULT
  1127. GetGroupObject(
  1128. POBJECTINFO pObjectInfo,
  1129. LPVOID * ppObject,
  1130. CWinNTCredentials& Credentials
  1131. )
  1132. {
  1133. LPUNKNOWN pUnknown = NULL;
  1134. WCHAR ADsParent[MAX_ADS_PATH];
  1135. HRESULT hr = S_OK;
  1136. LPWSTR szServerName = NULL;
  1137. LPWSTR szDomainName = NULL;
  1138. LPWSTR szGroupName = NULL;
  1139. DWORD dwParentId = 0;
  1140. ULONG uGroupType = 0;
  1141. POBJECTINFO pGroupObjectInfo = NULL;
  1142. hr = ValidateGroupObject(
  1143. pObjectInfo,
  1144. &uGroupType,
  1145. &dwParentId,
  1146. Credentials
  1147. );
  1148. BAIL_ON_FAILURE(hr);
  1149. switch (pObjectInfo->NumComponents) {
  1150. case 2:
  1151. //
  1152. // could be group in computer or group in domain
  1153. //
  1154. if(dwParentId == WINNT_DOMAIN_ID){
  1155. szDomainName = pObjectInfo->ComponentArray[0];
  1156. szGroupName = pObjectInfo->ComponentArray[1];
  1157. szServerName = NULL;
  1158. hr = BuildParent(pObjectInfo, ADsParent);
  1159. BAIL_ON_FAILURE(hr);
  1160. } else {
  1161. //
  1162. // group in a computer
  1163. //
  1164. hr = ConstructFullObjectInfo(pObjectInfo,
  1165. &pGroupObjectInfo,
  1166. Credentials );
  1167. if (SUCCEEDED(hr)) {
  1168. hr = BuildParent(pGroupObjectInfo, ADsParent);
  1169. BAIL_ON_FAILURE(hr);
  1170. szDomainName = pGroupObjectInfo->ComponentArray[0];
  1171. szServerName = pGroupObjectInfo->ComponentArray[1];
  1172. szGroupName = pGroupObjectInfo->ComponentArray[2];
  1173. }
  1174. else if (hr == HRESULT_FROM_WIN32(NERR_WkstaNotStarted)) {
  1175. //
  1176. // We will build the info without the parent
  1177. //
  1178. hr = BuildParent(pObjectInfo, ADsParent);
  1179. BAIL_ON_FAILURE(hr);
  1180. szDomainName = NULL;
  1181. szServerName = pObjectInfo->ComponentArray[0];
  1182. szGroupName = pObjectInfo->ComponentArray[1];
  1183. }
  1184. BAIL_ON_FAILURE(hr);
  1185. }
  1186. break;
  1187. case 3:
  1188. hr = BuildParent(pObjectInfo, ADsParent);
  1189. BAIL_ON_FAILURE(hr);
  1190. szDomainName = pObjectInfo->ComponentArray[0];
  1191. szServerName = pObjectInfo->ComponentArray[1];
  1192. szGroupName = pObjectInfo->ComponentArray[2];
  1193. break;
  1194. }
  1195. hr = CWinNTGroup::CreateGroup(
  1196. ADsParent,
  1197. dwParentId,
  1198. szDomainName,
  1199. szServerName,
  1200. szGroupName,
  1201. uGroupType,
  1202. ADS_OBJECT_BOUND,
  1203. IID_IUnknown,
  1204. Credentials,
  1205. (void **)&pUnknown
  1206. );
  1207. BAIL_ON_FAILURE(hr);
  1208. *ppObject = pUnknown;
  1209. if(pGroupObjectInfo){
  1210. FreeObjectInfo(pGroupObjectInfo);
  1211. }
  1212. RRETURN(hr);
  1213. error:
  1214. if (pUnknown) {
  1215. pUnknown->Release();
  1216. }
  1217. if(pGroupObjectInfo){
  1218. FreeObjectInfo(pGroupObjectInfo);
  1219. }
  1220. *ppObject = NULL;
  1221. RRETURN(hr);
  1222. }
  1223. //+---------------------------------------------------------------------------
  1224. // Function: GetGroupObjectInComputer
  1225. //
  1226. // Synopsis:
  1227. //
  1228. // Arguments:
  1229. //
  1230. // Returns:
  1231. //
  1232. // Modifies:
  1233. //
  1234. // History: 11-3-95 ramv Created.
  1235. //
  1236. //----------------------------------------------------------------------------
  1237. HRESULT
  1238. GetGroupObjectInComputer(
  1239. LPWSTR pszHostServerName, // pdc name
  1240. POBJECTINFO pObjectInfo,
  1241. LPVOID * ppObject,
  1242. CWinNTCredentials& Credentials)
  1243. {
  1244. LPUNKNOWN pUnknown = NULL;
  1245. WCHAR ADsParent[MAX_ADS_PATH];
  1246. HRESULT hr = S_OK;
  1247. LPWSTR szServerName = NULL;
  1248. LPWSTR szDomainName = NULL;
  1249. LPWSTR szGroupName = NULL;
  1250. DWORD dwParentId = WINNT_COMPUTER_ID;
  1251. ULONG uGroupType = 0;
  1252. POBJECTINFO pGroupObjectInfo = NULL;
  1253. WCHAR lpszUncName[MAX_PATH];
  1254. switch (pObjectInfo->NumComponents) {
  1255. case 2:
  1256. //
  1257. // group in a computer
  1258. //
  1259. MakeUncName(pObjectInfo->ComponentArray[0],
  1260. lpszUncName);
  1261. hr = ValidateGlobalGroupObject(
  1262. lpszUncName,
  1263. &(pObjectInfo->ComponentArray[1]),
  1264. Credentials
  1265. );
  1266. if (SUCCEEDED(hr)) {
  1267. uGroupType = WINNT_GROUP_GLOBAL;
  1268. }else{
  1269. hr = ValidateLocalGroupObject(
  1270. lpszUncName,
  1271. &(pObjectInfo->ComponentArray[1]),
  1272. Credentials
  1273. );
  1274. BAIL_ON_FAILURE(hr);
  1275. uGroupType = WINNT_GROUP_LOCAL;
  1276. }
  1277. hr = ConstructFullObjectInfo(pObjectInfo,
  1278. &pGroupObjectInfo,
  1279. Credentials );
  1280. BAIL_ON_FAILURE(hr);
  1281. hr = BuildParent(pGroupObjectInfo, ADsParent);
  1282. BAIL_ON_FAILURE(hr);
  1283. szDomainName = pGroupObjectInfo->ComponentArray[0];
  1284. szServerName = pGroupObjectInfo->ComponentArray[1];
  1285. szGroupName = pGroupObjectInfo->ComponentArray[2];
  1286. break;
  1287. case 3:
  1288. hr = ValidateComputerParent(pObjectInfo->ComponentArray[0],
  1289. pObjectInfo->ComponentArray[1],
  1290. Credentials);
  1291. BAIL_ON_FAILURE(hr);
  1292. MakeUncName(
  1293. pObjectInfo->ComponentArray[1],
  1294. lpszUncName
  1295. );
  1296. hr = ValidateGlobalGroupObject(
  1297. lpszUncName,
  1298. &(pObjectInfo->ComponentArray[2]),
  1299. Credentials
  1300. );
  1301. if (SUCCEEDED(hr)) {
  1302. uGroupType = WINNT_GROUP_GLOBAL;
  1303. } else {
  1304. hr = ValidateLocalGroupObject(
  1305. lpszUncName,
  1306. &(pObjectInfo->ComponentArray[2]),
  1307. Credentials
  1308. );
  1309. BAIL_ON_FAILURE(hr);
  1310. uGroupType = WINNT_GROUP_LOCAL;
  1311. }
  1312. hr = BuildParent(pObjectInfo, ADsParent);
  1313. BAIL_ON_FAILURE(hr);
  1314. szDomainName = pObjectInfo->ComponentArray[0];
  1315. szServerName = pObjectInfo->ComponentArray[1];
  1316. szGroupName = pObjectInfo->ComponentArray[2];
  1317. break;
  1318. }
  1319. if (uGroupType == WINNT_GROUP_LOCAL) {
  1320. hr = CWinNTGroup::CreateGroup(ADsParent,
  1321. dwParentId,
  1322. szDomainName,
  1323. szServerName,
  1324. szGroupName,
  1325. uGroupType,
  1326. ADS_OBJECT_BOUND,
  1327. IID_IUnknown,
  1328. Credentials,
  1329. (void **)&pUnknown
  1330. );
  1331. }else {
  1332. hr = CWinNTGroup::CreateGroup(ADsParent,
  1333. dwParentId,
  1334. szDomainName,
  1335. szServerName,
  1336. szGroupName,
  1337. uGroupType,
  1338. ADS_OBJECT_BOUND,
  1339. IID_IUnknown,
  1340. Credentials,
  1341. (void **)&pUnknown
  1342. );
  1343. }
  1344. BAIL_ON_FAILURE(hr);
  1345. *ppObject = pUnknown;
  1346. if(pGroupObjectInfo){
  1347. FreeObjectInfo(pGroupObjectInfo);
  1348. }
  1349. RRETURN(hr);
  1350. error:
  1351. if (pUnknown) {
  1352. pUnknown->Release();
  1353. }
  1354. if(pGroupObjectInfo){
  1355. FreeObjectInfo(pGroupObjectInfo);
  1356. }
  1357. *ppObject = NULL;
  1358. RRETURN(hr);
  1359. }
  1360. //+---------------------------------------------------------------------------
  1361. // Function: GetGroupObjectInDomain
  1362. //
  1363. // Synopsis:
  1364. //
  1365. // Arguments:
  1366. //
  1367. // Returns:
  1368. //
  1369. // Modifies:
  1370. //
  1371. // History: 8-8-96 Ramv Created.
  1372. //
  1373. //----------------------------------------------------------------------------
  1374. HRESULT
  1375. GetGroupObjectInDomain(
  1376. LPWSTR pszHostServerName,
  1377. POBJECTINFO pObjectInfo,
  1378. LPVOID * ppObject,
  1379. CWinNTCredentials& Credentials
  1380. )
  1381. {
  1382. LPUNKNOWN pUnknown = NULL;
  1383. WCHAR ADsParent[MAX_ADS_PATH];
  1384. HRESULT hr = S_OK;
  1385. LPWSTR szServerName = NULL;
  1386. LPWSTR szDomainName = NULL;
  1387. LPWSTR szGroupName = NULL;
  1388. DWORD dwParentId = WINNT_DOMAIN_ID;
  1389. ULONG uGroupType = 0;
  1390. BOOL fRefAdded = FALSE;
  1391. // At this point the host server name has a \\ prepended
  1392. // so we need to get rid of it.
  1393. hr = Credentials.RefServer(pszHostServerName+2);
  1394. if (SUCCEEDED(hr)) {
  1395. fRefAdded = TRUE;
  1396. }
  1397. hr = ValidateGlobalGroupObject(
  1398. pszHostServerName,
  1399. &(pObjectInfo->ComponentArray[1]),
  1400. Credentials
  1401. );
  1402. if (FAILED(hr)) {
  1403. hr = ValidateLocalGroupObject(
  1404. pszHostServerName,
  1405. &(pObjectInfo->ComponentArray[1]),
  1406. Credentials
  1407. );
  1408. // DeRef if ref added, no recovery possible on failed deref
  1409. if (fRefAdded) {
  1410. Credentials.DeRefServer();
  1411. fRefAdded = FALSE;
  1412. }
  1413. BAIL_ON_FAILURE(hr);
  1414. uGroupType = WINNT_GROUP_LOCAL;
  1415. }else {
  1416. uGroupType = WINNT_GROUP_GLOBAL;
  1417. }
  1418. // DeRef if ref added, no recovery possible on failed deref
  1419. if (fRefAdded) {
  1420. Credentials.DeRefServer();
  1421. fRefAdded = FALSE;
  1422. }
  1423. szDomainName = pObjectInfo->ComponentArray[0];
  1424. szGroupName = pObjectInfo->ComponentArray[1];
  1425. szServerName = NULL;
  1426. hr = BuildParent(pObjectInfo, ADsParent);
  1427. BAIL_ON_FAILURE(hr);
  1428. if (uGroupType==WINNT_GROUP_LOCAL) {
  1429. hr = CWinNTGroup::CreateGroup(
  1430. ADsParent,
  1431. dwParentId,
  1432. szDomainName,
  1433. szServerName,
  1434. szGroupName,
  1435. uGroupType,
  1436. ADS_OBJECT_BOUND,
  1437. IID_IUnknown,
  1438. Credentials,
  1439. (void **)&pUnknown
  1440. );
  1441. } else {
  1442. hr = CWinNTGroup::CreateGroup(ADsParent,
  1443. dwParentId,
  1444. szDomainName,
  1445. szServerName,
  1446. szGroupName,
  1447. uGroupType,
  1448. ADS_OBJECT_BOUND,
  1449. IID_IUnknown,
  1450. Credentials,
  1451. (void **)&pUnknown
  1452. );
  1453. }
  1454. BAIL_ON_FAILURE(hr);
  1455. *ppObject = pUnknown;
  1456. RRETURN(hr);
  1457. error:
  1458. if (pUnknown) {
  1459. pUnknown->Release();
  1460. }
  1461. *ppObject = NULL;
  1462. RRETURN(hr);
  1463. }
  1464. //+---------------------------------------------------------------------------
  1465. // Function: GetSchemaObject
  1466. //
  1467. // Synopsis:
  1468. //
  1469. // Arguments:
  1470. //
  1471. // Returns:
  1472. //
  1473. // Modifies:
  1474. //
  1475. // History: 1-17-96 yihsins Created.
  1476. //
  1477. //----------------------------------------------------------------------------
  1478. HRESULT
  1479. GetSchemaObject(
  1480. POBJECTINFO pObjectInfo,
  1481. LPVOID * ppObject,
  1482. CWinNTCredentials& Credentials
  1483. )
  1484. {
  1485. LPUNKNOWN pUnknown = NULL;
  1486. WCHAR ADsParent[MAX_ADS_PATH];
  1487. HRESULT hr = S_OK;
  1488. if (pObjectInfo->NumComponents != 2)
  1489. RRETURN(E_ADS_BAD_PATHNAME);
  1490. if ( _wcsicmp( pObjectInfo->ComponentArray[1], SCHEMA_NAME ) != 0 )
  1491. {
  1492. hr = E_ADS_BAD_PATHNAME;
  1493. BAIL_ON_FAILURE(hr);
  1494. }
  1495. hr = BuildParent(pObjectInfo, ADsParent);
  1496. BAIL_ON_FAILURE(hr);
  1497. hr = CWinNTSchema::CreateSchema( ADsParent,
  1498. pObjectInfo->ComponentArray[1],
  1499. ADS_OBJECT_BOUND,
  1500. IID_IUnknown,
  1501. Credentials,
  1502. (void **)&pUnknown );
  1503. BAIL_ON_FAILURE(hr);
  1504. *ppObject = pUnknown;
  1505. RRETURN(hr);
  1506. error:
  1507. if (pUnknown)
  1508. pUnknown->Release();
  1509. *ppObject = NULL;
  1510. RRETURN(hr);
  1511. }
  1512. //+---------------------------------------------------------------------------
  1513. // Function: GetClassObject
  1514. //
  1515. // Synopsis:
  1516. //
  1517. // Arguments:
  1518. //
  1519. // Returns:
  1520. //
  1521. // Modifies:
  1522. //
  1523. // History: 1-17-96 yihsins Created.
  1524. //
  1525. //----------------------------------------------------------------------------
  1526. HRESULT
  1527. GetClassObject(
  1528. POBJECTINFO pObjectInfo,
  1529. LPVOID * ppObject,
  1530. CWinNTCredentials& Credentials
  1531. )
  1532. {
  1533. LPUNKNOWN pUnknown = NULL;
  1534. WCHAR ADsParent[MAX_ADS_PATH];
  1535. HRESULT hr = S_OK;
  1536. DWORD i;
  1537. if (pObjectInfo->NumComponents != 3)
  1538. RRETURN(E_ADS_BAD_PATHNAME);
  1539. if ( _wcsicmp( pObjectInfo->ComponentArray[1], SCHEMA_NAME ) != 0 )
  1540. {
  1541. hr = E_ADS_BAD_PATHNAME;
  1542. BAIL_ON_FAILURE(hr);
  1543. }
  1544. //
  1545. // Look for the given class name
  1546. //
  1547. for ( i = 0; i < g_cWinNTClasses; i++ )
  1548. {
  1549. if ( _wcsicmp( g_aWinNTClasses[i].bstrName,
  1550. pObjectInfo->ComponentArray[2] ) == 0 )
  1551. break;
  1552. }
  1553. if ( i == g_cWinNTClasses )
  1554. {
  1555. // Class name not found, return error
  1556. hr = E_ADS_BAD_PATHNAME;
  1557. BAIL_ON_FAILURE(hr);
  1558. }
  1559. //
  1560. // Class name found, create and return the object
  1561. //
  1562. hr = BuildParent(pObjectInfo, ADsParent);
  1563. BAIL_ON_FAILURE(hr);
  1564. hr = CWinNTClass::CreateClass( ADsParent,
  1565. &g_aWinNTClasses[i],
  1566. ADS_OBJECT_BOUND,
  1567. IID_IUnknown,
  1568. Credentials,
  1569. (void **)&pUnknown );
  1570. BAIL_ON_FAILURE(hr);
  1571. *ppObject = pUnknown;
  1572. RRETURN(hr);
  1573. error:
  1574. if (pUnknown)
  1575. pUnknown->Release();
  1576. *ppObject = NULL;
  1577. RRETURN(hr);
  1578. }
  1579. //+---------------------------------------------------------------------------
  1580. // Function: GetSyntaxObject
  1581. //
  1582. // Synopsis:
  1583. //
  1584. // Arguments:
  1585. //
  1586. // Returns:
  1587. //
  1588. // Modifies:
  1589. //
  1590. // History: 1-17-96 yihsins Created.
  1591. //
  1592. //----------------------------------------------------------------------------
  1593. HRESULT
  1594. GetSyntaxObject(
  1595. POBJECTINFO pObjectInfo,
  1596. LPVOID * ppObject,
  1597. CWinNTCredentials& Credentials
  1598. )
  1599. {
  1600. LPUNKNOWN pUnknown = NULL;
  1601. WCHAR ADsParent[MAX_ADS_PATH];
  1602. HRESULT hr = S_OK;
  1603. DWORD i;
  1604. if (pObjectInfo->NumComponents != 3)
  1605. RRETURN(E_ADS_BAD_PATHNAME);
  1606. if ( _wcsicmp( pObjectInfo->ComponentArray[1], SCHEMA_NAME ) != 0 )
  1607. {
  1608. hr = E_ADS_BAD_PATHNAME;
  1609. BAIL_ON_FAILURE(hr);
  1610. }
  1611. //
  1612. // Look for the given syntax name
  1613. //
  1614. for ( i = 0; i < g_cWinNTSyntax; i++ )
  1615. {
  1616. if ( _wcsicmp( g_aWinNTSyntax[i].bstrName,
  1617. pObjectInfo->ComponentArray[2] ) == 0 )
  1618. break;
  1619. }
  1620. if ( i == g_cWinNTSyntax )
  1621. {
  1622. // Syntax name not found, return error
  1623. hr = E_ADS_BAD_PATHNAME;
  1624. BAIL_ON_FAILURE(hr);
  1625. }
  1626. //
  1627. // Syntax name found, create and return the object
  1628. //
  1629. hr = BuildParent(pObjectInfo, ADsParent);
  1630. BAIL_ON_FAILURE(hr);
  1631. hr = CWinNTSyntax::CreateSyntax( ADsParent,
  1632. &(g_aWinNTSyntax[i]),
  1633. ADS_OBJECT_BOUND,
  1634. IID_IUnknown,
  1635. Credentials,
  1636. (void **)&pUnknown );
  1637. BAIL_ON_FAILURE(hr);
  1638. *ppObject = pUnknown;
  1639. RRETURN(hr);
  1640. error:
  1641. if (pUnknown)
  1642. pUnknown->Release();
  1643. *ppObject = NULL;
  1644. RRETURN(hr);
  1645. }
  1646. //+---------------------------------------------------------------------------
  1647. // Function: GetPropertyObject
  1648. //
  1649. // Synopsis:
  1650. //
  1651. // Arguments:
  1652. //
  1653. // Returns:
  1654. //
  1655. // Modifies:
  1656. //
  1657. // History: 1-17-96 yihsins Created.
  1658. //
  1659. //----------------------------------------------------------------------------
  1660. HRESULT
  1661. GetPropertyObject(
  1662. POBJECTINFO pObjectInfo,
  1663. LPVOID * ppObject,
  1664. CWinNTCredentials& Credentials
  1665. )
  1666. {
  1667. LPUNKNOWN pUnknown = NULL;
  1668. WCHAR ADsParent[MAX_ADS_PATH];
  1669. WCHAR ADsGrandParent[MAX_ADS_PATH];
  1670. HRESULT hr = S_OK;
  1671. DWORD nClass, nProp;
  1672. if (pObjectInfo->NumComponents != 3)
  1673. RRETURN(E_ADS_BAD_PATHNAME);
  1674. if ( _wcsicmp( pObjectInfo->ComponentArray[1], SCHEMA_NAME ) != 0 )
  1675. {
  1676. hr = E_ADS_BAD_PATHNAME;
  1677. BAIL_ON_FAILURE(hr);
  1678. }
  1679. //
  1680. // We found the specified functional set, now see if we can locate
  1681. // the given property name
  1682. //
  1683. for ( nProp = 0; nProp < g_cWinNTProperties; nProp++ )
  1684. {
  1685. if ( _wcsicmp(g_aWinNTProperties[nProp].szPropertyName,
  1686. pObjectInfo->ComponentArray[2] ) == 0 )
  1687. break;
  1688. }
  1689. if ( nProp == g_cWinNTProperties )
  1690. {
  1691. // Return error because the given property name is not found
  1692. hr = E_ADS_BAD_PATHNAME;
  1693. BAIL_ON_FAILURE(hr);
  1694. }
  1695. //
  1696. // Property name is found, so create and return the object
  1697. //
  1698. hr = BuildParent(pObjectInfo, ADsParent);
  1699. BAIL_ON_FAILURE(hr);
  1700. hr = CWinNTProperty::CreateProperty(
  1701. ADsParent,
  1702. &(g_aWinNTProperties[nProp]),
  1703. ADS_OBJECT_BOUND,
  1704. IID_IUnknown,
  1705. Credentials,
  1706. (void **)&pUnknown );
  1707. BAIL_ON_FAILURE(hr);
  1708. *ppObject = pUnknown;
  1709. RRETURN(hr);
  1710. error:
  1711. if (pUnknown)
  1712. pUnknown->Release();
  1713. *ppObject = NULL;
  1714. RRETURN(hr);
  1715. }
  1716. //+---------------------------------------------------------------------------
  1717. // Function:
  1718. //
  1719. // Synopsis:
  1720. //
  1721. // Arguments:
  1722. //
  1723. // Returns:
  1724. //
  1725. // Modifies:
  1726. //
  1727. // History: 11-3-95 krishnag Created.
  1728. //
  1729. //----------------------------------------------------------------------------
  1730. HRESULT
  1731. HeuristicGetObject(
  1732. POBJECTINFO pObjectInfo,
  1733. LPVOID * ppObject,
  1734. CWinNTCredentials& Credentials
  1735. )
  1736. {
  1737. HRESULT hr = S_OK;
  1738. WCHAR szHostServerName[MAX_PATH];
  1739. DWORD dwElementType;
  1740. WCHAR szName[MAX_PATH];
  1741. WCHAR szSAMName[MAX_ADS_PATH];
  1742. WCHAR lpszUncName[MAX_PATH];
  1743. szSAMName[0] = L'\0';
  1744. //
  1745. // Case 0: Zero components - must be a namespace object
  1746. //
  1747. if (pObjectInfo->NumComponents == 0) {
  1748. RRETURN(GetNamespaceObject(pObjectInfo, ppObject, Credentials));
  1749. }
  1750. //
  1751. // Case 1: Single component - must be a domain object or
  1752. // computer object
  1753. //
  1754. if (pObjectInfo->NumComponents == 1) {
  1755. //
  1756. // hr = WinNTGetCachedObject(type, hit/miss, pdcname/domain name)
  1757. //
  1758. // if (succeeded...
  1759. // switch(type) .... call the appropriate
  1760. // GetDomain or GetWorkGroup or GetComputer
  1761. //
  1762. hr = WinNTGetCachedName(
  1763. pObjectInfo->ComponentArray[0],
  1764. &dwElementType,
  1765. szHostServerName,
  1766. szSAMName,
  1767. Credentials
  1768. );
  1769. BAIL_IF_ERROR(hr);
  1770. // update the name to the one on SAM
  1771. if (szSAMName[0] != L'\0') {
  1772. FreeADsStr(pObjectInfo->ComponentArray[0]);
  1773. pObjectInfo->ComponentArray[0] = AllocADsStr(szSAMName);
  1774. }
  1775. if (!pObjectInfo->ComponentArray[0]) {
  1776. BAIL_IF_ERROR(hr = E_OUTOFMEMORY);
  1777. }
  1778. switch(dwElementType) {
  1779. case DOMAIN_ENTRY_TYPE:
  1780. hr = GetDomainObject(pObjectInfo, ppObject, Credentials);
  1781. break;
  1782. case COMPUTER_ENTRY_TYPE:
  1783. hr = GetComputerObject(pObjectInfo, ppObject, Credentials);
  1784. break;
  1785. default:
  1786. hr = GetWorkGroupObject(pObjectInfo, ppObject, Credentials);
  1787. break;
  1788. }
  1789. goto cleanup;
  1790. }
  1791. //
  1792. // Case 2: Two components - could be user, group, computer,
  1793. // or any one of the computer's sub-objects.
  1794. //
  1795. if (pObjectInfo->NumComponents == 2) {
  1796. hr = GetSchemaObject(pObjectInfo, ppObject, Credentials);
  1797. if(SUCCEEDED(hr)){
  1798. goto cleanup;
  1799. }
  1800. if(FAILED(hr)) {
  1801. //
  1802. // try doing a WinNTGetCachedDCName first
  1803. // and if it goes through, then we have objects such as
  1804. // user,group,computer in domain, otherwise it is the
  1805. // computer case or workgroup case
  1806. //
  1807. // WinNtGetCachedObject will directly tell us to proceed or
  1808. // not
  1809. hr = WinNTGetCachedName(pObjectInfo->ComponentArray[0],
  1810. &dwElementType,
  1811. szHostServerName,
  1812. szSAMName,
  1813. Credentials );
  1814. BAIL_IF_ERROR(hr);
  1815. // Again we do not have to worry about the case of the
  1816. // object name, it is handled by the GetObject calls
  1817. switch(dwElementType) {
  1818. case DOMAIN_ENTRY_TYPE:
  1819. hr = GetUserObjectInDomain(szHostServerName,
  1820. pObjectInfo,
  1821. ppObject,
  1822. Credentials);
  1823. if (FAILED(hr)) {
  1824. hr = GetGroupObjectInDomain(szHostServerName,
  1825. pObjectInfo,
  1826. ppObject,
  1827. Credentials);
  1828. }
  1829. if (FAILED(hr)) {
  1830. hr = GetComputerObject(pObjectInfo, ppObject, Credentials);
  1831. }
  1832. goto cleanup;
  1833. case COMPUTER_ENTRY_TYPE:
  1834. hr = GetPrinterObject(pObjectInfo, ppObject, Credentials);
  1835. if (FAILED(hr)) {
  1836. hr = GetFileServiceObject(
  1837. pObjectInfo,
  1838. ppObject,
  1839. Credentials
  1840. );
  1841. }
  1842. if (FAILED(hr)) {
  1843. hr = GetServiceObject(pObjectInfo, ppObject, Credentials);
  1844. }
  1845. if(FAILED(hr)){
  1846. hr = GetUserObjectInComputer(
  1847. pObjectInfo->ComponentArray[0],
  1848. pObjectInfo,
  1849. ppObject,
  1850. Credentials
  1851. );
  1852. }
  1853. if (FAILED(hr)) {
  1854. hr = GetGroupObjectInComputer(
  1855. pObjectInfo->ComponentArray[0],
  1856. pObjectInfo,
  1857. ppObject,
  1858. Credentials
  1859. );
  1860. }
  1861. goto cleanup;
  1862. case WORKGROUP_ENTRY_TYPE:
  1863. hr = GetComputerObject(pObjectInfo, ppObject, Credentials);
  1864. if (FAILED(hr)) {
  1865. if (hr == HRESULT_FROM_WIN32(NERR_BadTransactConfig)) {
  1866. // In this case I want to mask the error
  1867. // as it means it could not find the object
  1868. hr = E_ADS_UNKNOWN_OBJECT;
  1869. }
  1870. }
  1871. goto cleanup;
  1872. default:
  1873. hr = E_ADS_UNKNOWN_OBJECT;
  1874. goto cleanup;
  1875. }
  1876. }
  1877. } /* NumComponents == 2 */
  1878. //
  1879. // Case 3: Three components - could be user, group, printer, fileservice
  1880. // or service or fileshare for computer in a workgroup environment.
  1881. //
  1882. if (pObjectInfo->NumComponents == 3) {
  1883. if ( _wcsicmp( pObjectInfo->ComponentArray[1], SCHEMA_NAME ) == 0 ){
  1884. hr = GetClassObject(pObjectInfo, ppObject, Credentials);
  1885. if (FAILED(hr)) {
  1886. hr = GetPropertyObject(pObjectInfo, ppObject, Credentials);
  1887. }
  1888. if (FAILED(hr)) {
  1889. hr = GetSyntaxObject(pObjectInfo, ppObject, Credentials);
  1890. }
  1891. }
  1892. else{
  1893. hr = GetUserObjectInComputer(pObjectInfo->ComponentArray[1],
  1894. pObjectInfo,
  1895. ppObject,
  1896. Credentials);
  1897. if (FAILED(hr)) {
  1898. hr = GetGroupObjectInComputer(pObjectInfo->ComponentArray[1],
  1899. pObjectInfo,
  1900. ppObject,
  1901. Credentials);
  1902. }
  1903. if(FAILED(hr)){
  1904. hr = GetPrinterObject(pObjectInfo, ppObject, Credentials);
  1905. }
  1906. if (FAILED(hr)) {
  1907. hr = GetFileServiceObject(pObjectInfo, ppObject, Credentials);
  1908. }
  1909. if (FAILED(hr)) {
  1910. hr = GetServiceObject(pObjectInfo, ppObject, Credentials);
  1911. }
  1912. if (FAILED(hr)) {
  1913. hr = GetFileShareObject(pObjectInfo, ppObject, Credentials);
  1914. }
  1915. }
  1916. if(FAILED(hr) ){
  1917. RRETURN(hr);
  1918. }
  1919. else{
  1920. RRETURN(S_OK);
  1921. }
  1922. }
  1923. if (pObjectInfo->NumComponents == 4) {
  1924. hr = GetFileShareObject(pObjectInfo, ppObject, Credentials);
  1925. if(FAILED(hr)){
  1926. RRETURN(hr);
  1927. }
  1928. else{
  1929. RRETURN(S_OK);
  1930. }
  1931. }
  1932. RRETURN (E_ADS_UNKNOWN_OBJECT);
  1933. cleanup:
  1934. if (hr == HRESULT_FROM_WIN32(NERR_WkstaNotStarted)) {
  1935. //
  1936. // There is a very good chance that this is a case
  1937. // where they are trying to work on the local machine
  1938. // when there are no workstation services. Note that this
  1939. // means that a fully qualified name was not given.
  1940. //
  1941. hr = HeuristicGetObjectNoWksta(
  1942. pObjectInfo,
  1943. ppObject,
  1944. Credentials
  1945. );
  1946. }
  1947. //
  1948. // Propagate the error code which we have rather than
  1949. // mask it and return information of little value
  1950. //
  1951. if (FAILED(hr)) {
  1952. // the error code NERR_BadTransactConfig means that the
  1953. // object did not exist, we want to mask just that ecode
  1954. if (hr == HRESULT_FROM_WIN32(NERR_BadTransactConfig)) {
  1955. hr = E_ADS_UNKNOWN_OBJECT;
  1956. }
  1957. RRETURN(hr);
  1958. } else {
  1959. RRETURN(S_OK);
  1960. }
  1961. }
  1962. //+---------------------------------------------------------------------------
  1963. // Function: HeuristicGetObjectNoWksta
  1964. //
  1965. // Synopsis: Tries to locate the object on local machine when there are no
  1966. // workstation services. This will happen in a minimum install of NT.
  1967. //
  1968. // Arguments: POBJECTINFO -> data about object being located.
  1969. // LPVOID -> Object to be returned in this arg.
  1970. // Credentials -> Credentials blob.
  1971. //
  1972. // Returns: Either S_OK or HR_From_Win32(NERR_WkstaNotStarted)
  1973. //
  1974. // Modifies:
  1975. //
  1976. // History: 08-03-98 AjayR Created.
  1977. //
  1978. //----------------------------------------------------------------------------
  1979. HRESULT
  1980. HeuristicGetObjectNoWksta(
  1981. POBJECTINFO pObjectInfo,
  1982. LPVOID * ppObject,
  1983. CWinNTCredentials& Credentials
  1984. )
  1985. {
  1986. HRESULT hr = S_OK;
  1987. HRESULT hrNoWksta = HRESULT_FROM_WIN32(NERR_WkstaNotStarted);
  1988. WCHAR szHostServerName[MAX_PATH];
  1989. DWORD dwElementType;
  1990. WCHAR szName[MAX_PATH];
  1991. WCHAR szSAMName[MAX_ADS_PATH];
  1992. WCHAR lpszUncName[MAX_PATH];
  1993. szSAMName[0] = L'\0';
  1994. //
  1995. // Case 0: Zero components - Should no be hit here.
  1996. //
  1997. if (pObjectInfo->NumComponents == 0) {
  1998. RRETURN(hrNoWksta);
  1999. }
  2000. //
  2001. // Case 1: Single component - Can only be a computer object
  2002. //
  2003. if (pObjectInfo->NumComponents == 1) {
  2004. hr = GetComputerObject(pObjectInfo, ppObject, Credentials);
  2005. goto cleanup;
  2006. }
  2007. //
  2008. // Case 2: Two components - could be user or group for now.
  2009. // Other possible objects - TBD.
  2010. //
  2011. if (pObjectInfo->NumComponents == 2) {
  2012. hr = GetPrinterObject(pObjectInfo, ppObject, Credentials);
  2013. if (FAILED(hr)) {
  2014. hr = GetFileServiceObject(
  2015. pObjectInfo,
  2016. ppObject,
  2017. Credentials
  2018. );
  2019. }
  2020. if (FAILED(hr)) {
  2021. hr = GetServiceObject(pObjectInfo, ppObject, Credentials);
  2022. }
  2023. if(FAILED(hr)){
  2024. hr = GetUserObject(
  2025. pObjectInfo,
  2026. ppObject,
  2027. Credentials
  2028. );
  2029. }
  2030. if (FAILED(hr)) {
  2031. hr = GetLocalGroupObject(
  2032. pObjectInfo,
  2033. ppObject,
  2034. Credentials
  2035. );
  2036. }
  2037. goto cleanup;
  2038. } /* NumComponents == 2 */
  2039. //
  2040. // Case 3 or more : Three or more components - not possible
  2041. //
  2042. if (pObjectInfo->NumComponents > 2) {
  2043. RRETURN(hrNoWksta);
  2044. }
  2045. RRETURN (E_ADS_UNKNOWN_OBJECT);
  2046. cleanup:
  2047. //
  2048. // Propagate the error code which we have rather than
  2049. // mask it and return information of little value
  2050. //
  2051. if (FAILED(hr)) {
  2052. // the error code NERR_BadTransactConfig means that the
  2053. // object did not exist, we want to mask just that ecode
  2054. if (hr == HRESULT_FROM_WIN32(NERR_BadTransactConfig)) {
  2055. hr = E_ADS_UNKNOWN_OBJECT;
  2056. }
  2057. RRETURN(hr);
  2058. } else {
  2059. RRETURN(S_OK);
  2060. }
  2061. }
  2062. HRESULT
  2063. BuildParent(
  2064. POBJECTINFO pObjectInfo,
  2065. LPWSTR szBuffer
  2066. )
  2067. {
  2068. DWORD i = 0;
  2069. DWORD dwLen = 0;
  2070. if (!pObjectInfo->ProviderName) {
  2071. RRETURN(E_ADS_BAD_PATHNAME);
  2072. }
  2073. wsprintf(szBuffer, L"%s:", pObjectInfo->ProviderName);
  2074. if (pObjectInfo->NumComponents - 1) {
  2075. dwLen = wcslen(pObjectInfo->ProviderName) + 3 +
  2076. wcslen(pObjectInfo->DisplayComponentArray[0]);
  2077. if(dwLen >= MAX_ADS_PATH) {
  2078. RRETURN(E_ADS_BAD_PATHNAME);
  2079. }
  2080. wcscat(szBuffer, L"//");
  2081. wcscat(szBuffer, pObjectInfo->DisplayComponentArray[0]);
  2082. for (i = 1; i < (pObjectInfo->NumComponents - 1); i++) {
  2083. dwLen += (1 + wcslen(pObjectInfo->DisplayComponentArray[i]));
  2084. if(dwLen >= MAX_ADS_PATH) {
  2085. RRETURN(E_ADS_BAD_PATHNAME);
  2086. }
  2087. wcscat(szBuffer, L"/");
  2088. wcscat(szBuffer, pObjectInfo->DisplayComponentArray[i]);
  2089. }
  2090. }
  2091. RRETURN(S_OK);
  2092. }
  2093. HRESULT
  2094. BuildGrandParent(
  2095. POBJECTINFO pObjectInfo,
  2096. LPWSTR szBuffer
  2097. )
  2098. {
  2099. DWORD i = 0;
  2100. if (!pObjectInfo->ProviderName) {
  2101. RRETURN(E_ADS_BAD_PATHNAME);
  2102. }
  2103. wsprintf(szBuffer, L"%s:", pObjectInfo->ProviderName);
  2104. if (pObjectInfo->NumComponents - 2) {
  2105. wcscat(szBuffer, L"//");
  2106. wcscat(szBuffer, pObjectInfo->ComponentArray[0]);
  2107. for (i = 1; i < (pObjectInfo->NumComponents - 2); i++) {
  2108. wcscat(szBuffer, L"/");
  2109. wcscat(szBuffer, pObjectInfo->ComponentArray[i]);
  2110. }
  2111. }
  2112. RRETURN(S_OK);
  2113. }
  2114. HRESULT
  2115. BuildADsPath(
  2116. POBJECTINFO pObjectInfo,
  2117. LPWSTR szBuffer
  2118. )
  2119. {
  2120. DWORD i = 0;
  2121. if (!pObjectInfo->ProviderName) {
  2122. RRETURN(E_ADS_BAD_PATHNAME);
  2123. }
  2124. wsprintf(szBuffer, L"%s:", pObjectInfo->ProviderName);
  2125. if (pObjectInfo->NumComponents) {
  2126. wcscat(szBuffer, L"//");
  2127. wcscat(szBuffer, pObjectInfo->DisplayComponentArray[0]);
  2128. for (i = 1; i < (pObjectInfo->NumComponents); i++) {
  2129. wcscat(szBuffer, L"/");
  2130. wcscat(szBuffer, pObjectInfo->DisplayComponentArray[i]);
  2131. }
  2132. }
  2133. RRETURN(S_OK);
  2134. }
  2135. HRESULT
  2136. ValidateUserObject(
  2137. POBJECTINFO pObjectInfo,
  2138. PDWORD pdwParentId,
  2139. CWinNTCredentials& Credentials
  2140. )
  2141. {
  2142. WCHAR szHostServerName[MAX_PATH];
  2143. LPUSER_INFO_20 lpUI = NULL;
  2144. HRESULT hr;
  2145. WCHAR lpszUncName[MAX_PATH];
  2146. NET_API_STATUS nasStatus;
  2147. WCHAR szSAMName[MAX_PATH];
  2148. BOOL fRefAdded = FALSE;
  2149. LPUSER_INFO_0 lpUI_0 = NULL;
  2150. DWORD dwLevelUsed = 20;
  2151. WCHAR szCompName[MAX_PATH];
  2152. DWORD dwSize = MAX_PATH;
  2153. szSAMName[0] = L'\0';
  2154. switch (pObjectInfo->NumComponents) {
  2155. case 2:
  2156. //
  2157. // if 2 components then either it is user in computer
  2158. // or user in domain.
  2159. hr = WinNTGetCachedDCName(
  2160. pObjectInfo->ComponentArray[0],
  2161. szHostServerName,
  2162. Credentials.GetFlags()
  2163. );
  2164. if(SUCCEEDED(hr)){
  2165. // Need to ref the server, note that RefServer
  2166. // checks if the credentials are non null
  2167. // We are not concerned about any error as we may
  2168. // still succeed with default credentials.
  2169. // The +2 is to skip the \\ at the head.
  2170. hr = Credentials.RefServer(szHostServerName+2);
  2171. if (SUCCEEDED(hr)) {
  2172. fRefAdded = TRUE;
  2173. }
  2174. nasStatus = NetUserGetInfo(szHostServerName,
  2175. pObjectInfo->ComponentArray[1],
  2176. 20,
  2177. (LPBYTE *)&lpUI);
  2178. //
  2179. // This code is here because Level 20 reads the flags
  2180. // and if you accessed WinNT://ntdev/foo with Redmond\foo
  2181. // credentials, it will fail. This allow a bind but the
  2182. // GetInfo will fail.
  2183. //
  2184. if (nasStatus == ERROR_ACCESS_DENIED) {
  2185. // try and drop down to level 0 as that may work
  2186. dwLevelUsed = 0;
  2187. nasStatus = NetUserGetInfo(
  2188. szHostServerName,
  2189. pObjectInfo->ComponentArray[1],
  2190. 0,
  2191. (LPBYTE *)&lpUI_0
  2192. );
  2193. }
  2194. // DeRef if ref added, no recovery possible on failed deref
  2195. if (fRefAdded) {
  2196. Credentials.DeRefServer();
  2197. fRefAdded = FALSE;
  2198. }
  2199. hr = HRESULT_FROM_WIN32(nasStatus);
  2200. BAIL_ON_FAILURE(hr);
  2201. // Need to use the name returned by the call as opposed
  2202. // to the name given in the ADsPath
  2203. if (dwLevelUsed == 20 ) {
  2204. if (pObjectInfo->ComponentArray[1] && lpUI->usri20_name) {
  2205. FreeADsStr(pObjectInfo->ComponentArray[1]);
  2206. pObjectInfo->ComponentArray[1]
  2207. = AllocADsStr(lpUI->usri20_name);
  2208. }
  2209. if (!pObjectInfo->ComponentArray[1])
  2210. BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
  2211. }
  2212. *pdwParentId = WINNT_DOMAIN_ID;
  2213. }
  2214. //
  2215. // if we are here with hr != S_OK it could be that we have
  2216. // user in a computer.
  2217. //
  2218. if(FAILED(hr)){
  2219. hr = ValidateComputerParent(
  2220. NULL,
  2221. pObjectInfo->ComponentArray[0],
  2222. Credentials
  2223. );
  2224. if (SUCCEEDED(hr)) {
  2225. // Need to ref the server on which the object lives
  2226. // Note that RefServer checks if Credentials are null.
  2227. // Again, we are not concerned about any errors as we
  2228. // will drop down to default credentials automatically.
  2229. hr = Credentials.RefServer(pObjectInfo->ComponentArray[0]);
  2230. if (SUCCEEDED(hr)) {
  2231. fRefAdded = TRUE;
  2232. }
  2233. MakeUncName(pObjectInfo->ComponentArray[0],
  2234. lpszUncName);
  2235. nasStatus = NetUserGetInfo(lpszUncName,
  2236. pObjectInfo->ComponentArray[1],
  2237. 20,
  2238. (LPBYTE *)&lpUI);
  2239. // DeRef if ref added, no recovery possible on failed deref
  2240. if (fRefAdded) {
  2241. Credentials.DeRefServer();
  2242. fRefAdded = FALSE;
  2243. }
  2244. hr = HRESULT_FROM_WIN32(nasStatus);
  2245. BAIL_ON_FAILURE(hr);
  2246. // Need to use the name returned by the call as opposed
  2247. // to the name given in the ADsPath
  2248. if (pObjectInfo->ComponentArray[1] && lpUI->usri20_name) {
  2249. FreeADsStr(pObjectInfo->ComponentArray[1]);
  2250. pObjectInfo->ComponentArray[1]
  2251. = AllocADsStr(lpUI->usri20_name);
  2252. }
  2253. if (!pObjectInfo->ComponentArray[1])
  2254. BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
  2255. *pdwParentId = WINNT_COMPUTER_ID;
  2256. }
  2257. else if (hr == HRESULT_FROM_WIN32(NERR_WkstaNotStarted)) {
  2258. //
  2259. // Need to see if the problem was not workstation
  2260. // services in which case we need to still try and
  2261. // locate user if the comptuer name matches.
  2262. //
  2263. if (!GetComputerName(szCompName, &dwSize)) {
  2264. //
  2265. // We could not get the computer name so bail
  2266. //
  2267. BAIL_ON_FAILURE(hr);
  2268. }
  2269. //
  2270. // Test the name before continuing.
  2271. //
  2272. #ifdef WIN95
  2273. if (_wcsicmp(szCompName, pObjectInfo->ComponentArray[0])) {
  2274. #else
  2275. if (CompareStringW(
  2276. LOCALE_SYSTEM_DEFAULT,
  2277. NORM_IGNORECASE,
  2278. szCompName,
  2279. -1,
  2280. pObjectInfo->ComponentArray[0],
  2281. -1
  2282. ) != CSTR_EQUAL ) {
  2283. #endif
  2284. // names do not match
  2285. BAIL_ON_FAILURE(hr);
  2286. }
  2287. //
  2288. // Valid computer name, so we can try and check for user
  2289. //
  2290. MakeUncName(pObjectInfo->ComponentArray[0], lpszUncName);
  2291. nasStatus = NetUserGetInfo(
  2292. lpszUncName,
  2293. pObjectInfo->ComponentArray[1],
  2294. 20,
  2295. (LPBYTE *)&lpUI
  2296. );
  2297. BAIL_ON_FAILURE(hr = HRESULT_FROM_WIN32(nasStatus));
  2298. *pdwParentId = WINNT_COMPUTER_ID;
  2299. }
  2300. }
  2301. BAIL_ON_FAILURE(hr);
  2302. break;
  2303. case 3:
  2304. //
  2305. // user in domain\computer or user in workgroup\computer
  2306. //
  2307. hr = ValidateComputerParent(
  2308. pObjectInfo->ComponentArray[0],
  2309. pObjectInfo->ComponentArray[1],
  2310. Credentials
  2311. );
  2312. BAIL_ON_FAILURE(hr);
  2313. // Again we need to ref the server
  2314. hr = Credentials.RefServer(pObjectInfo->ComponentArray[1]);
  2315. if (SUCCEEDED(hr)) {
  2316. fRefAdded = TRUE;
  2317. }
  2318. MakeUncName(pObjectInfo->ComponentArray[1],
  2319. lpszUncName);
  2320. nasStatus = NetUserGetInfo(lpszUncName,
  2321. pObjectInfo->ComponentArray[2],
  2322. 20,
  2323. (LPBYTE *)&lpUI);
  2324. // DeRef if ref added, no recovery possible on failed deref
  2325. if (fRefAdded) {
  2326. Credentials.DeRefServer();
  2327. fRefAdded = FALSE;
  2328. }
  2329. hr = HRESULT_FROM_WIN32(nasStatus);
  2330. BAIL_ON_FAILURE(hr);
  2331. // Need to use the name returned by the call as opposed
  2332. // to the name given in the ADsPath
  2333. if (pObjectInfo->ComponentArray[2] && lpUI->usri20_name) {
  2334. FreeADsStr(pObjectInfo->ComponentArray[2]);
  2335. pObjectInfo->ComponentArray[2]
  2336. = AllocADsStr(lpUI->usri20_name);
  2337. }
  2338. if (!pObjectInfo->ComponentArray[2])
  2339. BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
  2340. *pdwParentId = WINNT_COMPUTER_ID;
  2341. break;
  2342. default:
  2343. RRETURN(E_ADS_BAD_PATHNAME);
  2344. }
  2345. error:
  2346. if (lpUI) {
  2347. NetApiBufferFree((LPBYTE)lpUI);
  2348. }
  2349. if (lpUI_0) {
  2350. NetApiBufferFree((LPBYTE)lpUI_0);
  2351. }
  2352. RRETURN(hr);
  2353. }
  2354. HRESULT
  2355. ValidateComputerParent(
  2356. LPWSTR pszDomainName,
  2357. LPWSTR pszComputerName,
  2358. CWinNTCredentials& Credentials
  2359. )
  2360. {
  2361. HRESULT hr;
  2362. NET_API_STATUS nasStatus;
  2363. WCHAR szName[MAX_PATH];
  2364. WCHAR szSAMName[MAX_PATH];
  2365. WCHAR szCompName[MAX_PATH];
  2366. DWORD dwSize = MAX_PATH;
  2367. if(pszDomainName && (wcslen(pszDomainName) >= MAX_PATH))
  2368. {
  2369. hr = E_FAIL;
  2370. goto error;
  2371. }
  2372. szSAMName[0] = szName[0] = L'\0';
  2373. if(pszDomainName)
  2374. {
  2375. wcscpy(szName, pszDomainName);
  2376. }
  2377. hr = WinNTGetCachedComputerName(
  2378. pszComputerName,
  2379. szName,
  2380. szSAMName,
  2381. Credentials
  2382. );
  2383. if (hr == HRESULT_FROM_WIN32(NERR_WkstaNotStarted)) {
  2384. //
  2385. // We want to see if the computer being validated is
  2386. // the current host.
  2387. //
  2388. if (!GetComputerName(szCompName, &dwSize)
  2389. #ifdef WIN95
  2390. || (_wcsicmp(szCompName, pszComputerName))
  2391. #else
  2392. || (CompareStringW(
  2393. LOCALE_SYSTEM_DEFAULT,
  2394. NORM_IGNORECASE,
  2395. szCompName,
  2396. -1,
  2397. pszComputerName,
  2398. -1
  2399. ) != CSTR_EQUAL )
  2400. #endif
  2401. )
  2402. BAIL_ON_FAILURE(hr);
  2403. hr = S_OK;
  2404. }
  2405. BAIL_ON_FAILURE(hr);
  2406. if(pszDomainName == NULL){
  2407. //
  2408. // we are dealing with a case where we aren't supplied the
  2409. // computer's parent. Just validate the computer
  2410. //
  2411. hr = S_OK;
  2412. goto error;
  2413. } else {
  2414. #ifdef WIN95
  2415. //
  2416. // No NetpNameCompare for Win9x
  2417. //
  2418. if (!_wcsicmp(pszDomainName, szName)) {
  2419. #else
  2420. if ((CompareStringW(
  2421. LOCALE_SYSTEM_DEFAULT,
  2422. NORM_IGNORECASE,
  2423. pszDomainName,
  2424. -1,
  2425. szName,
  2426. -1
  2427. ) == CSTR_EQUAL )
  2428. || (NetpNameCompare(
  2429. NULL,
  2430. pszDomainName,
  2431. szName,
  2432. NAMETYPE_DOMAIN,
  2433. 0
  2434. ) == 0 )
  2435. ) {
  2436. #endif
  2437. hr = S_OK;
  2438. }else {
  2439. hr = E_ADS_BAD_PATHNAME;
  2440. }
  2441. }
  2442. error:
  2443. RRETURN(hr);
  2444. }
  2445. // Overloaded ValidateComputerParent function.
  2446. // This is used when the case of pszComputerName on the SAM
  2447. // databsae is needed.
  2448. HRESULT
  2449. ValidateComputerParent(
  2450. LPWSTR pszDomainName,
  2451. LPWSTR pszComputerName,
  2452. LPWSTR pszSAMName,
  2453. CWinNTCredentials& Credentials
  2454. )
  2455. {
  2456. HRESULT hr;
  2457. NET_API_STATUS nasStatus;
  2458. WCHAR szName[MAX_PATH];
  2459. WCHAR szSAMName[MAX_PATH];
  2460. if(pszDomainName && wcslen(pszDomainName) >= MAX_PATH)
  2461. {
  2462. hr = E_FAIL;
  2463. goto error;
  2464. }
  2465. szSAMName[0] = szName[0] = L'\0';
  2466. if(pszDomainName)
  2467. {
  2468. wcscpy(szName, pszDomainName);
  2469. }
  2470. hr = WinNTGetCachedComputerName(
  2471. pszComputerName,
  2472. szName,
  2473. szSAMName,
  2474. Credentials
  2475. );
  2476. BAIL_ON_FAILURE(hr);
  2477. if (szSAMName[0] != L'\0') {
  2478. wcscpy(pszSAMName, szSAMName);
  2479. }
  2480. if(pszDomainName == NULL){
  2481. //
  2482. // we are dealing with a case where we aren't supplied the
  2483. // computer's parent. Just validate the computer
  2484. //
  2485. hr = S_OK;
  2486. goto error;
  2487. } else {
  2488. #ifdef WIN95
  2489. //
  2490. // No NetpNameCompare for Win9x
  2491. //
  2492. if (!_wcsicmp(pszDomainName, szName)) {
  2493. #else
  2494. if ((CompareStringW(
  2495. LOCALE_SYSTEM_DEFAULT,
  2496. NORM_IGNORECASE,
  2497. pszDomainName,
  2498. -1,
  2499. szName,
  2500. -1
  2501. ) == CSTR_EQUAL )
  2502. || (NetpNameCompare(
  2503. NULL,
  2504. pszDomainName,
  2505. szName,
  2506. NAMETYPE_DOMAIN,
  2507. 0
  2508. ) == 0 )
  2509. ) {
  2510. #endif
  2511. hr = S_OK;
  2512. }else {
  2513. hr = E_FAIL;
  2514. }
  2515. }
  2516. error:
  2517. RRETURN(hr);
  2518. }
  2519. HRESULT
  2520. ValidateGroupObject(
  2521. POBJECTINFO pObjectInfo,
  2522. PULONG puGroupType,
  2523. PDWORD pdwParentId,
  2524. CWinNTCredentials& Credentials
  2525. )
  2526. {
  2527. WCHAR szHostServerName[MAX_PATH];
  2528. LPGROUP_INFO_0 lpGI = NULL;
  2529. HRESULT hr;
  2530. WCHAR lpszUncName[MAX_PATH];
  2531. NET_API_STATUS nasStatus;
  2532. ULONG uGroupType = 0L;
  2533. WCHAR szSAMName[MAX_PATH];
  2534. szSAMName[0] = L'\0';
  2535. switch (pObjectInfo->NumComponents) {
  2536. case 2:
  2537. //
  2538. // if 2 components then either it is a group in computer
  2539. // or group in domain.
  2540. //
  2541. hr = WinNTGetCachedDCName(
  2542. pObjectInfo->ComponentArray[0],
  2543. szHostServerName,
  2544. Credentials.GetFlags()
  2545. );
  2546. if(SUCCEEDED(hr)){
  2547. //
  2548. // must be a group in a domain
  2549. //
  2550. *pdwParentId = WINNT_DOMAIN_ID;
  2551. hr = ValidateGlobalGroupObject(
  2552. szHostServerName,
  2553. &(pObjectInfo->ComponentArray[1]),
  2554. Credentials
  2555. );
  2556. if (FAILED(hr)) {
  2557. hr = ValidateLocalGroupObject(
  2558. szHostServerName,
  2559. &(pObjectInfo->ComponentArray[1]),
  2560. Credentials
  2561. );
  2562. if(SUCCEEDED(hr)){
  2563. uGroupType = WINNT_GROUP_LOCAL;
  2564. }
  2565. }else{
  2566. uGroupType = WINNT_GROUP_GLOBAL;
  2567. }
  2568. }
  2569. if(FAILED(hr)){
  2570. //
  2571. // potentially a group in a computer
  2572. //
  2573. hr = ValidateComputerParent(NULL,
  2574. pObjectInfo->ComponentArray[0],
  2575. Credentials);
  2576. BAIL_ON_FAILURE(hr);
  2577. //
  2578. // group in a computer
  2579. //
  2580. *pdwParentId = WINNT_COMPUTER_ID;
  2581. MakeUncName(pObjectInfo->ComponentArray[0],
  2582. lpszUncName);
  2583. hr = ValidateGlobalGroupObject(
  2584. lpszUncName,
  2585. &(pObjectInfo->ComponentArray[1]),
  2586. Credentials
  2587. );
  2588. if (FAILED(hr)) {
  2589. hr = ValidateLocalGroupObject(
  2590. lpszUncName,
  2591. &(pObjectInfo->ComponentArray[1]),
  2592. Credentials
  2593. );
  2594. BAIL_ON_FAILURE(hr);
  2595. uGroupType = WINNT_GROUP_LOCAL;
  2596. }else{
  2597. uGroupType = WINNT_GROUP_GLOBAL;
  2598. }
  2599. }
  2600. break;
  2601. case 3:
  2602. //
  2603. // if there are 3 components then we must have parentid
  2604. // WINNT_COMPUTER_ID
  2605. //
  2606. *pdwParentId = WINNT_COMPUTER_ID;
  2607. hr = ValidateComputerParent(pObjectInfo->ComponentArray[0],
  2608. pObjectInfo->ComponentArray[1],
  2609. Credentials);
  2610. BAIL_ON_FAILURE(hr);
  2611. MakeUncName(
  2612. pObjectInfo->ComponentArray[1],
  2613. lpszUncName
  2614. );
  2615. hr = ValidateGlobalGroupObject(
  2616. lpszUncName,
  2617. &(pObjectInfo->ComponentArray[2]),
  2618. Credentials
  2619. );
  2620. if (FAILED(hr)) {
  2621. hr = ValidateLocalGroupObject(
  2622. lpszUncName,
  2623. &(pObjectInfo->ComponentArray[2]),
  2624. Credentials
  2625. );
  2626. BAIL_ON_FAILURE(hr);
  2627. uGroupType = WINNT_GROUP_LOCAL;
  2628. }else{
  2629. uGroupType = WINNT_GROUP_GLOBAL;
  2630. }
  2631. break;
  2632. default:
  2633. RRETURN(E_ADS_BAD_PATHNAME);
  2634. }
  2635. error:
  2636. if (lpGI) {
  2637. NetApiBufferFree((LPBYTE)lpGI);
  2638. }
  2639. *puGroupType = uGroupType;
  2640. RRETURN(hr);
  2641. }
  2642. HRESULT
  2643. ValidatePrinterObject(
  2644. POBJECTINFO pObjectInfo,
  2645. CWinNTCredentials& Credentials
  2646. )
  2647. {
  2648. LPTSTR szDomainName = NULL;
  2649. LPTSTR szServerName = NULL;
  2650. LPTSTR szPrinterName = NULL;
  2651. WCHAR szPrintObjectName[MAX_PATH];
  2652. HRESULT hr = E_ADS_UNKNOWN_OBJECT;
  2653. BOOL fStatus = FALSE;
  2654. HANDLE hPrinter = NULL;
  2655. PRINTER_DEFAULTS PrinterDefaults = {0, 0, PRINTER_ACCESS_USE};
  2656. BOOLEAN fRefAdded = FALSE;
  2657. if (!(pObjectInfo->NumComponents == 3 ||pObjectInfo->NumComponents == 2)){
  2658. RRETURN(E_ADS_BAD_PATHNAME);
  2659. }
  2660. if(pObjectInfo->NumComponents == 3){
  2661. //
  2662. // printer in domain\computer or workgroup\computer
  2663. //
  2664. szDomainName = pObjectInfo->ComponentArray[0];
  2665. szServerName = pObjectInfo->ComponentArray[1];
  2666. szPrinterName = pObjectInfo->ComponentArray[2];
  2667. hr = ValidateComputerParent(szDomainName,
  2668. szServerName,
  2669. Credentials);
  2670. BAIL_IF_ERROR(hr);
  2671. } else if ( pObjectInfo-> NumComponents == 2 ){
  2672. szServerName = pObjectInfo->ComponentArray[0];
  2673. szPrinterName = pObjectInfo->ComponentArray[1];
  2674. }
  2675. MakeUncName(szServerName, szPrintObjectName);
  2676. wcscat(szPrintObjectName, TEXT("\\"));
  2677. wcscat(szPrintObjectName, szPrinterName);
  2678. //
  2679. // validate the printer in computer now
  2680. //
  2681. hr = Credentials.RefServer(szServerName);
  2682. if (SUCCEEDED(hr)) {
  2683. fRefAdded = TRUE;
  2684. }
  2685. fStatus = OpenPrinter(szPrintObjectName,
  2686. &hPrinter,
  2687. &PrinterDefaults);
  2688. if(!fStatus){
  2689. hr = HRESULT_FROM_WIN32(GetLastError());
  2690. } else {
  2691. hr = S_OK;
  2692. }
  2693. cleanup:
  2694. if(hPrinter){
  2695. ClosePrinter(hPrinter);
  2696. }
  2697. if (fRefAdded) {
  2698. Credentials.DeRefServer();
  2699. fRefAdded = FALSE;
  2700. }
  2701. RRETURN(hr);
  2702. }
  2703. HRESULT
  2704. ValidateServiceObject(
  2705. POBJECTINFO pObjectInfo,
  2706. CWinNTCredentials& Credentials
  2707. )
  2708. {
  2709. LPTSTR szDomainName = NULL;
  2710. LPTSTR szServerName = NULL;
  2711. LPTSTR szServiceName = NULL;
  2712. SC_HANDLE schSCMHandle=NULL;
  2713. SC_HANDLE schServiceHandle=NULL;
  2714. HRESULT hr = S_OK;
  2715. BOOLEAN fRefAdded = FALSE;
  2716. if(!(pObjectInfo->NumComponents == 3 ||
  2717. pObjectInfo->NumComponents == 2))
  2718. {
  2719. RRETURN(E_ADS_BAD_PATHNAME);
  2720. }
  2721. if(pObjectInfo->NumComponents == 3){
  2722. szDomainName = pObjectInfo->ComponentArray[0];
  2723. szServerName = pObjectInfo->ComponentArray[1];
  2724. szServiceName = pObjectInfo->ComponentArray[2];
  2725. //
  2726. // First check to see if the computer is in the right domain
  2727. //
  2728. hr = ValidateComputerParent(
  2729. szDomainName,
  2730. szServerName,
  2731. Credentials
  2732. );
  2733. BAIL_ON_FAILURE(hr);
  2734. } else if (pObjectInfo->NumComponents == 2){
  2735. szServerName = pObjectInfo->ComponentArray[0];
  2736. szServiceName = pObjectInfo->ComponentArray[1];
  2737. }
  2738. //
  2739. // check to see if the service is valid by opening the active services
  2740. // database on the server
  2741. //
  2742. hr = Credentials.RefServer(szServerName);
  2743. if (SUCCEEDED(hr)) {
  2744. fRefAdded = TRUE;
  2745. }
  2746. //
  2747. // Open the Service Control Manager.
  2748. //
  2749. schSCMHandle = OpenSCManager(szServerName,
  2750. NULL,
  2751. GENERIC_READ);
  2752. if (schSCMHandle == NULL) {
  2753. hr = HRESULT_FROM_WIN32(GetLastError());
  2754. goto error;
  2755. }
  2756. //
  2757. // Need to ref the server before opening the service
  2758. //
  2759. //
  2760. // try to open the service
  2761. //
  2762. schServiceHandle = OpenService(schSCMHandle,
  2763. szServiceName,
  2764. GENERIC_READ);
  2765. if(schServiceHandle == NULL) {
  2766. CloseServiceHandle(schSCMHandle);
  2767. schSCMHandle = NULL;
  2768. hr = HRESULT_FROM_WIN32(GetLastError());
  2769. goto error;
  2770. }
  2771. CloseServiceHandle(schServiceHandle);
  2772. CloseServiceHandle(schSCMHandle);
  2773. error:
  2774. if (fRefAdded) {
  2775. Credentials.DeRefServer();
  2776. fRefAdded = FALSE;
  2777. }
  2778. RRETURN(hr);
  2779. }
  2780. HRESULT GetPrinterFromPath(LPTSTR *pszPrinter, LPWSTR szPathName)
  2781. {
  2782. //
  2783. // If passed an empty string, it returns an empty string
  2784. //
  2785. LPTSTR szRetval;
  2786. *pszPrinter = NULL;
  2787. szRetval = szPathName;
  2788. ADsAssert(szPathName);
  2789. while(!(*szRetval==L'\0' || *szRetval==L'\\')){
  2790. szRetval++;
  2791. }
  2792. if(*szRetval != L'\\'){
  2793. RRETURN(E_FAIL);
  2794. }
  2795. szRetval++;
  2796. *pszPrinter = szRetval;
  2797. RRETURN(S_OK);
  2798. }
  2799. HRESULT
  2800. ValidateComputerObject(
  2801. POBJECTINFO pObjectInfo,
  2802. CWinNTCredentials& Credentials)
  2803. {
  2804. HRESULT hr;
  2805. WCHAR szSAMName[MAX_PATH];
  2806. szSAMName[0] = L'\0';
  2807. if(!(pObjectInfo->NumComponents == 2 ||
  2808. pObjectInfo->NumComponents == 1)){
  2809. RRETURN(E_ADS_UNKNOWN_OBJECT);
  2810. }
  2811. if(pObjectInfo->NumComponents == 2){
  2812. hr = ValidateComputerParent(
  2813. pObjectInfo->ComponentArray[0],
  2814. pObjectInfo->ComponentArray[1],
  2815. szSAMName,
  2816. Credentials
  2817. );
  2818. BAIL_ON_FAILURE(hr);
  2819. if (szSAMName[0] != L'\0') {
  2820. FreeADsStr(pObjectInfo->ComponentArray[1]);
  2821. pObjectInfo->ComponentArray[1] = AllocADsStr(szSAMName);
  2822. if (!pObjectInfo->ComponentArray[1]) {
  2823. BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
  2824. }
  2825. }
  2826. } else {
  2827. hr = ValidateComputerParent(
  2828. NULL,
  2829. pObjectInfo->ComponentArray[0],
  2830. szSAMName,
  2831. Credentials
  2832. );
  2833. BAIL_ON_FAILURE(hr);
  2834. if (szSAMName[0] != L'\0') {
  2835. FreeADsStr(pObjectInfo->ComponentArray[0]);
  2836. pObjectInfo->ComponentArray[0] = AllocADsStr(szSAMName);
  2837. if (!pObjectInfo->ComponentArray[0]) {
  2838. BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
  2839. }
  2840. }
  2841. }
  2842. error:
  2843. RRETURN(hr);
  2844. }
  2845. HRESULT
  2846. ValidateFileServiceObject(
  2847. POBJECTINFO pObjectInfo,
  2848. CWinNTCredentials& Credentials
  2849. )
  2850. {
  2851. HRESULT hr = S_OK;
  2852. //
  2853. // check to see if it is a valid service
  2854. //
  2855. if(!(pObjectInfo->NumComponents == 3 ||
  2856. pObjectInfo->NumComponents == 2))
  2857. {
  2858. RRETURN(E_ADS_BAD_PATHNAME);
  2859. }
  2860. hr = ValidateServiceObject(pObjectInfo, Credentials);
  2861. if(FAILED(hr))
  2862. RRETURN(hr);
  2863. //
  2864. // check to see if it is the LanmanServer or FPNW service
  2865. //
  2866. if (pObjectInfo->NumComponents ==3){
  2867. if(!(_wcsicmp(pObjectInfo->ComponentArray[2],
  2868. TEXT("LanmanServer"))== 0
  2869. || _wcsicmp(pObjectInfo->ComponentArray[2],TEXT("FPNW"))==0)){
  2870. RRETURN(E_ADS_BAD_PATHNAME);
  2871. }
  2872. }else if(pObjectInfo->NumComponents == 2) {
  2873. if(!(_wcsicmp(pObjectInfo->ComponentArray[1],
  2874. TEXT("LanmanServer"))== 0
  2875. || _wcsicmp(pObjectInfo->ComponentArray[1],TEXT("FPNW"))==0)){
  2876. RRETURN(E_ADS_BAD_PATHNAME);
  2877. }
  2878. }
  2879. RRETURN(hr);
  2880. }
  2881. HRESULT
  2882. ValidateFileShareObject(
  2883. POBJECTINFO pObjectInfo,
  2884. CWinNTCredentials& Credentials
  2885. )
  2886. {
  2887. NET_API_STATUS nasStatus;
  2888. LPSHARE_INFO_1 lpShareInfo1 = NULL;
  2889. PNWVOLUMEINFO pVolumeInfo = NULL;
  2890. LPTSTR pszDomainName = NULL;
  2891. LPTSTR pszServerName = NULL;
  2892. LPTSTR pszShareName = NULL;
  2893. LPTSTR pszServerType = NULL;
  2894. HRESULT hr = S_OK;
  2895. DWORD dwSharePos = 3;
  2896. BOOL fRefAdded = FALSE;
  2897. //
  2898. // check to see if it is a valid file share
  2899. //
  2900. if (pObjectInfo->NumComponents == 4 ){
  2901. pszDomainName = pObjectInfo->ComponentArray[0];
  2902. pszServerName = pObjectInfo->ComponentArray[1];
  2903. pszServerType = pObjectInfo->ComponentArray[2];
  2904. pszShareName = pObjectInfo->ComponentArray[3];
  2905. dwSharePos = 3;
  2906. hr = ValidateComputerParent(pszDomainName,
  2907. pszServerName,
  2908. Credentials);
  2909. BAIL_ON_FAILURE(hr);
  2910. }
  2911. else if (pObjectInfo->NumComponents == 3 ){
  2912. pszServerName = pObjectInfo->ComponentArray[0];
  2913. pszServerType = pObjectInfo->ComponentArray[1];
  2914. pszShareName = pObjectInfo->ComponentArray[2];
  2915. dwSharePos = 2;
  2916. }
  2917. else {
  2918. hr = E_ADS_UNKNOWN_OBJECT;
  2919. goto error;
  2920. }
  2921. if(_tcsicmp(pszServerType,TEXT("LanmanServer")) == 0){
  2922. // Need to ref this server before we do the NetShareGetInfo
  2923. // so that we can authenticate against the server.
  2924. hr = Credentials.RefServer(pszServerName);
  2925. if (SUCCEEDED(hr)) {
  2926. fRefAdded = TRUE;
  2927. }
  2928. nasStatus = NetShareGetInfo(pszServerName,
  2929. pszShareName,
  2930. 1,
  2931. (LPBYTE*)&lpShareInfo1);
  2932. // DeRef if ref added, no recovery possible on failed deref
  2933. if (fRefAdded) {
  2934. hr = Credentials.DeRefServer();
  2935. fRefAdded = FALSE;
  2936. }
  2937. if(nasStatus != NERR_Success){
  2938. hr = HRESULT_FROM_WIN32(nasStatus);
  2939. goto error;
  2940. }
  2941. else {
  2942. // Need to use the name returned by the call as opposed
  2943. // to the name given in the ADsPath
  2944. if (pObjectInfo->ComponentArray[dwSharePos]
  2945. && lpShareInfo1->shi1_netname) {
  2946. FreeADsStr(pObjectInfo->ComponentArray[dwSharePos]);
  2947. pObjectInfo->ComponentArray[dwSharePos]
  2948. = AllocADsStr(lpShareInfo1->shi1_netname);
  2949. }
  2950. if (!pObjectInfo->ComponentArray[dwSharePos])
  2951. BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
  2952. hr = S_OK;
  2953. goto error;
  2954. }
  2955. }
  2956. else if(_tcsicmp(pszServerType,TEXT("FPNW")) == 0){
  2957. hr = Credentials.RefServer(pszServerName);
  2958. if (SUCCEEDED(hr)) {
  2959. fRefAdded = TRUE;
  2960. }
  2961. nasStatus = ADsNwVolumeGetInfo(pszServerName,
  2962. pszShareName,
  2963. 1,
  2964. &pVolumeInfo);
  2965. // need to deref, nothing we can do if deref fails
  2966. if (fRefAdded) {
  2967. hr = Credentials.DeRefServer();
  2968. fRefAdded = FALSE;
  2969. }
  2970. if(nasStatus != NERR_Success){
  2971. hr = HRESULT_FROM_WIN32(nasStatus);
  2972. goto error;
  2973. }
  2974. else{
  2975. // Need to use the name returned by the call as opposed
  2976. // to the name given in the ADsPath
  2977. if (pObjectInfo->ComponentArray[dwSharePos]
  2978. && pVolumeInfo->lpPath) {
  2979. FreeADsStr(pObjectInfo->ComponentArray[dwSharePos]);
  2980. pObjectInfo->ComponentArray[dwSharePos]
  2981. = AllocADsStr(pVolumeInfo->lpPath);
  2982. }
  2983. if (!pObjectInfo->ComponentArray[dwSharePos])
  2984. BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
  2985. hr = S_OK;
  2986. goto error;
  2987. }
  2988. } else {
  2989. hr = E_ADS_UNKNOWN_OBJECT ;
  2990. }
  2991. error:
  2992. if(pVolumeInfo){
  2993. ADsNwApiBufferFree(pVolumeInfo);
  2994. }
  2995. if(lpShareInfo1){
  2996. NetApiBufferFree(lpShareInfo1);
  2997. }
  2998. RRETURN(hr);
  2999. }
  3000. HRESULT
  3001. ValidateNamespaceObject(
  3002. POBJECTINFO pObjectInfo
  3003. )
  3004. {
  3005. if (!_wcsicmp(pObjectInfo->ProviderName, szProviderName)) {
  3006. RRETURN(S_OK);
  3007. }
  3008. RRETURN(E_FAIL);
  3009. }
  3010. HRESULT
  3011. ValidateLocalGroupObject(
  3012. LPWSTR szServerName,
  3013. LPWSTR *pszGroupName,
  3014. CWinNTCredentials& Credentials
  3015. )
  3016. {
  3017. NET_API_STATUS nasStatus;
  3018. LPLOCALGROUP_INFO_1 lpGI = NULL;
  3019. HRESULT hr = S_OK;
  3020. BOOL fRefAdded = FALSE;
  3021. // At this point the host server name has a \\ prepended
  3022. // so we need to get rid of it.
  3023. hr = Credentials.RefServer(szServerName+2);
  3024. if (SUCCEEDED(hr)) {
  3025. fRefAdded = TRUE;
  3026. }
  3027. nasStatus = NetLocalGroupGetInfo(
  3028. szServerName,
  3029. *pszGroupName,
  3030. 1,
  3031. (LPBYTE*)(&lpGI)
  3032. );
  3033. //
  3034. // if a ref has been added we need to delete if before
  3035. // checking the error status.
  3036. //
  3037. if (fRefAdded) {
  3038. hr = Credentials.DeRefServer();
  3039. // even if we fail, we have no recovery path
  3040. fRefAdded = FALSE;
  3041. }
  3042. hr = HRESULT_FROM_WIN32(nasStatus);
  3043. BAIL_ON_FAILURE(hr);
  3044. // Need to use the name returned by the call as opposed
  3045. // to the name given in the ADsPath
  3046. if ((*pszGroupName) && lpGI->lgrpi1_name) {
  3047. FreeADsStr(*pszGroupName);
  3048. *pszGroupName = AllocADsStr(lpGI->lgrpi1_name);
  3049. }
  3050. if (!(*pszGroupName))
  3051. BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
  3052. error:
  3053. if (lpGI) {
  3054. NetApiBufferFree(lpGI);
  3055. }
  3056. RRETURN(hr);
  3057. }
  3058. HRESULT
  3059. ValidateGlobalGroupObject(
  3060. LPWSTR szServerName,
  3061. LPWSTR *pszGroupName,
  3062. CWinNTCredentials& Credentials
  3063. )
  3064. {
  3065. NET_API_STATUS nasStatus;
  3066. LPGROUP_INFO_1 lpGI = NULL;
  3067. HRESULT hr = S_OK;
  3068. BOOL fRefAdded = FALSE;
  3069. // At this point the host server name has a \\ prepended
  3070. // so we need to get rid of it.
  3071. hr = Credentials.RefServer(szServerName+2);
  3072. if (SUCCEEDED(hr)) {
  3073. fRefAdded = TRUE;
  3074. }
  3075. nasStatus = NetGroupGetInfo(
  3076. szServerName,
  3077. *pszGroupName,
  3078. 1,
  3079. (LPBYTE*)(&lpGI)
  3080. );
  3081. //
  3082. // if a ref has been added we need to delete if before
  3083. // checking the error status.
  3084. //
  3085. if (fRefAdded) {
  3086. hr = Credentials.DeRefServer();
  3087. // even if we fail, we have no recovery path
  3088. fRefAdded = FALSE;
  3089. }
  3090. hr = HRESULT_FROM_WIN32(nasStatus);
  3091. BAIL_ON_FAILURE(hr);
  3092. // Need to use the name returned by the call as opposed
  3093. // to the name given in the ADsPath
  3094. if ((*pszGroupName) && lpGI->grpi1_name) {
  3095. FreeADsStr(*pszGroupName);
  3096. *pszGroupName = AllocADsStr(lpGI->grpi1_name);
  3097. }
  3098. if (!(*pszGroupName))
  3099. BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
  3100. error:
  3101. if (lpGI) {
  3102. NetApiBufferFree(lpGI);
  3103. }
  3104. RRETURN(hr);
  3105. }
  3106. HRESULT
  3107. GetComputerParent(
  3108. LPTSTR pszComputerName,
  3109. LPTSTR *ppszComputerParentName,
  3110. CWinNTCredentials& Credentials
  3111. )
  3112. {
  3113. //
  3114. // This function returns the computer parent irrespective of whether
  3115. // the computer belongs to a domain or to a workgroup
  3116. //
  3117. HRESULT hr = S_OK;
  3118. LPTSTR pszComputerParentName = NULL;
  3119. WCHAR szDomainName[MAX_PATH];
  3120. WCHAR szSAMName[MAX_PATH];
  3121. szSAMName[0] = szDomainName[0] = L'\0';
  3122. hr = WinNTGetCachedComputerName(pszComputerName,
  3123. szDomainName,
  3124. szSAMName,
  3125. Credentials );
  3126. BAIL_ON_FAILURE(hr);
  3127. pszComputerParentName = AllocADsStr(szDomainName);
  3128. if(!pszComputerParentName){
  3129. hr = E_OUTOFMEMORY;
  3130. }
  3131. *ppszComputerParentName = pszComputerParentName;
  3132. error:
  3133. RRETURN(hr);
  3134. }
  3135. HRESULT
  3136. ConstructFullObjectInfo(
  3137. POBJECTINFO pObjectInfo,
  3138. POBJECTINFO *ppFullObjectInfo,
  3139. CWinNTCredentials& Credentials
  3140. )
  3141. {
  3142. //
  3143. // used in the case where the domain name is not specified.
  3144. // Here the assumption is that an objectinfo structure with
  3145. // domain name not filled in is passed down. We create a new
  3146. // object info structure with the domain/workgroup name filled
  3147. // in
  3148. HRESULT hr = S_OK;
  3149. POBJECTINFO pTempObjectInfo = NULL;
  3150. DWORD i;
  3151. LPWSTR pszComputerParent = NULL;
  3152. pTempObjectInfo = (POBJECTINFO)AllocADsMem(sizeof(OBJECTINFO));
  3153. if (!pTempObjectInfo) {
  3154. RRETURN(hr = E_OUTOFMEMORY);
  3155. }
  3156. memset(pTempObjectInfo, 0, sizeof(OBJECTINFO));
  3157. if(!pObjectInfo){
  3158. RRETURN(E_OUTOFMEMORY);
  3159. }
  3160. pTempObjectInfo->ProviderName = AllocADsStr(pObjectInfo->ProviderName);
  3161. if(!pTempObjectInfo->ProviderName){
  3162. hr = E_OUTOFMEMORY;
  3163. goto error;
  3164. }
  3165. pTempObjectInfo->ObjectType = pObjectInfo->ObjectType;
  3166. pTempObjectInfo->NumComponents = pObjectInfo->NumComponents +1;
  3167. for(i=0; i<MAXCOMPONENTS-1; i++){
  3168. if(pObjectInfo->ComponentArray[i]) {
  3169. pTempObjectInfo->ComponentArray[i+1] =
  3170. AllocADsStr(pObjectInfo->ComponentArray[i]);
  3171. if(!pTempObjectInfo->ComponentArray[i+1]){
  3172. hr = E_OUTOFMEMORY;
  3173. goto error;
  3174. }
  3175. }
  3176. if(pObjectInfo->DisplayComponentArray[i]) {
  3177. pTempObjectInfo->DisplayComponentArray[i+1] =
  3178. AllocADsStr(pObjectInfo->DisplayComponentArray[i]);
  3179. if(!pTempObjectInfo->DisplayComponentArray[i+1]){
  3180. hr = E_OUTOFMEMORY;
  3181. goto error;
  3182. }
  3183. }
  3184. }
  3185. hr = GetComputerParent(pObjectInfo->ComponentArray[0],
  3186. &(pTempObjectInfo->ComponentArray[0]),
  3187. Credentials );
  3188. BAIL_ON_FAILURE(hr);
  3189. hr = GetDisplayName(pTempObjectInfo->ComponentArray[0],
  3190. &(pTempObjectInfo->DisplayComponentArray[0]) );
  3191. *ppFullObjectInfo = pTempObjectInfo ;
  3192. RRETURN(S_OK);
  3193. error:
  3194. FreeObjectInfo( pTempObjectInfo );
  3195. *ppFullObjectInfo = NULL;
  3196. RRETURN(hr);
  3197. }
  3198. //+---------------------------------------------------------------------------
  3199. // Function: GetGroupObject
  3200. //
  3201. // Synopsis:
  3202. //
  3203. // Arguments:
  3204. //
  3205. // Returns:
  3206. //
  3207. // Modifies:
  3208. //
  3209. // History: 11-3-95 krishnag Created.
  3210. //
  3211. //----------------------------------------------------------------------------
  3212. HRESULT
  3213. GetLocalGroupObject(
  3214. POBJECTINFO pObjectInfo,
  3215. LPVOID * ppObject,
  3216. CWinNTCredentials& Credentials
  3217. )
  3218. {
  3219. LPUNKNOWN pUnknown = NULL;
  3220. WCHAR ADsParent[MAX_ADS_PATH];
  3221. HRESULT hr = S_OK;
  3222. LPWSTR szServerName = NULL;
  3223. LPWSTR szDomainName = NULL;
  3224. LPWSTR szGroupName = NULL;
  3225. DWORD dwParentId = 0;
  3226. ULONG uGroupType = 0;
  3227. POBJECTINFO pGroupObjectInfo = NULL;
  3228. hr = ValidateGroupObject(
  3229. pObjectInfo,
  3230. &uGroupType,
  3231. &dwParentId,
  3232. Credentials
  3233. );
  3234. BAIL_ON_FAILURE(hr);
  3235. if (uGroupType != WINNT_GROUP_LOCAL) {
  3236. hr = E_ADS_BAD_PATHNAME;
  3237. BAIL_ON_FAILURE(hr);
  3238. }
  3239. switch (pObjectInfo->NumComponents) {
  3240. case 2:
  3241. //
  3242. // could be group in computer or group in domain
  3243. //
  3244. if(dwParentId == WINNT_DOMAIN_ID){
  3245. szDomainName = pObjectInfo->ComponentArray[0];
  3246. szGroupName = pObjectInfo->ComponentArray[1];
  3247. szServerName = NULL;
  3248. hr = BuildParent(pObjectInfo, ADsParent);
  3249. BAIL_ON_FAILURE(hr);
  3250. } else {
  3251. //
  3252. // group in a computer
  3253. //
  3254. hr = ConstructFullObjectInfo(pObjectInfo,
  3255. &pGroupObjectInfo,
  3256. Credentials );
  3257. if (hr == HRESULT_FROM_WIN32(NERR_WkstaNotStarted)) {
  3258. //
  3259. // Case when there are no workstation services.
  3260. //
  3261. hr = BuildParent(pObjectInfo, ADsParent);
  3262. BAIL_ON_FAILURE(hr);
  3263. szDomainName = NULL;
  3264. szServerName = pObjectInfo->ComponentArray[0];
  3265. szGroupName = pObjectInfo->ComponentArray[1];
  3266. } else {
  3267. BAIL_ON_FAILURE(hr);
  3268. hr = BuildParent(pGroupObjectInfo, ADsParent);
  3269. BAIL_ON_FAILURE(hr);
  3270. szDomainName = pGroupObjectInfo->ComponentArray[0];
  3271. szServerName = pGroupObjectInfo->ComponentArray[1];
  3272. szGroupName = pGroupObjectInfo->ComponentArray[2];
  3273. }
  3274. }
  3275. break;
  3276. case 3:
  3277. hr = BuildParent(pObjectInfo, ADsParent);
  3278. BAIL_ON_FAILURE(hr);
  3279. szDomainName = pObjectInfo->ComponentArray[0];
  3280. szServerName = pObjectInfo->ComponentArray[1];
  3281. szGroupName = pObjectInfo->ComponentArray[2];
  3282. break;
  3283. }
  3284. hr = CWinNTGroup::CreateGroup(ADsParent,
  3285. dwParentId,
  3286. szDomainName,
  3287. szServerName,
  3288. szGroupName,
  3289. uGroupType,
  3290. ADS_OBJECT_BOUND,
  3291. IID_IUnknown,
  3292. Credentials,
  3293. (void **)&pUnknown
  3294. );
  3295. BAIL_ON_FAILURE(hr);
  3296. *ppObject = pUnknown;
  3297. if(pGroupObjectInfo){
  3298. FreeObjectInfo(pGroupObjectInfo);
  3299. }
  3300. RRETURN(hr);
  3301. error:
  3302. if (pUnknown) {
  3303. pUnknown->Release();
  3304. }
  3305. if(pGroupObjectInfo){
  3306. FreeObjectInfo(pGroupObjectInfo);
  3307. }
  3308. *ppObject = NULL;
  3309. RRETURN(hr);
  3310. }
  3311. //+---------------------------------------------------------------------------
  3312. // Function: GetGroupObject
  3313. //
  3314. // Synopsis:
  3315. //
  3316. // Arguments:
  3317. //
  3318. // Returns:
  3319. //
  3320. // Modifies:
  3321. //
  3322. // History: 11-3-95 krishnag Created.
  3323. //
  3324. //----------------------------------------------------------------------------
  3325. HRESULT
  3326. GetGlobalGroupObject(
  3327. POBJECTINFO pObjectInfo,
  3328. LPVOID * ppObject,
  3329. CWinNTCredentials& Credentials
  3330. )
  3331. {
  3332. LPUNKNOWN pUnknown = NULL;
  3333. WCHAR ADsParent[MAX_ADS_PATH];
  3334. HRESULT hr = S_OK;
  3335. LPWSTR szServerName = NULL;
  3336. LPWSTR szDomainName = NULL;
  3337. LPWSTR szGroupName = NULL;
  3338. DWORD dwParentId = 0;
  3339. ULONG uGroupType = 0;
  3340. POBJECTINFO pGroupObjectInfo = NULL;
  3341. hr = ValidateGroupObject(
  3342. pObjectInfo,
  3343. &uGroupType,
  3344. &dwParentId,
  3345. Credentials
  3346. );
  3347. BAIL_ON_FAILURE(hr);
  3348. if (uGroupType != WINNT_GROUP_GLOBAL) {
  3349. hr = E_ADS_BAD_PATHNAME;
  3350. BAIL_ON_FAILURE(hr);
  3351. }
  3352. switch (pObjectInfo->NumComponents) {
  3353. case 2:
  3354. //
  3355. // could be group in computer or group in domain
  3356. //
  3357. if(dwParentId == WINNT_DOMAIN_ID){
  3358. szDomainName = pObjectInfo->ComponentArray[0];
  3359. szGroupName = pObjectInfo->ComponentArray[1];
  3360. szServerName = NULL;
  3361. hr = BuildParent(pObjectInfo, ADsParent);
  3362. BAIL_ON_FAILURE(hr);
  3363. } else {
  3364. //
  3365. // group in a computer
  3366. //
  3367. hr = ConstructFullObjectInfo(pObjectInfo,
  3368. &pGroupObjectInfo,
  3369. Credentials );
  3370. BAIL_ON_FAILURE(hr);
  3371. hr = BuildParent(pGroupObjectInfo, ADsParent);
  3372. BAIL_ON_FAILURE(hr);
  3373. szDomainName = pGroupObjectInfo->ComponentArray[0];
  3374. szServerName = pGroupObjectInfo->ComponentArray[1];
  3375. szGroupName = pGroupObjectInfo->ComponentArray[2];
  3376. }
  3377. break;
  3378. case 3:
  3379. hr = BuildParent(pObjectInfo, ADsParent);
  3380. BAIL_ON_FAILURE(hr);
  3381. szDomainName = pObjectInfo->ComponentArray[0];
  3382. szServerName = pObjectInfo->ComponentArray[1];
  3383. szGroupName = pObjectInfo->ComponentArray[2];
  3384. break;
  3385. }
  3386. hr = CWinNTGroup::CreateGroup(ADsParent,
  3387. dwParentId,
  3388. szDomainName,
  3389. szServerName,
  3390. szGroupName,
  3391. uGroupType,
  3392. ADS_OBJECT_BOUND,
  3393. IID_IUnknown,
  3394. Credentials,
  3395. (void **)&pUnknown
  3396. );
  3397. BAIL_ON_FAILURE(hr);
  3398. *ppObject = pUnknown;
  3399. if(pGroupObjectInfo){
  3400. FreeObjectInfo(pGroupObjectInfo);
  3401. }
  3402. RRETURN(hr);
  3403. error:
  3404. if (pUnknown) {
  3405. pUnknown->Release();
  3406. }
  3407. if(pGroupObjectInfo){
  3408. FreeObjectInfo(pGroupObjectInfo);
  3409. }
  3410. *ppObject = NULL;
  3411. RRETURN(hr);
  3412. }