mirror of https://github.com/tongzx/nt5src
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
6421 lines
180 KiB
6421 lines
180 KiB
//depot/private/vishnup_branch/DS/security/services/scerpc/server/editsave.cpp#3 - edit change 1167 (text)
|
|
/*++
|
|
|
|
Copyright (c) 1996 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
editsave.c
|
|
|
|
Abstract:
|
|
|
|
APIs for UI to handle SMP (configuration) editing.
|
|
|
|
Author:
|
|
|
|
Jin Huang (jinhuang) 17-Jun-1996
|
|
|
|
Revision History:
|
|
|
|
jinhuang 28-Jan-1998 splitted to client-server
|
|
|
|
--*/
|
|
|
|
#include "serverp.h"
|
|
#include <io.h>
|
|
#include "pfp.h"
|
|
#pragma hdrstop
|
|
|
|
//
|
|
// for whole buffer areas
|
|
//
|
|
|
|
SCESTATUS
|
|
ScepUpdateSystemAccess(
|
|
IN PSCECONTEXT hProfile,
|
|
IN PSCE_PROFILE_INFO pInfo,
|
|
IN PSCE_PROFILE_INFO pBufScep OPTIONAL,
|
|
IN PSCE_PROFILE_INFO pBufSap OPTIONAL,
|
|
IN DWORD dwMode
|
|
);
|
|
|
|
SCESTATUS
|
|
ScepUpdateSystemAuditing(
|
|
IN PSCECONTEXT hProfile,
|
|
IN PSCE_PROFILE_INFO pInfo,
|
|
IN PSCE_PROFILE_INFO pBufScep OPTIONAL,
|
|
IN PSCE_PROFILE_INFO pBufSap OPTIONAL,
|
|
IN DWORD dwMode
|
|
);
|
|
|
|
SCESTATUS
|
|
ScepUpdateLogs(
|
|
IN PSCECONTEXT hProfile,
|
|
IN PSCE_PROFILE_INFO pInfo,
|
|
IN PSCE_PROFILE_INFO pBufScep OPTIONAL,
|
|
IN PSCE_PROFILE_INFO pBufSap OPTIONAL,
|
|
IN DWORD dwMode
|
|
);
|
|
|
|
SCESTATUS
|
|
ScepUpdateKerberos(
|
|
IN PSCECONTEXT hProfile,
|
|
IN PSCE_KERBEROS_TICKET_INFO pInfo,
|
|
IN PSCE_KERBEROS_TICKET_INFO pBufScep OPTIONAL,
|
|
IN PSCE_KERBEROS_TICKET_INFO pBufSap OPTIONAL,
|
|
IN DWORD dwMode
|
|
);
|
|
|
|
SCESTATUS
|
|
ScepUpdateRegistryValues(
|
|
IN PSCECONTEXT hProfile,
|
|
IN PSCE_PROFILE_INFO pInfo,
|
|
IN PSCE_PROFILE_INFO pBufScep,
|
|
IN PSCE_PROFILE_INFO pBufSap
|
|
);
|
|
|
|
SCESTATUS
|
|
ScepSaveRegValueEntry(
|
|
IN PSCESECTION hSection,
|
|
IN PWSTR Name,
|
|
IN PWSTR CurrentValue,
|
|
IN DWORD dType,
|
|
IN DWORD Status
|
|
);
|
|
|
|
SCESTATUS
|
|
ScepUpdateFixValueSection(
|
|
IN PSCECONTEXT hProfile,
|
|
IN PSCE_PROFILE_INFO pInfo,
|
|
IN PSCE_PROFILE_INFO pBufScep,
|
|
IN PSCE_PROFILE_INFO pBufSap,
|
|
IN SCE_KEY_LOOKUP *Keys,
|
|
IN DWORD cKeys,
|
|
IN PCWSTR SectionName,
|
|
OUT PSCESECTION *hSecScep OPTIONAL,
|
|
OUT PSCESECTION *hSecSap OPTIONAL
|
|
);
|
|
|
|
SCESTATUS
|
|
ScepUpdateAccountName(
|
|
IN PSCESECTION hSectionSmp,
|
|
IN PSCESECTION hSectionSap,
|
|
IN PCWSTR KeyName,
|
|
IN PWSTR NewName OPTIONAL,
|
|
IN PWSTR SmpName OPTIONAL,
|
|
IN PWSTR SapName OPTIONAL
|
|
);
|
|
|
|
SCESTATUS
|
|
ScepUpdatePrivileges(
|
|
IN PSCECONTEXT hProfile,
|
|
IN PSCE_PRIVILEGE_ASSIGNMENT pNewPriv,
|
|
IN PSCE_PRIVILEGE_ASSIGNMENT *pScepPriv
|
|
);
|
|
|
|
SCESTATUS
|
|
ScepUpdateGroupMembership(
|
|
IN PSCECONTEXT hProfile,
|
|
IN PSCE_GROUP_MEMBERSHIP pNewGroup,
|
|
IN PSCE_GROUP_MEMBERSHIP *pScepGroup
|
|
);
|
|
|
|
SCESTATUS
|
|
ScepGetKeyNameList(
|
|
IN LSA_HANDLE LsaPolicy,
|
|
IN PSCESECTION hSection,
|
|
IN PWSTR Key,
|
|
IN DWORD KeyLen,
|
|
IN DWORD dwAccountFormat,
|
|
OUT PSCE_NAME_LIST *pNameList
|
|
);
|
|
|
|
#define SCE_FLAG_UPDATE_PRIV 0
|
|
#define SCE_FLAG_UPDATE_MEMBERS 1
|
|
#define SCE_FLAG_UPDATE_MEMBEROF 2
|
|
|
|
SCESTATUS
|
|
ScepUpdateKeyNameList(
|
|
IN LSA_HANDLE LsaPolicy,
|
|
IN PSCESECTION hSectionSmp,
|
|
IN PSCESECTION hSectionSap,
|
|
IN PWSTR GroupName OPTIONAL,
|
|
IN BOOL bScepExist,
|
|
IN PWSTR KeyName,
|
|
IN DWORD NameLen,
|
|
IN PSCE_NAME_LIST pNewList,
|
|
IN PSCE_NAME_LIST pScepList,
|
|
IN DWORD flag
|
|
);
|
|
|
|
SCESTATUS
|
|
ScepUpdateGeneralServices(
|
|
IN PSCECONTEXT hProfile,
|
|
IN PSCE_SERVICES pNewServices,
|
|
IN PSCE_SERVICES *pScepServices
|
|
);
|
|
|
|
//
|
|
// for object updates
|
|
//
|
|
|
|
SCESTATUS
|
|
ScepObjectUpdateExistingNode(
|
|
IN PSCESECTION hSectionSmp,
|
|
IN PSCESECTION hSectionSap,
|
|
IN PWSTR ObjectName,
|
|
IN DWORD NameLen,
|
|
IN SE_OBJECT_TYPE ObjectType,
|
|
IN BYTE ConfigStatus,
|
|
IN BOOL IsContainer,
|
|
IN PSECURITY_DESCRIPTOR pSD,
|
|
IN SECURITY_INFORMATION SeInfo,
|
|
OUT PBYTE pAnalysisStatus
|
|
);
|
|
|
|
SCESTATUS
|
|
ScepObjectGetKeySetting(
|
|
IN PSCESECTION hSection,
|
|
IN PWSTR ObjectName,
|
|
OUT PBYTE Status,
|
|
OUT PBOOL IsContainer OPTIONAL,
|
|
OUT PSECURITY_DESCRIPTOR *pSecurityDescriptor OPTIONAL,
|
|
OUT PSECURITY_INFORMATION SeInfo OPTIONAL
|
|
);
|
|
|
|
SCESTATUS
|
|
ScepObjectSetKeySetting(
|
|
IN PSCESECTION hSection,
|
|
IN PWSTR ObjectName,
|
|
IN BYTE Status,
|
|
IN BOOL IsContainer,
|
|
IN PSECURITY_DESCRIPTOR pSD,
|
|
IN SECURITY_INFORMATION SeInfo,
|
|
IN BOOL bOverwrite
|
|
);
|
|
|
|
|
|
SCESTATUS
|
|
ScepObjectCompareKeySetting(
|
|
IN PSCESECTION hSectionSap,
|
|
IN PWSTR ObjectName,
|
|
IN SE_OBJECT_TYPE ObjectType,
|
|
IN BOOL IsContainer,
|
|
IN PSECURITY_DESCRIPTOR pSD,
|
|
IN SECURITY_INFORMATION SeInfo,
|
|
IN PSECURITY_DESCRIPTOR pScepSD,
|
|
OUT PBYTE pAnalysisStatus
|
|
);
|
|
|
|
SCESTATUS
|
|
ScepObjectDeleteScepAndAllChildren(
|
|
IN PSCESECTION hSectionSmp,
|
|
IN PSCESECTION hSectionSap,
|
|
IN PWSTR ObjectName,
|
|
IN BOOL IsContainer,
|
|
IN BYTE StatusToRaise
|
|
);
|
|
|
|
SCESTATUS
|
|
ScepObjectAdjustNode(
|
|
IN PSCESECTION hSectionSmp,
|
|
IN PSCESECTION hSectionSap,
|
|
IN PWSTR ObjectName,
|
|
IN DWORD NameLen,
|
|
IN SE_OBJECT_TYPE ObjectType,
|
|
IN BYTE ConfigStatus,
|
|
IN BOOL IsContainer,
|
|
IN PSECURITY_DESCRIPTOR pSD,
|
|
IN SECURITY_INFORMATION SeInfo,
|
|
IN BOOL bAdd,
|
|
OUT PBYTE pAnalysisStatus
|
|
);
|
|
|
|
#define SCE_OBJECT_TURNOFF_IGNORE 0x1L
|
|
#define SCE_OBJECT_SEARCH_JUNCTION 0x2L
|
|
|
|
SCESTATUS
|
|
ScepObjectAdjustParentStatus(
|
|
IN PSCESECTION hSectionSmp,
|
|
IN PSCESECTION hSectionSap,
|
|
IN PWSTR ObjectName,
|
|
IN DWORD NameLen,
|
|
IN WCHAR Delim,
|
|
IN INT Level,
|
|
IN BYTE Flag,
|
|
OUT PINT ParentLevel,
|
|
OUT PBYTE ParentStatus OPTIONAL,
|
|
OUT PWSTR ParentName OPTIONAL
|
|
);
|
|
|
|
SCESTATUS
|
|
ScepObjectHasAnyChild(
|
|
IN PSCESECTION hSection,
|
|
IN PWSTR ObjectName,
|
|
IN DWORD NameLen,
|
|
IN WCHAR Delim,
|
|
OUT PBOOL bpHasChild
|
|
);
|
|
|
|
SCESTATUS
|
|
ScepObjectRaiseChildrenInBetween(
|
|
IN PSCESECTION hSectionSmp,
|
|
IN PSCESECTION hSectionSap,
|
|
IN PWSTR ObjectName,
|
|
IN DWORD NameLen,
|
|
IN BOOL IsContainer,
|
|
IN BYTE Status,
|
|
IN BOOL bChangeStatusOnly
|
|
);
|
|
|
|
SCESTATUS
|
|
ScepObjectRaiseNodesInPath(
|
|
IN PSCESECTION hSectionSap,
|
|
IN PWSTR ObjectName,
|
|
IN DWORD NameLen,
|
|
IN INT StartLevel,
|
|
IN INT EndLevel,
|
|
IN WCHAR Delim,
|
|
IN BYTE Status
|
|
);
|
|
|
|
SCESTATUS
|
|
ScepGetFullNameInLevel(
|
|
IN PCWSTR ObjectFullName,
|
|
IN DWORD Level,
|
|
IN WCHAR Delim,
|
|
IN BOOL bWithLastDelim,
|
|
OUT PWSTR Buffer,
|
|
OUT PBOOL LastOne
|
|
);
|
|
|
|
SCESTATUS
|
|
ScepObjectTotalLevel(
|
|
IN PWSTR ObjectName,
|
|
IN WCHAR Delim,
|
|
OUT PINT pLevel
|
|
);
|
|
|
|
SCESTATUS
|
|
ScepUpdateLocalSection(
|
|
IN PSCECONTEXT hProfile,
|
|
IN PSCE_PROFILE_INFO pInfo,
|
|
IN SCE_KEY_LOOKUP *Keys,
|
|
IN DWORD cKeys,
|
|
IN PCWSTR SectionName,
|
|
IN DWORD dwMode
|
|
);
|
|
|
|
SCESTATUS
|
|
ScepUpdateLocalAccountName(
|
|
IN PSCECONTEXT hProfile,
|
|
IN PCWSTR KeyName,
|
|
IN PWSTR NewName OPTIONAL
|
|
);
|
|
|
|
SCESTATUS
|
|
ScepUpdateLocalRegValues(
|
|
IN PSCECONTEXT hProfile,
|
|
IN PSCE_PROFILE_INFO pInfo,
|
|
IN DWORD dwMode
|
|
);
|
|
|
|
SCESTATUS
|
|
ScepUpdateLocalPrivileges(
|
|
IN PSCECONTEXT hProfile,
|
|
IN PSCE_PRIVILEGE_ASSIGNMENT pNewPriv,
|
|
IN DWORD dwMode
|
|
);
|
|
|
|
DWORD
|
|
ScepQueryAnalysisStatus(
|
|
IN PSCESECTION hSection,
|
|
IN PWSTR KeyName,
|
|
IN DWORD NameLen
|
|
);
|
|
|
|
DWORD
|
|
ScepConvertNameListFormat(
|
|
IN LSA_HANDLE LsaHandle,
|
|
IN PSCE_NAME_LIST pInList,
|
|
IN DWORD FromFormat,
|
|
IN DWORD ToFormat,
|
|
OUT PSCE_NAME_LIST *ppOutList
|
|
);
|
|
|
|
DWORD
|
|
ScepConvertPrivilegeList(
|
|
IN LSA_HANDLE LsaHandle,
|
|
IN PSCE_PRIVILEGE_ASSIGNMENT pFromList,
|
|
IN DWORD FromFormat,
|
|
IN DWORD ToFormat,
|
|
OUT PSCE_PRIVILEGE_ASSIGNMENT *ppToList
|
|
);
|
|
//
|
|
// implementations
|
|
//
|
|
|
|
|
|
SCESTATUS
|
|
ScepUpdateDatabaseInfo(
|
|
IN PSCECONTEXT hProfile,
|
|
IN AREA_INFORMATION Area,
|
|
IN PSCE_PROFILE_INFO pInfo
|
|
)
|
|
/*
|
|
Routine Description:
|
|
|
|
Update SMP section and "compute" analysis status to determine related
|
|
changes for SAP section. For rules on computing, refer to spec objedit.doc
|
|
|
|
This routine should work for areas security policy, privileges, and
|
|
group membership
|
|
|
|
Arguements:
|
|
|
|
hProfile - the jet database handle
|
|
|
|
Area - The areas to update
|
|
|
|
pInfo - the buffer containing modified SMP information
|
|
|
|
Return Value:
|
|
|
|
SCESTATUS
|
|
*/
|
|
{
|
|
SCESTATUS rc;
|
|
PSCE_PROFILE_INFO pBufScep=NULL;
|
|
PSCE_ERROR_LOG_INFO Errlog=NULL;
|
|
PSCE_PROFILE_INFO pBufSap=NULL;
|
|
|
|
|
|
if ( hProfile == NULL || pInfo == NULL ) {
|
|
|
|
return(SCESTATUS_INVALID_PARAMETER);
|
|
}
|
|
|
|
if ( Area & ~( AREA_SECURITY_POLICY | AREA_PRIVILEGES |
|
|
AREA_GROUP_MEMBERSHIP | AREA_SYSTEM_SERVICE ) ) {
|
|
|
|
return(SCESTATUS_INVALID_PARAMETER);
|
|
}
|
|
|
|
//
|
|
// get original SMP information
|
|
//
|
|
rc = ScepGetDatabaseInfo(
|
|
hProfile,
|
|
SCE_ENGINE_SMP,
|
|
Area,
|
|
SCE_ACCOUNT_SID_STRING,
|
|
&pBufScep,
|
|
&Errlog
|
|
);
|
|
|
|
ScepLogWriteError(Errlog, 1);
|
|
ScepFreeErrorLog(Errlog );
|
|
Errlog = NULL;
|
|
|
|
if ( rc != SCESTATUS_SUCCESS ) {
|
|
return(rc);
|
|
}
|
|
|
|
rc = SceJetStartTransaction( hProfile );
|
|
|
|
if ( rc == SCESTATUS_SUCCESS ) {
|
|
|
|
if ( Area & AREA_SECURITY_POLICY ) {
|
|
//
|
|
// security policy area, get SAP information
|
|
//
|
|
|
|
rc = ScepGetDatabaseInfo(
|
|
hProfile,
|
|
SCE_ENGINE_SAP,
|
|
AREA_SECURITY_POLICY,
|
|
0,
|
|
&pBufSap,
|
|
&Errlog
|
|
);
|
|
ScepLogWriteError(Errlog, 1);
|
|
ScepFreeErrorLog(Errlog );
|
|
Errlog = NULL;
|
|
|
|
if ( rc == SCESTATUS_SUCCESS ) {
|
|
//
|
|
// Update system access section
|
|
//
|
|
rc = ScepUpdateSystemAccess(hProfile,
|
|
pInfo,
|
|
pBufScep,
|
|
pBufSap,
|
|
0);
|
|
|
|
if ( rc == SCESTATUS_SUCCESS) {
|
|
//
|
|
// Update system auditing section
|
|
//
|
|
rc = ScepUpdateSystemAuditing(hProfile,
|
|
pInfo,
|
|
pBufScep,
|
|
pBufSap,
|
|
0);
|
|
|
|
if ( rc == SCESTATUS_SUCCESS) {
|
|
//
|
|
// Update log sections
|
|
//
|
|
rc = ScepUpdateLogs(hProfile,
|
|
pInfo,
|
|
pBufScep,
|
|
pBufSap,
|
|
0);
|
|
|
|
if ( rc == SCESTATUS_SUCCESS && pInfo->pKerberosInfo ) {
|
|
//
|
|
// Update kerberos policy
|
|
//
|
|
rc = ScepUpdateKerberos(hProfile,
|
|
pInfo->pKerberosInfo,
|
|
pBufScep->pKerberosInfo,
|
|
pBufSap->pKerberosInfo,
|
|
0);
|
|
}
|
|
if ( rc == SCESTATUS_SUCCESS ) {
|
|
//
|
|
// update registry values
|
|
//
|
|
rc = ScepUpdateRegistryValues(hProfile,
|
|
pInfo,
|
|
pBufScep,
|
|
pBufSap
|
|
);
|
|
|
|
}
|
|
//
|
|
// Note: policy attachment is not updated through this API
|
|
//
|
|
}
|
|
}
|
|
|
|
SceFreeProfileMemory(pBufSap);
|
|
}
|
|
|
|
if ( rc != SCESTATUS_SUCCESS ) {
|
|
goto Cleanup;
|
|
}
|
|
}
|
|
|
|
if ( Area & AREA_PRIVILEGES ) {
|
|
//
|
|
// privileges area
|
|
//
|
|
rc = ScepUpdatePrivileges(hProfile,
|
|
pInfo->OtherInfo.smp.pPrivilegeAssignedTo,
|
|
&(pBufScep->OtherInfo.smp.pPrivilegeAssignedTo)
|
|
);
|
|
|
|
if ( rc != SCESTATUS_SUCCESS ) {
|
|
goto Cleanup;
|
|
}
|
|
}
|
|
|
|
if ( Area & AREA_GROUP_MEMBERSHIP ) {
|
|
//
|
|
// group membership area
|
|
//
|
|
rc = ScepUpdateGroupMembership(hProfile,
|
|
pInfo->pGroupMembership,
|
|
&(pBufScep->pGroupMembership)
|
|
);
|
|
|
|
}
|
|
|
|
if ( Area & AREA_SYSTEM_SERVICE ) {
|
|
//
|
|
// system service general setting area
|
|
//
|
|
rc = ScepUpdateGeneralServices(hProfile,
|
|
pInfo->pServices,
|
|
&(pBufScep->pServices)
|
|
);
|
|
|
|
}
|
|
|
|
if ( rc == SCESTATUS_SUCCESS ) {
|
|
//
|
|
// needs return code for commiting the transaction
|
|
//
|
|
rc = SceJetCommitTransaction(hProfile, 0);
|
|
|
|
}
|
|
if ( rc != SCESTATUS_SUCCESS ) {
|
|
|
|
SceJetRollback(hProfile, 0);
|
|
}
|
|
}
|
|
|
|
Cleanup:
|
|
|
|
SceFreeProfileMemory(pBufScep);
|
|
|
|
return(rc);
|
|
|
|
}
|
|
|
|
|
|
SCESTATUS
|
|
ScepUpdateSystemAccess(
|
|
IN PSCECONTEXT hProfile,
|
|
IN PSCE_PROFILE_INFO pInfo,
|
|
IN PSCE_PROFILE_INFO pBufScep OPTIONAL,
|
|
IN PSCE_PROFILE_INFO pBufSap OPTIONAL,
|
|
IN DWORD dwMode
|
|
)
|
|
/*
|
|
Routine Description:
|
|
|
|
Update system access section
|
|
|
|
Arguements:
|
|
|
|
hProfile - the jet database handle
|
|
|
|
pInfo - the changed info buffer
|
|
|
|
pBufScep - the original SMP buffer
|
|
|
|
pBufSap - the SAP buffer
|
|
|
|
Return Value:
|
|
|
|
SCESTATUS
|
|
*/
|
|
{
|
|
SCE_KEY_LOOKUP AccessLookup[] = {
|
|
{(PWSTR)TEXT("MinimumPasswordAge"), offsetof(struct _SCE_PROFILE_INFO, MinimumPasswordAge), 'D'},
|
|
{(PWSTR)TEXT("MaximumPasswordAge"), offsetof(struct _SCE_PROFILE_INFO, MaximumPasswordAge), 'D'},
|
|
{(PWSTR)TEXT("MinimumPasswordLength"), offsetof(struct _SCE_PROFILE_INFO, MinimumPasswordLength), 'D'},
|
|
{(PWSTR)TEXT("PasswordComplexity"), offsetof(struct _SCE_PROFILE_INFO, PasswordComplexity), 'D'},
|
|
{(PWSTR)TEXT("PasswordHistorySize"), offsetof(struct _SCE_PROFILE_INFO, PasswordHistorySize), 'D'},
|
|
{(PWSTR)TEXT("LockoutBadCount"), offsetof(struct _SCE_PROFILE_INFO, LockoutBadCount), 'D'},
|
|
{(PWSTR)TEXT("ResetLockoutCount"), offsetof(struct _SCE_PROFILE_INFO, ResetLockoutCount), 'D'},
|
|
{(PWSTR)TEXT("LockoutDuration"), offsetof(struct _SCE_PROFILE_INFO, LockoutDuration), 'D'},
|
|
{(PWSTR)TEXT("RequireLogonToChangePassword"), offsetof(struct _SCE_PROFILE_INFO, RequireLogonToChangePassword), 'D'},
|
|
{(PWSTR)TEXT("ForceLogoffWhenHourExpire"), offsetof(struct _SCE_PROFILE_INFO, ForceLogoffWhenHourExpire), 'D'},
|
|
{(PWSTR)TEXT("ClearTextPassword"), offsetof(struct _SCE_PROFILE_INFO, ClearTextPassword), 'D'},
|
|
{(PWSTR)TEXT("LSAAnonymousNameLookup"), offsetof(struct _SCE_PROFILE_INFO, LSAAnonymousNameLookup), 'D'},
|
|
{(PWSTR)TEXT("EnableAdminAccount"), offsetof(struct _SCE_PROFILE_INFO, EnableAdminAccount), 'D'},
|
|
{(PWSTR)TEXT("EnableGuestAccount"), offsetof(struct _SCE_PROFILE_INFO, EnableGuestAccount), 'D'}
|
|
};
|
|
|
|
DWORD cAccess = sizeof(AccessLookup) / sizeof(SCE_KEY_LOOKUP);
|
|
|
|
SCESTATUS rc;
|
|
PSCESECTION hSectionSmp=NULL,
|
|
hSectionSap=NULL;
|
|
|
|
|
|
if ( hProfile == NULL || pInfo == NULL ) {
|
|
return(SCESTATUS_INVALID_PARAMETER);
|
|
}
|
|
|
|
|
|
if ( dwMode & SCE_UPDATE_LOCAL_POLICY ) {
|
|
//
|
|
// update local policy table only
|
|
//
|
|
|
|
rc = ScepUpdateLocalSection(
|
|
hProfile,
|
|
pInfo,
|
|
AccessLookup,
|
|
cAccess,
|
|
szSystemAccess,
|
|
dwMode
|
|
);
|
|
|
|
if ( rc == SCESTATUS_SUCCESS ) {
|
|
//
|
|
// new admin name
|
|
//
|
|
rc = ScepUpdateLocalAccountName(
|
|
hProfile,
|
|
L"newadministratorname",
|
|
pInfo->NewAdministratorName
|
|
);
|
|
|
|
if ( SCESTATUS_SUCCESS == rc ) {
|
|
|
|
//
|
|
// new guest name
|
|
//
|
|
rc = ScepUpdateLocalAccountName(
|
|
hProfile,
|
|
L"newguestname",
|
|
pInfo->NewGuestName
|
|
);
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if ( pBufScep == NULL || pBufSap == NULL ) {
|
|
return(SCESTATUS_INVALID_PARAMETER);
|
|
}
|
|
|
|
rc = ScepUpdateFixValueSection(
|
|
hProfile,
|
|
pInfo,
|
|
pBufScep,
|
|
pBufSap,
|
|
AccessLookup,
|
|
cAccess,
|
|
szSystemAccess,
|
|
&hSectionSmp,
|
|
&hSectionSap
|
|
);
|
|
|
|
if ( rc == SCESTATUS_SUCCESS ) {
|
|
//
|
|
// new admin name
|
|
//
|
|
rc = ScepUpdateAccountName(
|
|
hSectionSmp,
|
|
hSectionSap,
|
|
L"newadministratorname",
|
|
pInfo->NewAdministratorName,
|
|
pBufScep->NewAdministratorName,
|
|
pBufSap->NewAdministratorName
|
|
);
|
|
|
|
if ( SCESTATUS_SUCCESS == rc ) {
|
|
|
|
//
|
|
// new guest name
|
|
//
|
|
rc = ScepUpdateAccountName(
|
|
hSectionSmp,
|
|
hSectionSap,
|
|
L"newguestname",
|
|
pInfo->NewGuestName,
|
|
pBufScep->NewGuestName,
|
|
pBufSap->NewGuestName
|
|
);
|
|
}
|
|
|
|
SceJetCloseSection(&hSectionSap, TRUE);
|
|
SceJetCloseSection(&hSectionSmp, TRUE);
|
|
}
|
|
}
|
|
|
|
return(rc);
|
|
|
|
}
|
|
|
|
|
|
SCESTATUS
|
|
ScepUpdateAccountName(
|
|
IN PSCESECTION hSectionSmp,
|
|
IN PSCESECTION hSectionSap,
|
|
IN PCWSTR KeyName,
|
|
IN PWSTR NewName OPTIONAL,
|
|
IN PWSTR SmpName OPTIONAL,
|
|
IN PWSTR SapName OPTIONAL
|
|
)
|
|
/*
|
|
Routine Description:
|
|
|
|
Update or delete Administrator and/or guest name
|
|
|
|
Arguements:
|
|
|
|
hSectionSmp - the SMP section context
|
|
|
|
hSectionSap - the SAP section context
|
|
|
|
KeyName - the key name where this account name is stored
|
|
|
|
NewName - new name to change to, if NULL, the key is deleted
|
|
|
|
SmpName - the old name in SMP buffer
|
|
|
|
SapName - the analyzed name in SAP buffer
|
|
|
|
Return Value:
|
|
|
|
SCESTATUS
|
|
*/
|
|
{
|
|
DWORD LenNew=0, LenSmp=0, LenSap=0;
|
|
SCESTATUS rc=SCESTATUS_SUCCESS;
|
|
|
|
if ( !hSectionSmp || !hSectionSap || !KeyName ) {
|
|
return(SCESTATUS_INVALID_PARAMETER);
|
|
}
|
|
|
|
if ( NewName )
|
|
LenNew = wcslen(NewName);
|
|
|
|
if ( SmpName )
|
|
LenSmp = wcslen(SmpName);
|
|
|
|
if ( SapName )
|
|
LenSap = wcslen(SapName);
|
|
|
|
|
|
if ( LenSap > 0 ) {
|
|
//
|
|
// old status is mismatch for this item
|
|
//
|
|
if ( LenNew > 0 && _wcsicmp(NewName, SapName) == 0 ) {
|
|
//
|
|
// now it is matched, delete the SAP entry
|
|
//
|
|
rc = SceJetDelete(
|
|
hSectionSap,
|
|
(PWSTR)KeyName,
|
|
FALSE,
|
|
SCEJET_DELETE_LINE
|
|
);
|
|
}
|
|
//
|
|
// update SMP entry
|
|
//
|
|
if ( !LenNew ) {
|
|
//
|
|
// delete the SMP entry
|
|
//
|
|
rc = SceJetDelete(
|
|
hSectionSmp,
|
|
(PWSTR)KeyName,
|
|
FALSE,
|
|
SCEJET_DELETE_LINE
|
|
);
|
|
} else {
|
|
//
|
|
// update it
|
|
//
|
|
rc = SceJetSetLine(
|
|
hSectionSmp,
|
|
(PWSTR)KeyName,
|
|
TRUE,
|
|
NewName,
|
|
LenNew*sizeof(WCHAR),
|
|
0
|
|
);
|
|
}
|
|
|
|
} else {
|
|
//
|
|
// old status is match
|
|
//
|
|
if ( LenNew != LenSmp ||
|
|
( LenNew > 0 && _wcsicmp(NewName, SmpName) != 0 ) ) {
|
|
//
|
|
// mismatch should be raised with pBufScep
|
|
//
|
|
rc = SceJetSetLine(
|
|
hSectionSap,
|
|
(PWSTR)KeyName,
|
|
TRUE,
|
|
SmpName,
|
|
LenSmp*sizeof(WCHAR),
|
|
0
|
|
);
|
|
|
|
if ( !LenNew ) {
|
|
//
|
|
// delete SMP
|
|
//
|
|
rc = SceJetDelete(
|
|
hSectionSmp,
|
|
(PWSTR)KeyName,
|
|
FALSE,
|
|
SCEJET_DELETE_LINE
|
|
);
|
|
} else {
|
|
//
|
|
// update SMP
|
|
//
|
|
rc = SceJetSetLine(
|
|
hSectionSmp,
|
|
(PWSTR)KeyName,
|
|
TRUE,
|
|
NewName,
|
|
LenNew*sizeof(WCHAR),
|
|
0
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( SCESTATUS_RECORD_NOT_FOUND == rc ) {
|
|
rc = SCESTATUS_SUCCESS;
|
|
}
|
|
|
|
return(rc);
|
|
}
|
|
|
|
|
|
SCESTATUS
|
|
ScepUpdateLocalAccountName(
|
|
IN PSCECONTEXT hProfile,
|
|
IN PCWSTR KeyName,
|
|
IN PWSTR NewName OPTIONAL
|
|
)
|
|
/*
|
|
Routine Description:
|
|
|
|
Update or delete Administrator and/or guest name
|
|
|
|
Arguements:
|
|
|
|
KeyName - the key name where this account name is stored
|
|
|
|
NewName - new name to change to, if NULL, the key is deleted
|
|
|
|
Return Value:
|
|
|
|
SCESTATUS
|
|
*/
|
|
{
|
|
DWORD LenNew=0;
|
|
SCESTATUS rc=SCESTATUS_SUCCESS;
|
|
|
|
if ( !KeyName ) {
|
|
return(SCESTATUS_INVALID_PARAMETER);
|
|
}
|
|
|
|
if ( NewName )
|
|
LenNew = wcslen(NewName);
|
|
|
|
//
|
|
// open local policy section
|
|
//
|
|
PSCESECTION hSectionSmp=NULL;
|
|
|
|
rc = ScepOpenSectionForName(
|
|
hProfile,
|
|
SCE_ENGINE_SMP,
|
|
szSystemAccess,
|
|
&hSectionSmp
|
|
);
|
|
|
|
if ( rc != SCESTATUS_SUCCESS ) {
|
|
return(rc);
|
|
}
|
|
|
|
if ( LenNew > 0 ) {
|
|
//
|
|
// there is a new name to set
|
|
//
|
|
rc = SceJetSetLine(
|
|
hSectionSmp,
|
|
(PWSTR)KeyName,
|
|
TRUE,
|
|
NewName,
|
|
LenNew*sizeof(WCHAR),
|
|
0
|
|
);
|
|
} else {
|
|
//
|
|
// no name to set, delete it
|
|
//
|
|
rc = SceJetDelete(
|
|
hSectionSmp,
|
|
(PWSTR)KeyName,
|
|
FALSE,
|
|
SCEJET_DELETE_LINE
|
|
);
|
|
}
|
|
|
|
if ( SCESTATUS_RECORD_NOT_FOUND == rc ) {
|
|
rc = SCESTATUS_SUCCESS;
|
|
}
|
|
|
|
SceJetCloseSection(&hSectionSmp, TRUE);
|
|
|
|
return(rc);
|
|
}
|
|
|
|
|
|
SCESTATUS
|
|
ScepUpdateSystemAuditing(
|
|
IN PSCECONTEXT hProfile,
|
|
IN PSCE_PROFILE_INFO pInfo,
|
|
IN PSCE_PROFILE_INFO pBufScep OPTIONAL,
|
|
IN PSCE_PROFILE_INFO pBufSap OPTIONAL,
|
|
IN DWORD dwMode
|
|
)
|
|
/*
|
|
Routine Description:
|
|
|
|
Update system auditing section
|
|
|
|
Arguements:
|
|
|
|
hProfile - the jet database handle
|
|
|
|
pInfo - the changed info buffer
|
|
|
|
pBufScep - the original SMP buffer
|
|
|
|
pBufSap - the SAP buffer
|
|
|
|
Return Value:
|
|
|
|
SCESTATUS
|
|
*/
|
|
{
|
|
SCE_KEY_LOOKUP EventKeys[]={
|
|
{(PWSTR)TEXT("AuditSystemEvents"), offsetof(struct _SCE_PROFILE_INFO, AuditSystemEvents), 'D'},
|
|
{(PWSTR)TEXT("AuditLogonEvents"), offsetof(struct _SCE_PROFILE_INFO, AuditLogonEvents), 'D'},
|
|
{(PWSTR)TEXT("AuditObjectAccess"), offsetof(struct _SCE_PROFILE_INFO, AuditObjectAccess), 'D'},
|
|
{(PWSTR)TEXT("AuditPrivilegeUse"), offsetof(struct _SCE_PROFILE_INFO, AuditPrivilegeUse), 'D'},
|
|
{(PWSTR)TEXT("AuditPolicyChange"), offsetof(struct _SCE_PROFILE_INFO, AuditPolicyChange), 'D'},
|
|
{(PWSTR)TEXT("AuditAccountManage"), offsetof(struct _SCE_PROFILE_INFO, AuditAccountManage), 'D'},
|
|
{(PWSTR)TEXT("AuditProcessTracking"),offsetof(struct _SCE_PROFILE_INFO, AuditProcessTracking),'D'},
|
|
{(PWSTR)TEXT("AuditDSAccess"), offsetof(struct _SCE_PROFILE_INFO, AuditDSAccess), 'D'},
|
|
{(PWSTR)TEXT("AuditAccountLogon"), offsetof(struct _SCE_PROFILE_INFO, AuditAccountLogon), 'D'}};
|
|
|
|
DWORD cKeys = sizeof(EventKeys) / sizeof(SCE_KEY_LOOKUP);
|
|
|
|
|
|
if ( hProfile == NULL || pInfo == NULL ) {
|
|
return(SCESTATUS_INVALID_PARAMETER);
|
|
}
|
|
|
|
SCESTATUS rc;
|
|
|
|
if ( dwMode & SCE_UPDATE_LOCAL_POLICY ) {
|
|
//
|
|
// update local policy table only
|
|
//
|
|
|
|
rc = ScepUpdateLocalSection(
|
|
hProfile,
|
|
pInfo,
|
|
EventKeys,
|
|
cKeys,
|
|
szAuditEvent,
|
|
dwMode
|
|
);
|
|
|
|
} else {
|
|
|
|
if ( pBufScep == NULL || pBufSap == NULL ) {
|
|
return(SCESTATUS_INVALID_PARAMETER);
|
|
}
|
|
|
|
rc = ScepUpdateFixValueSection(
|
|
hProfile,
|
|
pInfo,
|
|
pBufScep,
|
|
pBufSap,
|
|
EventKeys,
|
|
cKeys,
|
|
szAuditEvent,
|
|
NULL,
|
|
NULL
|
|
);
|
|
}
|
|
|
|
return rc;
|
|
}
|
|
|
|
|
|
SCESTATUS
|
|
ScepUpdateLogs(
|
|
IN PSCECONTEXT hProfile,
|
|
IN PSCE_PROFILE_INFO pInfo,
|
|
IN PSCE_PROFILE_INFO pBufScep OPTIONAL,
|
|
IN PSCE_PROFILE_INFO pBufSap OPTIONAL,
|
|
IN DWORD dwMode
|
|
)
|
|
/*
|
|
Routine Description:
|
|
|
|
Update event log sections
|
|
|
|
Arguements:
|
|
|
|
hProfile - the jet database handle
|
|
|
|
pInfo - the changed info buffer
|
|
|
|
pBufScep - the original SMP buffer
|
|
|
|
pBufSap - the SAP buffer
|
|
|
|
Return Value:
|
|
|
|
SCESTATUS
|
|
*/
|
|
{
|
|
SCE_KEY_LOOKUP LogKeys[]={
|
|
{(PWSTR)TEXT("MaximumLogSize"), offsetof(struct _SCE_PROFILE_INFO, MaximumLogSize), 'D'},
|
|
{(PWSTR)TEXT("AuditLogRetentionPeriod"),offsetof(struct _SCE_PROFILE_INFO, AuditLogRetentionPeriod), 'D'},
|
|
{(PWSTR)TEXT("RetentionDays"), offsetof(struct _SCE_PROFILE_INFO, RetentionDays), 'D'},
|
|
{(PWSTR)TEXT("RestrictGuestAccess"), offsetof(struct _SCE_PROFILE_INFO, RestrictGuestAccess), 'D'}
|
|
};
|
|
|
|
DWORD cKeys = sizeof(LogKeys) / sizeof(SCE_KEY_LOOKUP);
|
|
|
|
SCESTATUS rc;
|
|
DWORD i, j;
|
|
PCWSTR szAuditLog=NULL;
|
|
|
|
if ( hProfile == NULL || pInfo == NULL ) {
|
|
return(SCESTATUS_INVALID_PARAMETER);
|
|
}
|
|
|
|
if ( !(dwMode & SCE_UPDATE_LOCAL_POLICY) ) {
|
|
if ( pBufScep == NULL || pBufSap == NULL ) {
|
|
return(SCESTATUS_INVALID_PARAMETER);
|
|
}
|
|
}
|
|
|
|
for ( i=0; i<3; i++) {
|
|
|
|
//
|
|
// Get Event Log setting for system log, security log and application log
|
|
//
|
|
|
|
switch (i) {
|
|
case 0:
|
|
szAuditLog = szAuditSystemLog;
|
|
break;
|
|
case 1:
|
|
szAuditLog = szAuditSecurityLog;
|
|
break;
|
|
default:
|
|
szAuditLog = szAuditApplicationLog;
|
|
break;
|
|
}
|
|
|
|
if ( dwMode & SCE_UPDATE_LOCAL_POLICY ) {
|
|
|
|
//
|
|
// update local policy table only
|
|
//
|
|
|
|
rc = ScepUpdateLocalSection(
|
|
hProfile,
|
|
pInfo,
|
|
LogKeys,
|
|
4,
|
|
szAuditLog,
|
|
dwMode
|
|
);
|
|
|
|
} else {
|
|
|
|
//
|
|
// get DWORD values for the section
|
|
//
|
|
rc = ScepUpdateFixValueSection(
|
|
hProfile,
|
|
pInfo,
|
|
pBufScep,
|
|
pBufSap,
|
|
LogKeys,
|
|
4,
|
|
szAuditLog,
|
|
NULL,
|
|
NULL
|
|
);
|
|
}
|
|
|
|
if ( rc != SCESTATUS_SUCCESS )
|
|
break;
|
|
|
|
//
|
|
// update the Offset for next section
|
|
//
|
|
for ( j=0; j<4; j++ )
|
|
LogKeys[j].Offset += sizeof(DWORD);
|
|
}
|
|
|
|
return(rc);
|
|
}
|
|
|
|
SCESTATUS
|
|
ScepUpdateKerberos(
|
|
IN PSCECONTEXT hProfile,
|
|
IN PSCE_KERBEROS_TICKET_INFO pInfo,
|
|
IN PSCE_KERBEROS_TICKET_INFO pBufScep OPTIONAL,
|
|
IN PSCE_KERBEROS_TICKET_INFO pBufSap OPTIONAL,
|
|
IN DWORD dwMode
|
|
)
|
|
{
|
|
SCESTATUS rc;
|
|
SCE_KEY_LOOKUP KerberosKeys[]={
|
|
{(PWSTR)TEXT("MaxTicketAge"), offsetof(struct _SCE_KERBEROS_TICKET_INFO_, MaxTicketAge), 'D'},
|
|
{(PWSTR)TEXT("MaxRenewAge"), offsetof(struct _SCE_KERBEROS_TICKET_INFO_, MaxRenewAge), 'D'},
|
|
{(PWSTR)TEXT("MaxServiceAge"), offsetof(struct _SCE_KERBEROS_TICKET_INFO_, MaxServiceAge), 'D'},
|
|
{(PWSTR)TEXT("MaxClockSkew"), offsetof(struct _SCE_KERBEROS_TICKET_INFO_, MaxClockSkew), 'D'},
|
|
{(PWSTR)TEXT("TicketValidateClient"), offsetof(struct _SCE_KERBEROS_TICKET_INFO_, TicketValidateClient), 'D'}
|
|
};
|
|
|
|
DWORD cKeys = sizeof(KerberosKeys) / sizeof(SCE_KEY_LOOKUP);
|
|
SCE_KERBEROS_TICKET_INFO tmpBuf;
|
|
|
|
if ( !pInfo ) {
|
|
return(SCESTATUS_SUCCESS);
|
|
}
|
|
|
|
if ( dwMode & SCE_UPDATE_LOCAL_POLICY ) {
|
|
|
|
rc = ScepUpdateLocalSection(
|
|
hProfile,
|
|
(PSCE_PROFILE_INFO)pInfo,
|
|
KerberosKeys,
|
|
cKeys,
|
|
szKerberosPolicy,
|
|
dwMode
|
|
);
|
|
|
|
} else {
|
|
|
|
if ( !pBufScep || !pBufSap ) {
|
|
//
|
|
// if SMP or SAP buffer is NULL
|
|
//
|
|
tmpBuf.MaxTicketAge = SCE_NO_VALUE;
|
|
tmpBuf.MaxRenewAge = SCE_NO_VALUE;
|
|
tmpBuf.MaxServiceAge = SCE_NO_VALUE;
|
|
tmpBuf.MaxClockSkew = SCE_NO_VALUE;
|
|
tmpBuf.TicketValidateClient = SCE_NO_VALUE;
|
|
}
|
|
|
|
//
|
|
// get DWORD values for the section
|
|
//
|
|
rc = ScepUpdateFixValueSection(
|
|
hProfile,
|
|
(PSCE_PROFILE_INFO)pInfo,
|
|
pBufScep ? (PSCE_PROFILE_INFO)pBufScep : (PSCE_PROFILE_INFO)&tmpBuf,
|
|
pBufSap ? (PSCE_PROFILE_INFO)pBufSap : (PSCE_PROFILE_INFO)&tmpBuf,
|
|
KerberosKeys,
|
|
cKeys,
|
|
szKerberosPolicy,
|
|
NULL,
|
|
NULL
|
|
);
|
|
}
|
|
|
|
return(rc);
|
|
}
|
|
|
|
|
|
SCESTATUS
|
|
ScepUpdateFixValueSection(
|
|
IN PSCECONTEXT hProfile,
|
|
IN PSCE_PROFILE_INFO pInfo,
|
|
IN PSCE_PROFILE_INFO pBufScep,
|
|
IN PSCE_PROFILE_INFO pBufSap,
|
|
IN SCE_KEY_LOOKUP *Keys,
|
|
IN DWORD cKeys,
|
|
IN PCWSTR SectionName,
|
|
OUT PSCESECTION *hSecScep OPTIONAL,
|
|
OUT PSCESECTION *hSecSap OPTIONAL
|
|
)
|
|
/*
|
|
Routine Description:
|
|
|
|
Update each key in the Keys array based on the editing rule. SMP entry is
|
|
updated with the new value. SAP entry is either deleted, or created, depending
|
|
on the new computed analysis status.
|
|
|
|
Arguements:
|
|
|
|
hProfile - the jet database handle
|
|
|
|
pInfo - the changed info buffer
|
|
|
|
pBufScep - the original SMP buffer
|
|
|
|
pBufSap - the SAP buffer
|
|
|
|
Keys - the lookup keys array
|
|
|
|
cKeys - the number of keys in the array
|
|
|
|
SecitonName - the section name to work on
|
|
|
|
hSecScep - the section context handle in SMP to output
|
|
|
|
hSecSap - the section context handle in SAP to output
|
|
|
|
Return Value:
|
|
|
|
SCESTATUS
|
|
*/
|
|
{
|
|
|
|
SCESTATUS rc;
|
|
PSCESECTION hSectionSmp=NULL;
|
|
PSCESECTION hSectionSap=NULL;
|
|
|
|
DWORD i;
|
|
UINT Offset;
|
|
DWORD valScep, valSap, valNewScep;
|
|
|
|
|
|
|
|
//
|
|
// open smp section for system access
|
|
//
|
|
rc = ScepOpenSectionForName(
|
|
hProfile,
|
|
SCE_ENGINE_SMP,
|
|
SectionName,
|
|
&hSectionSmp
|
|
);
|
|
|
|
if ( rc == SCESTATUS_SUCCESS ) {
|
|
|
|
//
|
|
// open sap section for system access
|
|
//
|
|
rc = ScepOpenSectionForName(
|
|
hProfile,
|
|
SCE_ENGINE_SAP,
|
|
SectionName,
|
|
&hSectionSap
|
|
);
|
|
|
|
if ( rc == SCESTATUS_SUCCESS) {
|
|
|
|
for ( i=0; i<cKeys; i++) {
|
|
|
|
//
|
|
// get settings in AccessLookup table
|
|
//
|
|
|
|
Offset = Keys[i].Offset;
|
|
|
|
switch ( Keys[i].BufferType ) {
|
|
case 'B':
|
|
break;
|
|
|
|
case 'D': {
|
|
|
|
valScep = *((DWORD *)((CHAR *)pBufScep+Offset));
|
|
valSap = *((DWORD *)((CHAR *)pBufSap+Offset));
|
|
valNewScep = *((DWORD *)((CHAR *)pInfo+Offset));
|
|
|
|
switch ( valSap ) {
|
|
case SCE_NO_VALUE:
|
|
|
|
//
|
|
// old status is match
|
|
//
|
|
if ( valNewScep != valScep ) {
|
|
//
|
|
// mismatch should be raised with valScep
|
|
//
|
|
rc = ScepCompareAndSaveIntValue(
|
|
hSectionSap,
|
|
Keys[i].KeyString,
|
|
FALSE,
|
|
SCE_NO_VALUE,
|
|
(valScep != SCE_NO_VALUE ) ? valScep : SCE_NOT_ANALYZED_VALUE
|
|
);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case SCE_ERROR_VALUE:
|
|
case SCE_NOT_ANALYZED_VALUE:
|
|
//
|
|
// old status is error when analyzing so we don't know the
|
|
// status of this one (yet), or
|
|
// this is an item that was added after analyzing
|
|
//
|
|
// do not change SAP table
|
|
//
|
|
break;
|
|
|
|
default:
|
|
//
|
|
// old status is mismatch for this item
|
|
//
|
|
if ( valNewScep == valSap ) {
|
|
//
|
|
// now it is matched, delete the SAP entry
|
|
//
|
|
rc = SceJetDelete(
|
|
hSectionSap,
|
|
Keys[i].KeyString,
|
|
FALSE,
|
|
SCEJET_DELETE_LINE_NO_CASE
|
|
);
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
//
|
|
// update SMP entry
|
|
//
|
|
if ( valNewScep != valScep ) {
|
|
|
|
if ( valNewScep == SCE_NO_VALUE ) {
|
|
//
|
|
// delete Scep
|
|
//
|
|
rc = SceJetDelete(
|
|
hSectionSmp,
|
|
Keys[i].KeyString,
|
|
FALSE,
|
|
SCEJET_DELETE_LINE_NO_CASE
|
|
);
|
|
} else {
|
|
//
|
|
// update SMP
|
|
//
|
|
rc = ScepCompareAndSaveIntValue(
|
|
hSectionSmp,
|
|
Keys[i].KeyString,
|
|
FALSE,
|
|
SCE_NO_VALUE,
|
|
valNewScep
|
|
);
|
|
}
|
|
}
|
|
|
|
if ( rc == SCESTATUS_RECORD_NOT_FOUND ) {
|
|
//
|
|
// if not find for delete, ignore the error
|
|
//
|
|
rc = SCESTATUS_SUCCESS;
|
|
}
|
|
break;
|
|
}
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
if ( rc != SCESTATUS_SUCCESS ) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
// return the section handle if asked, else free it
|
|
//
|
|
if ( hSecSap != NULL )
|
|
*hSecSap = hSectionSap;
|
|
else
|
|
SceJetCloseSection(&hSectionSap, TRUE);
|
|
}
|
|
|
|
//
|
|
// return the section handle if asked, else free it
|
|
//
|
|
if ( hSecScep != NULL )
|
|
*hSecScep = hSectionSmp;
|
|
else
|
|
SceJetCloseSection(&hSectionSmp, TRUE);
|
|
}
|
|
|
|
return(rc);
|
|
|
|
}
|
|
|
|
SCESTATUS
|
|
ScepUpdateRegistryValues(
|
|
IN PSCECONTEXT hProfile,
|
|
IN PSCE_PROFILE_INFO pInfo,
|
|
IN PSCE_PROFILE_INFO pBufScep,
|
|
IN PSCE_PROFILE_INFO pBufSap
|
|
)
|
|
{
|
|
SCESTATUS rc;
|
|
PSCESECTION hSectionSmp=NULL;
|
|
PSCESECTION hSectionSap=NULL;
|
|
PWSTR valScep, valSap, valNewScep;
|
|
DWORD i,j,k,status;
|
|
|
|
if ( pInfo->RegValueCount == 0 ||
|
|
pInfo->aRegValues == NULL ) {
|
|
//
|
|
// impossible to have a empty buffer to update
|
|
// this buffer should contain all available registry values to configure/analyze
|
|
//
|
|
return(SCESTATUS_SUCCESS);
|
|
}
|
|
|
|
if ( (pBufScep->RegValueCount != 0 && pBufScep->aRegValues == NULL) ||
|
|
(pBufSap->RegValueCount != 0 && pBufSap->aRegValues == NULL) ) {
|
|
return(SCESTATUS_INVALID_PARAMETER);
|
|
}
|
|
|
|
//
|
|
// open smp section for system access
|
|
//
|
|
rc = ScepOpenSectionForName(
|
|
hProfile,
|
|
SCE_ENGINE_SMP,
|
|
szRegistryValues,
|
|
&hSectionSmp
|
|
);
|
|
|
|
if ( rc == SCESTATUS_SUCCESS ) {
|
|
|
|
//
|
|
// open sap section for system access
|
|
//
|
|
rc = ScepOpenSectionForName(
|
|
hProfile,
|
|
SCE_ENGINE_SAP,
|
|
szRegistryValues,
|
|
&hSectionSap
|
|
);
|
|
|
|
if ( rc == SCESTATUS_SUCCESS) {
|
|
|
|
for (i=0; i<pInfo->RegValueCount; i++ ) {
|
|
|
|
if ( !(pInfo->aRegValues[i].FullValueName) ) {
|
|
continue;
|
|
}
|
|
//
|
|
// find SMP match
|
|
//
|
|
for ( j=0; j<pBufScep->RegValueCount; j++ ) {
|
|
if ( pBufScep->aRegValues[j].FullValueName &&
|
|
_wcsicmp(pInfo->aRegValues[i].FullValueName,
|
|
pBufScep->aRegValues[j].FullValueName) == 0 ) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
// find SAP match
|
|
//
|
|
for ( k=0; k<pBufSap->RegValueCount; k++ ) {
|
|
if ( pBufSap->aRegValues[k].FullValueName &&
|
|
_wcsicmp(pInfo->aRegValues[i].FullValueName,
|
|
pBufSap->aRegValues[k].FullValueName) == 0 ) {
|
|
break;
|
|
}
|
|
}
|
|
//
|
|
// find old configuration
|
|
//
|
|
if ( j < pBufScep->RegValueCount ) {
|
|
valScep = pBufScep->aRegValues[j].Value;
|
|
} else {
|
|
valScep = NULL;
|
|
}
|
|
|
|
//
|
|
// find analysis value and status
|
|
//
|
|
if ( k < pBufSap->RegValueCount ) {
|
|
valSap = pBufSap->aRegValues[k].Value;
|
|
status = pBufSap->aRegValues[k].Status;
|
|
} else {
|
|
valSap = NULL;
|
|
if ( valScep ) {
|
|
status = SCE_STATUS_GOOD;
|
|
} else {
|
|
status = SCE_STATUS_NOT_CONFIGURED;
|
|
}
|
|
}
|
|
|
|
valNewScep = pInfo->aRegValues[i].Value;
|
|
|
|
if ( status == SCE_STATUS_NOT_ANALYZED ||
|
|
status == SCE_STATUS_ERROR_NOT_AVAILABLE ) {
|
|
//
|
|
// do not change SAP
|
|
//
|
|
} else {
|
|
|
|
if ( valSap ) {
|
|
//
|
|
// mismatched
|
|
//
|
|
if ( valNewScep && _wcsicmp(valNewScep, valSap) == 0 ) {
|
|
//
|
|
// now it is matched, delete the SAP entry
|
|
//
|
|
rc = SceJetDelete(
|
|
hSectionSap,
|
|
pInfo->aRegValues[i].FullValueName,
|
|
FALSE,
|
|
SCEJET_DELETE_LINE_NO_CASE
|
|
);
|
|
}
|
|
} else {
|
|
if ( valScep ) {
|
|
//
|
|
// was a matched item
|
|
//
|
|
if (valNewScep && _wcsicmp(valNewScep, valScep) != 0 ) {
|
|
//
|
|
// mismatched
|
|
//
|
|
rc = ScepSaveRegValueEntry(
|
|
hSectionSap,
|
|
pInfo->aRegValues[i].FullValueName,
|
|
valScep,
|
|
pInfo->aRegValues[i].ValueType,
|
|
SCE_STATUS_MISMATCH
|
|
);
|
|
}
|
|
} else {
|
|
//
|
|
// was a not configure/not analyze item
|
|
//
|
|
rc = ScepSaveRegValueEntry(
|
|
hSectionSap,
|
|
pInfo->aRegValues[i].FullValueName,
|
|
NULL,
|
|
pInfo->aRegValues[i].ValueType,
|
|
SCE_STATUS_NOT_ANALYZED
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( !valNewScep ) {
|
|
//
|
|
// delete Scep
|
|
//
|
|
rc = SceJetDelete(
|
|
hSectionSmp,
|
|
pInfo->aRegValues[i].FullValueName,
|
|
FALSE,
|
|
SCEJET_DELETE_LINE_NO_CASE
|
|
);
|
|
} else {
|
|
//
|
|
// update SMP
|
|
//
|
|
rc = ScepSaveRegValueEntry(
|
|
hSectionSmp,
|
|
pInfo->aRegValues[i].FullValueName,
|
|
valNewScep,
|
|
pInfo->aRegValues[i].ValueType,
|
|
0
|
|
);
|
|
}
|
|
|
|
if ( rc == SCESTATUS_RECORD_NOT_FOUND ) {
|
|
//
|
|
// if not find for delete, ignore the error
|
|
//
|
|
rc = SCESTATUS_SUCCESS;
|
|
}
|
|
|
|
if ( SCESTATUS_SUCCESS != rc ) {
|
|
break;
|
|
}
|
|
|
|
}
|
|
|
|
SceJetCloseSection(&hSectionSap, TRUE);
|
|
}
|
|
SceJetCloseSection(&hSectionSmp, TRUE);
|
|
}
|
|
|
|
return(rc);
|
|
}
|
|
|
|
|
|
SCESTATUS
|
|
ScepSaveRegValueEntry(
|
|
IN PSCESECTION hSection,
|
|
IN PWSTR Name,
|
|
IN PWSTR CurrentValue,
|
|
IN DWORD dType,
|
|
IN DWORD Status
|
|
)
|
|
/* ++
|
|
Routine Description:
|
|
|
|
|
|
Arguments:
|
|
|
|
hSection - The JET section context
|
|
|
|
Name - The entry name
|
|
|
|
CurrentValue - The current system setting (DWORD value)
|
|
|
|
dType - the registry value type
|
|
|
|
Return Value:
|
|
|
|
SCESTATUS_SUCCESS
|
|
SCESTATUS_INVALID_PARAMETER
|
|
SCESTATUS returned from SceJetSetLine
|
|
|
|
-- */
|
|
{
|
|
SCESTATUS rc;
|
|
PWSTR StrValue;
|
|
DWORD Len=0;
|
|
|
|
if ( Name == NULL )
|
|
return(SCESTATUS_INVALID_PARAMETER);
|
|
|
|
|
|
if ( CurrentValue == NULL && Status == 0 ) {
|
|
//
|
|
// delete this entry
|
|
//
|
|
rc = SceJetDelete( hSection,
|
|
Name,
|
|
FALSE,
|
|
SCEJET_DELETE_LINE_NO_CASE);
|
|
return (rc);
|
|
}
|
|
|
|
//
|
|
// update this entry
|
|
//
|
|
|
|
if ( CurrentValue ) {
|
|
Len = wcslen(CurrentValue);
|
|
}
|
|
|
|
StrValue = (PWSTR)ScepAlloc(0, (Len+4)*sizeof(WCHAR));
|
|
|
|
if ( StrValue ) {
|
|
|
|
*((CHAR *)StrValue) = (BYTE)(dType % 10) + '0';
|
|
*((CHAR *)StrValue+1) = (BYTE)Status + '0';
|
|
|
|
// swprintf(StrValue, L"%1d", dType);
|
|
StrValue[1] = L'\0';
|
|
|
|
if ( CurrentValue ) {
|
|
|
|
// there are binary data here
|
|
memcpy(StrValue+2, CurrentValue, Len*2);
|
|
}
|
|
StrValue[Len+2] = L'\0';
|
|
StrValue[Len+3] = L'\0';
|
|
|
|
if ( REG_MULTI_SZ == dType ) {
|
|
//
|
|
// convert the , to null
|
|
//
|
|
ScepConvertMultiSzToDelim(StrValue+2, Len+1, L',', L'\0');
|
|
|
|
}
|
|
rc = SceJetSetLine( hSection, Name, FALSE, StrValue, (Len+3)*2, 0);
|
|
|
|
ScepFree(StrValue);
|
|
|
|
} else {
|
|
rc = SCESTATUS_NOT_ENOUGH_RESOURCE;
|
|
}
|
|
|
|
return(rc);
|
|
|
|
}
|
|
|
|
|
|
SCESTATUS
|
|
ScepUpdatePrivileges(
|
|
IN PSCECONTEXT hProfile,
|
|
IN PSCE_PRIVILEGE_ASSIGNMENT pNewPriv,
|
|
IN PSCE_PRIVILEGE_ASSIGNMENT *pScepPriv
|
|
)
|
|
/*
|
|
Routine Description:
|
|
|
|
Update privileges
|
|
|
|
Arguements:
|
|
|
|
hProfile - the jet database handle
|
|
|
|
pNewPriv - the changed info buffer
|
|
|
|
pBufScep - the original SMP priv buffer
|
|
|
|
Return Value:
|
|
|
|
SCESTATUS
|
|
*/
|
|
{
|
|
SCESTATUS rc;
|
|
PSCESECTION hSectionSmp=NULL;
|
|
PSCESECTION hSectionSap=NULL;
|
|
PSCE_PRIVILEGE_ASSIGNMENT pPriv, pNode, pParent;
|
|
DWORD NameLen;
|
|
|
|
|
|
if ( pScepPriv == NULL ) {
|
|
return(SCESTATUS_INVALID_PARAMETER);
|
|
}
|
|
|
|
if ( pNewPriv == NULL && *pScepPriv == NULL ) {
|
|
return(SCESTATUS_SUCCESS);
|
|
}
|
|
|
|
LSA_HANDLE LsaHandle=NULL;
|
|
|
|
rc = RtlNtStatusToDosError(
|
|
ScepOpenLsaPolicy(
|
|
MAXIMUM_ALLOWED,
|
|
&LsaHandle,
|
|
TRUE
|
|
));
|
|
|
|
if ( ERROR_SUCCESS != rc ) {
|
|
return(ScepDosErrorToSceStatus(rc));
|
|
}
|
|
|
|
//
|
|
// open smp section for system access
|
|
//
|
|
rc = ScepOpenSectionForName(
|
|
hProfile,
|
|
SCE_ENGINE_SMP,
|
|
szPrivilegeRights,
|
|
&hSectionSmp
|
|
);
|
|
|
|
if ( rc == SCESTATUS_SUCCESS ) {
|
|
|
|
//
|
|
// open sap section for system access
|
|
//
|
|
rc = ScepOpenSectionForName(
|
|
hProfile,
|
|
SCE_ENGINE_SAP,
|
|
szPrivilegeRights,
|
|
&hSectionSap
|
|
);
|
|
|
|
if ( rc == SCESTATUS_SUCCESS ) {
|
|
|
|
//
|
|
// convert pNewPriv to Name/*SID format (from all name format)
|
|
//
|
|
PSCE_PRIVILEGE_ASSIGNMENT pConvertedPriv=NULL;
|
|
|
|
rc = ScepConvertPrivilegeList(LsaHandle,
|
|
pNewPriv,
|
|
0,
|
|
SCE_ACCOUNT_SID_STRING,
|
|
&pConvertedPriv);
|
|
|
|
if ( ERROR_SUCCESS != rc ) {
|
|
//
|
|
// use the original list
|
|
//
|
|
pPriv = pNewPriv;
|
|
} else {
|
|
pPriv = pConvertedPriv;
|
|
}
|
|
|
|
for ( ; pPriv != NULL; pPriv = pPriv->Next ) {
|
|
//
|
|
// Process each privilege in the new list
|
|
//
|
|
if ( pPriv->Name == NULL ) {
|
|
continue;
|
|
}
|
|
NameLen = wcslen(pPriv->Name);
|
|
|
|
//
|
|
// look for the matched SMP
|
|
//
|
|
for ( pNode=*pScepPriv, pParent=NULL; pNode != NULL;
|
|
pParent = pNode, pNode = pNode->Next ) {
|
|
|
|
if ( pNode->Name == NULL ) {
|
|
continue;
|
|
}
|
|
if ( _wcsicmp(pPriv->Name, pNode->Name) == 0 ) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
rc = ScepUpdateKeyNameList(
|
|
LsaHandle,
|
|
hSectionSmp,
|
|
hSectionSap,
|
|
NULL, // not a group
|
|
( pNode == NULL ) ? FALSE : TRUE,
|
|
pPriv->Name,
|
|
NameLen,
|
|
pPriv->AssignedTo,
|
|
( pNode == NULL ) ? NULL : pNode->AssignedTo,
|
|
SCE_FLAG_UPDATE_PRIV
|
|
);
|
|
|
|
if ( rc == SCESTATUS_RECORD_NOT_FOUND ) {
|
|
rc = SCESTATUS_SUCCESS;
|
|
|
|
} else if ( rc != SCESTATUS_SUCCESS) {
|
|
break;
|
|
}
|
|
|
|
//
|
|
// remove the SMP node from pScepPriv
|
|
//
|
|
if ( pNode != NULL ) {
|
|
|
|
//
|
|
// link to the next
|
|
//
|
|
if ( pParent != NULL ) {
|
|
pParent->Next = pNode->Next;
|
|
|
|
} else {
|
|
*pScepPriv = pNode->Next;
|
|
}
|
|
//
|
|
// delete this node
|
|
//
|
|
ScepFreeNameList(pNode->AssignedTo);
|
|
ScepFree(pNode->Name);
|
|
ScepFree(pNode);
|
|
pNode = NULL;
|
|
}
|
|
}
|
|
|
|
if ( pConvertedPriv ) {
|
|
//
|
|
// free the new list
|
|
//
|
|
ScepFreePrivilege( pConvertedPriv );
|
|
pConvertedPriv = NULL;
|
|
}
|
|
|
|
//
|
|
// delete remaining SMP entries, do not care error code
|
|
//
|
|
if ( rc == SCESTATUS_SUCCESS ) {
|
|
|
|
for (pNode=*pScepPriv; pNode != NULL; pNode = pNode->Next ) {
|
|
//
|
|
// raise SAP entries first
|
|
//
|
|
if ( pNode->Name == NULL ) {
|
|
continue;
|
|
}
|
|
NameLen = wcslen(pNode->Name);
|
|
|
|
rc = SceJetSeek(
|
|
hSectionSap,
|
|
pNode->Name,
|
|
NameLen*sizeof(WCHAR),
|
|
SCEJET_SEEK_EQ_NO_CASE
|
|
);
|
|
|
|
if ( rc == SCESTATUS_RECORD_NOT_FOUND ) {
|
|
//
|
|
// pNode->AssignedTo is already in name, *SID format
|
|
// no need to convert
|
|
//
|
|
rc = ScepWriteNameListValue(
|
|
LsaHandle,
|
|
hSectionSap,
|
|
pNode->Name,
|
|
pNode->AssignedTo,
|
|
SCE_WRITE_EMPTY_LIST,
|
|
0
|
|
);
|
|
}
|
|
|
|
if ( rc == SCESTATUS_SUCCESS ) {
|
|
rc = SceJetDelete(
|
|
hSectionSmp,
|
|
pNode->Name,
|
|
FALSE,
|
|
SCEJET_DELETE_LINE_NO_CASE
|
|
);
|
|
if ( SCESTATUS_RECORD_NOT_FOUND == rc ) {
|
|
rc = SCESTATUS_SUCCESS;
|
|
}
|
|
}
|
|
if ( rc != SCESTATUS_SUCCESS ) {
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
SceJetCloseSection(&hSectionSap, TRUE);
|
|
}
|
|
|
|
SceJetCloseSection(&hSectionSmp, TRUE);
|
|
}
|
|
|
|
if ( LsaHandle ) {
|
|
LsaClose(LsaHandle);
|
|
}
|
|
|
|
return(rc);
|
|
}
|
|
|
|
|
|
|
|
SCESTATUS
|
|
ScepGetKeyNameList(
|
|
IN LSA_HANDLE LsaPolicy,
|
|
IN PSCESECTION hSection,
|
|
IN PWSTR Key,
|
|
IN DWORD KeyLen,
|
|
IN DWORD dwAccountFormat,
|
|
OUT PSCE_NAME_LIST *pNameList
|
|
)
|
|
/* ++
|
|
Routine Description:
|
|
|
|
Read multi-sz format value for the key from the section into a name list
|
|
structure
|
|
|
|
Arguments:
|
|
|
|
hSection - the section handle
|
|
|
|
Key - the key name
|
|
|
|
KeyLen - the key length
|
|
|
|
pNameList - the name list of multi-sz value
|
|
|
|
Return Value:
|
|
|
|
SCE status
|
|
|
|
-- */
|
|
{
|
|
SCESTATUS rc;
|
|
PWSTR Value=NULL;
|
|
|
|
PSCE_NAME_STATUS_LIST pPrivilegeList=NULL;
|
|
|
|
DWORD ValueLen;
|
|
DWORD Len;
|
|
PWSTR pTemp;
|
|
|
|
|
|
if ( hSection == NULL || pNameList == NULL || Key == NULL ) {
|
|
return(SCESTATUS_INVALID_PARAMETER);
|
|
}
|
|
//
|
|
// goto the key
|
|
//
|
|
rc = SceJetGetValue(
|
|
hSection,
|
|
SCEJET_EXACT_MATCH_NO_CASE,
|
|
Key,
|
|
NULL,
|
|
0,
|
|
NULL,
|
|
NULL,
|
|
0,
|
|
&ValueLen
|
|
);
|
|
|
|
if ( rc != SCESTATUS_SUCCESS ) {
|
|
return(rc);
|
|
}
|
|
|
|
//
|
|
// allocate memory for the group name and value string
|
|
//
|
|
Value = (PWSTR)ScepAlloc( LMEM_ZEROINIT, ValueLen+2);
|
|
|
|
if ( Value == NULL )
|
|
return(SCESTATUS_NOT_ENOUGH_RESOURCE);
|
|
|
|
//
|
|
// Get the group and its value
|
|
//
|
|
rc = SceJetGetValue(
|
|
hSection,
|
|
SCEJET_CURRENT,
|
|
NULL,
|
|
NULL,
|
|
0,
|
|
NULL,
|
|
Value,
|
|
ValueLen,
|
|
&ValueLen
|
|
);
|
|
|
|
if ( rc == SCESTATUS_SUCCESS ) {
|
|
|
|
//
|
|
// add the multi-sz value string to the node, depending on the value type
|
|
//
|
|
pTemp = Value;
|
|
while ( rc == SCESTATUS_SUCCESS && pTemp != NULL && pTemp[0]) {
|
|
|
|
Len = wcslen(pTemp);
|
|
|
|
if ( dwAccountFormat == 0 && pTemp[0] == L'*' ) {
|
|
//
|
|
// convert *SID to name
|
|
//
|
|
rc = ScepLookupSidStringAndAddToNameList(
|
|
LsaPolicy,
|
|
pNameList,
|
|
pTemp, // +1,
|
|
Len // -1
|
|
);
|
|
|
|
} else {
|
|
rc = ScepAddToNameList(pNameList, pTemp, Len );
|
|
|
|
}
|
|
|
|
pTemp += Len +1;
|
|
|
|
}
|
|
|
|
//
|
|
// Free the list if error
|
|
//
|
|
if ( rc != SCESTATUS_SUCCESS && *pNameList != NULL ) {
|
|
|
|
ScepFreeNameList(*pNameList);
|
|
*pNameList = NULL;
|
|
|
|
}
|
|
}
|
|
|
|
ScepFree(Value);
|
|
|
|
//
|
|
// close the find index range
|
|
//
|
|
SceJetGetValue(
|
|
hSection,
|
|
SCEJET_CLOSE_VALUE,
|
|
NULL,
|
|
NULL,
|
|
0,
|
|
NULL,
|
|
NULL,
|
|
0,
|
|
NULL
|
|
);
|
|
|
|
return(rc);
|
|
|
|
}
|
|
|
|
|
|
BYTE
|
|
ScepGetObjectAnalysisStatus(
|
|
IN PSCESECTION hSection,
|
|
IN PWSTR KeyName,
|
|
IN BOOL bLookForParent
|
|
)
|
|
/*
|
|
|
|
Routine Description:
|
|
|
|
Get analysis status for the KeyName specified. If bLookForParent is TRUE,
|
|
check for the closest parent status instead of this KeyName.
|
|
|
|
*/
|
|
{
|
|
|
|
WCHAR StatusFlag=L'\0';
|
|
BYTE Status=(BYTE)-1;
|
|
|
|
DWORD Len;
|
|
SCESTATUS rc=SCESTATUS_SUCCESS;
|
|
PWSTR Buffer=NULL, pTemp;
|
|
|
|
pTemp = KeyName;
|
|
|
|
while ( TRUE ) {
|
|
|
|
if ( bLookForParent ) {
|
|
|
|
pTemp = wcschr(pTemp, L'\\');
|
|
if ( pTemp ) {
|
|
Len = (DWORD)(pTemp-KeyName);
|
|
|
|
Buffer = (PWSTR)ScepAlloc(0, (Len+1)*sizeof(WCHAR));
|
|
if ( Buffer ) {
|
|
memcpy(Buffer, KeyName, Len*sizeof(WCHAR));
|
|
Buffer[Len] = L'\0';
|
|
} else {
|
|
// no memory
|
|
rc = SCESTATUS_NOT_ENOUGH_RESOURCE;
|
|
break;
|
|
}
|
|
} else {
|
|
Buffer = KeyName;
|
|
}
|
|
} else {
|
|
Buffer = KeyName;
|
|
}
|
|
|
|
rc = SceJetGetValue(
|
|
hSection,
|
|
SCEJET_EXACT_MATCH_NO_CASE,
|
|
Buffer,
|
|
NULL,
|
|
0,
|
|
NULL,
|
|
(PWSTR)&StatusFlag,
|
|
2,
|
|
&Len
|
|
);
|
|
if ( Buffer != KeyName ) {
|
|
ScepFree(Buffer);
|
|
Buffer = NULL;
|
|
}
|
|
|
|
if ( SCESTATUS_SUCCESS == rc ||
|
|
SCESTATUS_BUFFER_TOO_SMALL == rc ) {
|
|
//
|
|
// find the record
|
|
//
|
|
Status = *((BYTE *)&StatusFlag);
|
|
} else if ( rc != SCESTATUS_RECORD_NOT_FOUND ) {
|
|
break;
|
|
}
|
|
rc = SCESTATUS_SUCCESS;
|
|
|
|
if ( bLookForParent && pTemp ) {
|
|
pTemp++;
|
|
} else {
|
|
// the end
|
|
break;
|
|
}
|
|
}
|
|
|
|
if ( SCESTATUS_SUCCESS == rc ) {
|
|
return Status;
|
|
}
|
|
|
|
return (BYTE)-1;
|
|
|
|
}
|
|
|
|
DWORD
|
|
ScepQueryAnalysisStatus(
|
|
IN PSCESECTION hSection,
|
|
IN PWSTR KeyName,
|
|
IN DWORD NameLen
|
|
)
|
|
{
|
|
|
|
DWORD dwSapStatus = SCE_STATUS_GOOD;
|
|
|
|
SCESTATUS rc = SceJetSeek(
|
|
hSection,
|
|
KeyName,
|
|
NameLen*sizeof(WCHAR),
|
|
SCEJET_SEEK_EQ_NO_CASE
|
|
);
|
|
|
|
if ( rc == SCESTATUS_SUCCESS ) {
|
|
|
|
dwSapStatus = SCE_STATUS_MISMATCH;
|
|
|
|
//
|
|
// check if this is errored item, or not analyzed item
|
|
//
|
|
TCHAR szErrorValue[20];
|
|
DWORD ValueLen;
|
|
|
|
szErrorValue[0] = L'\0';
|
|
|
|
rc = SceJetGetValue(
|
|
hSection,
|
|
SCEJET_CURRENT,
|
|
NULL,
|
|
NULL,
|
|
0,
|
|
NULL,
|
|
szErrorValue,
|
|
20*sizeof(TCHAR),
|
|
&ValueLen
|
|
);
|
|
if ( SCESTATUS_SUCCESS == rc ||
|
|
SCESTATUS_BUFFER_TOO_SMALL == rc ) {
|
|
|
|
if ( szErrorValue[0] == L' ' ) {
|
|
dwSapStatus = SCE_STATUS_NOT_ANALYZED;
|
|
|
|
} else if ( _wcsicmp( SCE_ERROR_STRING, szErrorValue ) == 0 ) {
|
|
//
|
|
// this group is errored or not analyzed
|
|
//
|
|
dwSapStatus = SCE_STATUS_ERROR_NOT_AVAILABLE;
|
|
}
|
|
}
|
|
}
|
|
|
|
return dwSapStatus;
|
|
}
|
|
|
|
|
|
SCESTATUS
|
|
ScepUpdateKeyNameList(
|
|
IN LSA_HANDLE LsaPolicy,
|
|
IN PSCESECTION hSectionSmp,
|
|
IN PSCESECTION hSectionSap,
|
|
IN PWSTR GroupName OPTIONAL,
|
|
IN BOOL bScepExist,
|
|
IN PWSTR KeyName,
|
|
IN DWORD NameLen,
|
|
IN PSCE_NAME_LIST pNewList,
|
|
IN PSCE_NAME_LIST pScepList,
|
|
IN DWORD flag
|
|
)
|
|
/*
|
|
Routine Description:
|
|
|
|
Update multi-sz format value for a Key
|
|
|
|
Arguements:
|
|
|
|
hSectionSmp - the SMP section handle
|
|
|
|
hSectionSap - the SAP section handle
|
|
|
|
bScepExist - if th ekey exist in SMP
|
|
|
|
KeyName - the key name
|
|
|
|
NameLen - the name length
|
|
|
|
pNewList - the new value to update to
|
|
|
|
pScepList - the original value to update
|
|
|
|
Return Value:
|
|
|
|
SCESTATUS
|
|
*/
|
|
{
|
|
SCESTATUS rc=SCESTATUS_SUCCESS;
|
|
PSCE_NAME_LIST pSapList=NULL;
|
|
|
|
if ( hSectionSmp == NULL || hSectionSap == NULL || KeyName == NULL ) {
|
|
return(SCESTATUS_INVALID_PARAMETER);
|
|
}
|
|
|
|
DWORD dwSapExist=ScepQueryAnalysisStatus(hSectionSap,
|
|
KeyName,
|
|
NameLen
|
|
);
|
|
|
|
if ( GroupName && (flag == SCE_FLAG_UPDATE_MEMBEROF) ) {
|
|
//
|
|
// this is for group membership (memberof) update
|
|
//
|
|
DWORD TmpLen = wcslen(GroupName)+wcslen(szMembers);
|
|
PWSTR TmpStr = (PWSTR)ScepAlloc(LPTR, (TmpLen+1)*sizeof(WCHAR));
|
|
|
|
if ( TmpStr ) {
|
|
|
|
swprintf(TmpStr, L"%s%s\0", GroupName, szMembers);
|
|
|
|
DWORD dwTmp = ScepQueryAnalysisStatus(hSectionSap,
|
|
TmpStr,
|
|
TmpLen
|
|
);
|
|
|
|
if ( dwTmp == SCE_STATUS_NOT_ANALYZED ||
|
|
dwTmp == SCE_STATUS_ERROR_NOT_AVAILABLE ) {
|
|
dwSapExist = dwTmp;
|
|
}
|
|
|
|
ScepFree(TmpStr);
|
|
|
|
} else {
|
|
// ignore this error
|
|
}
|
|
|
|
}
|
|
|
|
switch ( dwSapExist ) {
|
|
case SCE_STATUS_GOOD:
|
|
|
|
//
|
|
// SAP entry does not exist -- matched
|
|
//
|
|
if ( bScepExist ) {
|
|
//
|
|
// SMP entry exist
|
|
//
|
|
if ( !SceCompareNameList(pNewList, pScepList) ) {
|
|
//
|
|
// new SMP does not match SAP. SAP entry should be created with SMP
|
|
// for privileges, it's already in SID/name format, no need to convert
|
|
//
|
|
rc = ScepWriteNameListValue(
|
|
LsaPolicy,
|
|
hSectionSap,
|
|
KeyName,
|
|
pScepList,
|
|
GroupName ? (SCE_WRITE_EMPTY_LIST | SCE_WRITE_CONVERT) :
|
|
SCE_WRITE_EMPTY_LIST,
|
|
0
|
|
);
|
|
}
|
|
|
|
} else {
|
|
//
|
|
// SMP entry does not exist. should not occur for privileges but
|
|
// it is possible for group membership (new added group)
|
|
// But if it occurs, create SAP entry with NULL
|
|
//
|
|
rc = SceJetSetLine(
|
|
hSectionSap,
|
|
KeyName,
|
|
FALSE,
|
|
L" ",
|
|
2,
|
|
0);
|
|
}
|
|
|
|
break;
|
|
|
|
case SCE_STATUS_ERROR_NOT_AVAILABLE:
|
|
case SCE_STATUS_NOT_ANALYZED:
|
|
//
|
|
// SAP entry errored or not analyzed
|
|
// do not change SAP entry
|
|
//
|
|
break;
|
|
|
|
default:
|
|
|
|
//
|
|
// SAP entry exists. -- mismatched or not configured
|
|
//
|
|
rc = ScepGetKeyNameList(
|
|
LsaPolicy,
|
|
hSectionSap,
|
|
KeyName,
|
|
NameLen,
|
|
GroupName ? 0 : SCE_ACCOUNT_SID_STRING,
|
|
&pSapList
|
|
);
|
|
if ( rc == SCESTATUS_SUCCESS ) {
|
|
//
|
|
// Get the SAP assigned to list and compare
|
|
//
|
|
if ( SceCompareNameList(pNewList, pSapList) ) {
|
|
//
|
|
// new SMP is the same as SAP, delete SAP entry
|
|
//
|
|
rc = SceJetDelete(
|
|
hSectionSap,
|
|
KeyName,
|
|
FALSE,
|
|
SCEJET_DELETE_LINE_NO_CASE
|
|
);
|
|
}
|
|
//
|
|
// free the Sap list
|
|
//
|
|
ScepFreeNameList(pSapList);
|
|
pSapList = NULL;
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
if ( SCESTATUS_RECORD_NOT_FOUND == rc ) {
|
|
rc = SCESTATUS_SUCCESS;
|
|
}
|
|
|
|
if ( SCESTATUS_SUCCESS == rc ) {
|
|
|
|
//
|
|
// Update SMP with new value
|
|
//
|
|
rc = ScepWriteNameListValue(
|
|
LsaPolicy,
|
|
hSectionSmp,
|
|
KeyName,
|
|
pNewList,
|
|
GroupName ? (SCE_WRITE_EMPTY_LIST | SCE_WRITE_CONVERT) :
|
|
SCE_WRITE_EMPTY_LIST,
|
|
0
|
|
);
|
|
}
|
|
|
|
return(rc);
|
|
}
|
|
|
|
|
|
SCESTATUS
|
|
ScepUpdateGroupMembership(
|
|
IN PSCECONTEXT hProfile,
|
|
IN PSCE_GROUP_MEMBERSHIP pNewGroup,
|
|
IN PSCE_GROUP_MEMBERSHIP *pScepGroup
|
|
)
|
|
/*
|
|
Routine Description:
|
|
|
|
Update group membership section
|
|
|
|
Arguements:
|
|
|
|
hProfile - the jet database handle
|
|
|
|
pNewGroup - the changed info buffer
|
|
|
|
pScepGroup - the original SMP buffer
|
|
|
|
Return Value:
|
|
|
|
SCESTATUS
|
|
*/
|
|
{
|
|
SCESTATUS rc;
|
|
PSCESECTION hSectionSmp=NULL;
|
|
PSCESECTION hSectionSap=NULL;
|
|
PSCE_GROUP_MEMBERSHIP pGroup, pNode, pParent;
|
|
DWORD NameLen, MembersLen, MemberofLen;
|
|
PWSTR KeyName=NULL;
|
|
PWSTR SidString=NULL;
|
|
|
|
|
|
if ( pScepGroup == NULL ) {
|
|
return(SCESTATUS_INVALID_PARAMETER);
|
|
}
|
|
|
|
if ( pNewGroup == NULL && *pScepGroup == NULL ) {
|
|
return(SCESTATUS_SUCCESS);
|
|
}
|
|
|
|
|
|
LSA_HANDLE LsaHandle=NULL;
|
|
|
|
rc = RtlNtStatusToDosError(
|
|
ScepOpenLsaPolicy(
|
|
MAXIMUM_ALLOWED,
|
|
&LsaHandle,
|
|
TRUE
|
|
));
|
|
|
|
if ( ERROR_SUCCESS != rc ) {
|
|
return(ScepDosErrorToSceStatus(rc));
|
|
}
|
|
|
|
//
|
|
// open smp section for system access
|
|
//
|
|
rc = ScepOpenSectionForName(
|
|
hProfile,
|
|
SCE_ENGINE_SMP,
|
|
szGroupMembership,
|
|
&hSectionSmp
|
|
);
|
|
|
|
if ( rc == SCESTATUS_SUCCESS ) {
|
|
|
|
//
|
|
// open sap section for system access
|
|
//
|
|
rc = ScepOpenSectionForName(
|
|
hProfile,
|
|
SCE_ENGINE_SAP,
|
|
szGroupMembership,
|
|
&hSectionSap
|
|
);
|
|
|
|
if ( rc == SCESTATUS_SUCCESS ) {
|
|
|
|
MemberofLen = wcslen(szMemberof);
|
|
MembersLen = wcslen(szMembers);
|
|
|
|
|
|
for ( pGroup=pNewGroup; pGroup != NULL; pGroup = pGroup->Next ) {
|
|
//
|
|
// Process each group members and memberof in the new list
|
|
//
|
|
if ( !(pGroup->GroupName) ) {
|
|
continue;
|
|
}
|
|
|
|
if ( (pGroup->Status & SCE_GROUP_STATUS_NC_MEMBERS) &&
|
|
(pGroup->Status & SCE_GROUP_STATUS_NC_MEMBEROF ) ) {
|
|
continue;
|
|
}
|
|
|
|
if ( wcschr(pGroup->GroupName, L'\\') ) {
|
|
//
|
|
// this is in account domain format, convert it to sid string
|
|
//
|
|
NameLen = 0;
|
|
|
|
ScepConvertNameToSidString(
|
|
LsaHandle,
|
|
pGroup->GroupName,
|
|
FALSE,
|
|
&SidString,
|
|
&NameLen
|
|
);
|
|
} else {
|
|
|
|
if ( ScepLookupNameTable( pGroup->GroupName, &SidString ) ) {
|
|
NameLen = wcslen(SidString);
|
|
} else {
|
|
SidString = NULL;
|
|
}
|
|
}
|
|
|
|
if ( SidString == NULL ) {
|
|
NameLen = wcslen(pGroup->GroupName);
|
|
}
|
|
|
|
KeyName = (PWSTR)ScepAlloc(LMEM_FIXED | LMEM_ZEROINIT,
|
|
(NameLen+MemberofLen+1)*sizeof(WCHAR));
|
|
|
|
if ( KeyName == NULL ) {
|
|
rc = SCESTATUS_NOT_ENOUGH_RESOURCE;
|
|
|
|
} else {
|
|
//
|
|
// look for the matched SMP
|
|
//
|
|
for ( pNode=*pScepGroup, pParent=NULL; pNode != NULL;
|
|
pParent = pNode, pNode = pNode->Next ) {
|
|
|
|
if ( _wcsicmp(pGroup->GroupName, pNode->GroupName) == 0 ) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
if ( !(pGroup->Status & SCE_GROUP_STATUS_NC_MEMBERS) ) {
|
|
|
|
//
|
|
// work for members first
|
|
//
|
|
if ( SidString ) {
|
|
swprintf(KeyName, L"%s%s\0", SidString, szMembers);
|
|
} else {
|
|
swprintf(KeyName, L"%s%s\0", pGroup->GroupName, szMembers);
|
|
}
|
|
KeyName = _wcslwr(KeyName);
|
|
|
|
rc = ScepUpdateKeyNameList(
|
|
LsaHandle,
|
|
hSectionSmp,
|
|
hSectionSap,
|
|
SidString ? SidString : pGroup->GroupName, // group name
|
|
( pNode == NULL || (pNode->Status & SCE_GROUP_STATUS_NC_MEMBERS)) ? FALSE : TRUE,
|
|
KeyName,
|
|
NameLen+MembersLen,
|
|
pGroup->pMembers,
|
|
( pNode == NULL ) ? NULL : pNode->pMembers,
|
|
SCE_FLAG_UPDATE_MEMBERS
|
|
);
|
|
}
|
|
|
|
if ( ( rc == SCESTATUS_SUCCESS ) &&
|
|
!(pGroup->Status & SCE_GROUP_STATUS_NC_MEMBERS) ) {
|
|
|
|
//
|
|
// work for memberof second
|
|
//
|
|
if ( SidString ) {
|
|
swprintf(KeyName, L"%s%s\0", SidString, szMemberof);
|
|
} else {
|
|
swprintf(KeyName, L"%s%s\0", pGroup->GroupName, szMemberof);
|
|
}
|
|
KeyName = _wcslwr(KeyName);
|
|
|
|
rc = ScepUpdateKeyNameList(
|
|
LsaHandle,
|
|
hSectionSmp,
|
|
hSectionSap,
|
|
SidString ? SidString : pGroup->GroupName,
|
|
( pNode == NULL || (pNode->Status & SCE_GROUP_STATUS_NC_MEMBEROF) ) ? FALSE : TRUE,
|
|
KeyName,
|
|
NameLen+MemberofLen,
|
|
pGroup->pMemberOf,
|
|
( pNode == NULL ) ? NULL : pNode->pMemberOf,
|
|
SCE_FLAG_UPDATE_MEMBEROF
|
|
);
|
|
}
|
|
|
|
ScepFree(KeyName);
|
|
KeyName = NULL;
|
|
|
|
}
|
|
|
|
if ( SidString ) {
|
|
LocalFree(SidString);
|
|
SidString = NULL;
|
|
}
|
|
|
|
if ( rc == SCESTATUS_RECORD_NOT_FOUND ) {
|
|
rc = SCESTATUS_SUCCESS;
|
|
|
|
} else if ( rc != SCESTATUS_SUCCESS) {
|
|
break;
|
|
}
|
|
|
|
//
|
|
// remove the SMP node/or portion from pScepPriv
|
|
//
|
|
if ( pNode != NULL ) {
|
|
|
|
if ( !(pGroup->Status & SCE_GROUP_STATUS_NC_MEMBERS) &&
|
|
!(pGroup->Status & SCE_GROUP_STATUS_NC_MEMBEROF) ) {
|
|
|
|
//
|
|
// both of members and memberof are processed
|
|
// link to the next
|
|
//
|
|
if ( pParent != NULL ) {
|
|
pParent->Next = pNode->Next;
|
|
|
|
} else {
|
|
*pScepGroup = pNode->Next;
|
|
}
|
|
//
|
|
// delete this node
|
|
//
|
|
ScepFreeNameList(pNode->pMembers);
|
|
ScepFreeNameList(pNode->pMemberOf);
|
|
ScepFreeNameStatusList(pNode->pPrivilegesHeld);
|
|
|
|
ScepFree(pNode->GroupName);
|
|
ScepFree(pNode);
|
|
pNode = NULL;
|
|
|
|
} else {
|
|
|
|
if (!(pGroup->Status & SCE_GROUP_STATUS_NC_MEMBERS) ) {
|
|
|
|
pNode->Status |= SCE_GROUP_STATUS_NC_MEMBERS;
|
|
ScepFreeNameList(pNode->pMembers);
|
|
pNode->pMembers = NULL;
|
|
}
|
|
|
|
if ( !(pGroup->Status & SCE_GROUP_STATUS_NC_MEMBEROF) ) {
|
|
|
|
pNode->Status |= SCE_GROUP_STATUS_NC_MEMBEROF;
|
|
ScepFreeNameList(pNode->pMemberOf);
|
|
pNode->pMemberOf = NULL;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// delete remaining SMP entries, do not care error code
|
|
//
|
|
if ( rc == SCESTATUS_SUCCESS ) {
|
|
for (pNode=*pScepGroup; pNode != NULL; pNode = pNode->Next ) {
|
|
//
|
|
// raise SAP if it's not there
|
|
//
|
|
if ( pNode->GroupName == NULL ) {
|
|
continue;
|
|
}
|
|
|
|
if ( (pNode->Status & SCE_GROUP_STATUS_NC_MEMBERS) &&
|
|
(pNode->Status & SCE_GROUP_STATUS_NC_MEMBEROF) ) {
|
|
continue;
|
|
}
|
|
|
|
if ( wcschr(pNode->GroupName, L'\\') ) {
|
|
//
|
|
// this is in account domain format, convert it to sid string
|
|
//
|
|
NameLen = 0;
|
|
|
|
ScepConvertNameToSidString(
|
|
LsaHandle,
|
|
pNode->GroupName,
|
|
FALSE,
|
|
&SidString,
|
|
&NameLen
|
|
);
|
|
} else {
|
|
if ( ScepLookupNameTable( pNode->GroupName, &SidString ) ) {
|
|
NameLen = wcslen(SidString);
|
|
} else {
|
|
SidString = NULL;
|
|
}
|
|
}
|
|
|
|
if ( SidString == NULL ) {
|
|
NameLen = wcslen(pNode->GroupName);
|
|
}
|
|
|
|
KeyName = (PWSTR)ScepAlloc(LMEM_FIXED | LMEM_ZEROINIT,
|
|
(NameLen+MemberofLen+1)*sizeof(WCHAR));
|
|
|
|
if ( KeyName == NULL ) {
|
|
rc = SCESTATUS_NOT_ENOUGH_RESOURCE;
|
|
|
|
} else {
|
|
|
|
BOOL bSapError=FALSE;
|
|
|
|
if ( SidString ) {
|
|
swprintf(KeyName, L"%s%s\0", SidString, szMembers);
|
|
} else {
|
|
swprintf(KeyName, L"%s%s\0", pNode->GroupName, szMembers);
|
|
}
|
|
|
|
if ( !(pNode->Status & SCE_GROUP_STATUS_NC_MEMBERS) ) {
|
|
|
|
//
|
|
// members configuration has to be deleted.
|
|
//
|
|
rc = SceJetDelete(
|
|
hSectionSmp,
|
|
KeyName,
|
|
FALSE,
|
|
SCEJET_DELETE_LINE_NO_CASE
|
|
);
|
|
}
|
|
|
|
if ( SCESTATUS_SUCCESS == rc ) {
|
|
|
|
rc = ScepQueryAnalysisStatus(hSectionSap,
|
|
KeyName,
|
|
NameLen+MembersLen
|
|
);
|
|
|
|
if ( rc == SCE_STATUS_NOT_ANALYZED ||
|
|
rc == SCE_STATUS_ERROR_NOT_AVAILABLE ) {
|
|
//
|
|
// the entire group is analyzed with error
|
|
// or the group is new added
|
|
//
|
|
if ( !(pNode->Status & SCE_GROUP_STATUS_NC_MEMBERS) &&
|
|
!(pNode->Status & SCE_GROUP_STATUS_NC_MEMBEROF) ) {
|
|
//
|
|
// the SAP should be removed because both members and
|
|
// memberof are deleted
|
|
//
|
|
rc = SceJetDelete(
|
|
hSectionSap,
|
|
SidString ? SidString : pNode->GroupName,
|
|
FALSE,
|
|
SCEJET_DELETE_PARTIAL_NO_CASE
|
|
);
|
|
} else {
|
|
// else leave the SAP stuff there.
|
|
rc = SCESTATUS_SUCCESS;
|
|
}
|
|
bSapError = TRUE;
|
|
|
|
} else {
|
|
|
|
if ( !(pNode->Status & SCE_GROUP_STATUS_NC_MEMBERS) ) {
|
|
|
|
if ( rc == SCE_STATUS_GOOD ) {
|
|
|
|
//
|
|
// SAP doesn't exist, this is a match group members
|
|
// remove SMP means this group becomes not configured
|
|
//
|
|
|
|
rc = ScepWriteNameListValue(
|
|
LsaHandle,
|
|
hSectionSap,
|
|
KeyName,
|
|
pNode->pMembers,
|
|
SCE_WRITE_EMPTY_LIST | SCE_WRITE_CONVERT,
|
|
0
|
|
);
|
|
} else {
|
|
//
|
|
// it's already mismatched. do nothing to SAP table
|
|
//
|
|
rc = SCESTATUS_SUCCESS;
|
|
|
|
}
|
|
} else {
|
|
rc = SCESTATUS_SUCCESS;
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( SCESTATUS_SUCCESS == rc ) {
|
|
|
|
//
|
|
// continue to process memberof
|
|
//
|
|
if ( !(pNode->Status & SCE_GROUP_STATUS_NC_MEMBEROF) ) {
|
|
|
|
if ( SidString ) {
|
|
swprintf(KeyName, L"%s%s\0", SidString, szMemberof);
|
|
} else {
|
|
swprintf(KeyName, L"%s%s\0", pNode->GroupName, szMemberof);
|
|
}
|
|
|
|
//
|
|
// delete configuration
|
|
//
|
|
rc = SceJetDelete(
|
|
hSectionSmp,
|
|
KeyName,
|
|
FALSE,
|
|
SCEJET_DELETE_LINE_NO_CASE
|
|
);
|
|
|
|
if ( (SCESTATUS_SUCCESS == rc) && !bSapError ) {
|
|
|
|
rc = SceJetSeek(
|
|
hSectionSap,
|
|
KeyName,
|
|
(NameLen+MemberofLen)*sizeof(WCHAR),
|
|
SCEJET_SEEK_EQ_NO_CASE
|
|
);
|
|
|
|
if ( rc == SCESTATUS_RECORD_NOT_FOUND ) {
|
|
|
|
//
|
|
// SAP doesn't exist, this is a match group membership
|
|
// remove SMP means membership becomes "not configured"
|
|
//
|
|
|
|
rc = ScepWriteNameListValue(
|
|
LsaHandle,
|
|
hSectionSap,
|
|
KeyName,
|
|
pNode->pMemberOf,
|
|
SCE_WRITE_EMPTY_LIST | SCE_WRITE_CONVERT,
|
|
0
|
|
);
|
|
} else {
|
|
//
|
|
// a mismatch item already
|
|
//
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
ScepFree(KeyName);
|
|
KeyName = NULL;
|
|
}
|
|
|
|
if ( SidString ) {
|
|
LocalFree(SidString);
|
|
SidString = NULL;
|
|
}
|
|
|
|
if ( SCESTATUS_RECORD_NOT_FOUND == rc ) {
|
|
rc = SCESTATUS_SUCCESS;
|
|
}
|
|
|
|
if ( rc != SCESTATUS_SUCCESS ) {
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
SceJetCloseSection(&hSectionSap, TRUE);
|
|
}
|
|
|
|
SceJetCloseSection(&hSectionSmp, TRUE);
|
|
}
|
|
|
|
if ( LsaHandle ) {
|
|
LsaClose(LsaHandle);
|
|
}
|
|
|
|
return(rc);
|
|
|
|
}
|
|
|
|
|
|
SCESTATUS
|
|
ScepUpdateGeneralServices(
|
|
IN PSCECONTEXT hProfile,
|
|
IN PSCE_SERVICES pNewServices,
|
|
IN PSCE_SERVICES *pScepServices
|
|
)
|
|
/*
|
|
Routine Description:
|
|
|
|
Update general services section
|
|
|
|
Arguements:
|
|
|
|
hProfile - the jet database handle
|
|
|
|
pNewServices - the new server list
|
|
|
|
pScepServices - the original SMP service list
|
|
|
|
Return Value:
|
|
|
|
SCESTATUS
|
|
*/
|
|
{
|
|
|
|
SCESTATUS rc;
|
|
PSCESECTION hSectionSmp=NULL;
|
|
PSCESECTION hSectionSap=NULL;
|
|
PSCE_SERVICES pService, pNode, pParent;
|
|
PSCE_SERVICES pSapService=NULL;
|
|
BOOL IsDifferent;
|
|
|
|
if ( pScepServices == NULL ) {
|
|
return(SCESTATUS_INVALID_PARAMETER);
|
|
}
|
|
|
|
if ( pNewServices == NULL && *pScepServices == NULL ) {
|
|
return(SCESTATUS_SUCCESS);
|
|
}
|
|
|
|
//
|
|
// open smp section for system access
|
|
//
|
|
rc = ScepOpenSectionForName(
|
|
hProfile,
|
|
SCE_ENGINE_SMP,
|
|
szServiceGeneral,
|
|
&hSectionSmp
|
|
);
|
|
|
|
if ( rc == SCESTATUS_SUCCESS ) {
|
|
|
|
//
|
|
// open sap section for system access
|
|
//
|
|
rc = ScepOpenSectionForName(
|
|
hProfile,
|
|
SCE_ENGINE_SAP,
|
|
szServiceGeneral,
|
|
&hSectionSap
|
|
);
|
|
|
|
if ( rc == SCESTATUS_SUCCESS ) {
|
|
|
|
for ( pService=pNewServices; pService != NULL; pService = pService->Next ) {
|
|
//
|
|
// look for the matched SMP
|
|
//
|
|
for ( pNode=*pScepServices, pParent=NULL; pNode != NULL;
|
|
pParent = pNode, pNode = pNode->Next ) {
|
|
|
|
if ( _wcsicmp(pService->ServiceName, pNode->ServiceName) == 0 ) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
// get Sap
|
|
//
|
|
rc = ScepGetSingleServiceSetting(
|
|
hSectionSap,
|
|
pService->ServiceName,
|
|
&pSapService
|
|
);
|
|
|
|
if ( rc == SCESTATUS_SUCCESS ) {
|
|
//
|
|
// old status is mismatch, error, no not analyzed for this item
|
|
//
|
|
if ( pSapService &&
|
|
( pSapService->Status == SCE_STATUS_NOT_ANALYZED ||
|
|
pSapService->Status == SCE_STATUS_ERROR_NOT_AVAILABLE ) ) {
|
|
// do not change SAP
|
|
} else {
|
|
|
|
rc = ScepCompareSingleServiceSetting(
|
|
pService,
|
|
pSapService,
|
|
&IsDifferent
|
|
);
|
|
if ( rc == SCESTATUS_SUCCESS ) {
|
|
|
|
if ( !IsDifferent ) {
|
|
//
|
|
// now it is matched, delete the SAP entry
|
|
//
|
|
SceJetDelete(
|
|
hSectionSap,
|
|
pService->ServiceName,
|
|
FALSE,
|
|
SCEJET_DELETE_LINE_NO_CASE
|
|
);
|
|
}
|
|
}
|
|
}
|
|
if ( SCESTATUS_SUCCESS == rc ) {
|
|
|
|
//
|
|
// update the SMP entry
|
|
//
|
|
rc = ScepSetSingleServiceSetting(
|
|
hSectionSmp,
|
|
pService
|
|
);
|
|
}
|
|
|
|
SceFreePSCE_SERVICES(pSapService);
|
|
pSapService = NULL;
|
|
|
|
} else if ( rc == SCESTATUS_RECORD_NOT_FOUND ) {
|
|
//
|
|
// old status is matched or new added
|
|
//
|
|
if ( pNode == NULL ) {
|
|
//
|
|
// new added, add SMP first
|
|
//
|
|
rc = ScepSetSingleServiceSetting(
|
|
hSectionSmp,
|
|
pService
|
|
);
|
|
if ( rc == SCESTATUS_SUCCESS) {
|
|
pService->Status = SCE_STATUS_NOT_ANALYZED;
|
|
//
|
|
// raise SAP
|
|
//
|
|
rc = ScepSetSingleServiceSetting(
|
|
hSectionSap,
|
|
pService
|
|
);
|
|
}
|
|
} else {
|
|
rc = ScepCompareSingleServiceSetting(
|
|
pService,
|
|
pNode,
|
|
&IsDifferent
|
|
);
|
|
if ( rc == SCESTATUS_SUCCESS ) {
|
|
|
|
if ( IsDifferent ) {
|
|
//
|
|
// mismatch should be raised with valScep
|
|
//
|
|
pNode->Status = SCE_STATUS_MISMATCH;
|
|
rc = ScepSetSingleServiceSetting(
|
|
hSectionSap,
|
|
pNode
|
|
);
|
|
if ( rc == SCESTATUS_SUCCESS) {
|
|
//
|
|
// update SMP
|
|
//
|
|
rc = ScepSetSingleServiceSetting(
|
|
hSectionSmp,
|
|
pService
|
|
);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( rc == SCESTATUS_RECORD_NOT_FOUND ) {
|
|
rc = SCESTATUS_SUCCESS;
|
|
|
|
} else if ( rc != SCESTATUS_SUCCESS) {
|
|
break;
|
|
}
|
|
|
|
//
|
|
// remove the SMP node from old configuration
|
|
//
|
|
if ( pNode != NULL ) {
|
|
|
|
//
|
|
// link to the next
|
|
//
|
|
if ( pParent != NULL ) {
|
|
pParent->Next = pNode->Next;
|
|
|
|
} else {
|
|
*pScepServices = pNode->Next;
|
|
}
|
|
//
|
|
// delete this node
|
|
//
|
|
ScepFree(pNode->ServiceName);
|
|
if (pNode->General.pSecurityDescriptor)
|
|
ScepFree(pNode->General.pSecurityDescriptor);
|
|
|
|
ScepFree(pNode);
|
|
pNode = NULL;
|
|
}
|
|
}
|
|
|
|
//
|
|
// delete remaining SMP entries, do not care error code
|
|
//
|
|
if ( rc == SCESTATUS_SUCCESS ) {
|
|
for (pNode=*pScepServices; pNode != NULL; pNode = pNode->Next ) {
|
|
|
|
//
|
|
// first change SAP entry
|
|
//
|
|
rc = SceJetSeek(
|
|
hSectionSap,
|
|
pNode->ServiceName,
|
|
wcslen(pNode->ServiceName)*sizeof(WCHAR),
|
|
SCEJET_SEEK_EQ_NO_CASE
|
|
);
|
|
|
|
if ( SCESTATUS_RECORD_NOT_FOUND == rc ) {
|
|
//
|
|
// was a match item
|
|
//
|
|
pNode->Status = SCE_STATUS_NOT_CONFIGURED;
|
|
rc = ScepSetSingleServiceSetting(
|
|
hSectionSap,
|
|
pNode
|
|
);
|
|
}
|
|
|
|
if ( rc == SCESTATUS_SUCCESS ||
|
|
rc == SCESTATUS_RECORD_NOT_FOUND ) {
|
|
|
|
//
|
|
// delete SMP - it's taken out of the service list
|
|
//
|
|
rc = SceJetDelete(
|
|
hSectionSmp,
|
|
pNode->ServiceName,
|
|
FALSE,
|
|
SCEJET_DELETE_LINE_NO_CASE
|
|
);
|
|
}
|
|
|
|
if ( SCESTATUS_RECORD_NOT_FOUND == rc ) {
|
|
rc = SCESTATUS_SUCCESS;
|
|
}
|
|
|
|
if ( rc != SCESTATUS_SUCCESS ) {
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
SceJetCloseSection(&hSectionSap, TRUE);
|
|
}
|
|
|
|
SceJetCloseSection(&hSectionSmp, TRUE);
|
|
}
|
|
|
|
return(rc);
|
|
}
|
|
|
|
|
|
SCESTATUS
|
|
ScepUpdateObjectInfo(
|
|
IN PSCECONTEXT hProfile,
|
|
IN AREA_INFORMATION Area,
|
|
IN PWSTR ObjectName,
|
|
IN DWORD NameLen, // number of characters
|
|
IN BYTE ConfigStatus,
|
|
IN BOOL IsContainer,
|
|
IN PSECURITY_DESCRIPTOR pSD,
|
|
IN SECURITY_INFORMATION SeInfo,
|
|
OUT PBYTE pAnalysisStatus
|
|
)
|
|
/*
|
|
Routine Description:
|
|
|
|
Determine related changes to the object's parent(s), child(ren) in SMP and SAP
|
|
database then update the SMP entry for the object. Refer to objedit.doc for
|
|
the rule to update database.
|
|
|
|
Arguments:
|
|
|
|
hProfile - the database handle
|
|
|
|
Area - security area to update (file, registry, ds)
|
|
|
|
ObjectName - object name in full name
|
|
|
|
NameLen - the length of the object name
|
|
|
|
ConfigStatus - the flag changed to
|
|
|
|
IsContainer - if the object is a container type
|
|
|
|
pSD - the security descriptor for the object
|
|
|
|
SeInfo - the security information for the object
|
|
|
|
pAnalysisStatus - output status of analysis for the object
|
|
|
|
Return Value:
|
|
|
|
SCE status
|
|
*/
|
|
{
|
|
SCESTATUS rc;
|
|
PCWSTR SectionName;
|
|
PSCESECTION hSectionSmp=NULL;
|
|
PSCESECTION hSectionSap=NULL;
|
|
SE_OBJECT_TYPE ObjectType;
|
|
|
|
HKEY hKey;
|
|
|
|
PWSTR JetName;
|
|
DWORD NewNameLen;
|
|
|
|
if ( hProfile == NULL || ObjectName == NULL ) {
|
|
|
|
return(SCESTATUS_INVALID_PARAMETER);
|
|
}
|
|
|
|
if ( (ConfigStatus > SCE_STATUS_NO_AUTO_INHERIT ||
|
|
ConfigStatus < SCE_STATUS_CHECK) &&
|
|
(BYTE)SCE_NO_VALUE != ConfigStatus &&
|
|
(DWORD)SCE_NO_VALUE != (DWORD)ConfigStatus ) {
|
|
|
|
return(SCESTATUS_INVALID_PARAMETER);
|
|
}
|
|
|
|
switch(Area) {
|
|
case AREA_REGISTRY_SECURITY:
|
|
SectionName = szRegistryKeys;
|
|
ObjectType = SE_REGISTRY_KEY;
|
|
|
|
rc = ScepOpenRegistryObject(
|
|
ObjectType,
|
|
ObjectName,
|
|
KEY_READ,
|
|
&hKey
|
|
);
|
|
|
|
if ( rc == ERROR_SUCCESS ) {
|
|
RegCloseKey(hKey);
|
|
|
|
} else {
|
|
//
|
|
// not find the key
|
|
//
|
|
return(SCESTATUS_INVALID_DATA);
|
|
}
|
|
|
|
JetName = ObjectName;
|
|
NewNameLen = NameLen;
|
|
|
|
break;
|
|
|
|
case AREA_FILE_SECURITY:
|
|
SectionName = szFileSecurity;
|
|
ObjectType = SE_FILE_OBJECT;
|
|
|
|
if ( ObjectName[0] == L'\\' ) { // UNC name format
|
|
return(SCESTATUS_INVALID_PARAMETER);
|
|
}
|
|
|
|
if ( 0xFFFFFFFF == GetFileAttributes(ObjectName) ) {
|
|
return(SCESTATUS_INVALID_DATA);
|
|
}
|
|
|
|
JetName = ObjectName;
|
|
NewNameLen = NameLen;
|
|
break;
|
|
#if 0
|
|
case AREA_DS_OBJECTS:
|
|
SectionName = szDSSecurity;
|
|
ObjectType = SE_DS_OBJECT;
|
|
|
|
rc = ScepLdapOpen(NULL);
|
|
|
|
if ( rc == SCESTATUS_SUCCESS ) {
|
|
//
|
|
// detect if the Ds object exist
|
|
//
|
|
rc = ScepDsObjectExist(ObjectName);
|
|
|
|
if ( rc == SCESTATUS_SUCCESS ) {
|
|
//
|
|
// convert LDAP name to Jet index name
|
|
//
|
|
rc = ScepConvertLdapToJetIndexName(
|
|
ObjectName,
|
|
&JetName
|
|
);
|
|
}
|
|
}
|
|
if ( rc != SCESTATUS_SUCCESS ) {
|
|
|
|
ScepLdapClose(NULL);
|
|
return(rc);
|
|
}
|
|
|
|
NewNameLen = wcslen(JetName);
|
|
|
|
break;
|
|
#endif
|
|
|
|
default:
|
|
|
|
return(SCESTATUS_INVALID_PARAMETER);
|
|
}
|
|
|
|
if ( pAnalysisStatus ) {
|
|
*pAnalysisStatus = (BYTE)SCE_NO_VALUE;
|
|
}
|
|
//
|
|
// open smp section for system access
|
|
//
|
|
rc = ScepOpenSectionForName(
|
|
hProfile,
|
|
SCE_ENGINE_SMP,
|
|
SectionName,
|
|
&hSectionSmp
|
|
);
|
|
|
|
if ( rc == SCESTATUS_SUCCESS ) {
|
|
|
|
//
|
|
// open sap section for system access
|
|
//
|
|
rc = ScepOpenSectionForName(
|
|
hProfile,
|
|
SCE_ENGINE_SAP,
|
|
SectionName,
|
|
&hSectionSap
|
|
);
|
|
|
|
if ( rc == SCESTATUS_SUCCESS) {
|
|
|
|
//
|
|
// Start a transaction so all updates related to this object is atomic
|
|
//
|
|
rc = SceJetStartTransaction( hProfile );
|
|
|
|
if ( rc == SCESTATUS_SUCCESS ) {
|
|
|
|
rc = SceJetSeek(
|
|
hSectionSmp,
|
|
JetName,
|
|
NewNameLen*sizeof(WCHAR),
|
|
SCEJET_SEEK_EQ_NO_CASE
|
|
);
|
|
|
|
if ( rc == SCESTATUS_SUCCESS ) {
|
|
//
|
|
// existing SMP object
|
|
//
|
|
if ( (BYTE)SCE_NO_VALUE == ConfigStatus ||
|
|
(DWORD)SCE_NO_VALUE == (DWORD)ConfigStatus ) {
|
|
//
|
|
// get the old configure flag
|
|
//
|
|
WCHAR StatusFlag;
|
|
BYTE ScepStatus=0;
|
|
DWORD Len;
|
|
|
|
rc = SceJetGetValue(
|
|
hSectionSmp,
|
|
SCEJET_CURRENT,
|
|
NULL,
|
|
NULL,
|
|
0,
|
|
NULL,
|
|
(PWSTR)&StatusFlag,
|
|
2,
|
|
&Len
|
|
);
|
|
|
|
if ( SCESTATUS_SUCCESS == rc ||
|
|
SCESTATUS_BUFFER_TOO_SMALL == rc ) {
|
|
//
|
|
// find the record
|
|
//
|
|
ScepStatus = *((BYTE *)&StatusFlag);
|
|
|
|
//
|
|
// update SAP entries.
|
|
//
|
|
rc = ScepObjectAdjustNode(
|
|
hSectionSmp,
|
|
hSectionSap,
|
|
JetName,
|
|
NewNameLen,
|
|
ObjectType,
|
|
ScepStatus,
|
|
IsContainer,
|
|
NULL,
|
|
0,
|
|
FALSE, // remove the node
|
|
pAnalysisStatus
|
|
);
|
|
|
|
if ( SCESTATUS_SUCCESS == rc ) {
|
|
//
|
|
// delete the SMP entry
|
|
//
|
|
rc = SceJetDelete(
|
|
hSectionSmp,
|
|
JetName,
|
|
FALSE,
|
|
SCEJET_DELETE_LINE_NO_CASE
|
|
);
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
rc = ScepObjectUpdateExistingNode(
|
|
hSectionSmp,
|
|
hSectionSap,
|
|
JetName,
|
|
NewNameLen,
|
|
ObjectType,
|
|
ConfigStatus,
|
|
IsContainer,
|
|
pSD,
|
|
SeInfo,
|
|
pAnalysisStatus
|
|
);
|
|
|
|
if ( rc == SCESTATUS_SUCCESS ) {
|
|
//
|
|
// Update the SMP record
|
|
//
|
|
rc = ScepObjectSetKeySetting(
|
|
hSectionSmp,
|
|
JetName,
|
|
ConfigStatus,
|
|
IsContainer,
|
|
pSD,
|
|
SeInfo,
|
|
TRUE
|
|
);
|
|
}
|
|
}
|
|
|
|
} else if ( rc == SCESTATUS_RECORD_NOT_FOUND &&
|
|
(BYTE)SCE_NO_VALUE != ConfigStatus &&
|
|
(DWORD)SCE_NO_VALUE != (DWORD)ConfigStatus ) {
|
|
//
|
|
// new added object
|
|
//
|
|
rc = ScepObjectAdjustNode(
|
|
hSectionSmp,
|
|
hSectionSap,
|
|
JetName,
|
|
NewNameLen,
|
|
ObjectType,
|
|
ConfigStatus,
|
|
IsContainer,
|
|
pSD,
|
|
SeInfo,
|
|
TRUE, // add the node
|
|
pAnalysisStatus
|
|
);
|
|
|
|
}
|
|
|
|
if ( SCESTATUS_RECORD_NOT_FOUND == rc ) {
|
|
rc = SCESTATUS_SUCCESS;
|
|
}
|
|
//
|
|
// Commit or Rollback the changes
|
|
//
|
|
if ( rc == SCESTATUS_SUCCESS ) {
|
|
//
|
|
// needs return code for commiting the transaction
|
|
//
|
|
rc = SceJetCommitTransaction(hProfile, 0);
|
|
|
|
}
|
|
if ( rc != SCESTATUS_SUCCESS ) {
|
|
|
|
SceJetRollback(hProfile, 0);
|
|
}
|
|
}
|
|
|
|
SceJetCloseSection(&hSectionSap, TRUE);
|
|
|
|
} else if ( rc == SCESTATUS_BAD_FORMAT ) {
|
|
//
|
|
// SMP exist, but SAP does not exist
|
|
//
|
|
}
|
|
|
|
SceJetCloseSection(&hSectionSmp, TRUE);
|
|
|
|
} else if ( rc == SCESTATUS_BAD_FORMAT ) {
|
|
//
|
|
// SMP section does not exist
|
|
//
|
|
}
|
|
|
|
//
|
|
// free stuff used for DS
|
|
//
|
|
if ( Area == AREA_DS_OBJECTS ) {
|
|
|
|
ScepFree(JetName);
|
|
|
|
ScepLdapClose(NULL);
|
|
}
|
|
|
|
return(rc);
|
|
}
|
|
|
|
|
|
|
|
SCESTATUS
|
|
ScepObjectUpdateExistingNode(
|
|
IN PSCESECTION hSectionSmp,
|
|
IN PSCESECTION hSectionSap,
|
|
IN PWSTR ObjectName,
|
|
IN DWORD NameLen,
|
|
IN SE_OBJECT_TYPE ObjectType,
|
|
IN BYTE ConfigStatus,
|
|
IN BOOL IsContainer,
|
|
IN PSECURITY_DESCRIPTOR pSD,
|
|
IN SECURITY_INFORMATION SeInfo,
|
|
OUT PBYTE pAnalysisStatus
|
|
)
|
|
/*
|
|
Routine Description:
|
|
|
|
Update an existing object
|
|
|
|
Arguements:
|
|
|
|
see ScepUpdateObjectInfo
|
|
|
|
Return Value:
|
|
|
|
SCESTATUS
|
|
*/
|
|
{
|
|
SCESTATUS rc;
|
|
BYTE ScepStatus, SapStatus;
|
|
PSECURITY_DESCRIPTOR pScepSD=NULL;
|
|
SECURITY_INFORMATION ScepSeInfo;
|
|
|
|
BYTE retStat = SCE_STATUS_NOT_ANALYZED;
|
|
|
|
rc = ScepObjectGetKeySetting(
|
|
hSectionSmp,
|
|
ObjectName,
|
|
&ScepStatus,
|
|
NULL,
|
|
&pScepSD,
|
|
&ScepSeInfo
|
|
);
|
|
|
|
if ( rc == SCESTATUS_SUCCESS ) {
|
|
|
|
//
|
|
// check for analysis status
|
|
//
|
|
SapStatus = ScepGetObjectAnalysisStatus(
|
|
hSectionSap,
|
|
ObjectName,
|
|
FALSE
|
|
);
|
|
|
|
if ( ScepStatus == SCE_STATUS_IGNORE ) {
|
|
//
|
|
// no change is needed if update from IGNORE to IGNORE
|
|
//
|
|
if ( ConfigStatus != SCE_STATUS_IGNORE ) {
|
|
|
|
//
|
|
// N.A. the object (changed from N.C)
|
|
//
|
|
rc = ScepObjectSetKeySetting(
|
|
hSectionSap,
|
|
ObjectName,
|
|
SCE_STATUS_NOT_ANALYZED,
|
|
TRUE,
|
|
NULL,
|
|
0,
|
|
TRUE
|
|
);
|
|
} else {
|
|
|
|
if ( SapStatus == SCE_STATUS_NOT_CONFIGURED ) {
|
|
retStat = SapStatus;
|
|
}
|
|
}
|
|
|
|
} else if ( ConfigStatus == SCE_STATUS_IGNORE ) {
|
|
//
|
|
// changed to ignore. delete all children from SMP & SAP
|
|
//
|
|
rc = ScepObjectDeleteScepAndAllChildren(
|
|
hSectionSmp,
|
|
hSectionSap,
|
|
ObjectName,
|
|
IsContainer,
|
|
SCE_STATUS_NOT_CONFIGURED
|
|
);
|
|
|
|
retStat = SCE_STATUS_NOT_CONFIGURED;
|
|
|
|
} else if ( SapStatus == SCE_STATUS_NOT_ANALYZED ) {
|
|
//
|
|
// was already added/modified, no need to update SAP
|
|
// although children status may be mixed with C.C. or N.A.
|
|
//
|
|
if ( ConfigStatus == SCE_STATUS_OVERWRITE &&
|
|
ScepStatus != SCE_STATUS_OVERWRITE ) {
|
|
|
|
//
|
|
// change C.C children to N.A. children
|
|
//
|
|
|
|
rc = ScepObjectRaiseChildrenInBetween(
|
|
hSectionSmp,
|
|
hSectionSap,
|
|
ObjectName,
|
|
NameLen,
|
|
IsContainer,
|
|
SCE_STATUS_NOT_ANALYZED,
|
|
TRUE // change status only
|
|
);
|
|
|
|
} else if ( ConfigStatus != SCE_STATUS_OVERWRITE &&
|
|
ScepStatus == SCE_STATUS_OVERWRITE ) {
|
|
|
|
//
|
|
// change N.A. children to C.C. children
|
|
//
|
|
rc = ScepObjectRaiseChildrenInBetween(
|
|
hSectionSmp,
|
|
hSectionSap,
|
|
ObjectName,
|
|
NameLen,
|
|
IsContainer,
|
|
SCE_STATUS_CHILDREN_CONFIGURED,
|
|
TRUE // change status only
|
|
);
|
|
}
|
|
|
|
} else {
|
|
|
|
if ( ScepStatus == SCE_STATUS_OVERWRITE &&
|
|
( ConfigStatus == SCE_STATUS_CHECK ||
|
|
ConfigStatus == SCE_STATUS_NO_AUTO_INHERIT ) ) {
|
|
//
|
|
// delete all mismatched status between this node
|
|
// and its children; N.A. all nodes in between
|
|
//
|
|
rc = ScepObjectRaiseChildrenInBetween(
|
|
hSectionSmp,
|
|
hSectionSap,
|
|
ObjectName,
|
|
NameLen,
|
|
IsContainer,
|
|
SCE_STATUS_NOT_ANALYZED,
|
|
FALSE
|
|
);
|
|
|
|
} else if ( ConfigStatus == SCE_STATUS_OVERWRITE &&
|
|
(ScepStatus == SCE_STATUS_CHECK ||
|
|
ScepStatus == SCE_STATUS_NO_AUTO_INHERIT) ) {
|
|
//
|
|
// change C.C children to N.A. children
|
|
//
|
|
rc = ScepObjectRaiseChildrenInBetween(
|
|
hSectionSmp,
|
|
hSectionSap,
|
|
ObjectName,
|
|
NameLen,
|
|
IsContainer,
|
|
SCE_STATUS_NOT_ANALYZED,
|
|
TRUE // change status only
|
|
);
|
|
}
|
|
|
|
//
|
|
// compare the current node status
|
|
//
|
|
if ( rc == SCESTATUS_SUCCESS ||
|
|
rc == SCESTATUS_RECORD_NOT_FOUND ) {
|
|
|
|
if ( SapStatus == SCE_STATUS_ERROR_NOT_AVAILABLE ) {
|
|
// if errored, don't touch it.
|
|
retStat = SapStatus;
|
|
rc = SCESTATUS_SUCCESS;
|
|
|
|
} else {
|
|
rc = ScepObjectCompareKeySetting(
|
|
hSectionSap,
|
|
ObjectName,
|
|
ObjectType,
|
|
TRUE,
|
|
pSD,
|
|
SeInfo,
|
|
pScepSD,
|
|
&retStat
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( pScepSD ) {
|
|
ScepFree(pScepSD);
|
|
}
|
|
}
|
|
|
|
if ( pAnalysisStatus ) {
|
|
*pAnalysisStatus = retStat;
|
|
}
|
|
|
|
return(rc);
|
|
}
|
|
|
|
|
|
SCESTATUS
|
|
ScepObjectGetKeySetting(
|
|
IN PSCESECTION hSection,
|
|
IN PWSTR ObjectName,
|
|
OUT PBYTE Status,
|
|
OUT PBOOL IsContainer OPTIONAL,
|
|
OUT PSECURITY_DESCRIPTOR *pSecurityDescriptor OPTIONAL,
|
|
OUT PSECURITY_INFORMATION SeInfo OPTIONAL
|
|
)
|
|
/*
|
|
Routine Description:
|
|
|
|
Read settings for the object in the section
|
|
|
|
Arguements:
|
|
|
|
hSection - the section handle
|
|
|
|
others see ScepUpdateObjectInfo
|
|
|
|
Return Value:
|
|
|
|
SCESTATUS
|
|
*/
|
|
{
|
|
|
|
SCESTATUS rc;
|
|
PWSTR Value=NULL;
|
|
DWORD ValueLen;
|
|
|
|
PSECURITY_DESCRIPTOR pTempSD=NULL;
|
|
SECURITY_INFORMATION tmpSeInfo;
|
|
DWORD SDsize, Win32Rc;
|
|
|
|
if ( hSection == NULL || ObjectName == NULL || Status == NULL ) {
|
|
|
|
return(SCESTATUS_INVALID_PARAMETER);
|
|
}
|
|
|
|
rc = SceJetGetValue(
|
|
hSection,
|
|
SCEJET_EXACT_MATCH_NO_CASE,
|
|
ObjectName,
|
|
NULL,
|
|
0,
|
|
NULL,
|
|
NULL,
|
|
0,
|
|
&ValueLen
|
|
);
|
|
|
|
if ( rc == SCESTATUS_SUCCESS ) {
|
|
//
|
|
// allocate memory for value string
|
|
//
|
|
Value = (PWSTR)ScepAlloc( LMEM_ZEROINIT, ValueLen+2);
|
|
|
|
if ( Value == NULL )
|
|
return(SCESTATUS_NOT_ENOUGH_RESOURCE);
|
|
//
|
|
// Get the value
|
|
//
|
|
rc = SceJetGetValue(
|
|
hSection,
|
|
SCEJET_CURRENT,
|
|
NULL,
|
|
NULL,
|
|
0,
|
|
NULL,
|
|
Value,
|
|
ValueLen,
|
|
&ValueLen
|
|
);
|
|
|
|
if ( rc == SCESTATUS_SUCCESS ) {
|
|
|
|
if (pSecurityDescriptor != NULL ) {
|
|
//
|
|
// convert security descriptor
|
|
//
|
|
Win32Rc = ConvertTextSecurityDescriptor(
|
|
Value+1,
|
|
&pTempSD,
|
|
&SDsize,
|
|
&tmpSeInfo
|
|
);
|
|
if ( Win32Rc == NO_ERROR ) {
|
|
|
|
*pSecurityDescriptor = pTempSD;
|
|
|
|
if (tmpSeInfo )
|
|
*SeInfo = tmpSeInfo;
|
|
|
|
} else
|
|
rc = ScepDosErrorToSceStatus(Win32Rc);
|
|
}
|
|
|
|
if ( rc == SCESTATUS_SUCCESS ) {
|
|
|
|
*Status = *((BYTE *)Value);
|
|
|
|
if ( IsContainer != NULL )
|
|
*IsContainer = *((CHAR *)Value+1) != '0' ? TRUE : FALSE;
|
|
}
|
|
}
|
|
|
|
ScepFree(Value);
|
|
|
|
}
|
|
|
|
return(rc);
|
|
}
|
|
|
|
|
|
SCESTATUS
|
|
ScepObjectSetKeySetting(
|
|
IN PSCESECTION hSection,
|
|
IN PWSTR ObjectName,
|
|
IN BYTE Status,
|
|
IN BOOL IsContainer,
|
|
IN PSECURITY_DESCRIPTOR pSD,
|
|
IN SECURITY_INFORMATION SeInfo,
|
|
IN BOOL bOverwrite
|
|
)
|
|
/*
|
|
Routine Description:
|
|
|
|
Set settings for the object in the section
|
|
|
|
Arguements:
|
|
|
|
See ScepObjectGetKeySetting
|
|
|
|
bOverwrite - if the new setting should overwrite existing settings
|
|
|
|
Return Value:
|
|
|
|
SCESTATUS
|
|
*/
|
|
{
|
|
SCESTATUS rc;
|
|
DWORD SDsize=0, Win32Rc=NO_ERROR;
|
|
PWSTR SDspec=NULL;
|
|
|
|
|
|
if ( hSection == NULL ||
|
|
ObjectName == NULL ) {
|
|
|
|
return(SCESTATUS_INVALID_PARAMETER);
|
|
}
|
|
|
|
if ( !bOverwrite ) {
|
|
rc = SceJetSeek(
|
|
hSection,
|
|
ObjectName,
|
|
wcslen(ObjectName)*sizeof(WCHAR),
|
|
SCEJET_SEEK_EQ_NO_CASE
|
|
);
|
|
|
|
if ( rc != SCESTATUS_RECORD_NOT_FOUND ) {
|
|
//
|
|
// if found it, do not overwrite, so just return
|
|
// if errored, also return
|
|
//
|
|
return(rc);
|
|
}
|
|
}
|
|
//
|
|
// convert security descriptor
|
|
//
|
|
if ( pSD ) {
|
|
|
|
Win32Rc = ConvertSecurityDescriptorToText (
|
|
pSD,
|
|
SeInfo,
|
|
&SDspec,
|
|
&SDsize
|
|
);
|
|
}
|
|
|
|
if ( Win32Rc == NO_ERROR ) {
|
|
|
|
rc = ScepSaveObjectString(
|
|
hSection,
|
|
ObjectName,
|
|
IsContainer,
|
|
Status,
|
|
SDspec,
|
|
SDsize
|
|
);
|
|
} else
|
|
rc = ScepDosErrorToSceStatus(Win32Rc);
|
|
|
|
if ( SDspec != NULL ) {
|
|
ScepFree(SDspec);
|
|
}
|
|
|
|
return(rc);
|
|
|
|
}
|
|
|
|
|
|
SCESTATUS
|
|
ScepObjectDeleteScepAndAllChildren(
|
|
IN PSCESECTION hSectionSmp,
|
|
IN PSCESECTION hSectionSap,
|
|
IN PWSTR ObjectName,
|
|
IN BOOL IsContainer,
|
|
IN BYTE StatusToRaise
|
|
)
|
|
/*
|
|
Routine Description:
|
|
|
|
Delete a object and all child objects from SMP and SAP
|
|
|
|
Arguements:
|
|
|
|
hSectionSmp - SMP section handle
|
|
|
|
hSectionSap - SAP section handle
|
|
|
|
ObjectName - the object's name
|
|
|
|
IsContainer - if the object is a container
|
|
|
|
Return Value:
|
|
|
|
SCESTATUS
|
|
*/
|
|
{
|
|
SCESTATUS rc;
|
|
|
|
rc = SceJetDelete(
|
|
hSectionSmp,
|
|
ObjectName,
|
|
TRUE,
|
|
SCEJET_DELETE_PARTIAL_NO_CASE
|
|
);
|
|
|
|
if ( rc == SCESTATUS_SUCCESS ||
|
|
rc == SCESTATUS_RECORD_NOT_FOUND ) {
|
|
|
|
rc = SceJetDelete(
|
|
hSectionSap,
|
|
ObjectName,
|
|
TRUE,
|
|
SCEJET_DELETE_PARTIAL_NO_CASE
|
|
);
|
|
|
|
if ( rc == SCESTATUS_SUCCESS ||
|
|
rc == SCESTATUS_RECORD_NOT_FOUND ) {
|
|
//
|
|
// Raise a N.C. status for the object
|
|
//
|
|
rc = ScepObjectSetKeySetting(
|
|
hSectionSap,
|
|
ObjectName,
|
|
StatusToRaise, //SCE_STATUS_NOT_CONFIGURED,
|
|
IsContainer,
|
|
NULL,
|
|
0,
|
|
TRUE
|
|
);
|
|
}
|
|
|
|
}
|
|
|
|
if ( SCESTATUS_RECORD_NOT_FOUND == rc ) {
|
|
rc = SCESTATUS_SUCCESS;
|
|
}
|
|
|
|
return(rc);
|
|
}
|
|
|
|
|
|
SCESTATUS
|
|
ScepObjectAdjustNode(
|
|
IN PSCESECTION hSectionSmp,
|
|
IN PSCESECTION hSectionSap,
|
|
IN PWSTR ObjectName,
|
|
IN DWORD NameLen,
|
|
IN SE_OBJECT_TYPE ObjectType,
|
|
IN BYTE ConfigStatus,
|
|
IN BOOL IsContainer,
|
|
IN PSECURITY_DESCRIPTOR pSD,
|
|
IN SECURITY_INFORMATION SeInfo,
|
|
IN BOOL bAdd,
|
|
OUT PBYTE pAnalysisStatus
|
|
)
|
|
/*
|
|
Routine Description:
|
|
|
|
Add a new object to SMP and SAP sections
|
|
|
|
Arguements:
|
|
|
|
hSectionSmp - the SMP section handle
|
|
|
|
hSectionSap - the SAP section handle
|
|
|
|
others see ScepUpdateObjectInfo
|
|
|
|
Return Value:
|
|
|
|
SCESTATUS
|
|
*/
|
|
{
|
|
|
|
if ( hSectionSmp == NULL || hSectionSap == NULL ||
|
|
ObjectName == NULL || NameLen == 0 ) {
|
|
|
|
return(SCESTATUS_INVALID_PARAMETER);
|
|
}
|
|
|
|
SCESTATUS rc=SCESTATUS_SUCCESS;
|
|
WCHAR Delim;
|
|
|
|
switch ( ObjectType) {
|
|
case SE_REGISTRY_KEY:
|
|
case SE_FILE_OBJECT:
|
|
Delim = L'\\';
|
|
break;
|
|
/*
|
|
case SE_DS_OBJECT:
|
|
Delim = L',';
|
|
break;
|
|
*/
|
|
default:
|
|
return(SCESTATUS_INVALID_PARAMETER);
|
|
}
|
|
|
|
INT i, Level=0, ParentLevel=0;
|
|
BYTE ParentStatus;
|
|
|
|
//
|
|
// get total number levels of the objectname
|
|
//
|
|
ScepObjectTotalLevel(ObjectName, Delim, &Level);
|
|
|
|
//
|
|
// allocate temp buffer
|
|
//
|
|
PWSTR ParentName = (PWSTR)ScepAlloc(0, (NameLen+1)*sizeof(WCHAR));
|
|
|
|
if ( ParentName == NULL ) {
|
|
return(SCESTATUS_NOT_ENOUGH_RESOURCE);
|
|
}
|
|
|
|
//
|
|
// loop through each parent of the object to turn of IGNORE status
|
|
//
|
|
ParentName[0] = L'\0';
|
|
|
|
rc = ScepObjectAdjustParentStatus(
|
|
hSectionSmp,
|
|
hSectionSap,
|
|
ObjectName,
|
|
NameLen,
|
|
Delim,
|
|
Level,
|
|
bAdd ? (BYTE)SCE_OBJECT_TURNOFF_IGNORE : 0, // if TRUE, turn off parent ignore status, otherwise, just get the parent
|
|
&ParentLevel,
|
|
&ParentStatus,
|
|
ParentName // ParentName
|
|
);
|
|
|
|
|
|
if ( rc != SCESTATUS_SUCCESS ) {
|
|
//
|
|
// error occurs when turning off IGNORE
|
|
//
|
|
ScepFree(ParentName);
|
|
return(rc);
|
|
}
|
|
|
|
BYTE retStat = SCE_STATUS_NOT_ANALYZED;
|
|
|
|
BOOL HasChild;
|
|
|
|
rc = ScepObjectHasAnyChild(
|
|
hSectionSmp,
|
|
ObjectName,
|
|
NameLen,
|
|
Delim,
|
|
&HasChild
|
|
);
|
|
|
|
if ( rc == SCESTATUS_SUCCESS ) {
|
|
|
|
if ( bAdd ) {
|
|
|
|
//
|
|
// ****when bAdd = TRUE, add the node.
|
|
// there are the following cases to consider regarding the SAP entries:
|
|
//
|
|
// 1. tree path is empty to the root (the first object added in this path)
|
|
// C.C. all parent nodes if they don't exist
|
|
// N.A. the object
|
|
// return status N.A.
|
|
// 2. have parent node but no child node (the new node is a leaf node)
|
|
// if the closest parent is in OVERWRITE status
|
|
// if the closet parent is new added (N.A. status)
|
|
// add the node, N.A. the object
|
|
// return status N.A.
|
|
// else
|
|
// if new node status is CHECK
|
|
// delete all SAP mismatches for children under the new node,
|
|
// determine MATCH/MISMATCH of the new node
|
|
// if new node status is OVERWRITE
|
|
// determine MATCH/MISMATCH of the new node, everthing else stays unchanged
|
|
// return status GOOD or MISMATCH
|
|
// if the closest parent is CHECK
|
|
// C.C. all nodes in the path to the parent,
|
|
// add the node, N.A. the object
|
|
// return status N.A.
|
|
// 3. have child node but no parent node
|
|
// new node's status (CHECK or OVERWRITE ) does not make difference
|
|
// if new status is IGNORE,
|
|
// delete all children in SMP and SAP,
|
|
// add the node and N.C. the object
|
|
// return status N.C.
|
|
// else
|
|
// delete all children in SAP,
|
|
// add the node,
|
|
// raise all SMP node and children as N.A.
|
|
// return status N.A
|
|
//
|
|
// 4. have both parent and child
|
|
// combine rules for 2 and 3 except:
|
|
// if parent's status is OVERWRITE and new node status is CHECK
|
|
// ONLY delete SAP mismatches for children between the new node and the child node
|
|
//
|
|
|
|
//
|
|
// decide child objects
|
|
//
|
|
if ( ConfigStatus == SCE_STATUS_IGNORE ) {
|
|
//
|
|
// delete all children objects from template and analysis database
|
|
//
|
|
rc = ScepObjectDeleteScepAndAllChildren(
|
|
hSectionSmp,
|
|
hSectionSap,
|
|
ObjectName,
|
|
IsContainer,
|
|
SCE_STATUS_NOT_ANALYZED
|
|
);
|
|
|
|
} else {
|
|
|
|
if ( ParentLevel > 0 && ParentStatus == SCE_STATUS_OVERWRITE ) {
|
|
|
|
//
|
|
// check if this parent was added (N.A. status)
|
|
//
|
|
BYTE oldStatus = ScepGetObjectAnalysisStatus(hSectionSap,
|
|
ParentName,
|
|
FALSE
|
|
);
|
|
|
|
if ( oldStatus == SCE_STATUS_NOT_ANALYZED ) {
|
|
//
|
|
// parent was also new added
|
|
// add the node, N.A. the object
|
|
//
|
|
rc = ScepObjectSetKeySetting(
|
|
hSectionSap,
|
|
ObjectName,
|
|
SCE_STATUS_NOT_ANALYZED,
|
|
TRUE,
|
|
NULL,
|
|
0,
|
|
TRUE
|
|
);
|
|
} else {
|
|
|
|
//
|
|
// closest parent has OVERWRITE status
|
|
//
|
|
|
|
if ( ConfigStatus == SCE_STATUS_CHECK ||
|
|
ConfigStatus == SCE_STATUS_NO_AUTO_INHERIT ) {
|
|
|
|
//
|
|
// delete all SAP children except explicitly specified
|
|
//
|
|
if ( !HasChild ) {
|
|
//
|
|
// no child - delete everything under the SAP
|
|
//
|
|
rc = SceJetDelete(
|
|
hSectionSap,
|
|
ObjectName,
|
|
TRUE,
|
|
SCEJET_DELETE_PARTIAL_NO_CASE
|
|
);
|
|
} else {
|
|
|
|
//
|
|
// here is the problem: should only delete SAP entry between
|
|
// the new node and its child(ren)
|
|
// and raise C.C. for nodes in between
|
|
//
|
|
// p
|
|
// /
|
|
// .
|
|
// N
|
|
// / |
|
|
// . C
|
|
// / \
|
|
// . C
|
|
// /|
|
|
// C C
|
|
//
|
|
//
|
|
|
|
rc = ScepObjectRaiseChildrenInBetween(
|
|
hSectionSmp,
|
|
hSectionSap,
|
|
ObjectName,
|
|
NameLen,
|
|
IsContainer,
|
|
SCE_STATUS_CHILDREN_CONFIGURED,
|
|
FALSE
|
|
);
|
|
}
|
|
}
|
|
|
|
//
|
|
// determine the current node's status, MATCH or MISMATCH
|
|
//
|
|
|
|
if ( rc == SCESTATUS_SUCCESS ||
|
|
rc == SCESTATUS_RECORD_NOT_FOUND ) {
|
|
|
|
if ( oldStatus == SCE_STATUS_ERROR_NOT_AVAILABLE ) {
|
|
|
|
//
|
|
// Leave Error status alone
|
|
//
|
|
rc = ScepObjectSetKeySetting(
|
|
hSectionSap,
|
|
ObjectName,
|
|
oldStatus,
|
|
TRUE,
|
|
NULL,
|
|
0,
|
|
TRUE
|
|
);
|
|
} else {
|
|
|
|
//
|
|
// should compare with SAP to decide mismatch status
|
|
//
|
|
rc = ScepObjectCompareKeySetting(
|
|
hSectionSap,
|
|
ObjectName,
|
|
ObjectType,
|
|
TRUE,
|
|
pSD,
|
|
SeInfo,
|
|
NULL,
|
|
&retStat
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
} else if ( !HasChild ) {
|
|
//
|
|
// there is no child but there may be a parent
|
|
// if there is a parent, parent's stauts is check
|
|
//
|
|
if ( ParentLevel > 0 ) {
|
|
// C.C. all nodes in the path to the parent,
|
|
// (if there is child, it's already CCed)
|
|
// add the node, N.A. the object
|
|
i = ParentLevel+1;
|
|
|
|
} else {
|
|
//
|
|
// no parent was found, no child - the first node
|
|
//
|
|
if ( ObjectType == SE_DS_OBJECT ) {
|
|
//
|
|
// Ds objects should start with the level for the local domain
|
|
//
|
|
PSCE_OBJECT_LIST pDsRoot=NULL;
|
|
rc = ScepEnumerateDsObjectRoots(NULL, &pDsRoot);
|
|
|
|
if ( rc == SCESTATUS_SUCCESS && pDsRoot != NULL ) {
|
|
ScepObjectTotalLevel(pDsRoot->Name, Delim, &ParentLevel);
|
|
|
|
ScepFreeObjectList(pDsRoot);
|
|
pDsRoot = NULL;
|
|
|
|
i = ParentLevel+1;
|
|
|
|
}
|
|
|
|
} else {
|
|
//
|
|
// other type starting with level 1
|
|
//
|
|
i = 1;
|
|
}
|
|
}
|
|
|
|
//
|
|
// process each node in between the new node and its closest parent
|
|
//
|
|
if ( rc == SCESTATUS_SUCCESS ) {
|
|
rc = ScepObjectRaiseNodesInPath(
|
|
hSectionSap,
|
|
ObjectName,
|
|
NameLen,
|
|
i,
|
|
Level,
|
|
Delim,
|
|
SCE_STATUS_CHILDREN_CONFIGURED
|
|
);
|
|
}
|
|
|
|
//
|
|
// N.A. the object
|
|
//
|
|
if ( rc == SCESTATUS_SUCCESS ) {
|
|
rc = ScepObjectSetKeySetting(
|
|
hSectionSap,
|
|
ObjectName,
|
|
SCE_STATUS_NOT_ANALYZED,
|
|
IsContainer,
|
|
NULL,
|
|
0,
|
|
TRUE
|
|
);
|
|
}
|
|
|
|
} else {
|
|
//
|
|
// there is child
|
|
//
|
|
if ( ConfigStatus == SCE_STATUS_OVERWRITE ) {
|
|
//
|
|
// if there is a parent, it must be in CHECK status
|
|
// nodes between this node and its children
|
|
// should all be N.A.
|
|
//
|
|
rc = ScepObjectRaiseChildrenInBetween(
|
|
hSectionSmp,
|
|
hSectionSap,
|
|
ObjectName,
|
|
NameLen,
|
|
IsContainer,
|
|
SCE_STATUS_NOT_ANALYZED,
|
|
FALSE
|
|
);
|
|
}
|
|
|
|
//
|
|
// N.A. the object
|
|
//
|
|
if ( rc == SCESTATUS_SUCCESS ) {
|
|
rc = ScepObjectSetKeySetting(
|
|
hSectionSap,
|
|
ObjectName,
|
|
SCE_STATUS_NOT_ANALYZED,
|
|
IsContainer,
|
|
NULL,
|
|
0,
|
|
TRUE
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// add the SMP entry
|
|
//
|
|
if ( rc == SCESTATUS_SUCCESS ) {
|
|
rc = ScepObjectSetKeySetting(
|
|
hSectionSmp,
|
|
ObjectName,
|
|
ConfigStatus,
|
|
IsContainer,
|
|
pSD,
|
|
SeInfo,
|
|
TRUE
|
|
);
|
|
}
|
|
|
|
} else {
|
|
|
|
//
|
|
// when bAdd = FALSE, remove the node
|
|
// there are the following cases to consider regarding the SAP entries:
|
|
//
|
|
// 1. if there is no existing child under this node
|
|
// if no parent, or parent N.A., or parent not OVERWRITE
|
|
// find junction point with other siblings
|
|
// remove all SAP below junction point (if not exist, use root/parent)
|
|
// if no juction point and no parent
|
|
// N.C. the root
|
|
// return status N.C.
|
|
// else { parent in overwrite } if ( TNA/TI/TC) }
|
|
// delete all SAP below this object
|
|
// N.A. the object
|
|
// return status N.A.
|
|
// else ( parent in overwrite and TO )
|
|
// N.A. the object
|
|
// return status N.A.
|
|
// 2. have existing child(ren) - note multiple branches
|
|
// if no parent
|
|
// if object status was OVERWRITE
|
|
// delete SAP entries between this node and all children
|
|
// C.C. all branch nodes in between
|
|
// C.C. this object
|
|
// return status C.C.
|
|
// else { there is a parent }
|
|
// if (parent OVERWRITE, object N.A. OVERWRITE) or
|
|
// (parent not N.A., parent OVERWRITE, object not N.A., object OVERWRITE)
|
|
// N.A. object
|
|
// return N.A.
|
|
// else if parent CHECK, object OVERWRITE
|
|
// delete SAP entries between this node and all children
|
|
// C.C. all branch nodes in between
|
|
// C.C. object
|
|
// return C.C.
|
|
// else if (parent OVERWRITE, object CHECK) or
|
|
// (parent N.A., parent OVERWRITE, object not N.A., object OVERWRITE)
|
|
// delete SAP entries between this node and all children
|
|
// N.A. all branch nodes in between
|
|
// N.A. object
|
|
// return N.A.
|
|
// else { must be parent CHECK, object CHECK }
|
|
// C.C. object
|
|
// return C.C
|
|
//
|
|
|
|
//
|
|
// check if this parent was added (N.A. status)
|
|
//
|
|
BYTE oldParentFlag = ScepGetObjectAnalysisStatus(hSectionSap,
|
|
ParentName,
|
|
FALSE
|
|
);
|
|
BYTE oldObjectFlag = ScepGetObjectAnalysisStatus(hSectionSap,
|
|
ObjectName,
|
|
FALSE
|
|
);
|
|
if ( !HasChild ) {
|
|
|
|
if ( ParentLevel <= 0 ||
|
|
oldParentFlag == SCE_STATUS_NOT_ANALYZED ||
|
|
ParentStatus != SCE_STATUS_OVERWRITE ) {
|
|
|
|
//
|
|
// find junction point with other siblings
|
|
//
|
|
INT JuncLevel=0;
|
|
|
|
rc = ScepObjectAdjustParentStatus(
|
|
hSectionSmp,
|
|
hSectionSap,
|
|
ObjectName,
|
|
NameLen,
|
|
Delim,
|
|
Level,
|
|
SCE_OBJECT_SEARCH_JUNCTION,
|
|
&JuncLevel,
|
|
NULL,
|
|
NULL
|
|
);
|
|
|
|
if ( SCESTATUS_RECORD_NOT_FOUND == rc ) {
|
|
rc = SCESTATUS_SUCCESS;
|
|
}
|
|
|
|
if ( JuncLevel == 0 ) {
|
|
JuncLevel = ParentLevel;
|
|
}
|
|
|
|
if ( SCESTATUS_SUCCESS == rc ) {
|
|
//
|
|
// remove all SAP below junction point
|
|
// (if not exist, use root/parent)
|
|
//
|
|
rc = ScepObjectRaiseNodesInPath(
|
|
hSectionSap,
|
|
ObjectName,
|
|
NameLen,
|
|
(JuncLevel > 0) ? JuncLevel+1 : 1,
|
|
Level,
|
|
Delim,
|
|
(BYTE)SCE_NO_VALUE
|
|
);
|
|
|
|
if ( SCESTATUS_SUCCESS == rc ) {
|
|
//
|
|
// delete everything under this deleted node
|
|
//
|
|
rc = SceJetDelete(
|
|
hSectionSap,
|
|
ObjectName,
|
|
TRUE,
|
|
SCEJET_DELETE_PARTIAL_NO_CASE
|
|
);
|
|
}
|
|
}
|
|
|
|
if ( SCESTATUS_RECORD_NOT_FOUND == rc ) {
|
|
rc = SCESTATUS_SUCCESS;
|
|
}
|
|
|
|
if ( SCESTATUS_SUCCESS == rc ) {
|
|
|
|
if ( JuncLevel <= 0 ) {
|
|
//
|
|
// if no juction point and no parent, N.C. the root
|
|
// use the ParentName buffer
|
|
//
|
|
if ( ObjectType == SE_FILE_OBJECT ) {
|
|
if ( ParentName[0] == L'\0' ) {
|
|
//
|
|
// there is no parent
|
|
//
|
|
ParentName[0] = ObjectName[0];
|
|
ParentName[1] = ObjectName[1];
|
|
}
|
|
ParentName[2] = L'\\';
|
|
ParentName[3] = L'\0';
|
|
} else {
|
|
// reg keys
|
|
PWSTR pTemp = wcschr(ParentName, L'\\');
|
|
if ( pTemp ) {
|
|
ParentName[pTemp-ParentName] = L'\0';
|
|
|
|
} else if ( ParentName[0] == L'\0' ) {
|
|
|
|
pTemp = wcschr(ObjectName, L'\\');
|
|
if ( pTemp ) {
|
|
|
|
wcsncpy(ParentName, ObjectName, pTemp-ObjectName);
|
|
ParentName[pTemp-ObjectName] = L'\0';
|
|
|
|
} else {
|
|
wcscpy(ParentName, ObjectName);
|
|
}
|
|
}
|
|
}
|
|
|
|
rc = ScepObjectSetKeySetting(
|
|
hSectionSap,
|
|
ParentName,
|
|
SCE_STATUS_NOT_CONFIGURED,
|
|
TRUE,
|
|
NULL,
|
|
0,
|
|
TRUE
|
|
);
|
|
}
|
|
}
|
|
|
|
retStat = SCE_STATUS_NOT_CONFIGURED;
|
|
|
|
} else {
|
|
|
|
if ( ConfigStatus != SCE_STATUS_OVERWRITE ) {
|
|
//
|
|
// delete all SAP below this object
|
|
//
|
|
rc = SceJetDelete(
|
|
hSectionSap,
|
|
ObjectName,
|
|
TRUE,
|
|
SCEJET_DELETE_PARTIAL_NO_CASE
|
|
);
|
|
}
|
|
|
|
if ( SCESTATUS_SUCCESS == rc ) {
|
|
|
|
//
|
|
// N.A. the object
|
|
//
|
|
rc = ScepObjectSetKeySetting(
|
|
hSectionSap,
|
|
ObjectName,
|
|
SCE_STATUS_NOT_ANALYZED,
|
|
IsContainer,
|
|
NULL,
|
|
0,
|
|
TRUE
|
|
);
|
|
}
|
|
|
|
retStat = SCE_STATUS_NOT_ANALYZED;
|
|
}
|
|
|
|
} else if ( ParentLevel <= 0 ||
|
|
( ParentStatus != SCE_STATUS_OVERWRITE &&
|
|
ConfigStatus == SCE_STATUS_OVERWRITE) ) {
|
|
|
|
// no parent, or parent check, object overwrite
|
|
|
|
if ( ConfigStatus == SCE_STATUS_OVERWRITE ) {
|
|
//
|
|
// delete SAP entries between this node and all children
|
|
// C.C. all branch nodes in between
|
|
//
|
|
rc = ScepObjectRaiseChildrenInBetween(
|
|
hSectionSmp,
|
|
hSectionSap,
|
|
ObjectName,
|
|
NameLen,
|
|
IsContainer,
|
|
SCE_STATUS_CHILDREN_CONFIGURED,
|
|
FALSE
|
|
);
|
|
}
|
|
|
|
if ( SCESTATUS_SUCCESS == rc ) {
|
|
|
|
// C.C. this object
|
|
rc = ScepObjectSetKeySetting(
|
|
hSectionSap,
|
|
ObjectName,
|
|
SCE_STATUS_CHILDREN_CONFIGURED,
|
|
IsContainer,
|
|
NULL,
|
|
0,
|
|
TRUE
|
|
);
|
|
}
|
|
|
|
retStat = SCE_STATUS_CHILDREN_CONFIGURED;
|
|
|
|
} else {
|
|
//
|
|
// have both parent and children
|
|
//
|
|
|
|
if ( ParentStatus == SCE_STATUS_OVERWRITE &&
|
|
ConfigStatus == SCE_STATUS_OVERWRITE &&
|
|
( oldObjectFlag == SCE_STATUS_NOT_ANALYZED ||
|
|
(oldParentFlag != SCE_STATUS_NOT_ANALYZED &&
|
|
oldObjectFlag != SCE_STATUS_NOT_ANALYZED )
|
|
) ) {
|
|
//
|
|
// (parent OVERWRITE, object N.A. OVERWRITE) or
|
|
// (parent not N.A., parent OVERWRITE, object not N.A., object OVERWRITE)
|
|
// N.A. the object
|
|
//
|
|
retStat = SCE_STATUS_NOT_ANALYZED;
|
|
|
|
} else if ( ParentStatus == SCE_STATUS_OVERWRITE &&
|
|
( ConfigStatus != SCE_STATUS_OVERWRITE ||
|
|
( oldParentFlag == SCE_STATUS_NOT_ANALYZED &&
|
|
oldObjectFlag != SCE_STATUS_NOT_ANALYZED &&
|
|
ConfigStatus == SCE_STATUS_OVERWRITE ))
|
|
) {
|
|
//
|
|
// (parent OVERWRITE, object CHECK) or
|
|
// (parent N.A., parent OVERWRITE, object not N.A., object OVERWRITE)
|
|
//
|
|
// delete SAP entries between this node and all children
|
|
// N.A. all branch nodes in between
|
|
//
|
|
|
|
rc = ScepObjectRaiseChildrenInBetween(
|
|
hSectionSmp,
|
|
hSectionSap,
|
|
ObjectName,
|
|
NameLen,
|
|
IsContainer,
|
|
SCE_STATUS_NOT_ANALYZED,
|
|
FALSE
|
|
);
|
|
|
|
// N.A. object
|
|
retStat = SCE_STATUS_NOT_ANALYZED;
|
|
|
|
} else {
|
|
//
|
|
// must be parent CHECK, object CHECK }
|
|
// C.C. object
|
|
//
|
|
|
|
retStat = SCE_STATUS_NOT_ANALYZED;
|
|
}
|
|
|
|
if ( SCESTATUS_SUCCESS == rc ) {
|
|
rc = ScepObjectSetKeySetting(
|
|
hSectionSap,
|
|
ObjectName,
|
|
retStat,
|
|
IsContainer,
|
|
NULL,
|
|
0,
|
|
TRUE
|
|
);
|
|
}
|
|
}
|
|
//
|
|
// remove the SMP entry
|
|
//
|
|
if ( rc == SCESTATUS_SUCCESS ) {
|
|
|
|
rc = SceJetDelete(
|
|
hSectionSmp,
|
|
ObjectName,
|
|
FALSE,
|
|
SCEJET_DELETE_LINE_NO_CASE
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
ScepFree(ParentName);
|
|
|
|
if ( pAnalysisStatus ) {
|
|
*pAnalysisStatus = retStat;
|
|
}
|
|
|
|
return(rc);
|
|
}
|
|
|
|
|
|
SCESTATUS
|
|
ScepObjectRaiseNodesInPath(
|
|
IN PSCESECTION hSectionSap,
|
|
IN PWSTR ObjectName,
|
|
IN DWORD NameLen,
|
|
IN INT StartLevel,
|
|
IN INT EndLevel,
|
|
IN WCHAR Delim,
|
|
IN BYTE Status
|
|
)
|
|
{
|
|
BOOL LastOne=FALSE;
|
|
SCESTATUS rc = SCESTATUS_SUCCESS;
|
|
PWSTR NodeName=NULL;
|
|
|
|
//
|
|
// process each node in between the start level and end level
|
|
//
|
|
for ( INT i=StartLevel; rc==SCESTATUS_SUCCESS && i < EndLevel; i++ ) {
|
|
|
|
if ( NodeName == NULL ) {
|
|
|
|
NodeName = (PWSTR)ScepAlloc(0, (NameLen+1)*sizeof(WCHAR));
|
|
if ( NodeName == NULL ) {
|
|
rc = SCESTATUS_NOT_ENOUGH_RESOURCE;
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
// get level i full name
|
|
//
|
|
memset(NodeName, '\0', (NameLen+1)*sizeof(WCHAR));
|
|
|
|
rc = ScepGetFullNameInLevel(
|
|
ObjectName,
|
|
i,
|
|
Delim,
|
|
FALSE,
|
|
NodeName,
|
|
&LastOne
|
|
);
|
|
|
|
if ( rc == SCESTATUS_SUCCESS) {
|
|
|
|
if ( Status != (BYTE)SCE_NO_VALUE ) {
|
|
//
|
|
// raise the status
|
|
//
|
|
|
|
rc = ScepObjectSetKeySetting(
|
|
hSectionSap,
|
|
NodeName,
|
|
Status,
|
|
TRUE,
|
|
NULL,
|
|
0,
|
|
TRUE
|
|
);
|
|
} else {
|
|
|
|
//
|
|
// remove the raise
|
|
//
|
|
rc = SceJetDelete(
|
|
hSectionSap,
|
|
NodeName,
|
|
FALSE,
|
|
SCEJET_DELETE_LINE_NO_CASE
|
|
);
|
|
}
|
|
|
|
}
|
|
|
|
if ( SCESTATUS_RECORD_NOT_FOUND == rc ) {
|
|
rc = SCESTATUS_SUCCESS;
|
|
}
|
|
|
|
if ( rc != SCESTATUS_SUCCESS ) {
|
|
break;
|
|
}
|
|
|
|
}
|
|
|
|
if ( NodeName ) {
|
|
ScepFree(NodeName);
|
|
}
|
|
|
|
return rc;
|
|
}
|
|
|
|
|
|
SCESTATUS
|
|
ScepObjectTotalLevel(
|
|
IN PWSTR ObjectName,
|
|
IN WCHAR Delim,
|
|
OUT PINT pLevel
|
|
)
|
|
/*
|
|
Routine Description:
|
|
|
|
Count total levels of the object name, for example, c:\winnt\system32
|
|
will return level of 3
|
|
|
|
Arguements:
|
|
|
|
ObjectName - the object's name in full path
|
|
|
|
Delim - the delimiter to look for
|
|
|
|
pLevel - the output level
|
|
|
|
Return Value:
|
|
|
|
SCESTATUS
|
|
*/
|
|
{
|
|
PWSTR pStart;
|
|
|
|
if ( ObjectName == NULL || pLevel == NULL ) {
|
|
return(SCESTATUS_INVALID_PARAMETER);
|
|
}
|
|
|
|
pStart = ObjectName;
|
|
*pLevel = 0;
|
|
|
|
while (pStart) {
|
|
|
|
(*pLevel)++;
|
|
pStart = wcschr(pStart, Delim);
|
|
|
|
if ( pStart != NULL && *(pStart+1) != L'\0' )
|
|
pStart++;
|
|
else
|
|
break;
|
|
}
|
|
|
|
return(SCESTATUS_SUCCESS);
|
|
}
|
|
|
|
|
|
SCESTATUS
|
|
ScepObjectCompareKeySetting(
|
|
IN PSCESECTION hSectionSap,
|
|
IN PWSTR ObjectName,
|
|
IN SE_OBJECT_TYPE ObjectType,
|
|
IN BOOL IsContainer,
|
|
IN PSECURITY_DESCRIPTOR pSD,
|
|
IN SECURITY_INFORMATION SeInfo,
|
|
IN PSECURITY_DESCRIPTOR pScepSD,
|
|
OUT PBYTE pAnalysisStatus
|
|
)
|
|
/*
|
|
Routine Description:
|
|
|
|
Compare an object's setting with info in the section.
|
|
|
|
Arguements:
|
|
|
|
hSectionSap - the SAP section handle
|
|
|
|
others see ScepUpdateObjectInfo
|
|
|
|
Return Value:
|
|
|
|
SCESTATUS
|
|
*/
|
|
{
|
|
SCESTATUS rc;
|
|
BYTE SapStatus;
|
|
PSECURITY_DESCRIPTOR pSapSD = NULL;
|
|
SECURITY_INFORMATION SapSeInfo;
|
|
DWORD Win32rc;
|
|
BYTE CompareStatus=0;
|
|
|
|
|
|
rc = ScepObjectGetKeySetting(
|
|
hSectionSap,
|
|
ObjectName,
|
|
&SapStatus,
|
|
NULL,
|
|
&pSapSD,
|
|
&SapSeInfo
|
|
);
|
|
|
|
if ( rc == SCESTATUS_SUCCESS ) {
|
|
//
|
|
// SAP record exists. was mismatched
|
|
//
|
|
Win32rc = ScepCompareObjectSecurity(
|
|
ObjectType,
|
|
IsContainer,
|
|
pSD,
|
|
pSapSD,
|
|
SeInfo,
|
|
&CompareStatus
|
|
);
|
|
|
|
if ( Win32rc != NO_ERROR ) {
|
|
rc = ScepDosErrorToSceStatus(Win32rc);
|
|
|
|
} else if ( !CompareStatus ) {
|
|
//
|
|
// new setting is same as the SAP setting - matched
|
|
// delete the SAP entry
|
|
//
|
|
rc = SceJetDelete(
|
|
hSectionSap,
|
|
ObjectName,
|
|
FALSE,
|
|
SCEJET_DELETE_LINE_NO_CASE
|
|
);
|
|
|
|
if ( pAnalysisStatus ) {
|
|
*pAnalysisStatus = SCE_STATUS_GOOD;
|
|
}
|
|
|
|
} else {
|
|
//
|
|
// still mismatched, just update the SMP entry (outside)
|
|
//
|
|
rc = ScepObjectSetKeySetting(
|
|
hSectionSap,
|
|
ObjectName,
|
|
CompareStatus, // SCE_STATUS_MISMATCH,
|
|
IsContainer,
|
|
pSapSD,
|
|
SapSeInfo,
|
|
TRUE
|
|
);
|
|
if ( pAnalysisStatus ) {
|
|
*pAnalysisStatus = CompareStatus; // SapStatus;
|
|
}
|
|
|
|
}
|
|
|
|
if ( pSapSD ) {
|
|
ScepFree(pSapSD);
|
|
}
|
|
|
|
} else if ( rc == SCESTATUS_RECORD_NOT_FOUND ) {
|
|
|
|
rc = SCESTATUS_SUCCESS;
|
|
//
|
|
// no SAP record exist. was matched
|
|
//
|
|
Win32rc = ScepCompareObjectSecurity(
|
|
ObjectType,
|
|
IsContainer,
|
|
pSD,
|
|
pScepSD,
|
|
SeInfo,
|
|
&CompareStatus
|
|
);
|
|
|
|
if ( Win32rc != NO_ERROR ) {
|
|
rc = ScepDosErrorToSceStatus(Win32rc);
|
|
|
|
} else if ( CompareStatus ) {
|
|
//
|
|
// new setting is different from the SMP setting
|
|
// create SAP entry using the SMP setting
|
|
//
|
|
rc = ScepObjectSetKeySetting(
|
|
hSectionSap,
|
|
ObjectName,
|
|
CompareStatus, // SCE_STATUS_MISMATCH,
|
|
IsContainer,
|
|
pScepSD,
|
|
SeInfo,
|
|
TRUE
|
|
);
|
|
if ( pAnalysisStatus ) {
|
|
*pAnalysisStatus = CompareStatus; // SCE_STATUS_MISMATCH;
|
|
}
|
|
|
|
} else {
|
|
|
|
if ( pAnalysisStatus ) {
|
|
*pAnalysisStatus = SCE_STATUS_GOOD;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
if ( SCESTATUS_RECORD_NOT_FOUND == rc ) {
|
|
rc = SCESTATUS_SUCCESS;
|
|
}
|
|
return(rc);
|
|
}
|
|
|
|
|
|
SCESTATUS
|
|
ScepObjectAdjustParentStatus(
|
|
IN PSCESECTION hSectionSmp,
|
|
IN PSCESECTION hSectionSap,
|
|
IN PWSTR ObjectName,
|
|
IN DWORD NameLen,
|
|
IN WCHAR Delim,
|
|
IN INT Level,
|
|
IN BYTE Flag,
|
|
OUT PINT ParentLevel,
|
|
OUT PBYTE ParentStatus OPTIONAL,
|
|
OUT PWSTR ParentName OPTIONAL
|
|
)
|
|
/*
|
|
Routine Description:
|
|
|
|
delete the ignored parent in the object's path (should only have one)
|
|
The following actions are taken when a IGNORE node is found:
|
|
(it should have N.C.ed in SAP but no children has N.C record)
|
|
delete all children in SMP and SAP
|
|
(force to have only no or one IGNORE in the path)
|
|
delete the SMP entry ( turn the IGNORE status to CHECK ?)
|
|
There should be no other nodes under a IGNORE node. But if there are,
|
|
delete them.
|
|
raise SAP status as "Not analyzed"
|
|
|
|
Arguments:
|
|
|
|
hSectionSmp - the SMP section handle
|
|
|
|
hSectionSap - the SAP section handle
|
|
|
|
ObjectName - the object's full name
|
|
|
|
NameLen - the length of the name
|
|
|
|
Delim - the delimiter to look for
|
|
|
|
Level - the total level of the object name
|
|
|
|
ParentLevel - output of its closest parent level
|
|
|
|
ParentStatus - output of its closest parent status
|
|
|
|
Return Value:
|
|
|
|
SCE status
|
|
*/
|
|
{
|
|
SCESTATUS rc=SCESTATUS_SUCCESS;
|
|
INT i;
|
|
PWSTR Name=NULL;
|
|
BOOL LastOne;
|
|
DWORD ParentLen;
|
|
BYTE Status;
|
|
PSECURITY_DESCRIPTOR pScepSD=NULL;
|
|
SECURITY_INFORMATION SeInfo;
|
|
|
|
Name = (PWSTR)ScepAlloc(0, (NameLen+2)*sizeof(WCHAR));
|
|
|
|
if ( Name == NULL ) {
|
|
return(SCESTATUS_NOT_ENOUGH_RESOURCE);
|
|
}
|
|
|
|
*ParentLevel = 0;
|
|
|
|
for ( i=Level-1; i>=1; i-- ) {
|
|
//
|
|
// get level i full name
|
|
//
|
|
memset(Name, '\0', (NameLen+2)*sizeof(WCHAR));
|
|
|
|
rc = ScepGetFullNameInLevel(
|
|
ObjectName,
|
|
i,
|
|
Delim,
|
|
(Flag & SCE_OBJECT_SEARCH_JUNCTION) ? TRUE : FALSE,
|
|
Name,
|
|
&LastOne
|
|
);
|
|
|
|
if ( rc == SCESTATUS_SUCCESS ) {
|
|
|
|
//
|
|
// search and get information of this path
|
|
//
|
|
if ( Flag & SCE_OBJECT_SEARCH_JUNCTION ) {
|
|
|
|
DWORD Count=0;
|
|
|
|
rc = SceJetGetLineCount(
|
|
hSectionSmp,
|
|
Name,
|
|
FALSE,
|
|
&Count
|
|
);
|
|
|
|
if ( rc == SCESTATUS_SUCCESS &&
|
|
Count > 1 ) {
|
|
//
|
|
// there are other children under this node
|
|
// this is the junction point
|
|
//
|
|
*ParentLevel = i;
|
|
break;
|
|
}
|
|
//
|
|
// dont' care error
|
|
//
|
|
rc = SCESTATUS_SUCCESS;
|
|
|
|
} else {
|
|
|
|
ParentLen = wcslen(Name);
|
|
Status = (BYTE)-1;
|
|
|
|
rc = ScepObjectGetKeySetting(
|
|
hSectionSmp,
|
|
Name,
|
|
&Status,
|
|
NULL,
|
|
&pScepSD,
|
|
&SeInfo
|
|
);
|
|
|
|
if ( rc == SCESTATUS_SUCCESS ) {
|
|
|
|
//
|
|
// find a parent.
|
|
//
|
|
*ParentLevel = i;
|
|
if ( ParentStatus ) {
|
|
*ParentStatus = Status;
|
|
}
|
|
if ( ParentName ) {
|
|
wcscpy(ParentName, Name);
|
|
}
|
|
|
|
if ( (Flag & SCE_OBJECT_TURNOFF_IGNORE) &&
|
|
Status == SCE_STATUS_IGNORE ) {
|
|
//
|
|
// delete all SMP and SAP under this node
|
|
//
|
|
rc = ScepObjectDeleteScepAndAllChildren(
|
|
hSectionSmp,
|
|
hSectionSap,
|
|
Name,
|
|
TRUE,
|
|
SCE_STATUS_NOT_ANALYZED
|
|
);
|
|
/*
|
|
if ( rc == SCESTATUS_SUCCESS ) {
|
|
//
|
|
// change its status to CHECK,
|
|
//
|
|
rc = ScepObjectSetKeySetting(
|
|
hSectionSmp,
|
|
Name,
|
|
SCE_STATUS_CHECK,
|
|
TRUE,
|
|
pScepSD,
|
|
SeInfo,
|
|
TRUE
|
|
);
|
|
}
|
|
*/
|
|
//
|
|
// all other nodes are deleted. should break out of the loop
|
|
//
|
|
}
|
|
|
|
if ( pScepSD ) {
|
|
ScepFree(pScepSD);
|
|
pScepSD = NULL;
|
|
}
|
|
|
|
if ( !(Flag & SCE_OBJECT_TURNOFF_IGNORE) ||
|
|
Status == SCE_STATUS_IGNORE ) {
|
|
|
|
if ( rc == SCESTATUS_RECORD_NOT_FOUND )
|
|
rc = SCESTATUS_SUCCESS;
|
|
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( rc == SCESTATUS_RECORD_NOT_FOUND ) {
|
|
rc = SCESTATUS_SUCCESS;
|
|
}
|
|
|
|
//
|
|
// process next parent
|
|
//
|
|
|
|
if ( rc != SCESTATUS_SUCCESS )
|
|
break;
|
|
}
|
|
|
|
ScepFree(Name);
|
|
|
|
return(rc);
|
|
}
|
|
|
|
SCESTATUS
|
|
ScepObjectHasAnyChild(
|
|
IN PSCESECTION hSection,
|
|
IN PWSTR ObjectName,
|
|
IN DWORD NameLen,
|
|
IN WCHAR Delim,
|
|
OUT PBOOL bpHasChild
|
|
)
|
|
/*
|
|
Routine Description:
|
|
|
|
Detect if the object has child objects in the section
|
|
|
|
Arguements:
|
|
|
|
hSection - the section handle
|
|
|
|
ObjectName - the object name
|
|
|
|
NameLen - the name length
|
|
|
|
Delim - the delimeter to look for
|
|
|
|
bpHasChild - output TRUE if the object has a child in the section
|
|
|
|
Return Value:
|
|
|
|
SCESTATUS
|
|
*/
|
|
{
|
|
SCESTATUS rc;
|
|
PWSTR pTemp=NULL;
|
|
|
|
if ( hSection == NULL || ObjectName == NULL ||
|
|
NameLen == 0 || Delim == L'\0' || bpHasChild == NULL ) {
|
|
|
|
return(SCESTATUS_INVALID_PARAMETER);
|
|
}
|
|
|
|
pTemp = (PWSTR)ScepAlloc(0, (NameLen+2)*sizeof(WCHAR));
|
|
if ( pTemp != NULL ) {
|
|
|
|
wcscpy(pTemp, ObjectName);
|
|
pTemp[NameLen] = Delim;
|
|
pTemp[NameLen+1] = L'\0';
|
|
|
|
rc = SceJetSeek(
|
|
hSection,
|
|
pTemp,
|
|
(NameLen+1)*sizeof(WCHAR),
|
|
SCEJET_SEEK_GE_NO_CASE
|
|
);
|
|
|
|
if ( rc == SCESTATUS_RECORD_NOT_FOUND ) {
|
|
*bpHasChild = FALSE;
|
|
rc = SCESTATUS_SUCCESS;
|
|
|
|
} else if ( rc == SCESTATUS_SUCCESS ) {
|
|
*bpHasChild = TRUE;
|
|
}
|
|
|
|
ScepFree(pTemp);
|
|
|
|
} else
|
|
rc = SCESTATUS_NOT_ENOUGH_RESOURCE;
|
|
|
|
return(rc);
|
|
}
|
|
|
|
|
|
SCESTATUS
|
|
ScepObjectRaiseChildrenInBetween(
|
|
IN PSCESECTION hSectionSmp,
|
|
IN PSCESECTION hSectionSap,
|
|
IN PWSTR ObjectName,
|
|
IN DWORD NameLen,
|
|
IN BOOL IsContainer,
|
|
IN BYTE Status,
|
|
IN BOOL bChangeStatusOnly
|
|
)
|
|
/*
|
|
Routine Description:
|
|
|
|
Delete any SAP entries for objects between Name and its children in SMP table
|
|
and raise SAP entries for bridge nodes to the Status specified.
|
|
|
|
For example, in the picture below, every SAP entry in the 1. level and 2. level
|
|
, except the C nodes, should be deleted from SAP. Then 1. and 2. nodes are
|
|
raised as Status.
|
|
|
|
p
|
|
/
|
|
.
|
|
N <----
|
|
/ |
|
|
1. C
|
|
/ \
|
|
2. C
|
|
/|
|
|
C C
|
|
|
|
Arguments:
|
|
|
|
hSectionSmp - the SMP section handle
|
|
|
|
hSection - the SAP section handle
|
|
|
|
Name - the object name
|
|
|
|
NameLen - the length of the name
|
|
|
|
Status - the object's status to raise
|
|
|
|
|
|
Return Value:
|
|
|
|
SCE status
|
|
*/
|
|
{
|
|
SCESTATUS rc;
|
|
|
|
PWSTR *pSmpNames=NULL;
|
|
DWORD *pSmpNameLen=NULL;
|
|
DWORD cntNames=0;
|
|
BOOL bFirst=TRUE;
|
|
WCHAR Delim=L'\\';
|
|
|
|
DWORD DirLen = wcslen(ObjectName);
|
|
|
|
if ( ObjectName[DirLen-1] != Delim ) {
|
|
DirLen++;
|
|
}
|
|
|
|
PWSTR DirName = (PWSTR)ScepAlloc(0, (DirLen+1)*sizeof(WCHAR));
|
|
|
|
if ( DirName == NULL ) {
|
|
return(SCESTATUS_NOT_ENOUGH_RESOURCE);
|
|
|
|
}
|
|
|
|
wcscpy(DirName, ObjectName);
|
|
|
|
if ( DirName[DirLen-1] != Delim ) {
|
|
DirName[DirLen-1] = Delim;
|
|
}
|
|
|
|
//
|
|
// get all children of DirName in SMP
|
|
//
|
|
rc = SceJetGetLineCount(
|
|
hSectionSmp,
|
|
DirName,
|
|
FALSE,
|
|
&cntNames);
|
|
|
|
DWORD index=0;
|
|
|
|
if ( rc == SCESTATUS_SUCCESS ) {
|
|
|
|
pSmpNames = (PWSTR *)ScepAlloc(LPTR, cntNames*sizeof(PWSTR));
|
|
pSmpNameLen = (DWORD *)ScepAlloc(LPTR, cntNames*sizeof(DWORD));
|
|
|
|
if ( pSmpNames != NULL && pSmpNameLen != NULL ) {
|
|
|
|
//
|
|
// get each name loaded into this array
|
|
//
|
|
PWSTR Buffer=NULL;
|
|
DWORD KeyLen;
|
|
|
|
rc = SceJetGetValue(
|
|
hSectionSmp,
|
|
SCEJET_PREFIX_MATCH_NO_CASE,
|
|
DirName,
|
|
NULL,
|
|
0,
|
|
&KeyLen,
|
|
NULL,
|
|
0,
|
|
NULL
|
|
);
|
|
|
|
bFirst = TRUE;
|
|
|
|
while ( rc == SCESTATUS_SUCCESS ) {
|
|
|
|
Buffer = (PWSTR)ScepAlloc(LPTR, (KeyLen+1)*sizeof(WCHAR));
|
|
|
|
if ( Buffer == NULL ) {
|
|
rc = SCESTATUS_NOT_ENOUGH_RESOURCE;
|
|
break;
|
|
}
|
|
|
|
rc = SceJetGetValue(
|
|
hSectionSmp,
|
|
SCEJET_CURRENT,
|
|
NULL,
|
|
Buffer,
|
|
KeyLen*sizeof(WCHAR),
|
|
NULL,
|
|
NULL,
|
|
0,
|
|
NULL
|
|
);
|
|
|
|
if ( rc == SCESTATUS_SUCCESS ) {
|
|
|
|
if ( !bFirst ||
|
|
_wcsicmp(DirName, Buffer) != 0 ) {
|
|
//
|
|
// ignore the object itself
|
|
//
|
|
pSmpNames[index] = Buffer;
|
|
pSmpNameLen[index] = wcslen(Buffer);
|
|
|
|
Buffer = NULL;
|
|
index++;
|
|
}
|
|
|
|
bFirst = FALSE;
|
|
|
|
} else {
|
|
|
|
ScepFree(Buffer);
|
|
Buffer = NULL;
|
|
break;
|
|
|
|
}
|
|
|
|
//
|
|
// read next line
|
|
//
|
|
rc = SceJetGetValue(
|
|
hSectionSmp,
|
|
SCEJET_NEXT_LINE,
|
|
NULL,
|
|
NULL,
|
|
0,
|
|
&KeyLen,
|
|
NULL,
|
|
0,
|
|
NULL
|
|
);
|
|
}
|
|
|
|
} else {
|
|
|
|
rc = SCESTATUS_NOT_ENOUGH_RESOURCE;
|
|
}
|
|
}
|
|
|
|
if ( SCESTATUS_RECORD_NOT_FOUND == rc ) {
|
|
rc = SCESTATUS_SUCCESS;
|
|
}
|
|
|
|
if ( SCESTATUS_SUCCESS == rc ) {
|
|
|
|
//
|
|
// should have one or more children but if it's 0
|
|
// delete everything in SAP
|
|
//
|
|
if ( cntNames == 0 || pSmpNames == NULL ||
|
|
pSmpNameLen == NULL ||
|
|
pSmpNameLen[0] == 0 || pSmpNames[0] == NULL ) {
|
|
|
|
rc = SceJetDelete(
|
|
hSectionSap,
|
|
DirName,
|
|
TRUE,
|
|
SCEJET_DELETE_PARTIAL_NO_CASE
|
|
);
|
|
|
|
} else if ( !bChangeStatusOnly ) {
|
|
|
|
//
|
|
// get each name loaded into this array
|
|
//
|
|
PWSTR Buffer=NULL;
|
|
DWORD KeyLen;
|
|
|
|
rc = SceJetGetValue(
|
|
hSectionSap,
|
|
SCEJET_PREFIX_MATCH_NO_CASE,
|
|
DirName,
|
|
NULL,
|
|
0,
|
|
&KeyLen,
|
|
NULL,
|
|
0,
|
|
NULL
|
|
);
|
|
|
|
bFirst = TRUE;
|
|
index = 0;
|
|
|
|
while ( rc == SCESTATUS_SUCCESS ) {
|
|
|
|
Buffer = (PWSTR)ScepAlloc(LPTR, (KeyLen+1)*sizeof(WCHAR));
|
|
|
|
if ( Buffer == NULL ) {
|
|
rc = SCESTATUS_NOT_ENOUGH_RESOURCE;
|
|
break;
|
|
}
|
|
|
|
rc = SceJetGetValue(
|
|
hSectionSap,
|
|
SCEJET_CURRENT,
|
|
NULL,
|
|
Buffer,
|
|
KeyLen*sizeof(WCHAR),
|
|
NULL,
|
|
NULL,
|
|
0,
|
|
NULL
|
|
);
|
|
|
|
if ( rc == SCESTATUS_SUCCESS &&
|
|
(!bFirst ||
|
|
_wcsicmp(DirName, Buffer) != 0) ) {
|
|
//
|
|
// ignore the object itself
|
|
// compare with the next child in SMP
|
|
// if it's before the next child, should delete it
|
|
//
|
|
int ci = _wcsnicmp(Buffer, pSmpNames[index], pSmpNameLen[index]);
|
|
|
|
while ( rc == SCESTATUS_SUCCESS &&
|
|
ci > 0 ) {
|
|
//
|
|
// this is the component or next one, move on to next one
|
|
//
|
|
index++;
|
|
|
|
if ( index >= cntNames || pSmpNames[index] == NULL ||
|
|
pSmpNameLen[index] == 0 ) {
|
|
//
|
|
// no more SMP child. We are done.
|
|
//
|
|
rc = SCESTATUS_RECORD_NOT_FOUND;
|
|
|
|
} else {
|
|
|
|
//
|
|
// already bigger than this child
|
|
//
|
|
|
|
ci = _wcsnicmp(Buffer, pSmpNames[index], pSmpNameLen[index]);
|
|
}
|
|
}
|
|
|
|
if ( ci < 0 ) {
|
|
|
|
SceJetDelete(
|
|
hSectionSap,
|
|
NULL, // delete the current line
|
|
FALSE,
|
|
SCEJET_DELETE_LINE
|
|
);
|
|
|
|
}
|
|
}
|
|
|
|
bFirst = FALSE;
|
|
|
|
ScepFree(Buffer);
|
|
Buffer = NULL;
|
|
|
|
if ( rc == SCESTATUS_SUCCESS ) {
|
|
|
|
//
|
|
// read next line
|
|
//
|
|
rc = SceJetGetValue(
|
|
hSectionSap,
|
|
SCEJET_NEXT_LINE,
|
|
NULL,
|
|
NULL,
|
|
0,
|
|
&KeyLen,
|
|
NULL,
|
|
0,
|
|
NULL
|
|
);
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
//
|
|
// raise SAP entries for branch nodes between ObjectName and
|
|
// SMP names as Status, then free smp names array
|
|
//
|
|
if ( SCESTATUS_RECORD_NOT_FOUND == rc ) {
|
|
rc = SCESTATUS_SUCCESS;
|
|
}
|
|
|
|
SCESTATUS rc2 = rc;
|
|
INT StartLevel=0, EndLevel=0;
|
|
|
|
if ( pSmpNames ) {
|
|
|
|
ScepObjectTotalLevel(ObjectName, Delim, &StartLevel);
|
|
StartLevel++;
|
|
|
|
for ( index=0; index<cntNames; index++) {
|
|
if ( pSmpNames[index] ) {
|
|
|
|
if ( SCESTATUS_SUCCESS == rc2 ) {
|
|
//
|
|
// get this object level
|
|
//
|
|
ScepObjectTotalLevel(pSmpNames[index], Delim, &EndLevel);
|
|
|
|
rc2 = ScepObjectRaiseNodesInPath(
|
|
hSectionSap,
|
|
pSmpNames[index],
|
|
pSmpNameLen[index],
|
|
StartLevel,
|
|
EndLevel,
|
|
Delim,
|
|
Status
|
|
);
|
|
|
|
if ( rc2 == SCESTATUS_RECORD_NOT_FOUND ) {
|
|
rc2 = SCESTATUS_SUCCESS;
|
|
}
|
|
if ( rc2 != SCESTATUS_SUCCESS ) {
|
|
rc = rc2;
|
|
}
|
|
}
|
|
|
|
ScepFree(pSmpNames[index]);
|
|
}
|
|
}
|
|
|
|
ScepFree(pSmpNames);
|
|
}
|
|
|
|
if ( pSmpNameLen ) {
|
|
ScepFree(pSmpNameLen);
|
|
}
|
|
|
|
ScepFree(DirName);
|
|
|
|
return rc;
|
|
}
|
|
|
|
|
|
SCESTATUS
|
|
ScepGetFullNameInLevel(
|
|
IN PCWSTR ObjectFullName,
|
|
IN DWORD Level,
|
|
IN WCHAR Delim,
|
|
IN BOOL bWithLastDelim,
|
|
OUT PWSTR Buffer,
|
|
OUT PBOOL LastOne
|
|
)
|
|
/* ++
|
|
Routine Description:
|
|
|
|
This routine parses a full path name and returns the component for the
|
|
level. For example, a object name "c:\winnt\system32" will return c: for
|
|
level 1, winnt for level 2, and system32 for level 3. This routine is
|
|
used when add a object to the security tree.
|
|
|
|
Arguments:
|
|
|
|
ObjectFullName - The full path name of the object
|
|
|
|
Level - the level of component to return
|
|
|
|
Delim - the deliminator to look for
|
|
|
|
Buffer - The address of buffer for the full path name to the level
|
|
|
|
LastOne - Flag to indicate if the component is the last one
|
|
|
|
Return value:
|
|
|
|
SCESTATUS
|
|
|
|
-- */
|
|
{
|
|
PWSTR pTemp, pStart;
|
|
DWORD i;
|
|
ULONG Len = 0;
|
|
|
|
if ( ObjectFullName == NULL )
|
|
return(SCESTATUS_INVALID_PARAMETER);
|
|
|
|
//
|
|
// loop through the object name to find the level
|
|
// if there is no such level, return INVALID_PARAMETER
|
|
//
|
|
pStart = (PWSTR)ObjectFullName;
|
|
|
|
for ( i=0; i<Level; i++) {
|
|
|
|
pTemp = wcschr(pStart, Delim);
|
|
|
|
if ( i == Level-1 ) {
|
|
//
|
|
// find the right level
|
|
//
|
|
if ( pTemp == NULL ) {
|
|
wcscpy(Buffer, ObjectFullName);
|
|
if ( bWithLastDelim ) {
|
|
Len = wcslen(ObjectFullName);
|
|
if (Buffer[Len - 1] != Delim)
|
|
Buffer[Len] = Delim;
|
|
}
|
|
*LastOne = TRUE;
|
|
} else {
|
|
Len = (DWORD)(pTemp - ObjectFullName);
|
|
|
|
if ( bWithLastDelim ) {
|
|
Len++;
|
|
}
|
|
wcsncpy(Buffer, ObjectFullName, Len);
|
|
|
|
if ( *(pTemp+1) == L'\0' )
|
|
*LastOne = TRUE;
|
|
else
|
|
*LastOne = FALSE;
|
|
}
|
|
} else {
|
|
if ( pTemp == NULL )
|
|
return(SCESTATUS_INVALID_PARAMETER);
|
|
else
|
|
pStart = pTemp + 1;
|
|
}
|
|
}
|
|
|
|
return(SCESTATUS_SUCCESS);
|
|
|
|
}
|
|
|
|
|
|
SCESTATUS
|
|
ScepUpdateLocalTable(
|
|
IN PSCECONTEXT hProfile,
|
|
IN AREA_INFORMATION Area,
|
|
IN PSCE_PROFILE_INFO pInfo,
|
|
IN DWORD dwMode
|
|
)
|
|
{
|
|
|
|
SCESTATUS rc=SCESTATUS_SUCCESS;
|
|
|
|
if ( Area & AREA_SECURITY_POLICY ) {
|
|
|
|
rc = ScepUpdateSystemAccess(hProfile,
|
|
pInfo,
|
|
NULL,
|
|
NULL,
|
|
dwMode
|
|
);
|
|
|
|
if ( rc == SCESTATUS_SUCCESS) {
|
|
//
|
|
// Update system auditing section
|
|
//
|
|
rc = ScepUpdateSystemAuditing(hProfile,
|
|
pInfo,
|
|
NULL,
|
|
NULL,
|
|
dwMode);
|
|
|
|
if ( rc == SCESTATUS_SUCCESS) {
|
|
//
|
|
// Update log sections
|
|
//
|
|
rc = ScepUpdateLogs(hProfile,
|
|
pInfo,
|
|
NULL,
|
|
NULL,
|
|
dwMode
|
|
);
|
|
|
|
if ( rc == SCESTATUS_SUCCESS && pInfo->pKerberosInfo ) {
|
|
//
|
|
// Update kerberos policy
|
|
//
|
|
rc = ScepUpdateKerberos(hProfile,
|
|
pInfo->pKerberosInfo,
|
|
NULL,
|
|
NULL,
|
|
dwMode
|
|
);
|
|
}
|
|
if ( rc == SCESTATUS_SUCCESS ) {
|
|
//
|
|
// update registry values
|
|
//
|
|
rc = ScepUpdateLocalRegValues(hProfile,
|
|
pInfo,
|
|
dwMode
|
|
);
|
|
|
|
}
|
|
//
|
|
// Note: policy attachment is not updated through this API
|
|
//
|
|
}
|
|
}
|
|
|
|
if ( rc != SCESTATUS_SUCCESS ) {
|
|
return(rc);
|
|
}
|
|
}
|
|
|
|
if ( Area & AREA_PRIVILEGES ) {
|
|
//
|
|
// update user rights
|
|
//
|
|
rc = ScepUpdateLocalPrivileges(
|
|
hProfile,
|
|
pInfo->OtherInfo.smp.pPrivilegeAssignedTo,
|
|
dwMode
|
|
);
|
|
|
|
}
|
|
|
|
return rc;
|
|
}
|
|
|
|
|
|
SCESTATUS
|
|
ScepUpdateLocalSection(
|
|
IN PSCECONTEXT hProfile,
|
|
IN PSCE_PROFILE_INFO pInfo,
|
|
IN SCE_KEY_LOOKUP *Keys,
|
|
IN DWORD cKeys,
|
|
IN PCWSTR SectionName,
|
|
IN DWORD dwMode
|
|
)
|
|
/*
|
|
Routine Description:
|
|
|
|
Update each key in the Keys array based on the editing rule. SMP entry is
|
|
updated with the new value. SAP entry is either deleted, or created, depending
|
|
on the new computed analysis status.
|
|
|
|
Arguements:
|
|
|
|
hProfile - the jet database handle
|
|
|
|
pInfo - the changed info buffer
|
|
|
|
Keys - the lookup keys array
|
|
|
|
cKeys - the number of keys in the array
|
|
|
|
SecitonName - the section name to work on
|
|
|
|
Return Value:
|
|
|
|
SCESTATUS
|
|
*/
|
|
{
|
|
|
|
SCESTATUS rc;
|
|
PSCESECTION hSectionSmp=NULL;
|
|
|
|
DWORD i;
|
|
UINT Offset;
|
|
DWORD val;
|
|
|
|
|
|
//
|
|
// open smp section for system access
|
|
//
|
|
rc = ScepOpenSectionForName(
|
|
hProfile,
|
|
SCE_ENGINE_SMP,
|
|
SectionName,
|
|
&hSectionSmp
|
|
);
|
|
|
|
if ( rc == SCESTATUS_SUCCESS ) {
|
|
|
|
if ( !( dwMode & SCE_UPDATE_DIRTY_ONLY) ) {
|
|
|
|
SceJetDelete(hSectionSmp, NULL, FALSE, SCEJET_DELETE_SECTION);
|
|
}
|
|
|
|
for ( i=0; i<cKeys; i++) {
|
|
|
|
//
|
|
// get settings in AccessLookup table
|
|
//
|
|
|
|
Offset = Keys[i].Offset;
|
|
|
|
switch ( Keys[i].BufferType ) {
|
|
case 'B':
|
|
break;
|
|
|
|
case 'D':
|
|
|
|
val = *((DWORD *)((CHAR *)pInfo+Offset));
|
|
|
|
if ( val != SCE_NO_VALUE ) {
|
|
//
|
|
// something changed for this one
|
|
//
|
|
if ( ( dwMode & SCE_UPDATE_DIRTY_ONLY ) &&
|
|
( val == SCE_DELETE_VALUE ) ) {
|
|
|
|
rc = SceJetDelete(
|
|
hSectionSmp,
|
|
Keys[i].KeyString,
|
|
FALSE,
|
|
SCEJET_DELETE_LINE_NO_CASE
|
|
);
|
|
} else {
|
|
|
|
//
|
|
// update the SMP entry
|
|
//
|
|
rc = ScepCompareAndSaveIntValue(
|
|
hSectionSmp,
|
|
Keys[i].KeyString,
|
|
FALSE,
|
|
SCE_NO_VALUE,
|
|
val
|
|
);
|
|
}
|
|
|
|
if ( rc == SCESTATUS_RECORD_NOT_FOUND ) {
|
|
//
|
|
// if not find for delete, ignore the error
|
|
//
|
|
rc = SCESTATUS_SUCCESS;
|
|
}
|
|
}
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
if ( rc != SCESTATUS_SUCCESS ) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
SceJetCloseSection(&hSectionSmp, TRUE);
|
|
}
|
|
|
|
return(rc);
|
|
|
|
}
|
|
|
|
|
|
SCESTATUS
|
|
ScepUpdateLocalRegValues(
|
|
IN PSCECONTEXT hProfile,
|
|
IN PSCE_PROFILE_INFO pInfo,
|
|
IN DWORD dwMode
|
|
)
|
|
{
|
|
if ( hProfile == NULL || pInfo == NULL ) {
|
|
return(SCESTATUS_INVALID_PARAMETER);
|
|
}
|
|
|
|
if ( pInfo->RegValueCount == 0 ||
|
|
pInfo->aRegValues == NULL ) {
|
|
//
|
|
// impossible to have a empty buffer to update
|
|
// this buffer should contain all available registry values to configure/analyze
|
|
//
|
|
return(SCESTATUS_SUCCESS);
|
|
}
|
|
|
|
SCESTATUS rc;
|
|
PSCESECTION hSectionSmp=NULL;
|
|
DWORD i;
|
|
|
|
//
|
|
// open smp section for system access
|
|
//
|
|
rc = ScepOpenSectionForName(
|
|
hProfile,
|
|
SCE_ENGINE_SMP,
|
|
szRegistryValues,
|
|
&hSectionSmp
|
|
);
|
|
|
|
if ( rc == SCESTATUS_SUCCESS ) {
|
|
|
|
if ( !(dwMode & SCE_UPDATE_DIRTY_ONLY) ) {
|
|
|
|
SceJetDelete(hSectionSmp, NULL, FALSE, SCEJET_DELETE_SECTION);
|
|
}
|
|
|
|
for (i=0; i<pInfo->RegValueCount; i++ ) {
|
|
|
|
if ( !(pInfo->aRegValues[i].FullValueName) ) {
|
|
continue;
|
|
}
|
|
|
|
if ( ( dwMode & SCE_UPDATE_DIRTY_ONLY) &&
|
|
(pInfo->aRegValues[i].ValueType == SCE_DELETE_VALUE) ) {
|
|
|
|
rc = SceJetDelete(
|
|
hSectionSmp,
|
|
pInfo->aRegValues[i].FullValueName,
|
|
FALSE,
|
|
SCEJET_DELETE_LINE_NO_CASE
|
|
);
|
|
} else {
|
|
|
|
//
|
|
// update the SMP entry
|
|
//
|
|
rc = ScepSaveRegValueEntry(
|
|
hSectionSmp,
|
|
pInfo->aRegValues[i].FullValueName,
|
|
pInfo->aRegValues[i].Value,
|
|
pInfo->aRegValues[i].ValueType,
|
|
0
|
|
);
|
|
}
|
|
|
|
if ( rc == SCESTATUS_RECORD_NOT_FOUND ) {
|
|
//
|
|
// if not find for delete, ignore the error
|
|
//
|
|
rc = SCESTATUS_SUCCESS;
|
|
}
|
|
|
|
if ( SCESTATUS_SUCCESS != rc ) {
|
|
break;
|
|
}
|
|
|
|
}
|
|
|
|
SceJetCloseSection(&hSectionSmp, TRUE);
|
|
}
|
|
|
|
return(rc);
|
|
}
|
|
|
|
|
|
SCESTATUS
|
|
ScepUpdateLocalPrivileges(
|
|
IN PSCECONTEXT hProfile,
|
|
IN PSCE_PRIVILEGE_ASSIGNMENT pNewPriv,
|
|
IN DWORD dwMode
|
|
)
|
|
/*
|
|
Routine Description:
|
|
|
|
Update privileges
|
|
|
|
Arguements:
|
|
|
|
hProfile - the jet database handle
|
|
|
|
pNewPriv - the changed info buffer
|
|
|
|
pBufScep - the original SMP priv buffer
|
|
|
|
Return Value:
|
|
|
|
SCESTATUS
|
|
*/
|
|
{
|
|
if ( hProfile == NULL ) {
|
|
return(SCESTATUS_INVALID_PARAMETER);
|
|
}
|
|
|
|
LSA_HANDLE LsaHandle=NULL;
|
|
SCESTATUS rc;
|
|
|
|
rc = RtlNtStatusToDosError(
|
|
ScepOpenLsaPolicy(
|
|
MAXIMUM_ALLOWED,
|
|
&LsaHandle,
|
|
TRUE
|
|
));
|
|
|
|
if ( ERROR_SUCCESS != rc ) {
|
|
return(ScepDosErrorToSceStatus(rc));
|
|
}
|
|
|
|
PSCESECTION hSectionSmp=NULL;
|
|
|
|
//
|
|
// open smp section for system access
|
|
//
|
|
rc = ScepOpenSectionForName(
|
|
hProfile,
|
|
SCE_ENGINE_SMP,
|
|
szPrivilegeRights,
|
|
&hSectionSmp
|
|
);
|
|
|
|
if ( rc == SCESTATUS_SUCCESS ) {
|
|
|
|
if ( !(dwMode & SCE_UPDATE_DIRTY_ONLY) ) {
|
|
|
|
SceJetDelete(hSectionSmp, NULL, FALSE, SCEJET_DELETE_SECTION);
|
|
}
|
|
|
|
PSCE_PRIVILEGE_ASSIGNMENT pPriv;
|
|
|
|
for ( pPriv=pNewPriv; pPriv != NULL; pPriv = pPriv->Next ) {
|
|
|
|
//
|
|
// Process each privilege in the new list
|
|
//
|
|
if ( pPriv->Name == NULL ) {
|
|
continue;
|
|
}
|
|
|
|
if ( ( dwMode & SCE_UPDATE_DIRTY_ONLY) &&
|
|
( pPriv->Status == SCE_DELETE_VALUE) ) {
|
|
|
|
rc = SceJetDelete(
|
|
hSectionSmp,
|
|
pPriv->Name,
|
|
FALSE,
|
|
SCEJET_DELETE_LINE_NO_CASE
|
|
);
|
|
} else {
|
|
|
|
rc = ScepWriteNameListValue(
|
|
LsaHandle,
|
|
hSectionSmp,
|
|
pPriv->Name,
|
|
pPriv->AssignedTo,
|
|
SCE_WRITE_EMPTY_LIST | SCE_WRITE_CONVERT | SCE_WRITE_LOCAL_TABLE,
|
|
0
|
|
);
|
|
|
|
}
|
|
|
|
if ( rc == SCESTATUS_RECORD_NOT_FOUND )
|
|
rc = SCESTATUS_SUCCESS;
|
|
|
|
if ( rc != SCESTATUS_SUCCESS) {
|
|
break;
|
|
}
|
|
|
|
}
|
|
|
|
SceJetCloseSection(&hSectionSmp, TRUE);
|
|
}
|
|
|
|
if ( LsaHandle ) {
|
|
LsaClose(LsaHandle);
|
|
}
|
|
|
|
return(rc);
|
|
}
|
|
|
|
|
|
DWORD
|
|
ScepConvertNameListFormat(
|
|
IN LSA_HANDLE LsaHandle,
|
|
IN PSCE_NAME_LIST pInList,
|
|
IN DWORD FromFormat,
|
|
IN DWORD ToFormat,
|
|
OUT PSCE_NAME_LIST *ppOutList
|
|
)
|
|
{
|
|
if (LsaHandle == NULL || ppOutList == NULL ) {
|
|
return(ERROR_INVALID_PARAMETER);
|
|
}
|
|
|
|
*ppOutList = NULL;
|
|
|
|
PSCE_NAME_LIST pList;
|
|
DWORD rc = ERROR_SUCCESS;
|
|
PWSTR SidString=NULL;
|
|
|
|
for ( pList=pInList; pList != NULL; pList=pList->Next ) {
|
|
|
|
if ( pList->Name == NULL ) {
|
|
continue;
|
|
}
|
|
|
|
if ( wcschr(pList->Name, L'\\') ) {
|
|
|
|
rc = ScepLookupNameAndAddToSidStringList(
|
|
LsaHandle,
|
|
ppOutList,
|
|
pList->Name,
|
|
wcslen(pList->Name)
|
|
);
|
|
} else if ( ScepLookupNameTable( pList->Name, &SidString ) ) {
|
|
|
|
rc = ScepAddTwoNamesToNameList(
|
|
ppOutList,
|
|
FALSE,
|
|
NULL,
|
|
0,
|
|
SidString,
|
|
wcslen(SidString)
|
|
);
|
|
} else {
|
|
|
|
rc = ScepAddToNameList(ppOutList, pList->Name, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ( rc != ERROR_SUCCESS ) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
if ( rc != ERROR_SUCCESS &&
|
|
(*ppOutList ) ) {
|
|
ScepFreeNameList(*ppOutList);
|
|
*ppOutList = NULL;
|
|
}
|
|
|
|
return(rc);
|
|
}
|
|
|
|
DWORD
|
|
ScepConvertPrivilegeList(
|
|
IN LSA_HANDLE LsaHandle,
|
|
IN PSCE_PRIVILEGE_ASSIGNMENT pFromList,
|
|
IN DWORD FromFormat,
|
|
IN DWORD ToFormat,
|
|
OUT PSCE_PRIVILEGE_ASSIGNMENT *ppToList
|
|
)
|
|
{
|
|
|
|
if ( LsaHandle == NULL || pFromList == NULL || ppToList == NULL ) {
|
|
return(ERROR_INVALID_PARAMETER);
|
|
}
|
|
|
|
if ( FromFormat != 0 ||
|
|
ToFormat != SCE_ACCOUNT_SID_STRING ) {
|
|
return(ERROR_NOT_SUPPORTED);
|
|
}
|
|
|
|
//
|
|
// only support name->sid string convert, for now.
|
|
//
|
|
DWORD rc = ERROR_SUCCESS;
|
|
PSCE_PRIVILEGE_ASSIGNMENT pPriv, pPriv2;
|
|
PSCE_NAME_LIST pTempList=NULL;
|
|
|
|
for ( pPriv=pFromList; pPriv != NULL; pPriv=pPriv->Next ) {
|
|
|
|
if ( pPriv->Name == NULL ) {
|
|
continue;
|
|
}
|
|
|
|
rc = ScepConvertNameListFormat(LsaHandle,
|
|
pPriv->AssignedTo,
|
|
FromFormat,
|
|
ToFormat,
|
|
&pTempList
|
|
);
|
|
|
|
if ( rc != ERROR_SUCCESS ) {
|
|
break;
|
|
}
|
|
|
|
//
|
|
// a sce_privilege_assignment structure. allocate buffer
|
|
//
|
|
pPriv2 = (PSCE_PRIVILEGE_ASSIGNMENT)ScepAlloc( LMEM_ZEROINIT,
|
|
sizeof(SCE_PRIVILEGE_ASSIGNMENT) );
|
|
if ( pPriv2 == NULL ) {
|
|
rc = ERROR_NOT_ENOUGH_MEMORY;
|
|
break;
|
|
}
|
|
|
|
pPriv2->Name = (PWSTR)ScepAlloc( (UINT)0, (wcslen(pPriv->Name)+1)*sizeof(WCHAR));
|
|
if ( pPriv2->Name == NULL ) {
|
|
ScepFree(pPriv2);
|
|
rc = ERROR_NOT_ENOUGH_MEMORY;
|
|
break;
|
|
}
|
|
|
|
wcscpy(pPriv2->Name, pPriv->Name);
|
|
pPriv2->Value = pPriv->Value;
|
|
pPriv2->Status = pPriv->Status;
|
|
|
|
pPriv2->AssignedTo = pTempList;
|
|
pTempList = NULL;
|
|
|
|
pPriv2->Next = *ppToList;
|
|
*ppToList = pPriv2;
|
|
|
|
}
|
|
|
|
if ( pTempList ) {
|
|
ScepFreeNameList(pTempList);
|
|
}
|
|
|
|
if ( rc != ERROR_SUCCESS &&
|
|
(*ppToList) ) {
|
|
//
|
|
// free the output list
|
|
//
|
|
ScepFreePrivilege(*ppToList);
|
|
*ppToList = NULL;
|
|
}
|
|
|
|
return(rc);
|
|
}
|
|
|