Beispiel #1
0
static
PSID
AppendRidToSid(PSID SrcSid,
               ULONG Rid)
{
    PSID DstSid = NULL;
    UCHAR RidCount;

    RidCount = *RtlSubAuthorityCountSid(SrcSid);
    if (RidCount >= 8)
        return NULL;

    DstSid = DispatchTable.AllocateLsaHeap(RtlLengthRequiredSid(RidCount + 1));
    if (DstSid == NULL)
        return NULL;

    RtlCopyMemory(DstSid,
                  SrcSid,
                  RtlLengthRequiredSid(RidCount));

    *RtlSubAuthorityCountSid(DstSid) = RidCount + 1;
    *RtlSubAuthoritySid(DstSid, RidCount) = Rid;

    return DstSid;
}
Beispiel #2
0
NTSTATUS
NTAPI
ScCreateWellKnownSids (
    VOID
    )
{
    ULONG i;
    NTSTATUS Status;

    /* Loop the non-domain SIDs */
    for (i = 0; i < RTL_NUMBER_OF(SidData); i++)
    {
        /* Convert our optimized structure into an actual SID */
        Status = ScAllocateAndInitializeSid(&SidData[i].Sid,
                                            &SidData[i].Authority,
                                            1);
        if (!NT_SUCCESS(Status)) break;

        /* Write the correct sub-authority */
        *RtlSubAuthoritySid(SidData[i].Sid, 0) = SidData[i].SubAuthority;
    }

    /* Now loop the domain SIDs  */
    for (i = 0; i < RTL_NUMBER_OF(DomainSidData); i++)
    {
        /* Convert our optimized structure into an actual SID */
        Status = ScDomainIdToSid(BuiltinDomainSid,
                                 DomainSidData[i].SubAuthority,
                                 &DomainSidData[i].Sid);
        if (!NT_SUCCESS(Status)) break;
    }

    /* If we got to the end, return success */
    return (i == RTL_NUMBER_OF(DomainSidData)) ? STATUS_SUCCESS : STATUS_NO_MEMORY;
}
Beispiel #3
0
/*
* ucmShowProcessIntegrityLevel
*
* Purpose:
*
* Output current integrity level of target application.
*
*/
void ucmShowProcessIntegrityLevel(
    VOID
    )
{
    NTSTATUS status;
    HANDLE hToken;

    ULONG LengthNeeded;

    PTOKEN_MANDATORY_LABEL pTIL = NULL;
    DWORD dwIntegrityLevel;
    WCHAR *t = NULL;
    WCHAR szBuffer[MAX_PATH + 1];

    status = NtOpenProcessToken(NtCurrentProcess(), TOKEN_QUERY, &hToken);
    if (NT_SUCCESS(status)) {

        status = NtQueryInformationToken(hToken, TokenIntegrityLevel, NULL, 0, &LengthNeeded);
        if (status == STATUS_BUFFER_TOO_SMALL) {

            pTIL = (PTOKEN_MANDATORY_LABEL)LocalAlloc(0, LengthNeeded);
            if (pTIL) {
                status = NtQueryInformationToken(hToken, TokenIntegrityLevel, pTIL, LengthNeeded, &LengthNeeded);
                if (NT_SUCCESS(status)) {

                    dwIntegrityLevel = *RtlSubAuthoritySid(pTIL->Label.Sid,
                        (DWORD)(UCHAR)(*RtlSubAuthorityCountSid(pTIL->Label.Sid) - 1));

                    if (dwIntegrityLevel == SECURITY_MANDATORY_LOW_RID)
                    {
                        t = L"Low Process";
                    }
                    else if (dwIntegrityLevel >= SECURITY_MANDATORY_MEDIUM_RID &&
                        dwIntegrityLevel < SECURITY_MANDATORY_HIGH_RID)
                    {
                        t = L"Medium Process";
                    }
                    else if (dwIntegrityLevel >= SECURITY_MANDATORY_HIGH_RID)
                    {
                        t = L"High Integrity Process";
                    }
                    else if (dwIntegrityLevel >= SECURITY_MANDATORY_SYSTEM_RID)
                    {
                        t = L"System Integrity Process";
                    }

                    RtlSecureZeroMemory(szBuffer, sizeof(szBuffer));
                    wsprintf(szBuffer, L"PID=%lu, IntegrityLevel=%ws",
                        GetCurrentProcessId(), t);

                }
                LocalFree(pTIL);
            }
        }
        NtClose(hToken);
    }
    if (t) MessageBox(GetDesktopWindow(), szBuffer, GetCommandLineW(), MB_ICONINFORMATION);
}
Beispiel #4
0
BOOLEAN
LsapCreateSid(PSID_IDENTIFIER_AUTHORITY IdentifierAuthority,
              UCHAR SubAuthorityCount,
              PULONG SubAuthorities,
              PWSTR Name,
              PWSTR Domain,
              SID_NAME_USE NameUse)
{
    PWELL_KNOWN_SID SidEntry;
    PULONG p;
    ULONG i;

    SidEntry = RtlAllocateHeap(RtlGetProcessHeap(), 0, sizeof(WELL_KNOWN_SID));
    if (SidEntry == NULL)
        return FALSE;

    InitializeListHead(&SidEntry->ListEntry);

    SidEntry->Sid = RtlAllocateHeap(RtlGetProcessHeap(),
                                    0,
                                    RtlLengthRequiredSid(SubAuthorityCount));
    if (SidEntry->Sid == NULL)
    {
        RtlFreeHeap(RtlGetProcessHeap(), 0, SidEntry);
        return FALSE;
    }

    RtlInitializeSid(SidEntry->Sid,
                     IdentifierAuthority,
                     SubAuthorityCount);

    for (i = 0; i < (ULONG)SubAuthorityCount; i++)
    {
        p = RtlSubAuthoritySid(SidEntry->Sid, i);
        *p = SubAuthorities[i];
    }

    RtlInitUnicodeString(&SidEntry->Name,
                         Name);

    RtlInitUnicodeString(&SidEntry->Domain,
                         Domain);

    SidEntry->NameUse = NameUse;

    InsertTailList(&WellKnownSidListHead,
                   &SidEntry->ListEntry);

    return TRUE;
}
Beispiel #5
0
NTSTATUS
NTAPI
ScDomainIdToSid (
    _In_ PSID SourceSid,
    _In_ ULONG DomainId,
    _Out_ PSID *DestinationSid
    )
{
    ULONG sidCount, sidLength;
    NTSTATUS status;

    /* Get the length of the SID based onthe number of subauthorities */
    sidCount = *RtlSubAuthorityCountSid(SourceSid);
    sidLength = RtlLengthRequiredSid(sidCount + 1);

    /* Allocate it */
    *DestinationSid = RtlAllocateHeap(RtlGetProcessHeap(), 0, sidLength);
    if (*DestinationSid)
    {
        /* Make a copy of it */
        status = RtlCopySid(sidLength, *DestinationSid, SourceSid);
        if (NT_SUCCESS(status))
        {
            /* Increase the subauthority count */
            ++*RtlSubAuthorityCountSid(*DestinationSid);

            /* And add the specific domain RID we're creating */
            *RtlSubAuthoritySid(*DestinationSid, sidCount) = DomainId;

            /* Everything worked */
            status = STATUS_SUCCESS;
        }
        else
        {
            /* The SID copy failed, so free the SID we just allocated */
            RtlFreeHeap(RtlGetProcessHeap(), 0, *DestinationSid);
        }
    }
    else
    {
        /* No space for the SID, bail out */
        status = STATUS_NO_MEMORY;
    }

    /* Return back to the caller */
    return status;
}
Beispiel #6
0
VOID
DisplayAccountSid(
    PSID Sid
    )
{
    UCHAR i;
    ULONG Tmp;
    PSID_IDENTIFIER_AUTHORITY IdentifierAuthority;
    UCHAR SubAuthorityCount;

    IdentifierAuthority = RtlIdentifierAuthoritySid(Sid);

    //
    // HACK! HACK!
    // The next line prints the revision of the SID.  Since there is no
    // rtl routine which gives us the SID revision, we must make due.
    // luckily, the revision field is the first field in the SID, so we
    // can just cast the pointer.
    //

    printf("S-%u-", (USHORT) *((PUCHAR) Sid) );

    if (  (IdentifierAuthority->Value[0] != 0)  ||
          (IdentifierAuthority->Value[1] != 0)     ){
        printf("0x%02hx%02hx%02hx%02hx%02hx%02hx",
                    IdentifierAuthority->Value[0],
                    IdentifierAuthority->Value[1],
                    IdentifierAuthority->Value[2],
                    IdentifierAuthority->Value[3],
                    IdentifierAuthority->Value[4],
                    IdentifierAuthority->Value[5] );
    } else {
        Tmp = IdentifierAuthority->Value[5]          +
              (IdentifierAuthority->Value[4] <<  8)  +
              (IdentifierAuthority->Value[3] << 16)  +
              (IdentifierAuthority->Value[2] << 24);
        printf("%lu", Tmp);
    }

    SubAuthorityCount = *RtlSubAuthorityCountSid(Sid);
    for (i=0;i<SubAuthorityCount ;i++ ) {
        printf("-%lu", (*RtlSubAuthoritySid(Sid, i)));
    }
    printf("\n");
}
Beispiel #7
0
/******************************************************************************
 *  RtlAllocateAndInitializeSid		[NTDLL.@]
 *
 */
BOOLEAN WINAPI RtlAllocateAndInitializeSid (
	PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
	BYTE nSubAuthorityCount,
	DWORD nSubAuthority0, DWORD nSubAuthority1,
	DWORD nSubAuthority2, DWORD nSubAuthority3,
	DWORD nSubAuthority4, DWORD nSubAuthority5,
	DWORD nSubAuthority6, DWORD nSubAuthority7,
	PSID *pSid )
{
	TRACE("(%p, 0x%04x,0x%08lx,0x%08lx,0x%08lx,0x%08lx,0x%08lx,0x%08lx,0x%08lx,0x%08lx,%p)\n",
		pIdentifierAuthority,nSubAuthorityCount,
		nSubAuthority0, nSubAuthority1,	nSubAuthority2, nSubAuthority3,
		nSubAuthority4, nSubAuthority5,	nSubAuthority6, nSubAuthority7, pSid);

	if (!(*pSid = RtlAllocateHeap( GetProcessHeap(), 0, RtlLengthRequiredSid(nSubAuthorityCount))))
	  return FALSE;

	(*pSid)->Revision = SID_REVISION;

	if (pIdentifierAuthority)
	  memcpy(&(*pSid)->IdentifierAuthority, pIdentifierAuthority, sizeof (SID_IDENTIFIER_AUTHORITY));
	*RtlSubAuthorityCountSid(*pSid) = nSubAuthorityCount;

	if (nSubAuthorityCount > 0)
          *RtlSubAuthoritySid(*pSid, 0) = nSubAuthority0;
	if (nSubAuthorityCount > 1)
          *RtlSubAuthoritySid(*pSid, 1) = nSubAuthority1;
	if (nSubAuthorityCount > 2)
          *RtlSubAuthoritySid(*pSid, 2) = nSubAuthority2;
	if (nSubAuthorityCount > 3)
          *RtlSubAuthoritySid(*pSid, 3) = nSubAuthority3;
	if (nSubAuthorityCount > 4)
          *RtlSubAuthoritySid(*pSid, 4) = nSubAuthority4;
	if (nSubAuthorityCount > 5)
          *RtlSubAuthoritySid(*pSid, 5) = nSubAuthority5;
        if (nSubAuthorityCount > 6)
	  *RtlSubAuthoritySid(*pSid, 6) = nSubAuthority6;
	if (nSubAuthorityCount > 7)
          *RtlSubAuthoritySid(*pSid, 7) = nSubAuthority7;

	return STATUS_SUCCESS;
}
Beispiel #8
0
/**************************************************************************
 *                 RtlInitializeSid			[NTDLL.@]
 */
