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.

295 lines
8.0 KiB

  1. //
  2. // Copyright (C) 2000-2002, Microsoft Corporation
  3. //
  4. // File: Adsecurity.c
  5. //
  6. // Contents: miscellaneous dfs functions.
  7. //
  8. // History: April 16 2002, Author: Rohanp
  9. //
  10. //-----------------------------------------------------------------------------
  11. #include <nt.h>
  12. #include <ntrtl.h>
  13. #include <nturtl.h>
  14. #include <windows.h>
  15. #include <stdio.h>
  16. #include <stdlib.h>
  17. #include <malloc.h>
  18. #include <dsgetdc.h>
  19. #include <lm.h>
  20. #include <dfsheader.h>
  21. #include <dfsmisc.h>
  22. #include <shellapi.h>
  23. #include <ole2.h>
  24. #include <activeds.h>
  25. #include <sddl.h>
  26. #include <WinLdap.h>
  27. #include <NtLdap.h>
  28. #include <ntdsapi.h>
  29. #include <dfssecurity.h>
  30. #include "securitylogmacros.hxx"
  31. #include "adsecurity.tmh"
  32. #define ACTRL_SD_PROP_NAME L"nTSecurityDescriptor"
  33. #define DFS_DS_GENERIC_READ ( DS_GENERIC_READ & ~ACTRL_DS_LIST_OBJECT )
  34. #define DFS_DS_GENERIC_WRITE ( DS_GENERIC_WRITE )
  35. #define DFS_DS_GENERIC_EXECUTE ( DS_GENERIC_EXECUTE )
  36. #define DFS_DS_GENERIC_ALL ( DS_GENERIC_ALL & ~ACTRL_DS_LIST_OBJECT )
  37. GENERIC_MAPPING DfsAdAdminGenericMapping = {
  38. DFS_DS_GENERIC_READ, // Generic read
  39. DFS_DS_GENERIC_WRITE, // Generic write
  40. DFS_DS_GENERIC_EXECUTE,
  41. DFS_DS_GENERIC_ALL
  42. };
  43. DFSSTATUS
  44. DfsReadDSObjSecDesc(
  45. LDAP * pLDAP,
  46. PWSTR pwszObject,
  47. SECURITY_INFORMATION SeInfo,
  48. PSECURITY_DESCRIPTOR *ppSD,
  49. PULONG pcSDSize)
  50. {
  51. DFSSTATUS Status = ERROR_SUCCESS;
  52. PLDAPMessage pMsg = NULL;
  53. LDAPMessage *pEntry = NULL;
  54. PWSTR *ppwszValues = NULL;
  55. PLDAP_BERVAL *pSize = NULL;
  56. PWSTR rgAttribs[2];
  57. BYTE berValue[8];
  58. LDAPControl SeInfoControl =
  59. {
  60. LDAP_SERVER_SD_FLAGS_OID_W,
  61. {
  62. 5, (PCHAR)berValue
  63. },
  64. TRUE
  65. };
  66. PLDAPControl ServerControls[2] =
  67. {
  68. &SeInfoControl,
  69. NULL
  70. };
  71. berValue[0] = 0x30;
  72. berValue[1] = 0x03;
  73. berValue[2] = 0x02;
  74. berValue[3] = 0x01;
  75. berValue[4] = (BYTE)((ULONG)SeInfo & 0xF);
  76. rgAttribs[0] = ACTRL_SD_PROP_NAME;
  77. rgAttribs[1] = NULL;
  78. Status = ldap_search_ext_s(
  79. pLDAP,
  80. pwszObject,
  81. LDAP_SCOPE_BASE,
  82. L"(objectClass=*)",
  83. rgAttribs,
  84. 0,
  85. (PLDAPControl *)ServerControls,
  86. NULL,
  87. NULL,
  88. 10000,
  89. &pMsg);
  90. Status = LdapMapErrorToWin32( Status );
  91. if(Status == ERROR_SUCCESS)
  92. {
  93. pEntry = ldap_first_entry(pLDAP, pMsg);
  94. if(pEntry == NULL)
  95. {
  96. Status = LdapMapErrorToWin32( pLDAP->ld_errno );
  97. }
  98. else
  99. {
  100. //
  101. // Now, we'll have to get the values
  102. //
  103. ppwszValues = ldap_get_values(pLDAP, pEntry, rgAttribs[0]);
  104. if(ppwszValues != NULL)
  105. {
  106. pSize = ldap_get_values_len(pLDAP, pMsg, rgAttribs[0]);
  107. if(pSize != NULL)
  108. {
  109. //
  110. // Allocate the security descriptor to return
  111. //
  112. *ppSD = (PSECURITY_DESCRIPTOR)DfsAllocateSecurityData((*pSize)->bv_len);
  113. if(*ppSD != NULL)
  114. {
  115. memcpy(*ppSD, (PBYTE)(*pSize)->bv_val, (*pSize)->bv_len);
  116. *pcSDSize = (*pSize)->bv_len;
  117. }
  118. else
  119. {
  120. Status = ERROR_NOT_ENOUGH_MEMORY;
  121. }
  122. ldap_value_free_len(pSize);
  123. }
  124. else
  125. {
  126. Status = LdapMapErrorToWin32( pLDAP->ld_errno );
  127. }
  128. ldap_value_free(ppwszValues);
  129. }
  130. else
  131. {
  132. Status = LdapMapErrorToWin32( pLDAP->ld_errno );
  133. }
  134. }
  135. }
  136. if (pMsg != NULL)
  137. {
  138. ldap_msgfree(pMsg);
  139. }
  140. return(Status);
  141. }
  142. //+---------------------------------------------------------------------------
  143. //
  144. // Function: DfsGetObjSecurity
  145. //
  146. // Synopsis: Gets the ACL list of an object in sddl stringized form
  147. //
  148. // Arguments: [pldap] -- The open LDAP connection
  149. // [wszObjectName] -- The fully-qualified name of the DS object
  150. // [pwszStringSD] -- Pointer to pointer to SD in string form (sddl)
  151. //
  152. // Returns: ERROR_SUCCESS -- The object is reachable
  153. //
  154. //----------------------------------------------------------------------------
  155. DFSSTATUS
  156. DfsGetObjSecurity(LDAP *pldap,
  157. LPWSTR pwszObjectName,
  158. PSECURITY_DESCRIPTOR * pSDRet)
  159. {
  160. DFSSTATUS Status = 0;
  161. PSECURITY_DESCRIPTOR pSD = NULL;
  162. ULONG cSDSize = 0;
  163. SECURITY_INFORMATION si;
  164. //get everything we can think of
  165. // si = ( DACL_SECURITY_INFORMATION | OWNER_SECURITY_INFORMATION |
  166. // GROUP_SECURITY_INFORMATION | PROTECTED_DACL_SECURITY_INFORMATION |
  167. // PROTECTED_SACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION |
  168. // UNPROTECTED_DACL_SECURITY_INFORMATION | UNPROTECTED_SACL_SECURITY_INFORMATION);
  169. si = ( DACL_SECURITY_INFORMATION | OWNER_SECURITY_INFORMATION |
  170. GROUP_SECURITY_INFORMATION | PROTECTED_DACL_SECURITY_INFORMATION);
  171. Status = DfsReadDSObjSecDesc(
  172. pldap,
  173. pwszObjectName,
  174. si,
  175. &pSD,
  176. &cSDSize);
  177. if(Status == ERROR_SUCCESS)
  178. {
  179. *pSDRet = pSD;
  180. }
  181. return Status;
  182. }
  183. DFSSTATUS
  184. DfsChangeDSObjSecDesc(LDAP * pLDAP,
  185. PWSTR ObjectName,
  186. PSECURITY_DESCRIPTOR pSecurityDescriptor,
  187. SECURITY_INFORMATION SeInfo)
  188. {
  189. DFSSTATUS Status = 0;
  190. PLDAPMod rgMods[2];
  191. PLDAP_BERVAL pBVals[2];
  192. LDAPMod Mod;
  193. LDAP_BERVAL BVal;
  194. BYTE berValue[8];
  195. LDAPControl SeInfoControl =
  196. {
  197. LDAP_SERVER_SD_FLAGS_OID_W,
  198. {
  199. 5, (PCHAR)berValue
  200. },
  201. TRUE
  202. };
  203. PLDAPControl ServerControls[2] =
  204. {
  205. &SeInfoControl,
  206. NULL
  207. };
  208. berValue[0] = 0x30;
  209. berValue[1] = 0x03;
  210. berValue[2] = 0x02;
  211. berValue[3] = 0x01;
  212. berValue[4] = (BYTE)((ULONG)SeInfo & 0xF);
  213. rgMods[0] = &Mod;
  214. rgMods[1] = NULL;
  215. pBVals[0] = &BVal;
  216. pBVals[1] = NULL;
  217. Mod.mod_op = LDAP_MOD_REPLACE | LDAP_MOD_BVALUES;
  218. Mod.mod_type = ACTRL_SD_PROP_NAME;
  219. Mod.mod_values = (PWSTR *)pBVals;
  220. if ( pSecurityDescriptor == NULL )
  221. BVal.bv_len = 0;
  222. else
  223. {
  224. BVal.bv_len = RtlLengthSecurityDescriptor(pSecurityDescriptor);
  225. }
  226. BVal.bv_val = (PCHAR)(pSecurityDescriptor);
  227. Status = ldap_modify_ext_s(pLDAP,
  228. ObjectName,
  229. rgMods,
  230. (PLDAPControl *)ServerControls,
  231. NULL);
  232. return Status;
  233. }
  234. DFSSTATUS
  235. DfsDoesUserHaveDesiredAccessToAd(DWORD DesiredAccess,
  236. PSECURITY_DESCRIPTOR pSD)
  237. {
  238. DFSSTATUS Status = 0;
  239. DWORD dwDesiredAccess = DesiredAccess;
  240. MapGenericMask(&dwDesiredAccess, &DfsAdAdminGenericMapping);
  241. Status = AccessImpersonateCheckRpcClientEx(pSD,
  242. &DfsAdAdminGenericMapping,
  243. dwDesiredAccess);
  244. return Status;
  245. }