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.

323 lines
8.3 KiB

  1. //Copyright (c) 1998 - 1999 Microsoft Corporation
  2. /*--------------------------------------------------------------------------------------------------------
  3. *
  4. * Module Name:
  5. *
  6. * rights.cpp
  7. *
  8. * Abstract:
  9. *
  10. * This file contains code to grant rights to objects.
  11. *
  12. *
  13. * Author:
  14. *
  15. * Makarand Patwardhan - March 6, 1998
  16. *
  17. * Environment:
  18. *
  19. * User Mode
  20. * -------------------------------------------------------------------------------------------------------*/
  21. #include "stdafx.h"
  22. #include <ntsecapi.h>
  23. #include "rights.h"
  24. #define SIZE_SID 1024
  25. #define SIZE_REF_DOMAIN 256
  26. #ifndef STATUS_SUCCESS
  27. #define STATUS_SUCCESS ((NTSTATUS)0x00000000L)
  28. #define STATUS_OBJECT_NAME_NOT_FOUND ((NTSTATUS)0xC0000034L)
  29. #define STATUS_INVALID_SID ((NTSTATUS)0xC0000078L)
  30. #endif
  31. void InitLsaString(PLSA_UNICODE_STRING LsaString, LPWSTR String);
  32. NTSTATUS OpenPolicy(LPWSTR ServerName, DWORD DesiredAccess, PLSA_HANDLE PolicyHandle);
  33. // returns 0 on success.
  34. // returns last error.
  35. DWORD GetAccountSID(LPWSTR wMachineName, LPWSTR wAccountName, PSID pSid, DWORD dwSidSize)
  36. {
  37. ASSERT(wAccountName);
  38. ASSERT(pSid);
  39. ASSERT(dwSidSize > 0);
  40. DWORD dwRefDomainSize = SIZE_REF_DOMAIN;
  41. LPWSTR szRefDomain = (LPWSTR) new WCHAR[dwRefDomainSize];
  42. SID_NAME_USE SidNameUse;
  43. LookupAccountNameW(
  44. wMachineName, // address of string for system name
  45. wAccountName, // address of string for account name
  46. pSid, // address of security identifier
  47. &dwSidSize, // address of size of security identifier
  48. szRefDomain, // address of string for referenced domain
  49. &dwRefDomainSize, // address of size of domain string
  50. &SidNameUse // address of SID-type indicator
  51. );
  52. delete [] szRefDomain;
  53. return GetLastError();
  54. }
  55. DWORD GrantRights(LPWSTR lpMachineName, LPWSTR lpAccountName, LPWSTR lpRightsString, BOOL bAdd)
  56. {
  57. DWORD dwSidSize = SIZE_SID;
  58. PSID pSid = new BYTE[dwSidSize];
  59. DWORD dwError = GetAccountSID(lpMachineName, lpAccountName, pSid, dwSidSize);
  60. if (dwError != ERROR_SUCCESS)
  61. {
  62. LOGMESSAGE1(_T("LookupAccountNameW failed with %lu"), dwError);
  63. }
  64. else
  65. {
  66. ASSERT(IsValidSid(pSid));
  67. LSA_HANDLE PolicyHandle;
  68. // open the policy on the said machine.
  69. dwError = OpenPolicy(
  70. lpMachineName,
  71. POLICY_ALL_ACCESS,
  72. &PolicyHandle
  73. );
  74. if(dwError != STATUS_SUCCESS)
  75. {
  76. LOGMESSAGE1(_T("LookupAccountNameW failed with %lu"), dwError);
  77. return dwError;
  78. }
  79. LSA_UNICODE_STRING lsaString;
  80. InitLsaString(&lsaString, lpRightsString);
  81. if (bAdd)
  82. {
  83. dwError = LsaAddAccountRights(
  84. PolicyHandle,
  85. pSid,
  86. &lsaString,
  87. 1
  88. );
  89. }
  90. else
  91. {
  92. dwError = LsaRemoveAccountRights(
  93. PolicyHandle,
  94. pSid,
  95. FALSE,
  96. &lsaString,
  97. 1
  98. );
  99. }
  100. if(dwError != STATUS_SUCCESS)
  101. {
  102. LOGMESSAGE1(_T("LsaAddAccountRights/LsaRemoveAccountRights failed with %lu"), dwError);
  103. return dwError;
  104. }
  105. LsaClose(PolicyHandle);
  106. }
  107. delete [] pSid;
  108. return dwError;
  109. }
  110. NTSTATUS OpenPolicy(LPWSTR ServerName, DWORD DesiredAccess, PLSA_HANDLE PolicyHandle)
  111. {
  112. LSA_OBJECT_ATTRIBUTES ObjectAttributes;
  113. LSA_UNICODE_STRING ServerString;
  114. PLSA_UNICODE_STRING Server = NULL;
  115. //
  116. // Always initialize the object attributes to all zeroes
  117. //
  118. ZeroMemory(&ObjectAttributes, sizeof(ObjectAttributes));
  119. if(ServerName != NULL) {
  120. //
  121. // Make a LSA_UNICODE_STRING out of the LPWSTR passed in
  122. //
  123. InitLsaString(&ServerString, ServerName);
  124. Server = &ServerString;
  125. }
  126. //
  127. // Attempt to open the policy
  128. //
  129. return LsaOpenPolicy(Server, &ObjectAttributes, DesiredAccess, PolicyHandle);
  130. }
  131. void InitLsaString( PLSA_UNICODE_STRING LsaString, LPWSTR String)
  132. {
  133. if(String == NULL)
  134. {
  135. LsaString->Buffer = NULL;
  136. LsaString->Length = 0;
  137. LsaString->MaximumLength = 0;
  138. return;
  139. }
  140. DWORD StringLength = lstrlenW(String);
  141. LsaString->Buffer = String;
  142. LsaString->Length = (USHORT) (StringLength * sizeof(WCHAR));
  143. LsaString->MaximumLength = (USHORT) ((StringLength + 1) * sizeof(WCHAR));
  144. }
  145. DWORD AddPermissions(LPWSTR wMachineName, LPWSTR wAccountName, PSECURITY_DESCRIPTOR pSecurityDescriptor, DWORD AccessMask)
  146. {
  147. ASSERT( wMachineName );
  148. ASSERT( wAccountName );
  149. ASSERT( pSecurityDescriptor );
  150. ASSERT( IsValidSecurityDescriptor(pSecurityDescriptor) );
  151. DWORD dwSidSize = SIZE_SID;
  152. PSID pSid = new BYTE[dwSidSize];
  153. BOOL bResult = FALSE;
  154. BOOL bAllocatedpDacl = FALSE;
  155. DWORD dwError = GetAccountSID(wMachineName, wAccountName, pSid, dwSidSize);
  156. if (dwError != ERROR_SUCCESS)
  157. {
  158. delete [] pSid;
  159. LOGMESSAGE0(_T("GetAccountSID failed."));
  160. return dwError;
  161. }
  162. BOOL bDaclPresent;
  163. PACL pDacl = NULL;
  164. BOOL bDaclDefaulted;
  165. if (!GetSecurityDescriptorDacl(
  166. pSecurityDescriptor, // address of security descriptor
  167. &bDaclPresent, // address of flag for presence of disc. ACL
  168. &pDacl, // address of pointer to ACL
  169. &bDaclDefaulted // address of flag for default disc. ACL
  170. ))
  171. {
  172. dwError = GetLastError();
  173. delete [] pSid;
  174. LOGMESSAGE0(_T("GetSecurityDescriptorDacl failed."));
  175. return dwError;
  176. }
  177. {
  178. if (bDaclPresent)
  179. {
  180. // there already exists a acl and we have a valid pDacl;
  181. }
  182. else
  183. {
  184. // there was no dacl present, so lets initialize new one ourselves.
  185. bAllocatedpDacl = TRUE;
  186. pDacl = (PACL) new BYTE [1024];
  187. bResult = InitializeAcl(
  188. pDacl, // address of access-control list
  189. 1024, // size of access-control list
  190. ACL_REVISION // revision level of access-control list
  191. );
  192. if (!bResult)
  193. {
  194. LOGMESSAGE0(_T("InitializeAcl failed."));
  195. }
  196. }
  197. if (bResult || bDaclPresent)
  198. {
  199. if (AddAccessAllowedAce(
  200. pDacl, // pointer to access-control list
  201. ACL_REVISION, // ACL revision level
  202. AccessMask, // access mask
  203. pSid // pointer to security identifier
  204. ))
  205. {
  206. if (SetSecurityDescriptorDacl(
  207. pSecurityDescriptor, // address of security descriptor
  208. TRUE, // flag for presence of discretionary ACL
  209. pDacl, // address of discretionary ACL
  210. FALSE // flag for default discretionary ACL
  211. ))
  212. {
  213. }
  214. else
  215. {
  216. LOGMESSAGE0(_T("SetSecurityDescriptorDacl failed."));
  217. }
  218. }
  219. else
  220. {
  221. LOGMESSAGE0(_T("AddAccessAllowedAce failed."));
  222. }
  223. } // bResult || bDaclPresent
  224. } // GetSecurityDescriptorDacl
  225. if (bAllocatedpDacl)
  226. delete [] pDacl;
  227. dwError = GetLastError();
  228. if (dwError != ERROR_SUCCESS)
  229. {
  230. LOGMESSAGE1(_T("LastError = %d"), dwError);
  231. }
  232. delete [] pSid;
  233. return dwError;
  234. }
  235. // AdjustTokenPrivileges
  236. // TOKEN_ADJUST_PRIVILEGES
  237. // LsaAddAccountRights
  238. // #define SE_INTERACTIVE_LOGON_NAME TEXT("SeInteractiveLogonRight")
  239. /*
  240. Article ID: Q145697
  241. Article ID: Q136867
  242. NTSTATUS
  243. NTAPI
  244. LsaOpenPolicy(
  245. IN PLSA_UNICODE_STRING SystemName OPTIONAL,
  246. IN PLSA_OBJECT_ATTRIBUTES ObjectAttributes,
  247. IN ACCESS_MASK DesiredAccess,
  248. IN OUT PLSA_HANDLE PolicyHandle
  249. );
  250. NTSTATUS
  251. NTAPI
  252. LsaAddAccountRights(
  253. IN LSA_HANDLE PolicyHandle,
  254. IN PSID AccountSid,
  255. IN PLSA_UNICODE_STRING UserRights,
  256. IN ULONG CountOfRights
  257. );
  258. // PRIVILEGE_SET
  259. // AdjustTokenPrivileges
  260. */