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.
1114 lines
31 KiB
1114 lines
31 KiB
/*++
|
|
|
|
Copyright (c) 1996 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
svcsrv.cpp
|
|
|
|
Abstract:
|
|
|
|
Server Service attachment APIs
|
|
|
|
Author:
|
|
|
|
Jin Huang (jinhuang) 23-Jun-1997
|
|
|
|
Revision History:
|
|
|
|
jinhuang 23-Jan-1998 splitted to client-server
|
|
--*/
|
|
#include "serverp.h"
|
|
#include "pfp.h"
|
|
#include "srvrpcp.h"
|
|
#include "service.h"
|
|
#pragma hdrstop
|
|
|
|
//
|
|
// private prototypes
|
|
//
|
|
SCESTATUS
|
|
SceSvcpGetOneKey(
|
|
IN PSCESECTION hSection,
|
|
IN PWSTR Prefix,
|
|
IN DWORD PrefixLen,
|
|
IN SCESVC_INFO_TYPE Type,
|
|
OUT PVOID *Info
|
|
);
|
|
|
|
SCESTATUS
|
|
SceSvcpEnumNext(
|
|
IN PSCESECTION hSection,
|
|
IN DWORD RequestCount,
|
|
IN SCESVC_INFO_TYPE Type,
|
|
OUT PVOID *Info,
|
|
OUT PDWORD CountReturned
|
|
);
|
|
|
|
//
|
|
// prototypes called from RPC interfaces
|
|
//
|
|
|
|
|
|
SCESTATUS
|
|
SceSvcpUpdateInfo(
|
|
IN PSCECONTEXT Context,
|
|
IN PCWSTR ServiceName,
|
|
IN PSCESVC_CONFIGURATION_INFO Info
|
|
)
|
|
/*
|
|
Routine Description:
|
|
|
|
Load service's engine dll and pass the Info buffer to service engine's
|
|
update API (SceSvcAttachmentUpdate). Currently security manager engine
|
|
is not doing any processing for the service data.
|
|
|
|
This routine triggers the update of configuration database and/or
|
|
analysis information by the service engine. Info may contain the
|
|
modifications only, or the whole configuratio data for the service,
|
|
or partial configuration data, depending on the agreement between service
|
|
extension and service engine.
|
|
|
|
This routine does not really write info to security manager database directly,
|
|
instead, it passes the info buffer to the service engine's update interface
|
|
and service engine will determine what and when to write inot the database.
|
|
|
|
Arguments:
|
|
|
|
hProfile - the security database context handle
|
|
|
|
ServiceName - The service's name as used by service control manager
|
|
|
|
Info - The information modified
|
|
|
|
*/
|
|
{
|
|
|
|
if ( Context == NULL || ServiceName == NULL ||
|
|
Info == NULL ) {
|
|
|
|
return(SCESTATUS_INVALID_PARAMETER);
|
|
|
|
}
|
|
|
|
SCESTATUS rc;
|
|
|
|
//
|
|
// get service's dll name
|
|
//
|
|
|
|
DWORD KeyLen;
|
|
PWSTR KeyStr=NULL;
|
|
|
|
KeyLen = wcslen(SCE_ROOT_SERVICE_PATH) + 1 + wcslen(ServiceName);
|
|
|
|
KeyStr = (PWSTR)ScepAlloc(0, (KeyLen+1)*sizeof(WCHAR));
|
|
|
|
if ( KeyStr == NULL ) {
|
|
|
|
return(SCESTATUS_NOT_ENOUGH_RESOURCE);
|
|
|
|
}
|
|
|
|
PWSTR Setting=NULL;
|
|
DWORD RegType;
|
|
|
|
swprintf(KeyStr, L"%s\\%s", SCE_ROOT_SERVICE_PATH, ServiceName);
|
|
KeyStr[KeyLen] = L'\0';
|
|
|
|
rc = ScepRegQueryValue(
|
|
HKEY_LOCAL_MACHINE,
|
|
KeyStr,
|
|
L"ServiceAttachmentPath",
|
|
(PVOID *)&Setting,
|
|
&RegType,
|
|
NULL
|
|
);
|
|
|
|
rc = ScepDosErrorToSceStatus(rc);
|
|
|
|
if ( rc == SCESTATUS_SUCCESS ) {
|
|
|
|
if ( Setting != NULL ) {
|
|
|
|
//
|
|
// load the dll.
|
|
//
|
|
HINSTANCE hService;
|
|
|
|
hService = LoadLibrary(Setting);
|
|
|
|
if ( hService != NULL ) {
|
|
//
|
|
// call SceSvcAttachmentUpdate from the dll
|
|
//
|
|
PF_UpdateService pfTemp;
|
|
|
|
pfTemp = (PF_UpdateService)
|
|
GetProcAddress(hService,
|
|
"SceSvcAttachmentUpdate") ;
|
|
if ( pfTemp != NULL ) {
|
|
|
|
SCEP_HANDLE sceHandle;
|
|
SCESVC_CALLBACK_INFO sceCbInfo;
|
|
|
|
sceHandle.hProfile = (PVOID)Context;
|
|
sceHandle.ServiceName = ServiceName;
|
|
|
|
sceCbInfo.sceHandle = &sceHandle;
|
|
sceCbInfo.pfQueryInfo = &SceCbQueryInfo;
|
|
sceCbInfo.pfSetInfo = &SceCbSetInfo;
|
|
sceCbInfo.pfFreeInfo = &SceSvcpFreeMemory;
|
|
sceCbInfo.pfLogInfo = &ScepLogOutput2;
|
|
|
|
//
|
|
// call the SceSvcAttachmentUpdate from the DLL
|
|
//
|
|
__try {
|
|
|
|
rc = (*pfTemp)((PSCESVC_CALLBACK_INFO)&sceCbInfo, Info );
|
|
|
|
} __except (EXCEPTION_EXECUTE_HANDLER) {
|
|
rc = SCESTATUS_SERVICE_NOT_SUPPORT;
|
|
}
|
|
|
|
} else {
|
|
//
|
|
// this API is not supported
|
|
//
|
|
rc = SCESTATUS_SERVICE_NOT_SUPPORT;
|
|
}
|
|
|
|
//
|
|
// try to free the library handle. If it fails, just leave it
|
|
// to to the process to terminate
|
|
//
|
|
FreeLibrary(hService);
|
|
|
|
} else
|
|
rc = SCESTATUS_SERVICE_NOT_SUPPORT;
|
|
|
|
ScepFree(Setting);
|
|
|
|
} else
|
|
rc = SCESTATUS_SERVICE_NOT_SUPPORT;
|
|
}
|
|
|
|
ScepFree(KeyStr);
|
|
|
|
return(rc);
|
|
|
|
}
|
|
|
|
|
|
SCESTATUS
|
|
SceSvcpQueryInfo(
|
|
IN PSCECONTEXT Context,
|
|
IN SCESVC_INFO_TYPE SceSvcType,
|
|
IN PCWSTR ServiceName,
|
|
IN PWSTR Prefix OPTIONAL,
|
|
IN BOOL bExact,
|
|
OUT PVOID *ppvInfo,
|
|
IN OUT PSCE_ENUMERATION_CONTEXT psceEnumHandle
|
|
)
|
|
/*
|
|
Routine Description:
|
|
|
|
Query information for the service in the configuration/analysis database
|
|
which contains the modified configuration and last analysis information.
|
|
|
|
One enumeration returns maximum SCESVC_ENUMERATION_MAX lines (key/value)
|
|
matching the lpPrefix for the service. If lpPrefix is NULL, all information
|
|
for the service is enumerated. If there is more information, psceEnumHandle
|
|
must be used to get next set of keys/values, until *ppvInfo is NULL or Count is 0.
|
|
|
|
When bExact is set and lpPrefix is not NULL, exact match on the lpPrefix is
|
|
searched and only one line is returned.
|
|
|
|
The output buffer must be freed by SceSvcFree
|
|
|
|
Arguments:
|
|
|
|
Context - the database context handle
|
|
|
|
SceSvcType - the information type to query
|
|
|
|
ServiceName - the service name to query info for
|
|
|
|
Prefix - the optional key name prefix for the query
|
|
|
|
bExact - TRUE = exact match on key
|
|
|
|
ppvInfo - the output buffer
|
|
|
|
psceEnumHandle - the output enumeration handle for next enumeartion
|
|
|
|
*/
|
|
{
|
|
if ( Context == NULL || ppvInfo == NULL ||
|
|
psceEnumHandle == NULL ) {
|
|
|
|
return(SCESTATUS_INVALID_PARAMETER);
|
|
|
|
}
|
|
|
|
PSCESECTION hSection=NULL;
|
|
DOUBLE SectionID;
|
|
SCESTATUS rc;
|
|
|
|
switch ( SceSvcType ) {
|
|
case SceSvcConfigurationInfo:
|
|
//
|
|
// query data in configuration database
|
|
//
|
|
rc = ScepOpenSectionForName(
|
|
Context,
|
|
SCE_ENGINE_SMP,
|
|
ServiceName,
|
|
&hSection
|
|
);
|
|
break;
|
|
|
|
case SceSvcAnalysisInfo:
|
|
//
|
|
// query data in analysis database
|
|
//
|
|
rc = ScepOpenSectionForName(
|
|
Context,
|
|
SCE_ENGINE_SAP,
|
|
ServiceName,
|
|
&hSection
|
|
);
|
|
break;
|
|
|
|
case SceSvcInternalUse:
|
|
case SceSvcMergedPolicyInfo:
|
|
//
|
|
// query data in SCP database
|
|
//
|
|
rc = SceJetGetSectionIDByName(
|
|
Context,
|
|
ServiceName,
|
|
&SectionID
|
|
);
|
|
if ( rc == SCESTATUS_SUCCESS ) {
|
|
|
|
rc = SceJetOpenSection(
|
|
Context,
|
|
SectionID,
|
|
SCEJET_TABLE_SCP,
|
|
&hSection
|
|
);
|
|
}
|
|
break;
|
|
|
|
default:
|
|
rc = SCESTATUS_INVALID_PARAMETER;
|
|
break;
|
|
}
|
|
|
|
if ( rc == SCESTATUS_SUCCESS ) {
|
|
|
|
*ppvInfo = NULL;
|
|
|
|
DWORD PrefixLen, CountReturned;
|
|
|
|
if ( Prefix != NULL ) {
|
|
PrefixLen = wcslen(Prefix);
|
|
} else
|
|
PrefixLen = 0;
|
|
|
|
if ( bExact && Prefix != NULL ) {
|
|
|
|
//
|
|
// one single key match
|
|
//
|
|
|
|
rc = SceSvcpGetOneKey(
|
|
hSection,
|
|
Prefix,
|
|
PrefixLen,
|
|
SceSvcType,
|
|
ppvInfo
|
|
);
|
|
|
|
*psceEnumHandle = 0;
|
|
|
|
} else {
|
|
//
|
|
// count total number of lines matching Prefix
|
|
//
|
|
DWORD LineCount;
|
|
|
|
rc = SceJetGetLineCount(
|
|
hSection,
|
|
Prefix,
|
|
TRUE,
|
|
&LineCount
|
|
);
|
|
|
|
if ( rc == SCESTATUS_SUCCESS && LineCount <= 0 )
|
|
rc = SCESTATUS_RECORD_NOT_FOUND;
|
|
|
|
if ( rc == SCESTATUS_SUCCESS ) {
|
|
|
|
if ( LineCount <= *psceEnumHandle ) {
|
|
//
|
|
// no more entries
|
|
//
|
|
|
|
} else {
|
|
//
|
|
// go to the first line of Prefix
|
|
//
|
|
rc = SceJetSeek(
|
|
hSection,
|
|
Prefix,
|
|
PrefixLen*sizeof(WCHAR),
|
|
SCEJET_SEEK_GE
|
|
);
|
|
|
|
if ( rc == SCESTATUS_SUCCESS ) {
|
|
//
|
|
// skip the first *EnumHandle lines
|
|
//
|
|
JET_ERR JetErr;
|
|
|
|
JetErr = JetMove(hSection->JetSessionID,
|
|
hSection->JetTableID,
|
|
*psceEnumHandle,
|
|
0
|
|
);
|
|
rc = SceJetJetErrorToSceStatus(JetErr);
|
|
|
|
if ( rc == SCESTATUS_SUCCESS ) {
|
|
//
|
|
// find the right start point
|
|
//
|
|
DWORD CountToReturn;
|
|
|
|
if ( LineCount - *psceEnumHandle > SCESVC_ENUMERATION_MAX ) {
|
|
CountToReturn = SCESVC_ENUMERATION_MAX;
|
|
} else
|
|
CountToReturn = LineCount - *psceEnumHandle;
|
|
//
|
|
// get next block of data
|
|
//
|
|
rc = SceSvcpEnumNext(
|
|
hSection,
|
|
CountToReturn,
|
|
SceSvcType,
|
|
ppvInfo,
|
|
&CountReturned
|
|
);
|
|
|
|
if ( rc == SCESTATUS_SUCCESS ) {
|
|
//
|
|
// update the enumeration handle
|
|
//
|
|
*psceEnumHandle += CountReturned;
|
|
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( rc != SCESTATUS_SUCCESS ) {
|
|
|
|
*psceEnumHandle = 0;
|
|
}
|
|
|
|
//
|
|
// close the section
|
|
//
|
|
SceJetCloseSection(&hSection, TRUE);
|
|
}
|
|
|
|
return(rc);
|
|
}
|
|
|
|
|
|
|
|
SCESTATUS
|
|
SceSvcpGetOneKey(
|
|
IN PSCESECTION hSection,
|
|
IN PWSTR Prefix,
|
|
IN DWORD PrefixLen,
|
|
IN SCESVC_INFO_TYPE Type,
|
|
OUT PVOID *Info
|
|
)
|
|
/*
|
|
Read key and value information into *Info for exact matched Prefix
|
|
|
|
*/
|
|
{
|
|
if ( hSection == NULL || Prefix == NULL ||
|
|
Info == NULL ) {
|
|
|
|
return(SCESTATUS_INVALID_PARAMETER);
|
|
}
|
|
|
|
SCESTATUS rc;
|
|
DWORD ValueLen;
|
|
PBYTE Value=NULL;
|
|
|
|
rc = SceJetGetValue(
|
|
hSection,
|
|
SCEJET_EXACT_MATCH,
|
|
Prefix,
|
|
NULL,
|
|
0,
|
|
NULL,
|
|
NULL,
|
|
0,
|
|
&ValueLen
|
|
);
|
|
|
|
if ( rc == SCESTATUS_SUCCESS ) {
|
|
//
|
|
// allocate buffer for Value
|
|
//
|
|
Value = (PBYTE)ScepAlloc(0, ValueLen+2);
|
|
|
|
if ( Value != NULL ) {
|
|
|
|
rc = SceJetGetValue(
|
|
hSection,
|
|
SCEJET_CURRENT,
|
|
NULL,
|
|
NULL,
|
|
0,
|
|
NULL,
|
|
(PWSTR)Value,
|
|
ValueLen,
|
|
&ValueLen
|
|
);
|
|
|
|
if ( rc == SCESTATUS_SUCCESS ) {
|
|
//
|
|
// allocate output buffer and assign
|
|
//
|
|
PSCESVC_ANALYSIS_INFO pAnalysisInfo=NULL;
|
|
PSCESVC_CONFIGURATION_INFO pConfigInfo=NULL;
|
|
|
|
if ( Type == SceSvcAnalysisInfo ) {
|
|
|
|
*Info = ScepAlloc(0, sizeof(SCESVC_ANALYSIS_INFO));
|
|
pAnalysisInfo = (PSCESVC_ANALYSIS_INFO)(*Info);
|
|
|
|
} else {
|
|
*Info = ScepAlloc(0, sizeof(SCESVC_CONFIGURATION_INFO));
|
|
pConfigInfo = (PSCESVC_CONFIGURATION_INFO)(*Info);
|
|
}
|
|
|
|
if ( *Info != NULL ) {
|
|
//
|
|
// Lines buffer
|
|
//
|
|
if ( Type == SceSvcAnalysisInfo ) {
|
|
|
|
pAnalysisInfo->Lines = (PSCESVC_ANALYSIS_LINE)ScepAlloc(0,
|
|
sizeof(SCESVC_ANALYSIS_LINE));
|
|
|
|
if ( pAnalysisInfo->Lines != NULL ) {
|
|
//
|
|
// Key buffer
|
|
//
|
|
pAnalysisInfo->Lines->Key = (PWSTR)ScepAlloc(0, (PrefixLen+1)*sizeof(WCHAR));
|
|
|
|
if ( pAnalysisInfo->Lines->Key != NULL ) {
|
|
|
|
wcscpy( pAnalysisInfo->Lines->Key, Prefix );
|
|
pAnalysisInfo->Lines->Value = Value;
|
|
pAnalysisInfo->Lines->ValueLen = ValueLen;
|
|
|
|
pAnalysisInfo->Count = 1;
|
|
|
|
Value = NULL;
|
|
|
|
|
|
} else {
|
|
//
|
|
// free *Info->Lines
|
|
//
|
|
rc = SCESTATUS_NOT_ENOUGH_RESOURCE;
|
|
ScepFree( pAnalysisInfo->Lines );
|
|
pAnalysisInfo->Lines = NULL;
|
|
}
|
|
|
|
} else
|
|
rc = SCESTATUS_NOT_ENOUGH_RESOURCE;
|
|
|
|
if ( rc != SCESTATUS_SUCCESS ) {
|
|
//
|
|
// free buffer allocate
|
|
//
|
|
ScepFree(*Info);
|
|
*Info = NULL;
|
|
|
|
}
|
|
|
|
} else {
|
|
pConfigInfo->Lines = (PSCESVC_CONFIGURATION_LINE)ScepAlloc(0,
|
|
sizeof(SCESVC_CONFIGURATION_LINE));
|
|
|
|
if ( pConfigInfo->Lines != NULL ) {
|
|
//
|
|
// Key buffer
|
|
//
|
|
pConfigInfo->Lines->Key = (PWSTR)ScepAlloc(0, (PrefixLen+1)*sizeof(WCHAR));
|
|
|
|
if ( pConfigInfo->Lines->Key != NULL ) {
|
|
|
|
wcscpy( pConfigInfo->Lines->Key, Prefix );
|
|
pConfigInfo->Lines->Value = (PWSTR)Value;
|
|
pConfigInfo->Lines->ValueLen = ValueLen;
|
|
|
|
pConfigInfo->Count = 1;
|
|
|
|
Value = NULL;
|
|
|
|
} else {
|
|
//
|
|
// free *Info->Lines
|
|
//
|
|
rc = SCESTATUS_NOT_ENOUGH_RESOURCE;
|
|
ScepFree( pConfigInfo->Lines );
|
|
pConfigInfo->Lines = NULL;
|
|
}
|
|
|
|
} else
|
|
rc = SCESTATUS_NOT_ENOUGH_RESOURCE;
|
|
|
|
if ( rc != SCESTATUS_SUCCESS ) {
|
|
//
|
|
// free buffer allocate
|
|
//
|
|
ScepFree(*Info);
|
|
*Info = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
//
|
|
// free *Info
|
|
//
|
|
if ( rc != SCESTATUS_SUCCESS ) {
|
|
|
|
ScepFree( *Info );
|
|
*Info = NULL;
|
|
}
|
|
|
|
} else
|
|
rc = SCESTATUS_NOT_ENOUGH_RESOURCE;
|
|
}
|
|
|
|
if ( Value != NULL ) {
|
|
ScepFree(Value);
|
|
Value = NULL;
|
|
}
|
|
|
|
}
|
|
}
|
|
return(rc);
|
|
}
|
|
|
|
|
|
SCESTATUS
|
|
SceSvcpEnumNext(
|
|
IN PSCESECTION hSection,
|
|
IN DWORD RequestCount,
|
|
IN SCESVC_INFO_TYPE Type,
|
|
OUT PVOID *Info,
|
|
OUT PDWORD CountReturned
|
|
)
|
|
{
|
|
if ( hSection == NULL || Info == NULL || CountReturned == NULL ) {
|
|
|
|
return(SCESTATUS_INVALID_PARAMETER);
|
|
}
|
|
|
|
if ( RequestCount <= 0 ) {
|
|
*CountReturned = 0;
|
|
|
|
return(SCESTATUS_SUCCESS);
|
|
}
|
|
|
|
SCESTATUS rc=SCESTATUS_SUCCESS;
|
|
|
|
//
|
|
// allocate output buffer
|
|
//
|
|
PSCESVC_ANALYSIS_INFO pAnalysisInfo=NULL;
|
|
PSCESVC_CONFIGURATION_INFO pConfigInfo=NULL;
|
|
|
|
if ( Type == SceSvcAnalysisInfo ) {
|
|
|
|
*Info = ScepAlloc(0, sizeof(SCESVC_ANALYSIS_INFO));
|
|
pAnalysisInfo = (PSCESVC_ANALYSIS_INFO)(*Info);
|
|
|
|
} else {
|
|
|
|
*Info = ScepAlloc(0, sizeof(SCESVC_CONFIGURATION_INFO));
|
|
pConfigInfo = (PSCESVC_CONFIGURATION_INFO)(*Info);
|
|
}
|
|
|
|
if ( *Info != NULL ) {
|
|
|
|
DWORD Count=0;
|
|
|
|
if ( Type == SceSvcAnalysisInfo ) {
|
|
|
|
pAnalysisInfo->Lines = (PSCESVC_ANALYSIS_LINE)ScepAlloc(0,
|
|
RequestCount*sizeof(SCESVC_ANALYSIS_LINE));
|
|
|
|
if ( pAnalysisInfo->Lines == NULL ) {
|
|
rc = SCESTATUS_NOT_ENOUGH_RESOURCE;
|
|
}
|
|
|
|
} else {
|
|
|
|
pConfigInfo->Lines = (PSCESVC_CONFIGURATION_LINE)ScepAlloc(0,
|
|
RequestCount*sizeof(SCESVC_CONFIGURATION_LINE));
|
|
|
|
if ( pConfigInfo->Lines == NULL ) {
|
|
rc = SCESTATUS_NOT_ENOUGH_RESOURCE;
|
|
}
|
|
|
|
}
|
|
|
|
if ( rc == SCESTATUS_SUCCESS ) { // if Lines is NULL, rc will be NOT_ENOUGH_RESOURCE
|
|
|
|
//
|
|
// loop through each line
|
|
//
|
|
DWORD KeyLen, ValueLen;
|
|
PWSTR Key=NULL, Value=NULL;
|
|
|
|
do {
|
|
|
|
rc = SceJetGetValue(
|
|
hSection,
|
|
SCEJET_CURRENT,
|
|
NULL,
|
|
NULL,
|
|
0,
|
|
&KeyLen,
|
|
NULL,
|
|
0,
|
|
&ValueLen
|
|
);
|
|
|
|
if ( rc == SCESTATUS_SUCCESS ) {
|
|
|
|
//
|
|
// allocate memory for the Key and Value
|
|
//
|
|
Key = (PWSTR)ScepAlloc(LMEM_ZEROINIT, KeyLen+2);
|
|
Value = (PWSTR)ScepAlloc( LMEM_ZEROINIT, ValueLen+2);
|
|
|
|
if ( Key == NULL || Value == NULL ) {
|
|
|
|
rc = SCESTATUS_NOT_ENOUGH_RESOURCE;
|
|
|
|
ScepFree(Key);
|
|
ScepFree(Value);
|
|
|
|
} else {
|
|
//
|
|
// Get the Key and Value
|
|
//
|
|
rc = SceJetGetValue(
|
|
hSection,
|
|
SCEJET_CURRENT,
|
|
NULL,
|
|
Key,
|
|
KeyLen,
|
|
&KeyLen,
|
|
Value,
|
|
ValueLen,
|
|
&ValueLen
|
|
);
|
|
|
|
if ( rc == SCESTATUS_SUCCESS ) {
|
|
//
|
|
// assign to the output buffer
|
|
//
|
|
if ( Type == SceSvcAnalysisInfo ) {
|
|
pAnalysisInfo->Lines[Count].Key = Key;
|
|
pAnalysisInfo->Lines[Count].Value = (PBYTE)Value;
|
|
pAnalysisInfo->Lines[Count].ValueLen = ValueLen;
|
|
} else {
|
|
pConfigInfo->Lines[Count].Key = Key;
|
|
pConfigInfo->Lines[Count].Value = Value;
|
|
pConfigInfo->Lines[Count].ValueLen = ValueLen;
|
|
}
|
|
|
|
} else {
|
|
ScepFree(Key);
|
|
ScepFree(Value);
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
//
|
|
// move to next line
|
|
//
|
|
if ( rc == SCESTATUS_SUCCESS ) {
|
|
|
|
rc = SceJetMoveNext(hSection);
|
|
|
|
Count++;
|
|
}
|
|
|
|
} while (rc == SCESTATUS_SUCCESS && Count < RequestCount );
|
|
|
|
}
|
|
|
|
*CountReturned = Count;
|
|
|
|
if (Type == SceSvcAnalysisInfo) {
|
|
|
|
pAnalysisInfo->Count = Count;
|
|
|
|
} else {
|
|
|
|
pConfigInfo->Count = Count;
|
|
}
|
|
|
|
if ( rc == SCESTATUS_RECORD_NOT_FOUND ) {
|
|
rc = SCESTATUS_SUCCESS;
|
|
|
|
} else if ( rc != SCESTATUS_SUCCESS ) {
|
|
//
|
|
// free memory allocated for output buffer
|
|
//
|
|
DWORD i;
|
|
|
|
if (Type == SceSvcAnalysisInfo) {
|
|
|
|
for ( i=0; i<Count; i++ ) {
|
|
ScepFree(pAnalysisInfo->Lines[i].Key);
|
|
ScepFree(pAnalysisInfo->Lines[i].Value);
|
|
}
|
|
|
|
ScepFree(pAnalysisInfo->Lines);
|
|
|
|
} else {
|
|
|
|
for ( i=0; i<Count; i++ ) {
|
|
|
|
ScepFree(pConfigInfo->Lines[i].Key);
|
|
ScepFree(pConfigInfo->Lines[i].Value);
|
|
}
|
|
|
|
ScepFree(pConfigInfo->Lines);
|
|
}
|
|
|
|
ScepFree(*Info);
|
|
*Info = NULL;
|
|
|
|
*CountReturned = 0;
|
|
}
|
|
|
|
} else
|
|
rc = SCESTATUS_NOT_ENOUGH_RESOURCE;
|
|
|
|
return(rc);
|
|
}
|
|
|
|
|
|
SCESTATUS
|
|
SceSvcpSetInfo(
|
|
IN PSCECONTEXT Context,
|
|
IN SCESVC_INFO_TYPE SceSvcType,
|
|
IN PCWSTR ServiceName,
|
|
IN PWSTR Prefix OPTIONAL,
|
|
IN BOOL bExact,
|
|
IN LONG GpoID,
|
|
IN PVOID pvInfo OPTIONAL
|
|
)
|
|
/*
|
|
Routine Description:
|
|
|
|
Save information of a service into security manager internal database. It's up
|
|
to the service to collect/decide the information to write.
|
|
|
|
Type indicates the type of internal database: CONFIGURATION or ANALYSIS.
|
|
|
|
If the service section does not exist, create it.
|
|
|
|
*/
|
|
{
|
|
if (!Context || !ServiceName ) {
|
|
return(SCESTATUS_INVALID_PARAMETER);
|
|
}
|
|
|
|
PSCESECTION hSection=NULL;
|
|
SCESTATUS rc;
|
|
|
|
//
|
|
// open/create the sections
|
|
//
|
|
|
|
rc = SceJetStartTransaction( Context );
|
|
|
|
if ( rc == SCESTATUS_SUCCESS ) {
|
|
|
|
switch ( SceSvcType ) {
|
|
case SceSvcConfigurationInfo:
|
|
|
|
rc = ScepStartANewSection(
|
|
Context,
|
|
&hSection,
|
|
SCEJET_TABLE_SMP,
|
|
ServiceName
|
|
);
|
|
break;
|
|
|
|
case SceSvcAnalysisInfo:
|
|
|
|
rc = ScepStartANewSection(
|
|
Context,
|
|
&hSection,
|
|
SCEJET_TABLE_SAP,
|
|
ServiceName
|
|
);
|
|
break;
|
|
|
|
case SceSvcInternalUse:
|
|
case SceSvcMergedPolicyInfo:
|
|
|
|
rc = ScepStartANewSection(
|
|
Context,
|
|
&hSection,
|
|
SCEJET_TABLE_SCP,
|
|
ServiceName
|
|
);
|
|
break;
|
|
|
|
default:
|
|
rc = SCESTATUS_INVALID_PARAMETER;
|
|
}
|
|
|
|
if ( rc == SCESTATUS_SUCCESS ) {
|
|
|
|
if ( pvInfo == NULL ) {
|
|
//
|
|
// delete the whole section, partial for Prefix, or a single line
|
|
//
|
|
if (Prefix == NULL ) {
|
|
rc = SceJetDelete(
|
|
hSection,
|
|
NULL,
|
|
FALSE,
|
|
SCEJET_DELETE_SECTION
|
|
);
|
|
} else if ( bExact ) {
|
|
//
|
|
// delete single line
|
|
//
|
|
rc = SceJetDelete(
|
|
hSection,
|
|
Prefix,
|
|
FALSE,
|
|
SCEJET_DELETE_LINE
|
|
);
|
|
} else {
|
|
rc = SceJetDelete(
|
|
hSection,
|
|
Prefix,
|
|
FALSE,
|
|
SCEJET_DELETE_PARTIAL
|
|
);
|
|
}
|
|
if ( rc == SCESTATUS_RECORD_NOT_FOUND ) {
|
|
rc = SCESTATUS_SUCCESS;
|
|
}
|
|
|
|
} else {
|
|
//
|
|
// if bExact is not set, delete the whole section first
|
|
//
|
|
if ( !bExact ) {
|
|
rc = SceJetDelete(
|
|
hSection,
|
|
NULL,
|
|
FALSE,
|
|
SCEJET_DELETE_SECTION
|
|
);
|
|
if ( rc == SCESTATUS_RECORD_NOT_FOUND ) {
|
|
rc = SCESTATUS_SUCCESS;
|
|
}
|
|
}
|
|
//
|
|
// overwrite some keys in Info
|
|
//
|
|
DWORD Count;
|
|
PWSTR Key;
|
|
PBYTE Value;
|
|
DWORD ValueLen;
|
|
|
|
if ( SceSvcType == SceSvcAnalysisInfo )
|
|
Count = ((PSCESVC_ANALYSIS_INFO)pvInfo)->Count;
|
|
else
|
|
Count = ((PSCESVC_CONFIGURATION_INFO)pvInfo)->Count;
|
|
|
|
for ( DWORD i=0; i<Count; i++ ) {
|
|
|
|
if ( SceSvcType == SceSvcAnalysisInfo ) {
|
|
|
|
Key = ((PSCESVC_ANALYSIS_INFO)pvInfo)->Lines[i].Key;
|
|
Value = ((PSCESVC_ANALYSIS_INFO)pvInfo)->Lines[i].Value;
|
|
ValueLen = ((PSCESVC_ANALYSIS_INFO)pvInfo)->Lines[i].ValueLen;
|
|
|
|
} else {
|
|
Key = ((PSCESVC_CONFIGURATION_INFO)pvInfo)->Lines[i].Key;
|
|
Value = (PBYTE)(((PSCESVC_CONFIGURATION_INFO)pvInfo)->Lines[i].Value);
|
|
ValueLen = ((PSCESVC_CONFIGURATION_INFO)pvInfo)->Lines[i].ValueLen;
|
|
}
|
|
|
|
rc = SceJetSetLine(
|
|
hSection,
|
|
Key,
|
|
TRUE,
|
|
(PWSTR)Value,
|
|
ValueLen,
|
|
GpoID
|
|
);
|
|
|
|
if ( rc != SCESTATUS_SUCCESS ) {
|
|
break;
|
|
}
|
|
|
|
}
|
|
}
|
|
}
|
|
//
|
|
// close the section
|
|
//
|
|
SceJetCloseSection(&hSection, TRUE);
|
|
|
|
if ( rc == SCESTATUS_SUCCESS ) {
|
|
//
|
|
// commit the change
|
|
//
|
|
rc = SceJetCommitTransaction(Context, 0);
|
|
|
|
}
|
|
if ( rc != SCESTATUS_SUCCESS ) {
|
|
|
|
SceJetRollback(Context, 0);
|
|
}
|
|
}
|
|
|
|
return(rc);
|
|
}
|
|
|
|
//
|
|
// attachment engine call back functions
|
|
//
|
|
|
|
SCESTATUS
|
|
SceCbQueryInfo(
|
|
IN SCE_HANDLE sceHandle,
|
|
IN SCESVC_INFO_TYPE sceType,
|
|
IN LPTSTR lpPrefix OPTIONAL,
|
|
IN BOOL bExact,
|
|
OUT PVOID *ppvInfo,
|
|
OUT PSCE_ENUMERATION_CONTEXT psceEnumHandle
|
|
)
|
|
{
|
|
|
|
PVOID hProfile;
|
|
SCESTATUS rc=ERROR_SUCCESS;
|
|
|
|
__try {
|
|
|
|
hProfile = ((SCEP_HANDLE *)sceHandle)->hProfile;
|
|
|
|
if ( !hProfile ||
|
|
((SCEP_HANDLE *)sceHandle)->ServiceName == NULL ) {
|
|
|
|
rc = SCESTATUS_INVALID_PARAMETER;
|
|
}
|
|
} __except(EXCEPTION_EXECUTE_HANDLER) {
|
|
|
|
rc = SCESTATUS_INVALID_PARAMETER;
|
|
}
|
|
|
|
if ( SCESTATUS_SUCCESS == rc ) {
|
|
|
|
//
|
|
// call the private function
|
|
//
|
|
|
|
rc = SceSvcpQueryInfo(
|
|
(PSCECONTEXT)hProfile,
|
|
sceType,
|
|
((SCEP_HANDLE *)sceHandle)->ServiceName,
|
|
lpPrefix,
|
|
bExact,
|
|
ppvInfo,
|
|
psceEnumHandle
|
|
);
|
|
}
|
|
|
|
return(rc);
|
|
|
|
}
|
|
|
|
SCESTATUS
|
|
SceCbSetInfo(
|
|
IN SCE_HANDLE sceHandle,
|
|
IN SCESVC_INFO_TYPE sceType,
|
|
IN LPTSTR lpPrefix OPTIONAL,
|
|
IN BOOL bExact,
|
|
IN PVOID pvInfo
|
|
)
|
|
{
|
|
|
|
PVOID hProfile;
|
|
SCESTATUS rc=ERROR_SUCCESS;
|
|
|
|
__try {
|
|
|
|
hProfile = ((SCEP_HANDLE *)sceHandle)->hProfile;
|
|
|
|
if ( !hProfile ||
|
|
((SCEP_HANDLE *)sceHandle)->ServiceName == NULL ) {
|
|
|
|
rc = SCESTATUS_INVALID_PARAMETER;
|
|
}
|
|
} __except(EXCEPTION_EXECUTE_HANDLER) {
|
|
|
|
rc = SCESTATUS_INVALID_PARAMETER;
|
|
}
|
|
|
|
if ( SCESTATUS_SUCCESS == rc ) {
|
|
|
|
//
|
|
// call the private function
|
|
//
|
|
|
|
rc = SceSvcpSetInfo(
|
|
(PSCECONTEXT)hProfile,
|
|
sceType,
|
|
((SCEP_HANDLE *)sceHandle)->ServiceName,
|
|
lpPrefix,
|
|
bExact,
|
|
0,
|
|
pvInfo
|
|
);
|
|
|
|
}
|
|
|
|
return(rc);
|
|
|
|
}
|
|
|