Example #1
0
NTSTATUS
SqliteOpenKeyInternal_inlock_inDblock(
    IN OPTIONAL HANDLE handle,
    IN PCWSTR pwszFullKeyName, // Full Key Path
    IN ACCESS_MASK AccessDesired,
    OUT OPTIONAL PREG_KEY_HANDLE* ppKeyHandle
    )
{
    NTSTATUS status = STATUS_SUCCESS;
    PREG_SRV_API_STATE pServerState = (PREG_SRV_API_STATE)handle;
    PREG_DB_KEY pRegEntry = NULL;
    PREG_KEY_HANDLE pKeyHandle = NULL;
    PREG_KEY_CONTEXT pKeyCtx = NULL;

    BAIL_ON_NT_INVALID_STRING(pwszFullKeyName);

    pKeyCtx = SqliteCacheLocateActiveKey_inlock(pwszFullKeyName);
    if (!pKeyCtx)
    {
        status = RegDbOpenKey_inlock(ghCacheConnection, pwszFullKeyName, &pRegEntry);
        BAIL_ON_NT_STATUS(status);

        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;

    *ppKeyHandle = pKeyHandle;

cleanup:
    SqliteReleaseKeyContext_inlock(pKeyCtx);
    RegDbSafeFreeEntryKey(&pRegEntry);

    return status;

error:
    SqliteSafeFreeKeyHandle_inlock(pKeyHandle);
    *ppKeyHandle = NULL;

    goto cleanup;
}
Example #2
0
NTSTATUS
SqliteCacheInsertActiveKey(
    IN PREG_KEY_CONTEXT pKeyResult
    )
{
	NTSTATUS status = STATUS_SUCCESS;
    BOOLEAN bInLock = FALSE;

    LWREG_LOCK_MUTEX(bInLock, &gActiveKeyList.mutex);

    status = SqliteCacheInsertActiveKey_inlock(pKeyResult);
    BAIL_ON_NT_STATUS(status);

cleanup:
    LWREG_UNLOCK_MUTEX(bInLock, &gActiveKeyList.mutex);

    return status;

error:
    goto cleanup;
}
Example #3
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;
}