Example #1
0
NTSTATUS FspFsvolSetSecurityComplete(
    PIRP Irp, const FSP_FSCTL_TRANSACT_RSP *Response)
{
    FSP_ENTER_IOC(PAGED_CODE());

    if (!NT_SUCCESS(Response->IoStatus.Status))
    {
        Irp->IoStatus.Information = 0;
        Result = Response->IoStatus.Status;
        FSP_RETURN();
    }

    PFILE_OBJECT FileObject = IrpSp->FileObject;
    FSP_FILE_NODE *FileNode = FileObject->FsContext;
    FSP_FSCTL_TRANSACT_REQ *Request = FspIrpRequest(Irp);

    /* if the security descriptor that we got back is valid */
    if (0 < Response->Rsp.SetSecurity.SecurityDescriptor.Size &&
        Response->Buffer + Response->Rsp.SetSecurity.SecurityDescriptor.Size <=
            (PUINT8)Response + Response->Size &&
        RtlValidRelativeSecurityDescriptor((PVOID)Response->Buffer,
            Response->Rsp.SetSecurity.SecurityDescriptor.Size, 0))
    {
        /* update the cached security */
        FspFileNodeSetSecurity(FileNode,
            Response->Buffer, Response->Rsp.SetSecurity.SecurityDescriptor.Size);
    }
    else
    {
        /* invalidate the cached security */
        FspFileNodeSetSecurity(FileNode, 0, 0);
    }

    FspIopRequestContext(Request, RequestFileNode) = 0;
    FspFileNodeReleaseOwner(FileNode, Full, Request);

    Irp->IoStatus.Information = 0;
    Result = STATUS_SUCCESS;

    FSP_LEAVE_IOC("FileObject=%p, SecurityInformation=%x",
        IrpSp->FileObject, IrpSp->Parameters.SetSecurity.SecurityInformation);
}
Example #2
0
/* Create a new key, if the key exists already,
 * open the existing key
 */
