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.

841 lines
24 KiB

  1. //-----------------------------------------------------------------------------
  2. //
  3. // Copyright (C) 1998, Microsoft Corporation
  4. //
  5. // File: dfsacl.c
  6. // Contents: Functions to add/remove entries from ACL list(s).
  7. //
  8. // History: Nov 6, 1998 JHarper created
  9. //
  10. //-----------------------------------------------------------------------------
  11. #define UNICODE
  12. #include <stdio.h>
  13. #include <nt.h>
  14. #include <ntrtl.h>
  15. #include <nturtl.h>
  16. #include <windows.h>
  17. #include <winldap.h>
  18. #include <ntldap.h>
  19. #include <stdlib.h>
  20. #include <dsgetdc.h>
  21. #include <lm.h>
  22. #include <sddl.h>
  23. #include <dfsstr.h>
  24. #include <dfsmrshl.h>
  25. #include <marshal.hxx>
  26. #include <lmdfs.h>
  27. #include <dfspriv.h>
  28. #include <csites.hxx>
  29. #include <dfsm.hxx>
  30. #include <recon.hxx>
  31. #include "dfsacl.hxx"
  32. #include "struct.hxx"
  33. DWORD
  34. ReadDSObjSecDesc(
  35. PLDAP pLDAP,
  36. PWSTR pwszObject,
  37. SECURITY_INFORMATION SeInfo,
  38. PSECURITY_DESCRIPTOR *ppSD,
  39. PULONG pcSDSize);
  40. DWORD
  41. DfsGetObjSecurity(
  42. LDAP *pldap,
  43. LPWSTR pwszObjectName,
  44. LPWSTR *pwszStringSD);
  45. DWORD
  46. DfsStampSD(
  47. PWSTR pwszObject,
  48. ULONG cSDSize,
  49. SECURITY_INFORMATION SeInfo,
  50. PSECURITY_DESCRIPTOR pSD,
  51. PLDAP pLDAP);
  52. DWORD
  53. DfsAddAce(
  54. LDAP *pldap,
  55. LPWSTR wszObjectName,
  56. LPWSTR wszStringSD,
  57. LPWSTR wszwszStringSid);
  58. DWORD
  59. DfsRemoveAce(
  60. LDAP *pldap,
  61. LPWSTR wszObjectName,
  62. LPWSTR wszStringSD,
  63. LPWSTR wszwszStringSid);
  64. BOOL
  65. DfsFindSid(
  66. LPWSTR DcName,
  67. LPWSTR Name,
  68. PSID *Sid);
  69. BOOLEAN
  70. DfsSidInAce(
  71. LPWSTR wszAce,
  72. LPWSTR wszStringSid);
  73. #define ACTRL_SD_PROP_NAME L"nTSecurityDescriptor"
  74. //
  75. // Name of the attribute holding the ACL/ACE list
  76. //
  77. #define ACTRL_SD_PROP_NAME L"nTSecurityDescriptor"
  78. //
  79. // The sddl description of the ACE we will be adding
  80. //
  81. LPWSTR wszAce = L"(A;;RPWP;;;";
  82. //+---------------------------------------------------------------------------
  83. //
  84. // Function: DfsAddMachineAce
  85. //
  86. // Synopsis: Adds an ACE representing this machine to the ACL list of the
  87. // object.
  88. //
  89. // Arguments: [pldap] -- The open LDAP connection
  90. // [wszDcName] -- The DC whose DS we are to use.
  91. // [wszObjectName] -- The fully-qualified name of the DS object
  92. // [wszRootName] -- The name of the machine/root we want to add
  93. //
  94. // Returns: ERROR_SUCCESS -- The object is reachable
  95. // ERROR_NOT_ENOUGH_MEMORY A memory allocation failed
  96. //
  97. //----------------------------------------------------------------------------
  98. DWORD
  99. DfsAddMachineAce(
  100. LDAP *pldap,
  101. LPWSTR wszDcName,
  102. LPWSTR wszObjectName,
  103. LPWSTR wszRootName)
  104. {
  105. ULONG dwErr = ERROR_SUCCESS;
  106. PSID Sid;
  107. BOOL Result;
  108. ULONG i;
  109. WCHAR wszNewSD[MAX_PATH];
  110. LPWSTR wszStringSD = NULL;
  111. LPWSTR wszStringSid = NULL;
  112. LPWSTR wszNewRootName = NULL;
  113. if (fSwDebug != 0)
  114. MyPrintf(L"DfsAddMachineAce(%ws,%ws)\r\n", wszObjectName, wszRootName);
  115. //
  116. // Get Security Descriptor on the FtDfs object
  117. //
  118. dwErr = DfsGetObjSecurity(pldap, wszObjectName, &wszStringSD);
  119. if (dwErr == ERROR_SUCCESS) {
  120. if (fSwDebug != 0)
  121. MyPrintf(L"ACL=[%ws]\r\n", wszStringSD);
  122. wszNewRootName = (LPWSTR)malloc((wcslen(wszRootName) + 2) * sizeof(WCHAR));
  123. if (wszNewRootName != NULL) {
  124. wcscpy(wszNewRootName, wszRootName);
  125. for (i = 0; wszNewRootName[i] != L'\0'; i++) {
  126. if (wszNewRootName[i] == L'.') {
  127. wszNewRootName[i] = L'\0';
  128. break;
  129. }
  130. }
  131. wcscat(wszNewRootName, L"$");
  132. //
  133. // Get SID representing root machine
  134. //
  135. Result = DfsFindSid(wszDcName,wszNewRootName, &Sid);
  136. if (Result == TRUE) {
  137. if (fSwDebug != 0)
  138. MyPrintf(L"Got SID for %ws\r\n", wszRootName);
  139. //
  140. // Convert the machine SID to a string
  141. //
  142. Result = ConvertSidToStringSid(Sid, &wszStringSid);
  143. if (Result == TRUE) {
  144. if (fSwDebug != 0)
  145. MyPrintf(L"Sid=[%ws]\r\n", wszStringSid);
  146. //
  147. // Now update the ACL list on the FtDfs object
  148. //
  149. DfsAddAce(
  150. pldap,
  151. wszObjectName,
  152. wszStringSD,
  153. wszStringSid);
  154. LocalFree(wszStringSid);
  155. }
  156. } else {
  157. dwErr = ERROR_OBJECT_NOT_FOUND;
  158. }
  159. free(wszNewRootName);
  160. } else {
  161. dwErr = ERROR_OUTOFMEMORY;
  162. }
  163. LocalFree(wszStringSD);
  164. }
  165. if (fSwDebug != 0)
  166. MyPrintf(L"DfsAddMachineAce returning %d\r\n", dwErr);
  167. return dwErr;
  168. }
  169. //+---------------------------------------------------------------------------
  170. //
  171. // Function: DfsRemoveMachineAce
  172. //
  173. // Synopsis: Removes an ACE representing this machine from the ACL list of the
  174. // object.
  175. //
  176. // Arguments: [pldap] -- The open LDAP connection
  177. // [wszDcName] -- The DC whose DS we are to use.
  178. // [wszObjectName] -- The fully-qualified name of the DS object
  179. // [wszRootName] -- The name of the machine/root we want to remove
  180. //
  181. // Returns: ERROR_SUCCESS -- The object is reachable
  182. // ERROR_NOT_ENOUGH_MEMORY A memory allocation failed
  183. //
  184. //----------------------------------------------------------------------------
  185. DWORD
  186. DfsRemoveMachineAce(
  187. LDAP *pldap,
  188. LPWSTR wszDcName,
  189. LPWSTR wszObjectName,
  190. LPWSTR wszRootName)
  191. {
  192. ULONG dwErr = ERROR_SUCCESS;
  193. PSID Sid;
  194. BOOL Result;
  195. WCHAR wszNewSD[MAX_PATH];
  196. LPWSTR wszStringSD = NULL;
  197. LPWSTR wszStringSid = NULL;
  198. LPWSTR wszNewRootName = NULL;
  199. ULONG i;
  200. if (fSwDebug != 0)
  201. MyPrintf(L"DfsRemoveMachineAce(DC=%ws,DN=\"%ws\",Root=%ws)\r\n",
  202. wszDcName,
  203. wszObjectName,
  204. wszRootName);
  205. //
  206. // Get Security Descriptor on the FtDfs object
  207. //
  208. dwErr = DfsGetObjSecurity(pldap, wszObjectName, &wszStringSD);
  209. if (dwErr == ERROR_SUCCESS) {
  210. if (fSwDebug != 0)
  211. MyPrintf(L"ACL=[%ws]\r\n", wszStringSD);
  212. wszNewRootName = (LPWSTR)malloc((wcslen(wszRootName) + 2) * sizeof(WCHAR));
  213. if (wszNewRootName != NULL) {
  214. wcscpy(wszNewRootName, wszRootName);
  215. for (i = 0; wszNewRootName[i] != L'\0'; i++) {
  216. if (wszNewRootName[i] == L'.') {
  217. wszNewRootName[i] = L'\0';
  218. break;
  219. }
  220. }
  221. wcscat(wszNewRootName, L"$");
  222. //
  223. // Get SID representing root machine
  224. //
  225. Result = DfsFindSid(wszDcName,wszNewRootName, &Sid);
  226. if (Result == TRUE) {
  227. if (fSwDebug != 0)
  228. MyPrintf(L"Got SID for %ws\r\n", wszRootName);
  229. //
  230. // Convert the machine SID to a string
  231. //
  232. Result = ConvertSidToStringSid(Sid, &wszStringSid);
  233. if (Result == TRUE) {
  234. if (fSwDebug != 0)
  235. MyPrintf(L"Sid=[%ws]\r\n", wszStringSid);
  236. //
  237. // Now update the ACL list on the FtDfs object
  238. //
  239. DfsRemoveAce(
  240. pldap,
  241. wszObjectName,
  242. wszStringSD,
  243. wszStringSid);
  244. LocalFree(wszStringSid);
  245. }
  246. } else {
  247. dwErr = ERROR_OBJECT_NOT_FOUND;
  248. }
  249. free(wszNewRootName);
  250. } else {
  251. dwErr = ERROR_OUTOFMEMORY;
  252. }
  253. LocalFree(wszStringSD);
  254. }
  255. if (fSwDebug != 0)
  256. MyPrintf(L"DfsRemoveMachineAce exit %d\r\n", dwErr);
  257. return dwErr;
  258. }
  259. //+---------------------------------------------------------------------------
  260. //
  261. // Function: ReadDSObjSecDesc
  262. //
  263. // Synopsis: Reads the security descriptor from the specied object via
  264. // the open ldap connection
  265. //
  266. // Arguments: [pLDAP] -- The open LDAP connection
  267. // [pwszDSObj] -- The DSObject to get the security
  268. // descriptor for
  269. // [SeInfo] -- Parts of the security descriptor to
  270. // read.
  271. // [ppSD] -- Where the security descriptor is
  272. // returned
  273. // [pcSDSize -- Size of the security descriptor
  274. //
  275. // Returns: ERROR_SUCCESS -- The object is reachable
  276. // ERROR_NOT_ENOUGH_MEMORY A memory allocation failed
  277. //
  278. // Notes: The returned security descriptor must be freed with LocalFree
  279. //
  280. //----------------------------------------------------------------------------
  281. DWORD
  282. ReadDSObjSecDesc(
  283. PLDAP pLDAP,
  284. PWSTR pwszObject,
  285. SECURITY_INFORMATION SeInfo,
  286. PSECURITY_DESCRIPTOR *ppSD,
  287. PULONG pcSDSize)
  288. {
  289. DWORD dwErr = ERROR_SUCCESS;
  290. PLDAPMessage pMsg = NULL;
  291. PWSTR rgAttribs[2];
  292. BYTE berValue[8];
  293. LDAPControl SeInfoControl =
  294. {
  295. LDAP_SERVER_SD_FLAGS_OID_W,
  296. {
  297. 5, (PCHAR)berValue
  298. },
  299. TRUE
  300. };
  301. PLDAPControl ServerControls[2] =
  302. {
  303. &SeInfoControl,
  304. NULL
  305. };
  306. if (fSwDebug != 0)
  307. MyPrintf(L"ReadDSObjSecDesc(%ws)\r\n", pwszObject);
  308. berValue[0] = 0x30;
  309. berValue[1] = 0x03;
  310. berValue[2] = 0x02;
  311. berValue[3] = 0x01;
  312. berValue[4] = (BYTE)((ULONG)SeInfo & 0xF);
  313. rgAttribs[0] = ACTRL_SD_PROP_NAME;
  314. rgAttribs[1] = NULL;
  315. dwErr = ldap_search_ext_s(
  316. pLDAP,
  317. pwszObject,
  318. LDAP_SCOPE_BASE,
  319. L"(objectClass=*)",
  320. rgAttribs,
  321. 0,
  322. (PLDAPControl *)&ServerControls,
  323. NULL,
  324. NULL,
  325. 10000,
  326. &pMsg);
  327. dwErr = LdapMapErrorToWin32( dwErr );
  328. if(dwErr == ERROR_SUCCESS) {
  329. LDAPMessage *pEntry = NULL;
  330. PWSTR *ppwszValues = NULL;
  331. PLDAP_BERVAL *pSize = NULL;
  332. pEntry = ldap_first_entry(pLDAP, pMsg);
  333. if(pEntry != NULL) {
  334. //
  335. // Now, we'll have to get the values
  336. //
  337. ppwszValues = ldap_get_values(pLDAP, pEntry, rgAttribs[0]);
  338. if(ppwszValues != NULL) {
  339. pSize = ldap_get_values_len(pLDAP, pMsg, rgAttribs[0]);
  340. if(pSize != NULL) {
  341. //
  342. // Allocate the security descriptor to return
  343. //
  344. *ppSD = (PSECURITY_DESCRIPTOR)malloc((*pSize)->bv_len);
  345. if(*ppSD != NULL) {
  346. memcpy(*ppSD, (PBYTE)(*pSize)->bv_val, (*pSize)->bv_len);
  347. *pcSDSize = (*pSize)->bv_len;
  348. } else {
  349. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  350. }
  351. ldap_value_free_len(pSize);
  352. } else {
  353. dwErr = LdapMapErrorToWin32( pLDAP->ld_errno );
  354. }
  355. ldap_value_free(ppwszValues);
  356. } else {
  357. dwErr = LdapMapErrorToWin32( pLDAP->ld_errno );
  358. }
  359. } else {
  360. dwErr = LdapMapErrorToWin32( pLDAP->ld_errno );
  361. }
  362. ldap_msgfree(pMsg);
  363. }
  364. if (fSwDebug != 0)
  365. MyPrintf(L"ReadDSObjSecDesc returning %d\r\n", dwErr);
  366. return(dwErr);
  367. }
  368. //+---------------------------------------------------------------------------
  369. //
  370. // Function: DfsGetObjSecurity
  371. //
  372. // Synopsis: Gets the ACL list of an object in sddl stringized form
  373. //
  374. // Arguments: [pldap] -- The open LDAP connection
  375. // [wszObjectName] -- The fully-qualified name of the DS object
  376. // [pwszStringSD] -- Pointer to pointer to SD in string form (sddl)
  377. //
  378. // Returns: ERROR_SUCCESS -- The object is reachable
  379. //
  380. //----------------------------------------------------------------------------
  381. DWORD
  382. DfsGetObjSecurity(
  383. LDAP *pldap,
  384. LPWSTR pwszObjectName,
  385. LPWSTR *pwszStringSD)
  386. {
  387. DWORD dwErr;
  388. WCHAR wszObjectName[ MAX_PATH ];
  389. SECURITY_INFORMATION si;
  390. PSECURITY_DESCRIPTOR pSD = NULL;
  391. ULONG cSDSize;
  392. if (fSwDebug != 0)
  393. MyPrintf(L"DfsGetObjSecurity(%ws)\r\n", pwszObjectName);
  394. si = DACL_SECURITY_INFORMATION;
  395. dwErr = ReadDSObjSecDesc(
  396. pldap,
  397. pwszObjectName,
  398. si,
  399. &pSD,
  400. &cSDSize);
  401. if (dwErr == ERROR_SUCCESS) {
  402. if (!ConvertSecurityDescriptorToStringSecurityDescriptor(
  403. pSD,
  404. SDDL_REVISION_1,
  405. DACL_SECURITY_INFORMATION,
  406. pwszStringSD,
  407. NULL)
  408. ) {
  409. dwErr = GetLastError();
  410. if (fSwDebug != 0)
  411. MyPrintf(L"ConvertSecurityDescriptorToStringSecurityDescriptor FAILED %d:\r\n", dwErr);
  412. }
  413. }
  414. return(dwErr);
  415. }
  416. //+---------------------------------------------------------------------------
  417. //
  418. // Function: DfsFindSid
  419. //
  420. // Synopsis: Gets the SID for a name
  421. //
  422. // [DcName] -- The DC to remote to
  423. // [Name] -- The Name of the object
  424. // [Sid] -- Pointer to pointer to returned SID, which must be freed
  425. // using LocalFree
  426. //
  427. // Returns: TRUE or FALSE
  428. //
  429. //----------------------------------------------------------------------------
  430. BOOL
  431. DfsFindSid(
  432. LPWSTR DcName,
  433. LPWSTR Name,
  434. PSID *Sid
  435. )
  436. {
  437. DWORD SidLength = 0;
  438. WCHAR DomainName[256];
  439. DWORD DomainNameLength = 256;
  440. SID_NAME_USE Use;
  441. BOOL Result;
  442. if (fSwDebug != 0)
  443. MyPrintf(L"DfsFindSid(%ws,%ws)\r\n", DcName,Name);
  444. Result = LookupAccountName(
  445. DcName,
  446. Name,
  447. (PSID)NULL,
  448. &SidLength,
  449. DomainName,
  450. &DomainNameLength,
  451. &Use);
  452. if ( !Result && (GetLastError() == ERROR_INSUFFICIENT_BUFFER) ) {
  453. *Sid = LocalAlloc( 0, SidLength );
  454. Result = LookupAccountName(
  455. NULL,
  456. Name,
  457. *Sid,
  458. &SidLength,
  459. DomainName,
  460. &DomainNameLength,
  461. &Use);
  462. }
  463. if (fSwDebug != 0)
  464. MyPrintf(L"DfsFindSid returning %s\r\n", Result == TRUE ? "TRUE" : "FALSE");
  465. return( Result );
  466. }
  467. //+---------------------------------------------------------------------------
  468. //
  469. // Function: DfsAddAce
  470. //
  471. // Synopsis: Adds a string ACE to a string version of an objects SD
  472. // object. This is a string manipulation routine.
  473. //
  474. // Arguments: [pldap] -- The open LDAP connection
  475. // [wszObjectName] -- The fully-qualified name of the DS object
  476. // [wszStringSD] -- String version of SD
  477. // [wszStringSid] -- String version of SID to add
  478. //
  479. // Returns: ERROR_SUCCESS -- ACE was added
  480. //
  481. //----------------------------------------------------------------------------
  482. DWORD
  483. DfsAddAce(
  484. LDAP *pldap,
  485. LPWSTR wszObjectName,
  486. LPWSTR wszStringSD,
  487. LPWSTR wszStringSid)
  488. {
  489. DWORD dwErr = ERROR_SUCCESS;
  490. LPWSTR wszNewStringSD = NULL;
  491. SECURITY_INFORMATION si;
  492. PSECURITY_DESCRIPTOR pSD = NULL;
  493. BOOL Result;
  494. ULONG Size = 0;
  495. ULONG cSDSize = 0;
  496. if (fSwDebug != 0)
  497. MyPrintf(L"DfsAddAce(%ws)\r\n", wszObjectName);
  498. Size = wcslen(wszStringSD) * sizeof(WCHAR) +
  499. wcslen(wszAce) * sizeof(WCHAR) +
  500. wcslen(wszStringSid) * sizeof(WCHAR) +
  501. wcslen(L")") * sizeof(WCHAR) +
  502. sizeof(WCHAR);
  503. wszNewStringSD = (LPWSTR)malloc(Size);
  504. if (wszNewStringSD != NULL) {
  505. wcscpy(wszNewStringSD,wszStringSD);
  506. wcscat(wszNewStringSD,wszAce);
  507. wcscat(wszNewStringSD,wszStringSid);
  508. wcscat(wszNewStringSD,L")");
  509. if (fSwDebug != 0)
  510. MyPrintf(L"NewSD=[%ws]\r\n", wszNewStringSD);
  511. Result = ConvertStringSecurityDescriptorToSecurityDescriptor(
  512. wszNewStringSD,
  513. SDDL_REVISION_1,
  514. &pSD,
  515. &cSDSize);
  516. if (Result == TRUE) {
  517. si = DACL_SECURITY_INFORMATION;
  518. dwErr = DfsStampSD(
  519. wszObjectName,
  520. cSDSize,
  521. si,
  522. pSD,
  523. pldap);
  524. LocalFree(pSD);
  525. } else {
  526. dwErr = GetLastError();
  527. if (fSwDebug != 0)
  528. MyPrintf(L"Convert returned %d\r\n", dwErr);
  529. }
  530. free(wszNewStringSD);
  531. } else {
  532. dwErr = ERROR_OUTOFMEMORY;
  533. }
  534. if (fSwDebug != 0)
  535. MyPrintf(L"DfsAddAce returning %d\r\n", dwErr);
  536. return(dwErr);
  537. }
  538. //+---------------------------------------------------------------------------
  539. //
  540. // Function: DfsRemoveAce
  541. //
  542. // Synopsis: Finds and removes a string ACE from the string SD of an
  543. // object. This is a string manipulation routine.
  544. //
  545. // Arguments: [pldap] -- The open LDAP connection
  546. // [wszObjectName] -- The fully-qualified name of the DS object
  547. // [wszStringSD] -- String version of SD
  548. // [wszStringSid] -- String version of SID to remove
  549. //
  550. // Returns: ERROR_SUCCESS -- ACE was removed or was not present
  551. //
  552. //----------------------------------------------------------------------------
  553. DWORD
  554. DfsRemoveAce(
  555. LDAP *pldap,
  556. LPWSTR wszObjectName,
  557. LPWSTR wszStringSD,
  558. LPWSTR wszStringSid)
  559. {
  560. DWORD dwErr = ERROR_SUCCESS;
  561. LPWSTR wszNewStringSD = NULL;
  562. SECURITY_INFORMATION si;
  563. PSECURITY_DESCRIPTOR pSD = NULL;
  564. BOOL Result;
  565. ULONG Size = 0;
  566. ULONG cSDSize = 0;
  567. BOOLEAN fCopying;
  568. ULONG s1, s2;
  569. if (fSwDebug != 0)
  570. MyPrintf(L"DfsRemoveAce(%ws)\r\n", wszObjectName);
  571. Size = wcslen(wszStringSD) * sizeof(WCHAR) + sizeof(WCHAR);
  572. wszNewStringSD = (LPWSTR)malloc(Size);
  573. if (wszNewStringSD != NULL) {
  574. RtlZeroMemory(wszNewStringSD, Size);
  575. //
  576. // We have to find the ACEs containing this SID, and remove them.
  577. //
  578. fCopying = TRUE;
  579. for (s1 = s2 = 0; wszStringSD[s1]; s1++) {
  580. //
  581. // If this is the start of an ACE that has this SID, stop copying
  582. //
  583. if (wszStringSD[s1] == L'(' && DfsSidInAce(&wszStringSD[s1],wszStringSid) == TRUE) {
  584. fCopying = FALSE;
  585. continue;
  586. }
  587. //
  588. // If this is the end of SID we are not copying, start copying again
  589. //
  590. if (wszStringSD[s1] == L')' && fCopying == FALSE) {
  591. fCopying = TRUE;
  592. continue;
  593. }
  594. //
  595. // If we are copying, do so.
  596. //
  597. if (fCopying == TRUE)
  598. wszNewStringSD[s2++] = wszStringSD[s1];
  599. }
  600. if (fSwDebug != 0)
  601. MyPrintf(L"NewSD=[%ws]\r\n", wszNewStringSD);
  602. Result = ConvertStringSecurityDescriptorToSecurityDescriptor(
  603. wszNewStringSD,
  604. SDDL_REVISION_1,
  605. &pSD,
  606. &cSDSize);
  607. if (Result == TRUE) {
  608. si = DACL_SECURITY_INFORMATION;
  609. dwErr = DfsStampSD(
  610. wszObjectName,
  611. cSDSize,
  612. si,
  613. pSD,
  614. pldap);
  615. LocalFree(pSD);
  616. } else {
  617. dwErr = GetLastError();
  618. if (fSwDebug != 0)
  619. MyPrintf(L"Convert returned %d\r\n", dwErr);
  620. }
  621. free(wszNewStringSD);
  622. } else {
  623. dwErr = ERROR_OUTOFMEMORY;
  624. }
  625. if (fSwDebug != 0)
  626. MyPrintf(L"DfsRemoveAce returning %d\r\n", dwErr);
  627. return(dwErr);
  628. }
  629. //+---------------------------------------------------------------------------
  630. //
  631. // Function: DfsSidInAce
  632. //
  633. // Synopsis: Scans an ACE to see if the string SID is in it.
  634. //
  635. // Arguments: [wszAce] -- ACE to scan
  636. // [wszStringSid] -- SID to scan for
  637. //
  638. // Returns: TRUE -- SID is in this ACE
  639. // FALSE -- SID is not in this ACE
  640. //
  641. //----------------------------------------------------------------------------
  642. BOOLEAN
  643. DfsSidInAce(
  644. LPWSTR wszAce,
  645. LPWSTR wszStringSid)
  646. {
  647. ULONG i;
  648. ULONG SidLen = wcslen(wszStringSid);
  649. ULONG AceLen;
  650. WCHAR Oldcp;
  651. for (AceLen = 0; wszAce[AceLen] && wszAce[AceLen] != L')'; AceLen++)
  652. /* NOTHING */;
  653. Oldcp = wszAce[AceLen];
  654. wszAce[AceLen] = L'\0';
  655. if (fSwDebug != 0)
  656. MyPrintf(L"DfsSidInAce(%ws),%ws)\r\n", wszAce, wszStringSid);
  657. wszAce[AceLen] = Oldcp;
  658. if (SidLen > AceLen || wszAce[0] != L'(') {
  659. if (fSwDebug != 0)
  660. MyPrintf(L"DfsSidInAce returning FALSE(1)\r\n");
  661. return FALSE;
  662. }
  663. for (i = 0; i <= (AceLen - SidLen); i++) {
  664. if (wszAce[i] == wszStringSid[0] && wcsncmp(&wszAce[i],wszStringSid,SidLen) == 0) {
  665. if (fSwDebug != 0)
  666. MyPrintf(L"DfsSidInAce returning TRUE\r\n");
  667. return TRUE;
  668. }
  669. }
  670. if (fSwDebug != 0)
  671. MyPrintf(L"DfsSidInAce returning FALSE(2)\r\n");
  672. return FALSE;
  673. }
  674. //+---------------------------------------------------------------------------
  675. //
  676. // Function: DfsStampSD
  677. //
  678. // Synopsis: Actually stamps the security descriptor on the object.
  679. //
  680. // Arguments: [pwszObject] -- The object to stamp the SD on
  681. // [cSDSize] -- The size of the security descriptor
  682. // [SeInfo] -- SecurityInformation about the security
  683. // descriptor
  684. // [pSD] -- The SD to stamp
  685. // [pLDAP] -- The LDAP connection to use
  686. //
  687. // Returns: ERROR_SUCCESS -- Success
  688. //
  689. //----------------------------------------------------------------------------
  690. DWORD
  691. DfsStampSD(
  692. PWSTR pwszObject,
  693. ULONG cSDSize,
  694. SECURITY_INFORMATION SeInfo,
  695. PSECURITY_DESCRIPTOR pSD,
  696. PLDAP pLDAP)
  697. {
  698. DWORD dwErr = ERROR_SUCCESS;
  699. PLDAPMod rgMods[2];
  700. PLDAP_BERVAL pBVals[2];
  701. LDAPMod Mod;
  702. LDAP_BERVAL BVal;
  703. BYTE ControlBuffer[ 5 ];
  704. LDAPControl SeInfoControl =
  705. {
  706. LDAP_SERVER_SD_FLAGS_OID_W,
  707. {
  708. 5, (PCHAR) &ControlBuffer
  709. },
  710. TRUE
  711. };
  712. PLDAPControl ServerControls[2] =
  713. {
  714. &SeInfoControl,
  715. NULL
  716. };
  717. if (fSwDebug != 0)
  718. MyPrintf(L"DfsStampSD(%ws,%d)\r\n", pwszObject, cSDSize);
  719. ASSERT(*(PULONG)pSD > 0xF );
  720. ControlBuffer[0] = 0x30;
  721. ControlBuffer[1] = 0x3;
  722. ControlBuffer[2] = 0x02; // Denotes an integer;
  723. ControlBuffer[3] = 0x01; // Size
  724. ControlBuffer[4] = (BYTE)((ULONG)SeInfo & 0xF);
  725. ASSERT(IsValidSecurityDescriptor( pSD ) );
  726. rgMods[0] = &Mod;
  727. rgMods[1] = NULL;
  728. pBVals[0] = &BVal;
  729. pBVals[1] = NULL;
  730. BVal.bv_len = cSDSize;
  731. BVal.bv_val = (PCHAR)pSD;
  732. Mod.mod_op = LDAP_MOD_REPLACE | LDAP_MOD_BVALUES;
  733. Mod.mod_type = ACTRL_SD_PROP_NAME;
  734. Mod.mod_values = (PWSTR *)pBVals;
  735. //
  736. // Now, we'll do the write...
  737. //
  738. dwErr = ldap_modify_ext_s(pLDAP,
  739. pwszObject,
  740. rgMods,
  741. (PLDAPControl *)&ServerControls,
  742. NULL);
  743. dwErr = LdapMapErrorToWin32(dwErr);
  744. if (fSwDebug != 0)
  745. MyPrintf(L"DfsStampSD returning %d\r\n", dwErr);
  746. return(dwErr);
  747. }