/* Editor Settings: expandtabs and use 4 spaces for indentation
* ex: set softtabstop=4 tabstop=8 expandtab shiftwidth=4: *
* -*- mode: c, c-basic-offset: 4 -*- */
/*
* Copyright Likewise Software 2004-2010
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or (at
* your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details. You should have received a copy of the GNU General
* Public License along with this program. If not, see
* .
*
* LIKEWISE SOFTWARE MAKES THIS SOFTWARE AVAILABLE UNDER OTHER LICENSING
* TERMS AS WELL. IF YOU HAVE ENTERED INTO A SEPARATE LICENSE AGREEMENT
* WITH LIKEWISE SOFTWARE, THEN YOU MAY ELECT TO USE THE SOFTWARE UNDER THE
* TERMS OF THAT SOFTWARE LICENSE AGREEMENT INSTEAD OF THE TERMS OF THE GNU
* GENERAL PUBLIC LICENSE, NOTWITHSTANDING THE ABOVE NOTICE. IF YOU
* HAVE QUESTIONS, OR WISH TO REQUEST A COPY OF THE ALTERNATE LICENSING
* TERMS OFFERED BY LIKEWISE SOFTWARE, PLEASE CONTACT LIKEWISE SOFTWARE AT
* license@likewisesoftware.com
*/
/*
* Copyright (C) Likewise Software. All rights reserved.
*
* Module Name:
*
* state_store.c
*
* Abstract:
*
* Caching for AD Provider Database Interface
*
* Authors: Kyle Stemen (kstemen@likewisesoftware.com)
* Adam Bernstein (adam.bernstein@likewise.com)
*
*/
#include "adprovider.h"
// The database consists of several tables. Because we're
// using a flat file and the amount of data is small, the
// easiest way to update it is to replace the entire file.
// However, we may be asked to write some of it before we
// have been asked to read all of it. The simplest solution
// is to preload everything into memory and hold it until
// either we're asked for it or we determine it isn't needed.
typedef struct _ADSTATE_CONNECTION
{
pthread_rwlock_t lock;
} ADSTATE_CONNECTION, *PADSTATE_CONNECTION;
// This is the maximum number of characters necessary to store a guid in
// string form.
#define UUID_STR_SIZE 37
typedef struct _AD_REGB_DOMAIN_INFO
{
PSTR pszDnsDomainName;
PSTR pszNetbiosDomainName;
PSTR pszSid;
PSTR pszGuid;
PSTR pszTrusteeDnsDomainName;
DWORD dwTrustFlags;
DWORD dwTrustType;
DWORD dwTrustAttributes;
LSA_TRUST_DIRECTION dwTrustDirection;
LSA_TRUST_MODE dwTrustMode;
// Can be NULL (e.g. external trust)
PSTR pszForestName;
PSTR pszClientSiteName;
LSA_DM_DOMAIN_FLAGS Flags;
PLSA_DM_DC_INFO DcInfo;
PLSA_DM_DC_INFO GcInfo;
} AD_REGDB_DOMAIN_INFO, *PAD_REGDB_DOMAIN_INFO;
static
DWORD
ADState_ReadFromRegistry(
OUT OPTIONAL PAD_PROVIDER_DATA* ppProviderData,
OUT OPTIONAL PDLINKEDLIST* ppDomainList
);
DWORD
ADState_ReadRegProviderData(
OUT PAD_PROVIDER_DATA *ppProviderData
);
DWORD
ADState_ReadRegCellEntry(
IN OUT PDLINKEDLIST *ppCellList
);
DWORD
ADState_ReadRegDomainEntry(
PDLINKEDLIST *ppDomainList
);
static
VOID
ADState_FreeEnumDomainInfoCallback(
IN OUT PVOID pData,
IN PVOID pUserData
);
VOID
ADState_FreeEnumDomainInfo(
IN OUT PLSA_DM_ENUM_DOMAIN_INFO pDomainInfo
);
static
DWORD
ADState_WriteToRegistry(
IN OPTIONAL PAD_PROVIDER_DATA pProviderData,
IN OPTIONAL PLSA_DM_ENUM_DOMAIN_INFO* ppDomainInfo,
IN OPTIONAL DWORD dwDomainInfoCount,
IN PLSA_DM_ENUM_DOMAIN_INFO pDomainInfoAppend
);
static
DWORD
ADState_WriteRegProviderData(
IN PAD_PROVIDER_DATA pProviderData
);
DWORD
ADState_WriteRegDomainEntry(
IN PLSA_DM_ENUM_DOMAIN_INFO pDomainInfoEntry
);
DWORD
ADState_WriteRegCellEntry(
IN PAD_LINKED_CELL_INFO pCellEntry
);
DWORD
ADState_OpenDb(
ADSTATE_CONNECTION_HANDLE* phDb
)
{
DWORD dwError = 0;
BOOLEAN bLockCreated = FALSE;
PADSTATE_CONNECTION pConn = NULL;
dwError = LwAllocateMemory(
sizeof(ADSTATE_CONNECTION),
(PVOID*)&pConn);
BAIL_ON_LSA_ERROR(dwError);
dwError = pthread_rwlock_init(&pConn->lock, NULL);
BAIL_ON_LSA_ERROR(dwError);
bLockCreated = TRUE;
*phDb = pConn;
cleanup:
return dwError;
error:
if (pConn != NULL)
{
if (bLockCreated)
{
pthread_rwlock_destroy(&pConn->lock);
}
LW_SAFE_FREE_MEMORY(pConn);
}
*phDb = NULL;
goto cleanup;
}
void
ADState_SafeCloseDb(
ADSTATE_CONNECTION_HANDLE* phDb
)
{
DWORD dwError = LW_ERROR_SUCCESS;
ADSTATE_CONNECTION_HANDLE hDb = NULL;
if (phDb == NULL || *phDb == NULL)
{
goto cleanup;
}
hDb = *phDb;
dwError = pthread_rwlock_destroy(&hDb->lock);
if (dwError != LW_ERROR_SUCCESS)
{
LSA_LOG_ERROR("Error destroying lock [%d]", dwError);
dwError = LW_ERROR_SUCCESS;
}
LW_SAFE_FREE_MEMORY(hDb);
cleanup:
return;
}
DWORD
ADState_EmptyDb(
ADSTATE_CONNECTION_HANDLE hDb
)
{
DWORD dwError = 0;
dwError = ADState_WriteToRegistry(
NULL,
NULL,
0,
NULL);
BAIL_ON_LSA_ERROR(dwError);
cleanup:
return dwError;
error:
goto cleanup;
}
DWORD
ADState_GetProviderData(
IN ADSTATE_CONNECTION_HANDLE hDb,
OUT PAD_PROVIDER_DATA* ppResult
)
{
DWORD dwError = 0;
dwError = ADState_ReadFromRegistry(
ppResult,
NULL);
return dwError;
}
DWORD
ADState_StoreProviderData(
IN ADSTATE_CONNECTION_HANDLE hDb,
IN PAD_PROVIDER_DATA pProvider
)
{
DWORD dwError = 0;
if (pProvider)
{
dwError = ADState_WriteToRegistry(
pProvider,
NULL,
0,
NULL);
}
return dwError;
}
DWORD
ADState_GetDomainTrustList(
IN ADSTATE_CONNECTION_HANDLE hDb,
// Contains type PLSA_DM_ENUM_DOMAIN_INFO
OUT PDLINKEDLIST* ppList
)
{
return ADState_ReadFromRegistry(
NULL,
ppList);
}
DWORD
ADState_AddDomainTrust(
IN ADSTATE_CONNECTION_HANDLE hDb,
IN PLSA_DM_ENUM_DOMAIN_INFO pDomainInfo
)
{
DWORD dwError = 0;
if (pDomainInfo)
{
dwError = ADState_WriteToRegistry(
NULL,
NULL,
0,
pDomainInfo);
}
return dwError;
}
DWORD
ADState_StoreDomainTrustList(
IN ADSTATE_CONNECTION_HANDLE hDb,
IN PLSA_DM_ENUM_DOMAIN_INFO* ppDomainInfo,
IN DWORD dwDomainInfoCount
)
{
DWORD dwError = 0;
if (ppDomainInfo && dwDomainInfoCount)
{
dwError = ADState_WriteToRegistry(
NULL,
ppDomainInfo,
dwDomainInfoCount,
NULL);
}
return dwError;
}
static
DWORD
ADState_ReadFromRegistry(
OUT OPTIONAL PAD_PROVIDER_DATA* ppProviderData,
OUT OPTIONAL PDLINKEDLIST* ppDomainList
)
{
DWORD dwError = 0;
PDLINKEDLIST pRegCellList = NULL;
PDLINKEDLIST pRegDomainList = NULL;
PAD_PROVIDER_DATA pRegProviderData = NULL;
if (ppProviderData)
{
dwError = ADState_ReadRegProviderData(
&pRegProviderData);
BAIL_ON_LSA_ERROR(dwError);
dwError = ADState_ReadRegCellEntry(
&pRegCellList);
BAIL_ON_LSA_ERROR(dwError);
if (pRegProviderData)
{
pRegProviderData->pCellList = pRegCellList;
pRegCellList = NULL;
}
*ppProviderData = pRegProviderData;
pRegProviderData = NULL;
}
if (ppDomainList)
{
dwError = ADState_ReadRegDomainEntry(
&pRegDomainList);
BAIL_ON_LSA_ERROR(dwError);
*ppDomainList = pRegDomainList;
}
cleanup:
return dwError;
error:
goto cleanup;
}
VOID
ADState_FreeEnumDomainInfoList(
// Contains type PLSA_DM_ENUM_DOMAIN_INFO
IN OUT PDLINKEDLIST pList
)
{
LsaDLinkedListForEach(
pList,
ADState_FreeEnumDomainInfoCallback,
NULL);
LsaDLinkedListFree(pList);
}
static
VOID
ADState_FreeEnumDomainInfoCallback(
IN OUT PVOID pData,
IN PVOID pUserData
)
{
PLSA_DM_ENUM_DOMAIN_INFO pInfo =
(PLSA_DM_ENUM_DOMAIN_INFO)pData;
ADState_FreeEnumDomainInfo(pInfo);
}
VOID
ADState_FreeEnumDomainInfo(
IN OUT PLSA_DM_ENUM_DOMAIN_INFO pDomainInfo
)
{
if (pDomainInfo)
{
LW_SAFE_FREE_STRING(pDomainInfo->pszDnsDomainName);
LW_SAFE_FREE_STRING(pDomainInfo->pszNetbiosDomainName);
LW_SAFE_FREE_MEMORY(pDomainInfo->pSid);
LW_SAFE_FREE_MEMORY(pDomainInfo->pGuid);
LW_SAFE_FREE_STRING(pDomainInfo->pszTrusteeDnsDomainName);
LW_SAFE_FREE_STRING(pDomainInfo->pszForestName);
LW_SAFE_FREE_STRING(pDomainInfo->pszClientSiteName);
if (pDomainInfo->DcInfo)
{
// ISSUE-2008/09/10-dalmeida -- need ASSERT macro
LSA_LOG_ALWAYS("ASSERT!!! - DcInfo should never be set by DB code!");
}
if (pDomainInfo->GcInfo)
{
// ISSUE-2008/09/10-dalmeida -- need ASSERT macro
LSA_LOG_ALWAYS("ASSERT!!! - GcInfo should never be set by DB code!");
}
LwFreeMemory(pDomainInfo);
}
}
static
DWORD
ADState_WriteToRegistry(
IN OPTIONAL PAD_PROVIDER_DATA pProviderData,
IN OPTIONAL PLSA_DM_ENUM_DOMAIN_INFO* ppDomainInfo,
IN OPTIONAL DWORD dwDomainInfoCount,
IN PLSA_DM_ENUM_DOMAIN_INFO pDomainInfoAppend
)
{
DWORD dwError = 0;
DWORD dwCount = 0;
PDLINKEDLIST pCellList = NULL;
HANDLE hReg = NULL;
/* Handle the ADState_EmptyDb case */
if (!pProviderData && !ppDomainInfo && !pDomainInfoAppend)
{
dwError = RegOpenServer(&hReg);
BAIL_ON_LSA_ERROR(dwError);
/* Don't care if these fail, these keys may not exist */
RegUtilDeleteTree(
hReg,
HKEY_THIS_MACHINE,
AD_PROVIDER_REGKEY,
AD_PROVIDER_DATA_REGKEY);
RegUtilDeleteTree(
hReg,
HKEY_THIS_MACHINE,
AD_PROVIDER_REGKEY,
AD_DOMAIN_TRUST_REGKEY);
RegUtilDeleteTree(
hReg,
HKEY_THIS_MACHINE,
AD_PROVIDER_REGKEY,
AD_LINKEDCELL_REGKEY);
}
else if (pProviderData)
{
/* Don't care if this fails, value may not exist yet */
dwError = RegUtilDeleteValue(
NULL,
HKEY_THIS_MACHINE,
AD_PROVIDER_REGKEY,
AD_LINKEDCELL_REGKEY,
"CellList");
dwError = ADState_WriteRegProviderData(
pProviderData);
BAIL_ON_LSA_ERROR(dwError);
pCellList = pProviderData->pCellList;
while (pCellList)
{
dwError = ADState_WriteRegCellEntry(
pCellList->pItem);
BAIL_ON_LSA_ERROR(dwError);
pCellList = pCellList->pNext;
}
}
if (ppDomainInfo)
{
for (dwCount=0; dwCountdwDirectoryMode,
&dwValueLen);
BAIL_ON_LSA_ERROR(dwError);
dwError = ADState_ReadRegProviderDataValue(
hReg,
AD_PROVIDER_REGKEY,
AD_PROVIDER_DATA_REGKEY,
"ADConfigurationMode",
REG_DWORD,
(PVOID) &pProviderData->adConfigurationMode,
&dwValueLen);
BAIL_ON_LSA_ERROR(dwError);
dwError = ADState_ReadRegProviderDataValue(
hReg,
AD_PROVIDER_REGKEY,
AD_PROVIDER_DATA_REGKEY,
"Domain",
REG_SZ,
(PVOID) &pProviderData->szDomain,
&dwValueLen);
BAIL_ON_LSA_ERROR(dwError);
dwError = ADState_ReadRegProviderDataValue(
hReg,
AD_PROVIDER_REGKEY,
AD_PROVIDER_DATA_REGKEY,
"ShortDomain",
REG_SZ,
(PVOID) &pProviderData->szShortDomain,
&dwValueLen);
BAIL_ON_LSA_ERROR(dwError);
dwError = ADState_ReadRegProviderDataValue(
hReg,
AD_PROVIDER_REGKEY,
AD_PROVIDER_DATA_REGKEY,
"ComputerDN",
REG_SZ,
(PVOID) &pProviderData->szComputerDN,
&dwValueLen);
BAIL_ON_LSA_ERROR(dwError);
dwError = ADState_ReadRegProviderDataValue(
hReg,
AD_PROVIDER_REGKEY,
AD_PROVIDER_DATA_REGKEY,
"CellDN",
REG_SZ,
(PVOID) &pProviderData->cell.szCellDN,
&dwValueLen);
BAIL_ON_LSA_ERROR(dwError);
*ppProviderData = pProviderData;
cleanup:
RegCloseServer(hReg);
return dwError;
error:
goto cleanup;
}
DWORD
ADState_ReadRegCellEntry(
PDLINKEDLIST *ppCellList)
{
PAD_LINKED_CELL_INFO pListEntry = NULL;
DWORD dwError = 0;
HANDLE hReg = NULL;
DWORD i = 0;
DWORD dwValueLen = 0;
PSTR *ppszMultiCellListOrder = NULL;
DWORD dwMultiCellListOrder = 0;
DWORD dwIsForestCell = 0;
dwError = LwAllocateMemory(sizeof(*pListEntry), (PVOID) &pListEntry);
BAIL_ON_LSA_ERROR(dwError);
dwError = RegOpenServer(&hReg);
BAIL_ON_LSA_ERROR(dwError);
dwError = RegUtilIsValidKey(
hReg,
HKEY_THIS_MACHINE,
AD_PROVIDER_REGKEY "\\" AD_LINKEDCELL_REGKEY);
if (dwError)
{
dwError = 0;
goto cleanup;
}
/* Ordered list of cells saved in REG_MULTI_SZ value */
dwError = RegUtilGetValue(
hReg,
HKEY_THIS_MACHINE,
AD_PROVIDER_REGKEY,
AD_LINKEDCELL_REGKEY,
"CellList",
NULL,
(PVOID) &ppszMultiCellListOrder,
&dwMultiCellListOrder);
BAIL_ON_LSA_ERROR(dwError);
for (i=0; ipszCellDN,
&dwValueLen);
BAIL_ON_LSA_ERROR(dwError);
dwError = RegUtilGetValue(
hReg,
HKEY_THIS_MACHINE,
AD_PROVIDER_REGKEY "\\" AD_LINKEDCELL_REGKEY,
ppszMultiCellListOrder[i],
"Domain",
NULL,
(PVOID) &pListEntry->pszDomain,
&dwValueLen);
BAIL_ON_LSA_ERROR(dwError);
dwError = RegUtilGetValue(
hReg,
HKEY_THIS_MACHINE,
AD_PROVIDER_REGKEY "\\" AD_LINKEDCELL_REGKEY,
ppszMultiCellListOrder[i],
"IsForestCell",
NULL,
(PVOID) &dwIsForestCell,
&dwValueLen);
BAIL_ON_LSA_ERROR(dwError);
pListEntry->bIsForestCell = dwIsForestCell ? 1 : 0;
dwError = LsaDLinkedListAppend(
ppCellList,
pListEntry);
BAIL_ON_LSA_ERROR(dwError);
}
cleanup:
for (i=0; ipszDnsDomainName,
&dwValueLen);
BAIL_ON_LSA_ERROR(dwError);
if (pListEntry->pszDnsDomainName &&
!*pListEntry->pszDnsDomainName)
{
LW_SAFE_FREE_STRING(pListEntry->pszDnsDomainName);
}
dwError = RegUtilGetValue(
hReg,
HKEY_THIS_MACHINE,
AD_PROVIDER_REGKEY "\\" AD_DOMAIN_TRUST_REGKEY,
pszSubKeyPtr,
"NetBiosDomainName",
NULL,
(PVOID) &pListEntry->pszNetbiosDomainName,
&dwValueLen);
BAIL_ON_LSA_ERROR(dwError);
if (pListEntry->pszNetbiosDomainName &&
!*pListEntry->pszNetbiosDomainName)
{
LW_SAFE_FREE_STRING(pListEntry->pszNetbiosDomainName);
}
dwError = RegUtilGetValue(
hReg,
HKEY_THIS_MACHINE,
AD_PROVIDER_REGKEY "\\" AD_DOMAIN_TRUST_REGKEY,
pszSubKeyPtr,
"SID",
NULL,
(PVOID) &pszSID,
&dwValueLen);
BAIL_ON_LSA_ERROR(dwError);
dwError = LsaAllocateSidFromCString(
&pListEntry->pSid,
pszSID);
BAIL_ON_LSA_ERROR(dwError);
dwError = RegUtilGetValue(
hReg,
HKEY_THIS_MACHINE,
AD_PROVIDER_REGKEY "\\" AD_DOMAIN_TRUST_REGKEY,
pszSubKeyPtr,
"GUID",
NULL,
(PVOID) &pszGUID,
&dwValueLen);
BAIL_ON_LSA_ERROR(dwError);
if (pszGUID)
{
dwError = LwAllocateMemory(
UUID_STR_SIZE,
(PVOID*)&pListEntry->pGuid);
BAIL_ON_LSA_ERROR(dwError);
if (uuid_parse(
pszGUID,
*pListEntry->pGuid) < 0)
{
// uuid_parse returns -1 on error, but does not set errno
dwError = LW_ERROR_INVALID_OBJECTGUID;
BAIL_ON_LSA_ERROR(dwError);
}
}
dwError = RegUtilGetValue(
hReg,
HKEY_THIS_MACHINE,
AD_PROVIDER_REGKEY "\\" AD_DOMAIN_TRUST_REGKEY,
pszSubKeyPtr,
"TrusteeDomainName",
NULL,
(PVOID) &pListEntry->pszTrusteeDnsDomainName,
&dwValueLen);
BAIL_ON_LSA_ERROR(dwError);
if (pListEntry->pszTrusteeDnsDomainName &&
!*pListEntry->pszTrusteeDnsDomainName)
{
LW_SAFE_FREE_STRING(pListEntry->pszTrusteeDnsDomainName);
}
dwError = RegUtilGetValue(
hReg,
HKEY_THIS_MACHINE,
AD_PROVIDER_REGKEY "\\" AD_DOMAIN_TRUST_REGKEY,
pszSubKeyPtr,
"TrustFlags",
NULL,
(PVOID) &pListEntry->dwTrustFlags,
&dwValueLen);
BAIL_ON_LSA_ERROR(dwError);
dwError = RegUtilGetValue(
hReg,
HKEY_THIS_MACHINE,
AD_PROVIDER_REGKEY "\\" AD_DOMAIN_TRUST_REGKEY,
pszSubKeyPtr,
"TrustType",
NULL,
(PVOID) &pListEntry->dwTrustType,
&dwValueLen);
BAIL_ON_LSA_ERROR(dwError);
dwError = RegUtilGetValue(
hReg,
HKEY_THIS_MACHINE,
AD_PROVIDER_REGKEY "\\" AD_DOMAIN_TRUST_REGKEY,
pszSubKeyPtr,
"TrustAttributes",
NULL,
(PVOID) &pListEntry->dwTrustAttributes,
&dwValueLen);
BAIL_ON_LSA_ERROR(dwError);
dwError = RegUtilGetValue(
hReg,
HKEY_THIS_MACHINE,
AD_PROVIDER_REGKEY "\\" AD_DOMAIN_TRUST_REGKEY,
pszSubKeyPtr,
"TrustDirection",
NULL,
(PVOID) &pListEntry->dwTrustDirection,
&dwValueLen);
BAIL_ON_LSA_ERROR(dwError);
dwError = RegUtilGetValue(
hReg,
HKEY_THIS_MACHINE,
AD_PROVIDER_REGKEY "\\" AD_DOMAIN_TRUST_REGKEY,
pszSubKeyPtr,
"TrustMode",
NULL,
(PVOID) &pListEntry->dwTrustMode,
&dwValueLen);
BAIL_ON_LSA_ERROR(dwError);
dwError = RegUtilGetValue(
hReg,
HKEY_THIS_MACHINE,
AD_PROVIDER_REGKEY "\\" AD_DOMAIN_TRUST_REGKEY,
pszSubKeyPtr,
"ForestName",
NULL,
(PVOID) &pListEntry->pszForestName,
&dwValueLen);
BAIL_ON_LSA_ERROR(dwError);
if (pListEntry->pszForestName && !*pListEntry->pszForestName)
{
LW_SAFE_FREE_STRING(pListEntry->pszForestName);
}
dwError = RegUtilGetValue(
hReg,
HKEY_THIS_MACHINE,
AD_PROVIDER_REGKEY "\\" AD_DOMAIN_TRUST_REGKEY,
pszSubKeyPtr,
"ClientSiteName",
NULL,
(PVOID) &pListEntry->pszClientSiteName,
&dwValueLen);
BAIL_ON_LSA_ERROR(dwError);
if (pListEntry->pszClientSiteName && !*pListEntry->pszClientSiteName)
{
LW_SAFE_FREE_STRING(pListEntry->pszClientSiteName);
}
dwError = RegUtilGetValue(
hReg,
HKEY_THIS_MACHINE,
AD_PROVIDER_REGKEY "\\" AD_DOMAIN_TRUST_REGKEY,
pszSubKeyPtr,
"Flags",
NULL,
(PVOID) &pListEntry->Flags,
&dwValueLen);
BAIL_ON_LSA_ERROR(dwError);
dwError = LsaDLinkedListAppend(
ppDomainList,
pListEntry);
BAIL_ON_LSA_ERROR(dwError);
pListEntry = NULL;
LW_SAFE_FREE_STRING(pszSubKey);
}
cleanup:
if (hReg)
{
RegCloseServer(hReg);
}
LW_SAFE_FREE_STRING(pszSubKey);
LW_SAFE_FREE_STRING(pszSID);
LW_SAFE_FREE_STRING(pszGUID);
for (i = 0; i < dwSubKeysLen; i++)
{
LW_SAFE_FREE_MEMORY(ppwszSubKeys[i]);
}
LW_SAFE_FREE_MEMORY(ppwszSubKeys);
return dwError;
error:
goto cleanup;
return dwError;
}
DWORD
ADState_WriteRegDomainEntry(
IN PLSA_DM_ENUM_DOMAIN_INFO pDomainInfoEntry
)
{
HANDLE hReg = NULL;
DWORD dwError = 0;
PSTR pszSid = NULL;
char szGuid[UUID_STR_SIZE] = {0};
dwError = RegOpenServer(&hReg);
BAIL_ON_LSA_ERROR(dwError);
/* Add top level AD DomainTrust data registry key */
dwError = RegUtilAddKey(
hReg,
HKEY_THIS_MACHINE,
AD_PROVIDER_REGKEY,
AD_DOMAIN_TRUST_REGKEY);
BAIL_ON_LSA_ERROR(dwError);
/* Add top level AD DomainTrust data registry key */
dwError = RegUtilAddKey(
hReg,
HKEY_THIS_MACHINE,
AD_PROVIDER_REGKEY "\\" AD_DOMAIN_TRUST_REGKEY,
pDomainInfoEntry->pszNetbiosDomainName);
BAIL_ON_LSA_ERROR(dwError);
/* Write DomainTrust data entries to registry */
dwError = RegUtilSetValue(
hReg,
HKEY_THIS_MACHINE,
AD_PROVIDER_REGKEY "\\" AD_DOMAIN_TRUST_REGKEY,
pDomainInfoEntry->pszNetbiosDomainName,
"DNSDomainName",
REG_SZ,
pDomainInfoEntry->pszDnsDomainName,
pDomainInfoEntry->pszDnsDomainName ?
strlen(pDomainInfoEntry->pszDnsDomainName) : 0);
BAIL_ON_LSA_ERROR(dwError);
dwError = RegUtilSetValue(
hReg,
HKEY_THIS_MACHINE,
AD_PROVIDER_REGKEY "\\" AD_DOMAIN_TRUST_REGKEY,
pDomainInfoEntry->pszNetbiosDomainName,
"NetBiosDomainName",
REG_SZ,
pDomainInfoEntry->pszNetbiosDomainName,
pDomainInfoEntry->pszNetbiosDomainName ?
strlen(pDomainInfoEntry->pszNetbiosDomainName) : 0);
BAIL_ON_LSA_ERROR(dwError);
if (pDomainInfoEntry->pSid != NULL)
{
dwError = LsaAllocateCStringFromSid(
&pszSid,
pDomainInfoEntry->pSid);
BAIL_ON_LSA_ERROR(dwError);
}
dwError = RegUtilSetValue(
hReg,
HKEY_THIS_MACHINE,
AD_PROVIDER_REGKEY "\\" AD_DOMAIN_TRUST_REGKEY,
pDomainInfoEntry->pszNetbiosDomainName,
"SID",
REG_SZ,
pszSid,
pszSid ? strlen(pszSid) : 0);
BAIL_ON_LSA_ERROR(dwError);
if (pDomainInfoEntry->pGuid)
{
// Writes into a 37-byte caller allocated string
uuid_unparse(*pDomainInfoEntry->pGuid, szGuid);
}
dwError = RegUtilSetValue(
hReg,
HKEY_THIS_MACHINE,
AD_PROVIDER_REGKEY "\\" AD_DOMAIN_TRUST_REGKEY,
pDomainInfoEntry->pszNetbiosDomainName,
"GUID",
REG_SZ,
szGuid,
strlen(szGuid));
BAIL_ON_LSA_ERROR(dwError);
dwError = RegUtilSetValue(
hReg,
HKEY_THIS_MACHINE,
AD_PROVIDER_REGKEY "\\" AD_DOMAIN_TRUST_REGKEY,
pDomainInfoEntry->pszNetbiosDomainName,
"TrusteeDomainName",
REG_SZ,
pDomainInfoEntry->pszTrusteeDnsDomainName,
pDomainInfoEntry->pszTrusteeDnsDomainName ?
strlen(pDomainInfoEntry->pszTrusteeDnsDomainName) : 0);
BAIL_ON_LSA_ERROR(dwError);
dwError = RegUtilSetValue(
hReg,
HKEY_THIS_MACHINE,
AD_PROVIDER_REGKEY "\\" AD_DOMAIN_TRUST_REGKEY,
pDomainInfoEntry->pszNetbiosDomainName,
"TrustFlags",
REG_DWORD,
&pDomainInfoEntry->dwTrustFlags,
sizeof(pDomainInfoEntry->dwTrustFlags));
BAIL_ON_LSA_ERROR(dwError);
dwError = RegUtilSetValue(
hReg,
HKEY_THIS_MACHINE,
AD_PROVIDER_REGKEY "\\" AD_DOMAIN_TRUST_REGKEY,
pDomainInfoEntry->pszNetbiosDomainName,
"TrustType",
REG_DWORD,
&pDomainInfoEntry->dwTrustType,
sizeof(pDomainInfoEntry->dwTrustType));
BAIL_ON_LSA_ERROR(dwError);
dwError = RegUtilSetValue(
hReg,
HKEY_THIS_MACHINE,
AD_PROVIDER_REGKEY "\\" AD_DOMAIN_TRUST_REGKEY,
pDomainInfoEntry->pszNetbiosDomainName,
"TrustAttributes",
REG_DWORD,
&pDomainInfoEntry->dwTrustAttributes,
sizeof(pDomainInfoEntry->dwTrustAttributes));
BAIL_ON_LSA_ERROR(dwError);
dwError = RegUtilSetValue(
hReg,
HKEY_THIS_MACHINE,
AD_PROVIDER_REGKEY "\\" AD_DOMAIN_TRUST_REGKEY,
pDomainInfoEntry->pszNetbiosDomainName,
"TrustDirection",
REG_DWORD,
&pDomainInfoEntry->dwTrustDirection,
sizeof(pDomainInfoEntry->dwTrustDirection));
BAIL_ON_LSA_ERROR(dwError);
dwError = RegUtilSetValue(
hReg,
HKEY_THIS_MACHINE,
AD_PROVIDER_REGKEY "\\" AD_DOMAIN_TRUST_REGKEY,
pDomainInfoEntry->pszNetbiosDomainName,
"TrustMode",
REG_DWORD,
&pDomainInfoEntry->dwTrustMode,
sizeof(pDomainInfoEntry->dwTrustMode));
BAIL_ON_LSA_ERROR(dwError);
dwError = RegUtilSetValue(
hReg,
HKEY_THIS_MACHINE,
AD_PROVIDER_REGKEY "\\" AD_DOMAIN_TRUST_REGKEY,
pDomainInfoEntry->pszNetbiosDomainName,
"ForestName",
REG_SZ,
pDomainInfoEntry->pszForestName,
pDomainInfoEntry->pszForestName ?
strlen(pDomainInfoEntry->pszForestName) : 0);
BAIL_ON_LSA_ERROR(dwError);
dwError = RegUtilSetValue(
hReg,
HKEY_THIS_MACHINE,
AD_PROVIDER_REGKEY "\\" AD_DOMAIN_TRUST_REGKEY,
pDomainInfoEntry->pszNetbiosDomainName,
"ClientSiteName",
REG_SZ,
pDomainInfoEntry->pszClientSiteName,
pDomainInfoEntry->pszClientSiteName ?
strlen(pDomainInfoEntry->pszClientSiteName) : 0);
BAIL_ON_LSA_ERROR(dwError);
dwError = RegUtilSetValue(
hReg,
HKEY_THIS_MACHINE,
AD_PROVIDER_REGKEY "\\" AD_DOMAIN_TRUST_REGKEY,
pDomainInfoEntry->pszNetbiosDomainName,
"Flags",
REG_DWORD,
&pDomainInfoEntry->Flags,
sizeof(pDomainInfoEntry->Flags));
BAIL_ON_LSA_ERROR(dwError);
cleanup:
LW_SAFE_FREE_STRING(pszSid);
RegCloseServer(hReg);
return dwError;
error:
goto cleanup;
}
DWORD
ADState_WriteRegCellEntry(
IN PAD_LINKED_CELL_INFO pCellEntry
)
{
HANDLE hReg = NULL;
DWORD dwError = 0;
DWORD dwBooleanValue = 0;
DWORD dwValueLen = 0;
PSTR *ppszMultiCellListOrder = NULL;
PSTR *ppszNewMultiCellListOrder = NULL;
dwError = RegOpenServer(&hReg);
BAIL_ON_LSA_ERROR(dwError);
/* Add top level AD CellEntry data registry key */
dwError = RegUtilAddKey(
hReg,
HKEY_THIS_MACHINE,
AD_PROVIDER_REGKEY,
AD_LINKEDCELL_REGKEY);
BAIL_ON_LSA_ERROR(dwError);
/* Add cell-specific key entry */
dwError = RegUtilAddKey(
hReg,
HKEY_THIS_MACHINE,
AD_PROVIDER_REGKEY "\\" AD_LINKEDCELL_REGKEY,
pCellEntry->pszCellDN);
BAIL_ON_LSA_ERROR(dwError);
dwError = RegUtilGetValue(
hReg,
HKEY_THIS_MACHINE,
AD_PROVIDER_REGKEY,
AD_LINKEDCELL_REGKEY,
"CellList",
NULL,
(PVOID) &ppszMultiCellListOrder,
&dwValueLen);
dwError = LwReallocMemory(
ppszMultiCellListOrder,
(PVOID) &ppszNewMultiCellListOrder,
(dwValueLen+2) * sizeof(PSTR));
BAIL_ON_LSA_ERROR(dwError);
ppszMultiCellListOrder = ppszNewMultiCellListOrder;
ppszMultiCellListOrder[dwValueLen] = pCellEntry->pszCellDN;
ppszMultiCellListOrder[dwValueLen+1] = NULL;
dwError = RegUtilSetValue(
hReg,
HKEY_THIS_MACHINE,
AD_PROVIDER_REGKEY,
AD_LINKEDCELL_REGKEY,
"CellList",
REG_MULTI_SZ,
(PVOID) ppszMultiCellListOrder,
dwValueLen);
BAIL_ON_LSA_ERROR(dwError);
/* Write cell data entries to registry */
dwError = RegUtilSetValue(
hReg,
HKEY_THIS_MACHINE,
AD_PROVIDER_REGKEY "\\" AD_LINKEDCELL_REGKEY,
pCellEntry->pszCellDN,
"CellDN",
REG_SZ,
pCellEntry->pszCellDN,
strlen(pCellEntry->pszCellDN));
BAIL_ON_LSA_ERROR(dwError);
dwError = RegUtilSetValue(
hReg,
HKEY_THIS_MACHINE,
AD_PROVIDER_REGKEY "\\" AD_LINKEDCELL_REGKEY,
pCellEntry->pszCellDN,
"Domain",
REG_SZ,
pCellEntry->pszDomain,
strlen(pCellEntry->pszDomain));
BAIL_ON_LSA_ERROR(dwError);
dwBooleanValue = pCellEntry->bIsForestCell;
dwError = RegUtilSetValue(
hReg,
HKEY_THIS_MACHINE,
AD_PROVIDER_REGKEY "\\" AD_LINKEDCELL_REGKEY,
pCellEntry->pszCellDN,
"IsForestCell",
REG_DWORD,
&dwBooleanValue,
sizeof(dwBooleanValue));
BAIL_ON_LSA_ERROR(dwError);
cleanup:
RegCloseServer(hReg);
return dwError;
error:
goto cleanup;
}
static
DWORD
ADState_WriteRegProviderData(
IN PAD_PROVIDER_DATA pProviderData
)
{
HANDLE hReg = NULL;
DWORD dwAdConfigurationMode = 0;
DWORD dwError = 0;
PSTR pszString = NULL;
dwError = RegOpenServer(&hReg);
BAIL_ON_LSA_ERROR(dwError);
/* Add top level AD provider provider data registry key */
dwError = RegUtilAddKey(
hReg,
HKEY_THIS_MACHINE,
AD_PROVIDER_REGKEY,
AD_PROVIDER_DATA_REGKEY);
BAIL_ON_LSA_ERROR(dwError);
/* Write provider data entries to registry */
dwError = ADState_WriteRegProviderDataValue(
hReg,
AD_PROVIDER_REGKEY,
AD_PROVIDER_DATA_REGKEY,
"DirectoryMode",
REG_DWORD,
&pProviderData->dwDirectoryMode,
sizeof(pProviderData->dwDirectoryMode));
BAIL_ON_LSA_ERROR(dwError);
dwAdConfigurationMode = (DWORD) pProviderData->adConfigurationMode;
dwError = ADState_WriteRegProviderDataValue(
hReg,
AD_PROVIDER_REGKEY,
AD_PROVIDER_DATA_REGKEY,
"ADConfigurationMode",
REG_DWORD,
&dwAdConfigurationMode,
sizeof(dwAdConfigurationMode));
BAIL_ON_LSA_ERROR(dwError);
pszString = (PSTR) pProviderData->szDomain;
dwError = ADState_WriteRegProviderDataValue(
hReg,
AD_PROVIDER_REGKEY,
AD_PROVIDER_DATA_REGKEY,
"Domain",
REG_SZ,
pszString,
strlen(pProviderData->szDomain));
BAIL_ON_LSA_ERROR(dwError);
pszString = (PSTR) pProviderData->szShortDomain;
dwError = ADState_WriteRegProviderDataValue(
hReg,
AD_PROVIDER_REGKEY,
AD_PROVIDER_DATA_REGKEY,
"ShortDomain",
REG_SZ,
pszString,
strlen(pProviderData->szShortDomain));
BAIL_ON_LSA_ERROR(dwError);
pszString = (PSTR) pProviderData->szComputerDN;
dwError = ADState_WriteRegProviderDataValue(
hReg,
AD_PROVIDER_REGKEY,
AD_PROVIDER_DATA_REGKEY,
"ComputerDN",
REG_SZ,
pszString,
strlen(pProviderData->szComputerDN));
BAIL_ON_LSA_ERROR(dwError);
pszString = (PSTR) pProviderData->cell.szCellDN;
dwError = ADState_WriteRegProviderDataValue(
hReg,
AD_PROVIDER_REGKEY,
AD_PROVIDER_DATA_REGKEY,
"CellDN",
REG_SZ,
pszString,
strlen(pProviderData->cell.szCellDN));
BAIL_ON_LSA_ERROR(dwError);
cleanup:
RegCloseServer(hReg);
return dwError;
error:
goto cleanup;
}