BOOL WINAPI RtlInitializeSid(
	PSID pSid,
	PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
	BYTE nSubAuthorityCount)
{
	int i;
	if (nSubAuthorityCount >= SID_MAX_SUB_AUTHORITIES)
	  return FALSE;

	pSid->Revision = SID_REVISION;
	pSid->SubAuthorityCount = nSubAuthorityCount;
	if (pIdentifierAuthority)
	  memcpy(&pSid->IdentifierAuthority, pIdentifierAuthority, sizeof (SID_IDENTIFIER_AUTHORITY));

	for (i = 0; i < nSubAuthorityCount; i++)
	  *RtlSubAuthoritySid(pSid, i) = 0;

	return TRUE;
}
Beispiel #9
0
BOOLEAN WepCreateServerObjects(
    VOID
    )
{
    OBJECT_ATTRIBUTES objectAttributes;
    WCHAR buffer[256];
    UNICODE_STRING objectName;
    SECURITY_DESCRIPTOR securityDescriptor;
    UCHAR saclBuffer[sizeof(ACL) + FIELD_OFFSET(SYSTEM_MANDATORY_LABEL_ACE, SidStart) + FIELD_OFFSET(SID, SubAuthority) + sizeof(ULONG)];
    PACL sacl;
    UCHAR mandatoryLabelAceBuffer[FIELD_OFFSET(SYSTEM_MANDATORY_LABEL_ACE, SidStart) + FIELD_OFFSET(SID, SubAuthority) + sizeof(ULONG)];
    PSYSTEM_MANDATORY_LABEL_ACE mandatoryLabelAce;
    PSID sid;

    if (!WeServerSharedSection)
    {
        LARGE_INTEGER maximumSize;

        WeFormatLocalObjectName(WE_SERVER_SHARED_SECTION_NAME, buffer, &objectName);
        InitializeObjectAttributes(&objectAttributes, &objectName, OBJ_CASE_INSENSITIVE, NULL, NULL);
        maximumSize.QuadPart = sizeof(WE_HOOK_SHARED_DATA);

        if (!NT_SUCCESS(NtCreateSection(
            &WeServerSharedSection,
            SECTION_ALL_ACCESS,
            &objectAttributes,
            &maximumSize,
            PAGE_READWRITE,
            SEC_COMMIT,
            NULL
            )))
        {
            return FALSE;
        }
    }

    if (!WeServerSharedData)
    {
        PVOID viewBase;
        SIZE_T viewSize;

        viewBase = NULL;
        viewSize = sizeof(WE_HOOK_SHARED_DATA);

        if (!NT_SUCCESS(NtMapViewOfSection(
            WeServerSharedSection,
            NtCurrentProcess(),
            &viewBase,
            0,
            0,
            NULL,
            &viewSize,
            ViewShare,
            0,
            PAGE_READWRITE
            )))
        {
            WepCloseServerObjects();
            return FALSE;
        }

        WeServerSharedData = viewBase;
    }

    if (!WeServerSharedSectionLock)
    {
        WeFormatLocalObjectName(WE_SERVER_SHARED_SECTION_LOCK_NAME, buffer, &objectName);
        InitializeObjectAttributes(&objectAttributes, &objectName, OBJ_CASE_INSENSITIVE, NULL, NULL);

        if (!NT_SUCCESS(NtCreateMutant(
            &WeServerSharedSectionLock,
            MUTANT_ALL_ACCESS,
            &objectAttributes,
            FALSE
            )))
        {
            WepCloseServerObjects();
            return FALSE;
        }
    }

    if (!WeServerSharedSectionEvent)
    {
        WeFormatLocalObjectName(WE_SERVER_SHARED_SECTION_EVENT_NAME, buffer, &objectName);
        InitializeObjectAttributes(&objectAttributes, &objectName, OBJ_CASE_INSENSITIVE, NULL, NULL);

        if (!NT_SUCCESS(NtCreateEvent(
            &WeServerSharedSectionEvent,
            EVENT_ALL_ACCESS,
            &objectAttributes,
            NotificationEvent,
            FALSE
            )))
        {
            WepCloseServerObjects();
            return FALSE;
        }
    }

    // If mandatory labels are supported, set it to the lowest possible level.
    if (WE_WindowsVersion >= WINDOWS_VISTA)
    {
        static SID_IDENTIFIER_AUTHORITY mandatoryLabelAuthority = SECURITY_MANDATORY_LABEL_AUTHORITY;

        RtlCreateSecurityDescriptor(&securityDescriptor, SECURITY_DESCRIPTOR_REVISION);

        sacl = (PACL)saclBuffer;
        RtlCreateAcl(sacl, sizeof(saclBuffer), ACL_REVISION);

        mandatoryLabelAce = (PSYSTEM_MANDATORY_LABEL_ACE)mandatoryLabelAceBuffer;
        mandatoryLabelAce->Header.AceType = SYSTEM_MANDATORY_LABEL_ACE_TYPE;
        mandatoryLabelAce->Header.AceFlags = 0;
        mandatoryLabelAce->Header.AceSize = sizeof(mandatoryLabelAceBuffer);
        mandatoryLabelAce->Mask = SYSTEM_MANDATORY_LABEL_NO_WRITE_UP;

        sid = (PSID)&mandatoryLabelAce->SidStart;
        RtlInitializeSid(sid, &mandatoryLabelAuthority, 1);
        *RtlSubAuthoritySid(sid, 0) = SECURITY_MANDATORY_LOW_RID;

        if (NT_SUCCESS(RtlAddAce(sacl, ACL_REVISION, MAXULONG32, mandatoryLabelAce, sizeof(mandatoryLabelAceBuffer))))
        {
            if (NT_SUCCESS(RtlSetSaclSecurityDescriptor(&securityDescriptor, TRUE, sacl, FALSE)))
            {
                NtSetSecurityObject(WeServerSharedSection, LABEL_SECURITY_INFORMATION, &securityDescriptor);
                NtSetSecurityObject(WeServerSharedSectionLock, LABEL_SECURITY_INFORMATION, &securityDescriptor);
                NtSetSecurityObject(WeServerSharedSectionEvent, LABEL_SECURITY_INFORMATION, &securityDescriptor);
            }
        }
    }

    return TRUE;
}
Beispiel #10
0
NTSTATUS PhSvcApiPortInitialization(
    _In_ PUNICODE_STRING PortName
    )
{
    static SID_IDENTIFIER_AUTHORITY ntAuthority = SECURITY_NT_AUTHORITY;

    NTSTATUS status;
    OBJECT_ATTRIBUTES objectAttributes;
    PSECURITY_DESCRIPTOR securityDescriptor;
    ULONG sdAllocationLength;
    UCHAR administratorsSidBuffer[FIELD_OFFSET(SID, SubAuthority) + sizeof(ULONG) * 2];
    PSID administratorsSid;
    PACL dacl;
    ULONG i;

    // Create the API port.

    administratorsSid = (PSID)administratorsSidBuffer;
    RtlInitializeSid(administratorsSid, &ntAuthority, 2);
    *RtlSubAuthoritySid(administratorsSid, 0) = SECURITY_BUILTIN_DOMAIN_RID;
    *RtlSubAuthoritySid(administratorsSid, 1) = DOMAIN_ALIAS_RID_ADMINS;

    sdAllocationLength = SECURITY_DESCRIPTOR_MIN_LENGTH +
        (ULONG)sizeof(ACL) +
        (ULONG)sizeof(ACCESS_ALLOWED_ACE) +
        RtlLengthSid(administratorsSid) +
        (ULONG)sizeof(ACCESS_ALLOWED_ACE) +
        RtlLengthSid(&PhSeEveryoneSid);

    securityDescriptor = PhAllocate(sdAllocationLength);
    dacl = (PACL)PTR_ADD_OFFSET(securityDescriptor, SECURITY_DESCRIPTOR_MIN_LENGTH);

    RtlCreateSecurityDescriptor(securityDescriptor, SECURITY_DESCRIPTOR_REVISION);
    RtlCreateAcl(dacl, sdAllocationLength - SECURITY_DESCRIPTOR_MIN_LENGTH, ACL_REVISION);
    RtlAddAccessAllowedAce(dacl, ACL_REVISION, PORT_ALL_ACCESS, administratorsSid);
    RtlAddAccessAllowedAce(dacl, ACL_REVISION, PORT_CONNECT, &PhSeEveryoneSid);
    RtlSetDaclSecurityDescriptor(securityDescriptor, TRUE, dacl, FALSE);

    InitializeObjectAttributes(
        &objectAttributes,
        PortName,
        OBJ_CASE_INSENSITIVE,
        NULL,
        securityDescriptor
        );

    status = NtCreatePort(
        &PhSvcApiPortHandle,
        &objectAttributes,
        sizeof(PHSVC_API_CONNECTINFO),
        PhIsExecutingInWow64() ? sizeof(PHSVC_API_MSG64) : sizeof(PHSVC_API_MSG),
        0
        );
    PhFree(securityDescriptor);

    if (!NT_SUCCESS(status))
        return status;

    // Start the API threads.

    PhSvcApiThreadContextTlsIndex = TlsAlloc();

    for (i = 0; i < 2; i++)
    {
        PhCreateThread2(PhSvcApiRequestThreadStart, NULL);
    }

    return status;
}
Beispiel #11
0
BOOLEAN
SepVariableInitialization()
/*++

Routine Description:

    This function initializes the global variables used by and exposed
    by security.

Arguments:

    None.

Return Value:

    TRUE if variables successfully initialized.
    FALSE if not successfully initialized.

--*/
{

    ULONG SidWithZeroSubAuthorities;
    ULONG SidWithOneSubAuthority;
    ULONG SidWithTwoSubAuthorities;
    ULONG SidWithThreeSubAuthorities;

    SID_IDENTIFIER_AUTHORITY NullSidAuthority;
    SID_IDENTIFIER_AUTHORITY WorldSidAuthority;
    SID_IDENTIFIER_AUTHORITY LocalSidAuthority;
    SID_IDENTIFIER_AUTHORITY CreatorSidAuthority;
    SID_IDENTIFIER_AUTHORITY SeNtAuthority;

    PAGED_CODE();

    NullSidAuthority         = SepNullSidAuthority;
    WorldSidAuthority        = SepWorldSidAuthority;
    LocalSidAuthority        = SepLocalSidAuthority;
    CreatorSidAuthority      = SepCreatorSidAuthority;
    SeNtAuthority            = SepNtAuthority;


    //
    //  The following SID sizes need to be allocated
    //

    SidWithZeroSubAuthorities  = RtlLengthRequiredSid( 0 );
    SidWithOneSubAuthority     = RtlLengthRequiredSid( 1 );
    SidWithTwoSubAuthorities   = RtlLengthRequiredSid( 2 );
    SidWithThreeSubAuthorities = RtlLengthRequiredSid( 3 );

    //
    //  Allocate and initialize the universal SIDs
    //

    SeNullSid         = (PSID)ExAllocatePoolWithTag(PagedPool | POOL_RAISE_IF_ALLOCATION_FAILURE,SidWithOneSubAuthority,'iSeS');
    SeWorldSid        = (PSID)ExAllocatePoolWithTag(PagedPool | POOL_RAISE_IF_ALLOCATION_FAILURE,SidWithOneSubAuthority,'iSeS');
    SeLocalSid        = (PSID)ExAllocatePoolWithTag(PagedPool | POOL_RAISE_IF_ALLOCATION_FAILURE,SidWithOneSubAuthority,'iSeS');
    SeCreatorOwnerSid = (PSID)ExAllocatePoolWithTag(PagedPool | POOL_RAISE_IF_ALLOCATION_FAILURE,SidWithOneSubAuthority,'iSeS');
    SeCreatorGroupSid = (PSID)ExAllocatePoolWithTag(PagedPool | POOL_RAISE_IF_ALLOCATION_FAILURE,SidWithOneSubAuthority,'iSeS');
    SeCreatorOwnerServerSid = (PSID)ExAllocatePoolWithTag(PagedPool | POOL_RAISE_IF_ALLOCATION_FAILURE,SidWithOneSubAuthority,'iSeS');
    SeCreatorGroupServerSid = (PSID)ExAllocatePoolWithTag(PagedPool | POOL_RAISE_IF_ALLOCATION_FAILURE,SidWithOneSubAuthority,'iSeS');

    //
    // Fail initialization if we didn't get enough memory for the universal
    // SIDs.
    //

    if ( (SeNullSid         == NULL)        ||
         (SeWorldSid        == NULL)        ||
         (SeLocalSid        == NULL)        ||
         (SeCreatorOwnerSid == NULL)        ||
         (SeCreatorGroupSid == NULL)        ||
         (SeCreatorOwnerServerSid == NULL ) ||
         (SeCreatorGroupServerSid == NULL )
       ) {

        return( FALSE );
    }

    RtlInitializeSid( SeNullSid,         &NullSidAuthority, 1 );
    RtlInitializeSid( SeWorldSid,        &WorldSidAuthority, 1 );
    RtlInitializeSid( SeLocalSid,        &LocalSidAuthority, 1 );
    RtlInitializeSid( SeCreatorOwnerSid, &CreatorSidAuthority, 1 );
    RtlInitializeSid( SeCreatorGroupSid, &CreatorSidAuthority, 1 );
    RtlInitializeSid( SeCreatorOwnerServerSid, &CreatorSidAuthority, 1 );
    RtlInitializeSid( SeCreatorGroupServerSid, &CreatorSidAuthority, 1 );

    *(RtlSubAuthoritySid( SeNullSid, 0 ))         = SECURITY_NULL_RID;
    *(RtlSubAuthoritySid( SeWorldSid, 0 ))        = SECURITY_WORLD_RID;
    *(RtlSubAuthoritySid( SeLocalSid, 0 ))        = SECURITY_LOCAL_RID;
    *(RtlSubAuthoritySid( SeCreatorOwnerSid, 0 )) = SECURITY_CREATOR_OWNER_RID;
    *(RtlSubAuthoritySid( SeCreatorGroupSid, 0 )) = SECURITY_CREATOR_GROUP_RID;
    *(RtlSubAuthoritySid( SeCreatorOwnerServerSid, 0 )) = SECURITY_CREATOR_OWNER_SERVER_RID;
    *(RtlSubAuthoritySid( SeCreatorGroupServerSid, 0 )) = SECURITY_CREATOR_GROUP_SERVER_RID;

    //
    // Allocate and initialize the NT defined SIDs
    //

    SeNtAuthoritySid  = (PSID)ExAllocatePoolWithTag(PagedPool | POOL_RAISE_IF_ALLOCATION_FAILURE,SidWithZeroSubAuthorities,'iSeS');
    SeDialupSid       = (PSID)ExAllocatePoolWithTag(PagedPool | POOL_RAISE_IF_ALLOCATION_FAILURE,SidWithOneSubAuthority,'iSeS');
    SeNetworkSid      = (PSID)ExAllocatePoolWithTag(PagedPool | POOL_RAISE_IF_ALLOCATION_FAILURE,SidWithOneSubAuthority,'iSeS');
    SeBatchSid        = (PSID)ExAllocatePoolWithTag(PagedPool | POOL_RAISE_IF_ALLOCATION_FAILURE,SidWithOneSubAuthority,'iSeS');
    SeInteractiveSid  = (PSID)ExAllocatePoolWithTag(PagedPool | POOL_RAISE_IF_ALLOCATION_FAILURE,SidWithOneSubAuthority,'iSeS');
    SeServiceSid      = (PSID)ExAllocatePoolWithTag(PagedPool | POOL_RAISE_IF_ALLOCATION_FAILURE,SidWithOneSubAuthority,'iSeS');
    SePrincipalSelfSid = (PSID)ExAllocatePoolWithTag(PagedPool | POOL_RAISE_IF_ALLOCATION_FAILURE,SidWithOneSubAuthority,'iSeS');
    SeLocalSystemSid  = (PSID)ExAllocatePoolWithTag(PagedPool | POOL_RAISE_IF_ALLOCATION_FAILURE,SidWithOneSubAuthority,'iSeS');
    SeAuthenticatedUsersSid  = (PSID)ExAllocatePoolWithTag(PagedPool | POOL_RAISE_IF_ALLOCATION_FAILURE,SidWithOneSubAuthority,'iSeS');
    SeRestrictedSid   = (PSID)ExAllocatePoolWithTag(PagedPool | POOL_RAISE_IF_ALLOCATION_FAILURE,SidWithOneSubAuthority,'iSeS');
    SeAnonymousLogonSid = (PSID)ExAllocatePoolWithTag(PagedPool | POOL_RAISE_IF_ALLOCATION_FAILURE,SidWithOneSubAuthority,'iSeS');
    SeLocalServiceSid = (PSID)ExAllocatePoolWithTag(PagedPool | POOL_RAISE_IF_ALLOCATION_FAILURE,SidWithOneSubAuthority,'iSeS');
    SeNetworkServiceSid = (PSID)ExAllocatePoolWithTag(PagedPool | POOL_RAISE_IF_ALLOCATION_FAILURE,SidWithOneSubAuthority,'iSeS');

    SeAliasAdminsSid     = (PSID)ExAllocatePoolWithTag(PagedPool | POOL_RAISE_IF_ALLOCATION_FAILURE,SidWithTwoSubAuthorities,'iSeS');
    SeAliasUsersSid      = (PSID)ExAllocatePoolWithTag(PagedPool | POOL_RAISE_IF_ALLOCATION_FAILURE,SidWithTwoSubAuthorities,'iSeS');
    SeAliasGuestsSid     = (PSID)ExAllocatePoolWithTag(PagedPool | POOL_RAISE_IF_ALLOCATION_FAILURE,SidWithTwoSubAuthorities,'iSeS');
    SeAliasPowerUsersSid = (PSID)ExAllocatePoolWithTag(PagedPool | POOL_RAISE_IF_ALLOCATION_FAILURE,SidWithTwoSubAuthorities,'iSeS');
    SeAliasAccountOpsSid = (PSID)ExAllocatePoolWithTag(PagedPool | POOL_RAISE_IF_ALLOCATION_FAILURE,SidWithTwoSubAuthorities,'iSeS');
    SeAliasSystemOpsSid  = (PSID)ExAllocatePoolWithTag(PagedPool | POOL_RAISE_IF_ALLOCATION_FAILURE,SidWithTwoSubAuthorities,'iSeS');
    SeAliasPrintOpsSid   = (PSID)ExAllocatePoolWithTag(PagedPool | POOL_RAISE_IF_ALLOCATION_FAILURE,SidWithTwoSubAuthorities,'iSeS');
    SeAliasBackupOpsSid  = (PSID)ExAllocatePoolWithTag(PagedPool | POOL_RAISE_IF_ALLOCATION_FAILURE,SidWithTwoSubAuthorities,'iSeS');

    //
    // Fail initialization if we didn't get enough memory for the NT SIDs.
    //

    if ( (SeNtAuthoritySid          == NULL) ||
         (SeDialupSid               == NULL) ||
         (SeNetworkSid              == NULL) ||
         (SeBatchSid                == NULL) ||
         (SeInteractiveSid          == NULL) ||
         (SeServiceSid              == NULL) ||
         (SePrincipalSelfSid        == NULL) ||
         (SeLocalSystemSid          == NULL) ||
         (SeAuthenticatedUsersSid   == NULL) ||
         (SeRestrictedSid           == NULL) ||
         (SeAnonymousLogonSid       == NULL) ||
         (SeLocalServiceSid         == NULL) ||
         (SeNetworkServiceSid       == NULL) ||
         (SeAliasAdminsSid          == NULL) ||
         (SeAliasUsersSid           == NULL) ||
         (SeAliasGuestsSid          == NULL) ||
         (SeAliasPowerUsersSid      == NULL) ||
         (SeAliasAccountOpsSid      == NULL) ||
         (SeAliasSystemOpsSid       == NULL) ||
         (SeAliasPrintOpsSid        == NULL) ||
         (SeAliasBackupOpsSid       == NULL)
       ) {

        return( FALSE );
    }

    RtlInitializeSid( SeNtAuthoritySid,         &SeNtAuthority, 0 );
    RtlInitializeSid( SeDialupSid,              &SeNtAuthority, 1 );
    RtlInitializeSid( SeNetworkSid,             &SeNtAuthority, 1 );
    RtlInitializeSid( SeBatchSid,               &SeNtAuthority, 1 );
    RtlInitializeSid( SeInteractiveSid,         &SeNtAuthority, 1 );
    RtlInitializeSid( SeServiceSid,             &SeNtAuthority, 1 );
    RtlInitializeSid( SePrincipalSelfSid,       &SeNtAuthority, 1 );
    RtlInitializeSid( SeLocalSystemSid,         &SeNtAuthority, 1 );
    RtlInitializeSid( SeAuthenticatedUsersSid,  &SeNtAuthority, 1 );
    RtlInitializeSid( SeRestrictedSid,          &SeNtAuthority, 1 );
    RtlInitializeSid( SeAnonymousLogonSid,      &SeNtAuthority, 1 );
    RtlInitializeSid( SeLocalServiceSid,        &SeNtAuthority, 1 );
    RtlInitializeSid( SeNetworkServiceSid,      &SeNtAuthority, 1 );

    RtlInitializeSid( SeAliasAdminsSid,     &SeNtAuthority, 2);
    RtlInitializeSid( SeAliasUsersSid,      &SeNtAuthority, 2);
    RtlInitializeSid( SeAliasGuestsSid,     &SeNtAuthority, 2);
    RtlInitializeSid( SeAliasPowerUsersSid, &SeNtAuthority, 2);
    RtlInitializeSid( SeAliasAccountOpsSid, &SeNtAuthority, 2);
    RtlInitializeSid( SeAliasSystemOpsSid,  &SeNtAuthority, 2);
    RtlInitializeSid( SeAliasPrintOpsSid,   &SeNtAuthority, 2);
    RtlInitializeSid( SeAliasBackupOpsSid,  &SeNtAuthority, 2);

    *(RtlSubAuthoritySid( SeDialupSid,              0 )) = SECURITY_DIALUP_RID;
    *(RtlSubAuthoritySid( SeNetworkSid,             0 )) = SECURITY_NETWORK_RID;
    *(RtlSubAuthoritySid( SeBatchSid,               0 )) = SECURITY_BATCH_RID;
    *(RtlSubAuthoritySid( SeInteractiveSid,         0 )) = SECURITY_INTERACTIVE_RID;
    *(RtlSubAuthoritySid( SeServiceSid,             0 )) = SECURITY_SERVICE_RID;
    *(RtlSubAuthoritySid( SePrincipalSelfSid,       0 )) = SECURITY_PRINCIPAL_SELF_RID;
    *(RtlSubAuthoritySid( SeLocalSystemSid,         0 )) = SECURITY_LOCAL_SYSTEM_RID;
    *(RtlSubAuthoritySid( SeAuthenticatedUsersSid,  0 )) = SECURITY_AUTHENTICATED_USER_RID;
    *(RtlSubAuthoritySid( SeRestrictedSid,          0 )) = SECURITY_RESTRICTED_CODE_RID;
    *(RtlSubAuthoritySid( SeAnonymousLogonSid,      0 )) = SECURITY_ANONYMOUS_LOGON_RID;
    *(RtlSubAuthoritySid( SeLocalServiceSid,        0 )) = SECURITY_LOCAL_SERVICE_RID;
    *(RtlSubAuthoritySid( SeNetworkServiceSid,      0 )) = SECURITY_NETWORK_SERVICE_RID;


    *(RtlSubAuthoritySid( SeAliasAdminsSid,     0 )) = SECURITY_BUILTIN_DOMAIN_RID;
    *(RtlSubAuthoritySid( SeAliasUsersSid,      0 )) = SECURITY_BUILTIN_DOMAIN_RID;
    *(RtlSubAuthoritySid( SeAliasGuestsSid,     0 )) = SECURITY_BUILTIN_DOMAIN_RID;
    *(RtlSubAuthoritySid( SeAliasPowerUsersSid, 0 )) = SECURITY_BUILTIN_DOMAIN_RID;
    *(RtlSubAuthoritySid( SeAliasAccountOpsSid, 0 )) = SECURITY_BUILTIN_DOMAIN_RID;
    *(RtlSubAuthoritySid( SeAliasSystemOpsSid,  0 )) = SECURITY_BUILTIN_DOMAIN_RID;
    *(RtlSubAuthoritySid( SeAliasPrintOpsSid,   0 )) = SECURITY_BUILTIN_DOMAIN_RID;
    *(RtlSubAuthoritySid( SeAliasBackupOpsSid,  0 )) = SECURITY_BUILTIN_DOMAIN_RID;

    *(RtlSubAuthoritySid( SeAliasAdminsSid,     1 )) = DOMAIN_ALIAS_RID_ADMINS;
    *(RtlSubAuthoritySid( SeAliasUsersSid,      1 )) = DOMAIN_ALIAS_RID_USERS;
    *(RtlSubAuthoritySid( SeAliasGuestsSid,     1 )) = DOMAIN_ALIAS_RID_GUESTS;
    *(RtlSubAuthoritySid( SeAliasPowerUsersSid, 1 )) = DOMAIN_ALIAS_RID_POWER_USERS;
    *(RtlSubAuthoritySid( SeAliasAccountOpsSid, 1 )) = DOMAIN_ALIAS_RID_ACCOUNT_OPS;
    *(RtlSubAuthoritySid( SeAliasSystemOpsSid,  1 )) = DOMAIN_ALIAS_RID_SYSTEM_OPS;
    *(RtlSubAuthoritySid( SeAliasPrintOpsSid,   1 )) = DOMAIN_ALIAS_RID_PRINT_OPS;
    *(RtlSubAuthoritySid( SeAliasBackupOpsSid,  1 )) = DOMAIN_ALIAS_RID_BACKUP_OPS;



    //
    // Initialize system default dacl
    //

    SepInitSystemDacls();


    //
    // Initialize the well known privilege values
    //

    SeCreateTokenPrivilege =
        RtlConvertLongToLuid(SE_CREATE_TOKEN_PRIVILEGE);
    SeAssignPrimaryTokenPrivilege =
        RtlConvertLongToLuid(SE_ASSIGNPRIMARYTOKEN_PRIVILEGE);
    SeLockMemoryPrivilege =
        RtlConvertLongToLuid(SE_LOCK_MEMORY_PRIVILEGE);
    SeIncreaseQuotaPrivilege =
        RtlConvertLongToLuid(SE_INCREASE_QUOTA_PRIVILEGE);
    SeUnsolicitedInputPrivilege =
        RtlConvertLongToLuid(SE_UNSOLICITED_INPUT_PRIVILEGE);
    SeTcbPrivilege =
        RtlConvertLongToLuid(SE_TCB_PRIVILEGE);
    SeSecurityPrivilege =
        RtlConvertLongToLuid(SE_SECURITY_PRIVILEGE);
    SeTakeOwnershipPrivilege =
        RtlConvertLongToLuid(SE_TAKE_OWNERSHIP_PRIVILEGE);
    SeLoadDriverPrivilege =
        RtlConvertLongToLuid(SE_LOAD_DRIVER_PRIVILEGE);
    SeCreatePagefilePrivilege =
        RtlConvertLongToLuid(SE_CREATE_PAGEFILE_PRIVILEGE);
    SeIncreaseBasePriorityPrivilege =
        RtlConvertLongToLuid(SE_INC_BASE_PRIORITY_PRIVILEGE);
    SeSystemProfilePrivilege =
        RtlConvertLongToLuid(SE_SYSTEM_PROFILE_PRIVILEGE);
    SeSystemtimePrivilege =
        RtlConvertLongToLuid(SE_SYSTEMTIME_PRIVILEGE);
    SeProfileSingleProcessPrivilege =
        RtlConvertLongToLuid(SE_PROF_SINGLE_PROCESS_PRIVILEGE);
    SeCreatePermanentPrivilege =
        RtlConvertLongToLuid(SE_CREATE_PERMANENT_PRIVILEGE);
    SeBackupPrivilege =
        RtlConvertLongToLuid(SE_BACKUP_PRIVILEGE);
    SeRestorePrivilege =
        RtlConvertLongToLuid(SE_RESTORE_PRIVILEGE);
    SeShutdownPrivilege =
        RtlConvertLongToLuid(SE_SHUTDOWN_PRIVILEGE);
    SeDebugPrivilege =
        RtlConvertLongToLuid(SE_DEBUG_PRIVILEGE);
    SeAuditPrivilege =
        RtlConvertLongToLuid(SE_AUDIT_PRIVILEGE);
    SeSystemEnvironmentPrivilege =
        RtlConvertLongToLuid(SE_SYSTEM_ENVIRONMENT_PRIVILEGE);
    SeChangeNotifyPrivilege =
        RtlConvertLongToLuid(SE_CHANGE_NOTIFY_PRIVILEGE);
    SeRemoteShutdownPrivilege =
        RtlConvertLongToLuid(SE_REMOTE_SHUTDOWN_PRIVILEGE);
    SeUndockPrivilege =
        RtlConvertLongToLuid(SE_UNDOCK_PRIVILEGE);
    SeSyncAgentPrivilege =
        RtlConvertLongToLuid(SE_SYNC_AGENT_PRIVILEGE);
    SeEnableDelegationPrivilege =
        RtlConvertLongToLuid(SE_ENABLE_DELEGATION_PRIVILEGE);
    SeManageVolumePrivilege =
        RtlConvertLongToLuid(SE_MANAGE_VOLUME_PRIVILEGE);
    SeImpersonatePrivilege = 
        RtlConvertLongToLuid(SE_IMPERSONATE_PRIVILEGE);
    SeCreateGlobalPrivilege =
        RtlConvertLongToLuid(SE_CREATE_GLOBAL_PRIVILEGE);


    //
    // Initialize the SeExports structure for exporting all
    // of the information we've created out of the kernel.
    //

    //
    // Package these together for export
    //


    SepExports.SeNullSid         = SeNullSid;
    SepExports.SeWorldSid        = SeWorldSid;
    SepExports.SeLocalSid        = SeLocalSid;
    SepExports.SeCreatorOwnerSid = SeCreatorOwnerSid;
    SepExports.SeCreatorGroupSid = SeCreatorGroupSid;


    SepExports.SeNtAuthoritySid         = SeNtAuthoritySid;
    SepExports.SeDialupSid              = SeDialupSid;
    SepExports.SeNetworkSid             = SeNetworkSid;
    SepExports.SeBatchSid               = SeBatchSid;
    SepExports.SeInteractiveSid         = SeInteractiveSid;
    SepExports.SeLocalSystemSid         = SeLocalSystemSid;
    SepExports.SeAuthenticatedUsersSid  = SeAuthenticatedUsersSid;
    SepExports.SeRestrictedSid          = SeRestrictedSid;
    SepExports.SeAnonymousLogonSid      = SeAnonymousLogonSid;
    SepExports.SeLocalServiceSid        = SeLocalServiceSid;
    SepExports.SeNetworkServiceSid      = SeNetworkServiceSid;
    SepExports.SeAliasAdminsSid         = SeAliasAdminsSid;
    SepExports.SeAliasUsersSid          = SeAliasUsersSid;
    SepExports.SeAliasGuestsSid         = SeAliasGuestsSid;
    SepExports.SeAliasPowerUsersSid     = SeAliasPowerUsersSid;
    SepExports.SeAliasAccountOpsSid     = SeAliasAccountOpsSid;
    SepExports.SeAliasSystemOpsSid      = SeAliasSystemOpsSid;
    SepExports.SeAliasPrintOpsSid       = SeAliasPrintOpsSid;
    SepExports.SeAliasBackupOpsSid      = SeAliasBackupOpsSid;



    SepExports.SeCreateTokenPrivilege          = SeCreateTokenPrivilege;
    SepExports.SeAssignPrimaryTokenPrivilege   = SeAssignPrimaryTokenPrivilege;
    SepExports.SeLockMemoryPrivilege           = SeLockMemoryPrivilege;
    SepExports.SeIncreaseQuotaPrivilege        = SeIncreaseQuotaPrivilege;
    SepExports.SeUnsolicitedInputPrivilege     = SeUnsolicitedInputPrivilege;
    SepExports.SeTcbPrivilege                  = SeTcbPrivilege;
    SepExports.SeSecurityPrivilege             = SeSecurityPrivilege;
    SepExports.SeTakeOwnershipPrivilege        = SeTakeOwnershipPrivilege;
    SepExports.SeLoadDriverPrivilege           = SeLoadDriverPrivilege;
    SepExports.SeCreatePagefilePrivilege       = SeCreatePagefilePrivilege;
    SepExports.SeIncreaseBasePriorityPrivilege = SeIncreaseBasePriorityPrivilege;
    SepExports.SeSystemProfilePrivilege        = SeSystemProfilePrivilege;
    SepExports.SeSystemtimePrivilege           = SeSystemtimePrivilege;
    SepExports.SeProfileSingleProcessPrivilege = SeProfileSingleProcessPrivilege;
    SepExports.SeCreatePermanentPrivilege      = SeCreatePermanentPrivilege;
    SepExports.SeBackupPrivilege               = SeBackupPrivilege;
    SepExports.SeRestorePrivilege              = SeRestorePrivilege;
    SepExports.SeShutdownPrivilege             = SeShutdownPrivilege;
    SepExports.SeDebugPrivilege                = SeDebugPrivilege;
    SepExports.SeAuditPrivilege                = SeAuditPrivilege;
    SepExports.SeSystemEnvironmentPrivilege    = SeSystemEnvironmentPrivilege;
    SepExports.SeChangeNotifyPrivilege         = SeChangeNotifyPrivilege;
    SepExports.SeRemoteShutdownPrivilege       = SeRemoteShutdownPrivilege;
    SepExports.SeUndockPrivilege               = SeUndockPrivilege;
    SepExports.SeSyncAgentPrivilege            = SeSyncAgentPrivilege;
    SepExports.SeEnableDelegationPrivilege     = SeEnableDelegationPrivilege;
    SepExports.SeManageVolumePrivilege         = SeManageVolumePrivilege;
    SepExports.SeImpersonatePrivilege          = SeImpersonatePrivilege ;
    SepExports.SeCreateGlobalPrivilege         = SeCreateGlobalPrivilege;


    SeExports = &SepExports;

    //
    // Initialize frequently used privilege sets to speed up access
    // validation.
    //

    SepInitializePrivilegeSets();

    return TRUE;

}
Beispiel #12
0
VOID
NtfsInitializeNtfsData (
    IN PDRIVER_OBJECT DriverObject
    )

