static
DWORD
LwpsLegacyCreateSecurityDescriptor(
    IN BOOLEAN bIsWorldReadable,
    IN OUT PSECURITY_DESCRIPTOR_ABSOLUTE *ppSecurityDescriptor
    )
{
    NTSTATUS status = STATUS_SUCCESS;
    int EE = 0;
    PSECURITY_DESCRIPTOR_ABSOLUTE pSecDesc = NULL;
    PACL pDacl = NULL;
    PSID pRootSid = NULL;
    PSID pAdminsSid = NULL;
    PSID pEveryoneSid = NULL;
    PSID pOwnerSid = NULL;
    PSID pGroupSid = NULL;
    DWORD dwError = 0;

    status = RtlAllocateWellKnownSid(WinLocalSystemSid, NULL, &pRootSid);
    GOTO_CLEANUP_ON_STATUS_EE(status, EE);

    status = RtlAllocateWellKnownSid(WinBuiltinAdministratorsSid, NULL, &pAdminsSid);
    GOTO_CLEANUP_ON_STATUS_EE(status, EE);

    if (bIsWorldReadable)
    {
        status = RtlAllocateWellKnownSid(WinWorldSid, NULL, &pEveryoneSid);
        GOTO_CLEANUP_ON_STATUS_EE(status, EE);
    }

    status = LW_RTL_ALLOCATE(
                    &pSecDesc,
                    VOID,
                    SECURITY_DESCRIPTOR_ABSOLUTE_MIN_SIZE);
    GOTO_CLEANUP_ON_STATUS_EE(status, EE);

    status = RtlCreateSecurityDescriptorAbsolute(
                    pSecDesc,
                    SECURITY_DESCRIPTOR_REVISION);
    GOTO_CLEANUP_ON_STATUS_EE(status, EE);

    // Owner: Root

    status = RtlDuplicateSid(&pOwnerSid, pRootSid);
    GOTO_CLEANUP_ON_STATUS_EE(status, EE);

    status = RtlSetOwnerSecurityDescriptor(
                    pSecDesc,
                    pOwnerSid,
                    FALSE);
    GOTO_CLEANUP_ON_STATUS_EE(status, EE);
    pOwnerSid = NULL;

    // Group: Administrators

    status = RtlDuplicateSid(&pGroupSid, pAdminsSid);
    GOTO_CLEANUP_ON_STATUS_EE(status, EE);

    status = RtlSetGroupSecurityDescriptor(
                    pSecDesc,
                    pGroupSid,
                    FALSE);
    GOTO_CLEANUP_ON_STATUS_EE(status, EE);
    pGroupSid = NULL;

    // Do not set Sacl currently

    // DACL
    status = LwpsLegacyBuildRestrictedDaclForKey(
                    pRootSid,
                    pEveryoneSid,
                    &pDacl);
    GOTO_CLEANUP_ON_STATUS_EE(status, EE);

    status = RtlSetDaclSecurityDescriptor(
                    pSecDesc,
                    TRUE,
                    pDacl,
                    FALSE);
    GOTO_CLEANUP_ON_STATUS_EE(status, EE);
    pDacl = NULL;

    if (!RtlValidSecurityDescriptor(pSecDesc))
    {
        status = STATUS_INVALID_SECURITY_DESCR;
        GOTO_CLEANUP_ON_STATUS_EE(status, EE);
    }

cleanup:
    if (status)
    {
        if (pSecDesc)
        {
            LwpsLegacyFreeSecurityDescriptor(&pSecDesc);
        }
    }

    LW_RTL_FREE(&pDacl);
    LW_RTL_FREE(&pRootSid);
    LW_RTL_FREE(&pAdminsSid);
    LW_RTL_FREE(&pEveryoneSid);
    LW_RTL_FREE(&pOwnerSid);
    LW_RTL_FREE(&pGroupSid);

    *ppSecurityDescriptor = pSecDesc;

    dwError = LwNtStatusToWin32Error(status);
    LSA_PSTORE_LOG_LEAVE_ERROR_EE(dwError, EE);
    return dwError;
}
Exemplo n.º 2
0
static
NTSTATUS
LsaDisableMachineAccount(
    IN PCWSTR pwszDCName,
    IN LW_PIO_CREDS pCreds,
    IN PCWSTR pwszMachineAccountName
    )
{
    const DWORD dwConnAccess = SAMR_ACCESS_OPEN_DOMAIN |
                               SAMR_ACCESS_ENUM_DOMAINS;

    const DWORD dwDomainAccess = DOMAIN_ACCESS_ENUM_ACCOUNTS |
                                 DOMAIN_ACCESS_OPEN_ACCOUNT |
                                 DOMAIN_ACCESS_LOOKUP_INFO_2;

    const DWORD dwUserAccess = USER_ACCESS_GET_ATTRIBUTES |
                               USER_ACCESS_SET_ATTRIBUTES |
                               USER_ACCESS_SET_PASSWORD;

    NTSTATUS ntStatus = STATUS_SUCCESS;
    SAMR_BINDING hSamrBinding = NULL;
    CONNECT_HANDLE hConnect = NULL;
    PSID pBuiltinSid = NULL;
    DWORD dwResume = 0;
    DWORD dwSize = 256;
    PWSTR *ppwszDomainNames = NULL;
    DWORD i = 0;
    DWORD dwNumEntries = 0;
    PSID pSid = NULL;
    PSID pDomainSid = NULL;
    DOMAIN_HANDLE hDomain = NULL;
    PDWORD pdwRids = NULL;
    PDWORD pdwTypes = NULL;
    ACCOUNT_HANDLE hUser = NULL;
    DWORD dwLevel = 0;
    UserInfo *pInfo = NULL;
    DWORD dwFlagsDisable = 0;
    UserInfo Info;

    memset(&Info, 0, sizeof(Info));

    ntStatus = SamrInitBindingDefault(&hSamrBinding,
                                      pwszDCName,
                                      pCreds);
    BAIL_ON_NT_STATUS(ntStatus);
    
    ntStatus = SamrConnect2(hSamrBinding,
                            pwszDCName,
                            dwConnAccess,
                            &hConnect);
    BAIL_ON_NT_STATUS(ntStatus);    

    ntStatus = RtlAllocateWellKnownSid(
                    WinBuiltinDomainSid,
                    NULL,
                    &pBuiltinSid);
    BAIL_ON_NT_STATUS(ntStatus);

    do
    {
        ntStatus = SamrEnumDomains(hSamrBinding,
                                   hConnect,
                                   &dwResume,
                                   dwSize,
                                   &ppwszDomainNames,
                                   &dwNumEntries);
        BAIL_ON_NT_STATUS(ntStatus);

        if (ntStatus != STATUS_SUCCESS &&
            ntStatus != STATUS_MORE_ENTRIES)
        {
            BAIL_ON_NT_STATUS(ntStatus);
        }

        for (i = 0; pDomainSid == NULL && i < dwNumEntries; i++)
        {
            ntStatus = SamrLookupDomain(hSamrBinding,
                                        hConnect,
                                        ppwszDomainNames[i],
                                        &pSid);
            BAIL_ON_NT_STATUS(ntStatus);

            if (!RtlEqualSid(pSid, pBuiltinSid))
            {
                ntStatus = RtlDuplicateSid(&pDomainSid, pSid);
                BAIL_ON_NT_STATUS(ntStatus);
            }

            SamrFreeMemory(pSid);
            pSid = NULL;
        }

        if (ppwszDomainNames)
        {
            SamrFreeMemory(ppwszDomainNames);
            ppwszDomainNames = NULL;
        }
    }
    while (ntStatus == STATUS_MORE_ENTRIES);

    ntStatus = SamrOpenDomain(hSamrBinding,
                              hConnect,
                              dwDomainAccess,
                              pDomainSid,
                              &hDomain);
    BAIL_ON_NT_STATUS(ntStatus);

    ntStatus = SamrLookupNames(hSamrBinding,
                               hDomain,
                               1,
                               (PWSTR*)&pwszMachineAccountName,
                               &pdwRids,
                               &pdwTypes,
                               NULL);
    if (ntStatus == STATUS_NONE_MAPPED)
    {
        BAIL_ON_LSA_ERROR(NERR_SetupAlreadyJoined);
    }

    ntStatus = SamrOpenUser(hSamrBinding,
                            hDomain,
                            dwUserAccess,
                            pdwRids[0],
                            &hUser);
    BAIL_ON_NT_STATUS(ntStatus);

    dwLevel = 16;

    ntStatus = SamrQueryUserInfo(hSamrBinding,
                                 hUser,
                                 dwLevel,
                                 &pInfo);
    BAIL_ON_NT_STATUS(ntStatus);

    dwFlagsDisable = pInfo->info16.account_flags | ACB_DISABLED;

    Info.info16.account_flags = dwFlagsDisable;
    ntStatus = SamrSetUserInfo2(hSamrBinding,
                                hUser,
                                dwLevel,
                                &Info);
    BAIL_ON_NT_STATUS(ntStatus);

cleanup:
    if (hSamrBinding && hUser)
    {
        SamrClose(hSamrBinding, hUser);
    }

    if (hSamrBinding && hDomain)
    {
        SamrClose(hSamrBinding, hDomain);
    }

    if (hSamrBinding && hConnect)
    {
        SamrClose(hSamrBinding, hConnect);
    }

    if (hSamrBinding)
    {
        SamrFreeBinding(&hSamrBinding);
    }

    if (pInfo)
    {
        SamrFreeMemory(pInfo);
    }

    if (pdwRids)
    {
        SamrFreeMemory(pdwRids);
    }

    if (pdwTypes)
    {
        SamrFreeMemory(pdwTypes);
    }

    if (ppwszDomainNames)
    {
        SamrFreeMemory(ppwszDomainNames);
    }

    RTL_FREE(&pBuiltinSid);
    RTL_FREE(&pDomainSid);

    return ntStatus;

error:
    goto cleanup;
}