Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

589 lines
13 KiB

  1. /*
  2. File: dsrights.c
  3. Implements the mechanisms needed to grant ras servers the
  4. rights in the DS that they need to operate.
  5. Paul Mayfield, 4/13/98
  6. */
  7. #include "dsrights.h"
  8. #include <mprapip.h>
  9. #include <rtutils.h>
  10. //
  11. // The character that delimits machine names from domain
  12. // names.
  13. //
  14. static const WCHAR pszMachineDelimeter[] = L"\\";
  15. CRITICAL_SECTION DsrLock;
  16. DWORD g_dwTraceId = 0;
  17. DWORD g_dwTraceCount = 0;
  18. //
  19. // Initializes the trace mechanism
  20. //
  21. DWORD
  22. DsrTraceInit()
  23. {
  24. EnterCriticalSection(&DsrLock);
  25. if (g_dwTraceCount == 0)
  26. {
  27. g_dwTraceId = TraceRegisterA("MprDomain");
  28. }
  29. g_dwTraceCount++;
  30. LeaveCriticalSection(&DsrLock);
  31. return NO_ERROR;
  32. }
  33. //
  34. // Cleans up the trace mechansim
  35. //
  36. DWORD
  37. DsrTraceCleanup()
  38. {
  39. EnterCriticalSection(&DsrLock);
  40. if (g_dwTraceCount != 0)
  41. {
  42. g_dwTraceCount--;
  43. if (g_dwTraceCount == 0)
  44. {
  45. TraceDeregisterA(g_dwTraceId);
  46. }
  47. }
  48. LeaveCriticalSection(&DsrLock);
  49. return NO_ERROR;
  50. }
  51. //
  52. // Sends debug trace and returns the given error
  53. //
  54. DWORD DsrTraceEx (
  55. IN DWORD dwErr,
  56. IN LPSTR pszTrace,
  57. IN ...)
  58. {
  59. va_list arglist;
  60. char szBuffer[1024], szTemp[1024];
  61. va_start(arglist, pszTrace);
  62. vsprintf(szTemp, pszTrace, arglist);
  63. va_end(arglist);
  64. sprintf(szBuffer, "Dsr: %s", szTemp);
  65. TracePrintfA(g_dwTraceId, szBuffer);
  66. return dwErr;
  67. }
  68. //
  69. // Allocates memory for use with dsr functions
  70. //
  71. PVOID DsrAlloc(DWORD dwSize, BOOL bZero) {
  72. return GlobalAlloc (bZero ? GPTR : GMEM_FIXED, dwSize);
  73. }
  74. //
  75. // Free memory used by dsr functions
  76. //
  77. DWORD DsrFree(PVOID pvBuf) {
  78. GlobalFree(pvBuf);
  79. return NO_ERROR;
  80. }
  81. //
  82. // Initializes the dcr library
  83. //
  84. DWORD
  85. DsrInit (
  86. OUT DSRINFO * pDsrInfo,
  87. IN PWCHAR pszMachineDomain,
  88. IN PWCHAR pszMachine,
  89. IN PWCHAR pszGroupDomain)
  90. {
  91. DWORD dwErr, dwSize;
  92. HRESULT hr;
  93. WCHAR pszBuf[1024];
  94. // Validate parameters
  95. if (pDsrInfo == NULL)
  96. return ERROR_INVALID_PARAMETER;
  97. ZeroMemory(pDsrInfo, sizeof(DSRINFO));
  98. // Initialize Com
  99. hr = CoInitialize(NULL);
  100. if (FAILED (hr)) {
  101. return DsrTraceEx(
  102. hr,
  103. "DsrInit: %x from CoInitialize",
  104. hr);
  105. }
  106. // Generate the Group DN
  107. dwErr = DsrFindRasServersGroup(
  108. pszGroupDomain,
  109. &(pDsrInfo->pszGroupDN));
  110. if (dwErr != NO_ERROR)
  111. return dwErr;
  112. // Generate the Machine DN
  113. dwErr = DsrFindDomainComputer(
  114. pszMachineDomain,
  115. pszMachine,
  116. &(pDsrInfo->pszMachineDN));
  117. if (dwErr != NO_ERROR)
  118. return dwErr;
  119. return NO_ERROR;
  120. }
  121. //
  122. // Cleans up the dsr library
  123. //
  124. DWORD
  125. DsrCleanup (DSRINFO * pDsrInfo)
  126. {
  127. if (pDsrInfo) {
  128. DSR_FREE (pDsrInfo->pszGroupDN);
  129. DSR_FREE (pDsrInfo->pszMachineDN);
  130. }
  131. CoUninitialize();
  132. return NO_ERROR;
  133. }
  134. //
  135. // Establishes the given machine as being
  136. // or not being a ras server in the domain.
  137. //
  138. // Parameters:
  139. // pszMachine Name of the machine
  140. // bEnable Whether it should or
  141. // shouldn't be a ras server
  142. //
  143. DWORD DsrEstablishComputerAsDomainRasServer (
  144. IN PWCHAR pszDomain,
  145. IN PWCHAR pszMachine,
  146. IN BOOL bEnable)
  147. {
  148. DSRINFO DsrInfo, *pDsrInfo = &DsrInfo;
  149. PWCHAR pszMachineDomain = NULL;
  150. DWORD dwErr = NO_ERROR;
  151. DsrTraceEx(
  152. 0,
  153. "DsrEstablish...: entered: %S, %S, %x",
  154. pszDomain,
  155. pszMachine,
  156. bEnable);
  157. // Parse out the machine's domain.
  158. pszMachineDomain = pszMachine;
  159. pszMachine = wcsstr(pszMachine, pszMachineDelimeter);
  160. if (pszMachine == NULL)
  161. {
  162. return ERROR_INVALID_PARAMETER;
  163. }
  164. *pszMachine = (WCHAR)0;
  165. pszMachine++;
  166. do
  167. {
  168. // Intialize the Dsr library
  169. dwErr = DsrInit(
  170. pDsrInfo,
  171. pszMachineDomain,
  172. pszMachine,
  173. pszDomain);
  174. if (dwErr != NO_ERROR)
  175. {
  176. DsrTraceEx(dwErr, "DsrEstablish...: %x from DsrInit", dwErr);
  177. break;
  178. }
  179. // Attempt to add the machine from the "Computers"
  180. // container
  181. dwErr = DsrGroupAddRemoveMember(
  182. pDsrInfo->pszGroupDN,
  183. pDsrInfo->pszMachineDN,
  184. bEnable);
  185. if (dwErr == ERROR_ALREADY_EXISTS)
  186. {
  187. dwErr = NO_ERROR;
  188. }
  189. if (dwErr != NO_ERROR)
  190. {
  191. DsrTraceEx(dwErr, "DsrEstablish...: %x from Add/Rem", dwErr);
  192. break;
  193. }
  194. } while (FALSE);
  195. // Cleanup
  196. {
  197. DsrCleanup (pDsrInfo);
  198. }
  199. return dwErr;
  200. }
  201. //
  202. // Returns whether the given machine is a member of the remote
  203. // access servers group.
  204. //
  205. DWORD
  206. DsrIsMachineRasServerInDomain(
  207. IN PWCHAR pszDomain,
  208. IN PWCHAR pszMachine,
  209. OUT PBOOL pbIsRasServer)
  210. {
  211. DSRINFO DsrInfo, *pDsrInfo = &DsrInfo;
  212. PWCHAR pszMachineDomain = NULL;
  213. DWORD dwErr = NO_ERROR;
  214. DsrTraceEx(0, "DsrIsRasServerInDomain: entered: %S", pszMachine);
  215. // Parse out the machine's domain.
  216. pszMachineDomain = pszMachine;
  217. pszMachine = wcsstr(pszMachine, pszMachineDelimeter);
  218. if (pszMachine == NULL)
  219. {
  220. return ERROR_INVALID_PARAMETER;
  221. }
  222. *pszMachine = (WCHAR)0;
  223. pszMachine++;
  224. do
  225. {
  226. // Intialize the Dsr library
  227. dwErr = DsrInit(
  228. pDsrInfo,
  229. pszMachineDomain,
  230. pszMachine,
  231. pszDomain);
  232. if (dwErr != NO_ERROR)
  233. {
  234. DsrTraceEx(dwErr, "DsrIsRasSvrInDom: %x from DsrInit", dwErr);
  235. break;
  236. }
  237. // Find out whether the machine is a member of the group
  238. dwErr = DsrGroupIsMember(
  239. pDsrInfo->pszGroupDN,
  240. pDsrInfo->pszMachineDN,
  241. pbIsRasServer);
  242. if (dwErr != NO_ERROR)
  243. {
  244. DsrTraceEx(dwErr, "DsrIsRasSrvInDom: %x from IsMemrGrp", dwErr);
  245. break;
  246. }
  247. } while (FALSE);
  248. // Cleanup
  249. {
  250. DsrCleanup (pDsrInfo);
  251. }
  252. return NO_ERROR;
  253. }
  254. //
  255. // Prepares parameters for the DSR functions. pszDomainComputer
  256. // will be in form <domain>/computer. pszDomain will point to a
  257. // valid domain.
  258. //
  259. DWORD
  260. GenerateDsrParameters(
  261. IN PWCHAR pszDomain,
  262. IN PWCHAR pszMachine,
  263. OUT PWCHAR *ppszDomainComputer,
  264. OUT PWCHAR *ppszGroupDomain)
  265. {
  266. DWORD dwLen, dwErr = NO_ERROR;
  267. PWCHAR pszSlash = NULL;
  268. PDOMAIN_CONTROLLER_INFO pInfo = NULL;
  269. WCHAR pszTemp[MAX_COMPUTERNAME_LENGTH + 1];
  270. // Initailize
  271. *ppszDomainComputer = pszMachine;
  272. *ppszGroupDomain = pszDomain;
  273. do {
  274. // Lookup the current domain if none was specifed
  275. if ((pszDomain == NULL) || (wcslen(pszDomain) == 0)) {
  276. dwErr = DsGetDcName(
  277. NULL,
  278. NULL,
  279. NULL,
  280. NULL,
  281. DS_DIRECTORY_SERVICE_REQUIRED,
  282. &pInfo);
  283. if (dwErr != NO_ERROR)
  284. break;
  285. // Copy the given domain name
  286. dwLen = wcslen(pInfo->DomainName) + 1;
  287. dwLen *= sizeof (WCHAR);
  288. *ppszGroupDomain = (PWCHAR) DsrAlloc(dwLen, FALSE);
  289. if (*ppszGroupDomain == NULL) {
  290. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  291. break;
  292. }
  293. wcscpy(*ppszGroupDomain, pInfo->DomainName);
  294. }
  295. // Make sure that the machine name is in the form
  296. // domain/computer
  297. if (pszMachine)
  298. pszSlash = wcsstr(pszMachine, pszMachineDelimeter);
  299. if (!pszMachine || !pszSlash) {
  300. // Get the domain name if it isn't already
  301. // gotten
  302. if (!pInfo) {
  303. dwErr = DsGetDcName(
  304. NULL,
  305. NULL,
  306. NULL,
  307. NULL,
  308. DS_DIRECTORY_SERVICE_REQUIRED,
  309. &pInfo);
  310. if (dwErr != NO_ERROR)
  311. break;
  312. }
  313. // Get the local computer name if no computer
  314. // name was specified
  315. if ((!pszMachine) || (wcslen(pszMachine) == 0)) {
  316. dwLen = sizeof(pszTemp) / sizeof(WCHAR);
  317. if (! GetComputerName(pszTemp, &dwLen)) {
  318. dwErr = GetLastError();
  319. break;
  320. }
  321. pszMachine = pszTemp;
  322. }
  323. // Allocate the buffer to return the computer name
  324. dwLen = wcslen(pInfo->DomainName) + wcslen(pszMachine) + 2;
  325. dwLen *= sizeof(WCHAR);
  326. *ppszDomainComputer = (PWCHAR) DsrAlloc(dwLen, FALSE);
  327. if (*ppszDomainComputer == NULL) {
  328. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  329. break;
  330. }
  331. wsprintfW(
  332. *ppszDomainComputer,
  333. L"%s%s%s",
  334. pInfo->DomainName,
  335. pszMachineDelimeter,
  336. pszMachine);
  337. }
  338. } while (FALSE);
  339. // Cleanup
  340. {
  341. if (pInfo)
  342. NetApiBufferFree(pInfo);
  343. }
  344. return dwErr;
  345. }
  346. //
  347. // Establishes the given computer as a server in the domain.
  348. // This function must be run under the context of a domain
  349. // admin.
  350. //
  351. DWORD
  352. WINAPI
  353. MprAdminEstablishDomainRasServer (
  354. IN PWCHAR pszDomain,
  355. IN PWCHAR pszMachine,
  356. IN BOOL bEnable)
  357. {
  358. return MprDomainRegisterRasServer(
  359. pszDomain,
  360. pszMachine,
  361. bEnable);
  362. }
  363. DWORD
  364. WINAPI
  365. MprAdminIsDomainRasServer (
  366. IN PWCHAR pszDomain,
  367. IN PWCHAR pszMachine,
  368. OUT PBOOL pbIsRasServer)
  369. {
  370. return MprDomainQueryRasServer(
  371. pszDomain,
  372. pszMachine,
  373. pbIsRasServer);
  374. }
  375. //
  376. // Establishes the given computer as a server in the domain.
  377. // This function must be run under the context of a domain
  378. // admin.
  379. //
  380. DWORD
  381. WINAPI
  382. MprDomainRegisterRasServer (
  383. IN PWCHAR pszDomain,
  384. IN PWCHAR pszMachine,
  385. IN BOOL bEnable)
  386. {
  387. PWCHAR pszDomainComputer, pszGroupDomain;
  388. DWORD dwErr;
  389. do
  390. {
  391. DsrTraceInit();
  392. // Generate the parameters formatted so that
  393. // the dsr functions will accept them.
  394. dwErr = GenerateDsrParameters(
  395. pszDomain,
  396. pszMachine,
  397. &pszDomainComputer,
  398. &pszGroupDomain);
  399. if (dwErr != NO_ERROR)
  400. {
  401. break;
  402. }
  403. dwErr = DsrEstablishComputerAsDomainRasServer (
  404. pszGroupDomain,
  405. pszDomainComputer,
  406. bEnable);
  407. } while (FALSE);
  408. // Cleanup
  409. {
  410. if ((pszDomainComputer) &&
  411. (pszDomainComputer != pszMachine))
  412. {
  413. DsrFree(pszDomainComputer);
  414. }
  415. if ((pszGroupDomain) &&
  416. (pszGroupDomain != pszDomain))
  417. {
  418. DsrFree(pszGroupDomain);
  419. }
  420. DsrTraceCleanup();
  421. }
  422. return dwErr;
  423. }
  424. //
  425. // Determines whether the given machine is an authorized ras
  426. // server in the domain
  427. //
  428. DWORD
  429. WINAPI
  430. MprDomainQueryRasServer (
  431. IN PWCHAR pszDomain,
  432. IN PWCHAR pszMachine,
  433. OUT PBOOL pbIsRasServer)
  434. {
  435. PWCHAR pszDomainComputer, pszGroupDomain;
  436. DWORD dwErr;
  437. do
  438. {
  439. DsrTraceInit();
  440. // Generate the parameters formatted so that
  441. // the dsr functions will accept them.
  442. dwErr = GenerateDsrParameters(
  443. pszDomain,
  444. pszMachine,
  445. &pszDomainComputer,
  446. &pszGroupDomain);
  447. if (dwErr != NO_ERROR)
  448. {
  449. break;
  450. }
  451. // Check the group membership
  452. dwErr = DsrIsMachineRasServerInDomain(
  453. pszGroupDomain,
  454. pszDomainComputer,
  455. pbIsRasServer);
  456. } while (FALSE);
  457. // Cleanup
  458. {
  459. if ((pszDomainComputer) &&
  460. (pszDomainComputer != pszMachine))
  461. {
  462. DsrFree(pszDomainComputer);
  463. }
  464. if ((pszGroupDomain) &&
  465. (pszGroupDomain != pszDomain))
  466. {
  467. DsrFree(pszGroupDomain);
  468. }
  469. DsrTraceCleanup();
  470. }
  471. return dwErr;
  472. }
  473. //
  474. // Enables NT4 Servers in the given domain
  475. //
  476. DWORD
  477. WINAPI
  478. MprDomainSetAccess(
  479. IN PWCHAR pszDomain,
  480. IN DWORD dwAccessFlags)
  481. {
  482. DWORD dwErr;
  483. DsrTraceInit();
  484. dwErr = DsrDomainSetAccess(pszDomain, dwAccessFlags);
  485. DsrTraceCleanup();
  486. return dwErr;
  487. }
  488. //
  489. // Discovers whether NT4 Servers in the given domain
  490. // are enabled.
  491. //
  492. DWORD
  493. WINAPI
  494. MprDomainQueryAccess(
  495. IN PWCHAR pszDomain,
  496. IN LPDWORD lpdwAccessFlags)
  497. {
  498. DWORD dwErr;
  499. DsrTraceInit();
  500. dwErr = DsrDomainQueryAccess(pszDomain, lpdwAccessFlags);
  501. DsrTraceCleanup();
  502. return dwErr;
  503. }