/*++

Routine Description:

    This routine initializes the global ntfs data record

Arguments:

    DriverObject - Supplies the driver object for NTFS

Return Value:

    None.

--*/

{
    USHORT FileLockMaxDepth;
    USHORT IoContextMaxDepth;
    USHORT IrpContextMaxDepth;
    USHORT KeventMaxDepth;
    USHORT ScbNonpagedMaxDepth;
    USHORT ScbSnapshotMaxDepth;

    USHORT CcbDataMaxDepth;
    USHORT CcbMaxDepth;
    USHORT DeallocatedRecordsMaxDepth;
    USHORT FcbDataMaxDepth;
    USHORT FcbIndexMaxDepth;
    USHORT IndexContextMaxDepth;
    USHORT LcbMaxDepth;
    USHORT NukemMaxDepth;
    USHORT ScbDataMaxDepth;

    PSECURITY_SUBJECT_CONTEXT SubjectContext = NULL;
    BOOLEAN CapturedSubjectContext = FALSE;

    PACL SystemDacl = NULL;
    ULONG SystemDaclLength;

    PSID AdminSid = NULL;
    PSID SystemSid = NULL;
    NTSTATUS Status = STATUS_SUCCESS;

    PAGED_CODE();

    DebugTrace( +1, Dbg, ("NtfsInitializeNtfsData\n") );

    //
    //  Zero the record and set its node type code and size
    //

    RtlZeroMemory( &NtfsData, sizeof(NTFS_DATA));

    NtfsData.NodeTypeCode = NTFS_NTC_DATA_HEADER;
    NtfsData.NodeByteSize = sizeof(NTFS_DATA);

    //
    //  Initialize the queue of mounted Vcbs
    //

    InitializeListHead(&NtfsData.VcbQueue);

    //
    //  This list head keeps track of closes yet to be done.
    //

    InitializeListHead( &NtfsData.AsyncCloseList );
    InitializeListHead( &NtfsData.DelayedCloseList );

    ExInitializeWorkItem( &NtfsData.NtfsCloseItem,
                          (PWORKER_THREAD_ROUTINE)NtfsFspClose,
                          NULL );

    //
    //  Set the driver object, device object, and initialize the global
    //  resource protecting the file system
    //

    NtfsData.DriverObject = DriverObject;

    ExInitializeResource( &NtfsData.Resource );

    //
    //  Now allocate and initialize the s-list structures used as our pool
    //  of IRP context records.  The size of the zone is based on the
    //  system memory size.  We also initialize the spin lock used to protect
    //  the zone.
    //

    KeInitializeSpinLock( &NtfsData.StrucSupSpinLock );
    {

        switch ( MmQuerySystemSize() ) {

        case MmSmallSystem:

            NtfsData.FreeEresourceTotal = 14;

            //
            //  Nonpaged Lookaside list maximum depths
            //

            FileLockMaxDepth           = 8;
            IoContextMaxDepth          = 8;
            IrpContextMaxDepth         = 4;
            KeventMaxDepth             = 8;
            ScbNonpagedMaxDepth        = 8;
            ScbSnapshotMaxDepth        = 8;

            //
            //  Paged Lookaside list maximum depths
            //

            CcbDataMaxDepth            = 4;
            CcbMaxDepth                = 4;
            DeallocatedRecordsMaxDepth = 8;
            FcbDataMaxDepth            = 8;
            FcbIndexMaxDepth           = 4;
            IndexContextMaxDepth       = 8;
            LcbMaxDepth                = 4;
            NukemMaxDepth              = 8;
            ScbDataMaxDepth            = 4;

            SetFlag( NtfsData.Flags, NTFS_FLAGS_SMALL_SYSTEM );
            NtfsMaxDelayedCloseCount = MAX_DELAYED_CLOSE_COUNT;

            break;

        case MmMediumSystem:

            NtfsData.FreeEresourceTotal = 30;

            //
            //  Nonpaged Lookaside list maximum depths
            //

            FileLockMaxDepth           = 8;
            IoContextMaxDepth          = 8;
            IrpContextMaxDepth         = 8;
            KeventMaxDepth             = 8;
            ScbNonpagedMaxDepth        = 30;
            ScbSnapshotMaxDepth        = 8;

            //
            //  Paged Lookaside list maximum depths
            //

            CcbDataMaxDepth            = 12;
            CcbMaxDepth                = 6;
            DeallocatedRecordsMaxDepth = 8;
            FcbDataMaxDepth            = 30;
            FcbIndexMaxDepth           = 12;
            IndexContextMaxDepth       = 8;
            LcbMaxDepth                = 12;
            NukemMaxDepth              = 8;
            ScbDataMaxDepth            = 12;

            SetFlag( NtfsData.Flags, NTFS_FLAGS_MEDIUM_SYSTEM );
            NtfsMaxDelayedCloseCount = 4 * MAX_DELAYED_CLOSE_COUNT;

            break;

        case MmLargeSystem:

            SetFlag( NtfsData.Flags, NTFS_FLAGS_LARGE_SYSTEM );
            NtfsMaxDelayedCloseCount = 16 * MAX_DELAYED_CLOSE_COUNT;

            if (MmIsThisAnNtAsSystem()) {

                NtfsData.FreeEresourceTotal = 256;

                //
                //  Nonpaged Lookaside list maximum depths
                //

                FileLockMaxDepth           = 8;
                IoContextMaxDepth          = 8;
                IrpContextMaxDepth         = 256;
                KeventMaxDepth             = 8;
                ScbNonpagedMaxDepth        = 128;
                ScbSnapshotMaxDepth        = 8;

                //
                //  Paged Lookaside list maximum depths
                //

                CcbDataMaxDepth            = 40;
                CcbMaxDepth                = 20;
                DeallocatedRecordsMaxDepth = 8;
                FcbDataMaxDepth            = 128;
                FcbIndexMaxDepth           = 40;
                IndexContextMaxDepth       = 8;
                LcbMaxDepth                = 40;
                NukemMaxDepth              = 8;
                ScbDataMaxDepth            = 40;

            } else {

                NtfsData.FreeEresourceTotal = 128;

                //
                //  Nonpaged Lookaside list maximum depths
                //

                FileLockMaxDepth           = 8;
                IoContextMaxDepth          = 8;
                IrpContextMaxDepth         = 64;
                KeventMaxDepth             = 8;
                ScbNonpagedMaxDepth        = 64;
                ScbSnapshotMaxDepth        = 8;

                //
                //  Paged Lookaside list maximum depths
                //

                CcbDataMaxDepth            = 20;
                CcbMaxDepth                = 10;
                DeallocatedRecordsMaxDepth = 8;
                FcbDataMaxDepth            = 64;
                FcbIndexMaxDepth           = 20;
                IndexContextMaxDepth       = 8;
                LcbMaxDepth                = 20;
                NukemMaxDepth              = 8;
                ScbDataMaxDepth            = 20;
            }

            break;
        }

        NtfsMinDelayedCloseCount = NtfsMaxDelayedCloseCount * 4 / 5;

    }

    //
    //  Initialize our various lookaside lists.  To make it a bit more readable we'll
    //  define two quick macros to do the initialization
    //

#if DBG && i386 && defined (NTFSPOOLCHECK)
#define NPagedInit(L,S,T,D) { ExInitializeNPagedLookasideList( (L), NtfsDebugAllocatePoolWithTag, NtfsDebugFreePool, POOL_RAISE_IF_ALLOCATION_FAILURE, S, T, D); }
#define PagedInit(L,S,T,D)  { ExInitializePagedLookasideList(  (L), NtfsDebugAllocatePoolWithTag, NtfsDebugFreePool, POOL_RAISE_IF_ALLOCATION_FAILURE, S, T, D); }
#else   //  DBG && i386
#define NPagedInit(L,S,T,D) { ExInitializeNPagedLookasideList( (L), NULL, NULL, POOL_RAISE_IF_ALLOCATION_FAILURE, S, T, D); }
#define PagedInit(L,S,T,D)  { ExInitializePagedLookasideList(  (L), NULL, NULL, POOL_RAISE_IF_ALLOCATION_FAILURE, S, T, D); }
#endif  //  DBG && i386

    NPagedInit( &NtfsFileLockLookasideList,    sizeof(FILE_LOCK),       'kftN', FileLockMaxDepth );
    NPagedInit( &NtfsIoContextLookasideList,   sizeof(NTFS_IO_CONTEXT), 'IftN', IoContextMaxDepth );
    NPagedInit( &NtfsIrpContextLookasideList,  sizeof(IRP_CONTEXT),     'iftN', IrpContextMaxDepth );
    NPagedInit( &NtfsKeventLookasideList,      sizeof(KEVENT),          'KftN', KeventMaxDepth );
    NPagedInit( &NtfsScbNonpagedLookasideList, sizeof(SCB_NONPAGED),    'nftN', ScbNonpagedMaxDepth );
    NPagedInit( &NtfsScbSnapshotLookasideList, sizeof(SCB_SNAPSHOT),    'TftN', ScbSnapshotMaxDepth );

    PagedInit(  &NtfsCcbLookasideList,                sizeof(CCB),                 'CftN', CcbMaxDepth );
    PagedInit(  &NtfsCcbDataLookasideList,            sizeof(CCB_DATA),            'cftN', CcbDataMaxDepth );
    PagedInit(  &NtfsDeallocatedRecordsLookasideList, sizeof(DEALLOCATED_RECORDS), 'DftN', DeallocatedRecordsMaxDepth );
    PagedInit(  &NtfsFcbDataLookasideList,            sizeof(FCB_DATA),            'fftN', FcbDataMaxDepth );
    PagedInit(  &NtfsFcbIndexLookasideList,           sizeof(FCB_INDEX),           'FftN', FcbIndexMaxDepth );
    PagedInit(  &NtfsIndexContextLookasideList,       sizeof(INDEX_CONTEXT),       'EftN', IndexContextMaxDepth );
    PagedInit(  &NtfsLcbLookasideList,                sizeof(LCB),                 'lftN', LcbMaxDepth );
    PagedInit(  &NtfsNukemLookasideList,              sizeof(NUKEM),               'NftN', NukemMaxDepth );
    PagedInit(  &NtfsScbDataLookasideList,            SIZEOF_SCB_DATA,             'sftN', ScbDataMaxDepth );

    //
    //  Initialize the cache manager callback routines,  First are the routines
    //  for normal file manipulations, followed by the routines for
    //  volume manipulations.
    //

    {
        PCACHE_MANAGER_CALLBACKS Callbacks = &NtfsData.CacheManagerCallbacks;

        Callbacks->AcquireForLazyWrite  = &NtfsAcquireScbForLazyWrite;
        Callbacks->ReleaseFromLazyWrite = &NtfsReleaseScbFromLazyWrite;
        Callbacks->AcquireForReadAhead  = &NtfsAcquireScbForReadAhead;
        Callbacks->ReleaseFromReadAhead = &NtfsReleaseScbFromReadAhead;
    }

    {
        PCACHE_MANAGER_CALLBACKS Callbacks = &NtfsData.CacheManagerVolumeCallbacks;

        Callbacks->AcquireForLazyWrite  = &NtfsAcquireVolumeFileForLazyWrite;
        Callbacks->ReleaseFromLazyWrite = &NtfsReleaseVolumeFileFromLazyWrite;
        Callbacks->AcquireForReadAhead  = NULL;
        Callbacks->ReleaseFromReadAhead = NULL;
    }

    //
    //  Initialize the queue of read ahead threads
    //

    InitializeListHead(&NtfsData.ReadAheadThreads);

    //
    //  Set up global pointer to our process.
    //

    NtfsData.OurProcess = PsGetCurrentProcess();

    //
    //  Use a try-finally to cleanup on errors.
    //

    try {

        SECURITY_DESCRIPTOR NewDescriptor;
        SID_IDENTIFIER_AUTHORITY Authority = SECURITY_NT_AUTHORITY;

        SubjectContext = NtfsAllocatePool( PagedPool, sizeof( SECURITY_SUBJECT_CONTEXT ));
        SeCaptureSubjectContext( SubjectContext );
        CapturedSubjectContext = TRUE;

        //
        //  Build the default security descriptor which gives full access to
        //  system and administrator.
        //

        AdminSid = (PSID) NtfsAllocatePool( PagedPool, RtlLengthRequiredSid( 2 ));
        RtlInitializeSid( AdminSid, &Authority, 2 );
        *(RtlSubAuthoritySid( AdminSid, 0 )) = SECURITY_BUILTIN_DOMAIN_RID;
        *(RtlSubAuthoritySid( AdminSid, 1 )) = DOMAIN_ALIAS_RID_ADMINS;

        SystemSid = (PSID) NtfsAllocatePool( PagedPool, RtlLengthRequiredSid( 1 ));
        RtlInitializeSid( SystemSid, &Authority, 1 );
        *(RtlSubAuthoritySid( SystemSid, 0 )) = SECURITY_LOCAL_SYSTEM_RID;

        SystemDaclLength = sizeof( ACL ) +
                           (2 * sizeof( ACCESS_ALLOWED_ACE )) +
                           SeLengthSid( AdminSid ) +
                           SeLengthSid( SystemSid ) +
                           8; // The 8 is just for good measure

        SystemDacl = NtfsAllocatePool( PagedPool, SystemDaclLength );

        Status = RtlCreateAcl( SystemDacl, SystemDaclLength, ACL_REVISION2 );

        if (!NT_SUCCESS( Status )) { leave; }

        Status = RtlAddAccessAllowedAce( SystemDacl,
                                         ACL_REVISION2,
                                         GENERIC_ALL,
                                         SystemSid );

        if (!NT_SUCCESS( Status )) { leave; }

        Status = RtlAddAccessAllowedAce( SystemDacl,
                                         ACL_REVISION2,
                                         GENERIC_ALL,
                                         AdminSid );

        if (!NT_SUCCESS( Status )) { leave; }

        Status = RtlCreateSecurityDescriptor( &NewDescriptor,
                                              SECURITY_DESCRIPTOR_REVISION1 );

        if (!NT_SUCCESS( Status )) { leave; }

        Status = RtlSetDaclSecurityDescriptor( &NewDescriptor,
                                               TRUE,
                                               SystemDacl,
                                               FALSE );

        if (!NT_SUCCESS( Status )) { leave; }

        Status = SeAssignSecurity( NULL,
                                   &NewDescriptor,
                                   &NtfsData.DefaultDescriptor,
                                   FALSE,
                                   SubjectContext,
                                   IoGetFileObjectGenericMapping(),
                                   PagedPool );

        if (!NT_SUCCESS( Status )) { leave; }

        NtfsData.DefaultDescriptorLength = RtlLengthSecurityDescriptor( NtfsData.DefaultDescriptor );

        ASSERT( SeValidSecurityDescriptor( NtfsData.DefaultDescriptorLength,
                                           NtfsData.DefaultDescriptor ));

    } finally {

        if (CapturedSubjectContext) {

            SeReleaseSubjectContext( SubjectContext );
        }

        if (SubjectContext != NULL) { NtfsFreePool( SubjectContext ); }

        if (SystemDacl != NULL) { NtfsFreePool( SystemDacl ); }

        if (AdminSid != NULL) { NtfsFreePool( AdminSid ); }

        if (SystemSid != NULL) { NtfsFreePool( SystemSid ); }
    }

    //
    //  Raise if we hit an error building the security descriptor.
    //

    if (!NT_SUCCESS( Status )) { ExRaiseStatus( Status ); }

    //
    //  And return to our caller
    //

    DebugTrace( -1, Dbg, ("NtfsInitializeNtfsData -> VOID\n") );

    return;
}
Beispiel #13
0
PSECURITY_DESCRIPTOR
NTAPI
INIT_FUNCTION
CmpHiveRootSecurityDescriptor(VOID)
{
    NTSTATUS Status;
    PSECURITY_DESCRIPTOR SecurityDescriptor;
    PACL Acl, AclCopy;
    PSID Sid[4];
    SID_IDENTIFIER_AUTHORITY WorldAuthority = {SECURITY_WORLD_SID_AUTHORITY};
    SID_IDENTIFIER_AUTHORITY NtAuthority = {SECURITY_NT_AUTHORITY};
    ULONG AceLength, AclLength, SidLength;
    PACE_HEADER AceHeader;
    ULONG i;
    PAGED_CODE();

    /* Phase 1: Allocate SIDs */
    SidLength = RtlLengthRequiredSid(1);
    Sid[0] = ExAllocatePoolWithTag(PagedPool, SidLength, TAG_CM);
    Sid[1] = ExAllocatePoolWithTag(PagedPool, SidLength, TAG_CM);
    Sid[2] = ExAllocatePoolWithTag(PagedPool, SidLength, TAG_CM);
    SidLength = RtlLengthRequiredSid(2);
    Sid[3] = ExAllocatePoolWithTag(PagedPool, SidLength, TAG_CM);

    /* Make sure all SIDs were allocated */
    if (!(Sid[0]) || !(Sid[1]) || !(Sid[2]) || !(Sid[3]))
    {
        /* Bugcheck */
        KeBugCheckEx(REGISTRY_ERROR, 11, 1, 0, 0);
    }

    /* Phase 2: Initialize all SIDs */
    Status = RtlInitializeSid(Sid[0], &WorldAuthority, 1);
    Status |= RtlInitializeSid(Sid[1], &NtAuthority, 1);
    Status |= RtlInitializeSid(Sid[2], &NtAuthority, 1);
    Status |= RtlInitializeSid(Sid[3], &NtAuthority, 2);
    if (!NT_SUCCESS(Status)) KeBugCheckEx(REGISTRY_ERROR, 11, 2, 0, 0);

    /* Phase 2: Setup SID Sub Authorities */
    *RtlSubAuthoritySid(Sid[0], 0) = SECURITY_WORLD_RID;
    *RtlSubAuthoritySid(Sid[1], 0) = SECURITY_RESTRICTED_CODE_RID;
    *RtlSubAuthoritySid(Sid[2], 0) = SECURITY_LOCAL_SYSTEM_RID;
    *RtlSubAuthoritySid(Sid[3], 0) = SECURITY_BUILTIN_DOMAIN_RID;
    *RtlSubAuthoritySid(Sid[3], 1) = DOMAIN_ALIAS_RID_ADMINS;

    /* Make sure all SIDs are valid */
    ASSERT(RtlValidSid(Sid[0]));
    ASSERT(RtlValidSid(Sid[1]));
    ASSERT(RtlValidSid(Sid[2]));
    ASSERT(RtlValidSid(Sid[3]));

    /* Phase 3: Calculate ACL Length */
    AclLength = sizeof(ACL);
    for (i = 0; i < 4; i++)
    {
        /* This is what MSDN says to do */
        AceLength = FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart);
        AceLength += SeLengthSid(Sid[i]);
        AclLength += AceLength;
    }

    /* Phase 3: Allocate the ACL */
    Acl = ExAllocatePoolWithTag(PagedPool, AclLength, TAG_CM);
    if (!Acl) KeBugCheckEx(REGISTRY_ERROR, 11, 3, 0, 0);

    /* Phase 4: Create the ACL */
    Status = RtlCreateAcl(Acl, AclLength, ACL_REVISION);
    if (!NT_SUCCESS(Status)) KeBugCheckEx(REGISTRY_ERROR, 11, 4, Status, 0);

    /* Phase 5: Build the ACL */
    Status = RtlAddAccessAllowedAce(Acl, ACL_REVISION, KEY_ALL_ACCESS, Sid[0]);
    Status |= RtlAddAccessAllowedAce(Acl, ACL_REVISION, KEY_ALL_ACCESS, Sid[1]);
    Status |= RtlAddAccessAllowedAce(Acl, ACL_REVISION, KEY_READ, Sid[2]);
    Status |= RtlAddAccessAllowedAce(Acl, ACL_REVISION, KEY_READ, Sid[3]);
    if (!NT_SUCCESS(Status)) KeBugCheckEx(REGISTRY_ERROR, 11, 5, Status, 0);

    /* Phase 5: Make the ACEs inheritable */
    Status = RtlGetAce(Acl, 0,( PVOID*)&AceHeader);
    ASSERT(NT_SUCCESS(Status));
    AceHeader->AceFlags |= CONTAINER_INHERIT_ACE;
    Status = RtlGetAce(Acl, 1, (PVOID*)&AceHeader);
    ASSERT(NT_SUCCESS(Status));
    AceHeader->AceFlags |= CONTAINER_INHERIT_ACE;
    Status = RtlGetAce(Acl, 2, (PVOID*)&AceHeader);
    ASSERT(NT_SUCCESS(Status));
    AceHeader->AceFlags |= CONTAINER_INHERIT_ACE;
    Status = RtlGetAce(Acl, 3, (PVOID*)&AceHeader);
    ASSERT(NT_SUCCESS(Status));
    AceHeader->AceFlags |= CONTAINER_INHERIT_ACE;

    /* Phase 6: Allocate the security descriptor and make space for the ACL */
    SecurityDescriptor = ExAllocatePoolWithTag(PagedPool,
                                               sizeof(SECURITY_DESCRIPTOR) +
                                               AclLength,
                                               TAG_CM);
    if (!SecurityDescriptor) KeBugCheckEx(REGISTRY_ERROR, 11, 6, 0, 0);

    /* Phase 6: Make a copy of the ACL */
    AclCopy = (PACL)((PISECURITY_DESCRIPTOR)SecurityDescriptor + 1);
    RtlCopyMemory(AclCopy, Acl, AclLength);

    /* Phase 7: Create the security descriptor */
    Status = RtlCreateSecurityDescriptor(SecurityDescriptor,
                                         SECURITY_DESCRIPTOR_REVISION);
    if (!NT_SUCCESS(Status)) KeBugCheckEx(REGISTRY_ERROR, 11, 7, Status, 0);

    /* Phase 8: Set the ACL as a DACL */
    Status = RtlSetDaclSecurityDescriptor(SecurityDescriptor,
                                          TRUE,
                                          AclCopy,
                                          FALSE);
    if (!NT_SUCCESS(Status)) KeBugCheckEx(REGISTRY_ERROR, 11, 8, Status, 0);

    /* Free the SIDs and original ACL */
    for (i = 0; i < 4; i++) ExFreePoolWithTag(Sid[i], TAG_CM);
    ExFreePoolWithTag(Acl, TAG_CM);

    /* Return the security descriptor */
    return SecurityDescriptor;
}
Beispiel #14
0
BOOLEAN
INIT_FUNCTION
NTAPI
SepInitSecurityIDs(VOID)
{
    ULONG SidLength0;
    ULONG SidLength1;
    ULONG SidLength2;
    PULONG SubAuthority;

    SidLength0 = RtlLengthRequiredSid(0);
    SidLength1 = RtlLengthRequiredSid(1);
    SidLength2 = RtlLengthRequiredSid(2);

    /* create NullSid */
    SeNullSid = ExAllocatePoolWithTag(PagedPool, SidLength1, TAG_SID);
    SeWorldSid = ExAllocatePoolWithTag(PagedPool, SidLength1, TAG_SID);
    SeLocalSid = ExAllocatePoolWithTag(PagedPool, SidLength1, TAG_SID);
    SeCreatorOwnerSid = ExAllocatePoolWithTag(PagedPool, SidLength1, TAG_SID);
    SeCreatorGroupSid = ExAllocatePoolWithTag(PagedPool, SidLength1, TAG_SID);
    SeCreatorOwnerServerSid = ExAllocatePoolWithTag(PagedPool, SidLength1, TAG_SID);
    SeCreatorGroupServerSid = ExAllocatePoolWithTag(PagedPool, SidLength1, TAG_SID);
    SeNtAuthoritySid = ExAllocatePoolWithTag(PagedPool, SidLength0, TAG_SID);
    SeDialupSid = ExAllocatePoolWithTag(PagedPool, SidLength1, TAG_SID);
    SeNetworkSid = ExAllocatePoolWithTag(PagedPool, SidLength1, TAG_SID);
    SeBatchSid = ExAllocatePoolWithTag(PagedPool, SidLength1, TAG_SID);
    SeInteractiveSid = ExAllocatePoolWithTag(PagedPool, SidLength1, TAG_SID);
    SeServiceSid = ExAllocatePoolWithTag(PagedPool, SidLength1, TAG_SID);
    SePrincipalSelfSid = ExAllocatePoolWithTag(PagedPool, SidLength1, TAG_SID);
    SeLocalSystemSid = ExAllocatePoolWithTag(PagedPool, SidLength1, TAG_SID);
    SeAuthenticatedUserSid = ExAllocatePoolWithTag(PagedPool, SidLength1, TAG_SID);
    SeRestrictedCodeSid = ExAllocatePoolWithTag(PagedPool, SidLength1, TAG_SID);
    SeAliasAdminsSid = ExAllocatePoolWithTag(PagedPool, SidLength2, TAG_SID);
    SeAliasUsersSid = ExAllocatePoolWithTag(PagedPool, SidLength2, TAG_SID);
    SeAliasGuestsSid = ExAllocatePoolWithTag(PagedPool, SidLength2, TAG_SID);
    SeAliasPowerUsersSid = ExAllocatePoolWithTag(PagedPool, SidLength2, TAG_SID);
    SeAliasAccountOpsSid = ExAllocatePoolWithTag(PagedPool, SidLength2, TAG_SID);
    SeAliasSystemOpsSid = ExAllocatePoolWithTag(PagedPool, SidLength2, TAG_SID);
    SeAliasPrintOpsSid = ExAllocatePoolWithTag(PagedPool, SidLength2, TAG_SID);
    SeAliasBackupOpsSid = ExAllocatePoolWithTag(PagedPool, SidLength2, TAG_SID);
    SeAuthenticatedUsersSid = ExAllocatePoolWithTag(PagedPool, SidLength1, TAG_SID);
    SeRestrictedSid = ExAllocatePoolWithTag(PagedPool, SidLength1, TAG_SID);
    SeAnonymousLogonSid = ExAllocatePoolWithTag(PagedPool, SidLength1, TAG_SID);
    SeLocalServiceSid = ExAllocatePoolWithTag(PagedPool, SidLength1, TAG_SID);
    SeNetworkServiceSid = ExAllocatePoolWithTag(PagedPool, SidLength1, TAG_SID);

    if (SeNullSid == NULL || SeWorldSid == NULL ||
        SeLocalSid == NULL || SeCreatorOwnerSid == NULL ||
        SeCreatorGroupSid == NULL || SeCreatorOwnerServerSid == NULL ||
        SeCreatorGroupServerSid == NULL || SeNtAuthoritySid == NULL ||
        SeDialupSid == NULL || SeNetworkSid == NULL || SeBatchSid == NULL ||
        SeInteractiveSid == NULL || SeServiceSid == NULL ||
        SePrincipalSelfSid == NULL || SeLocalSystemSid == NULL ||
        SeAuthenticatedUserSid == NULL || SeRestrictedCodeSid == NULL ||
        SeAliasAdminsSid == NULL || SeAliasUsersSid == NULL ||
        SeAliasGuestsSid == NULL || SeAliasPowerUsersSid == NULL ||
        SeAliasAccountOpsSid == NULL || SeAliasSystemOpsSid == NULL ||
        SeAliasPrintOpsSid == NULL || SeAliasBackupOpsSid == NULL ||
        SeAuthenticatedUsersSid == NULL || SeRestrictedSid == NULL ||
        SeAnonymousLogonSid == NULL || SeLocalServiceSid == NULL ||
        SeNetworkServiceSid == NULL)
    {
        FreeInitializedSids();
        return FALSE;
    }

    RtlInitializeSid(SeNullSid, &SeNullSidAuthority, 1);
    RtlInitializeSid(SeWorldSid, &SeWorldSidAuthority, 1);
    RtlInitializeSid(SeLocalSid, &SeLocalSidAuthority, 1);
    RtlInitializeSid(SeCreatorOwnerSid, &SeCreatorSidAuthority, 1);
    RtlInitializeSid(SeCreatorGroupSid, &SeCreatorSidAuthority, 1);
    RtlInitializeSid(SeCreatorOwnerServerSid, &SeCreatorSidAuthority, 1);
    RtlInitializeSid(SeCreatorGroupServerSid, &SeCreatorSidAuthority, 1);
    RtlInitializeSid(SeNtAuthoritySid, &SeNtSidAuthority, 0);
    RtlInitializeSid(SeDialupSid, &SeNtSidAuthority, 1);
    RtlInitializeSid(SeNetworkSid, &SeNtSidAuthority, 1);
    RtlInitializeSid(SeBatchSid, &SeNtSidAuthority, 1);
    RtlInitializeSid(SeInteractiveSid, &SeNtSidAuthority, 1);
    RtlInitializeSid(SeServiceSid, &SeNtSidAuthority, 1);
    RtlInitializeSid(SePrincipalSelfSid, &SeNtSidAuthority, 1);
    RtlInitializeSid(SeLocalSystemSid, &SeNtSidAuthority, 1);
    RtlInitializeSid(SeAuthenticatedUserSid, &SeNtSidAuthority, 1);
    RtlInitializeSid(SeRestrictedCodeSid, &SeNtSidAuthority, 1);
    RtlInitializeSid(SeAliasAdminsSid, &SeNtSidAuthority, 2);
    RtlInitializeSid(SeAliasUsersSid, &SeNtSidAuthority, 2);
    RtlInitializeSid(SeAliasGuestsSid, &SeNtSidAuthority, 2);
    RtlInitializeSid(SeAliasPowerUsersSid, &SeNtSidAuthority, 2);
    RtlInitializeSid(SeAliasAccountOpsSid, &SeNtSidAuthority, 2);
    RtlInitializeSid(SeAliasSystemOpsSid, &SeNtSidAuthority, 2);
    RtlInitializeSid(SeAliasPrintOpsSid, &SeNtSidAuthority, 2);
    RtlInitializeSid(SeAliasBackupOpsSid, &SeNtSidAuthority, 2);
    RtlInitializeSid(SeAuthenticatedUsersSid, &SeNtSidAuthority, 1);
    RtlInitializeSid(SeRestrictedSid, &SeNtSidAuthority, 1);
    RtlInitializeSid(SeAnonymousLogonSid, &SeNtSidAuthority, 1);
    RtlInitializeSid(SeLocalServiceSid, &SeNtSidAuthority, 1);
    RtlInitializeSid(SeNetworkServiceSid, &SeNtSidAuthority, 1);

    SubAuthority = RtlSubAuthoritySid(SeNullSid, 0);
    *SubAuthority = SECURITY_NULL_RID;
    SubAuthority = RtlSubAuthoritySid(SeWorldSid, 0);
    *SubAuthority = SECURITY_WORLD_RID;
    SubAuthority = RtlSubAuthoritySid(SeLocalSid, 0);
    *SubAuthority = SECURITY_LOCAL_RID;
    SubAuthority = RtlSubAuthoritySid(SeCreatorOwnerSid, 0);
    *SubAuthority = SECURITY_CREATOR_OWNER_RID;
    SubAuthority = RtlSubAuthoritySid(SeCreatorGroupSid, 0);
    *SubAuthority = SECURITY_CREATOR_GROUP_RID;
    SubAuthority = RtlSubAuthoritySid(SeCreatorOwnerServerSid, 0);
    *SubAuthority = SECURITY_CREATOR_OWNER_SERVER_RID;
    SubAuthority = RtlSubAuthoritySid(SeCreatorGroupServerSid, 0);
    *SubAuthority = SECURITY_CREATOR_GROUP_SERVER_RID;
    SubAuthority = RtlSubAuthoritySid(SeDialupSid, 0);
    *SubAuthority = SECURITY_DIALUP_RID;
    SubAuthority = RtlSubAuthoritySid(SeNetworkSid, 0);
    *SubAuthority = SECURITY_NETWORK_RID;
    SubAuthority = RtlSubAuthoritySid(SeBatchSid, 0);
    *SubAuthority = SECURITY_BATCH_RID;
    SubAuthority = RtlSubAuthoritySid(SeInteractiveSid, 0);
    *SubAuthority = SECURITY_INTERACTIVE_RID;
    SubAuthority = RtlSubAuthoritySid(SeServiceSid, 0);
    *SubAuthority = SECURITY_SERVICE_RID;
    SubAuthority = RtlSubAuthoritySid(SePrincipalSelfSid, 0);
    *SubAuthority = SECURITY_PRINCIPAL_SELF_RID;
    SubAuthority = RtlSubAuthoritySid(SeLocalSystemSid, 0);
    *SubAuthority = SECURITY_LOCAL_SYSTEM_RID;
    SubAuthority = RtlSubAuthoritySid(SeAuthenticatedUserSid, 0);
    *SubAuthority = SECURITY_AUTHENTICATED_USER_RID;
    SubAuthority = RtlSubAuthoritySid(SeRestrictedCodeSid, 0);
    *SubAuthority = SECURITY_RESTRICTED_CODE_RID;
    SubAuthority = RtlSubAuthoritySid(SeAliasAdminsSid, 0);
    *SubAuthority = SECURITY_BUILTIN_DOMAIN_RID;
    SubAuthority = RtlSubAuthoritySid(SeAliasAdminsSid, 1);
    *SubAuthority = DOMAIN_ALIAS_RID_ADMINS;
    SubAuthority = RtlSubAuthoritySid(SeAliasUsersSid, 0);
    *SubAuthority = SECURITY_BUILTIN_DOMAIN_RID;
    SubAuthority = RtlSubAuthoritySid(SeAliasUsersSid, 1);
    *SubAuthority = DOMAIN_ALIAS_RID_USERS;
    SubAuthority = RtlSubAuthoritySid(SeAliasGuestsSid, 0);
    *SubAuthority = SECURITY_BUILTIN_DOMAIN_RID;
    SubAuthority = RtlSubAuthoritySid(SeAliasGuestsSid, 1);
    *SubAuthority = DOMAIN_ALIAS_RID_GUESTS;
    SubAuthority = RtlSubAuthoritySid(SeAliasPowerUsersSid, 0);
    *SubAuthority = SECURITY_BUILTIN_DOMAIN_RID;
    SubAuthority = RtlSubAuthoritySid(SeAliasPowerUsersSid, 1);
    *SubAuthority = DOMAIN_ALIAS_RID_POWER_USERS;
    SubAuthority = RtlSubAuthoritySid(SeAliasAccountOpsSid, 0);
    *SubAuthority = SECURITY_BUILTIN_DOMAIN_RID;
    SubAuthority = RtlSubAuthoritySid(SeAliasAccountOpsSid, 1);
    *SubAuthority = DOMAIN_ALIAS_RID_ACCOUNT_OPS;
    SubAuthority = RtlSubAuthoritySid(SeAliasSystemOpsSid, 0);
    *SubAuthority = SECURITY_BUILTIN_DOMAIN_RID;
    SubAuthority = RtlSubAuthoritySid(SeAliasSystemOpsSid, 1);
    *SubAuthority = DOMAIN_ALIAS_RID_SYSTEM_OPS;
    SubAuthority = RtlSubAuthoritySid(SeAliasPrintOpsSid, 0);
    *SubAuthority = SECURITY_BUILTIN_DOMAIN_RID;
    SubAuthority = RtlSubAuthoritySid(SeAliasPrintOpsSid, 1);
    *SubAuthority = DOMAIN_ALIAS_RID_PRINT_OPS;
    SubAuthority = RtlSubAuthoritySid(SeAliasBackupOpsSid, 0);
    *SubAuthority = SECURITY_BUILTIN_DOMAIN_RID;
    SubAuthority = RtlSubAuthoritySid(SeAliasBackupOpsSid, 1);
    *SubAuthority = DOMAIN_ALIAS_RID_BACKUP_OPS;
    SubAuthority = RtlSubAuthoritySid(SeAuthenticatedUsersSid, 0);
    *SubAuthority = SECURITY_AUTHENTICATED_USER_RID;
    SubAuthority = RtlSubAuthoritySid(SeRestrictedSid, 0);
    *SubAuthority = SECURITY_RESTRICTED_CODE_RID;
    SubAuthority = RtlSubAuthoritySid(SeAnonymousLogonSid, 0);
    *SubAuthority = SECURITY_ANONYMOUS_LOGON_RID;
    SubAuthority = RtlSubAuthoritySid(SeLocalServiceSid, 0);
    *SubAuthority = SECURITY_LOCAL_SERVICE_RID;
    SubAuthority = RtlSubAuthoritySid(SeNetworkServiceSid, 0);
    *SubAuthority = SECURITY_NETWORK_SERVICE_RID;

    return TRUE;
}
Beispiel #15
0
/**
 * Sets the access control lists of the current window station
 * and desktop to allow all access.
 */
VOID PhSetDesktopWinStaAccess(
    VOID
    )
{
    static SID_IDENTIFIER_AUTHORITY appPackageAuthority = SECURITY_APP_PACKAGE_AUTHORITY;

    HWINSTA wsHandle;
    HDESK desktopHandle;
    ULONG allocationLength;
    PSECURITY_DESCRIPTOR securityDescriptor;
    PACL dacl;
    CHAR allAppPackagesSidBuffer[FIELD_OFFSET(SID, SubAuthority) + sizeof(ULONG) * 2];
    PSID allAppPackagesSid;

    // TODO: Set security on the correct window station and desktop.

    allAppPackagesSid = (PISID)allAppPackagesSidBuffer;
    RtlInitializeSid(allAppPackagesSid, &appPackageAuthority, SECURITY_BUILTIN_APP_PACKAGE_RID_COUNT);
    *RtlSubAuthoritySid(allAppPackagesSid, 0) = SECURITY_APP_PACKAGE_BASE_RID;
    *RtlSubAuthoritySid(allAppPackagesSid, 1) = SECURITY_BUILTIN_PACKAGE_ANY_PACKAGE;

    // We create a DACL that allows everyone to access everything.

    allocationLength = SECURITY_DESCRIPTOR_MIN_LENGTH +
        (ULONG)sizeof(ACL) +
        (ULONG)sizeof(ACCESS_ALLOWED_ACE) +
        RtlLengthSid(&PhSeEveryoneSid) +
        (ULONG)sizeof(ACCESS_ALLOWED_ACE) +
        RtlLengthSid(allAppPackagesSid);
    securityDescriptor = PhAllocate(allocationLength);
    dacl = (PACL)((PCHAR)securityDescriptor + SECURITY_DESCRIPTOR_MIN_LENGTH);

    RtlCreateSecurityDescriptor(securityDescriptor, SECURITY_DESCRIPTOR_REVISION);

    RtlCreateAcl(dacl, allocationLength - SECURITY_DESCRIPTOR_MIN_LENGTH, ACL_REVISION);
    RtlAddAccessAllowedAce(dacl, ACL_REVISION, GENERIC_ALL, &PhSeEveryoneSid);

    if (WindowsVersion >= WINDOWS_8)
    {
        RtlAddAccessAllowedAce(dacl, ACL_REVISION, GENERIC_ALL, allAppPackagesSid);
    }

    RtlSetDaclSecurityDescriptor(securityDescriptor, TRUE, dacl, FALSE);

    if (wsHandle = OpenWindowStation(
        L"WinSta0",
        FALSE,
        WRITE_DAC
        ))
    {
        PhSetObjectSecurity(wsHandle, DACL_SECURITY_INFORMATION, securityDescriptor);
        CloseWindowStation(wsHandle);
    }

    if (desktopHandle = OpenDesktop(
        L"Default",
        0,
        FALSE,
        WRITE_DAC | DESKTOP_READOBJECTS | DESKTOP_WRITEOBJECTS
        ))
    {
        PhSetObjectSecurity(desktopHandle, DACL_SECURITY_INFORMATION, securityDescriptor);
        CloseDesktop(desktopHandle);
    }

    PhFree(securityDescriptor);
}
Beispiel #16
0
NTSTATUS
NlAddGlobalGroupsToList(
    PLIST_ENTRY GroupList,
    ULONG LocalGroupID
    )
/*++

Routine Description:

    This procedure adds the global groups that are member of the given
    alias.

Arguments:

    GroupList : List to munch.

    LocalGroupId : Rid of the local group.

Return Value:

    Return NT Status code.

--*/
{
    NTSTATUS Status;
    SAMPR_HANDLE AliasHandle = NULL;

    SAMPR_PSID_ARRAY Members = {0, NULL};
    PULONG RidArray = NULL;
    DWORD RidArrayLength = 0;
    SAMPR_RETURNED_USTRING_ARRAY Names = {0, NULL};
    SAMPR_ULONG_ARRAY Use = {0, NULL};
    DWORD i;

    //
    // Open Local Group
    //

    Status = SamrOpenAlias(
                NlGlobalChWorkerBuiltinDBHandle,
                0,              // No desired access
                LocalGroupID,
                &AliasHandle );

    if (!NT_SUCCESS(Status)) {
        AliasHandle = NULL;
        goto Cleanup;
    }

    //
    // Enumerate members in this local group.
    //

    Status = SamrGetMembersInAlias(
                AliasHandle,
                &Members );

    if (!NT_SUCCESS(Status)) {
        Members.Sids = NULL;
        goto Cleanup;
    }

    //
    // Determine the SIDs that belong to the Account Domain and get the
    // RIDs of them.
    //

    if( Members.Count == 0) {

        Status = STATUS_SUCCESS;
        goto Cleanup;
    }

    //
    // Allocate the maximum size RID array required.
    //

    RidArray = (PULONG)NetpMemoryAllocate( Members.Count * sizeof(ULONG) );

    if( RidArray == NULL ) {
        Status = STATUS_NO_MEMORY;
        goto Cleanup;
    }

    for( i = 0; i < Members.Count; i++) {

        PUCHAR SubAuthorityCount;
        BOOLEAN EqualSid;

        SubAuthorityCount =
            RtlSubAuthorityCountSid(Members.Sids[i].SidPointer);

        (*SubAuthorityCount)--;
        EqualSid = RtlEqualSid( NlGlobalChWorkerSamDomainSid,
                                    Members.Sids[i].SidPointer );
        (*SubAuthorityCount)++;

        if( EqualSid ) {

            RidArray[RidArrayLength] =
                *RtlSubAuthoritySid( Members.Sids[i].SidPointer,
                                        (*SubAuthorityCount) -1 );
            RidArrayLength++;
        }
    }

    if( RidArrayLength == 0) {

        Status = STATUS_SUCCESS;
        goto Cleanup;
    }

    //
    // Get Group RIDs and add them to list.
    //

    Status = SamrLookupIdsInDomain( NlGlobalChWorkerSamDBHandle,
                                        RidArrayLength,
                                        RidArray,
                                        &Names,
                                        &Use );

    if ( !NT_SUCCESS(Status) ) {

        Names.Element = NULL;
        Use.Element = NULL;

        if( Status == STATUS_NONE_MAPPED ) {

            //
            // if no SID is mapped, we can't do much here.
            //

            NlPrint((NL_CRITICAL,
                "NlAddGlobalGroupsToList could not map any SID from "
                "local group, RID = %lx \n", LocalGroupID ));

            Status = STATUS_SUCCESS;
        }

        goto Cleanup;
    }

    NlAssert( Names.Count == RidArrayLength );
    NlAssert( Names.Element != NULL );
    NlAssert( Use.Count == RidArrayLength );
    NlAssert( Use.Element != NULL );

    //
    // Find groups and add them to list.
    //

    for( i = 0; i < RidArrayLength; i++ ) {

        if( Use.Element[i] == SidTypeGroup ) {

            //
            // we found a group, add it to the list if it is not there
            // already.
            //

            if( NlGetGroupEntry( GroupList, RidArray[i] ) != NULL ) {

                //
                // entry already in the list.
                //

                continue;
            }

            //
            // add an entry to the list.
            //

            Status = NlAddGroupEntry( GroupList, RidArray[i] );

            if ( !NT_SUCCESS(Status) ) {
                goto Cleanup;
            }
        }
    }

Cleanup:

    if( Names.Element != NULL ) {
        SamIFree_SAMPR_RETURNED_USTRING_ARRAY( &Names );
    }

    if( Use.Element != NULL ) {
        SamIFree_SAMPR_ULONG_ARRAY( &Use );
    }

    if( RidArray != NULL ) {
        NetpMemoryFree( RidArray );
    }

    if ( Members.Sids != NULL ) {
        SamIFree_SAMPR_PSID_ARRAY( (PSAMPR_PSID_ARRAY)&Members );
    }

    if( AliasHandle != NULL ) {
        SamrCloseHandle( &AliasHandle );
    }

    if ( !NT_SUCCESS(Status) ) {

        NlPrint((NL_CRITICAL, "NlAddGlobalGroupsToList failed %lx\n",
                    Status ));
    }

    return( Status );
}
Beispiel #17
0
NTSTATUS NTAPI
LsaApLogonUserEx (PLSA_CLIENT_REQUEST request, SECURITY_LOGON_TYPE logon_type,
		  PVOID auth, PVOID client_auth_base, ULONG auth_len,
		  PVOID *pbuf, PULONG pbuf_len, PLUID logon_id,
		  PNTSTATUS sub_stat, PLSA_TOKEN_INFORMATION_TYPE tok_type,
		  PVOID *tok, PUNICODE_STRING *account,
		  PUNICODE_STRING *authority, PUNICODE_STRING *machine)
{
  DWORD checksum, i;
  PDWORD csp, csp_end;
  NTSTATUS stat;
  SECPKG_CLIENT_INFO clinf;
  PLSA_TOKEN_INFORMATION_V2 tokinf;

  cyglsa_t *authinf = (cyglsa_t *) auth;

  /* Check if the caller has the SeTcbPrivilege, otherwise refuse service. */
  stat = funcs->GetClientInfo (&clinf);
  if (stat != STATUS_SUCCESS)
    {
      cyglsa_printf ("GetClientInfo failed: 0x%08lx\n", stat);
      return stat;
    }
  if (!clinf.HasTcbPrivilege)
    {
      cyglsa_printf ("Client has no TCB privilege.  Access denied.\n");
      return STATUS_ACCESS_DENIED;
    }

  /* Make a couple of validity checks. */
  if (auth_len < sizeof *authinf
      || authinf->magic != CYG_LSA_MAGIC
      || !authinf->username[0]
      || !authinf->domain[0])
    {
      cyglsa_printf ("Invalid authentication parameter.\n");
      return STATUS_INVALID_PARAMETER;
    }
  checksum = CYG_LSA_MAGIC;
  csp = (PDWORD) &authinf->username;
  csp_end = (PDWORD) ((PBYTE) authinf + auth_len);
  while (csp < csp_end)
    checksum += *csp++;
  if (authinf->checksum != checksum)
    {
      cyglsa_printf ("Invalid checksum.\n");
      return STATUS_INVALID_PARAMETER_3;
    }

  /* Set account to username and authority to domain resp. machine name.
     The name of the logon account name as returned by LookupAccountSid
     is created from here as "authority\account". */
  authinf->username[UNLEN] = '\0';
  authinf->domain[MAX_DOMAIN_NAME_LEN] = '\0';
  if (account && !(*account = uni_alloc (authinf->username,
  					 wcslen (authinf->username))))
    {
      cyglsa_printf ("No memory trying to create account.\n");
      return STATUS_NO_MEMORY;
    }
  if (authority && !(*authority = uni_alloc (authinf->domain,
					     wcslen (authinf->domain))))
    {
      cyglsa_printf ("No memory trying to create authority.\n");
      return STATUS_NO_MEMORY;
    }
  if (machine)
    {
      WCHAR mach[MAX_COMPUTERNAME_LENGTH + 1];
      DWORD msize = MAX_COMPUTERNAME_LENGTH + 1;
      if (!GetComputerNameW (mach, &msize))
        wcscpy (mach, L"UNKNOWN");
      if (!(*machine = uni_alloc (mach, wcslen (mach))))
	{
	  cyglsa_printf ("No memory trying to create machine.\n");
	  return STATUS_NO_MEMORY;
	}
    }
  /* Create a fake buffer in pbuf which is free'd again in the client.
     Windows 2000 tends to crash when setting this pointer to NULL. */
  if (pbuf)
    {
#ifdef JUST_ANOTHER_NONWORKING_SOLUTION
      cygprf_t prf;
      WCHAR sam_username[MAX_DOMAIN_NAME_LEN + UNLEN + 2];
      SECURITY_STRING sam_user, prefix;
      PUCHAR user_auth;
      ULONG user_auth_size;
      WCHAR flatname[UNLEN + 1];
      UNICODE_STRING flatnm;
      TOKEN_SOURCE ts;
      HANDLE token;
#endif /* JUST_ANOTHER_NONWORKING_SOLUTION */

      stat = funcs->AllocateClientBuffer (request, 64UL, pbuf);
      if (!LSA_SUCCESS (stat))
	{
	  cyglsa_printf ("AllocateClientBuffer failed: 0x%08lx\n", stat);
	  return stat;
	}
#ifdef JUST_ANOTHER_NONWORKING_SOLUTION
      prf.magic_pre = MAGIC_PRE;
      prf.token = NULL;
      prf.magic_post = MAGIC_POST;

#if 0
      /* That's how it was supposed to work according to MSDN... */
      wcscpy (sam_username, authinf->domain);
      wcscat (sam_username, L"\\");
      wcscat (sam_username, authinf->username);
#else
      /* That's the only solution which worked, and then it only worked
         for machine local accounts.  No domain authentication possible.
	 STATUS_NO_SUCH_USER galore! */
      wcscpy (sam_username, authinf->username);
#endif
      RtlInitUnicodeString (&sam_user, sam_username);
      RtlInitUnicodeString (&prefix, L"");
      RtlInitEmptyUnicodeString (&flatnm, flatname,
				 (UNLEN + 1) * sizeof (WCHAR));

      stat = funcs->GetAuthDataForUser (&sam_user, SecNameSamCompatible,
					NULL, &user_auth,
					&user_auth_size, &flatnm);
      if (!NT_SUCCESS (stat))
	{
	  char sam_u[MAX_DOMAIN_NAME_LEN + UNLEN + 2];
	  wcstombs (sam_u, sam_user.Buffer, sizeof (sam_u));
	  cyglsa_printf ("GetAuthDataForUser (%u,%u,%s) failed: 0x%08lx\n",
		  sam_user.Length, sam_user.MaximumLength, sam_u, stat);
	  return stat;
	}

      memcpy (ts.SourceName, "Cygwin.1", 8);
      ts.SourceIdentifier.HighPart = 0;
      ts.SourceIdentifier.LowPart = 0x0104;
      RtlInitEmptyUnicodeString (&flatnm, flatname,
				 (UNLEN + 1) * sizeof (WCHAR));
      stat = funcs->ConvertAuthDataToToken (user_auth, user_auth_size,
					    SecurityDelegation, &ts,
					    Interactive, *authority,
					    &token, logon_id, &flatnm,
					    sub_stat);
      if (!NT_SUCCESS (stat))
	{
	  cyglsa_printf ("ConvertAuthDataToToken failed: 0x%08lx\n", stat);
	  return stat;
	}

      stat = funcs->DuplicateHandle (token, &prf.token);
      if (!NT_SUCCESS (stat))
	{
	  cyglsa_printf ("DuplicateHandle failed: 0x%08lx\n", stat);
	  return stat;
	}
      
      stat = funcs->CopyToClientBuffer (request, sizeof prf, *pbuf, &prf);
      if (!NT_SUCCESS (stat))
	{
	  cyglsa_printf ("CopyToClientBuffer failed: 0x%08lx\n", stat);
	  return stat;
	}
      funcs->FreeLsaHeap (user_auth);
#endif /* JUST_ANOTHER_NONWORKING_SOLUTION */
    }
  if (pbuf_len)
    *pbuf_len = 64UL;

  /* A PLSA_TOKEN_INFORMATION_V2 is allocated in one piece, so... */
#if defined (__x86_64__) || defined (_M_AMD64)
    {
      /* ...on 64 bit systems we have to convert the incoming 32 bit offsets
	 into 64 bit pointers.  That requires to re-evaluate the size of the
	 outgoing tokinf structure and a somewhat awkward procedure to copy
	 the information over. */
      LONG_PTR base;
      PBYTE tptr;
      DWORD size, newsize;
      PSID src_sid;
      PCYG_TOKEN_GROUPS src_grps;
      PTOKEN_GROUPS grps;
      PTOKEN_PRIVILEGES src_privs;
      PACL src_acl;

      base = (LONG_PTR) &authinf->inf;

      newsize = authinf->inf_size;
      newsize += sizeof (TOKEN_USER) - sizeof (CYG_TOKEN_USER); /* User SID */
      newsize += sizeof (PTOKEN_GROUPS) - sizeof (OFFSET); /* Groups */
      src_grps = (PCYG_TOKEN_GROUPS) (base + authinf->inf.Groups);
      newsize += src_grps->GroupCount		  /* Group SIDs */
      		 * (sizeof (SID_AND_ATTRIBUTES)
		    - sizeof (CYG_SID_AND_ATTRIBUTES));
      newsize += sizeof (PSID) - sizeof (OFFSET); /* Primary Group SID */
      newsize += sizeof (PTOKEN_PRIVILEGES) - sizeof (OFFSET); /* Privileges */
      newsize += 0; /* Owner SID */
      newsize += sizeof (PACL) - sizeof (OFFSET); /* Default DACL */

      if (!(tokinf = funcs->AllocateLsaHeap (newsize)))
	return STATUS_NO_MEMORY;
      tptr = (PBYTE)(tokinf + 1);

      tokinf->ExpirationTime = authinf->inf.ExpirationTime;
      /* User SID */
      src_sid = (PSID) (base + authinf->inf.User.User.Sid);
      size = RtlLengthSid (src_sid);
      RtlCopySid (size, (PSID) tptr, src_sid);
      tokinf->User.User.Sid = (PSID) tptr;
      tptr += size;
      tokinf->User.User.Attributes = authinf->inf.User.User.Attributes;
      /* Groups */
      grps = (PTOKEN_GROUPS) tptr;
      tokinf->Groups = grps;
      grps->GroupCount = src_grps->GroupCount;
      tptr += sizeof grps->GroupCount
	      + grps->GroupCount * sizeof (SID_AND_ATTRIBUTES);
      /* Group SIDs */
      for (i = 0; i < src_grps->GroupCount; ++i)
	{
	  src_sid = (PSID) (base + src_grps->Groups[i].Sid);
	  size = RtlLengthSid (src_sid);
	  RtlCopySid (size, (PSID) tptr, src_sid);
	  tokinf->Groups->Groups[i].Sid = (PSID) tptr;
	  tptr += size;
	  tokinf->Groups->Groups[i].Attributes = src_grps->Groups[i].Attributes;
	}
      /* Primary Group SID */
      src_sid = (PSID) (base + authinf->inf.PrimaryGroup.PrimaryGroup);
      size = RtlLengthSid (src_sid);
      RtlCopySid (size, (PSID) tptr, src_sid);
      tokinf->PrimaryGroup.PrimaryGroup = (PSID) tptr;
      tptr += size;
      /* Privileges */
      src_privs = (PTOKEN_PRIVILEGES) (base + authinf->inf.Privileges);
      size = sizeof src_privs->PrivilegeCount
	     + src_privs->PrivilegeCount * sizeof (LUID_AND_ATTRIBUTES);
      memcpy (tptr, src_privs, size);
      tokinf->Privileges = (PTOKEN_PRIVILEGES) tptr;
      tptr += size;
      /* Owner */
      tokinf->Owner.Owner = NULL;
      /* Default DACL */
      src_acl = (PACL) (base + authinf->inf.DefaultDacl.DefaultDacl);
      size = src_acl->AclSize;
      memcpy (tptr, src_acl, size);
      tokinf->DefaultDacl.DefaultDacl = (PACL) tptr;
    }
#else
    {
      /* ...on 32 bit systems we just allocate tokinf with the same size as
         we get, copy the whole structure and convert offsets into pointers. */

      /* Allocate LUID for usage in the logon SID on Windows 2000.  This is
	 not done in the 64 bit code above for hopefully obvious reasons... */
      LUID logon_sid_id;

      if (must_create_logon_sid
	  && !NT_SUCCESS (NtAllocateLocallyUniqueId (&logon_sid_id)))
	return STATUS_INSUFFICIENT_RESOURCES;

      if (!(tokinf = funcs->AllocateLsaHeap (authinf->inf_size)))
	return STATUS_NO_MEMORY;
      memcpy (tokinf, &authinf->inf, authinf->inf_size);

      /* User SID */
      tokinf->User.User.Sid = (PSID)
	      ((PBYTE) tokinf + (LONG_PTR) tokinf->User.User.Sid);
      /* Groups */
      tokinf->Groups = (PTOKEN_GROUPS)
	      ((PBYTE) tokinf + (LONG_PTR) tokinf->Groups);
      /* Group SIDs */
      for (i = 0; i < tokinf->Groups->GroupCount; ++i)
	{
	  tokinf->Groups->Groups[i].Sid = (PSID)
		((PBYTE) tokinf + (LONG_PTR) tokinf->Groups->Groups[i].Sid);
	  if (must_create_logon_sid
	      && tokinf->Groups->Groups[i].Attributes & SE_GROUP_LOGON_ID
	      && *RtlSubAuthorityCountSid (tokinf->Groups->Groups[i].Sid) == 3
	      && *RtlSubAuthoritySid (tokinf->Groups->Groups[i].Sid, 0)
		 == SECURITY_LOGON_IDS_RID)
	    {
	      *RtlSubAuthoritySid (tokinf->Groups->Groups[i].Sid, 1)
	      = logon_sid_id.HighPart;
	      *RtlSubAuthoritySid (tokinf->Groups->Groups[i].Sid, 2)
	      = logon_sid_id.LowPart;
	    }
	}

      /* Primary Group SID */
      tokinf->PrimaryGroup.PrimaryGroup = (PSID)
	      ((PBYTE) tokinf + (LONG_PTR) tokinf->PrimaryGroup.PrimaryGroup);
      /* Privileges */
      tokinf->Privileges = (PTOKEN_PRIVILEGES)
	      ((PBYTE) tokinf + (LONG_PTR) tokinf->Privileges);
      /* Owner SID */
      tokinf->Owner.Owner = NULL;
      /* Default DACL */
      tokinf->DefaultDacl.DefaultDacl = (PACL)
	      ((PBYTE) tokinf + (LONG_PTR) tokinf->DefaultDacl.DefaultDacl);

    }
#endif

  *tok = (PVOID) tokinf;
  *tok_type = LsaTokenInformationV2;

  print_tokinf (tokinf, authinf->inf_size, authinf, &authinf->inf,
		(PVOID)((LONG_PTR) &authinf->inf + authinf->inf_size));

  /* Create logon session. */
  stat = NtAllocateLocallyUniqueId (logon_id);
  if (!NT_SUCCESS (stat))
    {
      funcs->FreeLsaHeap (*tok);
      *tok = NULL;
      cyglsa_printf ("NtAllocateLocallyUniqueId status 0x%08lx\n", stat);
      return STATUS_INSUFFICIENT_RESOURCES;
    }
  stat = funcs->CreateLogonSession (logon_id);
  if (stat != STATUS_SUCCESS)
    {
      funcs->FreeLsaHeap (*tok);
      *tok = NULL;
      cyglsa_printf ("CreateLogonSession failed: 0x%08lx\n", stat);
      return stat;
    }

  cyglsa_printf ("BINGO!!!\n", stat);
  return STATUS_SUCCESS;
}
Beispiel #18
0
NTSTATUS
I_NetNotifyDelta (
    IN SECURITY_DB_TYPE DbType,
    IN LARGE_INTEGER SerialNumber,
    IN SECURITY_DB_DELTA_TYPE DeltaType,
    IN SECURITY_DB_OBJECT_TYPE ObjectType,
    IN ULONG ObjectRid,
    IN PSID ObjectSid,
    IN PUNICODE_STRING ObjectName,
    IN DWORD ReplicateImmediately,
    IN PSAM_DELTA_DATA MemberId
)
/*++

Routine Description:

    This function is called by the SAM and LSA services after each
    change is made to the SAM and LSA databases.  The services describe
    the type of object that is modified, the type of modification made
    on the object, the serial number of this modification etc.  This
    information is stored for later retrieval when a BDC or member
    server wants a copy of this change.  See the description of
    I_NetSamDeltas for a description of how the change log is used.

    Add a change log entry to circular change log maintained in cache as
    well as on the disk and update the head and tail pointers

    It is assumed that Tail points to a block where this new change log
    entry may be stored.

Arguments:

    DbType - Type of the database that has been modified.

    SerialNumber - The value of the DomainModifiedCount field for the
        domain following the modification.

    DeltaType - The type of modification that has been made on the object.

    ObjectType - The type of object that has been modified.

    ObjectRid - The relative ID of the object that has been modified.
        This parameter is valid only when the object type specified is
        either SecurityDbObjectSamUser, SecurityDbObjectSamGroup or
        SecurityDbObjectSamAlias otherwise this parameter is set to zero.

    ObjectSid - The SID of the object that has been modified.  If the object
        modified is in a SAM database, ObjectSid is the DomainId of the Domain
        containing the object.

    ObjectName - The name of the secret object when the object type
        specified is SecurityDbObjectLsaSecret or the old name of the object
        when the object type specified is either SecurityDbObjectSamUser,
        SecurityDbObjectSamGroup or SecurityDbObjectSamAlias and the delta
        type is SecurityDbRename otherwise this parameter is set to NULL.

    ReplicateImmediately - TRUE if the change should be immediately
        replicated to all BDCs.  A password change should set the flag
        TRUE.

    MemberId - This parameter is specified when group/alias membership
        is modified. This structure will then point to the member's ID that
        has been updated.

Return Value:

    STATUS_SUCCESS - The Service completed successfully.

--*/
{
    NTSTATUS Status;
    CHANGELOG_ENTRY ChangeLogEntry;
    NETLOGON_DELTA_TYPE NetlogonDeltaType;
    USHORT Flags = 0;
    BOOL LanmanReplicateImmediately = FALSE;

    //
    // Ensure the role is right.  Otherwise, all the globals used below
    //  aren't initialized.
    //

    if ( NlGlobalChangeLogRole != ChangeLogPrimary ) {
        return STATUS_INVALID_DOMAIN_ROLE;
    }

    //
    // Also make sure that the change log cache is available.
    //

    if ( NlGlobalChangeLogDesc.Buffer == NULL ) {
        return STATUS_INVALID_DOMAIN_ROLE;
    }


    //
    // Determine the database index.
    //

    if( DbType == SecurityDbLsa ) {

        ChangeLogEntry.DBIndex = LSA_DB;

    } else if( DbType == SecurityDbSam ) {

        if ( RtlEqualSid( ObjectSid, NlGlobalChWorkerBuiltinDomainSid )) {

            ChangeLogEntry.DBIndex = BUILTIN_DB;

        } else {

            ChangeLogEntry.DBIndex = SAM_DB;

        }

        //
        // For the SAM database, we no longer need the ObjectSid.
        // Null out the pointer to prevent us from storing it in the
        // changelog.
        //

        ObjectSid = NULL;

    } else {

        //
        // unknown database, do nothing.
        //

        return STATUS_SUCCESS;
    }



    //
    // Map object type and delta type to NetlogonDeltaType
    //

    switch( ObjectType ) {
    case SecurityDbObjectLsaPolicy:

        switch (DeltaType) {
        case SecurityDbNew:
        case SecurityDbChange:
            NetlogonDeltaType = AddOrChangeLsaPolicy;
            break;

        // unknown delta type
        default:
            return STATUS_SUCCESS;
        }
        break;


    case SecurityDbObjectLsaTDomain:

        switch (DeltaType) {
        case SecurityDbNew:
        case SecurityDbChange:
            NetlogonDeltaType = AddOrChangeLsaTDomain;

            //
            //  Tell the netlogon service to update its in-memory list now.
            //
            (VOID) NlSendChangeLogNotification( ChangeLogTrustAdded,
                                                NULL,
                                                ObjectSid,
                                                0 );
            break;

        case SecurityDbDelete:
            NetlogonDeltaType = DeleteLsaTDomain;

            //
            //  Tell the netlogon service to update its in-memory list now.
            //
            (VOID) NlSendChangeLogNotification( ChangeLogTrustDeleted,
                                                NULL,
                                                ObjectSid,
                                                0 );
            break;

        // unknown delta type
        default:
            return STATUS_SUCCESS;
        }
        break;


    case SecurityDbObjectLsaAccount:

        switch (DeltaType) {
        case SecurityDbNew:
        case SecurityDbChange:
            NetlogonDeltaType = AddOrChangeLsaAccount;
            break;

        case SecurityDbDelete:
            NetlogonDeltaType = DeleteLsaAccount;
            break;

        // unknown delta type
        default:
            return STATUS_SUCCESS;
        }
        break;


    case SecurityDbObjectLsaSecret:

        switch (DeltaType) {
        case SecurityDbNew:
        case SecurityDbChange:
            NetlogonDeltaType = AddOrChangeLsaSecret;
            break;

        case SecurityDbDelete:
            NetlogonDeltaType = DeleteLsaSecret;
            break;

        // unknown delta type
        default:
            return STATUS_SUCCESS;
        }
        break;


    case SecurityDbObjectSamDomain:

        switch (DeltaType) {
        case SecurityDbNew:
        case SecurityDbChange:
            NetlogonDeltaType = AddOrChangeDomain;
            break;

        // unknown delta type
        default:
            return STATUS_SUCCESS;
        }
        break;

    case SecurityDbObjectSamUser:

        switch (DeltaType) {
        case SecurityDbChangePassword:
            Flags |= CHANGELOG_PASSWORD_CHANGE;
            LanmanReplicateImmediately = TRUE;
            NetlogonDeltaType = AddOrChangeUser;
            break;

        case SecurityDbNew:

            //
            // For down-level system, a newly added user needs to
            // have it's membership in "Domain Users" updated, too.
            // The following worker entry will add the additional
            // delta entry and increment the serial number
            // accordingly.
            //

            LOCK_CHANGELOG();
            if( IsChangeLogWorkerRunning() ) {
                (VOID) NlAddWorkerQueueEntry( ChangeLogAddUser, ObjectRid );
            }
            UNLOCK_CHANGELOG();

            NetlogonDeltaType = AddOrChangeUser;
            break;

        case SecurityDbChange:
            NetlogonDeltaType = AddOrChangeUser;
            break;

        //
        // This is a dummy delta sent by chworker to indicate that "Domain Users"
        // was added as a member of this user.
        //
        case SecurityDbChangeMemberAdd:
            Flags |= CHANGELOG_DOMAINUSERS_CHANGED;
            NetlogonDeltaType = AddOrChangeUser;
            break;

        case SecurityDbDelete:

            //
            // This might be a Lanman BDC so check to be sure.
            //

            NlLmBdcListDel( ObjectRid );

            NetlogonDeltaType = DeleteUser;
            break;


        case SecurityDbRename:
            NetlogonDeltaType = RenameUser;

            //
            // For down-level system, Rename user is handled as two
            // deltas, viz. 1) Delete old user and 2) Add new user.
            // The following worker entry will add the additional
            // delta entry and increment the serial number
            // accordingly.
            //

            LOCK_CHANGELOG();

            if( IsChangeLogWorkerRunning() ) {
                (VOID) NlAddWorkerQueueEntry( ChangeLogRenameUser, ObjectRid );
            }

            UNLOCK_CHANGELOG();

            break;

        //
        // unknown delta type
        //

        default:
            return STATUS_SUCCESS;
        }

        break;

    case SecurityDbObjectSamGroup:

        switch ( DeltaType ) {
        case SecurityDbNew:
        case SecurityDbChange:
            NetlogonDeltaType = AddOrChangeGroup;
            break;

        case SecurityDbDelete:
            NetlogonDeltaType = DeleteGroup;

            //
            // when a global group is deleted, we also delete it
            // from the special group list, if it is included
            // in the list.
            //

            LOCK_CHANGELOG();

            if( IsChangeLogWorkerRunning() ) {

                PGLOBAL_GROUP_ENTRY GroupEntry;

                GroupEntry = NlGetGroupEntry (
                                 &NlGlobalSpecialServerGroupList,
                                 ObjectRid );

                if( GroupEntry != NULL ) {

                    RemoveEntryList( &GroupEntry->Next );
                    NetpMemoryFree( GroupEntry );
                }

            }

            UNLOCK_CHANGELOG();
            break;

        case SecurityDbRename:
            NetlogonDeltaType = RenameGroup;

            //
            // For down-level system, Rename group is handled as
            // three deltas, viz. 1) Delete old group, 2) Add new
            // group and 3. Changemembership of new group. The
            // following worker entry will add the additional
            // two delta entries and increment the serial number
            // accordingly.
            //

            LOCK_CHANGELOG();

            if( IsChangeLogWorkerRunning() ) {
                (VOID) NlAddWorkerQueueEntry( ChangeLogRenameGroup, ObjectRid );

            }

            UNLOCK_CHANGELOG();

            break;

        case SecurityDbChangeMemberAdd:
        case SecurityDbChangeMemberSet:
        case SecurityDbChangeMemberDel: {

            UNICODE_STRING ServersGroup;

            NetlogonDeltaType = ChangeGroupMembership;

            //
            // without object name we can't do much here.
            //
            if( ObjectName == NULL ) {
                break;
            }

            //
            // do something for down level
            //

            RtlInitUnicodeString( &ServersGroup, SSI_SERVER_GROUP_W );

            LOCK_CHANGELOG();

            if( RtlEqualUnicodeString(
                        &ServersGroup, ObjectName, (BOOLEAN)TRUE ) ) {

                //
                // Handle a new LM BDC.
                //

                if( DeltaType == SecurityDbChangeMemberAdd ) {

                    NlLmBdcListAdd( MemberId->GroupMemberId.MemberRid );


                    //
                    // Handle an LM BDC being deleted.
                    //

                } else if( DeltaType == SecurityDbChangeMemberDel ) {

                    NlLmBdcListDel( MemberId->GroupMemberId.MemberRid );
                }

            } else {

                if( IsChangeLogWorkerRunning() ) {

                    //
                    // Change log work is running. If the global groups
                    // list watched is empty, add this delta in the
                    // queue anyway, otherwise add this delta to entry
                    // only if this group is monitored.
                    //

                    if( IsListEmpty( &NlGlobalSpecialServerGroupList ) ||

                            ( NlGetGroupEntry(
                                  &NlGlobalSpecialServerGroupList,
                                  ObjectRid ) != NULL ) ) {


                        (VOID) NlAddWorkerQueueEntry(
                            ChangeLogGroupMembership,
                            MemberId->GroupMemberId.MemberRid );

                    }
                }
            }

            UNLOCK_CHANGELOG();

            break;
        }

        //
        // unknown delta type
        //
        default:
            return STATUS_SUCCESS;
        }
        break;

    case SecurityDbObjectSamAlias:

        switch (DeltaType) {
        case SecurityDbNew:
        case SecurityDbChange:
            NetlogonDeltaType = AddOrChangeAlias;
            break;

        case SecurityDbDelete:
            NetlogonDeltaType = DeleteAlias;
            break;

        case SecurityDbRename:
            NetlogonDeltaType = RenameAlias;
            break;

        case SecurityDbChangeMemberAdd:
        case SecurityDbChangeMemberSet:
        case SecurityDbChangeMemberDel:

            NetlogonDeltaType = ChangeAliasMembership;

            LOCK_CHANGELOG();

            //
            // if this delta is BUILTIN domain delta and the group
            // modified is special group then add this delta to
            // workers queue if it is running.
            //

            if ( (ChangeLogEntry.DBIndex == BUILTIN_DB) &&
                    ( IsChangeLogWorkerRunning() ) &&
                    ( IsSpecialLocalGroup( ObjectRid ) ) ) {

                ULONG Rid;
                PUCHAR SubAuthorityCount;
                BOOLEAN EqualSid;

                //
                // if the member modified belongs to the local SAM
                // database.
                //

                SubAuthorityCount =
                    RtlSubAuthorityCountSid(
                        MemberId->AliasMemberId.MemberSid);

                (*SubAuthorityCount)--;

                if( NlGlobalChWorkerSamDomainSid != NULL ) {

                    EqualSid = RtlEqualSid(
                                   NlGlobalChWorkerSamDomainSid,
                                   MemberId->AliasMemberId.MemberSid);
                } else {
                    EqualSid = FALSE;
                }

                (*SubAuthorityCount)++;

                if( EqualSid ) {

                    Rid = *RtlSubAuthoritySid(
                              MemberId->AliasMemberId.MemberSid,
                              (*SubAuthorityCount) -1 );

                    (VOID) NlAddWorkerQueueEntry(
                        ChangeLogAliasMembership,
                        Rid );


                    //
                    // add this member in the global group list,
                    // since this member may be a global group and we
                    // don't want to miss any delta made on this group.
                    // Worker thread will adjust the list and remove
                    // unwanted user entries from the list.
                    //

                    Status = NlAddGroupEntry(
                                 &NlGlobalSpecialServerGroupList,
                                 Rid );

                    if ( !NT_SUCCESS(Status) ) {

                        NlPrint((NL_CRITICAL,
                                 "NlAddGroupEntry failed %lx\n",
                                 Status ) );
                    }
                }
            }

            UNLOCK_CHANGELOG();

            break;

        // unknown delta type
        default:
            return STATUS_SUCCESS;
        }
        break;

    default:

        // unknown object type
        return STATUS_SUCCESS;

    }


    //
    // Build the changelog entry and write it to the changelog
    //

    ChangeLogEntry.DeltaType = NetlogonDeltaType;
    ChangeLogEntry.SerialNumber = SerialNumber;
    ChangeLogEntry.ObjectRid = ObjectRid;
    ChangeLogEntry.Flags = ReplicateImmediately ? CHANGELOG_REPLICATE_IMMEDIATELY : 0;
    ChangeLogEntry.Flags |= Flags;

    (VOID) NlWriteChangeLogEntry( &NlGlobalChangeLogDesc, &ChangeLogEntry, ObjectSid, ObjectName, TRUE );


    //
    // If this change requires immediate replication, do so
    //

    if( ReplicateImmediately ) {

        LOCK_CHANGELOG();
        NlGlobalChangeLogReplicateImmediately = TRUE;
        UNLOCK_CHANGELOG();

        if ( !SetEvent( NlGlobalChangeLogEvent ) ) {
            NlPrint((NL_CRITICAL,
                     "Cannot set ChangeLog event: %lu\n",
                     GetLastError() ));
        }


        //
        // If this change requires immediate replication to Lanman BDCs, do so
        //

    } else if( LanmanReplicateImmediately ) {

        LOCK_CHANGELOG();
        NlGlobalChangeLogLanmanReplicateImmediately = TRUE;
        UNLOCK_CHANGELOG();

        if ( !SetEvent( NlGlobalChangeLogEvent ) ) {
            NlPrint((NL_CRITICAL,
                     "Cannot set ChangeLog event: %lu\n",
                     GetLastError() ));
        }

    }

    return STATUS_SUCCESS;
}
Beispiel #19
0
ULONG CreateSecurityDescriptor(
    ULONG *pSecurityDescriptor,
    PSID *ppWorldSid,
    ACCESS_MASK AccessMask)
{
    ULONG rc = 0L;                     /* return code */
    PACL pAclBuffer;                   /* ptr to ACL buffer */
    ULONG SidLength;                   /* length of SID - 1 sub authority */
    PSID pWSid;                        /* ptr to world SID */
    SID_IDENTIFIER_AUTHORITY SidAuth = SECURITY_WORLD_SID_AUTHORITY;


    /*
     *  Create World SID.
     */
    SidLength = RtlLengthRequiredSid(1);

    if ((pWSid = (PSID)RtlAllocateHeap(RtlProcessHeap(),
                                       MAKE_TAG( TMP_TAG ) | HEAP_ZERO_MEMORY,
                                       SidLength)) == NULL)
    {
        *ppWorldSid = NULL;
        KdPrint(("NLSAPI (BaseSrv): Could NOT Allocate SID Buffer.\n"));
        return (ERROR_OUTOFMEMORY);
    }
    *ppWorldSid = pWSid;

    RtlInitializeSid(pWSid, &SidAuth, 1);

    *(RtlSubAuthoritySid(pWSid, 0)) = SECURITY_WORLD_RID;

    /*
     *  Initialize Security Descriptor.
     */
    rc = RtlCreateSecurityDescriptor(pSecurityDescriptor,
                                     SECURITY_DESCRIPTOR_REVISION);
    if (!NT_SUCCESS(rc))
    {
        KdPrint(("NLSAPI (BaseSrv): Could NOT Create Security Descriptor - %lx.\n",
                 rc));
        RtlFreeHeap(RtlProcessHeap(), 0, (PVOID)pWSid);
        return (rc);
    }

    /*
     *  Initialize ACL.
     */
    pAclBuffer = (PACL)((PBYTE)pSecurityDescriptor + SECURITY_DESCRIPTOR_MIN_LENGTH);
    rc = RtlCreateAcl((PACL)pAclBuffer,
                      MAX_PATH_LEN * sizeof(ULONG),
                      ACL_REVISION2);
    if (!NT_SUCCESS(rc))
    {
        KdPrint(("NLSAPI (BaseSrv): Could NOT Create ACL - %lx.\n", rc));
        RtlFreeHeap(RtlProcessHeap(), 0, (PVOID)pWSid);
        return (rc);
    }

    /*
     *  Add an ACE to the ACL that allows World GENERIC_READ to the
     *  section object.
     */
    rc = RtlAddAccessAllowedAce((PACL)pAclBuffer,
                                ACL_REVISION2,
                                AccessMask,
                                pWSid);
    if (!NT_SUCCESS(rc))
    {
        KdPrint(("NLSAPI (BaseSrv): Could NOT Add Access Allowed ACE - %lx.\n",
                 rc));
        RtlFreeHeap(RtlProcessHeap(), 0, (PVOID)pWSid);
        return (rc);
    }

    /*
     *  Assign the DACL to the security descriptor.
     */
    rc = RtlSetDaclSecurityDescriptor((PSECURITY_DESCRIPTOR)pSecurityDescriptor,
                                      (BOOLEAN)TRUE,
                                      (PACL)pAclBuffer,
                                      (BOOLEAN)FALSE);
    if (!NT_SUCCESS(rc))
    {
        KdPrint(("NLSAPI (BaseSrv): Could NOT Set DACL Security Descriptor - %lx.\n",
                 rc));
        RtlFreeHeap(RtlProcessHeap(), 0, (PVOID)pWSid);
        return (rc);
    }

    /*
     *  Return success.
     */
    return (NO_ERROR);
}
Beispiel #20
0
BOOLEAN
TSeVariableInitialization()
/*++

Routine Description:

    This function initializes the global variables used in security
    tests.

Arguments:

    None.

Return Value:

    TRUE if variables successfully initialized.
    FALSE if not successfully initialized.

--*/
{
    ULONG SidWithZeroSubAuthorities;
    ULONG SidWithOneSubAuthority;
    ULONG SidWithThreeSubAuthorities;
    ULONG SidWithFourSubAuthorities;

    SID_IDENTIFIER_AUTHORITY NullSidAuthority    = SECURITY_NULL_SID_AUTHORITY;
    SID_IDENTIFIER_AUTHORITY WorldSidAuthority   = SECURITY_WORLD_SID_AUTHORITY;
    SID_IDENTIFIER_AUTHORITY LocalSidAuthority   = SECURITY_LOCAL_SID_AUTHORITY;
    SID_IDENTIFIER_AUTHORITY CreatorSidAuthority = SECURITY_CREATOR_SID_AUTHORITY;

    SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY;


    SID_IDENTIFIER_AUTHORITY BedrockAuthority = BEDROCK_AUTHORITY;

    SID_IDENTIFIER_AUTHORITY BedrockAAuthority = BEDROCKA_AUTHORITY;
    SID_IDENTIFIER_AUTHORITY BedrockBAuthority = BEDROCKB_AUTHORITY;
    SID_IDENTIFIER_AUTHORITY BedrockCAuthority = BEDROCKC_AUTHORITY;
    SID_IDENTIFIER_AUTHORITY BedrockDAuthority = BEDROCKD_AUTHORITY;
    SID_IDENTIFIER_AUTHORITY BedrockEAuthority = BEDROCKE_AUTHORITY;

    //
    //  The following SID sizes need to be allocated
    //

    SidWithZeroSubAuthorities  = RtlLengthRequiredSid( 0 );
    SidWithOneSubAuthority     = RtlLengthRequiredSid( 1 );
    SidWithThreeSubAuthorities = RtlLengthRequiredSid( 3 );
    SidWithFourSubAuthorities  = RtlLengthRequiredSid( 4 );

    //
    //  Allocate and initialize the universal SIDs
    //

    NullSid    = (PSID)TstAllocatePool(PagedPool,SidWithOneSubAuthority);
    WorldSid   = (PSID)TstAllocatePool(PagedPool,SidWithOneSubAuthority);
    LocalSid   = (PSID)TstAllocatePool(PagedPool,SidWithOneSubAuthority);
    CreatorOwnerSid = (PSID)TstAllocatePool(PagedPool,SidWithOneSubAuthority);
    CreatorGroupSid = (PSID)TstAllocatePool(PagedPool,SidWithOneSubAuthority);

    RtlInitializeSid( NullSid,    &NullSidAuthority, 1 );
    RtlInitializeSid( WorldSid,   &WorldSidAuthority, 1 );
    RtlInitializeSid( LocalSid,   &LocalSidAuthority, 1 );
    RtlInitializeSid( CreatorOwnerSid, &CreatorSidAuthority, 1 );
    RtlInitializeSid( CreatorGroupSid, &CreatorSidAuthority, 1 );

    *(RtlSubAuthoritySid( NullSid, 0 ))    = SECURITY_NULL_RID;
    *(RtlSubAuthoritySid( WorldSid, 0 ))   = SECURITY_WORLD_RID;
    *(RtlSubAuthoritySid( LocalSid, 0 ))   = SECURITY_LOCAL_RID;
    *(RtlSubAuthoritySid( CreatorOwnerSid, 0 )) = SECURITY_CREATOR_OWNER_RID;
    *(RtlSubAuthoritySid( CreatorGroupSid, 0 )) = SECURITY_CREATOR_GROUP_RID;

    //
    // Allocate and initialize the NT defined SIDs
    //

    NtAuthoritySid  = (PSID)TstAllocatePool(PagedPool,SidWithZeroSubAuthorities);
    DialupSid       = (PSID)TstAllocatePool(PagedPool,SidWithOneSubAuthority);
    NetworkSid      = (PSID)TstAllocatePool(PagedPool,SidWithOneSubAuthority);
    BatchSid        = (PSID)TstAllocatePool(PagedPool,SidWithOneSubAuthority);
    InteractiveSid  = (PSID)TstAllocatePool(PagedPool,SidWithOneSubAuthority);
    LocalSystemSid  = (PSID)TstAllocatePool(PagedPool,SidWithOneSubAuthority);

    RtlInitializeSid( NtAuthoritySid,   &NtAuthority, 0 );
    RtlInitializeSid( DialupSid,        &NtAuthority, 1 );
    RtlInitializeSid( NetworkSid,       &NtAuthority, 1 );
    RtlInitializeSid( BatchSid,         &NtAuthority, 1 );
    RtlInitializeSid( InteractiveSid,   &NtAuthority, 1 );
    RtlInitializeSid( LocalSystemSid,   &NtAuthority, 1 );

    *(RtlSubAuthoritySid( DialupSid,       0 )) = SECURITY_DIALUP_RID;
    *(RtlSubAuthoritySid( NetworkSid,      0 )) = SECURITY_NETWORK_RID;
    *(RtlSubAuthoritySid( BatchSid,        0 )) = SECURITY_BATCH_RID;
    *(RtlSubAuthoritySid( InteractiveSid,  0 )) = SECURITY_INTERACTIVE_RID;
    *(RtlSubAuthoritySid( LocalSystemSid,  0 )) = SECURITY_LOCAL_SYSTEM_RID;



    //
    // Allocate and initialize the Bedrock SIDs
    //

    BedrockDomainSid  = (PSID)TstAllocatePool(PagedPool,SidWithThreeSubAuthorities);
    BedrockADomainSid  = (PSID)TstAllocatePool(PagedPool,SidWithThreeSubAuthorities);
    BedrockBDomainSid  = (PSID)TstAllocatePool(PagedPool,SidWithThreeSubAuthorities);
    BedrockCDomainSid  = (PSID)TstAllocatePool(PagedPool,SidWithThreeSubAuthorities);
    BedrockDDomainSid  = (PSID)TstAllocatePool(PagedPool,SidWithThreeSubAuthorities);
    BedrockEDomainSid  = (PSID)TstAllocatePool(PagedPool,SidWithThreeSubAuthorities);

    FredSid           = (PSID)TstAllocatePool(PagedPool,SidWithFourSubAuthorities);
    WilmaSid          = (PSID)TstAllocatePool(PagedPool,SidWithFourSubAuthorities);
    PebblesSid        = (PSID)TstAllocatePool(PagedPool,SidWithFourSubAuthorities);
    DinoSid           = (PSID)TstAllocatePool(PagedPool,SidWithFourSubAuthorities);

    BarneySid         = (PSID)TstAllocatePool(PagedPool,SidWithFourSubAuthorities);
    BettySid          = (PSID)TstAllocatePool(PagedPool,SidWithFourSubAuthorities);
    BambamSid         = (PSID)TstAllocatePool(PagedPool,SidWithFourSubAuthorities);

    FlintstoneSid     = (PSID)TstAllocatePool(PagedPool,SidWithFourSubAuthorities);
    RubbleSid         = (PSID)TstAllocatePool(PagedPool,SidWithFourSubAuthorities);

    AdultSid          = (PSID)TstAllocatePool(PagedPool,SidWithFourSubAuthorities);
    ChildSid          = (PSID)TstAllocatePool(PagedPool,SidWithFourSubAuthorities);

    NeandertholSid    = (PSID)TstAllocatePool(PagedPool,SidWithFourSubAuthorities);

    RtlInitializeSid( BedrockDomainSid,   &BedrockAuthority, 3 );
    *(RtlSubAuthoritySid( BedrockDomainSid, 0)) = BEDROCK_SUBAUTHORITY_0;
    *(RtlSubAuthoritySid( BedrockDomainSid, 1)) = BEDROCK_SUBAUTHORITY_1;
    *(RtlSubAuthoritySid( BedrockDomainSid, 2)) = BEDROCK_SUBAUTHORITY_2;

    RtlInitializeSid( BedrockADomainSid,   &BedrockAAuthority, 3 );
    *(RtlSubAuthoritySid( BedrockADomainSid, 0)) = BEDROCKA_SUBAUTHORITY_0;
    *(RtlSubAuthoritySid( BedrockADomainSid, 1)) = BEDROCKA_SUBAUTHORITY_1;
    *(RtlSubAuthoritySid( BedrockADomainSid, 2)) = BEDROCKA_SUBAUTHORITY_2;


    RtlInitializeSid( BedrockBDomainSid,   &BedrockBAuthority, 3 );
    *(RtlSubAuthoritySid( BedrockBDomainSid, 0)) = BEDROCKB_SUBAUTHORITY_0;
    *(RtlSubAuthoritySid( BedrockBDomainSid, 1)) = BEDROCKB_SUBAUTHORITY_1;
    *(RtlSubAuthoritySid( BedrockBDomainSid, 2)) = BEDROCKB_SUBAUTHORITY_2;

    RtlInitializeSid( BedrockCDomainSid,   &BedrockCAuthority, 3 );
    *(RtlSubAuthoritySid( BedrockCDomainSid, 0)) = BEDROCKC_SUBAUTHORITY_0;
    *(RtlSubAuthoritySid( BedrockCDomainSid, 1)) = BEDROCKC_SUBAUTHORITY_1;
    *(RtlSubAuthoritySid( BedrockCDomainSid, 2)) = BEDROCKC_SUBAUTHORITY_2;

    RtlInitializeSid( BedrockDDomainSid,   &BedrockDAuthority, 3 );
    *(RtlSubAuthoritySid( BedrockDDomainSid, 0)) = BEDROCKD_SUBAUTHORITY_0;
    *(RtlSubAuthoritySid( BedrockDDomainSid, 1)) = BEDROCKD_SUBAUTHORITY_1;
    *(RtlSubAuthoritySid( BedrockDDomainSid, 2)) = BEDROCKD_SUBAUTHORITY_2;

    RtlInitializeSid( BedrockEDomainSid,   &BedrockEAuthority, 3 );
    *(RtlSubAuthoritySid( BedrockEDomainSid, 0)) = BEDROCKE_SUBAUTHORITY_0;
    *(RtlSubAuthoritySid( BedrockEDomainSid, 1)) = BEDROCKE_SUBAUTHORITY_1;
    *(RtlSubAuthoritySid( BedrockEDomainSid, 2)) = BEDROCKE_SUBAUTHORITY_2;

    RtlCopySid( SidWithFourSubAuthorities, FredSid, BedrockDomainSid);
    *(RtlSubAuthorityCountSid( FredSid )) += 1;
    *(RtlSubAuthoritySid( FredSid, 3)) = FRED_RID;

    RtlCopySid( SidWithFourSubAuthorities, WilmaSid, BedrockDomainSid);
    *(RtlSubAuthorityCountSid( WilmaSid )) += 1;
    *(RtlSubAuthoritySid( WilmaSid, 3)) = WILMA_RID;

    RtlCopySid( SidWithFourSubAuthorities, PebblesSid, BedrockDomainSid);
    *(RtlSubAuthorityCountSid( PebblesSid )) += 1;
    *(RtlSubAuthoritySid( PebblesSid, 3)) = PEBBLES_RID;

    RtlCopySid( SidWithFourSubAuthorities, DinoSid, BedrockDomainSid);
    *(RtlSubAuthorityCountSid( DinoSid )) += 1;
    *(RtlSubAuthoritySid( DinoSid, 3)) = DINO_RID;

    RtlCopySid( SidWithFourSubAuthorities, BarneySid, BedrockDomainSid);
    *(RtlSubAuthorityCountSid( BarneySid )) += 1;
    *(RtlSubAuthoritySid( BarneySid, 3)) = BARNEY_RID;

    RtlCopySid( SidWithFourSubAuthorities, BettySid, BedrockDomainSid);
    *(RtlSubAuthorityCountSid( BettySid )) += 1;
    *(RtlSubAuthoritySid( BettySid, 3)) = BETTY_RID;

    RtlCopySid( SidWithFourSubAuthorities, BambamSid, BedrockDomainSid);
    *(RtlSubAuthorityCountSid( BambamSid )) += 1;
    *(RtlSubAuthoritySid( BambamSid, 3)) = BAMBAM_RID;

    RtlCopySid( SidWithFourSubAuthorities, FlintstoneSid, BedrockDomainSid);
    *(RtlSubAuthorityCountSid( FlintstoneSid )) += 1;
    *(RtlSubAuthoritySid( FlintstoneSid, 3)) = FLINTSTONE_RID;

    RtlCopySid( SidWithFourSubAuthorities, RubbleSid, BedrockDomainSid);
    *(RtlSubAuthorityCountSid( RubbleSid )) += 1;
    *(RtlSubAuthoritySid( RubbleSid, 3)) = RUBBLE_RID;

    RtlCopySid( SidWithFourSubAuthorities, AdultSid, BedrockDomainSid);
    *(RtlSubAuthorityCountSid( AdultSid )) += 1;
    *(RtlSubAuthoritySid( AdultSid, 3)) = ADULT_RID;

    RtlCopySid( SidWithFourSubAuthorities, ChildSid, BedrockDomainSid);
    *(RtlSubAuthorityCountSid( ChildSid )) += 1;
    *(RtlSubAuthoritySid( ChildSid, 3)) = CHILD_RID;

    RtlCopySid( SidWithFourSubAuthorities, NeandertholSid, BedrockDomainSid);
    *(RtlSubAuthorityCountSid( NeandertholSid )) += 1;
    *(RtlSubAuthoritySid( NeandertholSid, 3)) = NEANDERTHOL_RID;

    CreateTokenPrivilege =
        RtlConvertLongToLargeInteger(SE_CREATE_TOKEN_PRIVILEGE);
    AssignPrimaryTokenPrivilege =
        RtlConvertLongToLargeInteger(SE_ASSIGNPRIMARYTOKEN_PRIVILEGE);
    LockMemoryPrivilege =
        RtlConvertLongToLargeInteger(SE_LOCK_MEMORY_PRIVILEGE);
    IncreaseQuotaPrivilege =
        RtlConvertLongToLargeInteger(SE_INCREASE_QUOTA_PRIVILEGE);
    UnsolicitedInputPrivilege =
        RtlConvertLongToLargeInteger(SE_UNSOLICITED_INPUT_PRIVILEGE);
    TcbPrivilege =
        RtlConvertLongToLargeInteger(SE_TCB_PRIVILEGE);
    SecurityPrivilege =
        RtlConvertLongToLargeInteger(SE_SECURITY_PRIVILEGE);
    TakeOwnershipPrivilege =
        RtlConvertLongToLargeInteger(SE_TAKE_OWNERSHIP_PRIVILEGE);
    LpcReplyBoostPrivilege =
        RtlConvertLongToLargeInteger(SE_LPC_REPLY_BOOST_PRIVILEGE);
    CreatePagefilePrivilege =
        RtlConvertLongToLargeInteger(SE_CREATE_PAGEFILE_PRIVILEGE);
    IncreaseBasePriorityPrivilege =
        RtlConvertLongToLargeInteger(SE_INC_BASE_PRIORITY_PRIVILEGE);
    SystemProfilePrivilege =
        RtlConvertLongToLargeInteger(SE_SYSTEM_PROFILE_PRIVILEGE);
    SystemtimePrivilege =
        RtlConvertLongToLargeInteger(SE_SYSTEMTIME_PRIVILEGE);
    ProfileSingleProcessPrivilege =
        RtlConvertLongToLargeInteger(SE_PROF_SINGLE_PROCESS_PRIVILEGE);
    CreatePermanentPrivilege =
        RtlConvertLongToLargeInteger(SE_CREATE_PERMANENT_PRIVILEGE);
    BackupPrivilege =
        RtlConvertLongToLargeInteger(SE_BACKUP_PRIVILEGE);
    RestorePrivilege =
        RtlConvertLongToLargeInteger(SE_RESTORE_PRIVILEGE);
    ShutdownPrivilege =
        RtlConvertLongToLargeInteger(SE_SHUTDOWN_PRIVILEGE);
    DebugPrivilege =
        RtlConvertLongToLargeInteger(SE_DEBUG_PRIVILEGE);


    return TRUE;

}
Beispiel #21
0
/******************************************************************************
 * GetSidSubAuthority [ADVAPI32.@]
 *
 * PARAMS
 *   pSid          []
 *   nSubAuthority []
 */
PDWORD WINAPI
GetSidSubAuthority( PSID pSid, DWORD nSubAuthority )
{
    return RtlSubAuthoritySid(pSid, nSubAuthority);
}
Beispiel #22
0
NTSTATUS
SampFixBug18471 (
    IN ULONG Revision
    )
/*++

Routine Description:

    This routine fixes bug 18471, that SAM does not adjust the protection
    on groups that are members of administrative aliases in the builtin
    domain. It fixes this by opening a fixed set of known aliases
    (Administrators, Account Operators, Backup Operators, Print Operators,
    and Server Operators), and enumerating their members.  To fix this,
    we will remove all the members of these aliases (except the
    Administrator user account) and re-add them.

Arguments:

    Revision - Revision of the Sam server.

Return Value:


    Note:


--*/
{
    NTSTATUS            Status;
    ULONG               Index, Index2;
    PSID                BuiltinDomainSid = NULL;
    SID_IDENTIFIER_AUTHORITY BuiltinAuthority = SECURITY_NT_AUTHORITY;
    PSID                AccountDomainSid;
    ULONG               AccountDomainIndex = 0xffffffff;
    ULONG               BuiltinDomainIndex = 0xffffffff;
    SAMPR_PSID_ARRAY    AliasMembership;
    ULONG               MemberRid;
    ULONG               SdRevision;
    PSECURITY_DESCRIPTOR OldDescriptor;
    PSECURITY_DESCRIPTOR SecurityDescriptor;
    ULONG               SecurityDescriptorLength;
    SAMP_OBJECT_TYPE    MemberType;
    PSAMP_OBJECT        MemberContext;
    PSAMP_OBJECT        AliasContext;
    SAMP_V1_0A_FIXED_LENGTH_GROUP GroupV1Fixed;
    SAMP_V1_0A_FIXED_LENGTH_USER UserV1Fixed;

    //
    // Check the revision on the server to see if this upgrade has
    // already been performed.
    //


    if (Revision >= SAMP_SERVER_REVISION) {

        //
        // This upgrade has already been performed.
        //

        goto Cleanup;
    }


    //
    // Build a the BuiltIn domain SID.
    //

    BuiltinDomainSid  = RtlAllocateHeap(RtlProcessHeap(), 0,RtlLengthRequiredSid( 1 ));

    if ( BuiltinDomainSid == NULL ) {
        Status = STATUS_INSUFFICIENT_RESOURCES;
        goto Cleanup;
    }

    RtlInitializeSid( BuiltinDomainSid,   &BuiltinAuthority, 1 );
    *(RtlSubAuthoritySid( BuiltinDomainSid,  0 )) = SECURITY_BUILTIN_DOMAIN_RID;


    //
    // Lookup the index of the account domain
    //

    for (Index = 0;
         Index < SampDefinedDomainsCount ;
         Index++ ) {

        if (RtlEqualSid( BuiltinDomainSid, SampDefinedDomains[Index].Sid)) {
            BuiltinDomainIndex = Index;
        } else {
            AccountDomainIndex = Index;
        }
    }

    ASSERT(AccountDomainIndex < SampDefinedDomainsCount);
    ASSERT(BuiltinDomainIndex < SampDefinedDomainsCount);

    AccountDomainSid = SampDefinedDomains[AccountDomainIndex].Sid;

    //
    // Create out transaction log
    //

    Status = SampCreate18471Key();
    if (!NT_SUCCESS(Status)) {
        goto Cleanup;
    }




    //
    // Now loop through and open the aliases we are intersted in
    //

    for (Index = 0;
         Index < ADMINISTRATIVE_ALIAS_COUNT ;
         Index++ )
    {

        SampSetTransactionDomain( BuiltinDomainIndex );

        SampAcquireReadLock();

        Status = SampCreateAccountContext(
                    SampAliasObjectType,
                    AdministrativeRids[Index],
                    TRUE,                       // Trusted client
                    TRUE,                       // Account exists
                    &AliasContext
                    );

        if ( !NT_SUCCESS(Status) ) {

            SampReleaseReadLock();
            if (Status == STATUS_NO_SUCH_ALIAS) {
                Status = STATUS_SUCCESS;
                continue;
            } else {

                goto Cleanup;
            }
        }


        //
        // Get the members in the alias so we can remove and re-add them
        //

        Status = SampRetrieveAliasMembers(
                    AliasContext,
                    &(AliasMembership.Count),
                    (PSID **)&(AliasMembership.Sids)
                    );

        SampDeleteContext(AliasContext);
        SampReleaseReadLock();
        if (!NT_SUCCESS(Status)) {
            break;
        }

        //
        // Write that we are opening this alias to the log.  We don't need
        // to do this for administrators, since for them we the update is
        // idempotent.
        //

        if (AdministrativeRids[Index] != DOMAIN_ALIAS_RID_ADMINS) {
            Status = SampAddAliasTo18471Key(
                        AdministrativeRids[Index]
                        );
            if (!NT_SUCCESS(Status)) {
                break;
            }
        }


        //
        // Loop through the members and split each sid.  For every
        // member in the account domain , remove it and re-add it from
        // this alias.
        //




        for (Index2 = 0; Index2 < AliasMembership.Count ; Index2++ )
        {
            //
            // Check to see if this account is in the account domain
            //

            if ( SampMatchDomainPrefix(
                    (PSID) AliasMembership.Sids[Index2].SidPointer,
                    AccountDomainSid
                    ) )
            {

                //
                // Get the RID for this member
                //

                MemberRid = *RtlSubAuthoritySid(
                                AliasMembership.Sids[Index2].SidPointer,
                                *RtlSubAuthorityCountSid(
                                    AliasMembership.Sids[Index2].SidPointer
                                ) - 1
                                );

                //
                // Now remove and re-add the administratie nature of this
                // membership
                //

                if (AdministrativeRids[Index] == DOMAIN_ALIAS_RID_ADMINS) {

                    Status = SampAcquireWriteLock();
                    if (!NT_SUCCESS(Status)) {
                        break;
                    }

                    SampSetTransactionDomain( AccountDomainIndex );

                    //
                    // Try to create a context for the account as a group.
                    //

                    Status = SampCreateAccountContext(
                                     SampGroupObjectType,
                                     MemberRid,
                                     TRUE, // Trusted client
                                     TRUE, // Account exists
                                     &MemberContext
                                     );

                    if (!NT_SUCCESS( Status ) ) {

                        //
                        // If this ID does not exist as a group, that's fine -
                        // it might be a user or might have been deleted.
                        //

                        SampReleaseWriteLock( FALSE );
                        if (Status == STATUS_NO_SUCH_GROUP) {
                            Status = STATUS_SUCCESS;
                            continue;
                        }
                        break;
                    }

                    //
                    // Now set a flag in the group itself,
                    // so that when users are added and removed
                    // in the future it is known whether this
                    // group is in an ADMIN alias or not.
                    //

                    Status = SampRetrieveGroupV1Fixed(
                                   MemberContext,
                                   &GroupV1Fixed
                                   );

                    if ( NT_SUCCESS(Status)) {

                        GroupV1Fixed.AdminCount = 1;

                        Status = SampReplaceGroupV1Fixed(
                                    MemberContext,
                                    &GroupV1Fixed
                                    );
                        //
                        // Modify the security descriptor to
                        // prevent account operators from adding
                        // anybody to this group
                        //

                        if ( NT_SUCCESS( Status ) ) {

                            Status = SampGetAccessAttribute(
                                        MemberContext,
                                        SAMP_GROUP_SECURITY_DESCRIPTOR,
                                        FALSE, // don't make copy
                                        &SdRevision,
                                        &OldDescriptor
                                        );

                            if (NT_SUCCESS(Status)) {

                                Status = SampModifyAccountSecurity(
                                            SampGroupObjectType,
                                            TRUE, // this is an admin
                                            OldDescriptor,
                                            &SecurityDescriptor,
                                            &SecurityDescriptorLength
                                            );
                            }

                            if ( NT_SUCCESS( Status ) ) {

                                //
                                // Write the new security descriptor into the object
                                //

                                Status = SampSetAccessAttribute(
                                               MemberContext,
                                               SAMP_USER_SECURITY_DESCRIPTOR,
                                               SecurityDescriptor,
                                               SecurityDescriptorLength
                                               );

                                MIDL_user_free( SecurityDescriptor );
                            }



                        }
                        if (NT_SUCCESS(Status)) {

                            //
                            // Add the modified group to the current transaction
                            // Don't use the open key handle since we'll be deleting the context.
                            //

                            Status = SampStoreObjectAttributes(MemberContext, FALSE);

                        }

                    }

                    //
                    // Clean up the group context
                    //

                    SampDeleteContext(MemberContext);

                    //
                    // we don't want the modified count to change
                    //

                    SampTransactionWithinDomain = FALSE;

                    if (NT_SUCCESS(Status)) {
                        Status = SampReleaseWriteLock( TRUE );
                    } else {
                        (VOID) SampReleaseWriteLock( FALSE );
                    }

                }
                else
                {


                    //
                    // Check to see if we've already upgraded this member
                    //

                    Status = SampCheckMemberUpgradedFor18471(
                                AdministrativeRids[Index],
                                MemberRid);

                    if (NT_SUCCESS(Status)) {

                        //
                        // This member already was upgraded.
                        //

                        continue;
                    } else {

                        //
                        // We continue on with the upgrade
                        //

                        Status = STATUS_SUCCESS;
                    }

                    //
                    // Change the operator account for the other
                    // aliases.
                    //

                    if (NT_SUCCESS(Status)) {

                        Status = SampAcquireWriteLock();
                        if (!NT_SUCCESS(Status)) {
                            break;
                        }

                        SampSetTransactionDomain( AccountDomainIndex );

                        Status = SampChangeAccountOperatorAccessToMember(
                                    AliasMembership.Sids[Index2].SidPointer,
                                    NoChange,
                                    AddToAdmin
                                    );

                        //
                        // If that succeeded, add this member to the log
                        // as one that was upgraded.
                        //

                        if (NT_SUCCESS(Status)) {
                            Status = SampAddMemberRidTo18471Key(
                                        AdministrativeRids[Index],
                                        MemberRid
                                        );

                        }

                        //
                        // We don't want the modified count to be updated so
                        // make this not a domain transaction
                        //

                        SampTransactionWithinDomain = FALSE;
                                                if (NT_SUCCESS(Status)) {
                            Status = SampReleaseWriteLock( TRUE );
                        } else {
                            (VOID) SampReleaseWriteLock( FALSE );
                        }

                    }

                    if (!NT_SUCCESS(Status)) {
                        break;
                    }

                }
            }
        }

        SamIFree_SAMPR_PSID_ARRAY(
            &AliasMembership
            );
        AliasMembership.Sids = NULL;


        //
        // If something up above failed or the upgrade was already done,
        // exit now.
        //

        if (!NT_SUCCESS(Status)) {
            break;
        }
    }

Cleanup:

    if (BuiltinDomainSid != NULL) {
        RtlFreeHeap(
            RtlProcessHeap(),
            0,
            BuiltinDomainSid
            );
    }

    if (NT_SUCCESS(Status)) {
        Status = SampCleanup18471();
    }
    return(Status);
}
Beispiel #23
0
BOOLEAN
SampMatchDomainPrefix(
    IN PSID AccountSid,
    IN PSID DomainSid
    )

