2542 lines
70 KiB
C++
2542 lines
70 KiB
C++
/*++
|
||
|
||
Copyright (c) 1996 Microsoft Corporation
|
||
|
||
Module Name:
|
||
|
||
pfset.cpp
|
||
|
||
Abstract:
|
||
|
||
Routines to set info to the jet database.
|
||
|
||
Author:
|
||
|
||
Jin Huang (jinhuang) 28-Oct-1996
|
||
|
||
Revision History:
|
||
|
||
--*/
|
||
|
||
#include "headers.h"
|
||
#include "serverp.h"
|
||
#include "pfp.h"
|
||
#include "regvalue.h"
|
||
#pragma hdrstop
|
||
|
||
//#define SCE_DBG 1
|
||
|
||
SCESTATUS
|
||
ScepOpenPrevPolicyContext(
|
||
IN PSCECONTEXT hProfile,
|
||
OUT PSCECONTEXT *phPrevProfile
|
||
);
|
||
|
||
SCESTATUS
|
||
ScepClosePrevPolicyContext(
|
||
IN OUT PSCECONTEXT *phProfile
|
||
);
|
||
|
||
|
||
SCESTATUS
|
||
ScepStartANewSection(
|
||
IN PSCECONTEXT hProfile,
|
||
IN OUT PSCESECTION *hSection,
|
||
IN SCEJET_TABLE_TYPE ProfileType,
|
||
IN PCWSTR SectionName
|
||
)
|
||
/* ++
|
||
Routine Description:
|
||
|
||
This routine open a JET section by Name. If the section exists, it is
|
||
opened, else it is created.
|
||
|
||
Arguments:
|
||
|
||
hProfile - The JET database handle
|
||
|
||
hSection - the JET section handle to return
|
||
|
||
ProfileType - the table to open
|
||
|
||
SectionName - the JET section name
|
||
|
||
Return Value:
|
||
|
||
SCESTATUS_SUCCESS
|
||
|
||
SCESTATUS returned from SceJetCloseSection,
|
||
SceJetAddSection,
|
||
SceJetOpenSection
|
||
|
||
-- */
|
||
{
|
||
SCESTATUS rc=SCESTATUS_SUCCESS;
|
||
DOUBLE SectionID;
|
||
|
||
if ( *hSection != NULL ) {
|
||
//
|
||
// free the previous used section
|
||
//
|
||
rc = SceJetCloseSection( hSection, FALSE );
|
||
}
|
||
|
||
if ( rc == SCESTATUS_SUCCESS ) {
|
||
//
|
||
// SceJetAddSection will seek for the section name first.
|
||
// if a match is found, the section id is returned, else add it.
|
||
// this is good for SAP profile.
|
||
//
|
||
rc = SceJetAddSection(
|
||
hProfile,
|
||
SectionName,
|
||
&SectionID
|
||
);
|
||
if ( rc == SCESTATUS_SUCCESS ) {
|
||
|
||
rc = SceJetOpenSection(
|
||
hProfile,
|
||
SectionID,
|
||
ProfileType,
|
||
hSection
|
||
);
|
||
}
|
||
}
|
||
return( rc );
|
||
|
||
}
|
||
|
||
|
||
SCESTATUS
|
||
ScepCompareAndSaveIntValue(
|
||
IN PSCESECTION hSection,
|
||
IN PWSTR Name,
|
||
IN BOOL bReplaceExistOnly,
|
||
IN DWORD BaseValue,
|
||
IN DWORD CurrentValue
|
||
)
|
||
/* ++
|
||
Routine Description:
|
||
|
||
This routine compares DWORD value system settings with the baseline profile
|
||
settings. If there is mismatch or unknown, the entry is saved in the SAP
|
||
profile.
|
||
|
||
Arguments:
|
||
|
||
hSection - The JET section context
|
||
|
||
Name - The entry name
|
||
|
||
BaseLine- The baseline profile value to compare with
|
||
|
||
CurrentValue - The current system setting (DWORD value)
|
||
|
||
Return Value:
|
||
|
||
SCESTATUS_SUCCESS
|
||
SCESTATUS_INVALID_PARAMETER
|
||
SCESTATUS returned from SceJetSetLine
|
||
|
||
-- */
|
||
{
|
||
SCESTATUS rc;
|
||
TCHAR StrValue[12];
|
||
|
||
if ( Name == NULL )
|
||
return(SCESTATUS_INVALID_PARAMETER);
|
||
|
||
if ( CurrentValue == SCE_NO_VALUE ) {
|
||
return(SCESTATUS_SUCCESS);
|
||
}
|
||
|
||
if ( ( CurrentValue == BaseValue) &&
|
||
( BaseValue != SCE_NO_VALUE) &&
|
||
( BaseValue != SCE_SNAPSHOT_VALUE) ) {
|
||
return(SCESTATUS_SUCCESS);
|
||
}
|
||
|
||
if ( bReplaceExistOnly &&
|
||
(BaseValue == SCE_NO_VALUE) ) {
|
||
return(SCESTATUS_SUCCESS);
|
||
}
|
||
|
||
memset(StrValue, '\0', 24);
|
||
|
||
//
|
||
// either mismatched/unknown
|
||
// Save this entry
|
||
//
|
||
swprintf(StrValue, L"%d", CurrentValue);
|
||
|
||
rc = SceJetSetLine( hSection, Name, FALSE, StrValue, wcslen(StrValue)*2, 0);
|
||
|
||
switch ( BaseValue ) {
|
||
case SCE_SNAPSHOT_VALUE:
|
||
|
||
ScepLogOutput2(2, 0, StrValue);
|
||
break;
|
||
|
||
case SCE_NO_VALUE:
|
||
|
||
if ( CurrentValue == SCE_ERROR_VALUE ) {
|
||
ScepLogOutput3(2, 0, SCEDLL_STATUS_ERROR, Name);
|
||
} else {
|
||
ScepLogOutput3(2, 0, SCEDLL_STATUS_NC, Name);
|
||
}
|
||
break;
|
||
|
||
default:
|
||
|
||
ScepLogOutput3(2, 0, SCEDLL_STATUS_MISMATCH, Name);
|
||
break;
|
||
}
|
||
|
||
#ifdef SCE_DBG
|
||
wprintf(L"rc=%d, Section: %d, %s=%d\n", rc, (DWORD)(hSection->SectionID), Name, CurrentValue);
|
||
#endif
|
||
return(rc);
|
||
|
||
}
|
||
|
||
|
||
SCESTATUS
|
||
ScepCompareAndSaveStringValue(
|
||
IN PSCESECTION hSection,
|
||
IN PWSTR Name,
|
||
IN PWSTR BaseValue,
|
||
IN PWSTR CurrentValue,
|
||
IN DWORD CurrentLen
|
||
)
|
||
/* ++
|
||
Routine Description:
|
||
|
||
This routine compares system settings in string with the baseline profile
|
||
settings. If there is mismatch or unknown, the entry is saved in the SAP
|
||
profile.
|
||
|
||
Arguments:
|
||
|
||
hSection - The section handle
|
||
|
||
Name - The entry name
|
||
|
||
BaseLine- The baseline profile value to compare with
|
||
|
||
CurrentValue - The current system setting
|
||
|
||
CurrentLen - The length of the current setting
|
||
|
||
Return Value:
|
||
|
||
SCESTATUS_SUCCESS
|
||
SCESTATUS_INVALID_PARAMETER
|
||
SCESTATUS returned from SceJetSetLine
|
||
|
||
-- */
|
||
{
|
||
SCESTATUS rc;
|
||
|
||
if ( Name == NULL )
|
||
return(SCESTATUS_INVALID_PARAMETER);
|
||
|
||
if ( CurrentValue == NULL )
|
||
return(SCESTATUS_SUCCESS);
|
||
|
||
rc = SceJetSetLine( hSection, Name, FALSE, CurrentValue, CurrentLen, 0);
|
||
|
||
if ( BaseValue ) {
|
||
if ( (ULONG_PTR)BaseValue == SCE_SNAPSHOT_VALUE ) {
|
||
|
||
ScepLogOutput2(2, 0, CurrentValue);
|
||
} else {
|
||
|
||
ScepLogOutput3(2, 0, SCEDLL_STATUS_MISMATCH, Name);
|
||
}
|
||
} else {
|
||
ScepLogOutput3(2, 0, SCEDLL_STATUS_NC, Name);
|
||
}
|
||
|
||
#ifdef SCE_DBG
|
||
wprintf(L"rc=%d, Section: %d, %s=%s\n", rc, (DWORD)(hSection->SectionID), Name, CurrentValue);
|
||
#endif
|
||
|
||
return(rc);
|
||
|
||
}
|
||
|
||
|
||
SCESTATUS
|
||
ScepSaveObjectString(
|
||
IN PSCESECTION hSection,
|
||
IN PWSTR Name,
|
||
IN BOOL IsContainer,
|
||
IN BYTE Flag,
|
||
IN PWSTR Value OPTIONAL,
|
||
IN DWORD ValueLen
|
||
)
|
||
/* ++
|
||
Routine Description:
|
||
|
||
This routine writes registry/file settings to the JET section. Registry/
|
||
file setting includes a flag (mismatch/unknown) and the security
|
||
descriptor in text format. The object setting is saved in the format of
|
||
1 byte flag followed by the Value.
|
||
|
||
Arguments:
|
||
|
||
hSection - the JET section handle
|
||
|
||
Name - The entry name
|
||
|
||
IsContainer - TRUE = The object is a container
|
||
FALSE = The object is not a container
|
||
|
||
Flag - the flag for object's setting
|
||
1 - Mismatch
|
||
0 - Unknown
|
||
|
||
Value - The security descriptor in text
|
||
|
||
ValueLen - the length of the text security descriptor
|
||
|
||
Return Value:
|
||
|
||
SCESTATUS_SUCCESS
|
||
SCESTATUS_INVALID_PARAMETER
|
||
|
||
SCESTATUS returned from SceJetSetLine
|
||
|
||
-- */
|
||
{
|
||
SCESTATUS rc;
|
||
DWORD Len;
|
||
PWSTR ValueToSet=NULL;
|
||
|
||
|
||
if ( hSection == NULL ||
|
||
Name == NULL ) {
|
||
return(SCESTATUS_INVALID_PARAMETER);
|
||
}
|
||
|
||
if ( Value != NULL )
|
||
Len = ( ValueLen+1)*sizeof(WCHAR);
|
||
else
|
||
Len = sizeof(WCHAR);
|
||
|
||
ValueToSet = (PWSTR)ScepAlloc( (UINT)0, Len+sizeof(WCHAR) );
|
||
|
||
if ( ValueToSet == NULL )
|
||
return(SCESTATUS_NOT_ENOUGH_RESOURCE);
|
||
|
||
//
|
||
// The first byte is the flag, the second byte is IsContainer (1,0)
|
||
//
|
||
*((BYTE *)ValueToSet) = Flag;
|
||
|
||
*((CHAR *)ValueToSet+1) = IsContainer ? '1' : '0';
|
||
|
||
if ( Value != NULL ) {
|
||
swprintf(ValueToSet+1, L"%s", Value );
|
||
ValueToSet[ValueLen+1] = L'\0'; //terminate this string
|
||
} else {
|
||
ValueToSet[1] = L'\0';
|
||
}
|
||
|
||
rc = SceJetSetLine( hSection, Name, FALSE, ValueToSet, Len, 0);
|
||
|
||
switch ( Flag ) {
|
||
case SCE_STATUS_CHILDREN_CONFIGURED:
|
||
case SCE_STATUS_NOT_CONFIGURED:
|
||
ScepLogOutput3(2, 0, SCEDLL_STATUS_NC, Name);
|
||
break;
|
||
case SCE_STATUS_ERROR_NOT_AVAILABLE:
|
||
ScepLogOutput3(2, 0, SCEDLL_STATUS_ERROR, Name);
|
||
break;
|
||
case SCE_STATUS_GOOD:
|
||
ScepLogOutput3(2, 0, SCEDLL_STATUS_MATCH, Name);
|
||
break;
|
||
case SCE_STATUS_NEW_SERVICE:
|
||
ScepLogOutput3(2, 0, SCEDLL_STATUS_NEW, Name);
|
||
break;
|
||
case SCE_STATUS_NO_ACL_SUPPORT:
|
||
ScepLogOutput3(2, 0, SCEDLL_STATUS_NOACL, Name);
|
||
break;
|
||
default:
|
||
ScepLogOutput3(2, 0, SCEDLL_STATUS_MISMATCH, Name);
|
||
break;
|
||
}
|
||
|
||
#ifdef SCE_DBG
|
||
wprintf(L"rc=%d, Section: %d, %s=%s\n", rc, (DWORD)(hSection->SectionID), Name, ValueToSet);
|
||
#endif
|
||
ScepFree( ValueToSet );
|
||
|
||
return( rc );
|
||
}
|
||
|
||
|
||
SCESTATUS
|
||
ScepWriteNameListValue(
|
||
IN LSA_HANDLE LsaPolicy OPTIONAL,
|
||
IN PSCESECTION hSection,
|
||
IN PWSTR Name,
|
||
IN PSCE_NAME_LIST NameList,
|
||
IN DWORD dwWriteOption,
|
||
IN INT Status
|
||
)
|
||
/* ++
|
||
Routine Description:
|
||
|
||
This routine writes a key with a list of value to the JET section. The list
|
||
of values is saved in a MULTI-SZ format which is separated by a NULL char and
|
||
terminated by 2 NULLs. If the list is NULL, nothing is saved unless
|
||
SaveEmptyList is set to TRUE, where a NULL value is saved with the key.
|
||
|
||
Arguments:
|
||
|
||
hSection - the JET hsection handle
|
||
|
||
Name - The key name
|
||
|
||
NameList - the list of values
|
||
|
||
SaveEmptyList - TRUE = save NULL value if the list is empty
|
||
FALSE = DO NOT save if the list is empty
|
||
|
||
Return Value:
|
||
|
||
SCESTATUS_SUCCESS
|
||
SCESTATUS_NOT_ENOUGH_RESOURCE
|
||
|
||
SCESTATUS returned from SceJetSetLine
|
||
|
||
-- */
|
||
{ SCESTATUS rc=SCESTATUS_SUCCESS;
|
||
DWORD TotalSize=0;
|
||
PWSTR Value=NULL;
|
||
PSCE_NAME_LIST pName;
|
||
PWSTR pTemp=NULL;
|
||
DWORD Len;
|
||
DWORD i=0,j;
|
||
DWORD cntAllocated=0;
|
||
SCE_TEMP_NODE *tmpArray=NULL, *pa=NULL;
|
||
PWSTR SidString = NULL;
|
||
|
||
|
||
for ( pName=NameList; pName != NULL; pName = pName->Next ) {
|
||
|
||
if ( pName->Name == NULL ) {
|
||
continue;
|
||
}
|
||
|
||
if ( dwWriteOption & SCE_WRITE_CONVERT ) {
|
||
|
||
if ( i >= cntAllocated ) {
|
||
//
|
||
// array is not enough, reallocate
|
||
//
|
||
tmpArray = (SCE_TEMP_NODE *)ScepAlloc(LPTR, (cntAllocated+16)*sizeof(SCE_TEMP_NODE));
|
||
|
||
if ( tmpArray ) {
|
||
|
||
//
|
||
// move pointers from the old array to the new array
|
||
//
|
||
|
||
if ( pa ) {
|
||
for ( j=0; j<cntAllocated; j++ ) {
|
||
tmpArray[j].Name = pa[j].Name;
|
||
tmpArray[j].Len = pa[j].Len;
|
||
tmpArray[j].bFree = pa[j].bFree;
|
||
}
|
||
ScepFree(pa);
|
||
}
|
||
pa = tmpArray;
|
||
tmpArray = NULL;
|
||
|
||
|
||
cntAllocated += 16;
|
||
|
||
} else {
|
||
rc = SCESTATUS_NOT_ENOUGH_RESOURCE;
|
||
break;
|
||
}
|
||
}
|
||
|
||
if ( LsaPolicy && wcschr(pName->Name, L'\\') ) {
|
||
|
||
//
|
||
// check if the name has a '\' in it, it should be translated to
|
||
// *SID
|
||
//
|
||
pTemp = NULL;
|
||
ScepConvertNameToSidString(LsaPolicy, pName->Name, FALSE, &pTemp, &Len);
|
||
|
||
if ( pTemp ) {
|
||
pa[i].Name = pTemp;
|
||
pa[i].bFree = TRUE;
|
||
} else {
|
||
pa[i].Name = pName->Name;
|
||
pa[i].bFree = FALSE;
|
||
Len= wcslen(pName->Name);
|
||
}
|
||
|
||
}
|
||
|
||
else if (dwWriteOption & SCE_WRITE_LOCAL_TABLE &&
|
||
ScepLookupNameTable( pName->Name, &SidString ) ) {
|
||
|
||
pa[i].Name = SidString;
|
||
pa[i].bFree = TRUE;
|
||
Len = wcslen(SidString);
|
||
|
||
}
|
||
|
||
else {
|
||
pa[i].Name = pName->Name;
|
||
pa[i].bFree = FALSE;
|
||
Len = wcslen(pName->Name);
|
||
}
|
||
pa[i].Len = Len;
|
||
|
||
TotalSize += Len + 1;
|
||
i++;
|
||
} else {
|
||
|
||
TotalSize += wcslen(pName->Name)+1;
|
||
}
|
||
}
|
||
|
||
TotalSize ++;
|
||
|
||
if ( SCESTATUS_SUCCESS == rc ) {
|
||
|
||
if ( TotalSize > 1 ) {
|
||
Value = (PWSTR)ScepAlloc( 0, (TotalSize+1)*sizeof(WCHAR));
|
||
if ( Value == NULL )
|
||
rc = SCESTATUS_NOT_ENOUGH_RESOURCE;
|
||
}
|
||
}
|
||
|
||
if ( SCESTATUS_SUCCESS == rc ) {
|
||
|
||
if ( TotalSize > 1 ) {
|
||
|
||
pTemp = Value;
|
||
|
||
if ( dwWriteOption & SCE_WRITE_CONVERT ) {
|
||
|
||
for (j=0; j<i; j++) {
|
||
if ( pa[j].Name ) {
|
||
|
||
if ( Status == 3 ) {
|
||
ScepLogOutput2(2, 0, pa[j].Name);
|
||
}
|
||
|
||
wcsncpy(pTemp, pa[j].Name, pa[j].Len);
|
||
pTemp += pa[j].Len;
|
||
*pTemp = L'\0';
|
||
pTemp++;
|
||
}
|
||
}
|
||
|
||
} else {
|
||
|
||
for ( pName=NameList; pName != NULL; pName = pName->Next ) {
|
||
|
||
if ( pName->Name == NULL ) {
|
||
continue;
|
||
}
|
||
if ( Status == 3 ) {
|
||
ScepLogOutput2(2, 0, pName->Name);
|
||
}
|
||
|
||
Len = wcslen(pName->Name);
|
||
wcsncpy(pTemp, pName->Name, Len);
|
||
pTemp += Len;
|
||
*pTemp = L'\0';
|
||
pTemp++;
|
||
}
|
||
}
|
||
|
||
*pTemp = L'\0';
|
||
|
||
} else
|
||
TotalSize = 0;
|
||
|
||
if ( TotalSize > 0 || (dwWriteOption & SCE_WRITE_EMPTY_LIST) ) {
|
||
rc = SceJetSetLine(
|
||
hSection,
|
||
Name,
|
||
FALSE,
|
||
Value,
|
||
TotalSize*sizeof(WCHAR),
|
||
0
|
||
);
|
||
|
||
switch ( Status ) {
|
||
case 1:
|
||
ScepLogOutput3(2, 0, SCEDLL_STATUS_MISMATCH, Name);
|
||
break;
|
||
case 3: // no analyze, already printed
|
||
break;
|
||
|
||
case 2:
|
||
ScepLogOutput3(2, 0, SCEDLL_STATUS_NC, Name);
|
||
break;
|
||
}
|
||
|
||
#ifdef SCE_DBG
|
||
if ( Value != NULL )
|
||
wprintf(L"rc=%d, Section: %d, %s=%s\n", rc, (DWORD)(hSection->SectionID), Name, Value);
|
||
else
|
||
wprintf(L"rc=%d, Section: %d, %s=", rc, (DWORD)(hSection->SectionID), Name);
|
||
#endif
|
||
}
|
||
|
||
if ( Value != NULL )
|
||
ScepFree(Value);
|
||
}
|
||
|
||
if ( pa ) {
|
||
|
||
for ( j=0; j<i; j++ ) {
|
||
if ( pa[j].Name && pa[j].bFree ) {
|
||
ScepFree(pa[j].Name);
|
||
}
|
||
}
|
||
ScepFree(pa);
|
||
}
|
||
|
||
return(rc);
|
||
}
|
||
|
||
|
||
SCESTATUS
|
||
ScepWriteNameStatusListValue(
|
||
IN PSCESECTION hSection,
|
||
IN PWSTR Name,
|
||
IN PSCE_NAME_STATUS_LIST NameList,
|
||
IN BOOL SaveEmptyList,
|
||
IN INT Status
|
||
)
|
||
/* ++
|
||
Routine Description:
|
||
|
||
This routine writes a key with a list of values to the JET section. The list
|
||
of values is saved in a MULTI-SZ format which is separated by a NULL char and
|
||
terminated by 2 NULLs. If the list is NULL, nothing is saved unless
|
||
SaveEmptyList is set to TRUE, where a NULL value is saved with the key.
|
||
|
||
The format in each string in the MULTI-SZ value is a 2 bytes Status field
|
||
followed by the Name field. This structure is primarily used for privileges
|
||
|
||
Arguments:
|
||
|
||
hSection - the JET hsection handle
|
||
|
||
Name - The key name
|
||
|
||
NameList - the list of values
|
||
|
||
SaveEmptyList - TRUE = save NULL value if the list is empty
|
||
FALSE = DO NOT save if the list is empty
|
||
|
||
Return Value:
|
||
|
||
SCESTATUS_SUCCESS
|
||
SCESTATUS_NOT_ENOUGH_RESOURCE
|
||
|
||
SCESTATUS returned from SceJetSetLine
|
||
|
||
-- */
|
||
{
|
||
SCESTATUS rc=SCESTATUS_SUCCESS;
|
||
DWORD TotalSize=0;
|
||
PWSTR Value=NULL;
|
||
PSCE_NAME_STATUS_LIST pName;
|
||
PWSTR pTemp=NULL;
|
||
DWORD Len;
|
||
|
||
|
||
for ( pName=NameList; pName != NULL; pName = pName->Next ) {
|
||
//
|
||
// Privilege value is stored in 2 bytes
|
||
//
|
||
TotalSize += 2;
|
||
if ( pName->Name != NULL)
|
||
TotalSize += wcslen(pName->Name);
|
||
TotalSize ++;
|
||
}
|
||
TotalSize ++;
|
||
|
||
if ( TotalSize > 1 ) {
|
||
Value = (PWSTR)ScepAlloc( 0, (TotalSize+1)*sizeof(WCHAR));
|
||
if ( Value == NULL )
|
||
return(SCESTATUS_NOT_ENOUGH_RESOURCE);
|
||
|
||
pTemp = Value;
|
||
for ( pName=NameList; pName != NULL; pName = pName->Next ) {
|
||
swprintf(pTemp, L"%02d", pName->Status);
|
||
pTemp += 2;
|
||
if ( pName->Name != NULL ) {
|
||
Len = wcslen(pName->Name);
|
||
wcsncpy(pTemp, pName->Name, Len);
|
||
pTemp += Len;
|
||
}
|
||
*pTemp = L'\0';
|
||
pTemp++;
|
||
}
|
||
*pTemp = L'\0';
|
||
|
||
} else
|
||
TotalSize = 0;
|
||
|
||
if ( TotalSize > 0 || SaveEmptyList ) {
|
||
rc = SceJetSetLine(
|
||
hSection,
|
||
Name,
|
||
FALSE,
|
||
Value,
|
||
TotalSize*sizeof(WCHAR),
|
||
0
|
||
);
|
||
|
||
if ( Status == 1 )
|
||
ScepLogOutput3(2, 0, SCEDLL_STATUS_MISMATCH, Name);
|
||
else if ( Status == 2 ) {
|
||
ScepLogOutput3(2, 0, SCEDLL_STATUS_NC, Name);
|
||
}
|
||
|
||
#ifdef SCE_DBG
|
||
wprintf(L"rc=%d, Section: %d, %s=%s\n", rc, (DWORD)(hSection->SectionID), Name, Value);
|
||
#endif
|
||
if ( Value != NULL )
|
||
ScepFree(Value);
|
||
}
|
||
|
||
return(rc);
|
||
}
|
||
|
||
|
||
SCESTATUS
|
||
ScepWriteSecurityDescriptorValue(
|
||
IN PSCESECTION hSection,
|
||
IN PWSTR Name,
|
||
IN PSECURITY_DESCRIPTOR pSD,
|
||
IN SECURITY_INFORMATION SeInfo
|
||
)
|
||
/* ++
|
||
Routine Description:
|
||
|
||
This routine writes a key with security descriptor value to the JET section.
|
||
The security descriptor is converted into text format based on the secrurity
|
||
information passed in.
|
||
|
||
Arguments:
|
||
|
||
hSection - the JET hsection handle
|
||
|
||
Name - The key name
|
||
|
||
pSD - The security descriptor
|
||
|
||
SeInfo - the part of the security information to save
|
||
|
||
Return Value:
|
||
|
||
SCESTATUS_SUCCESS
|
||
SCESTATUS_NOT_ENOUGH_RESOURCE
|
||
|
||
SCESTATUS returned from SceJetSetLine
|
||
|
||
-- */
|
||
{
|
||
SCESTATUS rc=SCESTATUS_SUCCESS;
|
||
PWSTR SDspec=NULL;
|
||
ULONG SDsize = 0;
|
||
|
||
|
||
if ( hSection == NULL || Name == NULL ) {
|
||
return(SCESTATUS_INVALID_PARAMETER);
|
||
}
|
||
|
||
if ( pSD != NULL && SeInfo != 0 ) {
|
||
|
||
rc = ConvertSecurityDescriptorToText (
|
||
pSD,
|
||
SeInfo,
|
||
&SDspec,
|
||
&SDsize
|
||
);
|
||
if ( rc == NO_ERROR ) {
|
||
rc = ScepCompareAndSaveStringValue(
|
||
hSection,
|
||
Name,
|
||
NULL,
|
||
SDspec,
|
||
SDsize*sizeof(WCHAR)
|
||
);
|
||
ScepFree(SDspec);
|
||
}
|
||
}
|
||
#ifdef SCE_DBG
|
||
wprintf(L"SD==>rc=%d, Section: %d, %s\n", rc, (DWORD)(hSection->SectionID), Name);
|
||
#endif
|
||
return(rc);
|
||
}
|
||
|
||
|
||
SCESTATUS
|
||
ScepDuplicateTable(
|
||
IN PSCECONTEXT hProfile,
|
||
IN SCEJET_TABLE_TYPE TableType,
|
||
IN LPSTR DupTableName,
|
||
OUT PSCE_ERROR_LOG_INFO *pErrlog
|
||
)
|
||
/* ++
|
||
Routine Description:
|
||
|
||
This routine copies table structure and data from a SCP/SMP/SAP table to
|
||
a table specified by DupTableName. This is used for the SAP table backup.
|
||
|
||
Arguments:
|
||
|
||
hProfile - the JET database handle
|
||
|
||
TableType - the table type -SCEJET_TABLE_SCP
|
||
SCEJET_TABLE_SAP
|
||
SCEJET_TABLE_SMP
|
||
|
||
DupTableName - The new table's name
|
||
|
||
pErrlog - the error list
|
||
|
||
Return Value:
|
||
|
||
SCESTATUS_SUCCESS
|
||
|
||
-- */
|
||
{
|
||
JET_ERR JetErr;
|
||
SCESTATUS rc;
|
||
|
||
SCECONTEXT hProfile2;
|
||
PSCESECTION hSection1=NULL;
|
||
PSCESECTION hSection2=NULL;
|
||
|
||
DOUBLE SectionID=0, SaveID=0;
|
||
DWORD Actual;
|
||
|
||
PWSTR KeyName=NULL;
|
||
PWSTR Value=NULL;
|
||
DWORD KeyLen=0;
|
||
DWORD ValueLen=0;
|
||
|
||
|
||
if ( hProfile == NULL ) {
|
||
return(SCESTATUS_INVALID_PARAMETER);
|
||
}
|
||
|
||
//
|
||
// Create a SCP section handle. the section ID is a dummy one
|
||
//
|
||
rc = SceJetOpenSection(
|
||
hProfile,
|
||
(DOUBLE)1,
|
||
TableType,
|
||
&hSection1
|
||
);
|
||
|
||
if ( rc != SCESTATUS_SUCCESS ) {
|
||
ScepBuildErrorLogInfo( ScepSceStatusToDosError(rc), pErrlog,
|
||
SCEERR_OPEN, L"SectionID 1");
|
||
return(rc);
|
||
}
|
||
|
||
memset(&hProfile2, '\0', sizeof(SCECONTEXT));
|
||
|
||
hProfile2.JetSessionID = hProfile->JetSessionID;
|
||
hProfile2.JetDbID = hProfile->JetDbID;
|
||
|
||
//
|
||
// Delete the dup table then create it
|
||
//
|
||
SceJetDeleteTable(
|
||
&hProfile2,
|
||
DupTableName,
|
||
TableType
|
||
);
|
||
rc = SceJetCreateTable(
|
||
&hProfile2,
|
||
DupTableName,
|
||
TableType,
|
||
SCEJET_CREATE_IN_BUFFER,
|
||
NULL,
|
||
NULL
|
||
);
|
||
if ( rc != SCESTATUS_SUCCESS ) {
|
||
ScepBuildErrorLogInfo( ScepSceStatusToDosError(rc), pErrlog,
|
||
SCEERR_CREATE, L"backup table");
|
||
goto Cleanup;
|
||
}
|
||
//
|
||
// Move to the first line of the SCP table
|
||
//
|
||
JetErr = JetMove(hSection1->JetSessionID, hSection1->JetTableID, JET_MoveFirst, 0);
|
||
|
||
while (JetErr == SCESTATUS_SUCCESS ) {
|
||
|
||
//
|
||
// get section ID
|
||
//
|
||
JetErr = JetRetrieveColumn(
|
||
hSection1->JetSessionID,
|
||
hSection1->JetTableID,
|
||
hSection1->JetColumnSectionID,
|
||
(void *)&SectionID,
|
||
8,
|
||
&Actual,
|
||
0,
|
||
NULL
|
||
);
|
||
|
||
if ( JetErr != JET_errSuccess ) {
|
||
ScepBuildErrorLogInfo( ERROR_READ_FAULT, pErrlog,
|
||
SCEERR_QUERY_INFO,
|
||
L"sectionID");
|
||
rc = SceJetJetErrorToSceStatus(JetErr);
|
||
break;
|
||
}
|
||
#ifdef SCE_DBG
|
||
printf("SectionID=%d, JetErr=%d\n", (DWORD)SectionID, JetErr);
|
||
#endif
|
||
//
|
||
// Prepare this Scep section
|
||
//
|
||
if ( SectionID != SaveID ) {
|
||
SaveID = SectionID;
|
||
//
|
||
// Prepare this section
|
||
//
|
||
rc = SceJetOpenSection(
|
||
&hProfile2,
|
||
SectionID,
|
||
TableType,
|
||
&hSection2
|
||
);
|
||
if ( rc != SCESTATUS_SUCCESS ) {
|
||
ScepBuildErrorLogInfo( ScepSceStatusToDosError(rc), pErrlog,
|
||
SCEERR_OPEN_ID,
|
||
(DWORD)SectionID);
|
||
break;
|
||
}
|
||
}
|
||
|
||
//
|
||
// get buffer size for key and value
|
||
//
|
||
rc = SceJetGetValue(
|
||
hSection1,
|
||
SCEJET_CURRENT,
|
||
NULL,
|
||
NULL,
|
||
0,
|
||
&KeyLen,
|
||
NULL,
|
||
0,
|
||
&ValueLen);
|
||
|
||
if ( rc != SCESTATUS_SUCCESS ) {
|
||
ScepBuildErrorLogInfo(ScepSceStatusToDosError(rc), pErrlog,
|
||
SCEERR_QUERY_VALUE, L"current row");
|
||
break;
|
||
}
|
||
|
||
//
|
||
// allocate memory
|
||
//
|
||
if ( KeyLen > 0 ) {
|
||
KeyName = (PWSTR)ScepAlloc( LMEM_ZEROINIT, KeyLen+2);
|
||
if ( KeyName == NULL ) {
|
||
rc = SCESTATUS_NOT_ENOUGH_RESOURCE;
|
||
break;
|
||
}
|
||
}
|
||
if ( ValueLen > 0 ) {
|
||
Value = (PWSTR)ScepAlloc( LMEM_ZEROINIT, ValueLen+2);
|
||
if ( Value == NULL ) {
|
||
rc = SCESTATUS_NOT_ENOUGH_RESOURCE;
|
||
break;
|
||
}
|
||
}
|
||
//
|
||
// get key and value
|
||
//
|
||
rc = SceJetGetValue(
|
||
hSection1,
|
||
SCEJET_CURRENT,
|
||
NULL,
|
||
KeyName,
|
||
KeyLen,
|
||
&KeyLen,
|
||
Value,
|
||
ValueLen,
|
||
&ValueLen);
|
||
|
||
if ( rc != SCESTATUS_SUCCESS ) {
|
||
ScepBuildErrorLogInfo(ScepSceStatusToDosError(rc), pErrlog,
|
||
SCEERR_QUERY_VALUE,
|
||
L"current row");
|
||
break;
|
||
}
|
||
#ifdef SCE_DBG
|
||
wprintf(L"\t%s=%s, rc=%d\n", KeyName, Value, rc);
|
||
#endif
|
||
//
|
||
// set this line to the dup table
|
||
//
|
||
rc = SceJetSetLine(
|
||
hSection2,
|
||
KeyName,
|
||
TRUE,
|
||
Value,
|
||
ValueLen,
|
||
0
|
||
);
|
||
if ( rc != SCESTATUS_SUCCESS ) {
|
||
ScepBuildErrorLogInfo(ScepSceStatusToDosError(rc), pErrlog,
|
||
SCEERR_WRITE_INFO,
|
||
KeyName);
|
||
break;
|
||
}
|
||
ScepFree(KeyName);
|
||
KeyName = NULL;
|
||
|
||
ScepFree(Value);
|
||
Value = NULL;
|
||
|
||
//
|
||
// Move to next line in the SCP table
|
||
//
|
||
JetErr = JetMove(hSection1->JetSessionID, hSection1->JetTableID, JET_MoveNext, 0);
|
||
|
||
}
|
||
|
||
Cleanup:
|
||
if ( rc != SCESTATUS_SUCCESS ) {
|
||
//
|
||
// error occurs. Clean up the dup table
|
||
//
|
||
#ifdef SCE_DBG
|
||
printf("Error occurs. delete the dup table.\n");
|
||
#endif
|
||
SceJetDeleteTable(
|
||
&hProfile2,
|
||
DupTableName,
|
||
TableType
|
||
);
|
||
}
|
||
|
||
if ( KeyName != NULL )
|
||
ScepFree(KeyName);
|
||
|
||
if ( Value != NULL )
|
||
ScepFree(Value);
|
||
|
||
SceJetCloseSection(&hSection1, TRUE);
|
||
SceJetCloseSection(&hSection2, TRUE);
|
||
|
||
return(rc);
|
||
|
||
}
|
||
|
||
|
||
SCESTATUS
|
||
ScepAddToPrivList(
|
||
IN PSCE_NAME_STATUS_LIST *pPrivList,
|
||
IN DWORD Rights,
|
||
IN PWSTR Name,
|
||
IN DWORD Len
|
||
)
|
||
/* ++
|
||
Routine Description:
|
||
|
||
This routine adds a privilege with optional group name to the list of
|
||
privilege assignments
|
||
|
||
Arguments:
|
||
|
||
pPrivList - the privilege list to add to. The structure of this list is
|
||
Status -- The privilege value
|
||
Name -- The group's name where the priv is assigned
|
||
if Name is NULL, the privilege is directly assigned
|
||
|
||
Rights - The privilege(s) assigned through group Name
|
||
|
||
Name - The group's name
|
||
|
||
Len - The group's name length
|
||
|
||
Return Value:
|
||
|
||
SCESTATUS_SUCCESS
|
||
SCESTATUS_INVALID_PARAMETER
|
||
SCESTATUS_NOT_ENOUGH_RESOURCE
|
||
|
||
-- */
|
||
{
|
||
PSCE_NAME_STATUS_LIST pTemp;
|
||
LONG i;
|
||
|
||
|
||
if ( pPrivList == NULL ) {
|
||
return(SCESTATUS_INVALID_PARAMETER);
|
||
}
|
||
|
||
for ( i=31; i>=0; i-- )
|
||
if ( Rights & (1 << i) ) {
|
||
for ( pTemp=*pPrivList; pTemp != NULL; pTemp = pTemp->Next ) {
|
||
if ( (DWORD)i == pTemp->Status )
|
||
break;
|
||
|
||
}
|
||
if ( pTemp == NULL ) {
|
||
//
|
||
// add this one
|
||
//
|
||
pTemp = (PSCE_NAME_STATUS_LIST)ScepAlloc( LMEM_ZEROINIT, sizeof(SCE_NAME_STATUS_LIST));
|
||
if ( pTemp == NULL )
|
||
return(SCESTATUS_NOT_ENOUGH_RESOURCE);
|
||
|
||
if ( Name != NULL && Len > 0 ) {
|
||
pTemp->Name = (PWSTR)ScepAlloc( LMEM_ZEROINIT, (Len+1)*sizeof(WCHAR));
|
||
if ( pTemp->Name == NULL) {
|
||
ScepFree(pTemp);
|
||
return(SCESTATUS_NOT_ENOUGH_RESOURCE);
|
||
}
|
||
wcsncpy(pTemp->Name, Name, Len);
|
||
}
|
||
#ifdef SCE_DBG
|
||
wprintf(L"Add %d %s to privilege list\n", i, pTemp->Name);
|
||
#endif
|
||
|
||
pTemp->Status = i;
|
||
|
||
pTemp->Next = *pPrivList;
|
||
*pPrivList = pTemp;
|
||
pTemp = NULL;
|
||
}
|
||
}
|
||
|
||
return(SCESTATUS_SUCCESS);
|
||
}
|
||
|
||
|
||
SCESTATUS
|
||
ScepOpenPrevPolicyContext(
|
||
IN PSCECONTEXT hProfile,
|
||
OUT PSCECONTEXT *phPrevProfile
|
||
)
|
||
{
|
||
|
||
if ( hProfile == NULL || phPrevProfile == NULL ) {
|
||
return(SCESTATUS_INVALID_PARAMETER);
|
||
}
|
||
|
||
|
||
*phPrevProfile = (PSCECONTEXT)LocalAlloc( LMEM_ZEROINIT, sizeof(SCECONTEXT));
|
||
if ( *phPrevProfile == NULL ) {
|
||
return(SCESTATUS_NOT_ENOUGH_RESOURCE);
|
||
}
|
||
|
||
memcpy( *phPrevProfile, hProfile, sizeof(SCECONTEXT));
|
||
|
||
DWORD ScpType = hProfile->Type;
|
||
(*phPrevProfile)->Type &= ~(SCEJET_MERGE_TABLE_2 | SCEJET_MERGE_TABLE_1);
|
||
|
||
SCESTATUS rc;
|
||
//
|
||
// now open the previous policy table
|
||
//
|
||
if ( ( ScpType & SCEJET_MERGE_TABLE_2 ) ) {
|
||
//
|
||
// the second table is the current one
|
||
// so the first table is the previous one
|
||
//
|
||
rc = SceJetOpenTable(
|
||
*phPrevProfile,
|
||
"SmTblScp",
|
||
SCEJET_TABLE_SCP,
|
||
SCEJET_OPEN_READ_ONLY,
|
||
NULL
|
||
);
|
||
(*phPrevProfile)->Type |= SCEJET_MERGE_TABLE_1;
|
||
|
||
} else {
|
||
rc = SceJetOpenTable(
|
||
*phPrevProfile,
|
||
"SmTblScp2",
|
||
SCEJET_TABLE_SCP,
|
||
SCEJET_OPEN_READ_ONLY,
|
||
NULL
|
||
);
|
||
(*phPrevProfile)->Type |= SCEJET_MERGE_TABLE_2;
|
||
}
|
||
/*
|
||
if ( SCESTATUS_SUCCESS == rc ) {
|
||
|
||
JET_COLUMNID ColGpoID = (JET_COLUMNID)JET_tableidNil;
|
||
JET_ERR JetErr;
|
||
JET_COLUMNDEF ColumnGpoIDDef;
|
||
|
||
JetErr = JetGetTableColumnInfo(
|
||
(*phPrevProfile)->JetSessionID,
|
||
(*phPrevProfile)->JetScpID,
|
||
"GpoID",
|
||
(VOID *)&ColumnGpoIDDef,
|
||
sizeof(JET_COLUMNDEF),
|
||
JET_ColInfo
|
||
);
|
||
if ( JET_errSuccess == JetErr ) {
|
||
ColGpoID = ColumnGpoIDDef.columnid;
|
||
|
||
} // else ignore error
|
||
|
||
// temp storage for the column ID
|
||
(*phPrevProfile)->JetSapValueID = ColGpoID;
|
||
|
||
}
|
||
*/
|
||
if ( rc != SCESTATUS_SUCCESS ) {
|
||
|
||
LocalFree(*phPrevProfile);
|
||
*phPrevProfile = NULL;
|
||
}
|
||
|
||
return(rc);
|
||
}
|
||
|
||
SCESTATUS
|
||
ScepClosePrevPolicyContext(
|
||
IN OUT PSCECONTEXT *phProfile
|
||
)
|
||
{
|
||
if ( phProfile && *phProfile ) {
|
||
|
||
//
|
||
// just free the table because all other info are copied from the
|
||
// current policy context and will be freed there
|
||
//
|
||
|
||
if ( (*phProfile)->JetScpID != JET_tableidNil ) {
|
||
|
||
if ( (*phProfile)->JetScpID != (*phProfile)->JetSmpID ) {
|
||
JetCloseTable(
|
||
(*phProfile)->JetSessionID,
|
||
(*phProfile)->JetScpID
|
||
);
|
||
}
|
||
}
|
||
|
||
LocalFree(*phProfile);
|
||
*phProfile = NULL;
|
||
}
|
||
|
||
return(SCESTATUS_SUCCESS);
|
||
}
|
||
|
||
|
||
SCESTATUS
|
||
ScepCopyLocalToMergeTable(
|
||
IN PSCECONTEXT hProfile,
|
||
IN DWORD Options,
|
||
IN DWORD CopyOptions,
|
||
OUT PSCE_ERROR_LOG_INFO *pErrlog
|
||
)
|
||
/* ++
|
||
Routine Description:
|
||
|
||
This routine populate data from SCP table into SMP table. All data except
|
||
those in the account profiles section(s) in SCP table will be copied over
|
||
to SMP table. Account profiles section is converted into User List section
|
||
format.
|
||
|
||
Arguments:
|
||
|
||
hProfile - the JET database handle
|
||
|
||
Return Value:
|
||
|
||
SCESTATUS_SUCCESS
|
||
|
||
-- */
|
||
{
|
||
JET_ERR JetErr;
|
||
SCESTATUS rc;
|
||
|
||
PSCESECTION hSectionScp=NULL;
|
||
PSCESECTION hSectionSmp=NULL;
|
||
PSCESECTION hSectionPrevScp=NULL;
|
||
PSCECONTEXT hPrevProfile=NULL;
|
||
DOUBLE SectionID=0, SavedID=0;
|
||
DWORD Actual;
|
||
BOOL bCopyIt=FALSE;
|
||
BOOL bCopyThisLine;
|
||
BOOL bConvert=FALSE; // to convert privilege accounts
|
||
|
||
PWSTR KeyName=NULL;
|
||
PWSTR Value=NULL;
|
||
DWORD KeyLen=0;
|
||
DWORD ValueLen=0;
|
||
|
||
WCHAR SectionName[256];
|
||
|
||
if ( hProfile == NULL ) {
|
||
return(SCESTATUS_INVALID_PARAMETER);
|
||
}
|
||
|
||
if ( hProfile->JetScpID == hProfile->JetSmpID ) {
|
||
// if it's the same table, return - shouldn't happen
|
||
return(SCESTATUS_SUCCESS);
|
||
}
|
||
|
||
if ( hProfile->JetSapID == JET_tableidNil ) {
|
||
// tattoo table doesn't exist, return - shouldn't happen
|
||
return(SCESTATUS_SUCCESS);
|
||
}
|
||
|
||
//
|
||
// get previous policy propagation info (if any)
|
||
//
|
||
|
||
if ( !(CopyOptions & SCE_LOCAL_POLICY_MIGRATE) ) {
|
||
rc = ScepOpenPrevPolicyContext(hProfile, &hPrevProfile);
|
||
if ( SCESTATUS_RECORD_NOT_FOUND == rc ||
|
||
SCESTATUS_PROFILE_NOT_FOUND == rc ) {
|
||
//
|
||
// the table doesn't exist - no previous policy prop
|
||
// do not need to copy anything, just quit
|
||
//
|
||
return(SCESTATUS_SUCCESS);
|
||
}
|
||
}
|
||
|
||
//
|
||
// Create a SMP section handle. the section ID is a dummy one
|
||
//
|
||
rc = SceJetOpenSection(
|
||
hProfile,
|
||
(DOUBLE)1,
|
||
(CopyOptions & SCE_LOCAL_POLICY_MIGRATE) ? SCEJET_TABLE_SMP : SCEJET_TABLE_TATTOO,
|
||
&hSectionSmp
|
||
);
|
||
|
||
if ( rc != SCESTATUS_SUCCESS ) {
|
||
ScepBuildErrorLogInfo( ScepSceStatusToDosError(rc), pErrlog,
|
||
SCEERR_OPEN,
|
||
(CopyOptions & SCE_LOCAL_POLICY_MIGRATE) ? L"SMP" : L"TATTOO");
|
||
|
||
if (hPrevProfile) ScepClosePrevPolicyContext(&hPrevProfile);
|
||
|
||
return(rc);
|
||
}
|
||
|
||
LSA_HANDLE LsaPolicy=NULL;
|
||
PWSTR pszNewValue=NULL;
|
||
DWORD NewLen=0;
|
||
|
||
//
|
||
// Move to the first line of the SCP table
|
||
//
|
||
JetErr = JetMove(hSectionSmp->JetSessionID, hSectionSmp->JetTableID, JET_MoveFirst, 0);
|
||
|
||
while (JetErr == SCESTATUS_SUCCESS ) {
|
||
//
|
||
// get section ID
|
||
//
|
||
JetErr = JetRetrieveColumn(
|
||
hSectionSmp->JetSessionID,
|
||
hSectionSmp->JetTableID,
|
||
hSectionSmp->JetColumnSectionID,
|
||
(void *)&SectionID,
|
||
8,
|
||
&Actual,
|
||
0,
|
||
NULL
|
||
);
|
||
|
||
if ( JetErr != JET_errSuccess ) {
|
||
ScepBuildErrorLogInfo( ERROR_READ_FAULT, pErrlog,
|
||
SCEERR_QUERY_INFO, L"sectionID");
|
||
rc = SceJetJetErrorToSceStatus(JetErr);
|
||
break;
|
||
}
|
||
#ifdef SCE_DBG
|
||
printf("SectionID=%d, JetErr=%d\n", (DWORD)SectionID, JetErr);
|
||
#endif
|
||
if ( SectionID != SavedID ) {
|
||
//
|
||
// a new section. Look for the section's name to see if this section
|
||
// is to be converted
|
||
//
|
||
SavedID = SectionID;
|
||
|
||
Actual = 510;
|
||
|
||
memset(SectionName, '\0', 512);
|
||
rc = SceJetGetSectionNameByID(
|
||
hProfile,
|
||
SectionID,
|
||
SectionName,
|
||
&Actual
|
||
);
|
||
if ( rc != SCESTATUS_SUCCESS ) {
|
||
ScepBuildErrorLogInfo( ERROR_BAD_FORMAT, pErrlog,
|
||
SCEERR_CANT_FIND_SECTION,
|
||
(DWORD)SectionID
|
||
);
|
||
break;
|
||
}
|
||
if ( Actual > 0 )
|
||
SectionName[Actual/sizeof(TCHAR)] = L'\0';
|
||
#ifdef SCE_DBG
|
||
wprintf(L"SectionName=%s\n", SectionName);
|
||
#endif
|
||
//
|
||
// Compare section name with domain sections to convert
|
||
//
|
||
|
||
bCopyIt = TRUE;
|
||
bConvert = FALSE;
|
||
|
||
if ( (CopyOptions & SCE_LOCAL_POLICY_DC) ) {
|
||
|
||
//
|
||
// do not copy user rights if it's on a domain controller
|
||
//
|
||
if ( _wcsicmp(szPrivilegeRights, SectionName) == 0 ||
|
||
_wcsicmp(szSystemAccess, SectionName) == 0 ||
|
||
_wcsicmp(szKerberosPolicy, SectionName) == 0 ||
|
||
_wcsicmp(szAuditEvent, SectionName) == 0 ||
|
||
_wcsicmp(szGroupMembership, SectionName) == 0 ) {
|
||
bCopyIt = FALSE;
|
||
|
||
} else if ( (CopyOptions & SCE_LOCAL_POLICY_MIGRATE) ) {
|
||
//
|
||
// migrate registry values only
|
||
//
|
||
if ( _wcsicmp(szRegistryValues, SectionName) != 0 )
|
||
bCopyIt = FALSE;
|
||
}
|
||
|
||
} else if ( (CopyOptions & SCE_LOCAL_POLICY_MIGRATE) ) {
|
||
|
||
//
|
||
// non DCs, should migrate all local policies
|
||
//
|
||
if ( _wcsicmp(szPrivilegeRights, SectionName) == 0 ) {
|
||
bConvert = TRUE;
|
||
} else if ( (_wcsicmp(szSystemAccess, SectionName) != 0) &&
|
||
(_wcsicmp(szKerberosPolicy, SectionName) != 0) &&
|
||
(_wcsicmp(szRegistryValues, SectionName) != 0) &&
|
||
(_wcsicmp(szAuditEvent, SectionName) != 0) ) {
|
||
bCopyIt = FALSE;
|
||
}
|
||
}
|
||
|
||
/*
|
||
if ( ( Options & SCE_NOCOPY_DOMAIN_POLICY) &&
|
||
( (_wcsicmp(szSystemAccess, SectionName) == 0) ||
|
||
(_wcsicmp(szKerberosPolicy, SectionName) == 0) ) ) {
|
||
|
||
bCopyIt = FALSE;
|
||
|
||
} else if ( (_wcsicmp(szGroupMembership, SectionName) == 0) ||
|
||
(_wcsicmp(szRegistryKeys, SectionName) == 0) ||
|
||
(_wcsicmp(szFileSecurity, SectionName) == 0) ||
|
||
(_wcsicmp(szServiceGeneral, SectionName) == 0) ||
|
||
(_wcsicmp(szAuditApplicationLog, SectionName) == 0) ||
|
||
(_wcsicmp(szAuditSecurityLog, SectionName) == 0) ||
|
||
(_wcsicmp(szAuditSystemLog, SectionName) == 0) ||
|
||
(_wcsicmp(szAttachments, SectionName) == 0) ||
|
||
(_wcsicmp(szDSSecurity, SectionName) == 0)
|
||
) {
|
||
// do not copy areas other than account policy and local policy
|
||
bCopyIt = FALSE;
|
||
|
||
} else {
|
||
|
||
bCopyIt = TRUE;
|
||
*/
|
||
if ( bCopyIt ) {
|
||
//
|
||
// Prepare this Scep section
|
||
//
|
||
rc = SceJetOpenSection(
|
||
hProfile,
|
||
SectionID,
|
||
(CopyOptions & SCE_LOCAL_POLICY_MIGRATE) ? SCEJET_TABLE_TATTOO : SCEJET_TABLE_SCP,
|
||
&hSectionScp
|
||
);
|
||
if ( rc != SCESTATUS_SUCCESS ) {
|
||
ScepBuildErrorLogInfo( ScepSceStatusToDosError(rc), pErrlog,
|
||
SCEERR_OPEN_ID,
|
||
(DWORD)SectionID);
|
||
break;
|
||
}
|
||
|
||
if ( (CopyOptions & SCE_LOCAL_POLICY_MIGRATE) ) {
|
||
//
|
||
// open current policy propagation table
|
||
// do not care error here
|
||
//
|
||
SceJetOpenSection(
|
||
hProfile,
|
||
SectionID,
|
||
SCEJET_TABLE_SCP,
|
||
&hSectionPrevScp
|
||
);
|
||
/* // should always copy tattoo value to the merged table
|
||
// even if the setting doesn't exist in previous policy prop
|
||
// this is to handle the dependent settings such as
|
||
// retention perild and retention days
|
||
} else if ( hPrevProfile ) {
|
||
//
|
||
// open previous policy propagation table
|
||
// do not care error here
|
||
//
|
||
|
||
SceJetOpenSection(
|
||
hPrevProfile,
|
||
SectionID,
|
||
SCEJET_TABLE_SCP,
|
||
&hSectionPrevScp
|
||
);
|
||
*/
|
||
}
|
||
}
|
||
|
||
}
|
||
|
||
if ( bCopyIt ) {
|
||
//
|
||
// get buffer size for key and value
|
||
//
|
||
rc = SceJetGetValue(
|
||
hSectionSmp,
|
||
SCEJET_CURRENT,
|
||
NULL,
|
||
NULL,
|
||
0,
|
||
&KeyLen,
|
||
NULL,
|
||
0,
|
||
&ValueLen);
|
||
|
||
if ( rc != SCESTATUS_SUCCESS ) {
|
||
ScepBuildErrorLogInfo(ScepSceStatusToDosError(rc), pErrlog,
|
||
SCEERR_QUERY_VALUE, L"current row");
|
||
break;
|
||
}
|
||
|
||
//
|
||
// allocate memory
|
||
//
|
||
if ( KeyLen > 0 ) {
|
||
KeyName = (PWSTR)ScepAlloc( LMEM_ZEROINIT, KeyLen+2);
|
||
if ( KeyName == NULL ) {
|
||
rc = SCESTATUS_NOT_ENOUGH_RESOURCE;
|
||
break;
|
||
}
|
||
}
|
||
if ( ValueLen > 0 ) {
|
||
Value = (PWSTR)ScepAlloc( LMEM_ZEROINIT, ValueLen+2);
|
||
if ( Value == NULL ) {
|
||
rc = SCESTATUS_NOT_ENOUGH_RESOURCE;
|
||
break;
|
||
}
|
||
}
|
||
//
|
||
// get key and value
|
||
//
|
||
rc = SceJetGetValue(
|
||
hSectionSmp,
|
||
SCEJET_CURRENT,
|
||
NULL,
|
||
KeyName,
|
||
KeyLen,
|
||
&KeyLen,
|
||
Value,
|
||
ValueLen,
|
||
&ValueLen);
|
||
|
||
if ( rc != SCESTATUS_SUCCESS ) {
|
||
ScepBuildErrorLogInfo(ScepSceStatusToDosError(rc), pErrlog,
|
||
SCEERR_QUERY_VALUE, L"current row");
|
||
break;
|
||
}
|
||
#ifdef SCE_DBG
|
||
wprintf(L"\t%s=%s, rc=%d\n", KeyName, Value, rc);
|
||
#endif
|
||
bCopyThisLine = TRUE;
|
||
|
||
//
|
||
// check if this key exist in the previous prop
|
||
//
|
||
if ( hSectionPrevScp ) {
|
||
|
||
rc = SceJetSeek(
|
||
hSectionPrevScp,
|
||
KeyName,
|
||
KeyLen,
|
||
SCEJET_SEEK_EQ_NO_CASE
|
||
);
|
||
if ( SCESTATUS_RECORD_NOT_FOUND == rc ||
|
||
(hSectionPrevScp->JetColumnGpoID == 0) ) {
|
||
|
||
bCopyThisLine = FALSE;
|
||
|
||
} else if ( SCESTATUS_SUCCESS == rc && (CopyOptions & SCE_LOCAL_POLICY_MIGRATE) ) {
|
||
//
|
||
// found. Let's check if this setting was from a GPO
|
||
// if in migration (build tattoo), a setting was not
|
||
// defined in GPO doesn't need a tattoo value
|
||
//
|
||
// for policy prop case, there may be undo settings in
|
||
// previous policy prop and they weren't reset successfully
|
||
// in previous prop. In this case, we still want to continue
|
||
// reset these settings. So these settings should be copied
|
||
// from the tattoo table to this policy table regardless if
|
||
// there is a domain setting defined for it in the previous
|
||
// policy propagation.
|
||
//
|
||
LONG GpoID = 0;
|
||
ULONG Actual;
|
||
|
||
(void)JetRetrieveColumn(
|
||
hSectionPrevScp->JetSessionID,
|
||
hSectionPrevScp->JetTableID,
|
||
hSectionPrevScp->JetColumnGpoID,
|
||
(void *)&GpoID,
|
||
4,
|
||
&Actual,
|
||
0,
|
||
NULL
|
||
);
|
||
|
||
if ( GpoID == 0 ) {
|
||
//
|
||
// this is not a setting from a GPO
|
||
//
|
||
bCopyThisLine = FALSE;
|
||
}
|
||
}
|
||
rc = SCESTATUS_SUCCESS;
|
||
}
|
||
|
||
if ( bCopyThisLine ) {
|
||
|
||
if ( bConvert ) {
|
||
|
||
rc = ScepConvertFreeTextAccountToSid(
|
||
&LsaPolicy,
|
||
Value,
|
||
ValueLen/sizeof(WCHAR),
|
||
&pszNewValue,
|
||
&NewLen
|
||
);
|
||
|
||
if ( rc == SCESTATUS_SUCCESS &&
|
||
pszNewValue ) {
|
||
|
||
ScepFree(Value);
|
||
Value = pszNewValue;
|
||
ValueLen = NewLen*sizeof(WCHAR);
|
||
|
||
pszNewValue = NULL;
|
||
} // if failed to convert, just use the name format
|
||
}
|
||
|
||
//
|
||
// set this line to the SCP table
|
||
//
|
||
rc = SceJetSetLine(
|
||
hSectionScp,
|
||
KeyName,
|
||
TRUE,
|
||
Value,
|
||
ValueLen,
|
||
0
|
||
);
|
||
if ( rc != SCESTATUS_SUCCESS ) {
|
||
ScepBuildErrorLogInfo(ScepSceStatusToDosError(rc), pErrlog,
|
||
SCEERR_WRITE_INFO,
|
||
KeyName);
|
||
break;
|
||
}
|
||
}
|
||
|
||
ScepFree(KeyName);
|
||
KeyName = NULL;
|
||
|
||
ScepFree(Value);
|
||
Value = NULL;
|
||
|
||
}
|
||
//
|
||
// Move to next line in the SCP table
|
||
//
|
||
JetErr = JetMove(hSectionSmp->JetSessionID, hSectionSmp->JetTableID, JET_MoveNext, 0);
|
||
|
||
}
|
||
|
||
|
||
if ( KeyName != NULL )
|
||
ScepFree(KeyName);
|
||
|
||
if ( Value != NULL )
|
||
ScepFree(Value);
|
||
|
||
SceJetCloseSection(&hSectionScp, TRUE);
|
||
SceJetCloseSection(&hSectionSmp, TRUE);
|
||
if ( hSectionPrevScp ) {
|
||
SceJetCloseSection(&hSectionPrevScp, TRUE);
|
||
}
|
||
|
||
if (hPrevProfile)
|
||
ScepClosePrevPolicyContext(&hPrevProfile);
|
||
|
||
if ( LsaPolicy ) {
|
||
LsaClose(LsaPolicy);
|
||
}
|
||
|
||
return(rc);
|
||
|
||
}
|
||
|
||
|
||
SCESTATUS
|
||
ScepWriteObjectSecurity(
|
||
IN PSCECONTEXT hProfile,
|
||
IN SCETYPE ProfileType,
|
||
IN AREA_INFORMATION Area,
|
||
IN PSCE_OBJECT_SECURITY ObjSecurity
|
||
)
|
||
/*
|
||
Get security for a single object
|
||
*/
|
||
{
|
||
SCESTATUS rc;
|
||
PCWSTR SectionName=NULL;
|
||
PSCESECTION hSection=NULL;
|
||
DWORD SDsize, Win32Rc;
|
||
PWSTR SDspec=NULL;
|
||
|
||
if ( hProfile == NULL ||
|
||
ObjSecurity == NULL ||
|
||
ObjSecurity->Name == NULL ) {
|
||
|
||
return(SCESTATUS_INVALID_PARAMETER);
|
||
}
|
||
|
||
switch (Area) {
|
||
case AREA_REGISTRY_SECURITY:
|
||
SectionName = szRegistryKeys;
|
||
break;
|
||
case AREA_FILE_SECURITY:
|
||
SectionName = szFileSecurity;
|
||
break;
|
||
#if 0
|
||
case AREA_DS_OBJECTS:
|
||
SectionName = szDSSecurity;
|
||
break;
|
||
#endif
|
||
default:
|
||
return(SCESTATUS_INVALID_PARAMETER);
|
||
}
|
||
|
||
rc = ScepOpenSectionForName(
|
||
hProfile,
|
||
ProfileType,
|
||
SectionName,
|
||
&hSection
|
||
);
|
||
|
||
if ( rc == SCESTATUS_SUCCESS ) {
|
||
|
||
//
|
||
// convert security descriptor
|
||
//
|
||
Win32Rc = ConvertSecurityDescriptorToText (
|
||
ObjSecurity->pSecurityDescriptor,
|
||
ObjSecurity->SeInfo,
|
||
&SDspec,
|
||
&SDsize
|
||
);
|
||
|
||
if ( Win32Rc == NO_ERROR ) {
|
||
|
||
if ( Area == AREA_DS_OBJECTS ) {
|
||
//
|
||
// ds needs to convert name
|
||
//
|
||
rc = ScepDosErrorToSceStatus(
|
||
ScepSaveDsStatusToSection(
|
||
ObjSecurity->Name,
|
||
ObjSecurity->IsContainer,
|
||
ObjSecurity->Status,
|
||
SDspec,
|
||
SDsize
|
||
) );
|
||
} else {
|
||
rc = ScepSaveObjectString(
|
||
hSection,
|
||
ObjSecurity->Name,
|
||
ObjSecurity->IsContainer,
|
||
ObjSecurity->Status,
|
||
SDspec,
|
||
SDsize
|
||
);
|
||
}
|
||
} else
|
||
rc = ScepDosErrorToSceStatus(Win32Rc);
|
||
}
|
||
|
||
SceJetCloseSection( &hSection, TRUE);
|
||
|
||
if (SDspec)
|
||
ScepFree(SDspec);
|
||
|
||
return(rc);
|
||
}
|
||
|
||
SCESTATUS
|
||
ScepTattooCheckAndUpdateArray(
|
||
IN OUT SCE_TATTOO_KEYS *pTattooKeys,
|
||
IN OUT DWORD *pcTattooKeys,
|
||
IN PWSTR KeyName,
|
||
IN DWORD ConfigOptions,
|
||
IN DWORD dwValue
|
||
)
|
||
/*
|
||
Description:
|
||
|
||
Add a new entry into the array which holds system (tatto) values for the settings
|
||
|
||
The input/output buffer pTattooKeys is allocated outside this routine.
|
||
|
||
*/
|
||
{
|
||
if ( pTattooKeys == NULL || pcTattooKeys == NULL ||
|
||
KeyName == NULL ) {
|
||
return(SCESTATUS_INVALID_PARAMETER);
|
||
}
|
||
|
||
if ( !(ConfigOptions & SCE_POLICY_TEMPLATE) ) {
|
||
return(SCESTATUS_SUCCESS);
|
||
}
|
||
|
||
pTattooKeys[*pcTattooKeys].KeyName = KeyName;
|
||
pTattooKeys[*pcTattooKeys].KeyLen = wcslen(KeyName);
|
||
pTattooKeys[*pcTattooKeys].DataType = 'D';
|
||
pTattooKeys[*pcTattooKeys].SaveValue = dwValue;
|
||
pTattooKeys[*pcTattooKeys].Value = NULL;
|
||
|
||
// ScepLogOutput3(3,0, SCESRV_POLICY_TATTOO_ADD, KeyName, *pcTattooKeys);
|
||
|
||
(*pcTattooKeys)++;
|
||
|
||
return(SCESTATUS_SUCCESS);
|
||
}
|
||
|
||
SCESTATUS
|
||
ScepTattooOpenPolicySections(
|
||
IN PSCECONTEXT hProfile,
|
||
IN PCWSTR SectionName,
|
||
OUT PSCESECTION *phSectionDomain,
|
||
OUT PSCESECTION *phSectionTattoo
|
||
)
|
||
/*
|
||
Open the table/sections for the merged policy and the undo settings
|
||
*/
|
||
{
|
||
|
||
if ( hProfile == NULL || SectionName == NULL ||
|
||
phSectionDomain == NULL || phSectionTattoo == NULL ) {
|
||
return(SCESTATUS_INVALID_PARAMETER);
|
||
}
|
||
|
||
SCESTATUS rCode;
|
||
DOUBLE SectionID;
|
||
|
||
*phSectionDomain = NULL;
|
||
*phSectionTattoo = NULL;
|
||
|
||
//
|
||
// open the section for both tattoo table and effective policy table
|
||
// get section id first
|
||
//
|
||
rCode = SceJetGetSectionIDByName(
|
||
hProfile,
|
||
SectionName,
|
||
&SectionID
|
||
);
|
||
if ( rCode == SCESTATUS_SUCCESS ) {
|
||
|
||
// open effective policy table
|
||
rCode = SceJetOpenSection(
|
||
hProfile,
|
||
SectionID,
|
||
SCEJET_TABLE_SCP,
|
||
phSectionDomain
|
||
);
|
||
if ( rCode == SCESTATUS_SUCCESS ) {
|
||
|
||
// open tattoo table
|
||
rCode = SceJetOpenSection(
|
||
hProfile,
|
||
SectionID,
|
||
SCEJET_TABLE_TATTOO,
|
||
phSectionTattoo
|
||
);
|
||
if ( rCode != SCESTATUS_SUCCESS ) {
|
||
|
||
SceJetCloseSection(phSectionDomain, TRUE);
|
||
*phSectionDomain = NULL;
|
||
}
|
||
}
|
||
}
|
||
|
||
//
|
||
// log tattoo process
|
||
//
|
||
if ( rCode != 0 )
|
||
ScepLogOutput3(1, 0,
|
||
SCESRV_POLICY_TATTOO_PREPARE,
|
||
ScepSceStatusToDosError(rCode),
|
||
SectionName);
|
||
|
||
return(rCode);
|
||
}
|
||
|
||
SCESTATUS
|
||
ScepTattooManageOneStringValue(
|
||
IN PSCESECTION hSectionDomain,
|
||
IN PSCESECTION hSectionTattoo,
|
||
IN PWSTR KeyName,
|
||
IN DWORD KeyLen OPTIONAL,
|
||
IN PWSTR Value,
|
||
IN DWORD ValueLen,
|
||
IN DWORD rc
|
||
)
|
||
{
|
||
if ( hSectionDomain == NULL || hSectionTattoo == NULL ||
|
||
KeyName == NULL || Value == NULL )
|
||
return(SCESTATUS_INVALID_PARAMETER);
|
||
|
||
PWSTR pNewValue=NULL;
|
||
DWORD NewLen=ValueLen;
|
||
SCESTATUS rCode;
|
||
|
||
if (Value && (ValueLen == 0) ) NewLen = wcslen(Value);
|
||
|
||
if ( NewLen ) {
|
||
//
|
||
// the buffer passed may not be NULL terminated
|
||
//
|
||
pNewValue = (PWSTR)ScepAlloc(LPTR,(NewLen+1)*sizeof(WCHAR));
|
||
if ( pNewValue == NULL ) return(SCESTATUS_NOT_ENOUGH_RESOURCE);
|
||
|
||
wcsncpy(pNewValue, Value, NewLen);
|
||
}
|
||
|
||
SCE_TATTOO_KEYS theKey;
|
||
theKey.KeyName = KeyName;
|
||
theKey.KeyLen = (KeyLen == 0) ? wcslen(KeyName) : KeyLen;
|
||
theKey.Value = pNewValue;
|
||
theKey.SaveValue = NewLen;
|
||
theKey.DataType = 'S';
|
||
|
||
rCode = ScepTattooManageValues(hSectionDomain, hSectionTattoo, &theKey, 1, rc);
|
||
|
||
if ( pNewValue ) ScepFree(pNewValue);
|
||
|
||
return(rCode);
|
||
}
|
||
|
||
SCESTATUS
|
||
ScepTattooManageOneIntValue(
|
||
IN PSCESECTION hSectionDomain,
|
||
IN PSCESECTION hSectionTattoo,
|
||
IN PWSTR KeyName,
|
||
IN DWORD KeyLen OPTIONAL,
|
||
IN DWORD Value,
|
||
IN DWORD rc
|
||
)
|
||
{
|
||
|
||
if ( hSectionDomain == NULL || hSectionTattoo == NULL || KeyName == NULL )
|
||
return(SCESTATUS_INVALID_PARAMETER);
|
||
|
||
SCE_TATTOO_KEYS theKey;
|
||
theKey.KeyName = KeyName;
|
||
theKey.KeyLen = (KeyLen == 0) ? wcslen(KeyName) : KeyLen;
|
||
theKey.SaveValue = Value;
|
||
theKey.DataType = 'D';
|
||
theKey.Value = NULL;
|
||
|
||
return(ScepTattooManageValues(hSectionDomain, hSectionTattoo, &theKey, 1, rc));
|
||
|
||
}
|
||
|
||
SCESTATUS
|
||
ScepTattooManageOneIntValueWithDependency(
|
||
IN PSCESECTION hSectionDomain,
|
||
IN PSCESECTION hSectionTattoo,
|
||
IN PWSTR DependentKeyName,
|
||
IN DWORD DependentKeyLen OPTIONAL,
|
||
IN PWSTR SaveKeyName,
|
||
IN DWORD Value,
|
||
IN DWORD rc
|
||
)
|
||
{
|
||
if ( hSectionDomain == NULL || hSectionTattoo == NULL ||
|
||
SaveKeyName == NULL || DependentKeyName == NULL)
|
||
return(SCESTATUS_INVALID_PARAMETER);
|
||
|
||
SCE_TATTOO_KEYS theKey;
|
||
theKey.KeyName = DependentKeyName;
|
||
theKey.KeyLen = (DependentKeyLen == 0) ? wcslen(DependentKeyName) : DependentKeyLen;
|
||
theKey.SaveValue = Value;
|
||
theKey.DataType = 'L';
|
||
theKey.Value = SaveKeyName;
|
||
|
||
return(ScepTattooManageValues(hSectionDomain, hSectionTattoo, &theKey, 1, rc));
|
||
|
||
}
|
||
|
||
SCESTATUS
|
||
ScepTattooManageOneRegistryValue(
|
||
IN PSCESECTION hSectionDomain,
|
||
IN PSCESECTION hSectionTattoo,
|
||
IN PWSTR KeyName,
|
||
IN DWORD KeyLen OPTIONAL,
|
||
IN PSCE_REGISTRY_VALUE_INFO pOneRegValue,
|
||
IN DWORD rc
|
||
)
|
||
{
|
||
if ( hSectionDomain == NULL || hSectionTattoo == NULL ||
|
||
KeyName == NULL || pOneRegValue == NULL )
|
||
return(SCESTATUS_INVALID_PARAMETER);
|
||
|
||
SCESTATUS rCode;
|
||
|
||
|
||
SCE_TATTOO_KEYS theKey;
|
||
theKey.KeyName = KeyName;
|
||
theKey.KeyLen = (KeyLen == 0) ? wcslen(KeyName) : KeyLen;
|
||
theKey.Value = (PWSTR)pOneRegValue;
|
||
theKey.SaveValue = 0;
|
||
theKey.DataType = 'R';
|
||
|
||
rCode = ScepTattooManageValues(hSectionDomain, hSectionTattoo, &theKey, 1, rc);
|
||
|
||
return(rCode);
|
||
}
|
||
|
||
SCESTATUS
|
||
ScepTattooManageOneMemberListValue(
|
||
IN PSCESECTION hSectionDomain,
|
||
IN PSCESECTION hSectionTattoo,
|
||
IN PWSTR GroupName,
|
||
IN DWORD GroupLen OPTIONAL,
|
||
IN PSCE_NAME_LIST pNameList,
|
||
IN BOOL bDeleteOnly,
|
||
IN DWORD rc
|
||
)
|
||
{
|
||
if ( hSectionDomain == NULL || hSectionTattoo == NULL ||
|
||
GroupName == NULL )
|
||
return(SCESTATUS_INVALID_PARAMETER);
|
||
|
||
SCESTATUS rCode;
|
||
SCE_TATTOO_KEYS theKey;
|
||
DWORD Len=GroupLen;
|
||
|
||
if ( Len == 0 ) Len = wcslen(GroupName);
|
||
Len += wcslen(szMembers);
|
||
|
||
PWSTR KeyString = (PWSTR)ScepAlloc(0, (Len+1)*sizeof(WCHAR));
|
||
if ( KeyString != NULL ) {
|
||
|
||
swprintf(KeyString, L"%s%s", GroupName, szMembers);
|
||
|
||
theKey.KeyName = KeyString;
|
||
theKey.KeyLen = Len;
|
||
theKey.Value = (PWSTR)pNameList;
|
||
theKey.SaveValue = bDeleteOnly ? 1 : 0;
|
||
theKey.DataType = 'M';
|
||
|
||
rCode = ScepTattooManageValues(hSectionDomain, hSectionTattoo, &theKey, 1, rc);
|
||
|
||
ScepFree(KeyString);
|
||
|
||
} else {
|
||
rCode = SCESTATUS_NOT_ENOUGH_RESOURCE;
|
||
}
|
||
return(rCode);
|
||
}
|
||
|
||
SCESTATUS
|
||
ScepTattooManageOneServiceValue(
|
||
IN PSCESECTION hSectionDomain,
|
||
IN PSCESECTION hSectionTattoo,
|
||
IN PWSTR ServiceName,
|
||
IN DWORD ServiceLen OPTIONAL,
|
||
IN PSCE_SERVICES pServiceNode,
|
||
IN DWORD rc
|
||
)
|
||
{
|
||
if ( hSectionDomain == NULL || hSectionTattoo == NULL ||
|
||
ServiceName == NULL )
|
||
return(SCESTATUS_INVALID_PARAMETER);
|
||
|
||
SCESTATUS rCode;
|
||
|
||
|
||
SCE_TATTOO_KEYS theKey;
|
||
theKey.KeyName = ServiceName;
|
||
theKey.KeyLen = (ServiceLen == 0) ? wcslen(ServiceName) : ServiceLen;
|
||
theKey.Value = (PWSTR)pServiceNode;
|
||
theKey.SaveValue = 0;
|
||
theKey.DataType = 'V';
|
||
|
||
rCode = ScepTattooManageValues(hSectionDomain, hSectionTattoo, &theKey, 1, rc);
|
||
|
||
return(rCode);
|
||
}
|
||
|
||
SCESTATUS
|
||
ScepTattooManageValues(
|
||
IN PSCESECTION hSectionDomain,
|
||
IN PSCESECTION hSectionTattoo,
|
||
IN SCE_TATTOO_KEYS *pTattooKeys,
|
||
IN DWORD cTattooKeys,
|
||
IN DWORD rc
|
||
)
|
||
/*
|
||
Description:
|
||
|
||
For each setting in the array, do the following:
|
||
|
||
1) Check if the setting come from domain
|
||
2) Check if there is a tattoo value already exist
|
||
3) Save the new value from the array to the tattoo table if it doesn't exist
|
||
4) Delete the tattoo value if the setting didn't come from domain and
|
||
it has been reset successfully
|
||
*/
|
||
{
|
||
if ( hSectionDomain == NULL || hSectionTattoo == NULL ||
|
||
pTattooKeys == NULL || cTattooKeys == 0 ) {
|
||
return(SCESTATUS_INVALID_PARAMETER);
|
||
}
|
||
|
||
SCESTATUS rCode=SCESTATUS_SUCCESS;
|
||
SCESTATUS rc2;
|
||
BOOL bTattooExist,bDomainExist;
|
||
PWSTR KeyString=NULL;
|
||
PWSTR pTempKey;
|
||
|
||
for ( DWORD i=0; i<cTattooKeys; i++) {
|
||
|
||
if ( pTattooKeys[i].KeyName == NULL ) continue;
|
||
if ( pTattooKeys[i].DataType == 'L' && pTattooKeys[i].Value == NULL ) continue;
|
||
|
||
//
|
||
// check if this setting exists in the tattoo table
|
||
//
|
||
bTattooExist = FALSE;
|
||
rc2 = SCESTATUS_SUCCESS;
|
||
|
||
if ( SCESTATUS_SUCCESS == SceJetSeek(
|
||
hSectionTattoo,
|
||
pTattooKeys[i].KeyName,
|
||
pTattooKeys[i].KeyLen*sizeof(WCHAR),
|
||
SCEJET_SEEK_EQ_NO_CASE
|
||
) ) {
|
||
bTattooExist = TRUE;
|
||
}
|
||
|
||
//
|
||
// check if the setting exists in the effective table
|
||
//
|
||
|
||
bDomainExist = FALSE;
|
||
|
||
if ( SCESTATUS_SUCCESS == SceJetSeek(
|
||
hSectionDomain,
|
||
pTattooKeys[i].KeyName,
|
||
pTattooKeys[i].KeyLen*sizeof(WCHAR),
|
||
SCEJET_SEEK_EQ_NO_CASE
|
||
) ) {
|
||
if ( !bTattooExist ) {
|
||
//
|
||
// if there is no tattoo value but there is a setting in domain table
|
||
// this setting must come from domain
|
||
//
|
||
bDomainExist = TRUE;
|
||
|
||
} else if ( hSectionDomain->JetColumnGpoID > 0 ) {
|
||
|
||
//
|
||
// check if GpoID > 0
|
||
//
|
||
|
||
LONG GpoID = 0;
|
||
DWORD Actual;
|
||
JET_ERR JetErr;
|
||
|
||
JetErr = JetRetrieveColumn(
|
||
hSectionDomain->JetSessionID,
|
||
hSectionDomain->JetTableID,
|
||
hSectionDomain->JetColumnGpoID,
|
||
(void *)&GpoID,
|
||
4,
|
||
&Actual,
|
||
0,
|
||
NULL
|
||
);
|
||
if ( JET_errSuccess != JetErr ) {
|
||
//
|
||
// if the column is nil (no value), it will return warning
|
||
// but the buffer pGpoID is trashed
|
||
//
|
||
GpoID = 0;
|
||
}
|
||
|
||
if ( GpoID > 0 ) {
|
||
bDomainExist = TRUE;
|
||
}
|
||
}
|
||
|
||
}
|
||
|
||
//
|
||
// check if we need to save the tatto value or delete the tattoo value
|
||
//
|
||
if ( bDomainExist ) {
|
||
|
||
pTempKey = pTattooKeys[i].KeyName;
|
||
BOOL bSave = FALSE;
|
||
|
||
if ( pTattooKeys[i].DataType == 'M' && pTattooKeys[i].SaveValue == 1 ) {
|
||
//
|
||
// delete only for group membership, don't do anything in this case
|
||
//
|
||
} else if ( !bTattooExist ) {
|
||
//
|
||
// domain setting is defined (the first time)
|
||
// save the tattoo value
|
||
//
|
||
switch ( pTattooKeys[i].DataType ) {
|
||
case 'D':
|
||
if ( pTattooKeys[i].SaveValue != SCE_NO_VALUE ) {
|
||
|
||
rc2 = ScepCompareAndSaveIntValue(hSectionTattoo,
|
||
pTattooKeys[i].KeyName,
|
||
FALSE,
|
||
SCE_SNAPSHOT_VALUE,
|
||
pTattooKeys[i].SaveValue
|
||
);
|
||
bSave = TRUE;
|
||
}
|
||
break;
|
||
case 'L': // dependency DWORD type
|
||
pTempKey = pTattooKeys[i].Value;
|
||
|
||
if ( pTattooKeys[i].SaveValue != SCE_NO_VALUE ) {
|
||
rc2 = ScepCompareAndSaveIntValue(hSectionTattoo,
|
||
pTattooKeys[i].Value,
|
||
FALSE,
|
||
SCE_SNAPSHOT_VALUE,
|
||
pTattooKeys[i].SaveValue
|
||
);
|
||
bSave = TRUE;
|
||
}
|
||
|
||
break;
|
||
case 'S':
|
||
if ( pTattooKeys[i].Value ) {
|
||
|
||
rc2 = ScepCompareAndSaveStringValue(hSectionTattoo,
|
||
pTattooKeys[i].KeyName,
|
||
(PWSTR)(ULONG_PTR)SCE_SNAPSHOT_VALUE,
|
||
pTattooKeys[i].Value,
|
||
pTattooKeys[i].SaveValue*sizeof(WCHAR)
|
||
);
|
||
bSave = TRUE;
|
||
}
|
||
break;
|
||
case 'R': // registry values
|
||
if ( ((PSCE_REGISTRY_VALUE_INFO)(pTattooKeys[i].Value))->Value ) {
|
||
|
||
if ( REG_DWORD == ((PSCE_REGISTRY_VALUE_INFO)(pTattooKeys[i].Value))->ValueType ) {
|
||
|
||
DWORD RegData = _wtol(((PSCE_REGISTRY_VALUE_INFO)(pTattooKeys[i].Value))->Value);
|
||
|
||
rc2 = ScepSaveRegistryValue(hSectionTattoo,
|
||
pTattooKeys[i].KeyName,
|
||
REG_DWORD,
|
||
(PWSTR)&RegData,
|
||
sizeof(DWORD),
|
||
0
|
||
);
|
||
} else {
|
||
|
||
rc2 = ScepSaveRegistryValue(hSectionTattoo,
|
||
pTattooKeys[i].KeyName,
|
||
((PSCE_REGISTRY_VALUE_INFO)(pTattooKeys[i].Value))->ValueType,
|
||
((PSCE_REGISTRY_VALUE_INFO)(pTattooKeys[i].Value))->Value,
|
||
wcslen(((PSCE_REGISTRY_VALUE_INFO)(pTattooKeys[i].Value))->Value)*sizeof(WCHAR),
|
||
0
|
||
);
|
||
}
|
||
bSave = TRUE;
|
||
}
|
||
break;
|
||
case 'M': // group member list
|
||
// allow empty member list to be saved
|
||
rc2 = ScepWriteNameListValue(
|
||
NULL,
|
||
hSectionTattoo,
|
||
pTattooKeys[i].KeyName,
|
||
(PSCE_NAME_LIST)(pTattooKeys[i].Value),
|
||
SCE_WRITE_EMPTY_LIST,
|
||
3
|
||
);
|
||
bSave = TRUE;
|
||
|
||
break;
|
||
case 'V': // service
|
||
|
||
if ( pTattooKeys[i].Value ) {
|
||
|
||
rc2 = ScepSetSingleServiceSetting(
|
||
hSectionTattoo,
|
||
(PSCE_SERVICES)(pTattooKeys[i].Value)
|
||
);
|
||
bSave = TRUE;
|
||
|
||
} else {
|
||
rc2 = SCESTATUS_INVALID_PARAMETER;
|
||
}
|
||
break;
|
||
default:
|
||
rc2 = SCESTATUS_INVALID_PARAMETER;
|
||
break;
|
||
}
|
||
|
||
if ( rc2 != SCESTATUS_SUCCESS ) {
|
||
|
||
ScepLogOutput3(1, 0, SCESRV_POLICY_TATTOO_ERROR_SETTING,
|
||
ScepSceStatusToDosError(rc2), pTempKey);
|
||
rCode = rc2;
|
||
} else if ( bSave ) {
|
||
ScepLogOutput3(2, 0, SCESRV_POLICY_TATTOO_CHECK, pTempKey);
|
||
}
|
||
|
||
} else {
|
||
|
||
//
|
||
// check if there is any value to save
|
||
//
|
||
switch ( pTattooKeys[i].DataType ) {
|
||
case 'D':
|
||
case 'L':
|
||
if ( pTattooKeys[i].SaveValue != SCE_NO_VALUE )
|
||
bSave = TRUE;
|
||
break;
|
||
case 'S':
|
||
case 'V':
|
||
if ( pTattooKeys[i].Value ) bSave = TRUE;
|
||
break;
|
||
case 'R':
|
||
if ( ((PSCE_REGISTRY_VALUE_INFO)(pTattooKeys[i].Value))->Value )
|
||
bSave = TRUE;
|
||
break;
|
||
}
|
||
|
||
if ( bSave )
|
||
ScepLogOutput3(3, 0, SCESRV_POLICY_TATTOO_EXIST, pTempKey);
|
||
}
|
||
|
||
} else {
|
||
pTempKey = (pTattooKeys[i].DataType == 'L') ? pTattooKeys[i].Value : pTattooKeys[i].KeyName;
|
||
|
||
if ( bTattooExist && ERROR_SUCCESS == rc ) {
|
||
//
|
||
// no domain setting defined
|
||
// tattoo setting has been reset, delete the tattoo value
|
||
// for dependency type, delete the right key
|
||
//
|
||
rc2 = SceJetDelete(hSectionTattoo,
|
||
pTempKey,
|
||
FALSE,
|
||
SCEJET_DELETE_LINE_NO_CASE);
|
||
|
||
if ( rc2 == SCESTATUS_RECORD_NOT_FOUND) rc2 = SCESTATUS_SUCCESS;
|
||
|
||
if ( rc2 != SCESTATUS_SUCCESS ) {
|
||
|
||
ScepLogOutput3(1, 0, SCESRV_POLICY_TATTOO_ERROR_REMOVE, ScepSceStatusToDosError(rc2), pTempKey);
|
||
rCode = rc2;
|
||
} else {
|
||
ScepLogOutput3(2, 0, SCESRV_POLICY_TATTOO_REMOVE_SETTING, pTempKey);
|
||
}
|
||
} else if ( bTattooExist ) {
|
||
//
|
||
// undo value wan't reset properly
|
||
//
|
||
ScepLogOutput3(1, 0, SCESRV_POLICY_TATTOO_ERROR_RESET, pTempKey, rc );
|
||
} else {
|
||
//
|
||
// there is no undo value
|
||
//
|
||
|
||
// ScepLogOutput3(3, 0, SCESRV_POLICY_TATTOO_NONEXIST, pTempKey );
|
||
}
|
||
}
|
||
}
|
||
|
||
return(rCode);
|
||
|
||
}
|
||
|
||
BOOL
|
||
ScepTattooIfQueryNeeded(
|
||
IN PSCESECTION hSectionDomain,
|
||
IN PSCESECTION hSectionTattoo,
|
||
IN PWSTR KeyName,
|
||
IN DWORD Len,
|
||
OUT BOOL *pbDomainExist,
|
||
OUT BOOL *pbTattooExist
|
||
)
|
||
{
|
||
if ( hSectionDomain == NULL || hSectionTattoo == NULL || KeyName == NULL || Len == 0 ) {
|
||
return FALSE;
|
||
}
|
||
|
||
//
|
||
// check if this setting exists in the tattoo table
|
||
//
|
||
BOOL bTattooExist = FALSE;
|
||
|
||
if ( SCESTATUS_SUCCESS == SceJetSeek(
|
||
hSectionTattoo,
|
||
KeyName,
|
||
Len*sizeof(WCHAR),
|
||
SCEJET_SEEK_EQ_NO_CASE
|
||
) ) {
|
||
bTattooExist = TRUE;
|
||
}
|
||
|
||
//
|
||
// check if the setting exists in the effective table
|
||
//
|
||
|
||
BOOL bDomainExist = FALSE;
|
||
|
||
if ( SCESTATUS_SUCCESS == SceJetSeek(
|
||
hSectionDomain,
|
||
KeyName,
|
||
Len*sizeof(WCHAR),
|
||
SCEJET_SEEK_EQ_NO_CASE
|
||
) ) {
|
||
if ( !bTattooExist ) {
|
||
//
|
||
// if there is no tattoo value but there is a setting in domain table
|
||
// this setting must come from domain
|
||
//
|
||
bDomainExist = TRUE;
|
||
|
||
} else if ( hSectionDomain->JetColumnGpoID > 0 ) {
|
||
|
||
//
|
||
// check if GpoID > 0
|
||
//
|
||
|
||
LONG GpoID = 0;
|
||
DWORD Actual;
|
||
JET_ERR JetErr;
|
||
|
||
JetErr = JetRetrieveColumn(
|
||
hSectionDomain->JetSessionID,
|
||
hSectionDomain->JetTableID,
|
||
hSectionDomain->JetColumnGpoID,
|
||
(void *)&GpoID,
|
||
4,
|
||
&Actual,
|
||
0,
|
||
NULL
|
||
);
|
||
if ( JET_errSuccess != JetErr ) {
|
||
//
|
||
// if the column is nil (no value), it will return warning
|
||
// but the buffer pGpoID is trashed
|
||
//
|
||
GpoID = 0;
|
||
}
|
||
|
||
if ( GpoID > 0 ) {
|
||
bDomainExist = TRUE;
|
||
}
|
||
}
|
||
}
|
||
|
||
//
|
||
// check if we need to save the tatto value or delete the tattoo value
|
||
//
|
||
if ( pbDomainExist ) *pbDomainExist = bDomainExist;
|
||
if ( pbTattooExist ) *pbTattooExist = bTattooExist;
|
||
|
||
if ( bDomainExist && !bTattooExist )
|
||
return TRUE;
|
||
|
||
return FALSE;
|
||
}
|
||
|
||
|
||
SCESTATUS
|
||
ScepDeleteOneSection(
|
||
IN PSCECONTEXT hProfile,
|
||
IN SCETYPE tblType,
|
||
IN PCWSTR SectionName
|
||
)
|
||
{
|
||
PSCESECTION hSection=NULL;
|
||
SCESTATUS rc;
|
||
|
||
rc = ScepOpenSectionForName(
|
||
hProfile,
|
||
tblType,
|
||
SectionName,
|
||
&hSection
|
||
);
|
||
|
||
if ( rc == SCESTATUS_SUCCESS ) {
|
||
|
||
rc = SceJetDelete( hSection, NULL, FALSE,SCEJET_DELETE_SECTION );
|
||
|
||
SceJetCloseSection(&hSection, TRUE );
|
||
|
||
}
|
||
|
||
if ( rc == SCESTATUS_RECORD_NOT_FOUND )
|
||
rc = SCESTATUS_SUCCESS;
|
||
|
||
return(rc);
|
||
}
|
||
|