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.

300 lines
9.1 KiB

  1. /*++
  2. Copyright (c) 1992 Microsoft Corporation
  3. Module Name:
  4. DomainId.c
  5. Abstract:
  6. This file contains NetpGetLocalDomainId(). This will eventually
  7. replace NetpGetDomainId().
  8. Author:
  9. John Rogers (JohnRo) 06-May-1992
  10. Environment:
  11. Interface is portable to any flat, 32-bit environment. (Uses Win32
  12. typedefs.) Requires ANSI C extensions: slash-slash comments, long
  13. external names. Code itself only runs under NT.
  14. Revision History:
  15. 06-May-1992 JohnRo
  16. Created. (Borrowed most code from DanHi's SDKTools/AddUser/AddUser.c.
  17. 08-May-1992 JohnRo
  18. Use <prefix.h> equates.
  19. 09-Jun-1992 JohnRo
  20. RAID 10139: PortUAS should add to admin group/alias.
  21. --*/
  22. // These must be included first:
  23. #include <nt.h> // IN, LPVOID, etc.
  24. #include <ntsam.h>
  25. #include <ntlsa.h>
  26. #include <ntrtl.h>
  27. #include <nturtl.h> // (Needed for ntrtl.h and windows.h to coexist.)
  28. #include <windows.h> // LocalAlloc(), LMEM_ equates, etc.
  29. #include <lmcons.h> // NET_API_STATUS, needed by <netlibnt.h>
  30. // These may be included in any order:
  31. #include <debuglib.h> // IF_DEBUG().
  32. #include <lmerr.h> // NO_ERROR, ERROR_, and NERR_ equates.
  33. #include <netdebug.h> // NetpAssert, FORMAT_ equates, etc.
  34. #include <netlib.h> // LOCAL_DOMAIN_TYPE, my prototype.
  35. #include <netlibnt.h> // NetpNtStatusToApiStatus().
  36. #include <prefix.h> // PREFIX_ equates.
  37. static SID_IDENTIFIER_AUTHORITY NetpBuiltinIdentifierAuthority
  38. = SECURITY_NT_AUTHORITY;
  39. NET_API_STATUS
  40. NetpGetLocalDomainId (
  41. IN LOCAL_DOMAIN_TYPE TypeWanted,
  42. OUT PSID *RetDomainId
  43. )
  44. /*++
  45. Routine Description:
  46. This routine obtains the domain id from LSA for the local domain.
  47. The routine is a superset of NetpGetDomainId().
  48. Arguments:
  49. TypeWanted - Indicates which type of local domain ID is wanted:
  50. the primary one or the accounts one.
  51. RetDomainId - This is a pointer to the location where the pointer
  52. to the domain id is to be placed. This must be freed via LocalFree().
  53. Return Value:
  54. NERR_Success - If the operation was successful.
  55. It will return assorted Net or Win32 error messages if not.
  56. --*/
  57. {
  58. NET_API_STATUS ApiStatus;
  59. LSA_HANDLE LsaHandle = NULL;
  60. NTSTATUS NtStatus;
  61. LPVOID PolicyInfo = NULL;
  62. DWORD SidSize;
  63. if (RetDomainId == NULL) {
  64. ApiStatus = ERROR_INVALID_PARAMETER;
  65. goto cleanupandexit;
  66. }
  67. *RetDomainId = NULL; // make error paths easy to code.
  68. //
  69. // The type of domain the caller wants determines the information class
  70. // we have to get LSA to deal with. So use one to get the other.
  71. //
  72. switch (TypeWanted) {
  73. case LOCAL_DOMAIN_TYPE_ACCOUNTS : /*FALLTHROUGH*/
  74. case LOCAL_DOMAIN_TYPE_PRIMARY :
  75. {
  76. OBJECT_ATTRIBUTES ObjectAttributes;
  77. POLICY_INFORMATION_CLASS PolicyInfoClass;
  78. LPVOID SourceDomainId;
  79. if (TypeWanted == LOCAL_DOMAIN_TYPE_ACCOUNTS) {
  80. PolicyInfoClass = PolicyAccountDomainInformation;
  81. } else {
  82. PolicyInfoClass = PolicyPrimaryDomainInformation;
  83. }
  84. //
  85. // Get LSA to open its local policy database.
  86. //
  87. InitializeObjectAttributes( &ObjectAttributes, NULL, 0, 0, NULL );
  88. NtStatus = LsaOpenPolicy(
  89. NULL,
  90. &ObjectAttributes,
  91. POLICY_VIEW_LOCAL_INFORMATION,
  92. &LsaHandle);
  93. if ( !NT_SUCCESS(NtStatus)) {
  94. ApiStatus = NetpNtStatusToApiStatus( NtStatus );
  95. IF_DEBUG( DOMAINID ) {
  96. NetpKdPrint((PREFIX_NETLIB "NetpGetLocalDomainId:\n"
  97. " Couldn't _open Lsa Policy database, nt status = "
  98. FORMAT_NTSTATUS "\n", NtStatus));
  99. }
  100. NetpAssert( ApiStatus != NO_ERROR );
  101. goto cleanupandexit;
  102. }
  103. NetpAssert( LsaHandle != NULL );
  104. //
  105. // Get the appropriate domain SID from LSA
  106. //
  107. NtStatus = LsaQueryInformationPolicy(
  108. LsaHandle,
  109. PolicyInfoClass,
  110. &PolicyInfo);
  111. if ( !NT_SUCCESS(NtStatus)) {
  112. ApiStatus = NetpNtStatusToApiStatus( NtStatus );
  113. IF_DEBUG( DOMAINID ) {
  114. NetpKdPrint((PREFIX_NETLIB "NetpGetLocalDomainId:\n"
  115. " Couldn't query Lsa Policy database, nt status = "
  116. FORMAT_NTSTATUS "\n", NtStatus));
  117. }
  118. NetpAssert( ApiStatus != NO_ERROR );
  119. goto cleanupandexit;
  120. }
  121. //
  122. // Find source domain ID in the appropriate structure.
  123. //
  124. if (TypeWanted == LOCAL_DOMAIN_TYPE_ACCOUNTS) {
  125. PPOLICY_ACCOUNT_DOMAIN_INFO PolicyAccountDomainInfo
  126. = PolicyInfo;
  127. SourceDomainId = PolicyAccountDomainInfo->DomainSid;
  128. NetpAssert( SourceDomainId != NULL );
  129. NetpAssert( RtlValidSid( SourceDomainId ) );
  130. } else {
  131. PPOLICY_PRIMARY_DOMAIN_INFO PolicyPrimaryDomainInfo
  132. = PolicyInfo;
  133. NetpAssert( TypeWanted == LOCAL_DOMAIN_TYPE_PRIMARY );
  134. SourceDomainId = PolicyPrimaryDomainInfo->Sid;
  135. if ( SourceDomainId != NULL ) {
  136. NetpAssert( RtlValidSid( SourceDomainId ) );
  137. }
  138. }
  139. //
  140. // If there was a domain ID, copy it now
  141. //
  142. if (SourceDomainId != NULL) {
  143. //
  144. // Compute size and alloc destination SID.
  145. //
  146. NetpAssert( sizeof(ULONG) <= sizeof(DWORD) );
  147. SidSize = (DWORD) RtlLengthSid( SourceDomainId );
  148. NetpAssert( SidSize != 0 );
  149. *RetDomainId = LocalAlloc( LMEM_FIXED, SidSize );
  150. if ( *RetDomainId == NULL ) {
  151. IF_DEBUG( DOMAINID ) {
  152. NetpKdPrint((PREFIX_NETLIB "NetpGetLocalDomainId:\n"
  153. " not enough memory (need " FORMAT_DWORD
  154. ")\n", SidSize));
  155. }
  156. ApiStatus = ERROR_NOT_ENOUGH_MEMORY;
  157. goto cleanupandexit;
  158. }
  159. //
  160. // Copy the SID (domain ID).
  161. //
  162. NtStatus = RtlCopySid(
  163. SidSize, // dest size in bytes
  164. *RetDomainId, // dest sid
  165. SourceDomainId); // src sid
  166. if ( !NT_SUCCESS(NtStatus)) {
  167. ApiStatus = NetpNtStatusToApiStatus( NtStatus );
  168. IF_DEBUG( DOMAINID ) {
  169. NetpKdPrint((PREFIX_NETLIB "NetpGetLocalDomainId:\n"
  170. " RtlCopySid failed, nt status = "
  171. FORMAT_NTSTATUS "\n", NtStatus));
  172. }
  173. NetpAssert( ApiStatus != NO_ERROR );
  174. goto cleanupandexit;
  175. }
  176. NetpAssert( RtlValidSid( SourceDomainId ) );
  177. NetpAssert( RtlEqualSid( SourceDomainId, *RetDomainId ) );
  178. } else {
  179. //
  180. // Just return the NULL domain id.
  181. //
  182. *RetDomainId = NULL;
  183. }
  184. }
  185. break;
  186. case LOCAL_DOMAIN_TYPE_BUILTIN :
  187. #define SUBAUTHORITIES_FOR_BUILTIN_DOMAIN 1
  188. SidSize = (DWORD)
  189. RtlLengthRequiredSid( SUBAUTHORITIES_FOR_BUILTIN_DOMAIN );
  190. NetpAssert( SidSize != 0 );
  191. *RetDomainId = LocalAlloc( LMEM_FIXED, SidSize );
  192. if ( *RetDomainId == NULL ) {
  193. IF_DEBUG( DOMAINID ) {
  194. NetpKdPrint((PREFIX_NETLIB "NetpGetLocalDomainId:\n"
  195. " not enough memory (need " FORMAT_DWORD
  196. ")\n", SidSize));
  197. }
  198. ApiStatus = ERROR_NOT_ENOUGH_MEMORY;
  199. goto cleanupandexit;
  200. }
  201. NtStatus = RtlInitializeSid(
  202. *RetDomainId, // SID being built
  203. &NetpBuiltinIdentifierAuthority, // identifier authority
  204. (UCHAR)SUBAUTHORITIES_FOR_BUILTIN_DOMAIN ); // subauth. count
  205. NetpAssert( NT_SUCCESS( NtStatus ) );
  206. NetpAssert( SUBAUTHORITIES_FOR_BUILTIN_DOMAIN == 1 );
  207. *(RtlSubAuthoritySid(*RetDomainId, 0)) = SECURITY_BUILTIN_DOMAIN_RID;
  208. NetpAssert( RtlValidSid( *RetDomainId ) );
  209. break;
  210. default :
  211. ApiStatus = ERROR_INVALID_PARAMETER;
  212. goto cleanupandexit;
  213. }
  214. ApiStatus = NO_ERROR;
  215. cleanupandexit:
  216. //
  217. // Clean up (either error or success).
  218. //
  219. if (PolicyInfo) {
  220. (VOID) LsaFreeMemory(PolicyInfo);
  221. }
  222. if (LsaHandle) {
  223. (VOID) LsaClose(LsaHandle);
  224. }
  225. if ((ApiStatus!=NO_ERROR) && (RetDomainId!=NULL) && (*RetDomainId!=NULL)) {
  226. (VOID) LocalFree( *RetDomainId );
  227. *RetDomainId = NULL;
  228. }
  229. return (ApiStatus);
  230. }