1535 lines
40 KiB
C
1535 lines
40 KiB
C
/*++
|
|
|
|
Copyright (c) 1996 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
security.c
|
|
|
|
Abstract:
|
|
|
|
This module provides security for the service.
|
|
|
|
Author:
|
|
|
|
Oded Sacher (OdedS) 13-Feb-2000
|
|
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
#include "faxsvc.h"
|
|
#include <aclapi.h>
|
|
#define ATLASSERT Assert
|
|
#include <smartptr.h>
|
|
#pragma hdrstop
|
|
|
|
//
|
|
// defined in ntrtl.h.
|
|
// do this to avoid dragging in ntrtl.h since we already include some stuff
|
|
// from ntrtl.h
|
|
//
|
|
extern "C"
|
|
NTSYSAPI
|
|
BOOLEAN
|
|
NTAPI
|
|
RtlValidRelativeSecurityDescriptor (
|
|
IN PSECURITY_DESCRIPTOR SecurityDescriptorInput,
|
|
IN ULONG SecurityDescriptorLength,
|
|
IN SECURITY_INFORMATION RequiredInformation
|
|
);
|
|
|
|
//
|
|
// Global Fax Service Security Descriptor
|
|
//
|
|
PSECURITY_DESCRIPTOR g_pFaxSD;
|
|
|
|
CFaxCriticalSection g_CsSecurity;
|
|
|
|
const GENERIC_MAPPING gc_FaxGenericMapping =
|
|
{
|
|
(STANDARD_RIGHTS_READ | FAX_GENERIC_READ),
|
|
(STANDARD_RIGHTS_WRITE | FAX_GENERIC_WRITE),
|
|
(STANDARD_RIGHTS_EXECUTE | FAX_GENERIC_EXECUTE),
|
|
(READ_CONTROL | WRITE_DAC | WRITE_OWNER | FAX_GENERIC_ALL)
|
|
};
|
|
|
|
|
|
DWORD
|
|
FaxSvcAccessCheck(
|
|
IN ACCESS_MASK DesiredAccess,
|
|
OUT BOOL* lpbAccessStatus,
|
|
OUT LPDWORD lpdwGrantedAccess
|
|
)
|
|
/*++
|
|
|
|
Routine name : FaxSvcAccessCheck
|
|
|
|
Routine description:
|
|
|
|
Performs an access check against the fax service security descriptor
|
|
|
|
Author:
|
|
|
|
Oded Sacher (OdedS), Feb, 2000
|
|
|
|
Arguments:
|
|
|
|
DesiredAccess [in ] - Desired access
|
|
lpbAccessStatus [out ] - Address of a BOOL to receive the access check result (TRUE is access allowed)
|
|
lpdwGrantedAccess [out ] - Optional., Address of a DWORD to receive the maximum access allowed. Desired Access should be MAXIMUM_ALLOWED
|
|
|
|
Return Value:
|
|
|
|
Standard Win32 error code
|
|
|
|
--*/
|
|
{
|
|
DWORD rc;
|
|
DWORD GrantedAccess;
|
|
DWORD dwRes;
|
|
BOOL fGenerateOnClose;
|
|
DEBUG_FUNCTION_NAME(TEXT("FaxSvcAccessCheck"));
|
|
|
|
Assert (lpbAccessStatus);
|
|
|
|
//
|
|
// Impersonate the client.
|
|
//
|
|
if ((rc = RpcImpersonateClient(NULL)) != RPC_S_OK)
|
|
{
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("RpcImpersonateClient() failed. (ec: %ld)"),
|
|
rc);
|
|
goto exit;
|
|
}
|
|
|
|
EnterCriticalSection( &g_CsSecurity );
|
|
//
|
|
// purify the access mask - get rid of generic access bits
|
|
//
|
|
MapGenericMask( &DesiredAccess, const_cast<PGENERIC_MAPPING>(&gc_FaxGenericMapping) );
|
|
|
|
//
|
|
// Check if the client has the required access.
|
|
//
|
|
if (!AccessCheckAndAuditAlarm(
|
|
FAX_SERVICE_NAME, // subsystem name
|
|
NULL, // handle to object
|
|
NULL, // type of object
|
|
NULL, // name of object
|
|
g_pFaxSD, // SD
|
|
DesiredAccess, // requested access rights
|
|
const_cast<PGENERIC_MAPPING>(&gc_FaxGenericMapping), // mapping
|
|
FALSE, // creation status
|
|
&GrantedAccess, // granted access rights
|
|
lpbAccessStatus, // result of access check
|
|
&fGenerateOnClose // audit generation option
|
|
))
|
|
{
|
|
rc = GetLastError();
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("AccessCheck() failed. (ec: %ld)"),
|
|
rc);
|
|
LeaveCriticalSection( &g_CsSecurity );
|
|
goto exit;
|
|
}
|
|
|
|
if (lpdwGrantedAccess)
|
|
{
|
|
*lpdwGrantedAccess = GrantedAccess;
|
|
}
|
|
|
|
LeaveCriticalSection( &g_CsSecurity );
|
|
Assert (ERROR_SUCCESS == rc);
|
|
|
|
exit:
|
|
dwRes=RpcRevertToSelf();
|
|
if (RPC_S_OK != dwRes)
|
|
{
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("RpcRevertToSelf() failed (ec: %ld)"),
|
|
dwRes);
|
|
Assert(FALSE);
|
|
}
|
|
return rc;
|
|
}
|
|
|
|
|
|
DWORD
|
|
SaveSecurityDescriptor(
|
|
PSECURITY_DESCRIPTOR pSD
|
|
)
|
|
/*++
|
|
|
|
Routine name : SaveSecurityDescriptor
|
|
|
|
Routine description:
|
|
|
|
Saves the Fax Service SD to the registry
|
|
|
|
Author:
|
|
|
|
Oded Sacher (OdedS), Feb, 2000
|
|
|
|
Arguments:
|
|
|
|
pSD [in ] - Pointer to a SD to be saved
|
|
|
|
Return Value:
|
|
|
|
DWORD
|
|
|
|
--*/
|
|
{
|
|
DWORD rc = ERROR_SUCCESS;
|
|
DWORD dwSize;
|
|
PSECURITY_DESCRIPTOR pSDSelfRelative = NULL;
|
|
HKEY hKey = NULL;
|
|
DWORD Disposition;
|
|
SECURITY_DESCRIPTOR_CONTROL Control = SE_SELF_RELATIVE;
|
|
DWORD dwRevision;
|
|
DEBUG_FUNCTION_NAME(TEXT("SaveSecurityDescriptor"));
|
|
|
|
Assert (pSD);
|
|
|
|
rc = RegCreateKeyEx(
|
|
HKEY_LOCAL_MACHINE,
|
|
REGKEY_FAX_SECURITY,
|
|
0,
|
|
TEXT(""),
|
|
0,
|
|
KEY_WRITE,
|
|
NULL,
|
|
&hKey,
|
|
&Disposition
|
|
);
|
|
if (rc != ERROR_SUCCESS)
|
|
{
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("RegCreateKeyEx() failed (ec: %ld)"),
|
|
rc);
|
|
return rc;
|
|
}
|
|
|
|
if (!IsValidSecurityDescriptor(pSD))
|
|
{
|
|
rc = ERROR_INVALID_SECURITY_DESCR;
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("IsValidSecurityDescriptor() failed."));
|
|
goto exit;
|
|
}
|
|
|
|
//
|
|
// Check if the security descriptor is absolute or self relative.
|
|
//
|
|
if (!GetSecurityDescriptorControl( pSD, &Control, &dwRevision))
|
|
{
|
|
rc = GetLastError();
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("GetSecurityDescriptorControl() failed (ec: %ld)"),
|
|
rc);
|
|
goto exit;
|
|
}
|
|
|
|
|
|
//
|
|
// store the security descriptor in the registry
|
|
//
|
|
dwSize = GetSecurityDescriptorLength( pSD );
|
|
|
|
if (SE_SELF_RELATIVE & Control)
|
|
{
|
|
//
|
|
// store the security descriptor in the registry use absolute SD
|
|
//
|
|
rc = RegSetValueEx(
|
|
hKey,
|
|
REGVAL_DESCRIPTOR,
|
|
0,
|
|
REG_BINARY,
|
|
(LPBYTE) pSD,
|
|
dwSize
|
|
);
|
|
if (ERROR_SUCCESS != rc)
|
|
{
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("RegSetValueEx() failed (ec: %ld)"),
|
|
rc);
|
|
goto exit;
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// Convert the absolute SD to self relative
|
|
//
|
|
pSDSelfRelative = (PSECURITY_DESCRIPTOR) MemAlloc( dwSize );
|
|
if (NULL == pSDSelfRelative)
|
|
{
|
|
rc = ERROR_NOT_ENOUGH_MEMORY;
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("Error Allocating security descriptor"));
|
|
goto exit;
|
|
}
|
|
|
|
//
|
|
// make the security descriptor self relative
|
|
//
|
|
if (!MakeSelfRelativeSD( pSD, pSDSelfRelative, &dwSize))
|
|
{
|
|
rc = GetLastError();
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("MakeSelfRelativeSD() failed (ec: %ld)"),
|
|
rc);
|
|
goto exit;
|
|
}
|
|
|
|
|
|
//
|
|
// store the security descriptor in the registry use self relative SD
|
|
//
|
|
rc = RegSetValueEx(
|
|
hKey,
|
|
REGVAL_DESCRIPTOR,
|
|
0,
|
|
REG_BINARY,
|
|
(LPBYTE) pSDSelfRelative,
|
|
dwSize
|
|
);
|
|
if (ERROR_SUCCESS != rc)
|
|
{
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("RegSetValueEx() failed (ec: %ld)"),
|
|
rc);
|
|
goto exit;
|
|
}
|
|
|
|
}
|
|
|
|
Assert (ERROR_SUCCESS == rc);
|
|
|
|
exit:
|
|
if (NULL != hKey)
|
|
{
|
|
RegCloseKey (hKey);
|
|
}
|
|
|
|
if (NULL != pSDSelfRelative)
|
|
{
|
|
MemFree (pSDSelfRelative);
|
|
}
|
|
return rc;
|
|
}
|
|
|
|
#define FAX_OWNER_SID TEXT("O:NS") // Owner sid : Network Service
|
|
#define FAX_GROUP_SID TEXT("G:NS") // Group sid : Network Service
|
|
|
|
#define FAX_DACL TEXT("D:")
|
|
|
|
#define FAX_BA_ALLOW_ACE TEXT("(A;;0xe07ff;;;BA)") // Allow Built-in administrators (BA) -
|
|
// Access mask : 0xe07ff == FAX_GENERIC_ALL |
|
|
// WRITE_OWNER |
|
|
// WRITE_DAC |
|
|
// READ_CONTROL
|
|
|
|
#define FAX_WD_ALLOW_ACE TEXT("(A;;0x20003;;;WD)") // Allow Everyone (WD) -
|
|
// Access mask : 0x20003 == FAX_ACCESS_SUBMIT |
|
|
// FAX_ACCESS_SUBMIT_NORMAL |
|
|
// READ_CONTROL
|
|
|
|
#define FAX_IU_ALLOW_ACE TEXT("(A;;0x202BF;;;IU)") // Allow Interactive users (IU) -
|
|
// Access mask : 0x202BF == FAX_ACCESS_SUBMIT |
|
|
// FAX_ACCESS_SUBMIT_NORMAL |
|
|
// FAX_ACCESS_SUBMIT_HIGH |
|
|
// FAX_ACCESS_QUERY_JOBS |
|
|
// FAX_ACCESS_MANAGE_JOBS |
|
|
// FAX_ACCESS_QUERY_CONFIG |
|
|
// FAX_ACCESS_QUERY_OUT_ARCHIVE |
|
|
// FAX_ACCESS_QUERY_IN_ARCHIVE |
|
|
// READ_CONTROL
|
|
|
|
#define FAX_DESKTOP_SKU_SD (FAX_OWNER_SID FAX_GROUP_SID FAX_DACL FAX_BA_ALLOW_ACE FAX_WD_ALLOW_ACE FAX_IU_ALLOW_ACE) // SD for per/pro SKU
|
|
|
|
#define FAX_SERVER_SKU_SD (FAX_OWNER_SID FAX_GROUP_SID FAX_DACL FAX_BA_ALLOW_ACE FAX_WD_ALLOW_ACE) // SD for server SKU
|
|
|
|
|
|
DWORD
|
|
CreateDefaultSecurityDescriptor(
|
|
VOID
|
|
)
|
|
/*++
|
|
|
|
Routine name : CreateDefaultSecurityDescriptor
|
|
|
|
Routine description:
|
|
|
|
Creates the default security descriptor
|
|
|
|
Author:
|
|
|
|
Oded Sacher (OdedS), Feb, 2000
|
|
Caliv Nir (t-nicali) Mar, 2002 - changed to use SDDL, while moving Fax service
|
|
to run under "Network service"
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
|
|
Return Value:
|
|
|
|
Standard Win32 error code.
|
|
|
|
--*/
|
|
{
|
|
DWORD dwRet = ERROR_SUCCESS;
|
|
BOOL bRet;
|
|
|
|
PSECURITY_DESCRIPTOR pSecurityDescriptor = NULL;
|
|
PSECURITY_DESCRIPTOR pPrivateObjectSD = NULL;
|
|
ULONG SecurityDescriptorSize = 0;
|
|
HANDLE hFaxServiceToken = NULL;
|
|
|
|
BOOL bDesktopSKU = FALSE;
|
|
|
|
TCHAR* ptstrSD = NULL;
|
|
|
|
DEBUG_FUNCTION_NAME(TEXT("CreateDefaultSecurityDescriptor"));
|
|
|
|
//
|
|
// If this is PERSONAL SKU, then add Interactive Users SID
|
|
//
|
|
bDesktopSKU = IsDesktopSKU();
|
|
ptstrSD = bDesktopSKU ? FAX_DESKTOP_SKU_SD : FAX_SERVER_SKU_SD;
|
|
|
|
bRet = ConvertStringSecurityDescriptorToSecurityDescriptor(
|
|
ptstrSD, // security descriptor string
|
|
SDDL_REVISION_1, // revision level
|
|
&pSecurityDescriptor, // SD
|
|
&SecurityDescriptorSize // SD size
|
|
);
|
|
if(!bRet)
|
|
{
|
|
dwRet = GetLastError();
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("ConvertStringSecurityDescriptorToSecurityDescriptor() failed (ec: %lu)"),
|
|
dwRet);
|
|
goto exit;
|
|
}
|
|
|
|
//
|
|
// Get the Fax Service Token
|
|
//
|
|
if (!OpenProcessToken( GetCurrentProcess(), // handle to process
|
|
TOKEN_QUERY, // desired access to process
|
|
&hFaxServiceToken // handle to open access token
|
|
))
|
|
{
|
|
dwRet = GetLastError();
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("OpenThreadToken failed. (ec: %ld)"),
|
|
dwRet);
|
|
goto exit;
|
|
}
|
|
|
|
//
|
|
// Create a private object SD
|
|
//
|
|
if (!CreatePrivateObjectSecurity( NULL, // parent directory SD
|
|
pSecurityDescriptor, // creator SD
|
|
&pPrivateObjectSD, // new SD
|
|
FALSE, // container
|
|
hFaxServiceToken, // handle to access token
|
|
const_cast<PGENERIC_MAPPING>(&gc_FaxGenericMapping) // mapping
|
|
))
|
|
{
|
|
dwRet = GetLastError();
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("CreatePrivateObjectSecurity() failed (ec: %ld)"),
|
|
dwRet);
|
|
goto exit;
|
|
}
|
|
|
|
//
|
|
// store the security descriptor in the registry
|
|
//
|
|
dwRet = SaveSecurityDescriptor (pPrivateObjectSD);
|
|
if (ERROR_SUCCESS != dwRet)
|
|
{
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("SaveSecurityDescriptor() failed (ec: %ld)"),
|
|
dwRet);
|
|
goto exit;
|
|
}
|
|
|
|
//
|
|
// All done! Set the global fax service security descriptor
|
|
//
|
|
g_pFaxSD = pPrivateObjectSD;
|
|
pPrivateObjectSD = NULL;
|
|
|
|
Assert (ERROR_SUCCESS == dwRet);
|
|
|
|
exit:
|
|
|
|
if(NULL != pSecurityDescriptor)
|
|
{
|
|
LocalFree(pSecurityDescriptor);
|
|
}
|
|
|
|
if (NULL != hFaxServiceToken)
|
|
{
|
|
if (!CloseHandle(hFaxServiceToken))
|
|
{
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("CloseHandle() failed. (ec: %ld)"),
|
|
GetLastError());
|
|
}
|
|
}
|
|
|
|
if (NULL != pPrivateObjectSD)
|
|
{
|
|
//
|
|
// in case of failure in creating the SD destroy the private object SD.
|
|
//
|
|
if (!DestroyPrivateObjectSecurity (&pPrivateObjectSD))
|
|
{
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("DestroyPrivateObjectSecurity() failed. (ec: %ld)"),
|
|
GetLastError());
|
|
}
|
|
}
|
|
|
|
return dwRet;
|
|
} // CreateDefaultSecurityDescriptor
|
|
|
|
|
|
|
|
DWORD
|
|
LoadSecurityDescriptor(
|
|
VOID
|
|
)
|
|
/*++
|
|
|
|
Routine name : LoadSecurityDescriptor
|
|
|
|
Routine description:
|
|
|
|
Loads the Fax Service security descriptor from the registry
|
|
|
|
Author:
|
|
|
|
Oded Sacher (OdedS), Feb, 2000
|
|
|
|
Arguments:
|
|
|
|
None
|
|
|
|
Return Value:
|
|
|
|
Standard Win32 error code
|
|
|
|
--*/
|
|
{
|
|
DWORD rc = ERROR_SUCCESS;
|
|
DWORD dwSize;
|
|
HKEY hKey = NULL;
|
|
DWORD Disposition;
|
|
DWORD dwType;
|
|
PSECURITY_DESCRIPTOR pRelativeSD = NULL;
|
|
DEBUG_FUNCTION_NAME(TEXT("LoadSecurityDescriptor"));
|
|
|
|
rc = RegCreateKeyEx(
|
|
HKEY_LOCAL_MACHINE,
|
|
REGKEY_FAX_SECURITY,
|
|
0,
|
|
TEXT(""),
|
|
0,
|
|
KEY_READ,
|
|
NULL,
|
|
&hKey,
|
|
&Disposition
|
|
);
|
|
if (rc != ERROR_SUCCESS)
|
|
{
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("RegCreateKeyEx() failed (ec: %ld)"),
|
|
rc);
|
|
goto exit;
|
|
}
|
|
|
|
rc = RegQueryValueEx(
|
|
hKey,
|
|
REGVAL_DESCRIPTOR,
|
|
NULL,
|
|
&dwType,
|
|
NULL,
|
|
&dwSize
|
|
);
|
|
|
|
if (ERROR_SUCCESS != rc)
|
|
{
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("RegQueryValueEx failed with %ld"),
|
|
rc);
|
|
goto exit;
|
|
}
|
|
|
|
//
|
|
// We opened an existing registry value
|
|
//
|
|
if (REG_BINARY != dwType ||
|
|
0 == dwSize)
|
|
{
|
|
//
|
|
// We expect only binary data here
|
|
//
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("Error reading security descriptor from the registry, not a binary type, or size is 0"));
|
|
rc = ERROR_BADDB; // The configuration registry database is corrupt.
|
|
goto exit;
|
|
}
|
|
|
|
//
|
|
// Allocate required buffer
|
|
// The buffer must be allocated using HeapAlloc (GetProcessHeap()...) because this is the way CreatePrivateObjectSecurity() allocates memory
|
|
// This is a result of a bad design of private object security APIs, see Windows Bugs #324906.
|
|
//
|
|
pRelativeSD = (PSECURITY_DESCRIPTOR) HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwSize );
|
|
if (!pRelativeSD)
|
|
{
|
|
rc = ERROR_NOT_ENOUGH_MEMORY;
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("Failed to allocate security descriptor buffer"));
|
|
goto exit;
|
|
}
|
|
|
|
//
|
|
// Read the data
|
|
//
|
|
rc = RegQueryValueEx(
|
|
hKey,
|
|
REGVAL_DESCRIPTOR,
|
|
NULL,
|
|
&dwType,
|
|
(LPBYTE)pRelativeSD,
|
|
&dwSize
|
|
);
|
|
if (ERROR_SUCCESS != rc)
|
|
{
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("RegQueryValueEx failed with %ld"),
|
|
rc);
|
|
goto exit;
|
|
}
|
|
|
|
if (!IsValidSecurityDescriptor(pRelativeSD))
|
|
{
|
|
rc = ERROR_INVALID_SECURITY_DESCR;
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("IsValidSecurityDescriptor() failed."));
|
|
goto exit;
|
|
}
|
|
|
|
g_pFaxSD = pRelativeSD;
|
|
pRelativeSD = NULL;
|
|
Assert (ERROR_SUCCESS == rc);
|
|
|
|
exit:
|
|
if (hKey)
|
|
{
|
|
RegCloseKey( hKey );
|
|
}
|
|
|
|
if (NULL != pRelativeSD)
|
|
{
|
|
if (!HeapFree(GetProcessHeap(), 0, pRelativeSD))
|
|
{
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("pRelativeSD() failed. (ec: %ld)"),
|
|
GetLastError());
|
|
}
|
|
}
|
|
return rc;
|
|
}
|
|
|
|
|
|
DWORD
|
|
InitializeServerSecurity(
|
|
VOID
|
|
)
|
|
/*++
|
|
|
|
Routine name : InitializeServerSecurity
|
|
|
|
Routine description:
|
|
|
|
Initializes the Fax Service security
|
|
|
|
Author:
|
|
|
|
Oded Sacher (OdedS), Feb, 2000
|
|
|
|
Arguments:
|
|
|
|
None
|
|
|
|
Return Value:
|
|
|
|
Standard Win32 error code
|
|
|
|
--*/
|
|
{
|
|
DWORD rc = ERROR_SUCCESS;
|
|
DEBUG_FUNCTION_NAME(TEXT("InitializeServerSecurity"));
|
|
|
|
rc = LoadSecurityDescriptor();
|
|
if (ERROR_SUCCESS != rc)
|
|
{
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("LoadSecurityDescriptor() failed (ec: %ld), Create default security descriptor"),
|
|
rc);
|
|
}
|
|
else
|
|
{
|
|
//success
|
|
return rc;
|
|
}
|
|
|
|
//
|
|
// We failed to load the security descriptor
|
|
//
|
|
if (ERROR_NOT_ENOUGH_MEMORY == rc)
|
|
{
|
|
//
|
|
// Do not let the service start
|
|
//
|
|
return rc;
|
|
}
|
|
|
|
//
|
|
// The registry is corrupted - create the default security descriptor
|
|
//
|
|
rc = CreateDefaultSecurityDescriptor();
|
|
if (ERROR_SUCCESS != rc)
|
|
{
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("CreateDefaultSecurityDescriptor() failed (ec: %ld)"),
|
|
rc);
|
|
}
|
|
return rc;
|
|
}
|
|
|
|
//*********************************************************************************
|
|
//* Name:GetClientUserName()
|
|
//* Author: Ronen Barenboim
|
|
//* Date: May 02, 1999
|
|
//*********************************************************************************
|
|
//* DESCRIPTION:
|
|
//* Returns the OS User Name of the connected RPC client.
|
|
//* PARAMETERS:
|
|
//* None.
|
|
//* RETURN VALUE:
|
|
//* A pointer to a newly allocated string holding the user name.
|
|
//* The caller must free this string using MemFree().
|
|
//* Returns NULL if an error occures.
|
|
//* To get extended error information, call GetLastError.
|
|
//*********************************************************************************
|
|
LPWSTR
|
|
GetClientUserName(
|
|
VOID
|
|
)
|
|
{
|
|
RPC_STATUS dwRes;
|
|
LPWSTR lpwstrUserName = NULL;
|
|
HANDLE hToken = NULL;
|
|
PSID pUserSid;
|
|
WCHAR szShortUserName[64];
|
|
WCHAR szShortDomainName[64];
|
|
DWORD dwUserNameLen = sizeof(szShortUserName) / sizeof(WCHAR);
|
|
DWORD dwDomainNameLen = sizeof(szShortDomainName) / sizeof(WCHAR);
|
|
|
|
LPWSTR szUserName = szShortUserName; // first point to short on stack buffers
|
|
LPWSTR szDomainName = szShortDomainName;
|
|
|
|
SID_NAME_USE SidNameUse;
|
|
LPWSTR szLongUserName = NULL;
|
|
LPWSTR szLongDomainName = NULL;
|
|
|
|
DEBUG_FUNCTION_NAME(TEXT("GetClientUserName"));
|
|
|
|
//
|
|
// Impersonate the user.
|
|
//
|
|
dwRes=RpcImpersonateClient(NULL);
|
|
|
|
if (dwRes != RPC_S_OK)
|
|
{
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("RpcImpersonateClient(NULL) failed. (ec: %ld)"),
|
|
dwRes);
|
|
SetLastError (dwRes);
|
|
return NULL;
|
|
}
|
|
|
|
//
|
|
// Open the thread token. We're in an RPC thread, not the main thread.
|
|
//
|
|
if (!OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, FALSE, &hToken))
|
|
{
|
|
dwRes = GetLastError();
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("OpenThreadToken failed. (ec: %ld)"),
|
|
dwRes);
|
|
goto exit;
|
|
}
|
|
|
|
//
|
|
// Get the user's SID. A 128 byte long buffer should always suffice since
|
|
// a SID length is limited to +/- 80 bytes at most.
|
|
//
|
|
BYTE abTokenUser[128];
|
|
DWORD dwReqSize;
|
|
|
|
if (!GetTokenInformation(hToken,
|
|
TokenUser,
|
|
(LPVOID)abTokenUser,
|
|
sizeof(abTokenUser),
|
|
&dwReqSize))
|
|
{
|
|
dwRes = GetLastError();
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("GetTokenInformation failed. (ec: %ld)"),
|
|
dwRes);
|
|
goto exit;
|
|
}
|
|
|
|
//
|
|
// Get the user name and domain.
|
|
//
|
|
pUserSid = ((TOKEN_USER *)abTokenUser)->User.Sid;
|
|
|
|
//
|
|
// Try to get account Sid - with small on stack buffers
|
|
//
|
|
if (!LookupAccountSid(NULL,
|
|
pUserSid,
|
|
szShortUserName,
|
|
&dwUserNameLen,
|
|
szShortDomainName,
|
|
&dwDomainNameLen,
|
|
&SidNameUse))
|
|
{
|
|
dwRes = GetLastError();
|
|
|
|
if (dwRes == ERROR_INSUFFICIENT_BUFFER)
|
|
{
|
|
//
|
|
// At least one of buffer were too small.
|
|
//
|
|
if (dwUserNameLen > sizeof(szShortUserName) / sizeof(WCHAR))
|
|
{
|
|
//
|
|
// Allocate a buffer for the user name.
|
|
//
|
|
szLongUserName = new (std::nothrow) WCHAR[dwUserNameLen];
|
|
if (!szLongUserName)
|
|
{
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("Failed to allocate user name buffer (%d bytes)"),
|
|
dwUserNameLen);
|
|
dwRes = ERROR_NOT_ENOUGH_MEMORY;
|
|
goto exit;
|
|
}
|
|
|
|
//
|
|
// Update szUserName to point to longer buffers
|
|
//
|
|
szUserName = szLongUserName;
|
|
}
|
|
|
|
if (dwDomainNameLen > sizeof(szShortDomainName) / sizeof(WCHAR))
|
|
{
|
|
//
|
|
// Allocate a buffer for the domain name.
|
|
//
|
|
szLongDomainName = new (std::nothrow) WCHAR[dwDomainNameLen];
|
|
if (!szLongDomainName)
|
|
{
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("Failed to allocate domain name buffer (%d bytes)"),
|
|
dwDomainNameLen);
|
|
dwRes = ERROR_NOT_ENOUGH_MEMORY;
|
|
goto exit;
|
|
}
|
|
|
|
//
|
|
// Update szDomainName to point to longer buffers
|
|
//
|
|
szDomainName = szLongDomainName;
|
|
|
|
}
|
|
}
|
|
else
|
|
{
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("LookupAccountSid(1) failed. (ec: %ld)"),
|
|
dwRes);
|
|
goto exit;
|
|
}
|
|
|
|
//
|
|
// Try now with larger buffers.
|
|
//
|
|
if (!LookupAccountSid(NULL,
|
|
pUserSid,
|
|
szUserName,
|
|
&dwUserNameLen,
|
|
szDomainName,
|
|
&dwDomainNameLen,
|
|
&SidNameUse))
|
|
{
|
|
dwRes = GetLastError();
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("LookupAccountSid(2) failed. (ec: %ld)"),
|
|
dwRes);
|
|
goto exit;
|
|
}
|
|
|
|
}
|
|
|
|
//
|
|
// Allocate a buffer for the combined string - domain\user
|
|
//
|
|
dwUserNameLen = wcslen(szUserName);
|
|
dwDomainNameLen = wcslen(szDomainName);
|
|
|
|
lpwstrUserName = (LPWSTR)MemAlloc(sizeof(WCHAR) * (dwUserNameLen + dwDomainNameLen + 2));
|
|
if (!lpwstrUserName)
|
|
{
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("Failed to allocate user and domain name buffer (%d bytes)"),
|
|
sizeof(WCHAR) * (dwUserNameLen + dwDomainNameLen + 2));
|
|
dwRes = ERROR_NOT_ENOUGH_MEMORY;
|
|
goto exit;
|
|
}
|
|
|
|
//
|
|
// Construct the combined string
|
|
//
|
|
memcpy(lpwstrUserName,
|
|
szDomainName,
|
|
sizeof(WCHAR) * dwDomainNameLen);
|
|
lpwstrUserName[dwDomainNameLen] = L'\\';
|
|
memcpy(lpwstrUserName + dwDomainNameLen + 1,
|
|
szUserName,
|
|
sizeof(WCHAR) * (dwUserNameLen + 1));
|
|
|
|
exit:
|
|
DWORD dwErr = RpcRevertToSelf();
|
|
if (RPC_S_OK != dwErr)
|
|
{
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("RpcRevertToSelf() failed. (ec: %ld)"),
|
|
dwRes);
|
|
Assert(dwErr == RPC_S_OK); // Assert(FALSE)
|
|
}
|
|
|
|
if (NULL != szLongUserName)
|
|
{
|
|
delete[] szLongUserName;
|
|
}
|
|
|
|
if (NULL != szLongDomainName)
|
|
{
|
|
delete[] szLongDomainName;
|
|
}
|
|
|
|
if (hToken)
|
|
{
|
|
CloseHandle(hToken);
|
|
}
|
|
|
|
if (dwRes != ERROR_SUCCESS)
|
|
{
|
|
Assert (NULL == lpwstrUserName);
|
|
SetLastError (dwRes);
|
|
}
|
|
return lpwstrUserName;
|
|
}
|
|
|
|
|
|
error_status_t
|
|
FAX_SetSecurity (
|
|
IN handle_t hFaxHandle,
|
|
IN SECURITY_INFORMATION SecurityInformation,
|
|
IN const LPBYTE lpBuffer,
|
|
IN DWORD dwBufferSize
|
|
)
|
|
/*++
|
|
|
|
Routine name : FAX_SetSecurity
|
|
|
|
Routine description:
|
|
|
|
RPC implementation of FaxSetSecurity
|
|
|
|
Author:
|
|
|
|
Eran Yariv (EranY), Nov, 1999
|
|
|
|
Arguments:
|
|
|
|
hFaxHandle [in] - Unused
|
|
SecurityInformation [in] - Defines the valid entries in the security descriptor (Bit wise OR )
|
|
lpBuffer [in] - Pointer to new security descriptor
|
|
dwBufferSize [in] - Buffer size
|
|
|
|
Return Value:
|
|
|
|
Standard RPC error codes
|
|
|
|
--*/
|
|
{
|
|
DWORD rVal = ERROR_SUCCESS;
|
|
DWORD rVal2;
|
|
BOOL fAccess;
|
|
ACCESS_MASK AccessMask = 0;
|
|
HANDLE hClientToken = NULL;
|
|
DEBUG_FUNCTION_NAME(TEXT("FAX_SetSecurity"));
|
|
|
|
Assert (g_pFaxSD);
|
|
Assert (IsValidSecurityDescriptor(g_pFaxSD));
|
|
|
|
if (!lpBuffer || !dwBufferSize)
|
|
{
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("'Error Null buffer"));
|
|
return ERROR_INVALID_PARAMETER;
|
|
}
|
|
|
|
//
|
|
// Must validate the RPC blob before calling IsValidSecurityDescriptor();
|
|
//
|
|
if (!RtlValidRelativeSecurityDescriptor( (PSECURITY_DESCRIPTOR)lpBuffer,
|
|
dwBufferSize,
|
|
SecurityInformation))
|
|
{
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("RtlValidRelativeSecurityDescriptor failed"));
|
|
return ERROR_INVALID_DATA;
|
|
}
|
|
|
|
//
|
|
// Access check
|
|
//
|
|
if (SecurityInformation & OWNER_SECURITY_INFORMATION)
|
|
{
|
|
AccessMask |= WRITE_OWNER;
|
|
}
|
|
|
|
if (SecurityInformation & (GROUP_SECURITY_INFORMATION |
|
|
DACL_SECURITY_INFORMATION) )
|
|
{
|
|
AccessMask |= WRITE_DAC;
|
|
}
|
|
|
|
if (SecurityInformation & SACL_SECURITY_INFORMATION)
|
|
{
|
|
AccessMask |= ACCESS_SYSTEM_SECURITY;
|
|
}
|
|
|
|
//
|
|
// Block other threads from changing the SD
|
|
//
|
|
EnterCriticalSection (&g_CsSecurity);
|
|
|
|
rVal = FaxSvcAccessCheck (AccessMask, &fAccess, NULL);
|
|
if (ERROR_SUCCESS != rVal)
|
|
{
|
|
DebugPrintEx(DEBUG_ERR,
|
|
TEXT("FaxSvcAccessCheck Failed, Error : %ld"),
|
|
rVal);
|
|
goto exit;
|
|
}
|
|
|
|
if (FALSE == fAccess)
|
|
{
|
|
DebugPrintEx(DEBUG_ERR,
|
|
TEXT("The user does not have the needed rights to change the security descriptor"));
|
|
rVal = ERROR_ACCESS_DENIED;
|
|
goto exit;
|
|
}
|
|
|
|
//
|
|
// Get the calling client access token
|
|
//
|
|
// Impersonate the user.
|
|
//
|
|
rVal = RpcImpersonateClient(NULL);
|
|
if (rVal != RPC_S_OK)
|
|
{
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("RpcImpersonateClient(NULL) failed. (ec: %ld)"),
|
|
rVal);
|
|
goto exit;
|
|
}
|
|
|
|
//
|
|
// Open the thread token. We're in an RPC thread, not the main thread.
|
|
//
|
|
if (!OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, FALSE, &hClientToken))
|
|
{
|
|
rVal = GetLastError();
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("OpenThreadToken failed. (ec: %ld)"),
|
|
rVal);
|
|
|
|
DWORD dwErr = RpcRevertToSelf();
|
|
if (RPC_S_OK != dwErr)
|
|
{
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("RpcRevertToSelf() failed. (ec: %ld)"),
|
|
dwErr);
|
|
}
|
|
goto exit;
|
|
}
|
|
|
|
//
|
|
// The calling process (SetPrivateObjectSecurity()) must not impersonate the client
|
|
//
|
|
rVal = RpcRevertToSelf();
|
|
if (RPC_S_OK != rVal)
|
|
{
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("RpcRevertToSelf() failed. (ec: %ld)"),
|
|
rVal);
|
|
goto exit;
|
|
}
|
|
|
|
//
|
|
// Get a new (Mereged) Fax service private object SD
|
|
//
|
|
if (!SetPrivateObjectSecurity ( SecurityInformation,
|
|
(PSECURITY_DESCRIPTOR)lpBuffer,
|
|
&g_pFaxSD,
|
|
const_cast<PGENERIC_MAPPING>(&gc_FaxGenericMapping),
|
|
hClientToken))
|
|
{
|
|
rVal = GetLastError();
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("SetPrivateObjectSecurity failed. (ec: %ld)"),
|
|
rVal);
|
|
goto exit;
|
|
}
|
|
Assert (IsValidSecurityDescriptor(g_pFaxSD));
|
|
|
|
//
|
|
// Save the new SD
|
|
//
|
|
rVal = SaveSecurityDescriptor(g_pFaxSD);
|
|
if (rVal != ERROR_SUCCESS)
|
|
{
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("Error in SaveSecurityDescriptor (%ld)"),
|
|
rVal);
|
|
rVal = ERROR_REGISTRY_CORRUPT;
|
|
goto exit;
|
|
}
|
|
|
|
rVal2 = CreateConfigEvent (FAX_CONFIG_TYPE_SECURITY);
|
|
if (ERROR_SUCCESS != rVal2)
|
|
{
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("CreateConfigEvent(FAX_CONFIG_TYPE_SECURITY) (ec: %lc)"),
|
|
rVal2);
|
|
}
|
|
|
|
Assert (ERROR_SUCCESS == rVal);
|
|
|
|
exit:
|
|
LeaveCriticalSection (&g_CsSecurity);
|
|
if (NULL != hClientToken)
|
|
{
|
|
if (!CloseHandle(hClientToken))
|
|
{
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("CloseHandle() failed. (ec: %ld)"),
|
|
GetLastError());
|
|
}
|
|
}
|
|
return GetServerErrorCode(rVal);
|
|
UNREFERENCED_PARAMETER (hFaxHandle);
|
|
} // FAX_SetSecurity
|
|
|
|
|
|
error_status_t
|
|
FAX_GetSecurityEx(
|
|
IN handle_t hFaxHandle,
|
|
IN SECURITY_INFORMATION SecurityInformation,
|
|
OUT LPBYTE *lpBuffer,
|
|
OUT LPDWORD lpdwBufferSize
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Retrieves the FAX security descriptor from the FAX server.
|
|
|
|
Arguments:
|
|
|
|
hFaxHandle - FAX handle obtained from FaxConnectFaxServer.
|
|
SecurityInformation - Defines the desired entries in the security descriptor (Bit wise OR )
|
|
lpBuffer - Pointer to a SECURITY_DESCRIPTOR structure.
|
|
lpdwBufferSize - Size of lpBuffer
|
|
|
|
Return Value:
|
|
|
|
TRUE - Success
|
|
FALSE - Failure, call GetLastError() for more error information.
|
|
|
|
--*/
|
|
{
|
|
error_status_t rVal = ERROR_SUCCESS;
|
|
DWORD dwDescLength = 0;
|
|
DEBUG_FUNCTION_NAME(TEXT("FAX_GetSecurityEx"));
|
|
BOOL fAccess;
|
|
ACCESS_MASK AccessMask = 0;
|
|
PSECURITY_DESCRIPTOR pSDPrivateObject = NULL;
|
|
|
|
Assert (g_pFaxSD);
|
|
Assert (IsValidSecurityDescriptor(g_pFaxSD));
|
|
|
|
Assert (lpdwBufferSize); // ref pointer in idl
|
|
if (!lpBuffer) // unique pointer in idl
|
|
{
|
|
return ERROR_INVALID_PARAMETER;
|
|
}
|
|
|
|
*lpBuffer = NULL;
|
|
*lpdwBufferSize = 0;
|
|
|
|
//
|
|
// Block other threads from changing the SD
|
|
//
|
|
EnterCriticalSection (&g_CsSecurity);
|
|
|
|
//
|
|
// Access check
|
|
//
|
|
if (SecurityInformation & (GROUP_SECURITY_INFORMATION |
|
|
DACL_SECURITY_INFORMATION |
|
|
OWNER_SECURITY_INFORMATION) )
|
|
{
|
|
AccessMask |= READ_CONTROL;
|
|
}
|
|
|
|
if (SecurityInformation & SACL_SECURITY_INFORMATION)
|
|
{
|
|
AccessMask |= ACCESS_SYSTEM_SECURITY;
|
|
}
|
|
|
|
rVal = FaxSvcAccessCheck (AccessMask, &fAccess, NULL);
|
|
if (ERROR_SUCCESS != rVal)
|
|
{
|
|
DebugPrintEx(DEBUG_ERR,
|
|
TEXT("FaxSvcAccessCheck Failed, Error : %ld"),
|
|
rVal);
|
|
goto exit;
|
|
}
|
|
|
|
if (FALSE == fAccess)
|
|
{
|
|
DebugPrintEx(DEBUG_ERR,
|
|
TEXT("The user does not have the READ_CONTROL or ACCESS_SYSTEM_SECURITY"));
|
|
rVal = ERROR_ACCESS_DENIED;;
|
|
goto exit;
|
|
}
|
|
|
|
if (!IsValidSecurityDescriptor( g_pFaxSD ))
|
|
{
|
|
rVal = ERROR_INVALID_SECURITY_DESCR;
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("IsValidSecurityDescriptor() failed. Got invalid SD"));
|
|
ASSERT_FALSE;
|
|
goto exit;
|
|
}
|
|
|
|
//
|
|
// Get the required buffer size
|
|
//
|
|
GetPrivateObjectSecurity( g_pFaxSD, // SD
|
|
SecurityInformation, // requested info type
|
|
NULL, // requested SD info
|
|
0, // size of SD buffer
|
|
&dwDescLength // required buffer size
|
|
);
|
|
|
|
//
|
|
// Allocate returned security descriptor buffer
|
|
//
|
|
Assert(dwDescLength);
|
|
*lpBuffer = (LPBYTE)MemAlloc(dwDescLength);
|
|
if (NULL == *lpBuffer)
|
|
{
|
|
rVal = ERROR_NOT_ENOUGH_MEMORY;
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("Failed to allocate SD"));
|
|
goto exit;
|
|
}
|
|
|
|
if (!GetPrivateObjectSecurity( g_pFaxSD, // SD
|
|
SecurityInformation, // requested info type
|
|
(PSECURITY_DESCRIPTOR)*lpBuffer, // requested SD info
|
|
dwDescLength, // size of SD buffer
|
|
&dwDescLength // required buffer size
|
|
))
|
|
{
|
|
rVal = GetLastError();
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("GetPrivateObjectSecurity() failed. (ec: %ld)"),
|
|
rVal);
|
|
goto exit;
|
|
}
|
|
|
|
*lpdwBufferSize = dwDescLength;
|
|
Assert (ERROR_SUCCESS == rVal);
|
|
|
|
exit:
|
|
LeaveCriticalSection (&g_CsSecurity);
|
|
if (ERROR_SUCCESS != rVal)
|
|
{
|
|
MemFree (*lpBuffer);
|
|
*lpBuffer = NULL;
|
|
*lpdwBufferSize = 0;
|
|
}
|
|
return GetServerErrorCode(rVal);
|
|
UNREFERENCED_PARAMETER (hFaxHandle);
|
|
} // FAX_GetSecurityEx
|
|
|
|
error_status_t
|
|
FAX_GetSecurity(
|
|
IN handle_t hFaxHandle,
|
|
OUT LPBYTE *lpBuffer,
|
|
OUT LPDWORD lpdwBufferSize
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Retrieves the FAX security descriptor from the FAX server.
|
|
|
|
Arguments:
|
|
|
|
hFaxHandle - FAX handle obtained from FaxConnectFaxServer.
|
|
lpBuffer - Pointer to a SECURITY_DESCRIPTOR structure.
|
|
lpdwBufferSize - Size of lpBuffer
|
|
|
|
Return Value:
|
|
|
|
TRUE - Success
|
|
FALSE - Failure, call GetLastError() for more error information.
|
|
|
|
--*/
|
|
{
|
|
error_status_t rVal = ERROR_SUCCESS;
|
|
DEBUG_FUNCTION_NAME(TEXT("FAX_GetSecurity"));
|
|
|
|
rVal = FAX_GetSecurityEx (hFaxHandle,
|
|
DACL_SECURITY_INFORMATION | // Read DACL
|
|
GROUP_SECURITY_INFORMATION | // Read group
|
|
OWNER_SECURITY_INFORMATION | // Read owner
|
|
SACL_SECURITY_INFORMATION, // Read SACL
|
|
lpBuffer,
|
|
lpdwBufferSize);
|
|
if (ERROR_ACCESS_DENIED == rVal)
|
|
{
|
|
//
|
|
// Let's try without the SACL
|
|
//
|
|
rVal = FAX_GetSecurityEx (hFaxHandle,
|
|
DACL_SECURITY_INFORMATION | // Read DACL
|
|
GROUP_SECURITY_INFORMATION | // Read group
|
|
OWNER_SECURITY_INFORMATION, // Read owner
|
|
lpBuffer,
|
|
lpdwBufferSize);
|
|
}
|
|
return rVal;
|
|
} // FAX_GetSecurity
|
|
|
|
|
|
|
|
error_status_t
|
|
FAX_AccessCheck(
|
|
IN handle_t hBinding,
|
|
IN DWORD dwAccessMask,
|
|
OUT BOOL* pfAccess,
|
|
OUT LPDWORD lpdwRights
|
|
)
|
|
/*++
|
|
|
|
Routine name : FAX_AccessCheck
|
|
|
|
Routine description:
|
|
|
|
Performs an access check against the fax service security descriptor
|
|
|
|
Author:
|
|
|
|
Oded Sacher (OdedS), Feb, 2000
|
|
|
|
Arguments:
|
|
|
|
hBinding [in ] - Handle to the Fax Server obtained from FaxConnectFaxServer()
|
|
dwAccessMask [in ] - Desired access
|
|
pfAccess [out] - Address of a BOOL to receive the access check return value (TRUE - access allowed).
|
|
lpdwRights [out] - Optional, Address of a DWORD to receive the access rights bit wise OR.
|
|
To get the access rights, set dwAccessMask to MAXIMUM_ALLOWED
|
|
|
|
Return Value:
|
|
|
|
Standard Win32 error code.
|
|
|
|
--*/
|
|
{
|
|
error_status_t Rval = ERROR_SUCCESS;
|
|
DEBUG_FUNCTION_NAME(TEXT("FAX_AccessCheck"));
|
|
|
|
if (!pfAccess)
|
|
{
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("fAccess is NULL "));
|
|
return ERROR_INVALID_PARAMETER;
|
|
}
|
|
|
|
Rval = FaxSvcAccessCheck (dwAccessMask, pfAccess, lpdwRights);
|
|
if (ERROR_SUCCESS != Rval)
|
|
{
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("FaxSvcAccessCheck failed with error (%ld)"),
|
|
Rval);
|
|
}
|
|
return GetServerErrorCode(Rval);
|
|
} // FAX_AccessCheck
|
|
|
|
|
|
//*********************************************************************************
|
|
//* Name:GetClientUserSID()
|
|
//* Author: Oded Sacher
|
|
//* Date: Oct 26, 1999
|
|
//*********************************************************************************
|
|
//* DESCRIPTION:
|
|
//* Returns the SID of the connected RPC client.
|
|
//* PARAMETERS:
|
|
//* None.
|
|
//* RETURN VALUE:
|
|
//* A pointer to a newly allocated SID buffer.
|
|
//* The caller must free this buffer using MemFree().
|
|
//* Returns NULL if an error occures.
|
|
//* To get extended error information, call GetLastError.
|
|
//*********************************************************************************
|
|
PSID
|
|
GetClientUserSID(
|
|
VOID
|
|
)
|
|
{
|
|
RPC_STATUS dwRes;
|
|
PSID pUserSid;
|
|
DEBUG_FUNCTION_NAME(TEXT("GetClientUserSID"));
|
|
//
|
|
// Impersonate the user.
|
|
//
|
|
dwRes=RpcImpersonateClient(NULL);
|
|
|
|
if (dwRes != RPC_S_OK)
|
|
{
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("RpcImpersonateClient(NULL) failed. (ec: %ld)"),
|
|
dwRes);
|
|
SetLastError( dwRes);
|
|
return NULL;
|
|
}
|
|
//
|
|
// Get SID of (impersonated) thread
|
|
//
|
|
pUserSid = GetCurrentThreadSID ();
|
|
if (!pUserSid)
|
|
{
|
|
dwRes = GetLastError ();
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("GetCurrentThreadSID failed. (ec: %ld)"),
|
|
dwRes);
|
|
}
|
|
dwRes = RpcRevertToSelf();
|
|
if (RPC_S_OK != dwRes)
|
|
{
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("RpcRevertToSelf() failed. (ec: %ld)"),
|
|
dwRes);
|
|
ASSERT_FALSE;
|
|
//
|
|
// Free SID (if exists)
|
|
MemFree (pUserSid);
|
|
SetLastError (dwRes);
|
|
return NULL;
|
|
}
|
|
return pUserSid;
|
|
}
|
|
|
|
|