windows-nt/Source/XPSP1/NT/ds/netapi/netlib/domainid.c
2020-09-26 16:20:57 +08:00

301 lines
9.1 KiB
C

/*++
Copyright (c) 1992 Microsoft Corporation
Module Name:
DomainId.c
Abstract:
This file contains NetpGetLocalDomainId(). This will eventually
replace NetpGetDomainId().
Author:
John Rogers (JohnRo) 06-May-1992
Environment:
Interface is portable to any flat, 32-bit environment. (Uses Win32
typedefs.) Requires ANSI C extensions: slash-slash comments, long
external names. Code itself only runs under NT.
Revision History:
06-May-1992 JohnRo
Created. (Borrowed most code from DanHi's SDKTools/AddUser/AddUser.c.
08-May-1992 JohnRo
Use <prefix.h> equates.
09-Jun-1992 JohnRo
RAID 10139: PortUAS should add to admin group/alias.
--*/
// These must be included first:
#include <nt.h> // IN, LPVOID, etc.
#include <ntsam.h>
#include <ntlsa.h>
#include <ntrtl.h>
#include <nturtl.h> // (Needed for ntrtl.h and windows.h to coexist.)
#include <windows.h> // LocalAlloc(), LMEM_ equates, etc.
#include <lmcons.h> // NET_API_STATUS, needed by <netlibnt.h>
// These may be included in any order:
#include <debuglib.h> // IF_DEBUG().
#include <lmerr.h> // NO_ERROR, ERROR_, and NERR_ equates.
#include <netdebug.h> // NetpAssert, FORMAT_ equates, etc.
#include <netlib.h> // LOCAL_DOMAIN_TYPE, my prototype.
#include <netlibnt.h> // NetpNtStatusToApiStatus().
#include <prefix.h> // PREFIX_ equates.
static SID_IDENTIFIER_AUTHORITY NetpBuiltinIdentifierAuthority
= SECURITY_NT_AUTHORITY;
NET_API_STATUS
NetpGetLocalDomainId (
IN LOCAL_DOMAIN_TYPE TypeWanted,
OUT PSID *RetDomainId
)
/*++
Routine Description:
This routine obtains the domain id from LSA for the local domain.
The routine is a superset of NetpGetDomainId().
Arguments:
TypeWanted - Indicates which type of local domain ID is wanted:
the primary one or the accounts one.
RetDomainId - This is a pointer to the location where the pointer
to the domain id is to be placed. This must be freed via LocalFree().
Return Value:
NERR_Success - If the operation was successful.
It will return assorted Net or Win32 error messages if not.
--*/
{
NET_API_STATUS ApiStatus;
LSA_HANDLE LsaHandle = NULL;
NTSTATUS NtStatus;
LPVOID PolicyInfo = NULL;
DWORD SidSize;
if (RetDomainId == NULL) {
ApiStatus = ERROR_INVALID_PARAMETER;
goto cleanupandexit;
}
*RetDomainId = NULL; // make error paths easy to code.
//
// The type of domain the caller wants determines the information class
// we have to get LSA to deal with. So use one to get the other.
//
switch (TypeWanted) {
case LOCAL_DOMAIN_TYPE_ACCOUNTS : /*FALLTHROUGH*/
case LOCAL_DOMAIN_TYPE_PRIMARY :
{
OBJECT_ATTRIBUTES ObjectAttributes;
POLICY_INFORMATION_CLASS PolicyInfoClass;
LPVOID SourceDomainId;
if (TypeWanted == LOCAL_DOMAIN_TYPE_ACCOUNTS) {
PolicyInfoClass = PolicyAccountDomainInformation;
} else {
PolicyInfoClass = PolicyPrimaryDomainInformation;
}
//
// Get LSA to open its local policy database.
//
InitializeObjectAttributes( &ObjectAttributes, NULL, 0, 0, NULL );
NtStatus = LsaOpenPolicy(
NULL,
&ObjectAttributes,
POLICY_VIEW_LOCAL_INFORMATION,
&LsaHandle);
if ( !NT_SUCCESS(NtStatus)) {
ApiStatus = NetpNtStatusToApiStatus( NtStatus );
IF_DEBUG( DOMAINID ) {
NetpKdPrint((PREFIX_NETLIB "NetpGetLocalDomainId:\n"
" Couldn't _open Lsa Policy database, nt status = "
FORMAT_NTSTATUS "\n", NtStatus));
}
NetpAssert( ApiStatus != NO_ERROR );
goto cleanupandexit;
}
NetpAssert( LsaHandle != NULL );
//
// Get the appropriate domain SID from LSA
//
NtStatus = LsaQueryInformationPolicy(
LsaHandle,
PolicyInfoClass,
&PolicyInfo);
if ( !NT_SUCCESS(NtStatus)) {
ApiStatus = NetpNtStatusToApiStatus( NtStatus );
IF_DEBUG( DOMAINID ) {
NetpKdPrint((PREFIX_NETLIB "NetpGetLocalDomainId:\n"
" Couldn't query Lsa Policy database, nt status = "
FORMAT_NTSTATUS "\n", NtStatus));
}
NetpAssert( ApiStatus != NO_ERROR );
goto cleanupandexit;
}
//
// Find source domain ID in the appropriate structure.
//
if (TypeWanted == LOCAL_DOMAIN_TYPE_ACCOUNTS) {
PPOLICY_ACCOUNT_DOMAIN_INFO PolicyAccountDomainInfo
= PolicyInfo;
SourceDomainId = PolicyAccountDomainInfo->DomainSid;
NetpAssert( SourceDomainId != NULL );
NetpAssert( RtlValidSid( SourceDomainId ) );
} else {
PPOLICY_PRIMARY_DOMAIN_INFO PolicyPrimaryDomainInfo
= PolicyInfo;
NetpAssert( TypeWanted == LOCAL_DOMAIN_TYPE_PRIMARY );
SourceDomainId = PolicyPrimaryDomainInfo->Sid;
if ( SourceDomainId != NULL ) {
NetpAssert( RtlValidSid( SourceDomainId ) );
}
}
//
// If there was a domain ID, copy it now
//
if (SourceDomainId != NULL) {
//
// Compute size and alloc destination SID.
//
NetpAssert( sizeof(ULONG) <= sizeof(DWORD) );
SidSize = (DWORD) RtlLengthSid( SourceDomainId );
NetpAssert( SidSize != 0 );
*RetDomainId = LocalAlloc( LMEM_FIXED, SidSize );
if ( *RetDomainId == NULL ) {
IF_DEBUG( DOMAINID ) {
NetpKdPrint((PREFIX_NETLIB "NetpGetLocalDomainId:\n"
" not enough memory (need " FORMAT_DWORD
")\n", SidSize));
}
ApiStatus = ERROR_NOT_ENOUGH_MEMORY;
goto cleanupandexit;
}
//
// Copy the SID (domain ID).
//
NtStatus = RtlCopySid(
SidSize, // dest size in bytes
*RetDomainId, // dest sid
SourceDomainId); // src sid
if ( !NT_SUCCESS(NtStatus)) {
ApiStatus = NetpNtStatusToApiStatus( NtStatus );
IF_DEBUG( DOMAINID ) {
NetpKdPrint((PREFIX_NETLIB "NetpGetLocalDomainId:\n"
" RtlCopySid failed, nt status = "
FORMAT_NTSTATUS "\n", NtStatus));
}
NetpAssert( ApiStatus != NO_ERROR );
goto cleanupandexit;
}
NetpAssert( RtlValidSid( SourceDomainId ) );
NetpAssert( RtlEqualSid( SourceDomainId, *RetDomainId ) );
} else {
//
// Just return the NULL domain id.
//
*RetDomainId = NULL;
}
}
break;
case LOCAL_DOMAIN_TYPE_BUILTIN :
#define SUBAUTHORITIES_FOR_BUILTIN_DOMAIN 1
SidSize = (DWORD)
RtlLengthRequiredSid( SUBAUTHORITIES_FOR_BUILTIN_DOMAIN );
NetpAssert( SidSize != 0 );
*RetDomainId = LocalAlloc( LMEM_FIXED, SidSize );
if ( *RetDomainId == NULL ) {
IF_DEBUG( DOMAINID ) {
NetpKdPrint((PREFIX_NETLIB "NetpGetLocalDomainId:\n"
" not enough memory (need " FORMAT_DWORD
")\n", SidSize));
}
ApiStatus = ERROR_NOT_ENOUGH_MEMORY;
goto cleanupandexit;
}
NtStatus = RtlInitializeSid(
*RetDomainId, // SID being built
&NetpBuiltinIdentifierAuthority, // identifier authority
(UCHAR)SUBAUTHORITIES_FOR_BUILTIN_DOMAIN ); // subauth. count
NetpAssert( NT_SUCCESS( NtStatus ) );
NetpAssert( SUBAUTHORITIES_FOR_BUILTIN_DOMAIN == 1 );
*(RtlSubAuthoritySid(*RetDomainId, 0)) = SECURITY_BUILTIN_DOMAIN_RID;
NetpAssert( RtlValidSid( *RetDomainId ) );
break;
default :
ApiStatus = ERROR_INVALID_PARAMETER;
goto cleanupandexit;
}
ApiStatus = NO_ERROR;
cleanupandexit:
//
// Clean up (either error or success).
//
if (PolicyInfo) {
(VOID) LsaFreeMemory(PolicyInfo);
}
if (LsaHandle) {
(VOID) LsaClose(LsaHandle);
}
if ((ApiStatus!=NO_ERROR) && (RetDomainId!=NULL) && (*RetDomainId!=NULL)) {
(VOID) LocalFree( *RetDomainId );
*RetDomainId = NULL;
}
return (ApiStatus);
}