/*++

Routine Description:

    This function compares the domain sid to the domain prefix of an
    account sid.

Arguments:

    AccountSid - Specifies the account Sid to be compared. The Sid is assumed to be
        syntactically valid.

    DomainSid - Specifies the domain Sid to compare against.


Return Value:

    TRUE - The account Sid is from the Domain specified by the domain Sid

    FALSE - The domain prefix of the account Sid did not match the domain.

--*/

{
    //
    // Check if the account Sid has one more subauthority than the
    // domain Sid.
    //

    if (*RtlSubAuthorityCountSid(DomainSid) + 1 !=
        *RtlSubAuthorityCountSid(AccountSid)) {
        return(FALSE);
    }

    if (memcmp(
            RtlIdentifierAuthoritySid(DomainSid),
            RtlIdentifierAuthoritySid(AccountSid),
            sizeof(SID_IDENTIFIER_AUTHORITY) ) ) {

        return(FALSE);
    }

    //
    // Compare the sub authorities
    //

    if (memcmp(
            RtlSubAuthoritySid(DomainSid, 0) ,
            RtlSubAuthoritySid(AccountSid, 0) ,
            *RtlSubAuthorityCountSid(DomainSid)
            ))
    {
        return(FALSE);
    }

    return(TRUE);

}
Beispiel #24
0
//----------------------------------------------------------------------
//
// NTIRemoveWorldAce
// 
// Scans the passed security descriptor's DACL, looking for
// the World SID's ACE (its first because the of the way device object
// security descriptors are created) and removes it.
//
// If successful, the original security descriptor is deallocated
// and a new one is returned.
//
//----------------------------------------------------------------------
NTSTATUS NTIRemoveWorldAce( PSECURITY_DESCRIPTOR SecurityDescriptor,
			    PSECURITY_DESCRIPTOR *NewSecurityDescriptor )
{
   PSECURITY_DESCRIPTOR	     absSecurityDescriptor;
   PSECURITY_DESCRIPTOR	     relSecurityDescriptor;
   PACE_HEADER               aceHeader;
   NTSTATUS		     status;
   PACL			     Dacl;
   BOOLEAN		     DaclPresent, DaclDefaulted;
   USHORT                    aceIndex;
   ULONG                     worldSidLength;
   SID_IDENTIFIER_AUTHORITY  worldSidAuthority = SECURITY_WORLD_SID_AUTHORITY;
   PULONG                    worldSidSubAuthority;
   ULONG                     relLength;
   PSID                      worldSid;
   PSID                      aceSid;

   //
   // First, get an absolute version of the self-relative descriptor
   //
   relLength = RtlLengthSecurityDescriptor( SecurityDescriptor );
   status = NTIMakeAbsoluteSD( SecurityDescriptor, 
			       &absSecurityDescriptor );
   if( !NT_SUCCESS( status )) {
	  
     return status;
   }

   //
   // Pull the DACL out so that we can scan it
   //
   status = RtlGetDaclSecurityDescriptor( absSecurityDescriptor,
					  &DaclPresent,
					  &Dacl,
					  &DaclDefaulted );
   if( !NT_SUCCESS( status ) || !DaclPresent ) {

     DbgPrint(("Secsys: strange - couldn't get DACL from our absolute SD: %x\n", 
	       status ));
     ExFreePool( absSecurityDescriptor );
     return status;
   }

   //
   // Initialize a SID that identifies the world-authority so
   // that we can recognize it in the ACL
   //
   worldSidLength = RtlLengthRequiredSid( 1 );
   worldSid = (PSID) ExAllocatePool( PagedPool, worldSidLength );
   RtlInitializeSid( worldSid, &worldSidAuthority, 1 );
   worldSidSubAuthority = RtlSubAuthoritySid( worldSid, 0 );
   *worldSidSubAuthority = SECURITY_WORLD_RID;

   //
   // Now march through the ACEs looking for the World ace. We could 
   // do one of two things: 
   //
   //	- remove the ACE
   //	- convert it into a grant-nothing ACE
   //
   // For demonstration purposes I'll remove the ACE. In addition,
   // this requires that I implement kernel-mode GetAce and DeleteAce functions,
   // since they are not implemented by the NT kernel.
   //
   DbgPrint(("Secsys: %d ACEs in DACL\n", Dacl->AceCount ));

   for( aceIndex = 0; aceIndex < Dacl->AceCount; aceIndex++ ) {

     aceHeader = NTIGetAce( Dacl, aceIndex );
     
     DbgPrint(("  ACE: type: %s mask: %x\n", 
	       (aceHeader->AceType & ACCESS_DENIED_ACE_TYPE ? "Deny" : "Allow"),
	       *(PULONG) ((PUCHAR) aceHeader + sizeof(ACE_HEADER))));

     //
     // Get the SID in this ACE and see if its the WORLD (Everyone) SID
     //
     aceSid    = (PSID) ((PUCHAR) aceHeader + sizeof(ACE_HEADER) + sizeof(ULONG));
     if( RtlEqualSid( worldSid, aceSid )) {

       //
       // We found it: remove it.
       //
       DbgPrint(("Secsys: Deleting ace %d\n", aceIndex ));
       NTIDeleteAce( Dacl, aceIndex );
       break;
     }
   }

   // 
   // Write new DACL back to security descriptor
   //
   status = RtlSetDaclSecurityDescriptor( absSecurityDescriptor,
					  TRUE,
					  Dacl,
					  FALSE );
   if( !NT_SUCCESS( status )) {

      DbgPrint(("Secsys: Could not update SD Dacl: %x\n", status ));
      goto cleanup;
   }

   // 
   // Make sure its valid
   //
   if( !RtlValidSecurityDescriptor( absSecurityDescriptor )) {

      DbgPrint(("Secsys: SD after remove is invalid!\n"));
      status = STATUS_UNSUCCESSFUL;
      goto cleanup;
   }

   //
   // Now convert the security descriptor back to 
   // self-relative
   //
   relSecurityDescriptor = ExAllocatePool( PagedPool, relLength );
   status = RtlAbsoluteToSelfRelativeSD( absSecurityDescriptor,
					 relSecurityDescriptor, &relLength );
   if( !NT_SUCCESS( status )) {

     DbgPrint(("Could not convert absolute SD to relative: %x\n", status ));
   }

   //
   // Final step, free the original security descriptor and return the new one
   //
   ExFreePool( SecurityDescriptor );
   *NewSecurityDescriptor = relSecurityDescriptor;

cleanup:
   ExFreePool( worldSid );
   ExFreePool( absSecurityDescriptor );
   return status;
}
Beispiel #25
0
/******************************************************************************
*  NtQueryInformationToken		[NTDLL.@]
*  ZwQueryInformationToken		[NTDLL.@]
*
* NOTES
*  Buffer for TokenUser:
*   0x00 TOKEN_USER the PSID field points to the SID
*   0x08 SID
*
*/
NTSTATUS WINAPI NtQueryInformationToken(
	HANDLE token,
	TOKEN_INFORMATION_CLASS tokeninfoclass,
	PVOID tokeninfo,
	ULONG tokeninfolength,
	PULONG retlen )
{
    ULONG len;
    NTSTATUS status = STATUS_SUCCESS;

    TRACE("(%p,%d,%p,%ld,%p)\n",
          token,tokeninfoclass,tokeninfo,tokeninfolength,retlen);

    switch (tokeninfoclass)
    {
    case TokenOwner:
        len = sizeof(TOKEN_OWNER) + sizeof(SID);
        break;
    case TokenPrimaryGroup:
        len = sizeof(TOKEN_PRIMARY_GROUP);
        break;
    case TokenDefaultDacl:
        len = sizeof(TOKEN_DEFAULT_DACL);
        break;
    case TokenSource:
        len = sizeof(TOKEN_SOURCE);
        break;
    case TokenType:
        len = sizeof (TOKEN_TYPE);
        break;
#if 0
    case TokenImpersonationLevel:
    case TokenStatistics:
#endif /* 0 */
    default:
        len = 0;
    }

    if (retlen) *retlen = len;

    if (tokeninfolength < len)
        return STATUS_BUFFER_TOO_SMALL;

    switch (tokeninfoclass)
    {
    case TokenUser:
        SERVER_START_REQ( get_token_user )
        {
            TOKEN_USER * tuser = tokeninfo;
            PSID sid = (PSID) (tuser + 1);
            DWORD sid_len = tokeninfolength < sizeof(TOKEN_USER) ? 0 : tokeninfolength - sizeof(TOKEN_USER);

            req->handle = token;
            wine_server_set_reply( req, sid, sid_len );
            status = wine_server_call( req );
            if (retlen) *retlen = reply->user_len + sizeof(TOKEN_USER);
            if (status == STATUS_SUCCESS)
            {
                tuser->User.Sid = sid;
                tuser->User.Attributes = 0;
            }
        }
        SERVER_END_REQ;
        break;
    case TokenGroups:
    {
        char stack_buffer[256];
        unsigned int server_buf_len = sizeof(stack_buffer);
        void *buffer = stack_buffer;
        BOOLEAN need_more_memory = FALSE;

        /* we cannot work out the size of the server buffer required for the
         * input size, since there are two factors affecting how much can be
         * stored in the buffer - number of groups and lengths of sids */
        do
        {
            SERVER_START_REQ( get_token_groups )
            {
                TOKEN_GROUPS *groups = tokeninfo;

                req->handle = token;
                wine_server_set_reply( req, buffer, server_buf_len );
                status = wine_server_call( req );
                if (status == STATUS_BUFFER_TOO_SMALL)
                {
                    if (buffer == stack_buffer)
                        buffer = RtlAllocateHeap(GetProcessHeap(), 0, reply->user_len);
                    else
                        buffer = RtlReAllocateHeap(GetProcessHeap(), 0, buffer, reply->user_len);
                    if (!buffer) return STATUS_NO_MEMORY;

                    server_buf_len = reply->user_len;
                    need_more_memory = TRUE;
                }
                else if (status == STATUS_SUCCESS)
                {
                    struct token_groups *tg = buffer;
                    unsigned int *attr = (unsigned int *)(tg + 1);
                    ULONG i;
                    const int non_sid_portion = (sizeof(struct token_groups) + tg->count * sizeof(unsigned long));
                    SID *sids = (SID *)((char *)tokeninfo + FIELD_OFFSET( TOKEN_GROUPS, Groups[tg->count] ));
                    ULONG needed_bytes = FIELD_OFFSET( TOKEN_GROUPS, Groups[tg->count] ) +
                        reply->user_len - non_sid_portion;

                    if (retlen) *retlen = needed_bytes;

                    if (needed_bytes <= tokeninfolength)
                    {
                        groups->GroupCount = tg->count;
                        memcpy( sids, (char *)buffer + non_sid_portion,
                                reply->user_len - non_sid_portion );

                        for (i = 0; i < tg->count; i++)
                        {
                            groups->Groups[i].Attributes = attr[i];
                            groups->Groups[i].Sid = sids;
                            sids = (SID *)((char *)sids + RtlLengthSid(sids));
                        }
                    }
                    else status = STATUS_BUFFER_TOO_SMALL;
                }
                else if (retlen) *retlen = 0;
            }
            SERVER_END_REQ;
        } while (need_more_memory);
        if (buffer != stack_buffer) RtlFreeHeap(GetProcessHeap(), 0, buffer);
        break;
    }
    case TokenPrimaryGroup:
        if (tokeninfo)
        {
            TOKEN_PRIMARY_GROUP *tgroup = tokeninfo;
            SID_IDENTIFIER_AUTHORITY sid = {SECURITY_NT_AUTHORITY};
            RtlAllocateAndInitializeSid( &sid,
                                         2,
                                         SECURITY_BUILTIN_DOMAIN_RID,
                                         DOMAIN_ALIAS_RID_ADMINS,
                                         0, 0, 0, 0, 0, 0,
                                         &(tgroup->PrimaryGroup));
        }
        break;
    case TokenPrivileges:
        SERVER_START_REQ( get_token_privileges )
        {
            TOKEN_PRIVILEGES *tpriv = tokeninfo;
            req->handle = token;
            if (tpriv && tokeninfolength > FIELD_OFFSET( TOKEN_PRIVILEGES, Privileges ))
                wine_server_set_reply( req, &tpriv->Privileges, tokeninfolength - FIELD_OFFSET( TOKEN_PRIVILEGES, Privileges ) );
            status = wine_server_call( req );
            if (retlen) *retlen = FIELD_OFFSET( TOKEN_PRIVILEGES, Privileges ) + reply->len;
            if (tpriv) tpriv->PrivilegeCount = reply->len / sizeof(LUID_AND_ATTRIBUTES);
        }
        SERVER_END_REQ;
        break;
    case TokenOwner:
        if (tokeninfo)
        {
            TOKEN_OWNER *owner = tokeninfo;
            PSID sid = (PSID) (owner + 1);
            SID_IDENTIFIER_AUTHORITY localSidAuthority = {SECURITY_NT_AUTHORITY};
            RtlInitializeSid(sid, &localSidAuthority, 1);
            *(RtlSubAuthoritySid(sid, 0)) = SECURITY_INTERACTIVE_RID;
            owner->Owner = sid;
        }
        break;
    default:
        {
            ERR("Unhandled Token Information class %d!\n", tokeninfoclass);
            return STATUS_NOT_IMPLEMENTED;
        }
    }
    return status;
}