NTSTATUS
SqliteCreateKeyInternal(
    IN OPTIONAL HANDLE handle,
    IN PREG_KEY_CONTEXT pParentKeyCtx,
    IN PWSTR pwszFullKeyName, // Full Key Path
    IN ACCESS_MASK AccessDesired,
    IN OPTIONAL PSECURITY_DESCRIPTOR_RELATIVE pSecDescRel,
    IN ULONG ulSecDescLength,
    OUT OPTIONAL PREG_KEY_HANDLE* ppKeyHandle,
    OUT OPTIONAL PDWORD pdwDisposition
    )
{
	NTSTATUS status = STATUS_SUCCESS;
    PREG_DB_KEY pRegEntry = NULL;
    PREG_KEY_HANDLE pKeyHandle = NULL;
    PREG_KEY_CONTEXT pKeyCtx = NULL;
    BOOLEAN bInLock = FALSE;
    PREG_SRV_API_STATE pServerState = (PREG_SRV_API_STATE)handle;
    PSECURITY_DESCRIPTOR_RELATIVE pSecDescRelToSet = NULL;
    ULONG ulSecDescLengthToSet = 0;
    DWORD dwDisposition = 0;

    // Full key path
    BAIL_ON_NT_INVALID_STRING(pwszFullKeyName);

    // when starting up lwregd pServerState is NULL and
    // creating root key can skip ACL check
    if (pServerState && !pServerState->pToken)
    {
        status = RegSrvCreateAccessToken(pServerState->peerUID,
                                         pServerState->peerGID,
                                         &pServerState->pToken);
        BAIL_ON_NT_STATUS(status);
    }

    LWREG_LOCK_MUTEX(bInLock, &gActiveKeyList.mutex);

	status = SqliteOpenKeyInternal_inlock(
			        handle,
			        pwszFullKeyName, // Full Key Path
	                AccessDesired,
	                &pKeyHandle);
	if (!status)
	{
		dwDisposition = REG_OPENED_EXISTING_KEY;

		goto done;
	}
	else if (STATUS_OBJECT_NAME_NOT_FOUND == status)
	{
		status = 0;
	}
	BAIL_ON_NT_STATUS(status);

	// Root Key has to be created with a given SD
	if (!pParentKeyCtx && !pSecDescRel)
	{
		status = STATUS_INTERNAL_ERROR;
		BAIL_ON_NT_STATUS(status);
	}

	// ACL check
	// Get key's security descriptor
	// Inherit from its direct parent or given by caller
	if (!pSecDescRel || !ulSecDescLength)
	{
		BAIL_ON_INVALID_KEY_CONTEXT(pParentKeyCtx);

		status = SqliteCacheKeySecurityDescriptor(pParentKeyCtx);
		BAIL_ON_NT_STATUS(status);

		pSecDescRelToSet = pParentKeyCtx->pSecurityDescriptor;
		ulSecDescLengthToSet = pParentKeyCtx->ulSecDescLength;
	}
	else
	{
		pSecDescRelToSet = pSecDescRel;
		ulSecDescLengthToSet = ulSecDescLength;
	}

	// Make sure SD has at least owner information
	if (!RtlValidRelativeSecurityDescriptor(pSecDescRelToSet,
			                                ulSecDescLengthToSet,
			                                OWNER_SECURITY_INFORMATION))
	{
		status = STATUS_INVALID_SECURITY_DESCR;
		BAIL_ON_NT_STATUS(status);
	}

	// Create key with SD
	status = RegDbCreateKey(ghCacheConnection,
							pwszFullKeyName,
							pSecDescRelToSet,
							ulSecDescLengthToSet,
							&pRegEntry);
	BAIL_ON_NT_STATUS(status);

    if (pParentKeyCtx)
	{
	    SqliteCacheResetParentKeySubKeyInfo_inlock(pParentKeyCtx->pwszKeyName);
	}

	status = SqliteCreateKeyContext(pRegEntry, &pKeyCtx);
	BAIL_ON_NT_STATUS(status);

	// Cache this new key in gActiveKeyList
	status = SqliteCacheInsertActiveKey_inlock(pKeyCtx);
	BAIL_ON_NT_STATUS(status);

	status = SqliteCreateKeyHandle(pServerState ? pServerState->pToken : NULL,
	                               AccessDesired,
	                               pKeyCtx,
	                               &pKeyHandle);
	BAIL_ON_NT_STATUS(status);
	pKeyCtx = NULL;

	dwDisposition = REG_CREATED_NEW_KEY;

done:
    if (ppKeyHandle)
	{
		*ppKeyHandle = pKeyHandle;
	}
	else
	{
		SqliteSafeFreeKeyHandle_inlock(pKeyHandle);
	}

    if (pdwDisposition)
    {
    	*pdwDisposition =  dwDisposition;
    }

cleanup:

    SqliteReleaseKeyContext_inlock(pKeyCtx);

    LWREG_UNLOCK_MUTEX(bInLock, &gActiveKeyList.mutex);

    RegDbSafeFreeEntryKey(&pRegEntry);

    return status;

error:

    if (ppKeyHandle)
    {
	    *ppKeyHandle = NULL;
    }

    SqliteSafeFreeKeyHandle_inlock(pKeyHandle);

    goto cleanup;
}
Example #3
0
NTSTATUS FspFsvolQuerySecurityComplete(
    PIRP Irp, const FSP_FSCTL_TRANSACT_RSP *Response)
{
    FSP_ENTER_IOC(PAGED_CODE());

    if (!NT_SUCCESS(Response->IoStatus.Status))
    {
        Irp->IoStatus.Information = 0;
        Result = Response->IoStatus.Status;
        FSP_RETURN();
    }

    PFILE_OBJECT FileObject = IrpSp->FileObject;
    FSP_FILE_NODE *FileNode = FileObject->FsContext;
    SECURITY_INFORMATION SecurityInformation = IrpSp->Parameters.QuerySecurity.SecurityInformation;
    PVOID Buffer = Irp->AssociatedIrp.SystemBuffer;
    ULONG Length = IrpSp->Parameters.QuerySecurity.Length;
    PVOID SecurityBuffer = 0;
    FSP_FSCTL_TRANSACT_REQ *Request = FspIrpRequest(Irp);
    BOOLEAN Success;

    if (0 != FspIopRequestContext(Request, RequestFileNode))
    {
        /* check that the security descriptor we got back is valid */
        if (Response->Buffer + Response->Rsp.QuerySecurity.SecurityDescriptor.Size >
                (PUINT8)Response + Response->Size ||
            !RtlValidRelativeSecurityDescriptor((PVOID)Response->Buffer,
                Response->Rsp.QuerySecurity.SecurityDescriptor.Size, 0))
        {
            Irp->IoStatus.Information = 0;
            Result = STATUS_INVALID_SECURITY_DESCR;
            FSP_RETURN();
        }

        FspIopRequestContext(Request, RequestSecurityChangeNumber) = (PVOID)FileNode->SecurityChangeNumber;
        FspIopRequestContext(Request, RequestFileNode) = 0;

        FspFileNodeReleaseOwner(FileNode, Full, Request);
    }

    Success = DEBUGTEST(90) && FspFileNodeTryAcquireExclusive(FileNode, Main);
    if (!Success)
    {
        FspIopRetryCompleteIrp(Irp, Response, &Result);
        FSP_RETURN();
    }

    Success = !FspFileNodeTrySetSecurity(FileNode,
        Response->Buffer, Response->Rsp.QuerySecurity.SecurityDescriptor.Size,
        (ULONG)(UINT_PTR)FspIopRequestContext(Request, RequestSecurityChangeNumber));
    Success = Success && FspFileNodeReferenceSecurity(FileNode, &SecurityBuffer, 0);
    FspFileNodeRelease(FileNode, Main);
    if (Success)
    {
        Result = FspQuerySecurityDescriptorInfo(SecurityInformation, Buffer, &Length, SecurityBuffer);
        FspFileNodeDereferenceSecurity(SecurityBuffer);
    }
    else
    {
        SecurityBuffer = (PVOID)Response->Buffer;
        Result = FspQuerySecurityDescriptorInfo(SecurityInformation, Buffer, &Length, SecurityBuffer);
    }

    Irp->IoStatus.Information = Length;

    FSP_LEAVE_IOC("FileObject=%p, SecurityInformation=%x",
        IrpSp->FileObject, IrpSp->Parameters.QuerySecurity.SecurityInformation);
}