3923 lines
118 KiB
C++
3923 lines
118 KiB
C++
/*++
|
||
|
||
Copyright (c) 1996 Microsoft Corporation
|
||
|
||
Module Name:
|
||
|
||
smbsvc.cpp
|
||
|
||
Abstract:
|
||
|
||
File sharing security engine attachment for Security Configuration Editor
|
||
|
||
Author:
|
||
|
||
Jin Huang (jinhuang) 11-Jul-1997
|
||
|
||
Revision History:
|
||
|
||
--*/
|
||
|
||
#include "smbsvcp.h"
|
||
#include "util.h"
|
||
#include "smbdllrc.h"
|
||
#include <lmapibuf.h>
|
||
#pragma hdrstop
|
||
|
||
#define SMBSVC_BUF_LEN 1024
|
||
#define SCESMB_ROOT_PATH SCE_ROOT_SERVICE_PATH TEXT("\\LanManServer")
|
||
|
||
#define SmbsvcServerKey L"System\\CurrentControlSet\\Services\\LanManServer\\Parameters"
|
||
#define SmbsvcRdrKey L"System\\CurrentControlSet\\Services\\MrxSmb\\Parameters"
|
||
|
||
#define SmbsvcEnableSS L"EnableSecuritySignature"
|
||
#define SmbsvcRequireSS L"RequireSecuritySignature"
|
||
#define SmbsvcPlainPassword L"EnablePlainTextPassword"
|
||
#define SmbsvcRequireECR L"RequireEnhancedChallengeResponse"
|
||
#define SmbsvcNTResponse L"SendNTResponseOnly"
|
||
|
||
#define SmbsvcRestrictNull L"RestrictNullSessAccess"
|
||
#define SmbsvcAutoShareServer L"AutoShareServer"
|
||
#define SmbsvcAutoShareWks L"AutoShareWks"
|
||
#define SmbsvcForcedLogOff L"EnableForcedLogOff"
|
||
#define SmbsvcAutoDisconnect L"AutoDisconnect"
|
||
|
||
#define NUM_COMP 14
|
||
|
||
#if defined(_NT4BACK_PORT)
|
||
|
||
HINSTANCE MyModuleHandle = NULL;
|
||
|
||
#else
|
||
/*
|
||
#if !defined(Thread)
|
||
#define Thread __declspec( thread )
|
||
#endif
|
||
HINSTANCE Thread MyModuleHandle=NULL;
|
||
*/
|
||
|
||
HINSTANCE MyModuleHandle=NULL;
|
||
|
||
#endif
|
||
|
||
static NT_PRODUCT_TYPE ProductType;
|
||
|
||
GENERIC_MAPPING ShareGenMap = {
|
||
STANDARD_RIGHTS_READ | SYNCHRONIZE | 0x1,
|
||
STANDARD_RIGHTS_WRITE | SYNCHRONIZE | 0x2,
|
||
STANDARD_RIGHTS_EXECUTE | SYNCHRONIZE | 0x4,
|
||
STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0x1FF
|
||
};
|
||
|
||
SCESTATUS
|
||
SmbsvcpResetInfo(
|
||
IN PSMBSVC_SEC_INFO pInfo
|
||
);
|
||
|
||
SCESTATUS
|
||
SmbsvcpGetInformation(
|
||
IN PSCESVC_CALLBACK_INFO pSceCbInfo,
|
||
OUT PSMBSVC_SEC_INFO pSmbInfo
|
||
);
|
||
|
||
SCESTATUS
|
||
SmbsvcpAddAShareToList(
|
||
OUT PSMBSVC_SHARES *pShareList,
|
||
IN PWSTR ShareName,
|
||
IN DWORD Status,
|
||
IN PSECURITY_DESCRIPTOR pSD
|
||
);
|
||
|
||
SCESTATUS
|
||
SmbsvcpFree(
|
||
IN PSMBSVC_SEC_INFO pSmbInfo
|
||
);
|
||
|
||
SCESTATUS
|
||
SmbsvcpFreeShareList(
|
||
PSMBSVC_SHARES pShares
|
||
);
|
||
|
||
SCESTATUS
|
||
SmbsvcpWriteError(
|
||
IN PFSCE_LOG_INFO pfLogCallback,
|
||
IN INT ErrLevel,
|
||
IN DWORD ErrCode,
|
||
IN PWSTR Mes
|
||
);
|
||
|
||
SCESTATUS
|
||
SmbsvcpWriteError2(
|
||
IN PFSCE_LOG_INFO pfLogCallback,
|
||
IN INT ErrLevel,
|
||
IN DWORD ErrCode,
|
||
IN UINT nId,
|
||
...
|
||
);
|
||
|
||
SCESTATUS
|
||
SmbsvcpConfigureValue(
|
||
IN PCWSTR RegKey,
|
||
IN PCWSTR ValueName,
|
||
IN DWORD Value
|
||
);
|
||
|
||
SCESTATUS
|
||
SmbsvcpQueryShareList(
|
||
OUT PSMBSVC_SHARES *pShareList,
|
||
OUT PDWORD ShareCount
|
||
);
|
||
|
||
SCESTATUS
|
||
SmbsvcpAnalyzeValue(
|
||
IN PCWSTR RegKey,
|
||
IN PCWSTR RegValueName,
|
||
IN PCWSTR KeyName,
|
||
IN DWORD ConfigValue,
|
||
OUT PSCESVC_ANALYSIS_LINE pLineInfo,
|
||
IN OUT PDWORD pCount
|
||
);
|
||
|
||
DWORD
|
||
SmbsvcpConvertStringToMultiSz(
|
||
IN PWSTR theStr,
|
||
IN DWORD theLen,
|
||
OUT PBYTE *outValue,
|
||
OUT PDWORD outLen
|
||
);
|
||
|
||
SCESTATUS
|
||
SmbsvcpAnalyzeMultiSzString(
|
||
IN PCWSTR RegKey,
|
||
IN PCWSTR RegValueName,
|
||
IN PWSTR pConfigInfo,
|
||
IN DWORD InfoLength,
|
||
OUT PSCESVC_ANALYSIS_LINE pLineInfo,
|
||
IN OUT PDWORD pCount
|
||
);
|
||
|
||
DWORD
|
||
SmbsvcpChangeMultiSzToString(
|
||
IN PWSTR Value
|
||
);
|
||
|
||
DWORD
|
||
SmbsvcpCompareMultiSzString(
|
||
IN PWSTR pConfigInfo,
|
||
IN PWSTR Value,
|
||
OUT PDWORD pValueLen,
|
||
OUT PBOOL pDiff
|
||
);
|
||
|
||
DWORD
|
||
SmbsvcpCountComponents(
|
||
IN PWSTR Value,
|
||
OUT PDWORD ValueLen,
|
||
OUT PDWORD Count
|
||
);
|
||
|
||
SCESTATUS
|
||
SmbsvcpUpdateMultiSzString(
|
||
IN PSCESVC_CALLBACK_INFO pSceCbInfo,
|
||
IN SCESVC_CONFIGURATION_LINE NewLine,
|
||
IN PSCESVC_CONFIGURATION_INFO pConfigInfo OPTIONAL,
|
||
IN PSCESVC_ANALYSIS_INFO pAnaInfo OPTIONAL
|
||
);
|
||
|
||
SCESTATUS
|
||
SmbsvcpUpdateShareValue(
|
||
IN PSCESVC_CALLBACK_INFO pSceCbInfo,
|
||
IN SCESVC_CONFIGURATION_LINE NewLine,
|
||
IN PSCESVC_CONFIGURATION_INFO pConfigInfo OPTIONAL,
|
||
IN PSCESVC_ANALYSIS_INFO pAnaInfo OPTIONAL
|
||
);
|
||
|
||
SCESTATUS
|
||
SmbsvcpEqualSecurityDescriptor(
|
||
IN PSECURITY_DESCRIPTOR pSD1,
|
||
IN PSECURITY_DESCRIPTOR pSD2,
|
||
IN BOOL bExplicitOnly,
|
||
OUT PBOOL pbEqual
|
||
);
|
||
|
||
DWORD
|
||
SmbsvcEveryoneFullAccess(
|
||
IN PACL pAcl,
|
||
IN BOOL bExplicit,
|
||
OUT PBOOL pbEqual
|
||
);
|
||
|
||
DWORD
|
||
SmbsvcpCompareAcl(
|
||
IN PACL pAcl1,
|
||
IN PACL pAcl2,
|
||
IN BOOL bExplicitOnly,
|
||
OUT PBOOL pDifferent
|
||
);
|
||
|
||
DWORD
|
||
SmbsvcpAnyExplicitAcl(
|
||
IN PACL Acl,
|
||
IN DWORD Processed,
|
||
OUT PBOOL pExist
|
||
);
|
||
|
||
BOOL
|
||
SmbsvcpEqualAce(
|
||
IN ACE_HEADER *pAce1,
|
||
IN ACE_HEADER *pAce2
|
||
);
|
||
|
||
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||
// Implementation of well-known interfaces
|
||
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||
|
||
SCESTATUS
|
||
WINAPI
|
||
SceSvcAttachmentConfig(
|
||
IN PSCESVC_CALLBACK_INFO pSceCbInfo
|
||
)
|
||
/*
|
||
Routine Description:
|
||
|
||
|
||
Arguments:
|
||
|
||
pSceCbInfo - the callback info structure which contains the database handle,
|
||
callback functions to query info, set info, and free info.
|
||
All configuration information for SMB server is stored in the storage.
|
||
|
||
Return Value:
|
||
|
||
SCESTATUS
|
||
*/
|
||
{
|
||
if ( pSceCbInfo == NULL ||
|
||
pSceCbInfo->sceHandle == NULL ||
|
||
pSceCbInfo->pfQueryInfo == NULL ||
|
||
pSceCbInfo->pfSetInfo == NULL ||
|
||
pSceCbInfo->pfFreeInfo == NULL ) {
|
||
|
||
return(SCESTATUS_INVALID_PARAMETER);
|
||
}
|
||
|
||
if ( !RtlGetNtProductType(&ProductType) ) {
|
||
|
||
return(SmbsvcpDosErrorToSceStatus(GetLastError()));
|
||
}
|
||
|
||
SCESTATUS rc;
|
||
SMBSVC_SEC_INFO SmbInfo;
|
||
PSMBSVC_SEC_INFO pSmbInfo=&SmbInfo;
|
||
|
||
SmbsvcpResetInfo(&SmbInfo);
|
||
|
||
SmbsvcpWriteError2(
|
||
pSceCbInfo->pfLogInfo,
|
||
SCE_LOG_LEVEL_DETAIL,
|
||
0,
|
||
SMBSVC_QUERY_INFO
|
||
);
|
||
|
||
rc = SmbsvcpGetInformation(
|
||
pSceCbInfo,
|
||
pSmbInfo
|
||
);
|
||
|
||
if ( rc == SCESTATUS_SUCCESS ) {
|
||
//
|
||
// configure the registry keys first
|
||
//
|
||
|
||
SmbsvcpWriteError2(
|
||
pSceCbInfo->pfLogInfo,
|
||
SCE_LOG_LEVEL_DETAIL,
|
||
0,
|
||
SMBSVC_CONFIGURE_CLIENT_START
|
||
);
|
||
|
||
SCESTATUS rc2;
|
||
|
||
//
|
||
// EnableSecuritySignature for client
|
||
//
|
||
rc2 = SmbsvcpConfigureValue(
|
||
SmbsvcRdrKey,
|
||
SmbsvcEnableSS,
|
||
pSmbInfo->EnableClientSecuritySignature
|
||
);
|
||
if ( rc2 != SCESTATUS_SUCCESS ) {
|
||
|
||
SmbsvcpWriteError2(pSceCbInfo->pfLogInfo,
|
||
SCE_LOG_LEVEL_ERROR,
|
||
SmbsvcpSceStatusToDosError(rc2),
|
||
SMBSVC_ERROR_CONFIGURE,
|
||
SmbsvcEnableSS);
|
||
|
||
if ( rc == SCESTATUS_SUCCESS &&
|
||
rc2 != SCESTATUS_PROFILE_NOT_FOUND ) {
|
||
rc = rc2;
|
||
}
|
||
}
|
||
//
|
||
// RequireSecuritySignature for client
|
||
//
|
||
rc2 = SmbsvcpConfigureValue(
|
||
SmbsvcRdrKey,
|
||
SmbsvcRequireSS,
|
||
pSmbInfo->RequireClientSecuritySignature
|
||
);
|
||
if ( rc2 != SCESTATUS_SUCCESS ) {
|
||
|
||
SmbsvcpWriteError2(pSceCbInfo->pfLogInfo,
|
||
SCE_LOG_LEVEL_ERROR,
|
||
SmbsvcpSceStatusToDosError(rc2),
|
||
SMBSVC_ERROR_CONFIGURE,
|
||
SmbsvcRequireSS);
|
||
|
||
if ( rc == SCESTATUS_SUCCESS && rc2 != SCESTATUS_PROFILE_NOT_FOUND )
|
||
rc = rc2;
|
||
}
|
||
//
|
||
// EnablePlainTextPassword (client only)
|
||
//
|
||
rc2 = SmbsvcpConfigureValue(
|
||
SmbsvcRdrKey,
|
||
SmbsvcPlainPassword,
|
||
pSmbInfo->EnablePlainTextPassword
|
||
);
|
||
if ( rc2 != SCESTATUS_SUCCESS ) {
|
||
|
||
SmbsvcpWriteError2(pSceCbInfo->pfLogInfo,
|
||
SCE_LOG_LEVEL_ERROR,
|
||
SmbsvcpSceStatusToDosError(rc2),
|
||
SMBSVC_ERROR_CONFIGURE,
|
||
SmbsvcPlainPassword);
|
||
|
||
if ( rc == SCESTATUS_SUCCESS && rc2 != SCESTATUS_PROFILE_NOT_FOUND )
|
||
rc = rc2;
|
||
}
|
||
|
||
//
|
||
// RequireEnhancedChallengeResponse (client only)
|
||
//
|
||
rc2 = SmbsvcpConfigureValue(
|
||
SmbsvcRdrKey,
|
||
SmbsvcRequireECR,
|
||
pSmbInfo->RequireEnhancedChallengeResponse
|
||
);
|
||
if ( rc2 != SCESTATUS_SUCCESS ) {
|
||
|
||
SmbsvcpWriteError2(pSceCbInfo->pfLogInfo,
|
||
SCE_LOG_LEVEL_ERROR,
|
||
SmbsvcpSceStatusToDosError(rc2),
|
||
SMBSVC_ERROR_CONFIGURE,
|
||
SmbsvcRequireECR);
|
||
|
||
if ( rc == SCESTATUS_SUCCESS && rc2 != SCESTATUS_PROFILE_NOT_FOUND )
|
||
rc = rc2;
|
||
}
|
||
//
|
||
// SendNTResponseOnly (client only)
|
||
//
|
||
rc2 = SmbsvcpConfigureValue(
|
||
SmbsvcRdrKey,
|
||
SmbsvcNTResponse,
|
||
pSmbInfo->SendNTResponseOnly
|
||
);
|
||
if ( rc2 != SCESTATUS_SUCCESS ) {
|
||
|
||
SmbsvcpWriteError2(pSceCbInfo->pfLogInfo,
|
||
SCE_LOG_LEVEL_ERROR,
|
||
SmbsvcpSceStatusToDosError(rc2),
|
||
SMBSVC_ERROR_CONFIGURE,
|
||
SmbsvcNTResponse);
|
||
|
||
if ( rc == SCESTATUS_SUCCESS && rc2 != SCESTATUS_PROFILE_NOT_FOUND )
|
||
rc = rc2;
|
||
}
|
||
|
||
if ( SCESTATUS_SUCCESS == rc ) {
|
||
|
||
SmbsvcpWriteError2(
|
||
pSceCbInfo->pfLogInfo,
|
||
SCE_LOG_LEVEL_DETAIL,
|
||
0,
|
||
SMBSVC_CONFIGURE_CLIENT_DONE
|
||
);
|
||
}
|
||
|
||
//
|
||
// !!!!!!!! server settings !!!!!!!!!
|
||
//
|
||
SmbsvcpWriteError2(
|
||
pSceCbInfo->pfLogInfo,
|
||
SCE_LOG_LEVEL_DETAIL,
|
||
0,
|
||
SMBSVC_CONFIGURE_SERVER_START
|
||
);
|
||
|
||
SCESTATUS rc3 = rc;
|
||
rc = SCESTATUS_SUCCESS;
|
||
|
||
//
|
||
// EnableSecuritySignature for server
|
||
//
|
||
rc2 = SmbsvcpConfigureValue(
|
||
SmbsvcServerKey,
|
||
SmbsvcEnableSS,
|
||
pSmbInfo->EnableServerSecuritySignature
|
||
);
|
||
if ( rc2 != SCESTATUS_SUCCESS ) {
|
||
|
||
SmbsvcpWriteError2(pSceCbInfo->pfLogInfo,
|
||
SCE_LOG_LEVEL_ERROR,
|
||
SmbsvcpSceStatusToDosError(rc2),
|
||
SMBSVC_ERROR_CONFIGURE,
|
||
SmbsvcEnableSS);
|
||
|
||
if ( rc == SCESTATUS_SUCCESS && rc2 != SCESTATUS_PROFILE_NOT_FOUND )
|
||
rc = rc2;
|
||
}
|
||
|
||
//
|
||
// RequireSecuritySignature for server
|
||
//
|
||
rc2 = SmbsvcpConfigureValue(
|
||
SmbsvcServerKey,
|
||
SmbsvcRequireSS,
|
||
pSmbInfo->RequireServerSecuritySignature
|
||
);
|
||
if ( rc2 != SCESTATUS_SUCCESS ) {
|
||
|
||
SmbsvcpWriteError2(pSceCbInfo->pfLogInfo,
|
||
SCE_LOG_LEVEL_ERROR,
|
||
SmbsvcpSceStatusToDosError(rc2),
|
||
SMBSVC_ERROR_CONFIGURE,
|
||
SmbsvcRequireSS);
|
||
|
||
if ( rc == SCESTATUS_SUCCESS && rc2 != SCESTATUS_PROFILE_NOT_FOUND )
|
||
rc = rc2;
|
||
}
|
||
//
|
||
// RestrictNullSessionAccess
|
||
//
|
||
rc2 = SmbsvcpConfigureValue(
|
||
SmbsvcServerKey,
|
||
SmbsvcRestrictNull,
|
||
pSmbInfo->RestrictNullSessionAccess
|
||
);
|
||
if ( rc2 != SCESTATUS_SUCCESS ) {
|
||
|
||
SmbsvcpWriteError2(pSceCbInfo->pfLogInfo,
|
||
SCE_LOG_LEVEL_ERROR,
|
||
SmbsvcpSceStatusToDosError(rc2),
|
||
SMBSVC_ERROR_CONFIGURE,
|
||
SmbsvcRestrictNull);
|
||
|
||
if ( rc == SCESTATUS_SUCCESS && rc2 != SCESTATUS_PROFILE_NOT_FOUND )
|
||
rc = rc2;
|
||
}
|
||
|
||
//
|
||
// AutoShareServer or AutoShareWks
|
||
//
|
||
PCWSTR AutoValueName;
|
||
|
||
if ( ProductType == NtProductLanManNt ||
|
||
ProductType == NtProductServer) {
|
||
AutoValueName = SmbsvcAutoShareServer;
|
||
} else {
|
||
AutoValueName = SmbsvcAutoShareWks;
|
||
}
|
||
|
||
rc2 = SmbsvcpConfigureValue(
|
||
SmbsvcServerKey,
|
||
AutoValueName,
|
||
pSmbInfo->EnableAutoShare
|
||
);
|
||
if ( rc2 != SCESTATUS_SUCCESS ) {
|
||
|
||
SmbsvcpWriteError2(pSceCbInfo->pfLogInfo,
|
||
SCE_LOG_LEVEL_ERROR,
|
||
SmbsvcpSceStatusToDosError(rc2),
|
||
SMBSVC_ERROR_CONFIGURE,
|
||
(PWSTR)AutoValueName);
|
||
|
||
if ( rc == SCESTATUS_SUCCESS && rc2 != SCESTATUS_PROFILE_NOT_FOUND )
|
||
rc = rc2;
|
||
}
|
||
|
||
//
|
||
// EnableForcedLogOff
|
||
//
|
||
rc2 = SmbsvcpConfigureValue(
|
||
SmbsvcServerKey,
|
||
SmbsvcForcedLogOff,
|
||
pSmbInfo->EnableForcedLogOff
|
||
);
|
||
if ( rc2 != SCESTATUS_SUCCESS ) {
|
||
|
||
SmbsvcpWriteError2(pSceCbInfo->pfLogInfo,
|
||
SCE_LOG_LEVEL_ERROR,
|
||
SmbsvcpSceStatusToDosError(rc2),
|
||
SMBSVC_ERROR_CONFIGURE,
|
||
SmbsvcForcedLogOff);
|
||
|
||
if ( rc == SCESTATUS_SUCCESS && rc2 != SCESTATUS_PROFILE_NOT_FOUND )
|
||
rc = rc2;
|
||
}
|
||
//
|
||
// AutoDisconnectTime
|
||
//
|
||
rc2 = SmbsvcpConfigureValue(
|
||
SmbsvcServerKey,
|
||
SmbsvcAutoDisconnect,
|
||
pSmbInfo->AutoDisconnect
|
||
);
|
||
if ( rc2 != SCESTATUS_SUCCESS ) {
|
||
|
||
SmbsvcpWriteError2(pSceCbInfo->pfLogInfo,
|
||
SCE_LOG_LEVEL_ERROR,
|
||
SmbsvcpSceStatusToDosError(rc2),
|
||
SMBSVC_ERROR_CONFIGURE,
|
||
SmbsvcAutoDisconnect);
|
||
|
||
if ( rc == SCESTATUS_SUCCESS && rc2 != SCESTATUS_PROFILE_NOT_FOUND )
|
||
rc = rc2;
|
||
}
|
||
|
||
//
|
||
// configure Null Session Pipes and Shares
|
||
//
|
||
// buffer NullSessionPipes and NullSessionShares are already in MULTI_SZ format
|
||
//
|
||
DWORD Win32rc;
|
||
PBYTE MultiSzValue=NULL;
|
||
DWORD MultiSzLength=0;
|
||
|
||
if ( pSmbInfo->LengthPipes != SMBSVC_NO_VALUE ) {
|
||
|
||
Win32rc = SmbsvcpConvertStringToMultiSz(
|
||
pSmbInfo->NullSessionPipes,
|
||
pSmbInfo->LengthPipes,
|
||
&MultiSzValue,
|
||
&MultiSzLength
|
||
);
|
||
if ( Win32rc == ERROR_SUCCESS ) {
|
||
|
||
Win32rc = SmbsvcpRegSetValue(
|
||
HKEY_LOCAL_MACHINE,
|
||
SmbsvcServerKey,
|
||
L"NullSessionPipes",
|
||
REG_MULTI_SZ,
|
||
MultiSzValue,
|
||
MultiSzLength
|
||
);
|
||
}
|
||
|
||
if ( Win32rc != ERROR_SUCCESS ) {
|
||
|
||
SmbsvcpWriteError2(pSceCbInfo->pfLogInfo,
|
||
SCE_LOG_LEVEL_ERROR,
|
||
Win32rc,
|
||
SMBSVC_ERROR_CONFIGURE,
|
||
L"NullSessionPipes");
|
||
|
||
if ( rc == SCESTATUS_SUCCESS && Win32rc != ERROR_FILE_NOT_FOUND )
|
||
rc = SmbsvcpDosErrorToSceStatus(Win32rc);;
|
||
}
|
||
}
|
||
|
||
if ( pSmbInfo->LengthShares != SMBSVC_NO_VALUE ) {
|
||
|
||
Win32rc = SmbsvcpConvertStringToMultiSz(
|
||
pSmbInfo->NullSessionShares,
|
||
pSmbInfo->LengthShares,
|
||
&MultiSzValue,
|
||
&MultiSzLength
|
||
);
|
||
if ( Win32rc == ERROR_SUCCESS ) {
|
||
|
||
Win32rc = SmbsvcpRegSetValue(
|
||
HKEY_LOCAL_MACHINE,
|
||
SmbsvcServerKey,
|
||
L"NullSessionShares",
|
||
REG_MULTI_SZ,
|
||
(PBYTE)(pSmbInfo->NullSessionShares),
|
||
pSmbInfo->LengthShares
|
||
);
|
||
}
|
||
|
||
if ( Win32rc != ERROR_SUCCESS ) {
|
||
|
||
SmbsvcpWriteError2(pSceCbInfo->pfLogInfo,
|
||
SCE_LOG_LEVEL_ERROR,
|
||
Win32rc,
|
||
SMBSVC_ERROR_CONFIGURE,
|
||
L"NullSessionShares");
|
||
|
||
if ( rc == SCESTATUS_SUCCESS && Win32rc != ERROR_FILE_NOT_FOUND )
|
||
rc = SmbsvcpDosErrorToSceStatus(Win32rc);;
|
||
}
|
||
|
||
}
|
||
|
||
//
|
||
// configure security on existing shares
|
||
//
|
||
SHARE_INFO_1501 ShareInfo;
|
||
PSMBSVC_SHARES pTemp;
|
||
|
||
for ( pTemp=pSmbInfo->pShares; pTemp != NULL;
|
||
pTemp = pTemp->Next) {
|
||
|
||
ShareInfo.shi1501_reserved = 0;
|
||
ShareInfo.shi1501_security_descriptor = pTemp->pShareSD;
|
||
|
||
Win32rc = NetShareSetInfo (
|
||
NULL,
|
||
pTemp->ShareName,
|
||
1501,
|
||
(LPBYTE)&ShareInfo,
|
||
NULL
|
||
);
|
||
|
||
|
||
if ( Win32rc != ERROR_SUCCESS ) {
|
||
|
||
SmbsvcpWriteError2(pSceCbInfo->pfLogInfo,
|
||
SCE_LOG_LEVEL_ERROR,
|
||
Win32rc,
|
||
SMBSVC_ERROR_CONFIGURE,
|
||
pTemp->ShareName);
|
||
|
||
if ( rc == SCESTATUS_SUCCESS )
|
||
rc = SmbsvcpDosErrorToSceStatus(Win32rc);;
|
||
}
|
||
//
|
||
// continue to configure even if error occurs
|
||
//
|
||
}
|
||
|
||
if ( SCESTATUS_SUCCESS == rc ) {
|
||
|
||
SmbsvcpWriteError2(pSceCbInfo->pfLogInfo,
|
||
SCE_LOG_LEVEL_DETAIL,
|
||
0,
|
||
SMBSVC_CONFIGURE_SERVER_DONE
|
||
);
|
||
rc = rc3; // saved status for client configuration
|
||
|
||
}
|
||
//
|
||
// free memory
|
||
//
|
||
SmbsvcpFree(pSmbInfo);
|
||
}
|
||
|
||
return(rc);
|
||
|
||
}
|
||
|
||
|
||
|
||
SCESTATUS
|
||
WINAPI
|
||
SceSvcAttachmentAnalyze(
|
||
IN PSCESVC_CALLBACK_INFO pSceCbInfo
|
||
)
|
||
/*
|
||
Routine Description:
|
||
|
||
|
||
Arguments:
|
||
|
||
pSceCbInfo - the callback info structure which contains a opaque database handle
|
||
and callback function pointers to query info, set info, and free info.
|
||
Only mismatched info for SMB server is stored in the storage.
|
||
|
||
Return Value:
|
||
|
||
SCESTATUS
|
||
*/
|
||
{
|
||
if ( pSceCbInfo == NULL ||
|
||
pSceCbInfo->sceHandle == NULL ||
|
||
pSceCbInfo->pfQueryInfo == NULL ||
|
||
pSceCbInfo->pfSetInfo == NULL ||
|
||
pSceCbInfo->pfFreeInfo == NULL ) {
|
||
|
||
return(SCESTATUS_INVALID_PARAMETER);
|
||
}
|
||
|
||
if ( !RtlGetNtProductType(&ProductType) )
|
||
return(SmbsvcpDosErrorToSceStatus(GetLastError()));
|
||
|
||
SCESTATUS rc, Saverc;
|
||
SMBSVC_SEC_INFO SmbInfo;
|
||
PSMBSVC_SEC_INFO pSmbInfo=&SmbInfo;
|
||
|
||
PWSTR ErrPoint=NULL;
|
||
WCHAR Errbuf[64];
|
||
|
||
//
|
||
// reset the Smb buffer
|
||
//
|
||
SmbsvcpResetInfo(&SmbInfo);
|
||
|
||
|
||
SmbsvcpWriteError2(
|
||
pSceCbInfo->pfLogInfo,
|
||
SCE_LOG_LEVEL_DETAIL,
|
||
0,
|
||
SMBSVC_QUERY_INFO
|
||
);
|
||
|
||
//
|
||
// get configuration information
|
||
//
|
||
rc = SmbsvcpGetInformation(
|
||
pSceCbInfo,
|
||
pSmbInfo
|
||
);
|
||
|
||
if ( rc == SCESTATUS_SUCCESS ) {
|
||
|
||
// rc == SCESTATUS_RECORD_NOT_FOUND ) {
|
||
//
|
||
// analyze share information to a buffer
|
||
//
|
||
PSMBSVC_SHARES pShares=NULL;
|
||
DWORD ShareCount=0;
|
||
//
|
||
// get all shares
|
||
//
|
||
rc = SmbsvcpQueryShareList(&pShares, &ShareCount);
|
||
|
||
if ( rc == SCESTATUS_SUCCESS ) {
|
||
|
||
//
|
||
// Allocate PSCESVC_ANALYSIS_INFO buffer
|
||
//
|
||
PSCESVC_ANALYSIS_INFO pAnaInfo;
|
||
DWORD nCount;
|
||
|
||
pAnaInfo = (PSCESVC_ANALYSIS_INFO)LocalAlloc(LMEM_FIXED, sizeof(SCESVC_ANALYSIS_INFO));
|
||
|
||
if ( pAnaInfo != NULL ) {
|
||
|
||
pAnaInfo->Count = 0;
|
||
pAnaInfo->Lines = (PSCESVC_ANALYSIS_LINE)LocalAlloc(LMEM_ZEROINIT,
|
||
(NUM_COMP+ShareCount)*sizeof(SCESVC_ANALYSIS_LINE));
|
||
|
||
if ( pAnaInfo->Lines != NULL ) {
|
||
|
||
nCount = 0;
|
||
|
||
SmbsvcpWriteError2(pSceCbInfo->pfLogInfo,
|
||
SCE_LOG_LEVEL_DETAIL,
|
||
0,
|
||
SMBSVC_ANALYZE_CLIENT_START
|
||
);
|
||
|
||
//
|
||
// EnableSecuritySignature for client
|
||
//
|
||
rc = SmbsvcpAnalyzeValue(
|
||
SmbsvcRdrKey,
|
||
SmbsvcEnableSS,
|
||
L"EnableClientSecuritySignature",
|
||
pSmbInfo->EnableClientSecuritySignature,
|
||
&(pAnaInfo->Lines[nCount]),
|
||
&nCount
|
||
);
|
||
ErrPoint = SmbsvcEnableSS;
|
||
|
||
if ( rc == SCESTATUS_SUCCESS || rc == SCESTATUS_PROFILE_NOT_FOUND) {
|
||
//
|
||
// RequireSecuritySignature for client
|
||
//
|
||
rc = SmbsvcpAnalyzeValue(
|
||
SmbsvcRdrKey,
|
||
SmbsvcRequireSS,
|
||
L"RequireClientSecuritySignature",
|
||
pSmbInfo->RequireClientSecuritySignature,
|
||
&(pAnaInfo->Lines[nCount]),
|
||
&nCount
|
||
);
|
||
ErrPoint = SmbsvcRequireSS;
|
||
}
|
||
if ( rc == SCESTATUS_SUCCESS || rc == SCESTATUS_PROFILE_NOT_FOUND) {
|
||
//
|
||
// EnablePlainTextPassword (client only)
|
||
//
|
||
rc = SmbsvcpAnalyzeValue(
|
||
SmbsvcRdrKey,
|
||
SmbsvcPlainPassword,
|
||
L"EnablePlainTextPassword",
|
||
pSmbInfo->EnablePlainTextPassword,
|
||
&(pAnaInfo->Lines[nCount]),
|
||
&nCount
|
||
);
|
||
ErrPoint = SmbsvcPlainPassword;
|
||
}
|
||
if ( rc == SCESTATUS_SUCCESS || rc == SCESTATUS_PROFILE_NOT_FOUND) {
|
||
//
|
||
// RequireEnhancedChallengeResponse
|
||
//
|
||
rc = SmbsvcpAnalyzeValue(
|
||
SmbsvcRdrKey,
|
||
SmbsvcRequireECR,
|
||
L"RequireEnhancedChallengeResponse",
|
||
pSmbInfo->RequireEnhancedChallengeResponse,
|
||
&(pAnaInfo->Lines[nCount]),
|
||
&nCount
|
||
);
|
||
ErrPoint = SmbsvcRequireECR;
|
||
}
|
||
if ( rc == SCESTATUS_SUCCESS || rc == SCESTATUS_PROFILE_NOT_FOUND) {
|
||
//
|
||
// SendNTResponseOnly
|
||
//
|
||
rc = SmbsvcpAnalyzeValue(
|
||
SmbsvcRdrKey,
|
||
SmbsvcNTResponse,
|
||
L"SendNTResponseOnly",
|
||
pSmbInfo->SendNTResponseOnly,
|
||
&(pAnaInfo->Lines[nCount]),
|
||
&nCount
|
||
);
|
||
ErrPoint = SmbsvcNTResponse;
|
||
}
|
||
|
||
if ( rc == SCESTATUS_PROFILE_NOT_FOUND ) {
|
||
rc = SCESTATUS_SUCCESS;
|
||
}
|
||
|
||
if ( rc == SCESTATUS_SUCCESS ) {
|
||
|
||
SmbsvcpWriteError2(pSceCbInfo->pfLogInfo,
|
||
SCE_LOG_LEVEL_DETAIL,
|
||
0,
|
||
SMBSVC_ANALYZE_CLIENT_DONE
|
||
);
|
||
} else {
|
||
|
||
SmbsvcpWriteError2(pSceCbInfo->pfLogInfo,
|
||
SCE_LOG_LEVEL_ERROR,
|
||
SmbsvcpSceStatusToDosError(rc),
|
||
SMBSVC_ERROR_ANALYZE,
|
||
ErrPoint
|
||
);
|
||
}
|
||
|
||
Saverc = rc;
|
||
|
||
SmbsvcpWriteError2(pSceCbInfo->pfLogInfo,
|
||
SCE_LOG_LEVEL_DETAIL,
|
||
0,
|
||
SMBSVC_ANALYZE_SERVER_START
|
||
);
|
||
|
||
//
|
||
// EnableSecuritySignature for server
|
||
//
|
||
rc = SmbsvcpAnalyzeValue(
|
||
SmbsvcServerKey,
|
||
SmbsvcEnableSS,
|
||
L"EnableServerSecuritySignature",
|
||
pSmbInfo->EnableServerSecuritySignature,
|
||
&(pAnaInfo->Lines[nCount]),
|
||
&nCount
|
||
);
|
||
ErrPoint = SmbsvcEnableSS;
|
||
|
||
if ( rc == SCESTATUS_SUCCESS || rc == SCESTATUS_PROFILE_NOT_FOUND) {
|
||
//
|
||
// RequireSecuritySignature for server
|
||
//
|
||
rc = SmbsvcpAnalyzeValue(
|
||
SmbsvcServerKey,
|
||
SmbsvcRequireSS,
|
||
L"RequireServerSecuritySignature",
|
||
pSmbInfo->RequireServerSecuritySignature,
|
||
&(pAnaInfo->Lines[nCount]),
|
||
&nCount
|
||
);
|
||
ErrPoint = SmbsvcRequireSS;
|
||
}
|
||
|
||
if ( rc == SCESTATUS_SUCCESS || rc == SCESTATUS_PROFILE_NOT_FOUND) {
|
||
//
|
||
// RestrictNullSessionAccess
|
||
//
|
||
rc = SmbsvcpAnalyzeValue(
|
||
SmbsvcServerKey,
|
||
SmbsvcRestrictNull,
|
||
L"RestrictNullSessionAccess",
|
||
pSmbInfo->RestrictNullSessionAccess,
|
||
&(pAnaInfo->Lines[nCount]),
|
||
&nCount
|
||
);
|
||
ErrPoint = SmbsvcRestrictNull;
|
||
}
|
||
if ( rc == SCESTATUS_SUCCESS || rc == SCESTATUS_PROFILE_NOT_FOUND) {
|
||
//
|
||
// AutoShareServer or AutoShareWks
|
||
//
|
||
|
||
PCWSTR AutoValueName;
|
||
|
||
if ( ProductType == NtProductLanManNt ||
|
||
ProductType == NtProductServer ) {
|
||
AutoValueName = SmbsvcAutoShareServer;
|
||
} else {
|
||
AutoValueName = SmbsvcAutoShareWks;
|
||
}
|
||
|
||
rc = SmbsvcpAnalyzeValue(
|
||
SmbsvcServerKey,
|
||
AutoValueName,
|
||
L"EnableAutoShare",
|
||
pSmbInfo->EnableAutoShare,
|
||
&(pAnaInfo->Lines[nCount]),
|
||
&nCount
|
||
);
|
||
ErrPoint = (PWSTR)AutoValueName;
|
||
}
|
||
if ( rc == SCESTATUS_SUCCESS || rc == SCESTATUS_PROFILE_NOT_FOUND) {
|
||
//
|
||
// EnableForcedLogOff
|
||
//
|
||
rc = SmbsvcpAnalyzeValue(
|
||
SmbsvcServerKey,
|
||
SmbsvcForcedLogOff,
|
||
L"EnableForcedLogOff",
|
||
pSmbInfo->EnableForcedLogOff,
|
||
&(pAnaInfo->Lines[nCount]),
|
||
&nCount
|
||
);
|
||
ErrPoint = SmbsvcForcedLogOff;
|
||
}
|
||
if ( rc == SCESTATUS_SUCCESS || rc == SCESTATUS_PROFILE_NOT_FOUND) {
|
||
//
|
||
// AutoDisconnectTime
|
||
//
|
||
rc = SmbsvcpAnalyzeValue(
|
||
SmbsvcServerKey,
|
||
SmbsvcAutoDisconnect,
|
||
L"AutoDisconnect",
|
||
pSmbInfo->AutoDisconnect,
|
||
&(pAnaInfo->Lines[nCount]),
|
||
&nCount
|
||
);
|
||
ErrPoint = SmbsvcAutoDisconnect;
|
||
}
|
||
|
||
if ( rc == SCESTATUS_PROFILE_NOT_FOUND ) {
|
||
//
|
||
// the key does not exist
|
||
//
|
||
rc = SCESTATUS_SUCCESS;
|
||
|
||
}
|
||
|
||
|
||
if ( rc == SCESTATUS_SUCCESS ) {
|
||
//
|
||
// analyze Null Session Pipes and Shares
|
||
//
|
||
rc = SmbsvcpAnalyzeMultiSzString(
|
||
SmbsvcServerKey,
|
||
L"NullSessionPipes",
|
||
pSmbInfo->NullSessionPipes,
|
||
pSmbInfo->LengthPipes,
|
||
&(pAnaInfo->Lines[nCount]),
|
||
&nCount
|
||
);
|
||
wcscpy(Errbuf, L"NullSessionPipes");
|
||
ErrPoint = Errbuf;
|
||
if ( rc == SCESTATUS_SUCCESS ) {
|
||
|
||
rc = SmbsvcpAnalyzeMultiSzString(
|
||
SmbsvcServerKey,
|
||
L"NullSessionShares",
|
||
pSmbInfo->NullSessionShares,
|
||
pSmbInfo->LengthShares,
|
||
&(pAnaInfo->Lines[nCount]),
|
||
&nCount
|
||
);
|
||
wcscpy(Errbuf, L"NullSessionShares");
|
||
ErrPoint = Errbuf;
|
||
}
|
||
}
|
||
//
|
||
// analyze existing shares
|
||
//
|
||
if ( rc == SCESTATUS_SUCCESS ) {
|
||
|
||
PSMBSVC_SHARES pTemp, pConfigShare;
|
||
//
|
||
// process each share
|
||
//
|
||
for ( pTemp=pShares; pTemp != NULL;
|
||
pTemp = pTemp->Next) {
|
||
//
|
||
// Compare with configuration data
|
||
//
|
||
for ( pConfigShare=pSmbInfo->pShares;
|
||
pConfigShare != NULL; pConfigShare = pConfigShare->Next ) {
|
||
|
||
if ( _wcsicmp(pTemp->ShareName, pConfigShare->ShareName) == 0 ) {
|
||
//
|
||
// find the share in configuation data, compare security descriptor
|
||
//
|
||
break;
|
||
}
|
||
}
|
||
|
||
BOOL bEqual = FALSE;
|
||
DWORD Status;
|
||
|
||
if ( pConfigShare != NULL ) {
|
||
|
||
rc = SmbsvcpEqualSecurityDescriptor(
|
||
pTemp->pShareSD,
|
||
pConfigShare->pShareSD,
|
||
FALSE,
|
||
&bEqual
|
||
);
|
||
wcscpy(Errbuf, pTemp->ShareName);
|
||
ErrPoint = Errbuf;
|
||
Status = SMBSVC_STATUS_MISMATCH;
|
||
|
||
} else
|
||
Status = SMBSVC_STATUS_NOT_CONFIGURED;
|
||
|
||
if ( rc == SCESTATUS_SUCCESS && !bEqual ) {
|
||
//
|
||
// different, save this share
|
||
//
|
||
if ( pSmbInfo->pShares == NULL ) {
|
||
|
||
SmbsvcpWriteError2(pSceCbInfo->pfLogInfo,
|
||
SCE_LOG_LEVEL_DETAIL,
|
||
0,
|
||
SMBSVC_NOT_CONFIGURED,
|
||
pTemp->ShareName
|
||
);
|
||
} else {
|
||
|
||
SmbsvcpWriteError2(pSceCbInfo->pfLogInfo,
|
||
SCE_LOG_LEVEL_DETAIL,
|
||
0,
|
||
SMBSVC_MISMATCH,
|
||
pTemp->ShareName
|
||
);
|
||
}
|
||
|
||
PWSTR TextSD=NULL;
|
||
DWORD SDsize=0;
|
||
|
||
if ( pTemp->pShareSD != NULL ) {
|
||
#if defined(_NT4BACK_PORT)
|
||
rc = SceSvcConvertSDToText(
|
||
pTemp->pShareSD,
|
||
DACL_SECURITY_INFORMATION,
|
||
&TextSD,
|
||
&SDsize
|
||
);
|
||
rc = SmbsvcpDosErrorToSceStatus(rc);
|
||
|
||
#else
|
||
if ( !ConvertSecurityDescriptorToStringSecurityDescriptor(
|
||
pTemp->pShareSD,
|
||
SDDL_REVISION,
|
||
DACL_SECURITY_INFORMATION,
|
||
&TextSD,
|
||
&SDsize
|
||
) ) {
|
||
rc = SmbsvcpDosErrorToSceStatus(GetLastError());
|
||
} else {
|
||
rc = SCESTATUS_SUCCESS;
|
||
|
||
}
|
||
#endif
|
||
wcscpy(Errbuf, pTemp->ShareName);
|
||
ErrPoint = Errbuf;
|
||
}
|
||
|
||
PWSTR Value;
|
||
|
||
Value = (PWSTR)LocalAlloc(LMEM_FIXED, (SDsize+9)*sizeof(WCHAR));
|
||
if ( Value != NULL ) {
|
||
|
||
if ( TextSD != NULL )
|
||
swprintf(Value, L"Share,%1d,%s", Status, TextSD);
|
||
else
|
||
swprintf(Value, L"Share,%1d,", Status);
|
||
|
||
Value[SDsize+8] = L'\0';
|
||
|
||
pAnaInfo->Lines[nCount].Key = pTemp->ShareName;
|
||
pAnaInfo->Lines[nCount].Value = (PBYTE)Value;
|
||
pAnaInfo->Lines[nCount].ValueLen = (SDsize+8)*sizeof(WCHAR);
|
||
pTemp->ShareName = NULL;
|
||
|
||
nCount++;
|
||
|
||
} else {
|
||
wcscpy(Errbuf, pTemp->ShareName);
|
||
ErrPoint = Errbuf;
|
||
rc = SCESTATUS_NOT_ENOUGH_RESOURCE;
|
||
}
|
||
|
||
if ( TextSD != NULL )
|
||
LocalFree(TextSD);
|
||
TextSD = NULL;
|
||
|
||
} else {
|
||
|
||
SmbsvcpWriteError2(pSceCbInfo->pfLogInfo,
|
||
SCE_LOG_LEVEL_DETAIL,
|
||
0,
|
||
SMBSVC_MATCH,
|
||
pTemp->ShareName
|
||
);
|
||
}
|
||
|
||
if ( rc != SCESTATUS_SUCCESS ) {
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
if ( rc == SCESTATUS_SUCCESS ) {
|
||
|
||
SmbsvcpWriteError2(pSceCbInfo->pfLogInfo,
|
||
SCE_LOG_LEVEL_DETAIL,
|
||
0,
|
||
SMBSVC_ANALYZE_SERVER_DONE
|
||
);
|
||
rc = Saverc; // saved status for client analysis
|
||
|
||
} else {
|
||
|
||
SmbsvcpWriteError2(pSceCbInfo->pfLogInfo,
|
||
SCE_LOG_LEVEL_ERROR,
|
||
SmbsvcpSceStatusToDosError(rc),
|
||
SMBSVC_ERROR_ANALYZE,
|
||
ErrPoint
|
||
);
|
||
}
|
||
|
||
//
|
||
// Now save the information to the database
|
||
//
|
||
if ( rc == SCESTATUS_SUCCESS ) {
|
||
|
||
SmbsvcpWriteError2(
|
||
pSceCbInfo->pfLogInfo,
|
||
SCE_LOG_LEVEL_DETAIL,
|
||
0,
|
||
SMBSVC_SAVE_INFO
|
||
);
|
||
|
||
pAnaInfo->Count = nCount;
|
||
|
||
__try {
|
||
rc = (*(pSceCbInfo->pfSetInfo))(
|
||
pSceCbInfo->sceHandle,
|
||
SceSvcAnalysisInfo,
|
||
NULL,
|
||
FALSE,
|
||
(PVOID)pAnaInfo
|
||
);
|
||
} __except (EXCEPTION_EXECUTE_HANDLER) {
|
||
rc = SCESTATUS_SERVICE_NOT_SUPPORT;
|
||
}
|
||
|
||
if ( SCESTATUS_SUCCESS != rc ) {
|
||
|
||
SmbsvcpWriteError2(
|
||
pSceCbInfo->pfLogInfo,
|
||
SCE_LOG_LEVEL_ERROR,
|
||
SmbsvcpSceStatusToDosError(rc),
|
||
SMBSVC_ERROR_SAVE_INFO
|
||
);
|
||
}
|
||
}
|
||
|
||
//
|
||
// free pAnaInfo
|
||
//
|
||
__try {
|
||
(*(pSceCbInfo->pfFreeInfo))((PVOID)pAnaInfo);
|
||
|
||
} __except (EXCEPTION_EXECUTE_HANDLER) {
|
||
//
|
||
// BUGBUG: buffer is not freed ??
|
||
//
|
||
}
|
||
|
||
} else {
|
||
rc = SCESTATUS_NOT_ENOUGH_RESOURCE;
|
||
LocalFree(pAnaInfo);
|
||
}
|
||
|
||
} else
|
||
rc = SCESTATUS_NOT_ENOUGH_RESOURCE;
|
||
|
||
SmbsvcpFreeShareList(pShares);
|
||
|
||
} else {
|
||
|
||
SmbsvcpWriteError2(
|
||
pSceCbInfo->pfLogInfo,
|
||
SCE_LOG_LEVEL_ERROR,
|
||
SmbsvcpSceStatusToDosError(rc),
|
||
SMBSVC_ERROR_ENUM_SHARE
|
||
);
|
||
}
|
||
|
||
//
|
||
// free memory
|
||
//
|
||
SmbsvcpFree(pSmbInfo);
|
||
}
|
||
|
||
return(rc);
|
||
}
|
||
|
||
|
||
SCESTATUS
|
||
WINAPI
|
||
SceSvcAttachmentUpdate(
|
||
IN PSCESVC_CALLBACK_INFO pSceCbInfo,
|
||
IN SCESVC_CONFIGURATION_INFO *ServiceInfo
|
||
)
|
||
/*
|
||
Routine Description:
|
||
|
||
|
||
Arguments:
|
||
|
||
pSceCbInfo - the callback handle and function pointers to SCE.
|
||
|
||
ServiceInfo - The update configuration information for SMB server to process.
|
||
|
||
Return Value:
|
||
|
||
SCESTATUS
|
||
*/
|
||
{
|
||
if ( pSceCbInfo == NULL ||
|
||
pSceCbInfo->sceHandle == NULL ||
|
||
pSceCbInfo->pfQueryInfo == NULL ||
|
||
pSceCbInfo->pfSetInfo == NULL ||
|
||
pSceCbInfo->pfFreeInfo == NULL ||
|
||
ServiceInfo == NULL ) {
|
||
|
||
return(SCESTATUS_INVALID_PARAMETER);
|
||
}
|
||
|
||
SCESTATUS rc=SCESTATUS_SUCCESS;
|
||
|
||
PSCESVC_CONFIGURATION_INFO pConfigInfo=NULL;
|
||
SCE_ENUMERATION_CONTEXT EnumHandle;
|
||
|
||
PSCESVC_ANALYSIS_INFO pAnaInfo=NULL;
|
||
|
||
//
|
||
// prepare two buffers for update
|
||
//
|
||
SCESVC_ANALYSIS_INFO UpdtAnaInfo;
|
||
SCESVC_ANALYSIS_LINE UpdtAnaLine;
|
||
|
||
SCESVC_CONFIGURATION_INFO UpdtConfigInfo;
|
||
SCESVC_CONFIGURATION_LINE UpdtConfigLine;
|
||
|
||
UpdtAnaInfo.Count = 1;
|
||
UpdtAnaInfo.Lines = &UpdtAnaLine;
|
||
|
||
UpdtConfigInfo.Count = 1;
|
||
UpdtConfigInfo.Lines = &UpdtConfigLine;
|
||
|
||
//
|
||
// process each line
|
||
//
|
||
for ( DWORD i=0; i<ServiceInfo->Count; i++ ) {
|
||
|
||
|
||
SmbsvcpWriteError2(pSceCbInfo->pfLogInfo,
|
||
SCE_LOG_LEVEL_DETAIL,
|
||
0,
|
||
SMBSVC_UPDATE_INFO,
|
||
ServiceInfo->Lines[i].Key
|
||
);
|
||
//
|
||
// query the configuration setting
|
||
//
|
||
EnumHandle = 0;
|
||
|
||
__try {
|
||
rc = (*(pSceCbInfo->pfQueryInfo))(
|
||
pSceCbInfo->sceHandle,
|
||
SceSvcConfigurationInfo,
|
||
ServiceInfo->Lines[i].Key,
|
||
TRUE,
|
||
(PVOID *)&pConfigInfo,
|
||
&EnumHandle
|
||
);
|
||
} __except (EXCEPTION_EXECUTE_HANDLER) {
|
||
rc = SCESTATUS_SERVICE_NOT_SUPPORT;
|
||
}
|
||
|
||
if ( rc == SCESTATUS_SUCCESS || rc == SCESTATUS_RECORD_NOT_FOUND ) {
|
||
|
||
// if ( ServiceInfo->Lines[i].Value == NULL ) {
|
||
if ( ServiceInfo->Lines[i].ValueLen == SMBSVC_NO_VALUE ) {
|
||
|
||
//
|
||
// delete is requested
|
||
//
|
||
if ( rc == SCESTATUS_SUCCESS ) {
|
||
//
|
||
// delete the configuration, but make sure analysis is ok
|
||
//
|
||
EnumHandle = 0;
|
||
|
||
__try {
|
||
rc = (*(pSceCbInfo->pfQueryInfo))(
|
||
pSceCbInfo->sceHandle,
|
||
SceSvcAnalysisInfo,
|
||
ServiceInfo->Lines[i].Key,
|
||
TRUE,
|
||
(PVOID *)&pAnaInfo,
|
||
&EnumHandle
|
||
);
|
||
|
||
} __except (EXCEPTION_EXECUTE_HANDLER) {
|
||
rc = SCESTATUS_SERVICE_NOT_SUPPORT;
|
||
}
|
||
|
||
if ( rc == SCESTATUS_RECORD_NOT_FOUND ) {
|
||
//
|
||
// analysis info does not exist, matched.
|
||
// should save configuration info as analysis
|
||
//
|
||
UpdtAnaLine.Key = ServiceInfo->Lines[i].Key;
|
||
UpdtAnaLine.Value = (PBYTE)(pConfigInfo->Lines[0].Value);
|
||
UpdtAnaLine.ValueLen = pConfigInfo->Lines[0].ValueLen;
|
||
|
||
if ( pConfigInfo->Lines[0].ValueLen > 14 &&
|
||
pConfigInfo->Lines[0].Value != NULL &&
|
||
_wcsnicmp(L"Share,", pConfigInfo->Lines[0].Value, 6) == 0 ) {
|
||
//
|
||
// this is a share, needs to update status
|
||
//
|
||
*(pConfigInfo->Lines[0].Value+6) = L'2';
|
||
}
|
||
|
||
__try {
|
||
rc = (*(pSceCbInfo->pfSetInfo))(
|
||
pSceCbInfo->sceHandle,
|
||
SceSvcAnalysisInfo,
|
||
NULL,
|
||
TRUE,
|
||
(PVOID)&UpdtAnaInfo
|
||
);
|
||
|
||
} __except (EXCEPTION_EXECUTE_HANDLER) {
|
||
rc = SCESTATUS_SERVICE_NOT_SUPPORT;
|
||
}
|
||
}
|
||
if ( rc == SCESTATUS_SUCCESS ) {
|
||
//
|
||
// delete the configuration info
|
||
//
|
||
__try {
|
||
rc = (*(pSceCbInfo->pfSetInfo))(
|
||
pSceCbInfo->sceHandle,
|
||
SceSvcConfigurationInfo,
|
||
ServiceInfo->Lines[i].Key,
|
||
TRUE,
|
||
NULL
|
||
);
|
||
} __except (EXCEPTION_EXECUTE_HANDLER) {
|
||
rc = SCESTATUS_SERVICE_NOT_SUPPORT;
|
||
}
|
||
}
|
||
|
||
} // if configuration is not found, just continue
|
||
|
||
} else {
|
||
|
||
if ( rc == SCESTATUS_RECORD_NOT_FOUND ) {
|
||
//
|
||
// no configuration setting for this one,
|
||
// either a new added share, or other configuration settings.
|
||
// BUGBUG: need to validate the key for other settings.
|
||
//
|
||
// if not valid, break out here
|
||
}
|
||
//
|
||
// query the analysis setting
|
||
//
|
||
EnumHandle = 0;
|
||
|
||
__try {
|
||
rc = (*(pSceCbInfo->pfQueryInfo))(
|
||
pSceCbInfo->sceHandle,
|
||
SceSvcAnalysisInfo,
|
||
ServiceInfo->Lines[i].Key,
|
||
TRUE,
|
||
(PVOID *)&pAnaInfo,
|
||
&EnumHandle
|
||
);
|
||
|
||
} __except (EXCEPTION_EXECUTE_HANDLER) {
|
||
rc = SCESTATUS_SERVICE_NOT_SUPPORT;
|
||
}
|
||
|
||
if ( rc == SCESTATUS_SUCCESS || rc == SCESTATUS_RECORD_NOT_FOUND ) {
|
||
//
|
||
// mismatch is found for this one, or a matched item
|
||
//
|
||
if ( _wcsicmp(L"NullSessionShares", ServiceInfo->Lines[i].Key ) == 0 ||
|
||
_wcsicmp(L"NullSessionPipes", ServiceInfo->Lines[i].Key ) == 0 ) {
|
||
|
||
rc = SmbsvcpUpdateMultiSzString(
|
||
pSceCbInfo,
|
||
ServiceInfo->Lines[i],
|
||
pConfigInfo,
|
||
pAnaInfo
|
||
);
|
||
} else if ( ServiceInfo->Lines[i].ValueLen > 14 &&
|
||
ServiceInfo->Lines[i].Value != NULL &&
|
||
_wcsnicmp(L"Share,", ServiceInfo->Lines[i].Value, 6) == 0 ) {
|
||
//
|
||
// shares
|
||
//
|
||
rc = SmbsvcpUpdateShareValue(pSceCbInfo,
|
||
ServiceInfo->Lines[i],
|
||
pConfigInfo,
|
||
pAnaInfo
|
||
);
|
||
} else {
|
||
//
|
||
// other BYTE or DWORD type fields
|
||
//
|
||
|
||
DWORD NewValue = SMBSVC_NO_VALUE;
|
||
|
||
if ( swscanf(ServiceInfo->Lines[i].Value, L"%d", &NewValue) != EOF ) {
|
||
|
||
DWORD ConfigValue = SMBSVC_NO_VALUE;
|
||
DWORD AnaValue = SMBSVC_NO_VALUE;
|
||
|
||
if ( pConfigInfo != NULL && pConfigInfo->Lines != NULL )
|
||
swscanf(pConfigInfo->Lines[0].Value, L"%d", &ConfigValue);
|
||
|
||
if ( pAnaInfo != NULL && pAnaInfo->Lines != NULL ) {
|
||
swscanf((PWSTR)(pAnaInfo->Lines[0].Value), L"%d", &AnaValue);
|
||
}
|
||
|
||
if ( AnaValue != SMBSVC_NO_VALUE ) {
|
||
//
|
||
// old status is mismatch for this item
|
||
//
|
||
if ( NewValue == AnaValue ) {
|
||
//
|
||
// now it is matched, delete the analysis entry
|
||
//
|
||
|
||
SmbsvcpWriteError(pSceCbInfo->pfLogInfo,
|
||
SCE_LOG_LEVEL_DEBUG,
|
||
0,
|
||
L"mismatch->match"
|
||
);
|
||
__try {
|
||
rc = (*(pSceCbInfo->pfSetInfo))(
|
||
pSceCbInfo->sceHandle,
|
||
SceSvcAnalysisInfo,
|
||
ServiceInfo->Lines[i].Key,
|
||
TRUE,
|
||
NULL
|
||
);
|
||
|
||
} __except (EXCEPTION_EXECUTE_HANDLER) {
|
||
rc = SCESTATUS_SERVICE_NOT_SUPPORT;
|
||
}
|
||
}
|
||
if ( NewValue != ConfigValue ) {
|
||
//
|
||
// update the configuration setting
|
||
//
|
||
UpdtConfigLine.Key = ServiceInfo->Lines[i].Key;
|
||
UpdtConfigLine.Value = ServiceInfo->Lines[i].Value;
|
||
UpdtConfigLine.ValueLen = ServiceInfo->Lines[i].ValueLen;
|
||
|
||
__try {
|
||
rc = (*(pSceCbInfo->pfSetInfo))(
|
||
pSceCbInfo->sceHandle,
|
||
SceSvcConfigurationInfo,
|
||
NULL,
|
||
TRUE,
|
||
(PVOID)&UpdtConfigInfo
|
||
);
|
||
|
||
} __except (EXCEPTION_EXECUTE_HANDLER) {
|
||
rc = SCESTATUS_SERVICE_NOT_SUPPORT;
|
||
}
|
||
}
|
||
} else {
|
||
//
|
||
// old status is match, or a new added configuration key
|
||
//
|
||
if ( NewValue != ConfigValue ) {
|
||
|
||
SmbsvcpWriteError(pSceCbInfo->pfLogInfo,
|
||
SCE_LOG_LEVEL_DEBUG,
|
||
0,
|
||
L"match->mismatch"
|
||
);
|
||
//
|
||
// mismatch should be raised with ConfigValue
|
||
//
|
||
UpdtAnaLine.Key = ServiceInfo->Lines[i].Key;
|
||
UpdtAnaLine.Value = ( pConfigInfo != NULL ) ? (PBYTE)(pConfigInfo->Lines[0].Value) : NULL ;
|
||
UpdtAnaLine.ValueLen = ( pConfigInfo != NULL ) ? pConfigInfo->Lines[0].ValueLen : 0;
|
||
|
||
__try {
|
||
rc = (*(pSceCbInfo->pfSetInfo))(
|
||
pSceCbInfo->sceHandle,
|
||
SceSvcAnalysisInfo,
|
||
NULL,
|
||
TRUE,
|
||
(PVOID)&UpdtAnaInfo
|
||
);
|
||
|
||
} __except (EXCEPTION_EXECUTE_HANDLER) {
|
||
rc = SCESTATUS_SERVICE_NOT_SUPPORT;
|
||
}
|
||
|
||
if ( rc == SCESTATUS_SUCCESS ) {
|
||
|
||
if ( NewValue == SMBSVC_NO_VALUE ) {
|
||
|
||
SmbsvcpWriteError(pSceCbInfo->pfLogInfo,
|
||
SCE_LOG_LEVEL_DEBUG,
|
||
0,
|
||
L"delelte base setting"
|
||
);
|
||
//
|
||
// delete configuration setting
|
||
//
|
||
__try {
|
||
rc = (*(pSceCbInfo->pfSetInfo))(
|
||
pSceCbInfo->sceHandle,
|
||
SceSvcConfigurationInfo,
|
||
ServiceInfo->Lines[i].Key,
|
||
TRUE,
|
||
NULL
|
||
);
|
||
|
||
} __except (EXCEPTION_EXECUTE_HANDLER) {
|
||
rc = SCESTATUS_SERVICE_NOT_SUPPORT;
|
||
}
|
||
} else {
|
||
//
|
||
// update configuration setting with NewValue
|
||
//
|
||
UpdtConfigLine.Key = ServiceInfo->Lines[i].Key;
|
||
UpdtConfigLine.Value = ServiceInfo->Lines[i].Value;
|
||
UpdtConfigLine.ValueLen = ServiceInfo->Lines[i].ValueLen;
|
||
|
||
__try {
|
||
rc = (*(pSceCbInfo->pfSetInfo))(
|
||
pSceCbInfo->sceHandle,
|
||
SceSvcConfigurationInfo,
|
||
NULL,
|
||
TRUE,
|
||
(PVOID)&UpdtConfigInfo
|
||
);
|
||
|
||
} __except (EXCEPTION_EXECUTE_HANDLER) {
|
||
rc = SCESTATUS_SERVICE_NOT_SUPPORT;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
} else
|
||
rc = SCESTATUS_INVALID_DATA;
|
||
}
|
||
|
||
if ( pAnaInfo != NULL ) {
|
||
|
||
__try {
|
||
(*(pSceCbInfo->pfFreeInfo))((PVOID)pAnaInfo);
|
||
|
||
} __except (EXCEPTION_EXECUTE_HANDLER) {
|
||
}
|
||
}
|
||
pAnaInfo = NULL;
|
||
|
||
}
|
||
}
|
||
|
||
if ( pConfigInfo != NULL ) {
|
||
|
||
__try {
|
||
(*(pSceCbInfo->pfFreeInfo))((PVOID)pConfigInfo);
|
||
} __except (EXCEPTION_EXECUTE_HANDLER) {
|
||
}
|
||
}
|
||
pConfigInfo = NULL;
|
||
|
||
}
|
||
|
||
if ( rc == SCESTATUS_RECORD_NOT_FOUND ) {
|
||
rc = SCESTATUS_SUCCESS;
|
||
}
|
||
|
||
if ( rc != SCESTATUS_SUCCESS ) {
|
||
break;
|
||
}
|
||
}
|
||
|
||
return(rc);
|
||
|
||
}
|
||
|
||
|
||
SCESTATUS
|
||
SmbsvcpResetInfo(
|
||
IN PSMBSVC_SEC_INFO pInfo
|
||
)
|
||
/*
|
||
Routine Description:
|
||
|
||
This routine resets or initializes the buffer. All BYTE and DWORD
|
||
type fields are set to SMBSVC_NO_VALUE and all othe pointers are
|
||
set to NULL
|
||
|
||
Arguments:
|
||
|
||
pInfo - the buffer to reset.
|
||
|
||
Return Value:
|
||
|
||
SCESTATUS
|
||
*/
|
||
{
|
||
if ( pInfo == NULL ) {
|
||
return(SCESTATUS_INVALID_PARAMETER);
|
||
}
|
||
|
||
pInfo->EnableClientSecuritySignature = SMBSVC_NO_VALUE;
|
||
pInfo->RequireClientSecuritySignature = SMBSVC_NO_VALUE;
|
||
pInfo->EnablePlainTextPassword = SMBSVC_NO_VALUE;
|
||
pInfo->RequireEnhancedChallengeResponse = SMBSVC_NO_VALUE;
|
||
pInfo->SendNTResponseOnly = SMBSVC_NO_VALUE;
|
||
|
||
pInfo->EnableAutoShare = SMBSVC_NO_VALUE;
|
||
pInfo->EnableServerSecuritySignature = SMBSVC_NO_VALUE;
|
||
pInfo->RequireServerSecuritySignature = SMBSVC_NO_VALUE;
|
||
pInfo->RestrictNullSessionAccess = SMBSVC_NO_VALUE;
|
||
|
||
pInfo->EnableForcedLogOff = SMBSVC_NO_VALUE;
|
||
pInfo->AutoDisconnect = SMBSVC_NO_VALUE;
|
||
|
||
pInfo->NullSessionShares = NULL;
|
||
pInfo->LengthShares = SMBSVC_NO_VALUE;
|
||
|
||
pInfo->NullSessionPipes = NULL;
|
||
pInfo->LengthPipes = SMBSVC_NO_VALUE;
|
||
|
||
pInfo->pShares=NULL;
|
||
|
||
return(SCESTATUS_SUCCESS);
|
||
}
|
||
|
||
|
||
SCESTATUS
|
||
SmbsvcpGetInformation(
|
||
IN PSCESVC_CALLBACK_INFO pSceCbInfo,
|
||
OUT PSMBSVC_SEC_INFO pSmbInfo
|
||
)
|
||
/*
|
||
Routine Description:
|
||
|
||
This routine queries information from the storage pointed by sceHandle.
|
||
Infomration is loaded into each field in the buffer pSmbInfo. Type argument
|
||
indicates configuration information or analysis information to query.
|
||
|
||
Arguments:
|
||
|
||
pSceCbInfo - the callback info structure
|
||
|
||
Type - SceSvcConfigurationInfo or SceSvcAnalysisInfo
|
||
|
||
pSmbInfo - the buffer to hold information. Note, this buffer must be allocated
|
||
before this call
|
||
|
||
Return Value:
|
||
|
||
SCESTATUS
|
||
*/
|
||
{
|
||
if ( pSceCbInfo == NULL ||
|
||
pSceCbInfo->sceHandle == NULL ||
|
||
pSceCbInfo->pfQueryInfo == NULL ||
|
||
pSmbInfo == NULL ) {
|
||
|
||
return(SCESTATUS_INVALID_PARAMETER);
|
||
}
|
||
|
||
SCESTATUS rc;
|
||
SCE_ENUMERATION_CONTEXT EnumHandle=0;
|
||
PSCESVC_CONFIGURATION_INFO pConfigInfo=NULL;
|
||
|
||
SMBSVC_KEY_LOOKUP LookupKeys[] = {
|
||
{(PWSTR)TEXT("EnableForcedLogOff"), offsetof(struct _SMBSVC_SEC_INFO_, EnableForcedLogOff), 'B'},
|
||
{(PWSTR)TEXT("AutoDisconnect"), offsetof(struct _SMBSVC_SEC_INFO_, AutoDisconnect),'D'},
|
||
{(PWSTR)TEXT("EnableAutoShare"), offsetof(struct _SMBSVC_SEC_INFO_, EnableAutoShare), 'B'},
|
||
{(PWSTR)TEXT("EnableServerSecuritySignature"),offsetof(struct _SMBSVC_SEC_INFO_, EnableServerSecuritySignature),'B'},
|
||
{(PWSTR)TEXT("RequireServerSecuritySignature"),offsetof(struct _SMBSVC_SEC_INFO_, RequireServerSecuritySignature), 'B'},
|
||
{(PWSTR)TEXT("RestrictNullSessionAccess"), offsetof(struct _SMBSVC_SEC_INFO_, RestrictNullSessionAccess), 'B'},
|
||
{(PWSTR)TEXT("EnableClientSecuritySignature"),offsetof(struct _SMBSVC_SEC_INFO_, EnableClientSecuritySignature),'B'},
|
||
{(PWSTR)TEXT("RequireClientSecuritySignature"),offsetof(struct _SMBSVC_SEC_INFO_, RequireClientSecuritySignature), 'B'},
|
||
{(PWSTR)TEXT("EnablePlainTextPassword"), offsetof(struct _SMBSVC_SEC_INFO_, EnablePlainTextPassword), 'B'},
|
||
{(PWSTR)TEXT("RequireEnhancedChallengeResponse"),offsetof(struct _SMBSVC_SEC_INFO_, RequireEnhancedChallengeResponse),'B'},
|
||
{(PWSTR)TEXT("SendNTResponseOnly"),offsetof(struct _SMBSVC_SEC_INFO_, SendNTResponseOnly), 'B'},
|
||
{(PWSTR)TEXT("NullSessionPipes"), offsetof(struct _SMBSVC_SEC_INFO_, NullSessionPipes), 'M'},
|
||
{(PWSTR)TEXT("NullSessionShares"), offsetof(struct _SMBSVC_SEC_INFO_, NullSessionShares), 'M'}
|
||
};
|
||
|
||
DWORD cKeys = sizeof(LookupKeys) / sizeof(SMBSVC_KEY_LOOKUP);
|
||
DWORD CountReturned;
|
||
|
||
PSMBSVC_SHARES pShareList=NULL;
|
||
|
||
//
|
||
// read configuration information for smb server
|
||
//
|
||
do {
|
||
|
||
CountReturned = 0;
|
||
|
||
__try {
|
||
rc = (*(pSceCbInfo->pfQueryInfo))(
|
||
pSceCbInfo->sceHandle,
|
||
SceSvcConfigurationInfo,
|
||
NULL,
|
||
FALSE,
|
||
(PVOID *)&pConfigInfo,
|
||
&EnumHandle
|
||
);
|
||
|
||
} __except (EXCEPTION_EXECUTE_HANDLER) {
|
||
rc = SCESTATUS_SERVICE_NOT_SUPPORT;
|
||
}
|
||
|
||
if ( rc == SCESTATUS_SUCCESS && pConfigInfo != NULL &&
|
||
pConfigInfo->Count > 0 ) {
|
||
//
|
||
// got something
|
||
//
|
||
CountReturned = pConfigInfo->Count;
|
||
|
||
DWORD i, j;
|
||
PSECURITY_DESCRIPTOR pTempSD=NULL;
|
||
DWORD KeyValue, ValueLen, k;
|
||
PCHAR StrValue=NULL;
|
||
|
||
for ( i=0; i<pConfigInfo->Count; i++ ) {
|
||
|
||
if ( pConfigInfo->Lines[i].Key == NULL )
|
||
continue;
|
||
|
||
for (j=0; j<cKeys; j++) {
|
||
|
||
if ( _wcsicmp( pConfigInfo->Lines[i].Key, LookupKeys[j].KeyString) == 0 ) {
|
||
//
|
||
// find the matched string
|
||
//
|
||
switch ( LookupKeys[j].BufferType ) {
|
||
case 'B':
|
||
|
||
if ( pConfigInfo->Lines[i].Value != NULL ) {
|
||
KeyValue = _wtoi(pConfigInfo->Lines[i].Value);
|
||
*((BYTE *)pSmbInfo+LookupKeys[j].Offset) = (BYTE)KeyValue;
|
||
}
|
||
break;
|
||
|
||
case 'D':
|
||
|
||
if ( pConfigInfo->Lines[i].Value != NULL ) {
|
||
KeyValue = _wtol(pConfigInfo->Lines[i].Value);
|
||
*((DWORD *)((BYTE *)pSmbInfo+LookupKeys[j].Offset)) = KeyValue;
|
||
}
|
||
|
||
break;
|
||
|
||
case 'M':
|
||
// comma separated strings,
|
||
ValueLen = pConfigInfo->Lines[i].ValueLen;
|
||
|
||
if ( pConfigInfo->Lines[i].Value != NULL ) {
|
||
|
||
StrValue = (PCHAR)LocalAlloc(LMEM_FIXED, ValueLen + 4 );
|
||
|
||
if ( StrValue != NULL ) {
|
||
|
||
memcpy((PVOID)StrValue, (PVOID)(pConfigInfo->Lines[i].Value),
|
||
ValueLen);
|
||
//
|
||
// terminate the buffer by two L'\0's
|
||
//
|
||
*((WCHAR *)(StrValue+ValueLen)) = L'\0';
|
||
*((WCHAR *)(StrValue+ValueLen+2)) = L'\0';
|
||
/*
|
||
//
|
||
// replace ',' with '\0's
|
||
//
|
||
for ( k=0; k<ValueLen; k++ ) {
|
||
if ( StrValue[k] == ',' ) {
|
||
StrValue[k] = '\0';
|
||
}
|
||
}
|
||
*/
|
||
*((PVOID *)((BYTE *)pSmbInfo+LookupKeys[j].Offset)) = (PVOID)StrValue;
|
||
StrValue = NULL;
|
||
*((DWORD *)((BYTE *)pSmbInfo+LookupKeys[j].Offset+sizeof(PVOID))) = ValueLen;
|
||
|
||
} else {
|
||
|
||
rc = SCESTATUS_NOT_ENOUGH_RESOURCE;
|
||
}
|
||
}
|
||
break;
|
||
|
||
default:
|
||
//
|
||
// unknown type, should not occur, ignore!!!
|
||
//
|
||
break;
|
||
}
|
||
|
||
break;
|
||
}
|
||
}
|
||
|
||
if ( j >= cKeys && rc == SCESTATUS_SUCCESS ) {
|
||
//
|
||
// did not find a match for pre-defined keywords
|
||
//
|
||
if ( pConfigInfo->Lines[i].Value != NULL && pConfigInfo->Lines[i].ValueLen > 14 &&
|
||
_wcsnicmp(L"Share,", pConfigInfo->Lines[i].Value, 6) == 0 ) {
|
||
//
|
||
// shares and security
|
||
//
|
||
if ( wcslen(pConfigInfo->Lines[i].Value) > 8) {
|
||
|
||
#if defined(_NT4BACK_PORT)
|
||
DWORD SDsize;
|
||
SECURITY_INFORMATION SeInfo;
|
||
|
||
rc = SceSvcConvertTextToSD(
|
||
pConfigInfo->Lines[i].Value+8,
|
||
&pTempSD,
|
||
&SDsize,
|
||
&SeInfo
|
||
);
|
||
|
||
rc = SmbsvcpDosErrorToSceStatus(rc);
|
||
#else
|
||
if ( !ConvertStringSecurityDescriptorToSecurityDescriptor(
|
||
(PCWSTR)(pConfigInfo->Lines[i].Value+8),
|
||
SDDL_REVISION,
|
||
&pTempSD,
|
||
NULL
|
||
) ) {
|
||
rc = SmbsvcpDosErrorToSceStatus(GetLastError());
|
||
}
|
||
#endif
|
||
} else {
|
||
pTempSD = NULL;
|
||
}
|
||
|
||
DWORD Status = *(pConfigInfo->Lines[i].Value+6)-L'0';
|
||
|
||
if ( rc == SCESTATUS_SUCCESS ) {
|
||
|
||
rc = SmbsvcpAddAShareToList(&pShareList,
|
||
pConfigInfo->Lines[i].Key,
|
||
Status,
|
||
pTempSD
|
||
);
|
||
|
||
if ( rc != SCESTATUS_SUCCESS && pTempSD != NULL ) {
|
||
LocalFree(pTempSD);
|
||
}
|
||
}
|
||
|
||
if ( rc != SCESTATUS_SUCCESS && pSceCbInfo->pfLogInfo != NULL ) {
|
||
|
||
SmbsvcpWriteError2(pSceCbInfo->pfLogInfo,
|
||
SCE_LOG_LEVEL_ERROR,
|
||
SmbsvcpSceStatusToDosError(rc),
|
||
SMBSVC_ERROR_QUERY,
|
||
pConfigInfo->Lines[i]
|
||
);
|
||
}
|
||
|
||
} else if (pSceCbInfo->pfLogInfo != NULL ) {
|
||
//
|
||
// did not find a match
|
||
// warning for unknown data, but return success
|
||
//
|
||
SmbsvcpWriteError2(pSceCbInfo->pfLogInfo,
|
||
SCE_LOG_LEVEL_ERROR,
|
||
0,
|
||
SMBSVC_UNKNOWN_KEYWORD,
|
||
pConfigInfo->Lines[i].Key
|
||
);
|
||
}
|
||
} else if ( rc != SCESTATUS_SUCCESS &&
|
||
pSceCbInfo->pfLogInfo != NULL ) {
|
||
|
||
SmbsvcpWriteError2(pSceCbInfo->pfLogInfo,
|
||
SCE_LOG_LEVEL_ERROR,
|
||
SmbsvcpSceStatusToDosError(rc),
|
||
SMBSVC_ERROR_QUERY,
|
||
pConfigInfo->Lines[i]
|
||
);
|
||
}
|
||
|
||
if ( rc != SCESTATUS_SUCCESS )
|
||
break;
|
||
|
||
}
|
||
|
||
__try {
|
||
|
||
(*(pSceCbInfo->pfFreeInfo))((PVOID)pConfigInfo);
|
||
|
||
} __except (EXCEPTION_EXECUTE_HANDLER) {
|
||
}
|
||
|
||
pConfigInfo = NULL;
|
||
}
|
||
|
||
} while ( rc == SCESTATUS_SUCCESS && CountReturned >= SCESVC_ENUMERATION_MAX ); //0
|
||
|
||
if ( pShareList != NULL ) {
|
||
pSmbInfo->pShares = pShareList;
|
||
}
|
||
|
||
if ( rc != SCESTATUS_SUCCESS ) {
|
||
//
|
||
// free memory
|
||
//
|
||
SmbsvcpFree(pSmbInfo);
|
||
|
||
}
|
||
|
||
return(rc);
|
||
|
||
}
|
||
|
||
|
||
SCESTATUS
|
||
SmbsvcpAddAShareToList(
|
||
OUT PSMBSVC_SHARES *pShareList,
|
||
IN PWSTR ShareName,
|
||
IN DWORD Status,
|
||
IN PSECURITY_DESCRIPTOR pSD
|
||
)
|
||
/*
|
||
Routine Description:
|
||
|
||
This routine adds a share's information (Name, Security descriptor, and
|
||
security information) to the list of shares. Memory allocated for the
|
||
share node must be freed using LocalFree
|
||
|
||
Arguments:
|
||
|
||
pShareList - The ouput list of shares
|
||
|
||
ShareName - The name of the share
|
||
|
||
pSD - The security descriptor of the share object
|
||
|
||
Return Value:
|
||
|
||
SCESTATUS
|
||
*/
|
||
{
|
||
if ( pShareList == NULL || ShareName == NULL ) {
|
||
return(SCESTATUS_INVALID_PARAMETER);
|
||
}
|
||
|
||
PSMBSVC_SHARES pTempShare;
|
||
|
||
pTempShare = (PSMBSVC_SHARES)LocalAlloc(LMEM_FIXED, sizeof(SMBSVC_SHARES));
|
||
|
||
if ( pTempShare == NULL ) {
|
||
return(SCESTATUS_NOT_ENOUGH_RESOURCE);
|
||
|
||
} else {
|
||
|
||
SCESTATUS rc=SCESTATUS_SUCCESS;
|
||
|
||
pTempShare->ShareName = (PWSTR)LocalAlloc(LMEM_FIXED, (wcslen(ShareName)+1)*sizeof(WCHAR));
|
||
|
||
if ( pTempShare->ShareName == NULL ) {
|
||
rc = SCESTATUS_NOT_ENOUGH_RESOURCE;
|
||
|
||
} else {
|
||
wcscpy(pTempShare->ShareName, ShareName);
|
||
pTempShare->pShareSD = pSD;
|
||
pTempShare->Status = Status;
|
||
|
||
pTempShare->Next = *pShareList;
|
||
*pShareList = pTempShare;
|
||
}
|
||
|
||
if ( rc != SCESTATUS_SUCCESS ) {
|
||
LocalFree(pTempShare);
|
||
}
|
||
|
||
return(rc);
|
||
}
|
||
}
|
||
|
||
|
||
SCESTATUS
|
||
SmbsvcpFree(
|
||
IN PSMBSVC_SEC_INFO pSmbInfo
|
||
)
|
||
/*
|
||
Routine Description:
|
||
|
||
This routine frees the memory allocated for the components in the buffer.
|
||
|
||
Arguments:
|
||
|
||
pSmbInfo - the buffer to free.
|
||
|
||
Return Value:
|
||
|
||
SCESTATUS
|
||
*/
|
||
{
|
||
if ( pSmbInfo == NULL ) {
|
||
return(SCESTATUS_SUCCESS);
|
||
}
|
||
|
||
if ( pSmbInfo->NullSessionPipes != NULL ) {
|
||
LocalFree(pSmbInfo->NullSessionPipes);
|
||
}
|
||
|
||
if ( pSmbInfo->NullSessionShares != NULL ) {
|
||
LocalFree(pSmbInfo->NullSessionShares);
|
||
}
|
||
|
||
SmbsvcpFreeShareList(pSmbInfo->pShares);
|
||
|
||
return( SmbsvcpResetInfo( pSmbInfo ) );
|
||
|
||
}
|
||
|
||
|
||
SCESTATUS
|
||
SmbsvcpFreeShareList(
|
||
PSMBSVC_SHARES pShares
|
||
)
|
||
{
|
||
PSMBSVC_SHARES pTemp, pTemp2;
|
||
|
||
pTemp = pShares;
|
||
while (pTemp != NULL ) {
|
||
|
||
if ( pTemp->ShareName != NULL )
|
||
LocalFree(pTemp->ShareName);
|
||
|
||
if (pTemp->pShareSD != NULL )
|
||
LocalFree(pTemp->pShareSD);
|
||
|
||
pTemp2 = pTemp;
|
||
pTemp = pTemp->Next;
|
||
|
||
LocalFree(pTemp2);
|
||
}
|
||
|
||
return(SCESTATUS_SUCCESS);
|
||
}
|
||
|
||
|
||
|
||
SCESTATUS
|
||
SmbsvcpWriteError(
|
||
IN PFSCE_LOG_INFO pfLogCallback,
|
||
IN INT ErrLevel,
|
||
IN DWORD ErrCode,
|
||
IN PWSTR Mes
|
||
)
|
||
|
||
{
|
||
if ( Mes == NULL || pfLogCallback == NULL ) {
|
||
return(SCESTATUS_SUCCESS);
|
||
}
|
||
|
||
SCESTATUS rc;
|
||
|
||
__try {
|
||
|
||
rc = (*pfLogCallback)(ErrLevel,
|
||
ErrCode,
|
||
Mes);
|
||
|
||
} __except (EXCEPTION_EXECUTE_HANDLER) {
|
||
rc = SCESTATUS_SERVICE_NOT_SUPPORT;
|
||
}
|
||
|
||
return(rc);
|
||
|
||
}
|
||
|
||
SCESTATUS
|
||
SmbsvcpWriteError2(
|
||
IN PFSCE_LOG_INFO pfLogCallback,
|
||
IN INT ErrLevel,
|
||
IN DWORD ErrCode,
|
||
IN UINT nId,
|
||
...
|
||
)
|
||
{
|
||
WCHAR szTempString[256];
|
||
TCHAR buf[SMBSVC_BUF_LEN];
|
||
va_list args;
|
||
|
||
if ( nId > 0 && pfLogCallback ) {
|
||
|
||
szTempString[0] = L'\0';
|
||
|
||
if ( MyModuleHandle != NULL ) {
|
||
|
||
LoadString( MyModuleHandle,
|
||
nId,
|
||
szTempString,
|
||
256
|
||
);
|
||
}
|
||
|
||
//
|
||
// check arguments
|
||
//
|
||
va_start( args, nId );
|
||
vswprintf( buf, szTempString, args );
|
||
va_end( args );
|
||
|
||
return ( SmbsvcpWriteError(pfLogCallback,
|
||
ErrLevel,
|
||
ErrCode,
|
||
buf) );
|
||
}
|
||
|
||
return(SCESTATUS_SUCCESS);
|
||
|
||
}
|
||
|
||
|
||
|
||
SCESTATUS
|
||
SmbsvcpConfigureValue(
|
||
IN PCWSTR RegKey,
|
||
IN PCWSTR ValueName,
|
||
IN DWORD Value
|
||
)
|
||
{
|
||
if ( Value == (DWORD)SMBSVC_NO_VALUE ||
|
||
(BYTE)Value == (BYTE)SMBSVC_NO_VALUE ) {
|
||
return(SCESTATUS_SUCCESS);
|
||
}
|
||
|
||
DWORD Win32rc;
|
||
|
||
Win32rc = SmbsvcpRegSetIntValue(
|
||
HKEY_LOCAL_MACHINE,
|
||
(PWSTR)RegKey,
|
||
(PWSTR)ValueName,
|
||
Value
|
||
);
|
||
|
||
return(SmbsvcpDosErrorToSceStatus(Win32rc));
|
||
}
|
||
|
||
|
||
SCESTATUS
|
||
SmbsvcpQueryShareList(
|
||
OUT PSMBSVC_SHARES *pShareList,
|
||
OUT PDWORD ShareCount
|
||
)
|
||
{
|
||
if ( pShareList == NULL || ShareCount == NULL ) {
|
||
return(SCESTATUS_INVALID_PARAMETER);
|
||
}
|
||
|
||
LPSHARE_INFO_502 pShareInfo=NULL;
|
||
DWORD EntriesRead, TotalEntries, ResumeHandle=0;
|
||
|
||
SCESTATUS rc=SCESTATUS_SUCCESS;
|
||
|
||
DWORD Win32rc;
|
||
DWORD nCount=0;
|
||
|
||
*ShareCount = 0;
|
||
|
||
do {
|
||
|
||
Win32rc = NetShareEnum (
|
||
NULL,
|
||
502,
|
||
(LPBYTE *)&pShareInfo,
|
||
0xFFFFFFFF,
|
||
&EntriesRead,
|
||
&TotalEntries,
|
||
&ResumeHandle
|
||
);
|
||
|
||
if ( Win32rc == ERROR_SUCCESS ) {
|
||
|
||
nCount += EntriesRead;
|
||
|
||
for( DWORD i=0; i < EntriesRead; i++ ) {
|
||
|
||
if( (pShareInfo + i)->shi502_type == STYPE_DISKTREE )
|
||
{
|
||
PSECURITY_DESCRIPTOR pSD=NULL;
|
||
|
||
if ( (pShareInfo + i)->shi502_security_descriptor != NULL ) {
|
||
|
||
NTSTATUS status;
|
||
DWORD RequireLength=0;
|
||
|
||
status = RtlMakeSelfRelativeSD(
|
||
(pShareInfo + i)->shi502_security_descriptor,
|
||
NULL,
|
||
&RequireLength
|
||
);
|
||
|
||
if ( status == STATUS_BUFFER_TOO_SMALL ) {
|
||
|
||
pSD = (PSECURITY_DESCRIPTOR)LocalAlloc(LMEM_FIXED, RequireLength+1);
|
||
|
||
status = RtlMakeSelfRelativeSD(
|
||
(pShareInfo + i)->shi502_security_descriptor,
|
||
pSD,
|
||
&RequireLength
|
||
);
|
||
}
|
||
rc = SmbsvcpDosErrorToSceStatus(RtlNtStatusToDosError(status));
|
||
}
|
||
|
||
if ( rc == SCESTATUS_SUCCESS ) {
|
||
|
||
rc = SmbsvcpAddAShareToList(pShareList,
|
||
(pShareInfo + i)->shi502_netname,
|
||
0,
|
||
pSD
|
||
);
|
||
if ( rc == SCESTATUS_SUCCESS ) {
|
||
(*ShareCount)++;
|
||
|
||
} else if ( pSD != NULL ) {
|
||
LocalFree(pSD);
|
||
pSD = NULL;
|
||
}
|
||
|
||
}
|
||
if ( rc != SCESTATUS_SUCCESS ) {
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
//
|
||
// free the buffer
|
||
//
|
||
NetApiBufferFree(pShareInfo);
|
||
pShareInfo = NULL;
|
||
|
||
} else
|
||
rc = SmbsvcpDosErrorToSceStatus(Win32rc);
|
||
|
||
} while ( rc == SCESTATUS_SUCCESS && nCount < TotalEntries );
|
||
|
||
if ( rc != SCESTATUS_SUCCESS && *pShareList != NULL ) {
|
||
|
||
SmbsvcpFreeShareList(*pShareList);
|
||
*pShareList = NULL;
|
||
|
||
*ShareCount = 0;
|
||
}
|
||
|
||
return(rc);
|
||
}
|
||
|
||
|
||
SCESTATUS
|
||
SmbsvcpAnalyzeValue(
|
||
IN PCWSTR RegKey,
|
||
IN PCWSTR RegValueName,
|
||
IN PCWSTR KeyName,
|
||
IN DWORD ConfigValue,
|
||
OUT PSCESVC_ANALYSIS_LINE pLineInfo,
|
||
IN OUT PDWORD pCount
|
||
)
|
||
{
|
||
if ( RegKey == NULL || RegValueName == NULL ||
|
||
KeyName == NULL || pLineInfo == NULL || pCount == NULL ) {
|
||
|
||
return(SCESTATUS_INVALID_PARAMETER);
|
||
}
|
||
|
||
if ( ConfigValue == (DWORD)SMBSVC_NO_VALUE ||
|
||
(BYTE)ConfigValue == (BYTE)SMBSVC_NO_VALUE ) {
|
||
return(SCESTATUS_SUCCESS);
|
||
}
|
||
//
|
||
// query the registry value
|
||
//
|
||
DWORD Value=0;
|
||
DWORD Win32rc = SmbsvcpRegQueryIntValue(
|
||
HKEY_LOCAL_MACHINE,
|
||
(PWSTR)RegKey,
|
||
(PWSTR)RegValueName,
|
||
&Value
|
||
);
|
||
if ( Win32rc == ERROR_SUCCESS || Win32rc == ERROR_FILE_NOT_FOUND ) {
|
||
|
||
Win32rc = ERROR_SUCCESS;
|
||
|
||
if ( ConfigValue != Value ) {
|
||
//
|
||
// mismatched
|
||
//
|
||
PWSTR Key, StrValue;
|
||
DWORD ValueLen;
|
||
//
|
||
// allocate buffer for key and value
|
||
//
|
||
Key = (PWSTR)LocalAlloc(LMEM_FIXED, (wcslen(KeyName)+1)*sizeof(WCHAR));
|
||
|
||
if ( Key != NULL ) {
|
||
|
||
WCHAR TempBuf[16];
|
||
|
||
memset(TempBuf, '\0', 32);
|
||
swprintf(TempBuf, L"%d", Value);
|
||
|
||
DWORD Len = wcslen(TempBuf);
|
||
|
||
StrValue = (PWSTR)LocalAlloc(LMEM_FIXED, (Len+1)*sizeof(WCHAR));
|
||
|
||
if ( StrValue != NULL ) {
|
||
//
|
||
// assign to the line buffer and increment the count
|
||
//
|
||
wcsncpy(StrValue, TempBuf, Len);
|
||
StrValue[Len] = L'\0';
|
||
|
||
wcscpy(Key, KeyName);
|
||
|
||
pLineInfo->Key = Key;
|
||
pLineInfo->Value = (PBYTE)StrValue;
|
||
pLineInfo->ValueLen = Len*sizeof(WCHAR);
|
||
|
||
(*pCount)++;
|
||
|
||
} else {
|
||
Win32rc = ERROR_NOT_ENOUGH_MEMORY;
|
||
LocalFree(Key);
|
||
}
|
||
|
||
} else
|
||
Win32rc = ERROR_NOT_ENOUGH_MEMORY;
|
||
}
|
||
}
|
||
|
||
return(SmbsvcpDosErrorToSceStatus(Win32rc));
|
||
|
||
}
|
||
|
||
DWORD
|
||
SmbsvcpConvertStringToMultiSz(
|
||
IN PWSTR theStr,
|
||
IN DWORD theLen,
|
||
OUT PBYTE *outValue,
|
||
OUT PDWORD outLen
|
||
)
|
||
{
|
||
if ( outValue == NULL || outLen == NULL ) {
|
||
return(ERROR_INVALID_PARAMETER);
|
||
}
|
||
*outValue = NULL;
|
||
*outLen = 0;
|
||
|
||
if ( theStr == NULL || theLen == 0 || theLen == SMBSVC_NO_VALUE ) {
|
||
return ERROR_SUCCESS;
|
||
}
|
||
|
||
*outValue = (PBYTE)LocalAlloc(0, theLen+4);
|
||
|
||
if ( *outValue != NULL ) {
|
||
wcscpy((PWSTR)(*outValue), theStr);
|
||
// terminate the last w-char with 0 for Multi-Sz format
|
||
*((PWSTR)(*outValue+theLen+2)) = L'\0';
|
||
|
||
// replace ',' with '\0'
|
||
PWSTR pTemp = (PWSTR)(*outValue);
|
||
|
||
while ( pTemp != NULL ) {
|
||
pTemp = wcschr(pTemp, L',');
|
||
if ( pTemp != NULL ) {
|
||
*pTemp = L'\0';
|
||
pTemp++;
|
||
}
|
||
}
|
||
|
||
return ERROR_SUCCESS;
|
||
|
||
} else
|
||
return ERROR_NOT_ENOUGH_MEMORY;
|
||
|
||
}
|
||
|
||
|
||
SCESTATUS
|
||
SmbsvcpAnalyzeMultiSzString(
|
||
IN PCWSTR RegKey,
|
||
IN PCWSTR RegValueName,
|
||
IN PWSTR pConfigInfo,
|
||
IN DWORD InfoLength,
|
||
OUT PSCESVC_ANALYSIS_LINE pLineInfo,
|
||
IN OUT PDWORD pCount
|
||
)
|
||
{
|
||
if ( RegKey == NULL || RegValueName == NULL ||
|
||
pLineInfo == NULL || pCount == NULL ) {
|
||
|
||
return(SCESTATUS_INVALID_PARAMETER);
|
||
}
|
||
|
||
if ( InfoLength == SMBSVC_NO_VALUE ) {
|
||
// do not configure
|
||
return(SCESTATUS_SUCCESS);
|
||
}
|
||
//
|
||
// query the registry value
|
||
//
|
||
DWORD RegType;
|
||
PWSTR Value=NULL;
|
||
|
||
DWORD Win32rc = SmbsvcpRegQueryValue(
|
||
HKEY_LOCAL_MACHINE,
|
||
(PWSTR)RegKey,
|
||
(PWSTR)RegValueName,
|
||
(PVOID *)&Value,
|
||
&RegType
|
||
);
|
||
|
||
if ( Win32rc == ERROR_SUCCESS || Win32rc == ERROR_FILE_NOT_FOUND ) {
|
||
|
||
BOOL Diff;
|
||
DWORD ValueLen;
|
||
|
||
//
|
||
// change multi-sz to comma separated strings IN PLACE
|
||
//
|
||
SmbsvcpChangeMultiSzToString(Value);
|
||
|
||
Win32rc = SmbsvcpCompareMultiSzString(pConfigInfo, Value, &ValueLen, &Diff);
|
||
|
||
if (Win32rc == ERROR_SUCCESS && Diff ) {
|
||
//
|
||
// mismatched
|
||
//
|
||
PWSTR Key;
|
||
//
|
||
// allocate buffer for key and value
|
||
//
|
||
Key = (PWSTR)LocalAlloc(LMEM_FIXED, (wcslen(RegValueName)+1)*sizeof(WCHAR));
|
||
|
||
if ( Key != NULL ) {
|
||
|
||
//
|
||
// assign to the line buffer and increment the count
|
||
//
|
||
wcscpy(Key, RegValueName);
|
||
|
||
pLineInfo->Key = Key;
|
||
pLineInfo->Value = (PBYTE)Value;
|
||
pLineInfo->ValueLen = ValueLen*sizeof(WCHAR);
|
||
|
||
(*pCount)++;
|
||
|
||
Value = NULL;
|
||
} else
|
||
Win32rc = ERROR_NOT_ENOUGH_MEMORY;
|
||
}
|
||
//
|
||
// free Value is not NULL
|
||
//
|
||
if ( Value != NULL ) {
|
||
LocalFree(Value);
|
||
}
|
||
}
|
||
|
||
return(SmbsvcpDosErrorToSceStatus(Win32rc));
|
||
|
||
}
|
||
|
||
|
||
DWORD
|
||
SmbsvcpChangeMultiSzToString(
|
||
IN PWSTR Value
|
||
)
|
||
{
|
||
if ( Value == NULL )
|
||
return ERROR_SUCCESS;
|
||
|
||
//
|
||
// replace '\0' with ','s
|
||
//
|
||
PWSTR pTemp=Value;
|
||
|
||
while ( pTemp ) {
|
||
|
||
if ( *pTemp == L'\0' ) {
|
||
|
||
if ( *(pTemp+1) != L'\0' )
|
||
*pTemp = L',';
|
||
else
|
||
break;
|
||
}
|
||
|
||
pTemp++;
|
||
}
|
||
|
||
|
||
return ERROR_SUCCESS;
|
||
|
||
}
|
||
|
||
|
||
DWORD
|
||
SmbsvcpCompareMultiSzString(
|
||
IN PWSTR pConfigInfo,
|
||
IN PWSTR Value,
|
||
OUT PDWORD pValueLen,
|
||
OUT PBOOL pDiff
|
||
)
|
||
{
|
||
if ( pDiff == NULL || pValueLen == NULL ) {
|
||
return(ERROR_INVALID_PARAMETER);
|
||
}
|
||
|
||
*pDiff = FALSE;
|
||
*pValueLen = 0;
|
||
|
||
if ( pConfigInfo == NULL && Value == NULL ) {
|
||
return(ERROR_SUCCESS);
|
||
}
|
||
|
||
if ( (pConfigInfo == NULL && Value != NULL) ||
|
||
(pConfigInfo != NULL && Value == NULL) ) {
|
||
|
||
*pDiff = TRUE;
|
||
return ERROR_SUCCESS;
|
||
}
|
||
|
||
DWORD CountValue=0, ValueLen=0;
|
||
DWORD ConfigLen=0, CountConfig=0;
|
||
|
||
DWORD Win32rc;
|
||
|
||
Win32rc = SmbsvcpCountComponents(Value, &ValueLen, &CountValue);
|
||
|
||
//
|
||
// both pConfigInfo and Value are not NULL
|
||
//
|
||
if ( Win32rc == ERROR_SUCCESS ) {
|
||
*pValueLen = ValueLen;
|
||
Win32rc = SmbsvcpCountComponents(pConfigInfo, &ConfigLen, &CountConfig);
|
||
}
|
||
|
||
if ( Win32rc == ERROR_SUCCESS ) {
|
||
|
||
if ( ConfigLen != ValueLen ||
|
||
CountConfig != CountValue ) {
|
||
|
||
*pDiff = TRUE;
|
||
return(Win32rc);
|
||
}
|
||
|
||
if ( CountConfig == 0 ) {
|
||
//
|
||
// No component, return FALSE for *pDiff
|
||
//
|
||
return(Win32rc);
|
||
}
|
||
//
|
||
// both value are not empty, have the same count and same length
|
||
// build the pointers into array to compare
|
||
//
|
||
PWSTR *ConfigPtr;
|
||
PWSTR *ValuePtr;
|
||
|
||
ConfigPtr = (PWSTR *)LocalAlloc(LMEM_FIXED, CountConfig*sizeof(PWSTR));
|
||
if ( ConfigPtr != NULL ) {
|
||
|
||
ValuePtr = (PWSTR *)LocalAlloc(LMEM_FIXED, CountValue*2*sizeof(PWSTR));
|
||
|
||
if ( ValuePtr != NULL ) {
|
||
|
||
PWSTR pTemp = (PWSTR)pConfigInfo;
|
||
DWORD i = 0;
|
||
|
||
//
|
||
// build the pointers from pConfigInfo into ConfigPtr
|
||
//
|
||
do {
|
||
ConfigPtr[i++] = pTemp;
|
||
pTemp = wcschr(pTemp, L',');
|
||
|
||
if ( pTemp != NULL ) {
|
||
pTemp++;
|
||
}
|
||
} while ( pTemp != NULL );
|
||
|
||
pTemp = (PWSTR)Value;
|
||
i = 0;
|
||
|
||
//
|
||
// build the pointers from Value into ValuePtr
|
||
//
|
||
do {
|
||
ValuePtr[i++] = pTemp;
|
||
pTemp = wcschr(pTemp, L',');
|
||
|
||
if ( pTemp != NULL ) {
|
||
ValuePtr[i] = (PWSTR)((DWORD_PTR)pTemp-(DWORD_PTR)(ValuePtr[i-1]));
|
||
i++;
|
||
pTemp++;
|
||
|
||
} else {
|
||
|
||
ValuePtr[i] = (PWSTR)(wcslen(ValuePtr[i-1]));
|
||
i++;
|
||
}
|
||
|
||
} while ( pTemp != NULL );
|
||
|
||
DWORD j, nLen;
|
||
|
||
//
|
||
// compare two pointer arrays. if a match is found, the pointer element is set to NULL
|
||
// so next time it won't be compared again.
|
||
//
|
||
for ( i=0; i<CountConfig; i++ ) {
|
||
|
||
if ( i == CountConfig-1 )
|
||
// the last one
|
||
nLen = wcslen(ConfigPtr[i]);
|
||
else
|
||
nLen = (DWORD)(ConfigPtr[i+1]-ConfigPtr[i]-1);
|
||
|
||
for ( j=0; j<CountValue*2; j+=2) {
|
||
|
||
if ( ValuePtr[j] != NULL ) {
|
||
|
||
if ( (DWORD_PTR)(ValuePtr[j+1]) == nLen &&
|
||
_wcsnicmp(ConfigPtr[i], ValuePtr[j], nLen) == 0 ) {
|
||
|
||
ValuePtr[j] = NULL;
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
if ( j >= CountValue*2 ) {
|
||
//
|
||
// did not find a match
|
||
//
|
||
*pDiff = TRUE;
|
||
break;
|
||
}
|
||
}
|
||
|
||
for ( j=0; j < CountValue*2; j+=2 ) {
|
||
|
||
if ( ValuePtr[j] != NULL ) {
|
||
*pDiff = TRUE;
|
||
break;
|
||
}
|
||
}
|
||
|
||
LocalFree(ValuePtr);
|
||
|
||
} else
|
||
Win32rc = ERROR_NOT_ENOUGH_MEMORY;
|
||
|
||
|
||
LocalFree(ConfigPtr);
|
||
|
||
} else
|
||
Win32rc = ERROR_NOT_ENOUGH_MEMORY;
|
||
|
||
}
|
||
|
||
return(Win32rc);
|
||
|
||
}
|
||
|
||
|
||
DWORD
|
||
SmbsvcpCountComponents(
|
||
IN PWSTR Value,
|
||
OUT PDWORD ValueLen,
|
||
OUT PDWORD Count
|
||
)
|
||
{
|
||
if ( ValueLen == NULL ||
|
||
Count == NULL ) {
|
||
return(ERROR_INVALID_PARAMETER);
|
||
}
|
||
|
||
if ( Value == NULL ) {
|
||
*ValueLen = 0;
|
||
*Count = 0;
|
||
return(ERROR_SUCCESS);
|
||
}
|
||
|
||
PWSTR pTemp = (PWSTR)Value;
|
||
|
||
DWORD Len = 0;
|
||
*Count = 0;
|
||
*ValueLen = wcslen(pTemp);
|
||
|
||
do {
|
||
|
||
(*Count)++;
|
||
pTemp = wcschr(pTemp, L',');
|
||
if ( pTemp != NULL ) {
|
||
pTemp++;
|
||
}
|
||
|
||
} while ( pTemp != NULL );
|
||
|
||
|
||
return(ERROR_SUCCESS);
|
||
}
|
||
|
||
|
||
SCESTATUS
|
||
SmbsvcpUpdateMultiSzString(
|
||
IN PSCESVC_CALLBACK_INFO pSceCbInfo,
|
||
IN SCESVC_CONFIGURATION_LINE NewLine,
|
||
IN PSCESVC_CONFIGURATION_INFO pConfigInfo OPTIONAL,
|
||
IN PSCESVC_ANALYSIS_INFO pAnaInfo OPTIONAL
|
||
)
|
||
{
|
||
//
|
||
// the value in the structure is Multi-Sz
|
||
//
|
||
if ( pSceCbInfo == NULL ||
|
||
pSceCbInfo->sceHandle == NULL ||
|
||
pSceCbInfo->pfSetInfo == NULL ) {
|
||
|
||
return(SCESTATUS_INVALID_PARAMETER);
|
||
}
|
||
|
||
SCESTATUS rc=SCESTATUS_SUCCESS;
|
||
DWORD Win32rc;
|
||
|
||
BOOL bDiff, bDiff2;
|
||
DWORD ValueLen;
|
||
|
||
//
|
||
// prepare an update buffer
|
||
//
|
||
SCESVC_ANALYSIS_INFO UpdtAnaInfo;
|
||
SCESVC_ANALYSIS_LINE UpdtAnaLine;
|
||
|
||
UpdtAnaInfo.Count = 1;
|
||
UpdtAnaInfo.Lines = &UpdtAnaLine;
|
||
|
||
SCESVC_CONFIGURATION_INFO UpdtConfigInfo;
|
||
SCESVC_CONFIGURATION_LINE UpdtConfigLine;
|
||
|
||
UpdtConfigInfo.Count = 1;
|
||
UpdtConfigInfo.Lines = &UpdtConfigLine;
|
||
|
||
|
||
if ( pAnaInfo == NULL ) {
|
||
//
|
||
// old status is match, or new added configuration key
|
||
//
|
||
if ( pConfigInfo != NULL && pConfigInfo->Lines != NULL ) {
|
||
// match item
|
||
Win32rc = SmbsvcpCompareMultiSzString(
|
||
NewLine.Value,
|
||
pConfigInfo->Lines[0].Value,
|
||
&ValueLen,
|
||
&bDiff
|
||
);
|
||
if ( Win32rc != ERROR_SUCCESS ) {
|
||
return(SmbsvcpDosErrorToSceStatus(Win32rc));
|
||
}
|
||
|
||
} else {
|
||
// new add
|
||
bDiff = TRUE;
|
||
ValueLen = 0;
|
||
}
|
||
|
||
if ( bDiff ) {
|
||
|
||
SmbsvcpWriteError(pSceCbInfo->pfLogInfo,
|
||
SCE_LOG_LEVEL_DEBUG,
|
||
0,
|
||
L"match->mismatch"
|
||
);
|
||
//
|
||
// mismatch should be raised with ConfigValue
|
||
//
|
||
UpdtAnaLine.Key = NewLine.Key;
|
||
UpdtAnaLine.Value = ( pConfigInfo != NULL ) ? (PBYTE)(pConfigInfo->Lines[0].Value) : NULL;
|
||
UpdtAnaLine.ValueLen = ( pConfigInfo != NULL ) ? pConfigInfo->Lines[0].ValueLen : 0;
|
||
|
||
__try {
|
||
rc = (*(pSceCbInfo->pfSetInfo))(
|
||
pSceCbInfo->sceHandle,
|
||
SceSvcAnalysisInfo,
|
||
NULL,
|
||
TRUE,
|
||
(PVOID)&UpdtAnaInfo
|
||
);
|
||
} __except (EXCEPTION_EXECUTE_HANDLER) {
|
||
rc = SCESTATUS_SERVICE_NOT_SUPPORT;
|
||
}
|
||
|
||
if ( rc == SCESTATUS_SUCCESS ) {
|
||
//
|
||
// update configuration setting with NewValue
|
||
//
|
||
UpdtConfigLine.Key = NewLine.Key;
|
||
UpdtConfigLine.Value = NewLine.Value;
|
||
UpdtConfigLine.ValueLen = NewLine.ValueLen;
|
||
|
||
__try {
|
||
rc = (*(pSceCbInfo->pfSetInfo))(
|
||
pSceCbInfo->sceHandle,
|
||
SceSvcConfigurationInfo,
|
||
NULL,
|
||
TRUE,
|
||
(PVOID)&UpdtConfigInfo
|
||
);
|
||
|
||
} __except (EXCEPTION_EXECUTE_HANDLER) {
|
||
rc = SCESTATUS_SERVICE_NOT_SUPPORT;
|
||
}
|
||
}
|
||
}
|
||
|
||
} else {
|
||
//
|
||
// old status is mismatch for this item
|
||
//
|
||
Win32rc = SmbsvcpCompareMultiSzString(
|
||
NewLine.Value,
|
||
(PWSTR)(pAnaInfo->Lines[0].Value),
|
||
&ValueLen,
|
||
&bDiff
|
||
);
|
||
if ( Win32rc == ERROR_SUCCESS ) {
|
||
|
||
if (pConfigInfo != NULL && pConfigInfo->Lines != NULL ) {
|
||
|
||
Win32rc = SmbsvcpCompareMultiSzString(
|
||
NewLine.Value,
|
||
pConfigInfo->Lines[0].Value,
|
||
&ValueLen,
|
||
&bDiff2
|
||
);
|
||
} else {
|
||
bDiff2 = TRUE;
|
||
ValueLen = 0;
|
||
}
|
||
|
||
}
|
||
if ( Win32rc != ERROR_SUCCESS ) {
|
||
return(SmbsvcpDosErrorToSceStatus(Win32rc));
|
||
}
|
||
|
||
if ( !bDiff ) {
|
||
|
||
SmbsvcpWriteError(pSceCbInfo->pfLogInfo,
|
||
SCE_LOG_LEVEL_DEBUG,
|
||
0,
|
||
L"mismatch->match"
|
||
);
|
||
//
|
||
// now it is matched, delete the analysis entry
|
||
//
|
||
__try {
|
||
rc = (*(pSceCbInfo->pfSetInfo))(
|
||
pSceCbInfo->sceHandle,
|
||
SceSvcAnalysisInfo,
|
||
NewLine.Key,
|
||
TRUE,
|
||
NULL
|
||
);
|
||
|
||
} __except (EXCEPTION_EXECUTE_HANDLER) {
|
||
rc = SCESTATUS_SERVICE_NOT_SUPPORT;
|
||
}
|
||
}
|
||
|
||
if ( bDiff2 ) {
|
||
//
|
||
// update the configuration setting
|
||
//
|
||
UpdtConfigLine.Key = NewLine.Key;
|
||
UpdtConfigLine.Value = NewLine.Value;
|
||
UpdtConfigLine.ValueLen = NewLine.ValueLen;
|
||
|
||
__try {
|
||
rc = (*(pSceCbInfo->pfSetInfo))(
|
||
pSceCbInfo->sceHandle,
|
||
SceSvcConfigurationInfo,
|
||
NULL,
|
||
TRUE,
|
||
(PVOID)&UpdtConfigInfo
|
||
);
|
||
} __except (EXCEPTION_EXECUTE_HANDLER) {
|
||
rc = SCESTATUS_SERVICE_NOT_SUPPORT;
|
||
}
|
||
}
|
||
}
|
||
|
||
return(rc);
|
||
}
|
||
|
||
|
||
SCESTATUS
|
||
SmbsvcpUpdateShareValue(
|
||
IN PSCESVC_CALLBACK_INFO pSceCbInfo,
|
||
IN SCESVC_CONFIGURATION_LINE NewLine,
|
||
IN PSCESVC_CONFIGURATION_INFO pConfigInfo OPTIONAL,
|
||
IN PSCESVC_ANALYSIS_INFO pAnaInfo OPTIONAL
|
||
)
|
||
{
|
||
//
|
||
// the value in the structure is "Share," followed by a security descriptor text
|
||
//
|
||
if ( pSceCbInfo == NULL ||
|
||
pSceCbInfo->sceHandle == NULL ||
|
||
pSceCbInfo->pfSetInfo == NULL ) {
|
||
|
||
return(SCESTATUS_INVALID_PARAMETER);
|
||
}
|
||
|
||
SCESTATUS rc=SCESTATUS_SUCCESS;
|
||
|
||
//
|
||
// prepare an update buffer
|
||
//
|
||
SCESVC_ANALYSIS_INFO UpdtAnaInfo;
|
||
SCESVC_ANALYSIS_LINE UpdtAnaLine;
|
||
|
||
UpdtAnaInfo.Count = 1;
|
||
UpdtAnaInfo.Lines = &UpdtAnaLine;
|
||
|
||
SCESVC_CONFIGURATION_INFO UpdtConfigInfo;
|
||
SCESVC_CONFIGURATION_LINE UpdtConfigLine;
|
||
|
||
UpdtConfigInfo.Count = 1;
|
||
UpdtConfigInfo.Lines = &UpdtConfigLine;
|
||
|
||
PSECURITY_DESCRIPTOR pSD1=NULL, pSD2=NULL;
|
||
DWORD SDsize;
|
||
BOOL bEqual;
|
||
|
||
if ( pAnaInfo == NULL ) {
|
||
//
|
||
// old status is match, or a new added share
|
||
//
|
||
if ( pConfigInfo == NULL ) {
|
||
//
|
||
// a new share, query the current setting in the system
|
||
//
|
||
PSHARE_INFO_1501 ShareInfo=NULL;
|
||
DWORD Win32rc;
|
||
|
||
Win32rc = NetShareGetInfo (
|
||
NULL,
|
||
NewLine.Key,
|
||
1501,
|
||
(LPBYTE *)&ShareInfo
|
||
);
|
||
|
||
if ( Win32rc == ERROR_SUCCESS ) {
|
||
|
||
PWSTR TextSD=NULL;
|
||
DWORD SDsize=0;
|
||
|
||
if ( ShareInfo->shi1501_security_descriptor != NULL ) {
|
||
|
||
#if defined(_NT4BACK_PORT)
|
||
rc = SceSvcConvertSDToText(
|
||
ShareInfo->shi1501_security_descriptor,
|
||
DACL_SECURITY_INFORMATION,
|
||
&TextSD,
|
||
&SDsize
|
||
);
|
||
rc = SmbsvcpDosErrorToSceStatus(rc);
|
||
#else
|
||
if ( !ConvertSecurityDescriptorToStringSecurityDescriptor(
|
||
ShareInfo->shi1501_security_descriptor,
|
||
SDDL_REVISION,
|
||
DACL_SECURITY_INFORMATION,
|
||
&TextSD,
|
||
&SDsize
|
||
) ) {
|
||
rc = SmbsvcpDosErrorToSceStatus(GetLastError());
|
||
} else {
|
||
rc = SCESTATUS_SUCCESS;
|
||
|
||
}
|
||
#endif
|
||
}
|
||
|
||
if ( rc == SCESTATUS_SUCCESS ) {
|
||
|
||
PWSTR Value;
|
||
|
||
Value = (PWSTR)LocalAlloc(LMEM_FIXED, (SDsize+9)*sizeof(WCHAR));
|
||
|
||
if ( Value != NULL ) {
|
||
|
||
if ( TextSD != NULL )
|
||
swprintf(Value, L"Share,%1d,%s", SMBSVC_STATUS_NOT_CONFIGURED, TextSD );
|
||
else
|
||
swprintf(Value, L"Share,%1d,",SMBSVC_STATUS_NOT_CONFIGURED);
|
||
|
||
Value[SDsize+8] = L'\0';
|
||
|
||
UpdtAnaLine.Key = NewLine.Key;
|
||
UpdtAnaLine.Value = (PBYTE)Value;
|
||
UpdtAnaLine.ValueLen = (SDsize+8)*sizeof(WCHAR);
|
||
|
||
__try {
|
||
rc = (*(pSceCbInfo->pfSetInfo))(
|
||
pSceCbInfo->sceHandle,
|
||
SceSvcAnalysisInfo,
|
||
NULL,
|
||
TRUE,
|
||
(PVOID)&UpdtAnaInfo
|
||
);
|
||
|
||
} __except (EXCEPTION_EXECUTE_HANDLER) {
|
||
rc = SCESTATUS_SERVICE_NOT_SUPPORT;
|
||
}
|
||
|
||
LocalFree(Value);
|
||
|
||
} else
|
||
rc = SCESTATUS_NOT_ENOUGH_RESOURCE;
|
||
|
||
}
|
||
|
||
NetApiBufferFree(ShareInfo);
|
||
|
||
} else
|
||
rc = SmbsvcpDosErrorToSceStatus(Win32rc);
|
||
|
||
} else {
|
||
//
|
||
// matched item.
|
||
//
|
||
bEqual = FALSE;
|
||
|
||
SECURITY_INFORMATION SeInfo;
|
||
|
||
if ( NewLine.ValueLen > 14 &&
|
||
NewLine.Value != NULL &&
|
||
NewLine.Value[8] != L'\0' ) {
|
||
|
||
#if defined(_NT4BACK_PORT)
|
||
|
||
rc = SceSvcConvertTextToSD(
|
||
NewLine.Value+8,
|
||
&pSD1,
|
||
&SDsize,
|
||
&SeInfo
|
||
);
|
||
rc = SmbsvcpDosErrorToSceStatus(rc);
|
||
|
||
#else
|
||
if ( !ConvertStringSecurityDescriptorToSecurityDescriptor(
|
||
(PCWSTR)(NewLine.Value+8),
|
||
SDDL_REVISION,
|
||
&pSD1,
|
||
NULL
|
||
) ) {
|
||
rc = SmbsvcpDosErrorToSceStatus(GetLastError());
|
||
} else {
|
||
rc = SCESTATUS_SUCCESS;
|
||
}
|
||
#endif
|
||
}
|
||
if ( rc == SCESTATUS_SUCCESS && pConfigInfo->Lines != NULL &&
|
||
pConfigInfo->Lines[0].ValueLen > 14 &&
|
||
pConfigInfo->Lines[0].Value != NULL &&
|
||
pConfigInfo->Lines[0].Value[8] != L'\0' ) {
|
||
|
||
#if defined(_NT4BACK_PORT)
|
||
|
||
rc = SceSvcConvertTextToSD(
|
||
pConfigInfo->Lines[0].Value+8,
|
||
&pSD2,
|
||
&SDsize,
|
||
&SeInfo
|
||
);
|
||
rc = SmbsvcpDosErrorToSceStatus(rc);
|
||
|
||
#else
|
||
if ( !ConvertStringSecurityDescriptorToSecurityDescriptor(
|
||
(PCWSTR)(pConfigInfo->Lines[0].Value+8),
|
||
SDDL_REVISION,
|
||
&pSD2,
|
||
NULL
|
||
) ) {
|
||
rc = SmbsvcpDosErrorToSceStatus(GetLastError());
|
||
}
|
||
#endif
|
||
}
|
||
|
||
if ( rc == SCESTATUS_SUCCESS ) {
|
||
|
||
rc = SmbsvcpEqualSecurityDescriptor(
|
||
pSD1,
|
||
pSD2,
|
||
FALSE,
|
||
&bEqual
|
||
);
|
||
}
|
||
|
||
if ( rc == SCESTATUS_SUCCESS && !bEqual ) {
|
||
|
||
SmbsvcpWriteError(pSceCbInfo->pfLogInfo,
|
||
SCE_LOG_LEVEL_DEBUG,
|
||
0,
|
||
L"match->mismatch"
|
||
);
|
||
//
|
||
// mismatch should be raised with ConfigValue
|
||
//
|
||
UpdtAnaLine.Key = NewLine.Key;
|
||
UpdtAnaLine.Value = (PBYTE)(pConfigInfo->Lines[0].Value);
|
||
UpdtAnaLine.ValueLen = pConfigInfo->Lines[0].ValueLen;
|
||
|
||
__try {
|
||
rc = (*(pSceCbInfo->pfSetInfo))(
|
||
pSceCbInfo->sceHandle,
|
||
SceSvcAnalysisInfo,
|
||
NULL,
|
||
TRUE,
|
||
(PVOID)&UpdtAnaInfo
|
||
);
|
||
|
||
} __except (EXCEPTION_EXECUTE_HANDLER) {
|
||
rc = SCESTATUS_SERVICE_NOT_SUPPORT;
|
||
}
|
||
}
|
||
}
|
||
|
||
if ( rc == SCESTATUS_SUCCESS ) {
|
||
//
|
||
// update configuration setting with NewValue
|
||
//
|
||
UpdtConfigLine.Key = NewLine.Key;
|
||
UpdtConfigLine.Value = NewLine.Value;
|
||
UpdtConfigLine.ValueLen = NewLine.ValueLen;
|
||
|
||
__try {
|
||
rc = (*(pSceCbInfo->pfSetInfo))(
|
||
pSceCbInfo->sceHandle,
|
||
SceSvcConfigurationInfo,
|
||
NULL,
|
||
TRUE,
|
||
(PVOID)&UpdtConfigInfo
|
||
);
|
||
|
||
} __except (EXCEPTION_EXECUTE_HANDLER) {
|
||
rc = SCESTATUS_SERVICE_NOT_SUPPORT;
|
||
}
|
||
}
|
||
|
||
} else {
|
||
//
|
||
// old status is mismatch for this item
|
||
//
|
||
bEqual = FALSE;
|
||
|
||
if ( NewLine.ValueLen > 14 &&
|
||
NewLine.Value != NULL &&
|
||
NewLine.Value[8] != L'\0' ) {
|
||
|
||
#if defined(_NT4BACK_PORT)
|
||
|
||
SECURITY_INFORMATION SeInfo;
|
||
|
||
rc = SceSvcConvertTextToSD(
|
||
NewLine.Value+8,
|
||
&pSD1,
|
||
&SDsize,
|
||
&SeInfo
|
||
);
|
||
rc = SmbsvcpDosErrorToSceStatus(rc);
|
||
|
||
#else
|
||
if ( !ConvertStringSecurityDescriptorToSecurityDescriptor(
|
||
(PCWSTR)(NewLine.Value+8),
|
||
SDDL_REVISION,
|
||
&pSD1,
|
||
NULL
|
||
) ) {
|
||
rc = SmbsvcpDosErrorToSceStatus(GetLastError());
|
||
} else {
|
||
rc = SCESTATUS_SUCCESS;
|
||
}
|
||
#endif
|
||
}
|
||
if ( rc == SCESTATUS_SUCCESS && pAnaInfo->Lines != NULL &&
|
||
pAnaInfo->Lines[0].ValueLen > 14 &&
|
||
pAnaInfo->Lines[0].Value != NULL &&
|
||
((PWSTR)(pAnaInfo->Lines[0].Value))[8] != L'\0' ) {
|
||
|
||
#if defined(_NT4BACK_PORT)
|
||
|
||
SECURITY_INFORMATION SeInfo;
|
||
|
||
rc = SceSvcConvertTextToSD(
|
||
(PWSTR)(pAnaInfo->Lines[0].Value+8),
|
||
&pSD2,
|
||
&SDsize,
|
||
&SeInfo
|
||
);
|
||
rc = SmbsvcpDosErrorToSceStatus(rc);
|
||
|
||
#else
|
||
if ( !ConvertStringSecurityDescriptorToSecurityDescriptor(
|
||
(PCWSTR)(pAnaInfo->Lines[0].Value+8),
|
||
SDDL_REVISION,
|
||
&pSD2,
|
||
NULL
|
||
) ) {
|
||
rc = SmbsvcpDosErrorToSceStatus(GetLastError());
|
||
} else {
|
||
rc = SCESTATUS_SUCCESS;
|
||
}
|
||
#endif
|
||
}
|
||
|
||
if ( rc == SCESTATUS_SUCCESS ) {
|
||
|
||
rc = SmbsvcpEqualSecurityDescriptor(
|
||
pSD1,
|
||
pSD2,
|
||
FALSE,
|
||
&bEqual
|
||
);
|
||
}
|
||
|
||
if ( rc == SCESTATUS_SUCCESS && bEqual ) {
|
||
|
||
SmbsvcpWriteError(pSceCbInfo->pfLogInfo,
|
||
SCE_LOG_LEVEL_DEBUG,
|
||
0,
|
||
L"mismatch->match"
|
||
);
|
||
//
|
||
// now it is matched, delete the analysis entry
|
||
//
|
||
__try {
|
||
rc = (*(pSceCbInfo->pfSetInfo))(
|
||
pSceCbInfo->sceHandle,
|
||
SceSvcAnalysisInfo,
|
||
NewLine.Key,
|
||
TRUE,
|
||
NULL
|
||
);
|
||
|
||
} __except (EXCEPTION_EXECUTE_HANDLER) {
|
||
rc = SCESTATUS_SERVICE_NOT_SUPPORT;
|
||
}
|
||
}
|
||
|
||
if ( rc == SCESTATUS_SUCCESS ) {
|
||
|
||
//
|
||
// update the configuration setting
|
||
//
|
||
UpdtConfigLine.Key = NewLine.Key;
|
||
UpdtConfigLine.Value = NewLine.Value;
|
||
UpdtConfigLine.ValueLen = NewLine.ValueLen;
|
||
|
||
__try {
|
||
rc = (*(pSceCbInfo->pfSetInfo))(
|
||
pSceCbInfo->sceHandle,
|
||
SceSvcConfigurationInfo,
|
||
NULL,
|
||
TRUE,
|
||
(PVOID)&UpdtConfigInfo
|
||
);
|
||
} __except (EXCEPTION_EXECUTE_HANDLER) {
|
||
rc = SCESTATUS_SERVICE_NOT_SUPPORT;
|
||
}
|
||
}
|
||
}
|
||
|
||
if ( pSD1 != NULL ) {
|
||
LocalFree(pSD1);
|
||
}
|
||
if ( pSD2 != NULL ) {
|
||
LocalFree(pSD2);
|
||
}
|
||
|
||
return(rc);
|
||
|
||
}
|
||
|
||
|
||
SCESTATUS
|
||
SmbsvcpEqualSecurityDescriptor(
|
||
IN PSECURITY_DESCRIPTOR pSD1,
|
||
IN PSECURITY_DESCRIPTOR pSD2,
|
||
IN BOOL bExplicitOnly,
|
||
OUT PBOOL pbEqual
|
||
)
|
||
{
|
||
if ( pbEqual == NULL ) {
|
||
return(SCESTATUS_INVALID_PARAMETER);
|
||
}
|
||
|
||
*pbEqual = TRUE;
|
||
|
||
if ( pSD1 == NULL && pSD2 == NULL )
|
||
return(SCESTATUS_SUCCESS);
|
||
|
||
BOOLEAN aclPresent, tFlag;
|
||
PACL pAcl1=NULL, pAcl2=NULL;
|
||
|
||
//
|
||
// get the DACL in each SD
|
||
//
|
||
if ( pSD1 == NULL ||
|
||
!NT_SUCCESS( RtlGetDaclSecurityDescriptor(
|
||
pSD1,
|
||
&aclPresent,
|
||
&pAcl1,
|
||
&tFlag)
|
||
) ) {
|
||
|
||
pAcl1 = NULL;
|
||
} else if ( !aclPresent )
|
||
pAcl1 = NULL;
|
||
|
||
if ( pSD2 == NULL ||
|
||
!NT_SUCCESS( RtlGetDaclSecurityDescriptor(
|
||
pSD2,
|
||
&aclPresent,
|
||
&pAcl2,
|
||
&tFlag)
|
||
) ) {
|
||
|
||
pAcl2 = NULL;
|
||
} else if ( !aclPresent )
|
||
pAcl2 = NULL;
|
||
//
|
||
// NOTE:
|
||
// if SD is NULL, it is Everyone Full Control
|
||
//
|
||
if ( pSD1 == NULL ) {
|
||
//
|
||
// check if pAcl2 has only Everyone Full Access
|
||
//
|
||
return( SmbsvcpDosErrorToSceStatus(
|
||
SmbsvcEveryoneFullAccess(pAcl2, bExplicitOnly, pbEqual) ));
|
||
}
|
||
if ( pSD2 == NULL ) {
|
||
//
|
||
// check if pAcl1 has only Everyone Full Access
|
||
//
|
||
return(SmbsvcpDosErrorToSceStatus(
|
||
SmbsvcEveryoneFullAccess(pAcl1, bExplicitOnly, pbEqual) ));
|
||
}
|
||
|
||
if ( pAcl1 == NULL && pAcl2 == NULL ) {
|
||
return(SCESTATUS_SUCCESS);
|
||
}
|
||
|
||
// if DACL is NULL, it is deny everyone access
|
||
if ( !bExplicitOnly) {
|
||
//
|
||
// if all aces are checked, they are different when one is NULL
|
||
//
|
||
if ( (pAcl1 == NULL && pAcl2 != NULL) ||
|
||
(pAcl1 != NULL && pAcl2 == NULL) ) {
|
||
|
||
*pbEqual = FALSE;
|
||
return(SCESTATUS_SUCCESS);
|
||
}
|
||
}
|
||
//
|
||
// compare two ACLs
|
||
//
|
||
BOOL bDifferent = FALSE;
|
||
DWORD rc;
|
||
|
||
rc = SmbsvcpCompareAcl( pAcl1, pAcl2, bExplicitOnly, &bDifferent );
|
||
|
||
if ( rc == ERROR_SUCCESS ) {
|
||
|
||
if (bDifferent )
|
||
*pbEqual = FALSE;
|
||
|
||
} else
|
||
*pbEqual = FALSE;
|
||
|
||
return(SmbsvcpDosErrorToSceStatus(rc));
|
||
}
|
||
|
||
|
||
DWORD
|
||
SmbsvcEveryoneFullAccess(
|
||
IN PACL pAcl,
|
||
IN BOOL bExplicit,
|
||
OUT PBOOL pbEqual
|
||
)
|
||
{
|
||
if ( pbEqual == NULL ) {
|
||
return(ERROR_INVALID_PARAMETER);
|
||
}
|
||
|
||
*pbEqual = FALSE;
|
||
if ( pAcl == NULL ) {
|
||
return(ERROR_SUCCESS);
|
||
}
|
||
|
||
NTSTATUS NtStatus;
|
||
PSID pSidEveryone=NULL;
|
||
SID_IDENTIFIER_AUTHORITY IdentifierAuthority=SECURITY_WORLD_SID_AUTHORITY;
|
||
//
|
||
// build everyone sid
|
||
//
|
||
pSidEveryone = (PSID) LocalAlloc(LMEM_FIXED, RtlLengthRequiredSid(1));
|
||
|
||
if (NULL == pSidEveryone )
|
||
return(ERROR_NOT_ENOUGH_MEMORY);
|
||
|
||
NtStatus = RtlInitializeSid(pSidEveryone, &IdentifierAuthority, (UCHAR)1);
|
||
|
||
if ( !NT_SUCCESS(NtStatus) ) {
|
||
LocalFree(pSidEveryone);
|
||
return(RtlNtStatusToDosError(NtStatus));
|
||
}
|
||
|
||
*(RtlSubAuthoritySid(pSidEveryone, 0)) = SECURITY_WORLD_RID;
|
||
|
||
|
||
ACE_HEADER *pAce=NULL;
|
||
PSID pSid;
|
||
ACCESS_MASK Access;
|
||
DWORD nAceCount, j;
|
||
|
||
for ( j=0, nAceCount=0; j<pAcl->AceCount; j++ ) {
|
||
|
||
NtStatus = RtlGetAce(pAcl, j, (PVOID *)&pAce);
|
||
|
||
if ( !NT_SUCCESS(NtStatus) )
|
||
break;
|
||
|
||
if ( pAce == NULL )
|
||
continue;
|
||
|
||
if ( bExplicit && (pAce->AceFlags & INHERITED_ACE) ) {
|
||
//
|
||
// find a inherit Ace in Acl
|
||
//
|
||
continue;
|
||
}
|
||
|
||
nAceCount++;
|
||
|
||
if ( nAceCount == 1 && pAce->AceType == ACCESS_ALLOWED_ACE_TYPE ) {
|
||
|
||
pSid = (PSID)&((PACCESS_ALLOWED_ACE)pAce)->SidStart;
|
||
Access = ((PACCESS_ALLOWED_ACE)pAce)->Mask;
|
||
|
||
if ( pSid != NULL ) {
|
||
if ( Access == FILE_ALL_ACCESS || Access == GENERIC_ALL ) {
|
||
|
||
if ( EqualSid(pSid, pSidEveryone) )
|
||
*pbEqual = TRUE;
|
||
}
|
||
}
|
||
}
|
||
if ( !*pbEqual)
|
||
break;
|
||
|
||
if ( nAceCount > 1 ) { // should only allow one ace
|
||
*pbEqual = FALSE;
|
||
break;
|
||
}
|
||
}
|
||
|
||
LocalFree(pSidEveryone);
|
||
|
||
return(RtlNtStatusToDosError(NtStatus));
|
||
}
|
||
|
||
|
||
DWORD
|
||
SmbsvcpCompareAcl(
|
||
IN PACL pAcl1,
|
||
IN PACL pAcl2,
|
||
IN BOOL bExplicitOnly,
|
||
OUT PBOOL pDifferent
|
||
)
|
||
/*
|
||
Routine Description:
|
||
|
||
This routine compares explicit aces of two ACLs for exact match. Exact
|
||
match means: same access type, same inheritance flag, same access mask,
|
||
same GUID/Object GUID (if available), and same SID.
|
||
|
||
Inherited aces (INHERITED_ACE is set) are ignored.
|
||
|
||
Arguments:
|
||
|
||
pAcl1 - The first ACL
|
||
|
||
pAcl2 - The 2nd ACL
|
||
|
||
pDifferent - The output flag to indicate different
|
||
|
||
Return Value:
|
||
|
||
Win32 error codes
|
||
*/
|
||
{
|
||
NTSTATUS NtStatus=STATUS_SUCCESS;
|
||
DWORD i, j;
|
||
ACE_HEADER *pAce1=NULL;
|
||
ACE_HEADER *pAce2=NULL;
|
||
DWORD ProcessAce=0;
|
||
|
||
|
||
*pDifferent = FALSE;
|
||
|
||
//
|
||
// if pAcl1 is NULL, pAcl2 should have 0 explicit Ace
|
||
//
|
||
if ( pAcl1 == NULL ) {
|
||
return( SmbsvcpAnyExplicitAcl( pAcl2, 0, pDifferent ) );
|
||
}
|
||
|
||
//
|
||
// if pAcl2 is NULL, pAcl1 should have 0 explicit Ace
|
||
//
|
||
if ( pAcl2 == NULL ) {
|
||
return( SmbsvcpAnyExplicitAcl( pAcl1, 0, pDifferent ) );
|
||
}
|
||
//
|
||
// both ACLs are not NULL
|
||
// BUGBUG: note there is a limit of AceCount because of DWORD (32 bits)
|
||
//
|
||
for ( i=0; i<pAcl1->AceCount; i++) {
|
||
|
||
NtStatus = RtlGetAce(pAcl1, i, (PVOID *)&pAce1);
|
||
if ( !NT_SUCCESS(NtStatus) )
|
||
goto Done;
|
||
//
|
||
// ignore inherited Aces
|
||
//
|
||
if ( bExplicitOnly && (pAce1->AceFlags & INHERITED_ACE) )
|
||
continue;
|
||
|
||
//
|
||
// try to find a match in pAcl2
|
||
//
|
||
for ( j=0; j<pAcl2->AceCount; j++ ) {
|
||
|
||
if ( ProcessAce & (1 << j) )
|
||
// this one is already processed
|
||
continue;
|
||
|
||
NtStatus = RtlGetAce(pAcl2, j, (PVOID *)&pAce2);
|
||
if ( !NT_SUCCESS(NtStatus) )
|
||
goto Done;
|
||
|
||
//
|
||
// ignore inherited Aces too
|
||
//
|
||
if ( bExplicitOnly && (pAce2->AceFlags & INHERITED_ACE) ) {
|
||
ProcessAce |= (1 << j);
|
||
continue;
|
||
}
|
||
|
||
//
|
||
// compare two Aces (pAce1 and pAce2)
|
||
//
|
||
if ( SmbsvcpEqualAce(pAce1, pAce2) ) {
|
||
//
|
||
// find a match
|
||
//
|
||
ProcessAce |= (1 << j);
|
||
break;
|
||
}
|
||
|
||
}
|
||
|
||
if ( j >= pAcl2->AceCount ) {
|
||
//
|
||
// did not find a match for pAce1
|
||
//
|
||
*pDifferent = TRUE;
|
||
return(ERROR_SUCCESS);
|
||
}
|
||
}
|
||
|
||
if ( i >= pAcl1->AceCount ) {
|
||
//
|
||
// every Ace in pAcl1 finds a match in pAcl2
|
||
// see if every Ace in pAcl2 has a match
|
||
//
|
||
return( SmbsvcpAnyExplicitAcl( pAcl2, ProcessAce, pDifferent ) );
|
||
}
|
||
Done:
|
||
|
||
return(RtlNtStatusToDosError(NtStatus));
|
||
}
|
||
|
||
|
||
DWORD
|
||
SmbsvcpAnyExplicitAcl(
|
||
IN PACL Acl,
|
||
IN DWORD Processed,
|
||
OUT PBOOL pExist
|
||
)
|
||
/*
|
||
Routine Description:
|
||
|
||
This routine detects if there is any explicit ace in the Acl. The DWORD
|
||
Processed is a bit mask of the aces already checked.
|
||
|
||
Arguments:
|
||
|
||
Acl - The Acl
|
||
|
||
Processed - The bit mask for the processed aces (so it won't be checked again)
|
||
|
||
pExist - The output flag to indicate if there is any explicit ace
|
||
|
||
Return Value:
|
||
|
||
win32 error codes
|
||
*/
|
||
{
|
||
NTSTATUS NtStatus=STATUS_SUCCESS;
|
||
DWORD j;
|
||
ACE_HEADER *pAce=NULL;
|
||
|
||
//
|
||
// check output argument
|
||
//
|
||
if ( pExist == NULL )
|
||
return(ERROR_INVALID_PARAMETER);
|
||
|
||
*pExist = FALSE;
|
||
|
||
if ( Acl == NULL )
|
||
return(ERROR_SUCCESS);
|
||
|
||
for ( j=0; j<Acl->AceCount; j++ ) {
|
||
if ( Processed & (1 << j) )
|
||
continue;
|
||
|
||
NtStatus = RtlGetAce(Acl, j, (PVOID *)&pAce);
|
||
|
||
if ( !NT_SUCCESS(NtStatus) )
|
||
return(RtlNtStatusToDosError(NtStatus));
|
||
|
||
if ( pAce == NULL )
|
||
continue;
|
||
|
||
if ( !(pAce->AceFlags & INHERITED_ACE) ) {
|
||
//
|
||
// find a explicit Ace in Acl
|
||
//
|
||
*pExist = TRUE;
|
||
break;
|
||
}
|
||
|
||
}
|
||
|
||
return(RtlNtStatusToDosError(NtStatus));
|
||
|
||
}
|
||
|
||
|
||
BOOL
|
||
SmbsvcpEqualAce(
|
||
IN ACE_HEADER *pAce1,
|
||
IN ACE_HEADER *pAce2
|
||
)
|
||
// compare two aces for exact match. The return BOOL value indicates the
|
||
// match or not
|
||
{
|
||
PSID pSid1=NULL, pSid2=NULL;
|
||
ACCESS_MASK Access1=0, Access2=0;
|
||
|
||
if ( pAce1 == NULL && pAce2 == NULL )
|
||
return(TRUE);
|
||
|
||
if ( pAce1 == NULL || pAce2 == NULL )
|
||
return(FALSE);
|
||
|
||
//
|
||
// compare ace access type
|
||
//
|
||
if ( pAce1->AceType != pAce2->AceType )
|
||
return(FALSE);
|
||
|
||
//
|
||
// compare ace inheritance flag
|
||
//
|
||
if ( pAce1->AceFlags != pAce2->AceFlags )
|
||
return(FALSE);
|
||
|
||
switch ( pAce1->AceType ) {
|
||
case ACCESS_ALLOWED_ACE_TYPE:
|
||
case ACCESS_DENIED_ACE_TYPE:
|
||
case SYSTEM_AUDIT_ACE_TYPE:
|
||
case SYSTEM_ALARM_ACE_TYPE:
|
||
pSid1 = (PSID)&((PACCESS_ALLOWED_ACE)pAce1)->SidStart;
|
||
pSid2 = (PSID)&((PACCESS_ALLOWED_ACE)pAce2)->SidStart;
|
||
Access1 = ((PACCESS_ALLOWED_ACE)pAce1)->Mask;
|
||
Access2 = ((PACCESS_ALLOWED_ACE)pAce2)->Mask;
|
||
break;
|
||
|
||
case ACCESS_ALLOWED_OBJECT_ACE_TYPE:
|
||
case ACCESS_DENIED_OBJECT_ACE_TYPE:
|
||
case SYSTEM_AUDIT_OBJECT_ACE_TYPE:
|
||
case SYSTEM_ALARM_OBJECT_ACE_TYPE:
|
||
pSid1 = (PSID)&((PACCESS_ALLOWED_OBJECT_ACE)pAce1)->SidStart;
|
||
pSid2 = (PSID)&((PACCESS_ALLOWED_OBJECT_ACE)pAce2)->SidStart;
|
||
Access1 = ((PACCESS_ALLOWED_OBJECT_ACE)pAce1)->Mask;
|
||
Access2 = ((PACCESS_ALLOWED_OBJECT_ACE)pAce2)->Mask;
|
||
|
||
//
|
||
// ignore the guids
|
||
//
|
||
break;
|
||
default:
|
||
return(FALSE); // not recognized Ace type
|
||
}
|
||
|
||
if ( pSid1 == NULL || pSid2 == NULL )
|
||
//
|
||
// no Sid, ignore the Ace
|
||
//
|
||
return(FALSE);
|
||
|
||
//
|
||
// compare the sids
|
||
//
|
||
if ( !EqualSid(pSid1, pSid2) )
|
||
return(FALSE);
|
||
|
||
//
|
||
// access mask
|
||
//
|
||
// Translation is already done when calculating security descriptor
|
||
// for file objects and registry objects
|
||
//
|
||
if ( Access1 != Access2 ) {
|
||
RtlMapGenericMask (
|
||
&Access2,
|
||
&ShareGenMap
|
||
);
|
||
if ( Access1 != Access2)
|
||
return(FALSE);
|
||
}
|
||
|
||
return(TRUE);
|
||
}
|
||
|
||
|
||
/*=============================================================================
|
||
** Procedure Name: DllMain
|
||
**
|
||
** Arguments:
|
||
**
|
||
**
|
||
**
|
||
** Returns: 0 = SUCCESS
|
||
** !0 = ERROR
|
||
**
|
||
** Abstract:
|
||
**
|
||
** Notes:
|
||
**
|
||
**===========================================================================*/
|
||
BOOL WINAPI DllMain(
|
||
IN HANDLE DllHandle,
|
||
IN ULONG ulReason,
|
||
IN LPVOID Reserved )
|
||
{
|
||
|
||
switch(ulReason) {
|
||
|
||
case DLL_PROCESS_ATTACH:
|
||
|
||
MyModuleHandle = (HINSTANCE)DllHandle;
|
||
|
||
//
|
||
// Fall through to process first thread
|
||
//
|
||
|
||
case DLL_THREAD_ATTACH:
|
||
|
||
break;
|
||
|
||
case DLL_PROCESS_DETACH:
|
||
|
||
break;
|
||
|
||
case DLL_THREAD_DETACH:
|
||
|
||
break;
|
||
}
|
||
|
||
return TRUE;
|
||
}
|
||
|
||
/////////////////////////////////////////////////////////////////////////////
|
||
// DllRegisterServer - Adds entries to the system registry
|
||
|
||
STDAPI DllRegisterServer(void)
|
||
{
|
||
HKEY hKey;
|
||
LONG lResult;
|
||
DWORD dwDisp;
|
||
|
||
lResult = RegCreateKeyEx (HKEY_LOCAL_MACHINE, SCESMB_ROOT_PATH, 0, NULL,
|
||
REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL,
|
||
&hKey, &dwDisp);
|
||
|
||
if (lResult != ERROR_SUCCESS)
|
||
{
|
||
return lResult;
|
||
}
|
||
|
||
|
||
RegSetValueEx (hKey, TEXT("ServiceAttachmentPath"), 0, REG_SZ, (LPBYTE)TEXT("seFilShr.dll"),
|
||
(lstrlen(TEXT("seFilShr.dll")) + 1) * sizeof(TCHAR));
|
||
|
||
RegCloseKey (hKey);
|
||
|
||
return S_OK;
|
||
}
|
||
|
||
/////////////////////////////////////////////////////////////////////////////
|
||
// DllUnregisterServer - Removes entries from the system registry
|
||
|
||
STDAPI DllUnregisterServer(void)
|
||
{
|
||
|
||
RegDeleteKey (HKEY_LOCAL_MACHINE, SCESMB_ROOT_PATH);
|
||
|
||
return S_OK;
|
||
}
|
||
|