static
DWORD
LsaPstorepGetPluginNames(
    OUT PSTR** Names,
    OUT PDWORD Count
    )
{
    DWORD dwError = 0;
    HANDLE registryConnection = NULL;
    HKEY keyHandle = NULL;
    PSTR* loadOrder = NULL;
    DWORD loadOrderCount = 0;

    dwError = LwRegOpenServer(&registryConnection);
    GOTO_CLEANUP_ON_WINERROR(dwError);

    dwError = LwRegOpenKeyExA(
                    registryConnection,
                    NULL,
                    LSA_PSTORE_REG_KEY_PATH_PLUGINS,
                    0,
                    GENERIC_READ,
                    &keyHandle);
    if (dwError == LWREG_ERROR_NO_SUCH_KEY_OR_VALUE)
    {
        dwError = 0;
        GOTO_CLEANUP();
    }
    GOTO_CLEANUP_ON_WINERROR(dwError);

    dwError = LsaPstorepRegGetMultiStringA(
                    registryConnection,
                    keyHandle,
                    LSA_PSTORE_REG_VALUE_NAME_PLUGINS_LOAD_ORDER,
                    &loadOrder,
                    &loadOrderCount);
    if (dwError == LWREG_ERROR_NO_SUCH_KEY_OR_VALUE)
    {
        dwError = 0;
    }
    GOTO_CLEANUP_ON_WINERROR(dwError);

cleanup:
    if (dwError)
    {
        LSA_PSTORE_FREE_STRING_ARRAY_A(&loadOrder, &loadOrderCount);
    }

    *Names = loadOrder;
    *Count = loadOrderCount;

    return dwError;
}
static
DWORD
LsaPstorepGetPluginPath(
    IN PCSTR pszName,
    OUT PSTR* ppszPath
    )
{
    DWORD dwError = 0;
    int EE = 0;
    HANDLE registryConnection = NULL;
    HKEY keyHandle = NULL;
    PSTR pszKeyPath = NULL;
    PSTR pszPath = NULL;

    dwError = LwNtStatusToWin32Error(LwRtlCStringAllocatePrintf(
                    &pszKeyPath,
                    "%s\\%s",
                    LSA_PSTORE_REG_KEY_PATH_PLUGINS,
                    pszName));
    GOTO_CLEANUP_ON_WINERROR_EE(dwError, EE);

    dwError = LwRegOpenServer(&registryConnection);
    GOTO_CLEANUP_ON_WINERROR_EE(dwError, EE);

    dwError = LwRegOpenKeyExA(
                    registryConnection,
                    NULL,
                    pszKeyPath,
                    0,
                    GENERIC_READ,
                    &keyHandle);
    if (dwError == LWREG_ERROR_NO_SUCH_KEY_OR_VALUE)
    {
        LW_RTL_LOG_ERROR("LSA pstore plugin '%s' is missing its configuration registry key '%s'",
                pszName, pszKeyPath);
        dwError = ERROR_DLL_INIT_FAILED;
        GOTO_CLEANUP_EE(EE);
    }
    GOTO_CLEANUP_ON_WINERROR_EE(dwError, EE);

    dwError = LsaPstorepRegGetStringA(
                    registryConnection,
                    keyHandle,
                    LSA_PSTORE_REG_VALUE_NAME_PLUGINS_PATH,
                    &pszPath);
    if (dwError == LWREG_ERROR_NO_SUCH_KEY_OR_VALUE)
    {
        LW_RTL_LOG_ERROR("LSA pstore plugin '%s' is missing the '%s' configuration value from its configuration registry key '%s'",
                pszName, LSA_PSTORE_REG_VALUE_NAME_PLUGINS_PATH, pszKeyPath);
        dwError = ERROR_DLL_INIT_FAILED;
        GOTO_CLEANUP_EE(EE);
    }
    GOTO_CLEANUP_ON_WINERROR_EE(dwError, EE);

cleanup:
    if (dwError)
    {
        LSA_PSTORE_FREE(&pszPath);
    }

    if (keyHandle)
    {
        LwRegCloseKey(registryConnection, keyHandle);
    }

    if (registryConnection)
    {
        LwRegCloseServer(registryConnection);
    }

    LSA_PSTORE_FREE(&pszKeyPath);

    *ppszPath = pszPath;

    LSA_PSTORE_LOG_LEAVE_ERROR_EE(dwError, EE);
    return dwError;
}
DWORD
LwpsLegacyWritePassword(
    IN PLWPS_LEGACY_STATE pContext,
    IN PLSA_MACHINE_PASSWORD_INFO_A pPasswordInfo
    )
{
    DWORD dwError = 0;
    int EE = 0;
    HKEY rootKeyHandle = NULL;
    HKEY accountKeyHandle = NULL;
    HKEY passwordKeyHandle = NULL;
    PSTR pszRegistryPath = NULL;
    PSTR pszDefaultDomain = NULL;
    time_t unixLastChangeTime = 0;

    //
    // Convert data
    //

    if (0 == pPasswordInfo->Account.LastChangeTime)
    {
        // Treat 0 as "now".
        unixLastChangeTime = time(NULL);
    }
    else
    {
        dwError = LwpsConvertTimeWindowsToUnix(
                        pPasswordInfo->Account.LastChangeTime,
                        &unixLastChangeTime);
        GOTO_CLEANUP_ON_WINERROR_EE(dwError, EE);
    }

    if ((unixLastChangeTime < 0) || (unixLastChangeTime > MAXDWORD))
    {
        dwError = ERROR_ARITHMETIC_OVERFLOW;
        GOTO_CLEANUP_ON_WINERROR_EE(dwError, EE);
    }

    //
    // Compute registry paths
    //

    dwError = LwAllocateStringPrintf(
                  &pszRegistryPath,
                  "%s\\%s\\%s",
                  PSTOREDB_REGISTRY_AD_KEY,
                  pPasswordInfo->Account.DnsDomainName,
                  PSTOREDB_REGISTRY_PSTORE_SUBKEY);
    GOTO_CLEANUP_ON_WINERROR_EE(dwError, EE);

    //
    // Create keys
    //

    dwError = RegUtilAddKeySecDesc(
                  pContext->hReg,
                  NULL,
                  pszRegistryPath,
                  NULL,
                  KEY_ALL_ACCESS,
                  pContext->pAccountSecurityDescriptor);
    GOTO_CLEANUP_ON_WINERROR_EE(dwError, EE);

    dwError = RegUtilAddKeySecDesc(
                  pContext->hReg,
                  NULL,
                  pszRegistryPath,
                  PSTOREDB_REGISTRY_PASSWORD_INFO_SUBKEY,
                  KEY_ALL_ACCESS,
                  pContext->pPasswordSecurityDescriptor);
    GOTO_CLEANUP_ON_WINERROR_EE(dwError, EE);

    //
    // Open keys
    //

    dwError = LwRegOpenKeyExA(
                    pContext->hReg,
                    NULL,
                    HKEY_THIS_MACHINE,
                    0,
                    KEY_READ,
                    &rootKeyHandle);
    GOTO_CLEANUP_ON_WINERROR_EE(dwError, EE);

    dwError = LwRegOpenKeyExA(
                    pContext->hReg,
                    rootKeyHandle,
                    pszRegistryPath,
                    0,
                    KEY_WRITE,
                    &accountKeyHandle);
    GOTO_CLEANUP_ON_WINERROR_EE(dwError, EE);

    dwError = LwRegOpenKeyExA(
                    pContext->hReg,
                    accountKeyHandle,
                    PSTOREDB_REGISTRY_PASSWORD_INFO_SUBKEY,
                    0,
                    KEY_WRITE,
                    &passwordKeyHandle);
    GOTO_CLEANUP_ON_WINERROR_EE(dwError, EE);

    //
    // Write account portion
    //

    dwError = LsaPstorepRegSetStringA(
                    pContext->hReg,
                    accountKeyHandle,
                    LWPS_REG_DNS_DOMAIN_NAME,
                    pPasswordInfo->Account.DnsDomainName);
    GOTO_CLEANUP_ON_WINERROR_EE(dwError, EE);

    dwError = LsaPstorepRegSetStringA(
                    pContext->hReg,
                    accountKeyHandle,
                    LWPS_REG_NETBIOS_DOMAIN_NAME,
                    pPasswordInfo->Account.NetbiosDomainName);
    GOTO_CLEANUP_ON_WINERROR_EE(dwError, EE);

    dwError = LsaPstorepRegSetStringA(
                    pContext->hReg,
                    accountKeyHandle,
                    LWPS_REG_DOMAIN_SID,
                    pPasswordInfo->Account.DomainSid);
    GOTO_CLEANUP_ON_WINERROR_EE(dwError, EE);

    dwError = LsaPstorepRegSetStringA(
                    pContext->hReg,
                    accountKeyHandle,
                    LWPS_REG_SAM_ACCOUNT_NAME,
                    pPasswordInfo->Account.SamAccountName);
    GOTO_CLEANUP_ON_WINERROR_EE(dwError, EE);

    dwError = LsaPstorepRegSetDword(
                    pContext->hReg,
                    accountKeyHandle,
                    LWPS_REG_ACCOUNT_FLAGS,
                    pPasswordInfo->Account.AccountFlags);
    GOTO_CLEANUP_ON_WINERROR_EE(dwError, EE);

    dwError = LsaPstorepRegSetDword(
                    pContext->hReg,
                    accountKeyHandle,
                    LWPS_REG_KEY_VERSION_NUMBER,
                    pPasswordInfo->Account.KeyVersionNumber);
    GOTO_CLEANUP_ON_WINERROR_EE(dwError, EE);

    dwError = LsaPstorepRegSetStringA(
                    pContext->hReg,
                    accountKeyHandle,
                    LWPS_REG_FQDN,
                    pPasswordInfo->Account.Fqdn);
    GOTO_CLEANUP_ON_WINERROR_EE(dwError, EE);

    dwError = LsaPstorepRegSetDword(
                    pContext->hReg,
                    accountKeyHandle,
                    LWPS_REG_UNIX_LAST_CHANGE_TIME,
                    (DWORD) unixLastChangeTime);
    GOTO_CLEANUP_ON_WINERROR_EE(dwError, EE);

    //
    // Write password portion
    //

    dwError = LsaPstorepRegSetStringA(
                    pContext->hReg,
                    passwordKeyHandle,
                    LWPS_REG_PASSWORD,
                    pPasswordInfo->Password);
    GOTO_CLEANUP_ON_WINERROR_EE(dwError, EE);

cleanup:
    if (passwordKeyHandle)
    {
        LwRegCloseKey(pContext->hReg, passwordKeyHandle);
    }
    if (accountKeyHandle)
    {
        LwRegCloseKey(pContext->hReg, accountKeyHandle);
    }
    if (rootKeyHandle)
    {
        LwRegCloseKey(pContext->hReg, rootKeyHandle);
    }

    LW_SAFE_FREE_MEMORY(pszRegistryPath);
    LW_SAFE_FREE_MEMORY(pszDefaultDomain);

    LSA_PSTORE_LOG_LEAVE_ERROR_EE(dwError, EE);
    return dwError;
}
DWORD
LwpsLegacyReadPassword(
    IN PLWPS_LEGACY_STATE pContext,
    IN PCSTR pszDnsDomainName,
    OUT OPTIONAL PLSA_MACHINE_PASSWORD_INFO_A* ppPasswordInfo
    )
{
    DWORD dwError = 0;
    int EE = 0;
    PLSA_MACHINE_PASSWORD_INFO_A pPasswordInfo = NULL;
    HKEY rootKeyHandle = NULL;
    HKEY accountKeyHandle = NULL;
    HKEY passwordKeyHandle = NULL;
    PSTR pszRegistryPath = NULL;
    PSTR pszDefaultDomain = NULL;
    DWORD unixLastChangeTime = 0;

    //
    // Compute registry path
    //

    dwError = LwAllocateStringPrintf(
                  &pszRegistryPath,
                  "%s\\%s\\%s",
                  PSTOREDB_REGISTRY_AD_KEY,
                  pszDnsDomainName,
                  PSTOREDB_REGISTRY_PSTORE_SUBKEY);
    GOTO_CLEANUP_ON_WINERROR_EE(dwError, EE);

    //
    // Open keys
    //

    dwError = LwRegOpenKeyExA(
                    pContext->hReg,
                    NULL,
                    HKEY_THIS_MACHINE,
                    0,
                    KEY_READ,
                    &rootKeyHandle);
    GOTO_CLEANUP_ON_WINERROR_EE(dwError, EE);

    dwError = LwRegOpenKeyExA(
                    pContext->hReg,
                    rootKeyHandle,
                    pszRegistryPath,
                    0,
                    KEY_READ,
                    &accountKeyHandle);
    if (LWREG_ERROR_NO_SUCH_KEY_OR_VALUE == dwError)
    {
        dwError = NERR_SetupNotJoined;
    }
    GOTO_CLEANUP_ON_WINERROR_EE(dwError, EE);

    dwError = LwRegOpenKeyExA(
                    pContext->hReg,
                    accountKeyHandle,
                    PSTOREDB_REGISTRY_PASSWORD_INFO_SUBKEY,
                    0,
                    KEY_READ,
                    &passwordKeyHandle);
    if (LWREG_ERROR_NO_SUCH_KEY_OR_VALUE == dwError)
    {
        dwError = NERR_SetupNotJoined;
    }
    GOTO_CLEANUP_ON_WINERROR_EE(dwError, EE);

    //
    // Allocate info structure
    //

    dwError = LSA_PSTORE_ALLOCATE_AUTO(&pPasswordInfo);
    GOTO_CLEANUP_ON_WINERROR_EE(dwError, EE);

    //
    // Read account portion
    //

    dwError = LsaPstorepRegGetStringA(
                    pContext->hReg,
                    accountKeyHandle,
                    LWPS_REG_DNS_DOMAIN_NAME,
                    &pPasswordInfo->Account.DnsDomainName);
    if (LWREG_ERROR_NO_SUCH_KEY_OR_VALUE == dwError)
    {
        dwError = NERR_SetupNotJoined;
    }
    GOTO_CLEANUP_ON_WINERROR_EE(dwError, EE);

    dwError = LsaPstorepRegGetStringA(
                    pContext->hReg,
                    accountKeyHandle,
                    LWPS_REG_NETBIOS_DOMAIN_NAME,
                    &pPasswordInfo->Account.NetbiosDomainName);
    if (LWREG_ERROR_NO_SUCH_KEY_OR_VALUE == dwError)
    {
        dwError = NERR_SetupNotJoined;
    }
    GOTO_CLEANUP_ON_WINERROR_EE(dwError, EE);

    dwError = LsaPstorepRegGetStringA(
                    pContext->hReg,
                    accountKeyHandle,
                    LWPS_REG_DOMAIN_SID,
                    &pPasswordInfo->Account.DomainSid);
    if (LWREG_ERROR_NO_SUCH_KEY_OR_VALUE == dwError)
    {
        dwError = NERR_SetupNotJoined;
    }
    GOTO_CLEANUP_ON_WINERROR_EE(dwError, EE);

    dwError = LsaPstorepRegGetStringA(
                    pContext->hReg,
                    accountKeyHandle,
                    LWPS_REG_SAM_ACCOUNT_NAME,
                    &pPasswordInfo->Account.SamAccountName);
    if (LWREG_ERROR_NO_SUCH_KEY_OR_VALUE == dwError)
    {
        dwError = NERR_SetupNotJoined;
    }
    GOTO_CLEANUP_ON_WINERROR_EE(dwError, EE);

    dwError = LsaPstorepRegGetDword(
                    pContext->hReg,
                    accountKeyHandle,
                    LWPS_REG_ACCOUNT_FLAGS,
                    &pPasswordInfo->Account.AccountFlags);
    if (LWREG_ERROR_NO_SUCH_KEY_OR_VALUE == dwError)
    {
        dwError = NERR_SetupNotJoined;
    }
    GOTO_CLEANUP_ON_WINERROR_EE(dwError, EE);

    dwError = LsaPstorepRegGetDword(
                    pContext->hReg,
                    accountKeyHandle,
                    LWPS_REG_KEY_VERSION_NUMBER,
                    &pPasswordInfo->Account.KeyVersionNumber);
    if (LWREG_ERROR_NO_SUCH_KEY_OR_VALUE == dwError)
    {
        dwError = NERR_SetupNotJoined;
    }
    GOTO_CLEANUP_ON_WINERROR_EE(dwError, EE);

    dwError = LsaPstorepRegGetStringA(
                    pContext->hReg,
                    accountKeyHandle,
                    LWPS_REG_FQDN,
                    &pPasswordInfo->Account.Fqdn);
    if (LWREG_ERROR_NO_SUCH_KEY_OR_VALUE == dwError)
    {
        dwError = NERR_SetupNotJoined;
    }
    GOTO_CLEANUP_ON_WINERROR_EE(dwError, EE);

    dwError = LsaPstorepRegGetDword(
                    pContext->hReg,
                    accountKeyHandle,
                    LWPS_REG_UNIX_LAST_CHANGE_TIME,
                    &unixLastChangeTime);
    if (LWREG_ERROR_NO_SUCH_KEY_OR_VALUE == dwError)
    {
        dwError = NERR_SetupNotJoined;
    }
    GOTO_CLEANUP_ON_WINERROR_EE(dwError, EE);

    dwError = LwpsConvertTimeUnixToWindows(
                    (time_t) unixLastChangeTime,
                    &pPasswordInfo->Account.LastChangeTime);
    if (LWREG_ERROR_NO_SUCH_KEY_OR_VALUE == dwError)
    {
        dwError = NERR_SetupNotJoined;
    }
    GOTO_CLEANUP_ON_WINERROR_EE(dwError, EE);

    //
    // Read password portion
    //

    dwError = LsaPstorepRegGetStringA(
                    pContext->hReg,
                    passwordKeyHandle,
                    LWPS_REG_PASSWORD,
                    &pPasswordInfo->Password);
    if (LWREG_ERROR_NO_SUCH_KEY_OR_VALUE == dwError)
    {
        dwError = NERR_SetupNotJoined;
    }
    GOTO_CLEANUP_ON_WINERROR_EE(dwError, EE);

cleanup:
    if (dwError)
    {
        LSA_PSTORE_FREE_PASSWORD_INFO_A(&pPasswordInfo);
    }

    if (passwordKeyHandle)
    {
        LwRegCloseKey(pContext->hReg, passwordKeyHandle);
    }
    if (accountKeyHandle)
    {
        LwRegCloseKey(pContext->hReg, accountKeyHandle);
    }
    if (rootKeyHandle)
    {
        LwRegCloseKey(pContext->hReg, rootKeyHandle);
    }

    LW_SAFE_FREE_MEMORY(pszRegistryPath);
    LW_SAFE_FREE_MEMORY(pszDefaultDomain);

    if (ppPasswordInfo)
    {
        *ppPasswordInfo = pPasswordInfo;
    }
    else
    {
        LSA_PSTORE_FREE_PASSWORD_INFO_A(&pPasswordInfo);
    }

    LSA_PSTORE_LOG_LEAVE_ERROR_EE(dwError, EE);
    return dwError;
}
Beispiel #5
0
static
DWORD
RemoveSambaLoadPath(
    IN HANDLE hReg
    )
{
    DWORD type = 0;
    HKEY hKey = NULL;
    DWORD error = 0;
    DWORD loadOrderSize = 0;
    PSTR pLoadOrder = NULL;
    // Do not free
    PSTR pPos = NULL;
    BOOLEAN removedSamba = FALSE;

    error = LwRegOpenKeyExA(
                hReg,
                NULL,
                LSA_PSTORE_REG_KEY_PATH_PLUGINS,
                0,
                KEY_WRITE,
                &hKey);
    BAIL_ON_LSA_ERROR(error);

    error = LwRegGetValueA(
                hReg,
                hKey,
                NULL,
                "LoadOrder",
                RRF_RT_REG_MULTI_SZ,
                &type,
                NULL,
                &loadOrderSize);
    if (error == LWREG_ERROR_NO_SUCH_KEY_OR_VALUE)
    {
        LW_RTL_LOG_INFO("LoadOrder key not present");
        error = 0;
        goto cleanup;
    }
    BAIL_ON_LSA_ERROR(error);

    error = LwAllocateMemory(loadOrderSize, (PVOID*) &pLoadOrder);
    BAIL_ON_LSA_ERROR(error);

    error = LwRegGetValueA(
                hReg,
                hKey,
                NULL,
                "LoadOrder",
                RRF_RT_REG_MULTI_SZ,
                &type,
                pLoadOrder,
                &loadOrderSize);
    BAIL_ON_LSA_ERROR(error);

    pPos = pLoadOrder;
    while (pPos[0])
    {
        DWORD valueLen = strlen(pPos) + 1;

        if (!strcmp(pPos, PLUGIN_NAME))
        {
            loadOrderSize -= valueLen;
            memmove(
                    pPos,
                    pPos + valueLen,
                    valueLen);
            removedSamba = TRUE;
        }
        else
        {
            pPos += valueLen;
        }
    }

    if (removedSamba)
    {
        LW_RTL_LOG_INFO("Removed Samba from load order");
        error = LwRegSetValueExA(
            hReg,
            hKey,
            "LoadOrder",
            0,
            REG_MULTI_SZ,
            (const BYTE*)pLoadOrder,
            loadOrderSize);
        BAIL_ON_LSA_ERROR(error);
    }

cleanup:
    if (hKey != NULL)
    {
        LwRegCloseKey(
                hReg,
                hKey);
    }
    LW_SAFE_FREE_STRING(pLoadOrder);

    return error;
}
Beispiel #6
0
static
DWORD
AddSambaLoadPath(
    IN HANDLE hReg
    )
{
    DWORD type = 0;
    HKEY hKey = NULL;
    DWORD error = 0;
    DWORD loadOrderSize = 0;
    PSTR pLoadOrder = NULL;
    DWORD newLoadOrderSize = 0;
    PSTR pNewLoadOrder = NULL;
    PCSTR pPos = NULL;

    error = LwRegOpenKeyExA(
                hReg,
                NULL,
                LSA_PSTORE_REG_KEY_PATH_PLUGINS,
                0,
                KEY_WRITE,
                &hKey);
    BAIL_ON_LSA_ERROR(error);

    error = LwRegGetValueA(
                hReg,
                hKey,
                NULL,
                "LoadOrder",
                RRF_RT_REG_MULTI_SZ,
                &type,
                NULL,
                &loadOrderSize);
    if (error == LWREG_ERROR_NO_SUCH_KEY_OR_VALUE)
    {
        loadOrderSize = 1;
        error = LwAllocateMemory(loadOrderSize, (PVOID*) &pLoadOrder);
        BAIL_ON_LSA_ERROR(error);
        // pLoadOrder is already memset to 0

        error = 0;
    }
    else
    {
        BAIL_ON_LSA_ERROR(error);

        error = LwAllocateMemory(loadOrderSize, (PVOID*) &pLoadOrder);
        BAIL_ON_LSA_ERROR(error);

        error = LwRegGetValueA(
                    hReg,
                    hKey,
                    NULL,
                    "LoadOrder",
                    RRF_RT_REG_MULTI_SZ,
                    &type,
                    pLoadOrder,
                    &loadOrderSize);
        BAIL_ON_LSA_ERROR(error);
    }

    pPos = pLoadOrder;
    while (pPos[0])
    {
        if (!strcmp(pPos, PLUGIN_NAME))
        {
            LW_RTL_LOG_INFO("Samba is already in the load order");
            goto cleanup;
        }
        pPos += strlen(pPos) + 1;
    }

    newLoadOrderSize = loadOrderSize + strlen(PLUGIN_NAME) + 1;
    error = LwAllocateMemory(newLoadOrderSize, (PVOID*) &pNewLoadOrder);
    BAIL_ON_LSA_ERROR(error);

    memcpy(pNewLoadOrder, PLUGIN_NAME, strlen(PLUGIN_NAME) + 1);
    memcpy(pNewLoadOrder + strlen(PLUGIN_NAME) + 1, pLoadOrder, loadOrderSize);

    error = LwRegSetValueExA(
        hReg,
        hKey,
        "LoadOrder",
        0,
        REG_MULTI_SZ,
        (const BYTE*)pNewLoadOrder,
        newLoadOrderSize);
    BAIL_ON_LSA_ERROR(error);

cleanup:
    if (hKey != NULL)
    {
        LwRegCloseKey(
                hReg,
                hKey);
    }
    LW_SAFE_FREE_STRING(pLoadOrder);
    LW_SAFE_FREE_STRING(pNewLoadOrder);

    return error;
}