182 lines
5.2 KiB
C++
182 lines
5.2 KiB
C++
//+------------------------------------------------------------------
|
|
//
|
|
// Copyright (C) 1995, Microsoft Corporation.
|
|
//
|
|
// File: filesec.cxx
|
|
//
|
|
// Classes: CFileSecurity class encapsulating SECURITY_DESCRIPTOR
|
|
//
|
|
// History: Nov-93 DaveMont Created.
|
|
//
|
|
//-------------------------------------------------------------------
|
|
|
|
#include <filesec.hxx>
|
|
//+---------------------------------------------------------------------------
|
|
// Function: Add2Ptr
|
|
//
|
|
// Synopsis: Add an unscaled increment to a ptr regardless of type.
|
|
//
|
|
// Arguments: [pv] -- Initial ptr.
|
|
// [cb] -- Increment
|
|
//
|
|
// Returns: Incremented ptr.
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
VOID * Add2Ptr(VOID *pv, ULONG cb)
|
|
{
|
|
return((BYTE *) pv + cb);
|
|
}
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Member: CFileSecurity::CFileSecurity, public
|
|
//
|
|
// Synopsis: initializes data members
|
|
// constructor will not throw
|
|
//
|
|
// Arguments: [filename] - name of file to apply security descriptor to
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
CFileSecurity::CFileSecurity(WCHAR *filename)
|
|
: _psd(NULL),
|
|
_pwfilename(filename)
|
|
{
|
|
}
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Member: CFileSecurity::Init, public
|
|
//
|
|
// Synopsis: Init must be called before any other methods - this
|
|
// is not enforced. gets security descriptor from file
|
|
//
|
|
// Arguments: none
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
ULONG CFileSecurity::Init()
|
|
{
|
|
ULONG ret;
|
|
ULONG cpsd;
|
|
|
|
// get the size of the security buffer
|
|
|
|
if (!GetFileSecurity(_pwfilename,
|
|
DACL_SECURITY_INFORMATION |
|
|
GROUP_SECURITY_INFORMATION |
|
|
OWNER_SECURITY_INFORMATION,
|
|
NULL,
|
|
0,
|
|
&cpsd) )
|
|
{
|
|
if (ERROR_INSUFFICIENT_BUFFER == (ret = GetLastError()))
|
|
{
|
|
if (NULL == (_psd = (BYTE *)LocalAlloc(LMEM_FIXED, cpsd)))
|
|
{
|
|
return(ERROR_NOT_ENOUGH_MEMORY);
|
|
}
|
|
|
|
// actually get the buffer this time
|
|
|
|
if ( GetFileSecurity(_pwfilename,
|
|
DACL_SECURITY_INFORMATION |
|
|
GROUP_SECURITY_INFORMATION |
|
|
OWNER_SECURITY_INFORMATION,
|
|
_psd,
|
|
cpsd,
|
|
&cpsd) )
|
|
ret = ERROR_SUCCESS;
|
|
else
|
|
ret = GetLastError();
|
|
|
|
}
|
|
} else
|
|
return(ERROR_NO_SECURITY_ON_OBJECT);
|
|
return(ret);
|
|
}
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Member: Dtor, public
|
|
//
|
|
// Synopsis: frees security descriptor if allocated
|
|
//
|
|
// Arguments: none
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
CFileSecurity::~CFileSecurity()
|
|
{
|
|
if (_psd)
|
|
{
|
|
LocalFree(_psd);
|
|
}
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Member: CFileSecurity::SetFS, public
|
|
//
|
|
// Synopsis: sets or modifies the security descriptor DACL on the specified file
|
|
//
|
|
// Arguments: IN - [fmodify] - TRUE = modify ACL, FALSE = replace ACL
|
|
// IN - [pcdw] - wrapper around new ACEs
|
|
// IN - [fdir] - TRUE = directory
|
|
//
|
|
// Returns: status
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
ULONG CFileSecurity::SetFS(BOOL fmodify, CDaclWrap *pcdw, BOOL fdir)
|
|
{
|
|
BOOL fdaclpresent;
|
|
BOOL cod;
|
|
ACL *pdacl;
|
|
ULONG ret;
|
|
|
|
// get the ACL from the security descriptor
|
|
|
|
if ( GetSecurityDescriptorDacl(_psd,
|
|
&fdaclpresent,
|
|
&pdacl,
|
|
&cod) )
|
|
|
|
{
|
|
if (fdaclpresent)
|
|
{
|
|
// build the new ACL (from the new ACEs and the old ACL)
|
|
|
|
PACL pnewdacl = NULL;
|
|
|
|
if (ERROR_SUCCESS == (ret = pcdw->BuildAcl(&pnewdacl,
|
|
fmodify ? pdacl : NULL,
|
|
pdacl ? pdacl->AclRevision : ACL_REVISION,
|
|
fdir)
|
|
))
|
|
{
|
|
// make a new security descriptor
|
|
|
|
SECURITY_DESCRIPTOR newsd;
|
|
|
|
InitializeSecurityDescriptor( &newsd, SECURITY_DESCRIPTOR_REVISION );
|
|
|
|
SetSecurityDescriptorDacl( &newsd, TRUE, pnewdacl, FALSE );
|
|
|
|
//
|
|
// apply it to the file
|
|
//
|
|
|
|
if (!SetFileSecurity(_pwfilename,
|
|
DACL_SECURITY_INFORMATION,
|
|
&newsd))
|
|
{
|
|
ret = GetLastError();
|
|
}
|
|
LocalFree(pnewdacl);
|
|
}
|
|
}
|
|
else
|
|
return(ERROR_NO_SECURITY_ON_OBJECT);
|
|
} else
|
|
{
|
|
ret = GetLastError();
|
|
}
|
|
|
|
return(ret);
|
|
}
|
|
|