📄 shareinfo.cpp
字号:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft shared
// source or premium shared source license agreement under which you licensed
// this source code. If you did not accept the terms of the license agreement,
// you are not authorized to use this source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the SOURCE.RTF on your install media or the root of your tools installation.
// THE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES.
//
#include <CReg.hxx>
#include <authhlp.h>
#include "SMB_Globals.h"
#include "ShareInfo.h"
#include "CriticalSection.h"
#include "encrypt.h"
#include "PrintQueue.h"
#include "FileServer.h"
#include "ConnectionManager.h"
#ifdef SMB_NMPIPE
#include "ipcstream.h"
#endif
//
// Just used to make sure (in debug) that multiple instances of ShareManager/TIDManager
// dont get created
#ifdef DEBUG
BOOL ShareManager::fFirstInst = TRUE;
#endif
UniqueID TIDState::UIDTidGenerator;
UniqueID TIDState::UniqueFID;
ce::fixed_block_allocator<30> SMB_Globals::g_FileStreamAllocator;
ce::fixed_block_allocator<10> SMB_Globals::g_PrintStreamAllocator;
Share::Share() {
pShareName = NULL;
pShareNameSZ = NULL;
pRemark = NULL;
fHidden = FALSE;
shareType = 0xFF;
pPrintQueue = NULL;
fRequireAuth = TRUE;
}
Share::~Share() {
if(pShareName)
delete [] pShareName;
if(pShareNameSZ)
delete [] pShareNameSZ;
if(pRemark)
delete [] pRemark;
if(pPrintQueue) {
delete pPrintQueue;
}
}
HRESULT
Share::SetPrintQueue(SMBPrintQueue *_pPrintQueue)
{
ASSERT(NULL == pPrintQueue);
pPrintQueue = _pPrintQueue;
return S_OK;
}
SMBPrintQueue *
Share::GetPrintQueue()
{
return pPrintQueue;
}
HRESULT
Share::SetRemark(const CHAR *_pRemark)
{
HRESULT hr=S_OK;;
UINT uiRemarkLen;
if(NULL == _pRemark) {
hr = E_INVALIDARG;
goto Done;
}
if(NULL != pRemark) {
delete [] pRemark;
}
uiRemarkLen = strlen(_pRemark) + 1;
pRemark = new CHAR[uiRemarkLen];
if(NULL == pRemark) {
hr = E_OUTOFMEMORY;
goto Done;
}
memcpy(pRemark, _pRemark, uiRemarkLen);
Done:
return hr;
}
HRESULT
Share::SetShareName(const WCHAR *_pShareName)
{
HRESULT hr = S_OK;
WCHAR *pNewShareName = NULL;
CHAR *pNewShareNameSZ = NULL;
UINT uiSize = 0;
UINT uiMultiSize = 0;
//
// Verify that the sharename is not null or empty string
if(!_pShareName || !_pShareName[0]) {
TRACEMSG(ZONE_ERROR, (L"SMB_SRV: ERROR: Sharename must not be null or empty string."));
ASSERT(FALSE);
return E_INVALIDARG;
}
uiSize = wcslen(_pShareName) + 1;
uiMultiSize = WideCharToMultiByte(CP_ACP, 0, _pShareName, -1, NULL, NULL, NULL, NULL);
//
// Share name must be <= 13 characters total (with null)
if(uiSize > 13) {
TRACEMSG(ZONE_ERROR, (L"SMB_SRV: ERROR: Sharename must be <= 13 characters with null"));
ASSERT(FALSE);
return E_INVALIDARG;
}
pNewShareName = new WCHAR[uiSize];
pNewShareNameSZ = new CHAR[uiMultiSize];
if(NULL == pNewShareName || NULL == pNewShareNameSZ) {
hr = E_OUTOFMEMORY;
goto Done;
}
WideCharToMultiByte(CP_ACP, 0, _pShareName, -1, pNewShareNameSZ, uiMultiSize,NULL,NULL);
wcscpy(pNewShareName, _pShareName);
if(pShareName)
delete [] pShareName;
if(pShareNameSZ)
delete [] pShareNameSZ;
pShareName = pNewShareName;
pShareNameSZ = pNewShareNameSZ;
Done:
if(FAILED(hr)) {
if(pNewShareName)
delete [] pNewShareName;
if(pNewShareNameSZ)
delete [] pNewShareNameSZ;
}
return hr;
}
HRESULT
Share::SetDirectoryName(const WCHAR *_pDirectory)
{
m_DirectoryName.Clear();
return m_DirectoryName.append(_pDirectory);
}
HRESULT
Share::SetServiceName(const WCHAR *_pServiceName)
{
m_ServiceName.Clear();
return m_ServiceName.append(_pServiceName);
}
const WCHAR *
Share::GetServiceName()
{
return m_ServiceName.GetString();
}
const CHAR *
Share::GetShareNameSZ()
{
return pShareNameSZ;
}
const WCHAR *
Share::GetShareName()
{
return pShareName;
}
const WCHAR *
Share::GetDirectoryName()
{
return m_DirectoryName.GetString();
}
const CHAR *
Share::GetRemark()
{
return pRemark;
}
BYTE
Share::GetShareType()
{
return shareType;
}
HRESULT
Share::SetShareType(BYTE _shareType)
{
shareType = _shareType;
return S_OK;
}
HRESULT
Share::AllowUser(const WCHAR *pUserName, DWORD dwAccess)
{
HRESULT hr = E_ACCESSDENIED;
CReg RegAllowAll;
BOOL fAllowAll = FALSE;
//
// See if they have full control first
if(!RequireAuth() || IsAccessAllowed((WCHAR *)pUserName, NULL, (WCHAR *)(m_FullACLList.GetString()), FALSE)) {
hr = S_OK;
goto Done;
}
//
// See if they have read only (only if they are trying to get SEC_READ)
if(SEC_READ == dwAccess && IsAccessAllowed((WCHAR *)pUserName, NULL, (WCHAR *)(m_ReadOnlyACLList.GetString()), FALSE)) {
hr = S_OK;
goto Done;
}
//
// See if security is disabled wholesale
if(TRUE == RegAllowAll.Open(HKEY_LOCAL_MACHINE, L"Services\\SMBServer\\Shares")) {
fAllowAll = !(RegAllowAll.ValueDW(L"UseAuthentication", TRUE));
if(TRUE == fAllowAll) {
hr = S_OK;
goto Done;
}
}
hr = E_ACCESSDENIED;
Done:
return hr;;
}
HRESULT
Share::SetACL(const WCHAR *pFullACL, const WCHAR *pReadACL) {
HRESULT hr;
if(FAILED(hr = m_FullACLList.Clear())) {
goto Done;
}
if(FAILED(hr = m_ReadOnlyACLList.Clear())) {
goto Done;
}
if(FAILED(hr = m_FullACLList.append(pFullACL))) {
goto Done;
}
if(FAILED(hr = m_ReadOnlyACLList.append(pReadACL))) {
goto Done;
}
Done:
if(FAILED(hr)) {
m_FullACLList.Clear();
m_ReadOnlyACLList.Clear();
}
return hr;
}
HRESULT
Share::IsValidPath(const WCHAR *pPath)
{
if(0 != wcsstr(pPath, L"\\..\\")) {
RETAILMSG(1, (L"SMBSRV: Invalid char in path %s\n", pPath));
return E_FAIL;
} else if(0 != wcsstr(pPath, L"\\\\")) {
RETAILMSG(1, (L"SMBSRV: Invalid char in path %s\n", pPath));
return E_FAIL;
}
else {
return S_OK;
}
}
/******************************************************************************
*
* ShareManager -- this utility class manages shares on the system.
* The class is used to collect functions related to which shares are on the
* system
*
******************************************************************************/
ShareManager::ShareManager()
{
#ifdef DEBUG
//
// Just used to make sure (in debug) that multiple instances of ShareManager
// dont get created
if(fFirstInst) {
fFirstInst = FALSE;
}
else {
ASSERT(FALSE);
TRACEMSG(ZONE_ERROR, (L"Only one instance of ShareManager allowed!!!"));
}
#endif
InitializeCriticalSection(&csShareManager);
}
ShareManager::~ShareManager()
{
//
// Just used to make sure (in debug) that multiple instances of ShareManager
// dont get created
#ifdef DEBUG
ASSERT(FALSE == fFirstInst);
fFirstInst = TRUE;
#endif
//clear our the share lists
CCritSection csLock(&csShareManager);
csLock.Lock();
//
// Delete all Shares that are outstanding
while(MasterListOfShares.size()) {
Share *pToDel = MasterListOfShares.front();
ASSERT(pToDel);
MasterListOfShares.pop_front();
delete pToDel;
}
csLock.UnLock();
DeleteCriticalSection(&csShareManager);
}
HRESULT
ShareManager::AddShare(Share *pShare)
{
if(NULL == pShare)
return E_INVALIDARG;
if(SearchForShare(pShare->GetShareName())) {
RETAILMSG(1, (L"SMBSRV: ERROR! adding share %s when it already exists!", pShare->GetShareName()));
return E_FAIL;
}
CCritSection csLock(&csShareManager);
csLock.Lock();
if(!MasterListOfShares.push_front(pShare)) {
return E_OUTOFMEMORY;
} else {
return S_OK;
}
}
HRESULT
ShareManager::DeleteShare(Share *pShare)
{
if(NULL == pShare)
return E_INVALIDARG;
BOOL fFound = FALSE;
CCritSection csLock(&csShareManager);
csLock.Lock();
ce::list<Share *, SHARE_MANANGER_SHARE_ALLOC >::iterator it;
for(it=MasterListOfShares.begin(); it!=MasterListOfShares.end(); it++) {
if(pShare == (*it)) {
MasterListOfShares.erase(it);
delete pShare;
fFound = TRUE;
break;
}
}
return (TRUE == fFound)?S_OK:E_FAIL;
}
HRESULT
ShareManager::ReloadACLS()
{
Share *pRet = NULL;
CCritSection csLock(&csShareManager);
csLock.Lock();
ce::list<Share *, SHARE_MANANGER_SHARE_ALLOC >::iterator it;
ce::list<Share *, SHARE_MANANGER_SHARE_ALLOC >::iterator itEnd = MasterListOfShares.end();
for(it = MasterListOfShares.begin(); it != itEnd; ++it) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -