Example #1
0
static
NTSTATUS
NtpAllocAsyncContext(
    OUT PVOID* ppContext,
    size_t Size
    )
{
    NTSTATUS status = STATUS_SUCCESS;
    PIO_CLIENT_ASYNC_CONTEXT pContext = NULL;
    static const LWMsgParams init = LWMSG_PARAMS_INITIALIZER;

    status = RTL_ALLOCATE(&pContext, IO_CLIENT_ASYNC_CONTEXT, Size);
    BAIL_ON_NT_STATUS(status);

    pContext->in = init;
    pContext->out = init;

    *ppContext = (PVOID) pContext;

error:

    if (status)
    {
        *ppContext = NULL;
    }

    return status;
}
Example #2
0
NTSTATUS
PvfsListInit(
    PPVFS_LIST *ppNewList,
    DWORD dwMaxSize,
    PPVFS_LIST_FREE_DATA_FN pfnFreeData
    )
{
    NTSTATUS ntError = STATUS_UNSUCCESSFUL;
    PPVFS_LIST pList = NULL;

    BAIL_ON_INVALID_PTR(ppNewList, ntError);

    ntError = RTL_ALLOCATE(&pList, PVFS_LIST, sizeof(PVFS_LIST));
    BAIL_ON_NT_STATUS(ntError);

    pList->MaxSize = dwMaxSize;
    pList->CurrentSize = 0;

    pList->pfnFreeData = pfnFreeData;

    LwListInit(&pList->DataList);

    *ppNewList = pList;
    pList = NULL;

    ntError = STATUS_SUCCESS;

cleanup:
    RTL_FREE(&pList);

    return ntError;

error:
    goto cleanup;
}
Example #3
0
NTSTATUS
RtlDuplicateSid(
    OUT PSID* NewSid,
    IN PSID OriginalSid
    )
{
    NTSTATUS status = STATUS_SUCCESS;
    ULONG length = RtlLengthSid(OriginalSid);
    PSID resultSid = NULL;

    status = RTL_ALLOCATE(&resultSid, SID, length);
    GOTO_CLEANUP_ON_STATUS(status);

    RtlCopyMemory(resultSid, OriginalSid, length);

cleanup:
    if (!NT_SUCCESS(status))
    {
        RTL_FREE(&resultSid);
    }

    *NewSid = resultSid;

    return status;
}
Example #4
0
NTSTATUS
LwRtlWC16StringDuplicate(
    OUT PWSTR* ppszNewString,
    IN PCWSTR pszOriginalString
    )
{
    NTSTATUS status = 0;
    int EE ATTRIBUTE_UNUSED = 0;
    size_t size = 0;
    PWSTR pszNewString = NULL;

    if (!pszOriginalString)
    {
        status = STATUS_INVALID_PARAMETER;
        GOTO_CLEANUP_ON_STATUS_EE(status, EE);
    }

    size = (LwRtlWC16StringNumChars(pszOriginalString) + 1) * sizeof(pszOriginalString[0]);

    status = RTL_ALLOCATE(&pszNewString, wchar16_t, size);
    GOTO_CLEANUP_ON_STATUS_EE(status, EE);

    memcpy(pszNewString, pszOriginalString, size);

cleanup:
    if (status)
    {
        RTL_FREE(&pszNewString);
    }

    *ppszNewString = pszNewString;

    return status;
}
Example #5
0
DWORD
UmnSrvInitConfig(
    PUMN_SRV_API_CONFIG *ppConfig
    )
{
    PUMN_SRV_API_CONFIG pConfig = NULL;
    DWORD dwError = 0;

    dwError = RTL_ALLOCATE(
                    &pConfig,
                    UMN_SRV_API_CONFIG,
                    sizeof(*pConfig));
    BAIL_ON_UMN_ERROR(dwError);

    pConfig->CheckInterval = 60 * 30;
    pConfig->SkipNoLogin = FALSE;

    *ppConfig = pConfig;

cleanup:
    return dwError;

error:
    *ppConfig = NULL;
    UmnSrvFreeConfig(pConfig);
    goto cleanup;
}
Example #6
0
static
NTSTATUS
ItpCreateDriverState(
    OUT PIT_DRIVER_STATE* ppState
    )
{
    NTSTATUS status = STATUS_SUCCESS;
    int EE = 0;
    PIT_DRIVER_STATE pState = NULL;

    status = RTL_ALLOCATE(&pState, IT_DRIVER_STATE, sizeof(*pState));
    GOTO_CLEANUP_ON_STATUS_EE(status, EE);

    status = ItCreateWorkQueue(&pState->pWorkQueue);
    GOTO_CLEANUP_ON_STATUS_EE(status, EE);

cleanup:
    if (status)
    {
        ItpDestroyDriverState(&pState);
    }

    *ppState = pState;

    LOG_LEAVE_IF_STATUS_EE(status, EE);
    return status;
}
Example #7
0
LW_NTSTATUS
LwIoAllocateMemory(
    size_t Size,
    LW_PVOID * ppMemory
    )
{
    return RTL_ALLOCATE(ppMemory, VOID, Size);
}
Example #8
0
NTSTATUS
PvfsAllocateMemory(
    OUT PVOID *ppBuffer,
    IN DWORD dwSize
    )
{
    /* No op */
    if (dwSize == 0)
    {
        *ppBuffer = NULL;
        return STATUS_SUCCESS;
    }

    /* Real work */
    return RTL_ALLOCATE(ppBuffer, VOID, dwSize);
}
Example #9
0
NTSTATUS
RdrAllocatePacketBuffer(
    PSMB_PACKET pPacket,
    ULONG ulSize
    )
{
    NTSTATUS status = STATUS_SUCCESS;

    status = RTL_ALLOCATE(&pPacket->pRawBuffer, BYTE, ulSize);
    BAIL_ON_NT_STATUS(status);

    pPacket->bufferLen = ulSize;

error:

    return status;
}
Example #10
0
NTSTATUS
LwRtlAnsiStringDuplicate(
    OUT PANSI_STRING pNewString,
    IN PANSI_STRING pOriginalString
    )
{
    NTSTATUS status = 0;
    int EE ATTRIBUTE_UNUSED = 0;
    ANSI_STRING newString = { 0 };

    if (!pOriginalString || !pNewString)
    {
        status = STATUS_INVALID_PARAMETER;
        GOTO_CLEANUP_ON_STATUS_EE(status, EE);
    }

    if (pOriginalString->Buffer && pOriginalString->Length > 0)
    {
        // Add a NULL anyhow.

        newString.Length = pOriginalString->Length;
        newString.MaximumLength = pOriginalString->Length + sizeof(pOriginalString->Buffer[0]);

        status = RTL_ALLOCATE(&newString.Buffer, CHAR, newString.MaximumLength);
        GOTO_CLEANUP_ON_STATUS_EE(status, EE);

        memcpy(newString.Buffer, pOriginalString->Buffer, pOriginalString->Length);
        newString.Buffer[newString.Length/sizeof(newString.Buffer[0])] = 0;
    }

cleanup:
    if (status)
    {
        RtlAnsiStringFree(&newString);
    }

    if (pNewString)
    {
        *pNewString = newString;
    }

    return status;
}
Example #11
0
NTSTATUS
PvfsFileDirname(
    PSTR *ppszDirname,
    PCSTR pszPath
    )
{
    NTSTATUS ntError = STATUS_UNSUCCESSFUL;
    PSTR pszCursor = NULL;
    PSTR pszNewString = NULL;

    /* Case #1: No '/' so just return '.' */
    if (((pszCursor = strrchr(pszPath, '/')) == NULL))
    {
        ntError = RtlCStringDuplicate(ppszDirname, ".");
        goto cleanup;
    }

    /* Case #2: only one '/' (at beginning of path) */

    if (pszCursor == pszPath) {
        ntError = RtlCStringDuplicate(ppszDirname, "/");
        goto cleanup;
    }

    /* Case #3: Real dirname and file name components */

    ntError = RTL_ALLOCATE(&pszNewString, CHAR,
                           PVFS_PTR_DIFF(pszPath,pszCursor) + 1);
    BAIL_ON_NT_STATUS(ntError);

    RtlCopyMemory(pszNewString, pszPath, PVFS_PTR_DIFF(pszPath,pszCursor));

    *ppszDirname = pszNewString;
    ntError = STATUS_SUCCESS;

cleanup:
    return ntError;

error:
    goto cleanup;
}
Example #12
0
DWORD
RegAllocateMemory(
    size_t Size,
    LW_PVOID * ppMemory
    )
{
    DWORD dwError = 0;

	if (Size)
    {
		dwError = RegNtStatusToWin32Error(
		    		RTL_ALLOCATE(ppMemory, VOID, Size)
		    		);
    }
	else
	{
		dwError = RegNtStatusToWin32Error(LW_STATUS_INSUFFICIENT_RESOURCES);
	}

	return dwError;
}
Example #13
0
static
NTSTATUS
NpfsCommonProcessCreateEcp(
    PNPFS_IRP_CONTEXT pIrpContext,
    PIRP pIrp,
    PNPFS_CCB pCCB
    )
{
    NTSTATUS ntStatus = STATUS_SUCCESS;
    PNPFS_PIPE pPipe = pCCB->pPipe;
    PBYTE pSessionKey = NULL;
    ULONG ulSessionKeyLength = 0;
    PBYTE pAddr = NULL;
    ULONG ulEcpSize = 0;
    PFILE_NETWORK_OPEN_INFORMATION pNetworkOpenInfo = NULL;
    PFILE_PIPE_INFORMATION pPipeInfo = NULL;
    PFILE_PIPE_LOCAL_INFORMATION pPipeLocalInfo = NULL;

    ntStatus = IoRtlEcpListFind(
        pIrp->Args.Create.EcpList,
        IO_ECP_TYPE_SESSION_KEY,
        OUT_PPVOID(&pSessionKey),
        &ulSessionKeyLength);

    if (ntStatus != STATUS_NOT_FOUND)
    {
        BAIL_ON_NT_STATUS(ntStatus);

        ntStatus = RTL_ALLOCATE(&pPipe->pSessionKey, BYTE, ulSessionKeyLength);
        BAIL_ON_NT_STATUS(ntStatus);

        memcpy(pPipe->pSessionKey, pSessionKey, ulSessionKeyLength);
        pPipe->ulSessionKeyLength = ulSessionKeyLength;
    }

    ntStatus = IoRtlEcpListFind(
        pIrp->Args.Create.EcpList,
        IO_ECP_TYPE_PEER_ADDRESS,
        OUT_PPVOID(&pAddr),
        &ulEcpSize);

    if (ntStatus != STATUS_NOT_FOUND)
    {
        BAIL_ON_NT_STATUS(ntStatus);

        if (ulEcpSize > sizeof(pPipe->ClientAddress))
        {
            ntStatus = STATUS_INVALID_PARAMETER;
            BAIL_ON_NT_STATUS(ntStatus);
        }

        pPipe->usClientAddressLen = (USHORT) ulEcpSize;
        memcpy(pPipe->ClientAddress, pAddr, ulEcpSize);
    }

    ntStatus = IoRtlEcpListFind(
                    pIrp->Args.Create.EcpList,
                    SRV_ECP_TYPE_NET_OPEN_INFO,
                    OUT_PPVOID(&pNetworkOpenInfo),
                    &ulEcpSize);

    if (ntStatus == STATUS_SUCCESS)
    {
        if (ulEcpSize != sizeof(FILE_NETWORK_OPEN_INFORMATION))
        {
            ntStatus = STATUS_INVALID_PARAMETER;
            BAIL_ON_NT_STATUS(ntStatus);
        }

        ntStatus = NpfsQueryCcbFileNetworkOpenInfo(pCCB, pNetworkOpenInfo);
        BAIL_ON_NT_STATUS(ntStatus);

        ntStatus = IoRtlEcpListAcknowledge(
                        pIrp->Args.Create.EcpList,
                        SRV_ECP_TYPE_NET_OPEN_INFO);
        BAIL_ON_NT_STATUS(ntStatus);
    }
    else
    {
        ntStatus = STATUS_SUCCESS;
    }

    ntStatus = IoRtlEcpListFind(
                    pIrp->Args.Create.EcpList,
                    SRV_ECP_TYPE_PIPE_INFO,
                    OUT_PPVOID(&pPipeInfo),
                    &ulEcpSize);

    if (ntStatus == STATUS_SUCCESS)
    {
        if (ulEcpSize != sizeof(FILE_PIPE_INFORMATION))
        {
            ntStatus = STATUS_INVALID_PARAMETER;
            BAIL_ON_NT_STATUS(ntStatus);
        }

        ntStatus = NpfsQueryCcbFilePipeInfo(pCCB, pPipeInfo);
        BAIL_ON_NT_STATUS(ntStatus);

        ntStatus = IoRtlEcpListAcknowledge(
                        pIrp->Args.Create.EcpList,
                        SRV_ECP_TYPE_PIPE_INFO);
        BAIL_ON_NT_STATUS(ntStatus);
    }
    else
    {
        ntStatus = STATUS_SUCCESS;
    }

    ntStatus = IoRtlEcpListFind(
                    pIrp->Args.Create.EcpList,
                    SRV_ECP_TYPE_PIPE_LOCAL_INFO,
                    OUT_PPVOID(&pPipeLocalInfo),
                    &ulEcpSize);

    if (ntStatus == STATUS_SUCCESS)
    {
        if (ulEcpSize != sizeof(FILE_PIPE_LOCAL_INFORMATION))
        {
            ntStatus = STATUS_INVALID_PARAMETER;
            BAIL_ON_NT_STATUS(ntStatus);
        }

        ntStatus = NpfsQueryCcbFilePipeLocalInfo(pCCB, pPipeLocalInfo);
        BAIL_ON_NT_STATUS(ntStatus);

        ntStatus = IoRtlEcpListAcknowledge(
                        pIrp->Args.Create.EcpList,
                        SRV_ECP_TYPE_PIPE_LOCAL_INFO);
        BAIL_ON_NT_STATUS(ntStatus);
    }
    else
    {
        ntStatus = STATUS_SUCCESS;
    }

cleanup:

    return ntStatus;

error:

    goto cleanup;
}
Example #14
0
NTSTATUS
RtlAllocateCStringFromSid(
    OUT PSTR* StringSid,
    IN PSID Sid
    )
{
    NTSTATUS status = STATUS_SUCCESS;
    PSTR result = NULL;
    size_t size = 0;
    int count = 0;
    ULONG i = 0;

    if (!StringSid || !RtlValidSid(Sid))
    {
        status = STATUS_INVALID_PARAMETER;
        GOTO_CLEANUP();
    }

    size = RTLP_STRING_SID_MAX_CHARS(Sid->SubAuthorityCount);

    status = RTL_ALLOCATE(&result, CHAR, size);
    GOTO_CLEANUP_ON_STATUS(status);

    if (Sid->IdentifierAuthority.Value[0] || Sid->IdentifierAuthority.Value[1])
    {
        count += snprintf(result + count,
                          size - count,
                          "S-%u-0x%.2X%.2X%.2X%.2X%.2X%.2X",
                          Sid->Revision,
                          Sid->IdentifierAuthority.Value[0],
                          Sid->IdentifierAuthority.Value[1],
                          Sid->IdentifierAuthority.Value[2],
                          Sid->IdentifierAuthority.Value[3],
                          Sid->IdentifierAuthority.Value[4],
                          Sid->IdentifierAuthority.Value[5]);
    }
    else
    {
        ULONG value = 0;

        value |= (ULONG) Sid->IdentifierAuthority.Value[5];
        value |= (ULONG) Sid->IdentifierAuthority.Value[4] << 8;
        value |= (ULONG) Sid->IdentifierAuthority.Value[3] << 16;
        value |= (ULONG) Sid->IdentifierAuthority.Value[2] << 24;

        count += snprintf(result + count,
                          size - count,
                          "S-%u-%u",
                          Sid->Revision,
                          value);
    }

    for (i = 0; i < Sid->SubAuthorityCount; i++)
    {
        count += snprintf(result + count,
                          size - count,
                          "-%u", 
                          Sid->SubAuthority[i]);
    }

    status = STATUS_SUCCESS;

cleanup:
    if (!NT_SUCCESS(status))
    {
        RTL_FREE(&result);
    }

    if (StringSid)
    {
        *StringSid = result;
    }

    return status;
}
Example #15
0
NTSTATUS
RtlCreateAccessToken(
    OUT PACCESS_TOKEN* AccessToken,
    IN PTOKEN_USER User,
    IN PTOKEN_GROUPS Groups,
    IN PTOKEN_PRIVILEGES Privileges,
    IN PTOKEN_OWNER Owner,
    IN PTOKEN_PRIMARY_GROUP PrimaryGroup,
    IN PTOKEN_DEFAULT_DACL DefaultDacl,
    IN OPTIONAL PTOKEN_UNIX Unix
    )
{
    NTSTATUS status = STATUS_SUCCESS;
    int unixError = 0;
    ULONG requiredSize = 0;
    PACCESS_TOKEN token = NULL;
    ULONG i = 0;
    ULONG size = 0;
    PVOID location = NULL;

    if (!User || !User->User.Sid ||
        !Groups ||
        !Owner ||
        !PrimaryGroup ||
        !DefaultDacl)
    {
        status = STATUS_INVALID_PARAMETER;
        GOTO_CLEANUP();
    }

    if (!RtlValidSid(User->User.Sid) ||
        (Owner->Owner && !RtlValidSid(Owner->Owner)) ||
        (PrimaryGroup->PrimaryGroup && !RtlValidSid(PrimaryGroup->PrimaryGroup)))
    {
        status = STATUS_INVALID_SID;
        GOTO_CLEANUP();
    }

    // No user attributes currently exist.
    if (User->User.Attributes != 0)
    {
        status = STATUS_INVALID_PARAMETER;
        GOTO_CLEANUP();
    }

    for (i = 0; i < Groups->GroupCount; i++)
    {
        // TODO-Perhaps validate Group attributes
        if (!Groups->Groups[i].Sid)
        {
            status = STATUS_INVALID_PARAMETER;
            GOTO_CLEANUP();
        }
        if (!RtlValidSid(Groups->Groups[i].Sid))
        {
            status = STATUS_INVALID_SID;
            GOTO_CLEANUP();
        }
    }

    if (DefaultDacl->DefaultDacl &&
        !RtlValidAcl(DefaultDacl->DefaultDacl, NULL))
    {
        status = STATUS_INVALID_ACL;
        GOTO_CLEANUP();
    }

    // Compute size required

    requiredSize = sizeof(*token);

    size = RtlLengthSid(User->User.Sid);
    status = RtlSafeAddULONG(&requiredSize, requiredSize, size);
    GOTO_CLEANUP_ON_STATUS(status);

    if (Owner->Owner)
    {
        size = RtlLengthSid(Owner->Owner);
        status = RtlSafeAddULONG(&requiredSize, requiredSize, size);
        GOTO_CLEANUP_ON_STATUS(status);
    }

    if (PrimaryGroup->PrimaryGroup)
    {
        size = RtlLengthSid(PrimaryGroup->PrimaryGroup);
        status = RtlSafeAddULONG(&requiredSize, requiredSize, size);
        GOTO_CLEANUP_ON_STATUS(status);
    }

    if (DefaultDacl->DefaultDacl)
    {
        status = RtlSafeAddULONG(&requiredSize, requiredSize,
                                 DefaultDacl->DefaultDacl->AclSize);
        GOTO_CLEANUP_ON_STATUS(status);
    }

    status = RtlSafeMultiplyULONG(&size, sizeof(Groups->Groups[0]), Groups->GroupCount);
    GOTO_CLEANUP_ON_STATUS(status);

    status = RtlSafeAddULONG(&requiredSize, requiredSize, size);
    GOTO_CLEANUP_ON_STATUS(status);

    for (i = 0; i < Groups->GroupCount; i++)
    {
        size = RtlLengthSid(Groups->Groups[i].Sid);

        status = RtlSafeAddULONG(&requiredSize, requiredSize, size);
        GOTO_CLEANUP_ON_STATUS(status);
    }

    status = RtlSafeMultiplyULONG(&size,
                                  sizeof(Privileges->Privileges[0]),
                                  Privileges->PrivilegeCount);
    GOTO_CLEANUP_ON_STATUS(status);

    status = RtlSafeAddULONG(&requiredSize, requiredSize, size);
    GOTO_CLEANUP_ON_STATUS(status);

    status = RTL_ALLOCATE(&token, ACCESS_TOKEN, requiredSize);
    GOTO_CLEANUP_ON_STATUS(status);

    location = LW_PTR_ADD(token, sizeof(*token));

    // Initialize

    token->ReferenceCount = 1;
    token->Flags = 0;
    unixError = pthread_rwlock_init(&token->RwLock, NULL);
    if (unixError)
    {
        LW_RTL_LOG_ERROR("Failed to init rwlock in access token "
                         "(error = %d).", unixError);
        status = LwErrnoToNtStatus(unixError);
        GOTO_CLEANUP();
    }
    token->pRwLock = &token->RwLock;

    token->User.Attributes = User->User.Attributes;
    token->User.Sid = (PSID) location;
    location = RtlpAppendData(location,
                              User->User.Sid,
                              RtlLengthSid(User->User.Sid));

    token->GroupCount = Groups->GroupCount;
    token->Groups = (PSID_AND_ATTRIBUTES) location;
    location = LwRtlOffsetToPointer(location, sizeof(Groups->Groups[0]) * Groups->GroupCount);
    for (i = 0; i < Groups->GroupCount; i++)
    {
        token->Groups[i].Attributes = Groups->Groups[i].Attributes;
        token->Groups[i].Sid = (PSID) location;
        location = RtlpAppendData(location,
                                  Groups->Groups[i].Sid,
                                  RtlLengthSid(Groups->Groups[i].Sid));
    }

    token->PrivilegeCount = Privileges->PrivilegeCount;
    token->Privileges = (PLUID_AND_ATTRIBUTES) location;
    location = LwRtlOffsetToPointer(
                location,
                sizeof(Privileges->Privileges[0]) * Privileges->PrivilegeCount);
    memcpy(token->Privileges,
           Privileges->Privileges,
           sizeof(token->Privileges[0]) * token->PrivilegeCount);

    if (Owner->Owner)
    {
        token->Owner = (PSID) location;
        location = RtlpAppendData(location,
                                  Owner->Owner,
                                  RtlLengthSid(Owner->Owner));
    }

    if (PrimaryGroup->PrimaryGroup)
    {
        token->PrimaryGroup = (PSID) location;
        location = RtlpAppendData(location,
                                  PrimaryGroup->PrimaryGroup,
                                  RtlLengthSid(PrimaryGroup->PrimaryGroup));
    }

    if (DefaultDacl->DefaultDacl)
    {
        token->DefaultDacl = (PACL) location;
        location = RtlpAppendData(location,
                                  DefaultDacl->DefaultDacl,
                                  DefaultDacl->DefaultDacl->AclSize);
    }

    if (Unix)
    {
        SetFlag(token->Flags, ACCESS_TOKEN_FLAG_UNIX_PRESENT);
        token->Uid = Unix->Uid;
        token->Gid = Unix->Gid;
        token->Umask = Unix->Umask;
    }

    if (location != LW_PTR_ADD(token, requiredSize))
    {
        status = STATUS_ASSERTION_FAILURE;
        GOTO_CLEANUP();
    }

    status = STATUS_SUCCESS;

cleanup:
    if (!NT_SUCCESS(status))
    {
        RtlReleaseAccessToken(&token);
    }

    *AccessToken = token;

    return status;
}
Example #16
0
NTSTATUS
LwNtCreateFile(
    OUT PIO_FILE_HANDLE FileHandle,
    IN OUT OPTIONAL PIO_ASYNC_CONTROL_BLOCK AsyncControlBlock,
    OUT PIO_STATUS_BLOCK IoStatusBlock,
    IN PIO_FILE_NAME FileName,
    IN OPTIONAL PSECURITY_DESCRIPTOR_RELATIVE SecurityDescriptor,
    IN OPTIONAL PVOID SecurityQualityOfService, // TBD
    IN ACCESS_MASK DesiredAccess,
    IN OPTIONAL LONG64 AllocationSize,
    IN FILE_ATTRIBUTES FileAttributes,
    IN FILE_SHARE_FLAGS ShareAccess,
    IN FILE_CREATE_DISPOSITION CreateDisposition,
    IN FILE_CREATE_OPTIONS CreateOptions,
    IN OPTIONAL PVOID EaBuffer, // PFILE_FULL_EA_INFORMATION
    IN ULONG EaLength,
    IN OPTIONAL PIO_ECP_LIST EcpList,
    IN OPTIONAL LW_PIO_CREDS pCreds
    )
{
    NTSTATUS status = 0;
    int EE = 0;
    PIO_CREDS pActiveCreds = NULL;
    PCREATEFILE_CONTEXT pCreateContext = NULL;

    if (!pCreds)
    {
        status = LwIoGetActiveCreds(FileName->FileName, &pActiveCreds);
        GOTO_CLEANUP_ON_STATUS_EE(status, EE);

        pCreds = pActiveCreds;
    }

    status = NtpAllocAsyncContext(OUT_PPVOID(&pCreateContext), sizeof(*pCreateContext));
    GOTO_CLEANUP_ON_STATUS_EE(status, EE);

    pCreateContext->IoStatusBlock = IoStatusBlock;
    pCreateContext->FileHandle = FileHandle;

    status = LwIoResolveCreds(pCreds, &pCreateContext->Request.pSecurityToken);
    GOTO_CLEANUP_ON_STATUS_EE(status, EE);

    pCreateContext->Request.FileName = *FileName;
    pCreateContext->Request.DesiredAccess = DesiredAccess;
    pCreateContext->Request.AllocationSize = AllocationSize;
    pCreateContext->Request.FileAttributes = FileAttributes;
    pCreateContext->Request.ShareAccess = ShareAccess;
    pCreateContext->Request.CreateDisposition = CreateDisposition;
    pCreateContext->Request.CreateOptions = CreateOptions;
    pCreateContext->Request.EaBuffer = EaBuffer;
    pCreateContext->Request.EaLength = EaLength;
    if (SecurityDescriptor)
    {
        pCreateContext->Request.SecurityDescriptor = SecurityDescriptor;
        pCreateContext->Request.SecDescLength =
                    RtlLengthSecurityDescriptorRelative(SecurityDescriptor);
    }
    pCreateContext->Request.EcpCount = IoRtlEcpListGetCount(EcpList);
    if (pCreateContext->Request.EcpCount)
    {
        PCSTR pszType = NULL;
        ULONG ecpIndex = 0;

        status = RTL_ALLOCATE(
            &pCreateContext->Request.EcpList,
            NT_IPC_HELPER_ECP,
            sizeof(*pCreateContext->Request.EcpList) * pCreateContext->Request.EcpCount);
        GOTO_CLEANUP_ON_STATUS_EE(status, EE);

        while (ecpIndex < pCreateContext->Request.EcpCount)
        {
            status = IoRtlEcpListGetNext(
                            EcpList,
                            pszType,
                            &pCreateContext->Request.EcpList[ecpIndex].pszType,
                            &pCreateContext->Request.EcpList[ecpIndex].pData,
                            &pCreateContext->Request.EcpList[ecpIndex].Size);
            GOTO_CLEANUP_ON_STATUS_EE(status, EE);

            pszType = pCreateContext->Request.EcpList[ecpIndex].pszType;
            ecpIndex++;
        }

        assert(ecpIndex == pCreateContext->Request.EcpCount);
        status = STATUS_SUCCESS;
    }

    status = NtpCtxCallAsync(
        &pCreateContext->Base,
        NT_IPC_MESSAGE_TYPE_CREATE_FILE,
        &pCreateContext->Request,
        NT_IPC_MESSAGE_TYPE_CREATE_FILE_RESULT,
        AsyncControlBlock,
        LwNtCreateFileComplete);
    GOTO_CLEANUP_ON_STATUS_EE(status, EE);

cleanup:

    if (pActiveCreds)
    {
        LwIoDeleteCreds(pActiveCreds);
    }

    if (status != STATUS_PENDING)
    {
        if (pCreateContext)
        {
            LwNtCreateFileComplete(&pCreateContext->Base, status);
            status = IoStatusBlock->Status;
            NtpFreeClientAsyncContext(&pCreateContext->Base);
        }
        else
        {
            IoStatusBlock->Status = status;
        }
    }

    LOG_LEAVE_IF_STATUS_EE(status, EE);
    
    return status;
}
Example #17
0
LW_NTSTATUS
LwIoSetRdrDomainHints(
    LW_PWSTR* ppwszDomains,
    ULONG ulCount
    )
{
    NTSTATUS status = STATUS_SUCCESS;
    IO_STATUS_BLOCK ioStatus = {0};
    WCHAR wszRdrPath[] = {'\\', 'r', 'd', 'r', '\0'};
    UNICODE_STRING rdrPath = LW_RTL_CONSTANT_STRING(wszRdrPath);
    IO_FILE_NAME fileName = {0};
    IO_FILE_HANDLE hFile = NULL;
    PWSTR pwszBuffer = NULL;
    ULONG ulLength = 0;
    ULONG ulIndex = 0;
    ULONG ulOffset = 0;
    ULONG ulStrLen = 0;

    for (ulIndex = 0; ulIndex < ulCount; ulIndex++)
    {
        ulLength += (LwRtlWC16StringNumChars(ppwszDomains[ulIndex]) + 1) * sizeof(WCHAR);
    }

    status = RTL_ALLOCATE(&pwszBuffer, WCHAR, ulLength);
    BAIL_ON_NT_STATUS(status);

    for (ulIndex = 0; ulIndex < ulCount; ulIndex++)
    {
        ulStrLen = (LwRtlWC16StringNumChars(ppwszDomains[ulIndex]) + 1) * sizeof(WCHAR);

        memcpy((PBYTE) pwszBuffer + ulOffset, ppwszDomains[ulIndex], ulStrLen);
        ulOffset += ulStrLen;
    }

    fileName.Name = rdrPath;

    status = LwNtCreateFile(
        &hFile,
        NULL,
        &ioStatus,
        &fileName,
        NULL,
        NULL,
        FILE_GENERIC_WRITE,
        0,
        0,
        FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
        FILE_OPEN,
        0,
        NULL,
        0,
        NULL,
        NULL);
    BAIL_ON_NT_STATUS(status);

    status = LwNtDeviceIoControlFile(
        hFile,
        NULL,
        &ioStatus,
        RDR_DEVCTL_SET_DOMAIN_HINTS,
        pwszBuffer,
        ulLength,
        NULL,
        0);
    BAIL_ON_NT_STATUS(status);

cleanup:

    RTL_FREE(&pwszBuffer);

    if (hFile)
    {
        LwNtCloseFile(hFile);
    }

    return status;

error:

    goto cleanup;
}
Example #18
0
static NTSTATUS
PvfsResolvePath(
    PSTR *ppszResolvedPath,
    PCSTR pszLookupPath
    )
{
    NTSTATUS ntError = STATUS_SUCCESS;
    PSTR pszCursor = NULL;
    PSTR pszComponent = NULL;
    PSTR pszPath = NULL;
    PVFS_STAT Stat = {0};
    PSTR pszResolvedPath = NULL;
    PSTR pszResWorkingPath = NULL;
    PSTR pszWorkingPath = NULL;
    DWORD Length = PATH_MAX;
    DIR *pDir = NULL;
    struct dirent *pDirEntry = NULL;

    if (*pszLookupPath != '/') {
        ntError = STATUS_INVALID_PARAMETER;
        BAIL_ON_NT_STATUS(ntError);
    }

    ntError = RTL_ALLOCATE(&pszResolvedPath, CHAR, Length);
    BAIL_ON_NT_STATUS(ntError);

    ntError = RTL_ALLOCATE(&pszWorkingPath, CHAR, PATH_MAX);
    BAIL_ON_NT_STATUS(ntError);

    ntError = RtlCStringDuplicate(&pszPath, pszLookupPath);
    BAIL_ON_NT_STATUS(ntError);

    pszComponent = pszPath + 1;

    while (pszComponent && (Length > 0))
    {
        pDir = NULL;

        if ((pszCursor = strchr(pszComponent, '/')) != NULL) {
            *pszCursor = '\0';
        }

        snprintf(pszWorkingPath, PATH_MAX-1, "%s/%s",
                 pszResolvedPath, pszComponent);

        /* Try cache first */

        ntError = PvfsPathCacheLookup(&pszResWorkingPath, pszWorkingPath);
        if(ntError == STATUS_SUCCESS)
        {
            strncpy(pszResolvedPath, pszResWorkingPath, PATH_MAX-1);
            Length = PATH_MAX - RtlCStringNumChars(pszResolvedPath);
            RtlCStringFree(&pszResWorkingPath);
        }

        /* Maybe an exact match on disk? */

        else if (PvfsSysStat(pszWorkingPath, &Stat) == STATUS_SUCCESS)
        {
            strncpy(pszResolvedPath, pszWorkingPath, PATH_MAX-1);
            Length = PATH_MAX - RtlCStringNumChars(pszResolvedPath);
            RtlCStringFree(&pszResWorkingPath);

            ntError = PvfsPathCacheAdd(pszResolvedPath);
            BAIL_ON_NT_STATUS(ntError);
        }

        /* Do the work ourselves */

        else
        {
            /* Enumerate directory entries and look for a match */

            ntError = PvfsSysOpenDir(pszResolvedPath, &pDir);
            if (ntError == STATUS_NOT_A_DIRECTORY)
            {
                ntError = STATUS_OBJECT_PATH_NOT_FOUND;
            }
            BAIL_ON_NT_STATUS(ntError);

            for(ntError = PvfsSysReadDir(pDir, &pDirEntry);
                pDirEntry;
                ntError = PvfsSysReadDir(pDir, &pDirEntry))
            {
                /* First check the error return */
                BAIL_ON_NT_STATUS(ntError);

                if (RtlCStringIsEqual(pszComponent, pDirEntry->d_name, FALSE)) {
                    break;
                }
            }

            /* Did we find a match? */

            if (!pDirEntry) {
                /* Return code depends on whether the last component was
                   not found or if an intermediate component was invalid */

                if (pszCursor == NULL)
                {
                    ntError = STATUS_OBJECT_NAME_NOT_FOUND;
                }
                else
                {
                    ntError = STATUS_OBJECT_PATH_NOT_FOUND;
                }

                BAIL_ON_NT_STATUS(ntError);
            }

            strncat(pszResolvedPath, "/", Length-1);
            Length -= 1;
            strncat(pszResolvedPath, pDirEntry->d_name, Length-1);
            Length -= RtlCStringNumChars(pDirEntry->d_name);

            ntError = PvfsSysCloseDir(pDir);
            pDir = NULL;
            BAIL_ON_NT_STATUS(ntError);

            ntError = PvfsPathCacheAdd(pszResolvedPath);
            BAIL_ON_NT_STATUS(ntError);

        }

        /* Cleanup for next loop */


        if (pszCursor) {
            *pszCursor = '/';
        }

        if ((pszComponent = strchr(pszComponent, '/')) != NULL) {
            pszComponent++;
        }
    }

    /* Did we finish? */

    if ((Length <= 0) && (pszComponent != NULL)) {
        ntError = STATUS_NAME_TOO_LONG;
        BAIL_ON_NT_STATUS(ntError);
    }

    *ppszResolvedPath = pszResolvedPath;
    pszResolvedPath = NULL;

    ntError = STATUS_SUCCESS;

cleanup:
    RtlCStringFree(&pszPath);
    RtlCStringFree(&pszWorkingPath);
    RtlCStringFree(&pszResWorkingPath);
    RtlCStringFree(&pszResolvedPath);

    if (pDir) {
        PvfsSysCloseDir(pDir);
    }

    return ntError;

error:
    goto cleanup;
}
Example #19
0
NTSTATUS
LwNtCreateNamedPipeFile(
    OUT PIO_FILE_HANDLE FileHandle,
    IN OUT OPTIONAL PIO_ASYNC_CONTROL_BLOCK AsyncControlBlock,
    OUT PIO_STATUS_BLOCK IoStatusBlock,
    IN PIO_FILE_NAME FileName,
    IN OPTIONAL PVOID SecurityDescriptor, // TBD
    IN OPTIONAL PVOID SecurityQualityOfService, // TBD
    IN ACCESS_MASK DesiredAccess,
    IN FILE_SHARE_FLAGS ShareAccess,
    IN FILE_CREATE_DISPOSITION CreateDisposition,
    IN FILE_CREATE_OPTIONS CreateOptions,
    IN FILE_PIPE_TYPE_MASK NamedPipeType,
    IN FILE_PIPE_READ_MODE_MASK ReadMode,
    IN FILE_PIPE_COMPLETION_MODE_MASK CompletionMode,
    IN ULONG MaximumInstances,
    IN ULONG InboundQuota,
    IN ULONG OutboundQuota,
    IN OPTIONAL PLONG64 DefaultTimeout
    )
{
    NTSTATUS status = 0;
    int EE = 0;
    PIO_ECP_LIST ecpList = NULL;
    PIO_ECP_NAMED_PIPE pPipeParams = NULL;
    PCREATEPIPE_CONTEXT pContext = NULL;

    status = RTL_ALLOCATE(&pPipeParams, IO_ECP_NAMED_PIPE, sizeof(*pPipeParams));
    GOTO_CLEANUP_ON_STATUS_EE(status, EE);

    status = IoRtlEcpListAllocate(&ecpList);
    GOTO_CLEANUP_ON_STATUS_EE(status, EE);
    
    pPipeParams->NamedPipeType = NamedPipeType;
    pPipeParams->ReadMode = ReadMode;
    pPipeParams->CompletionMode = CompletionMode;
    pPipeParams->MaximumInstances = MaximumInstances;
    pPipeParams->InboundQuota = InboundQuota;
    pPipeParams->OutboundQuota = OutboundQuota;
    if (DefaultTimeout)
    {
        pPipeParams->DefaultTimeout = *DefaultTimeout;
        pPipeParams->HaveDefaultTimeout = TRUE;
    }

    status = IoRtlEcpListInsert(ecpList,
                                IO_ECP_TYPE_NAMED_PIPE,
                                pPipeParams,
                                sizeof(*pPipeParams),
                                LwRtlMemoryFree);
    GOTO_CLEANUP_ON_STATUS_EE(status, EE);
    pPipeParams = NULL;

    if (AsyncControlBlock)
    {
        status = RTL_ALLOCATE(&pContext, CREATEPIPE_CONTEXT, sizeof(*pContext));
        GOTO_CLEANUP_ON_STATUS_EE(status, EE);

        pContext->pEcpList = ecpList;
        pContext->pChain = AsyncControlBlock;
        pContext->AsyncControl.Callback = LwNtCreateNamedPipeComplete;
        pContext->AsyncControl.CallbackContext = pContext;

        AsyncControlBlock = &pContext->AsyncControl;
    }

    status = NtCreateFile(
                    FileHandle,
                    AsyncControlBlock,
                    IoStatusBlock,
                    FileName,
                    SecurityDescriptor,
                    SecurityQualityOfService,
                    DesiredAccess,
                    0,
                    0,
                    ShareAccess,
                    CreateDisposition,
                    CreateOptions,
                    NULL,
                    0,
                    ecpList,
                    NULL);

    if (pContext)
    {
        pContext->pChain->AsyncCancelContext = pContext->AsyncControl.AsyncCancelContext;
    }

cleanup:

    if (status != STATUS_PENDING)
    {
        if (pContext)
        {
            IoRtlEcpListFree(&pContext->pEcpList);
            RTL_FREE(&pContext);
        }
        else
        {
            IoRtlEcpListFree(&ecpList);
        }

        IoStatusBlock->Status = status;

        RTL_FREE(&pPipeParams);
    }

    LOG_LEAVE_IF_STATUS_EE(status, EE);
    return status;
}
Example #20
0
NTSTATUS
LwIoFuseRename(
    const char* pszOldPath,
    const char* pszNewPath
    )
{
    NTSTATUS status = STATUS_SUCCESS;
    IO_STATUS_BLOCK ioStatus = {0};
    IO_FILE_HANDLE handle = NULL;
    PIO_FUSE_CONTEXT pFuseContext = NULL;
    IO_FILE_NAME filename = {0};
    PFILE_RENAME_INFORMATION pRenameInfo = NULL;
    PWSTR pwszNewPath = NULL;
    size_t newPathLength = 0;
    
    pFuseContext = LwIoFuseGetContext();

    status = LwIoFuseGetDriverRelativePath(
        pFuseContext,
        pszNewPath,
        &pwszNewPath);
    BAIL_ON_NT_STATUS(status);

    newPathLength = LwRtlWC16StringNumChars(pwszNewPath);

    status = RTL_ALLOCATE(
        &pRenameInfo,
        FILE_RENAME_INFORMATION,
        sizeof(*pRenameInfo) + (newPathLength + 1) * sizeof(WCHAR));
    BAIL_ON_NT_STATUS(status);

    pRenameInfo->ReplaceIfExists = TRUE;
    pRenameInfo->RootDirectory = NULL;
    pRenameInfo->FileNameLength = newPathLength * sizeof(WCHAR);
    
    memcpy(pRenameInfo->FileName, pwszNewPath, newPathLength * sizeof(WCHAR));

    status = LwIoFuseGetNtFilename(
        pFuseContext,
        pszOldPath,
        &filename);
    BAIL_ON_NT_STATUS(status);
    
    status = LwNtCreateFile(
        &handle,                 /* File handle */
        NULL,                    /* Async control block */
        &ioStatus,               /* IO status block */
        &filename,               /* Filename */
        NULL,                    /* Security descriptor */
        NULL,                    /* Security QOS */
        DELETE,                  /* Desired access mask */
        0,                       /* Allocation size */
        0,                       /* File attributes */
        FILE_SHARE_READ |
        FILE_SHARE_WRITE |
        FILE_SHARE_DELETE,       /* Share access */
        FILE_OPEN,               /* Create disposition */
        0,                       /* Create options */
        NULL,                    /* EA buffer */
        0,                       /* EA length */
        NULL,                    /* ECP list */
        NULL);
    BAIL_ON_NT_STATUS(status);
    
    status = LwNtSetInformationFile(
        handle, /* File handle */
        NULL, /* Async control block */
        &ioStatus, /* IO status block */
        pRenameInfo, /* File information */
        sizeof(*pRenameInfo) + (newPathLength + 1) * sizeof(WCHAR), /* File information size */
        FileRenameInformation); /* Information class */
    BAIL_ON_NT_STATUS(status);
    
cleanup:

    if (handle)
    {
        LwNtCloseFile(handle);
    }

    RTL_UNICODE_STRING_FREE(&filename.Name);
    RTL_FREE(&pwszNewPath);
    RTL_FREE(&pRenameInfo);

    return status;

error:

    goto cleanup;
}
Example #21
0
LW_NTSTATUS
LwIoGetPeerAccessToken(
    IO_FILE_HANDLE File,
    PACCESS_TOKEN* ppToken
    )
{
    NTSTATUS Status = STATUS_SUCCESS;
    IO_STATUS_BLOCK IoStatus;
    ULONG ulLength = ACCESS_TOKEN_LENGTH;
    PBYTE pBuffer = NULL;
    PBYTE pNewBuffer = NULL;

    Status = RTL_ALLOCATE(&pBuffer, BYTE, ulLength);
    BAIL_ON_NT_STATUS(Status);

    do
    {
        Status =
            LwNtFsControlFile(
                File,
                NULL,
                &IoStatus,
                IO_FSCTL_SMB_GET_PEER_ACCESS_TOKEN,
                NULL,
                0,
                pBuffer,
                ulLength);

        if (Status == STATUS_BUFFER_TOO_SMALL)
        {
            ulLength *= 2;
            pNewBuffer = LwRtlMemoryRealloc(pBuffer, ulLength);
            if (!pNewBuffer)
            {
                Status = STATUS_INSUFFICIENT_RESOURCES;
                BAIL_ON_NT_STATUS(Status);
            }
            pBuffer = pNewBuffer;
        }
    } while (Status == STATUS_BUFFER_TOO_SMALL);

    BAIL_ON_NT_STATUS(Status);

    if (IoStatus.BytesTransferred > 0)
    {
        Status = RtlSelfRelativeAccessTokenToAccessToken(
            (PACCESS_TOKEN_SELF_RELATIVE) pBuffer,
            IoStatus.BytesTransferred,
            ppToken);
        BAIL_ON_NT_STATUS(Status);
    }
    else
    {
        *ppToken = NULL;
    }

cleanup:

    RTL_FREE(&pBuffer);

    return Status;

error:

    *ppToken = NULL;

    goto cleanup;
}
Example #22
0
NTSTATUS
SrvShareSetDefaultSecurity(
    PSRV_SHARE_INFO pShareInfo
    )
{
    NTSTATUS ntStatus = STATUS_SUCCESS;
    PSECURITY_DESCRIPTOR_RELATIVE pRelSecDesc = NULL;
    ULONG ulRelSecDescLen = 0;
    PSECURITY_DESCRIPTOR_ABSOLUTE pAbsSecDesc = NULL;
    DWORD dwAceCount = 0;
    PSID pOwnerSid = NULL;
    PSID pGroupSid = NULL;
    PACL pDacl = NULL;
    DWORD dwSizeDacl = 0;
    union
    {
        SID sid;
        BYTE buffer[SID_MAX_SIZE];
    } administratorsSid;
    union
    {
        SID sid;
        BYTE buffer[SID_MAX_SIZE];
    } powerUsersSid;
    union
    {
        SID sid;
        BYTE buffer[SID_MAX_SIZE];
    } everyoneSid;
    ULONG ulAdministratorsSidSize = sizeof(administratorsSid.buffer);
    ULONG ulPowerUsersSidSize = sizeof(powerUsersSid.buffer);
    ULONG ulEveryoneSidSize = sizeof(everyoneSid.buffer);
    ACCESS_MASK worldAccessMask = 0;

    /* Clear out any existing SecDesc's.  This is not a normal
       use case, but be paranoid */

    if (pShareInfo->ulSecDescLen)
    {
        SrvShareFreeSecurity(pShareInfo);
    }

    /* Build the new Absolute Security Descriptor */

    ntStatus = RTL_ALLOCATE(
                   &pAbsSecDesc,
                   VOID,
                   SECURITY_DESCRIPTOR_ABSOLUTE_MIN_SIZE);
    BAIL_ON_NT_STATUS(ntStatus);

    ntStatus = RtlCreateSecurityDescriptorAbsolute(
                  pAbsSecDesc,
                  SECURITY_DESCRIPTOR_REVISION);
    BAIL_ON_NT_STATUS(ntStatus);

    /* Create some SIDs */

    ntStatus = RtlCreateWellKnownSid(
                   WinBuiltinAdministratorsSid,
                   NULL,
                   (PSID)administratorsSid.buffer,
                   &ulAdministratorsSidSize);
    BAIL_ON_NT_STATUS(ntStatus);

    ntStatus = RtlCreateWellKnownSid(
                   WinBuiltinPowerUsersSid,
                   NULL,
                   (PSID)powerUsersSid.buffer,
                   &ulPowerUsersSidSize);
    BAIL_ON_NT_STATUS(ntStatus);

    ntStatus = RtlCreateWellKnownSid(
                   WinWorldSid,
                   NULL,
                   (PSID)everyoneSid.buffer,
                   &ulEveryoneSidSize);
    BAIL_ON_NT_STATUS(ntStatus);

    /* Owner: Administrators */

    ntStatus = RtlDuplicateSid(&pOwnerSid, &administratorsSid.sid);
    BAIL_ON_NT_STATUS(ntStatus);

    ntStatus = RtlSetOwnerSecurityDescriptor(
                   pAbsSecDesc,
                   pOwnerSid,
                   FALSE);
    BAIL_ON_NT_STATUS(ntStatus);

    /* Group: Power Users */

    ntStatus = RtlDuplicateSid(&pGroupSid, &powerUsersSid.sid);
    BAIL_ON_NT_STATUS(ntStatus);

    ntStatus = RtlSetGroupSecurityDescriptor(
                   pAbsSecDesc,
                   pGroupSid,
                   FALSE);
    BAIL_ON_NT_STATUS(ntStatus);

    /* DACL:
       Administrators - (Full Control)
       Everyone - (Read) for disk shares, (Read/Write) to IPC shares */

    dwAceCount = 2;

    dwSizeDacl = ACL_HEADER_SIZE +
        dwAceCount * sizeof(ACCESS_ALLOWED_ACE) +
        RtlLengthSid(&administratorsSid.sid) +
        RtlLengthSid(&everyoneSid.sid) -
        dwAceCount * sizeof(ULONG);

    ntStatus= RTL_ALLOCATE(&pDacl, VOID, dwSizeDacl);
    BAIL_ON_NT_STATUS(ntStatus);

    ntStatus = RtlCreateAcl(pDacl, dwSizeDacl, ACL_REVISION);
    BAIL_ON_NT_STATUS(ntStatus);

    ntStatus = RtlAddAccessAllowedAceEx(
                  pDacl,
                  ACL_REVISION,
                  0,
                  FILE_ALL_ACCESS,
                  &administratorsSid.sid);
    BAIL_ON_NT_STATUS(ntStatus);

    worldAccessMask = FILE_GENERIC_READ | FILE_GENERIC_EXECUTE;
    if (pShareInfo->service == SHARE_SERVICE_NAMED_PIPE)
    {
        worldAccessMask |= FILE_GENERIC_WRITE;
    }

    ntStatus = RtlAddAccessAllowedAceEx(
                  pDacl,
                  ACL_REVISION,
                  0,
                  worldAccessMask,
                  &everyoneSid.sid);
    BAIL_ON_NT_STATUS(ntStatus);

    ntStatus = RtlSetDaclSecurityDescriptor(
                  pAbsSecDesc,
                  TRUE,
                  pDacl,
                  FALSE);
    BAIL_ON_NT_STATUS(ntStatus);

    /* Create the SelfRelative SD and assign them to the Share */

    ntStatus = RtlAbsoluteToSelfRelativeSD(
                   pAbsSecDesc,
                   NULL,
                   &ulRelSecDescLen);
    if (ntStatus == STATUS_BUFFER_TOO_SMALL)
    {
        ntStatus = SrvAllocateMemory(ulRelSecDescLen, (PVOID*)&pRelSecDesc);
        BAIL_ON_NT_STATUS(ntStatus);

        ntStatus = RtlAbsoluteToSelfRelativeSD(
                       pAbsSecDesc,
                       pRelSecDesc,
                       &ulRelSecDescLen);
    }
    BAIL_ON_NT_STATUS(ntStatus);

    pShareInfo->pSecDesc = pRelSecDesc;
    pShareInfo->ulSecDescLen = ulRelSecDescLen;
    pShareInfo->pAbsSecDesc = pAbsSecDesc;

    ntStatus = STATUS_SUCCESS;


cleanup:

    return ntStatus;

error:
    RTL_FREE(&pAbsSecDesc);
    RTL_FREE(&pOwnerSid);
    RTL_FREE(&pGroupSid);
    RTL_FREE(&pDacl);

    if (pRelSecDesc)
    {
        SrvFreeMemory(pRelSecDesc);
    }

    goto cleanup;
}
Example #23
0
static
NTSTATUS
SrvShareCreateAbsoluteSecDescFromRel(
    OUT PSECURITY_DESCRIPTOR_ABSOLUTE *ppAbsSecDesc,
    IN   PSECURITY_DESCRIPTOR_RELATIVE pRelSecDesc
    )
{
    NTSTATUS ntStatus = STATUS_SUCCESS;
    PSECURITY_DESCRIPTOR_ABSOLUTE pAbsSecDesc = NULL;
    ULONG ulAbsSecDescLen = 0;
    PACL pDacl = NULL;
    ULONG ulDaclLen = 0;
    PACL pSacl = NULL;
    ULONG ulSaclLen = 0;
    PSID pOwner = NULL;
    ULONG ulOwnerLen = 0;
    PSID pGroup = NULL;
    ULONG ulGroupLen = 0;

    /* Get sizes for the Absolute SD */

    ntStatus = RtlSelfRelativeToAbsoluteSD(
                   pRelSecDesc,
                   pAbsSecDesc,
                   &ulAbsSecDescLen,
                   pDacl,
                   &ulDaclLen,
                   pSacl,
                   &ulSaclLen,
                   pOwner,
                   &ulOwnerLen,
                   pGroup,
                   &ulGroupLen);
    if (ntStatus == STATUS_BUFFER_TOO_SMALL)
    {
        ntStatus = STATUS_SUCCESS;
    }
    BAIL_ON_NT_STATUS(ntStatus);

    /* Allocate -- Always use RTL routines for Absolute SDs */

    if (ulOwnerLen)
    {
        ntStatus = RTL_ALLOCATE(&pOwner, SID, ulOwnerLen);
        BAIL_ON_NT_STATUS(ntStatus);
    }

    if (ulGroupLen)
    {
        ntStatus = RTL_ALLOCATE(&pGroup, SID, ulGroupLen);
        BAIL_ON_NT_STATUS(ntStatus);
    }

    if (ulDaclLen)
    {
        ntStatus = RTL_ALLOCATE(&pDacl, VOID, ulDaclLen);
        BAIL_ON_NT_STATUS(ntStatus);
    }

    if (ulSaclLen)
    {
        ntStatus = RTL_ALLOCATE(&pSacl, VOID, ulSaclLen);
        BAIL_ON_NT_STATUS(ntStatus);
    }

    ntStatus = RTL_ALLOCATE(&pAbsSecDesc, VOID, ulAbsSecDescLen);
    BAIL_ON_NT_STATUS(ntStatus);

    /* Translate the SD */

    ntStatus = RtlSelfRelativeToAbsoluteSD(
                   pRelSecDesc,
                   pAbsSecDesc,
                   &ulAbsSecDescLen,
                   pDacl,
                   &ulDaclLen,
                   pSacl,
                   &ulSaclLen,
                   pOwner,
                   &ulOwnerLen,
                   pGroup,
                   &ulGroupLen);
    BAIL_ON_NT_STATUS(ntStatus);

    *ppAbsSecDesc = pAbsSecDesc;

cleanup:
    return ntStatus;


error:
    LW_RTL_FREE(&pAbsSecDesc);
    LW_RTL_FREE(&pOwner);
    LW_RTL_FREE(&pGroup);
    LW_RTL_FREE(&pSacl);
    LW_RTL_FREE(&pDacl);

    goto cleanup;
}
Example #24
0
NTSTATUS
RtlSelfRelativeAccessTokenToAccessToken(
    IN PACCESS_TOKEN_SELF_RELATIVE pRelative,
    IN ULONG ulRelativeSize,
    OUT PACCESS_TOKEN* ppToken
    )
{
    NTSTATUS status = STATUS_SUCCESS;
    ULONG ulOffset = 0;
    PBYTE pBuffer = (PBYTE) pRelative;
    PSID pSid = NULL;
    PSID_AND_ATTRIBUTES_SELF_RELATIVE pGroups = NULL;
    ULONG ulSize = 0;
    ULONG ulRealSize = 0;
    ULONG i = 0;
    TOKEN_USER User = {{0}};
    TOKEN_OWNER Owner = {0};
    TOKEN_PRIMARY_GROUP PrimaryGroup = {0};
    TOKEN_UNIX Unix = {0};
    PTOKEN_GROUPS pTokenGroups = NULL;
    PTOKEN_PRIVILEGES pTokenPrivileges = NULL;
    TOKEN_DEFAULT_DACL DefaultDacl = {0};

    status = CheckOffset(0, sizeof(*pRelative), ulRelativeSize);
    GOTO_CLEANUP_ON_STATUS(status);

    if (pRelative->Flags & ACCESS_TOKEN_FLAG_UNIX_PRESENT)
    {
        Unix.Uid = pRelative->Uid;
        Unix.Gid = pRelative->Gid;
        Unix.Umask = pRelative->Umask;
    }

    User.User.Attributes = pRelative->User.Attributes;
    ulOffset = pRelative->User.SidOffset;
    pSid = (PSID) (pBuffer + ulOffset);
    status = RtlValidateSelfRelativeSid(pSid, ulOffset, ulRelativeSize);
    GOTO_CLEANUP_ON_STATUS(status);
    
    User.User.Sid = pSid;

    ulOffset = pRelative->GroupsOffset;
    if (ulOffset)
    {
        status = LwRtlSafeMultiplyULONG(
            &ulSize,
            sizeof(SID_AND_ATTRIBUTES_SELF_RELATIVE),
            pRelative->GroupCount);
        GOTO_CLEANUP_ON_STATUS(status);

        status = LwRtlSafeMultiplyULONG(
            &ulRealSize,
            sizeof(SID_AND_ATTRIBUTES),
            pRelative->GroupCount);
        GOTO_CLEANUP_ON_STATUS(status);

        status = LwRtlSafeAddULONG(
            &ulRealSize,
            ulRealSize,
            sizeof(TOKEN_GROUPS));
        GOTO_CLEANUP_ON_STATUS(status);

        status = CheckOffset(ulOffset, ulSize, ulRelativeSize);
        GOTO_CLEANUP_ON_STATUS(status);

        pGroups = (PSID_AND_ATTRIBUTES_SELF_RELATIVE) (pBuffer + ulOffset);
        
        status = RTL_ALLOCATE(&pTokenGroups, TOKEN_GROUPS, ulRealSize);
        GOTO_CLEANUP_ON_STATUS(status);
        
        pTokenGroups->GroupCount = pRelative->GroupCount;

        for (i = 0; i < pRelative->GroupCount; i++)
        {
            pTokenGroups->Groups[i].Attributes = pGroups[i].Attributes;
            
            ulOffset = pGroups[i].SidOffset;
            pSid = (PSID) (pBuffer + ulOffset);
            status = RtlValidateSelfRelativeSid(pSid, ulOffset, ulRelativeSize);
            GOTO_CLEANUP_ON_STATUS(status);
            
            pTokenGroups->Groups[i].Sid = pSid;
        }
    }

    ulOffset = pRelative->PrivilegesOffset;
    if (ulOffset)
    {
        status = LwRtlSafeMultiplyULONG(
            &ulSize,
            sizeof(LUID_AND_ATTRIBUTES),
            pRelative->PrivilegeCount);
        GOTO_CLEANUP_ON_STATUS(status);

        status = LwRtlSafeMultiplyULONG(
            &ulRealSize,
            sizeof(LUID_AND_ATTRIBUTES),
            pRelative->PrivilegeCount);
        GOTO_CLEANUP_ON_STATUS(status);

        status = LwRtlSafeAddULONG(
            &ulRealSize,
            ulRealSize,
            sizeof(TOKEN_PRIVILEGES));
        GOTO_CLEANUP_ON_STATUS(status);

        status = CheckOffset(ulOffset, ulSize, ulRelativeSize);
        GOTO_CLEANUP_ON_STATUS(status);

        status = RTL_ALLOCATE(&pTokenPrivileges, TOKEN_PRIVILEGES, ulRealSize);
        GOTO_CLEANUP_ON_STATUS(status);

        pTokenPrivileges->PrivilegeCount = pRelative->PrivilegeCount;
        memcpy(pTokenPrivileges->Privileges,
               pBuffer + ulOffset,
               sizeof(LUID_AND_ATTRIBUTES) * pTokenPrivileges->PrivilegeCount);
        
    }

    ulOffset = pRelative->OwnerOffset;
    if (ulOffset)
    {
        pSid = (PSID) (pBuffer + ulOffset);
        status = RtlValidateSelfRelativeSid(pSid, ulOffset, ulRelativeSize);
        GOTO_CLEANUP_ON_STATUS(status);
    
        Owner.Owner = pSid;
    }

    ulOffset = pRelative->PrimaryGroupOffset;
    if (ulOffset)
    {
        pSid = (PSID) (pBuffer + ulOffset);
        status = RtlValidateSelfRelativeSid(pSid, ulOffset, ulRelativeSize);
        GOTO_CLEANUP_ON_STATUS(status);
        
        PrimaryGroup.PrimaryGroup = pSid;
    }

    status = RtlCreateAccessToken(
        ppToken,
        &User,
        pTokenGroups,
        pTokenPrivileges,
        &Owner,
        &PrimaryGroup,
        &DefaultDacl,
        pRelative->Flags & ACCESS_TOKEN_FLAG_UNIX_PRESENT ? &Unix : NULL);
    GOTO_CLEANUP_ON_STATUS(status);

cleanup:

    RTL_FREE(&pTokenGroups);

    if (!NT_SUCCESS(status))
    {
        *ppToken = NULL;
    }

    return status;
}
Example #25
0
NTSTATUS
LwIoFuseTranslateSecurityDescriptor(
    PSECURITY_DESCRIPTOR_RELATIVE pSecurityDescriptor,
    struct stat* pStatbuf
    )
{
    NTSTATUS status = STATUS_SUCCESS;
    PSECURITY_DESCRIPTOR_ABSOLUTE pAbsolute = NULL;
    PACL pDacl = NULL;
    PACL pSacl = NULL;
    PSID pOwnerSid = NULL;
    PSID pGroupSid = NULL;
    ULONG ulOwnerSidSize = 0;
    ULONG ulGroupSidSize = 0;
    ULONG ulDaclSize = 0;
    ULONG ulSaclSize = 0;
    ULONG ulAbsSize = 0;

    /* Get required sizes */
    RtlSelfRelativeToAbsoluteSD(
        pSecurityDescriptor,
        pAbsolute,
        &ulAbsSize,
        pDacl,
        &ulDaclSize,
        pSacl,
        &ulSaclSize,
        pOwnerSid,
        &ulOwnerSidSize,
        pGroupSid,
        &ulGroupSidSize);
    
    /* Allocate space */
    status = RTL_ALLOCATE(&pAbsolute, struct _SECURITY_DESCRIPTOR_ABSOLUTE, ulAbsSize);
    BAIL_ON_NT_STATUS(status);

    if (ulDaclSize)
    {
        status = RTL_ALLOCATE(&pDacl, struct _ACL, ulDaclSize);
        BAIL_ON_NT_STATUS(status);
    }

    if (ulSaclSize)
    {
        status = RTL_ALLOCATE(&pSacl, struct _ACL, ulSaclSize);
        BAIL_ON_NT_STATUS(status);
    }

    if (ulOwnerSidSize)
    {
        status = RTL_ALLOCATE(&pOwnerSid, SID, ulOwnerSidSize);
        BAIL_ON_NT_STATUS(status);
    }

    if (ulGroupSidSize)
    {
        status = RTL_ALLOCATE(&pGroupSid, SID, ulGroupSidSize);
        BAIL_ON_NT_STATUS(status);
    }

    /* Unpack descriptor */
    status = RtlSelfRelativeToAbsoluteSD(
        pSecurityDescriptor,
        pAbsolute,
        &ulAbsSize,
        pDacl,
        &ulDaclSize,
        pSacl,
        &ulSaclSize,
        pOwnerSid,
        &ulOwnerSidSize,
        pGroupSid,
        &ulGroupSidSize);
    BAIL_ON_NT_STATUS(status);

    status = LwIoFuseTranslateAbsoluteSecurityDescriptor(
        pAbsolute,
        pOwnerSid,
        pGroupSid,
        pStatbuf);
    BAIL_ON_NT_STATUS(status);

error:
    
    RTL_FREE(&pAbsolute);
    RTL_FREE(&pDacl);
    RTL_FREE(&pSacl);
    RTL_FREE(&pOwnerSid);
    RTL_FREE(&pGroupSid);

    return status;
}
Example #26
0
static
NTSTATUS
SrvBuildDefaultShareSID(
    PSECURITY_DESCRIPTOR_RELATIVE* ppSecDesc
    )
{
    NTSTATUS ntStatus = STATUS_SUCCESS;
    PSECURITY_DESCRIPTOR_RELATIVE pRelSecDesc = NULL;
    ULONG ulRelSecDescLen = 0;
    PSECURITY_DESCRIPTOR_ABSOLUTE pAbsSecDesc = NULL;
    DWORD dwAceCount = 0;
    PSID pOwnerSid = NULL;
    PSID pGroupSid = NULL;
    PACL pDacl = NULL;
    DWORD dwSizeDacl = 0;
    union
    {
        SID sid;
        BYTE buffer[SID_MAX_SIZE];
    } localSystemSid;
    union
    {
        SID sid;
        BYTE buffer[SID_MAX_SIZE];
    } administratorsSid;
    union
    {
        SID sid;
        BYTE buffer[SID_MAX_SIZE];
    } builtinUsersSid;
    ULONG ulLocalSystemSidSize = sizeof(localSystemSid.buffer);
    ULONG ulAdministratorsSidSize = sizeof(administratorsSid.buffer);
    ULONG ulBuiltinUsersSidSize = sizeof(builtinUsersSid.buffer);
    ACCESS_MASK builtinUsersAccessMask = 0;
    ULONG ulAceFlags = OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE;

    /* Build the new Absolute Security Descriptor */

    ntStatus = RTL_ALLOCATE(
                   &pAbsSecDesc,
                   VOID,
                   SECURITY_DESCRIPTOR_ABSOLUTE_MIN_SIZE);
    BAIL_ON_NT_STATUS(ntStatus);

    ntStatus = RtlCreateSecurityDescriptorAbsolute(
                  pAbsSecDesc,
                  SECURITY_DESCRIPTOR_REVISION);
    BAIL_ON_NT_STATUS(ntStatus);

    /* Create some SIDs */

    ntStatus = RtlCreateWellKnownSid(
                   WinLocalSystemSid,
                   NULL,
                   (PSID)localSystemSid.buffer,
                   &ulLocalSystemSidSize);
    BAIL_ON_NT_STATUS(ntStatus);

    ntStatus = RtlCreateWellKnownSid(
                   WinBuiltinAdministratorsSid,
                   NULL,
                   (PSID)administratorsSid.buffer,
                   &ulAdministratorsSidSize);
    BAIL_ON_NT_STATUS(ntStatus);

    ntStatus = RtlCreateWellKnownSid(
                    WinBuiltinUsersSid,
                    NULL,
                    (PSID)builtinUsersSid.buffer,
                    &ulBuiltinUsersSidSize);
    BAIL_ON_NT_STATUS(ntStatus);

    /* Owner: Local System */

    ntStatus = RtlDuplicateSid(&pOwnerSid, &localSystemSid.sid);
    BAIL_ON_NT_STATUS(ntStatus);

    ntStatus = RtlSetOwnerSecurityDescriptor(
                   pAbsSecDesc,
                   pOwnerSid,
                   FALSE);
    BAIL_ON_NT_STATUS(ntStatus);

    /* Group: Administrators */

    ntStatus = RtlDuplicateSid(&pGroupSid, &administratorsSid.sid);
    BAIL_ON_NT_STATUS(ntStatus);

    ntStatus = RtlSetGroupSecurityDescriptor(
                   pAbsSecDesc,
                   pGroupSid,
                   FALSE);
    BAIL_ON_NT_STATUS(ntStatus);

    /* DACL:
       Administrators - (Full Control)
       LocalSystem    - (Full Control)
       Builtin Users  - (Read && Execute && List Directory Contents)
     */

    dwAceCount = 3;

    dwSizeDacl = ACL_HEADER_SIZE +
        dwAceCount * sizeof(ACCESS_ALLOWED_ACE) +
        RtlLengthSid(&localSystemSid.sid) +
        RtlLengthSid(&administratorsSid.sid) +
        RtlLengthSid(&builtinUsersSid.sid) -
        dwAceCount * sizeof(ULONG);

    ntStatus= RTL_ALLOCATE(&pDacl, VOID, dwSizeDacl);
    BAIL_ON_NT_STATUS(ntStatus);

    ntStatus = RtlCreateAcl(pDacl, dwSizeDacl, ACL_REVISION);
    BAIL_ON_NT_STATUS(ntStatus);

    ntStatus = RtlAddAccessAllowedAceEx(
                  pDacl,
                  ACL_REVISION,
                  ulAceFlags,
                  FILE_ALL_ACCESS,
                  &localSystemSid.sid);
    BAIL_ON_NT_STATUS(ntStatus);

    ntStatus = RtlAddAccessAllowedAceEx(
                  pDacl,
                  ACL_REVISION,
                  ulAceFlags,
                  FILE_ALL_ACCESS,
                  &administratorsSid.sid);
    BAIL_ON_NT_STATUS(ntStatus);

    builtinUsersAccessMask = FILE_GENERIC_READ | FILE_GENERIC_EXECUTE;

    ntStatus = RtlAddAccessAllowedAceEx(
                  pDacl,
                  ACL_REVISION,
                  ulAceFlags,
                  builtinUsersAccessMask,
                  &builtinUsersSid.sid);
    BAIL_ON_NT_STATUS(ntStatus);

    ntStatus = RtlSetDaclSecurityDescriptor(
                  pAbsSecDesc,
                  TRUE,
                  pDacl,
                  FALSE);
    BAIL_ON_NT_STATUS(ntStatus);

    /* Create the SelfRelative SD */

    ntStatus = RtlAbsoluteToSelfRelativeSD(
                   pAbsSecDesc,
                   NULL,
                   &ulRelSecDescLen);
    if (ntStatus == STATUS_BUFFER_TOO_SMALL)
    {
        ntStatus = SrvAllocateMemory(ulRelSecDescLen, (PVOID*)&pRelSecDesc);
        BAIL_ON_NT_STATUS(ntStatus);

        ntStatus = RtlAbsoluteToSelfRelativeSD(
                       pAbsSecDesc,
                       pRelSecDesc,
                       &ulRelSecDescLen);
    }
    BAIL_ON_NT_STATUS(ntStatus);

    *ppSecDesc = pRelSecDesc;

cleanup:

    RTL_FREE(&pAbsSecDesc);
    RTL_FREE(&pOwnerSid);
    RTL_FREE(&pGroupSid);
    RTL_FREE(&pDacl);

    return ntStatus;

error:

    *ppSecDesc = NULL;

    if (pRelSecDesc)
    {
        SrvFreeMemory(pRelSecDesc);
    }

    goto cleanup;
}
Example #27
0
LW_NTSTATUS
LwIoSetPathCreds(
    IN LW_PUNICODE_STRING PathPrefix,
    IN OPTIONAL LW_PIO_CREDS pCreds
    )
{
    LW_NTSTATUS Status = STATUS_SUCCESS;
    PIO_PATH_CREDS pPathCreds = NULL;
    PIO_CREDS pCredCopy = NULL;
    BOOL bInLock = FALSE;

    LWIO_LOCK_MUTEX(bInLock, &gLock);

    Status = LwIoFindPathCreds(PathPrefix, TRUE, &pPathCreds);
    BAIL_ON_NT_STATUS(Status);

    if (pPathCreds)
    {
        Status = LwIoCopyCreds(pCreds, &pCredCopy);
        BAIL_ON_NT_STATUS(Status);

        if (pPathCreds->pCreds)
        {
            LwIoDeleteCreds(pPathCreds->pCreds);
        }

        pPathCreds->pCreds = pCredCopy;
        pCredCopy = NULL;
        pPathCreds = NULL;
    }
    else if (pCreds)
    {
        Status = RTL_ALLOCATE(&pPathCreds, IO_PATH_CREDS, sizeof(IO_PATH_CREDS));
        BAIL_ON_NT_STATUS(Status);

        LwListInit(&pPathCreds->link);

        Status = LwIoNormalizePath(PathPrefix, &pPathCreds->PathPrefix);
        BAIL_ON_NT_STATUS(Status);

        Status = LwIoCopyCreds(pCreds, &pPathCreds->pCreds);
        BAIL_ON_NT_STATUS(Status);

        LwListInsertBefore(&gPathCreds, &pPathCreds->link);
        pPathCreds = NULL;
    }

cleanup:

    LWIO_UNLOCK_MUTEX(bInLock, &gLock);

    if (pCredCopy)
    {
        LwIoDeleteCreds(pCredCopy);
    }

    if (pPathCreds)
    {
        LwIoDeletePathCreds(pPathCreds);
    }

    return Status;

error:

    goto cleanup;
}
Example #28
0
LW_NTSTATUS
LwIoRdrGetPhysicalPath(
    IO_FILE_HANDLE File,
    LW_PWSTR* ppResolved
    )
{
    NTSTATUS status = STATUS_SUCCESS;
    IO_STATUS_BLOCK ioStatus;
    ULONG length = RESOLVED_PATH_LENGTH;
    PBYTE pBuffer = NULL;
    PBYTE pNewBuffer = NULL;
    PWSTR pResolved = NULL;

    status = RTL_ALLOCATE(&pBuffer, BYTE, length);
    GOTO_CLEANUP_ON_STATUS(status);

    do
    {
        status =
            LwNtDeviceIoControlFile(
                File,
                NULL,
                &ioStatus,
                RDR_DEVCTL_GET_PHYSICAL_PATH,
                NULL,
                0,
                pBuffer,
                length);

        if (status == STATUS_BUFFER_TOO_SMALL)
        {
            length *= 2;
            pNewBuffer = LwRtlMemoryRealloc(pBuffer, length);
            if (!pNewBuffer)
            {
                status = STATUS_INSUFFICIENT_RESOURCES;
                GOTO_CLEANUP_ON_STATUS(status);
            }
            pBuffer = pNewBuffer;
        }
    } while (status == STATUS_BUFFER_TOO_SMALL);

    GOTO_CLEANUP_ON_STATUS(status);

    if (ioStatus.BytesTransferred > 0)
    {
        status = LW_RTL_ALLOCATE(
            &pResolved,
            WCHAR,
            ioStatus.BytesTransferred + sizeof(WCHAR));
        GOTO_CLEANUP_ON_STATUS(status);

#ifdef WORDS_BIGENDIAN
        swab(pBuffer, pResolved, ioStatus.BytesTransferred);
#else
        memcpy(pResolved, pBuffer, ioStatus.BytesTransferred);
#endif
    }

cleanup:

    *ppResolved = pResolved;

    RTL_FREE(&pBuffer);

    return status;
}