You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
254 lines
7.9 KiB
254 lines
7.9 KiB
//-----------------------------------------------------------------------------
|
|
// fileperms.h
|
|
//-----------------------------------------------------------------------------
|
|
|
|
#include <aclapi.h>
|
|
|
|
////////////////////////////////////////////////////////////////
|
|
//
|
|
// AddPermissionToPath( PATH, ACCOUNT(RID or SAM), PERMISSION, INHERIT, OVERWRITE )
|
|
//
|
|
// pszPath - Should be the path to the File Object that you
|
|
// want to set permissions on. Note: This is not
|
|
// setting SHARE permissions, but NTFS file perms.
|
|
// (Directories will work as well.)
|
|
//
|
|
// dwRID - Well-known RID specifying the account you want
|
|
// to give access to the file.
|
|
// (DOMAIN_ALIAS_RID_ADMINS, for example.)
|
|
//
|
|
// pszSAM - SAM-Account name specifying the account you want
|
|
// to give access to the file.
|
|
// (Users.h includes all SBS groups and users.)
|
|
//
|
|
// nAccess - Specify the File access flags that you want the
|
|
// user to have.
|
|
// (FILE_ALL_ACCESS is the default.)
|
|
//
|
|
// bInheritFromParent - Specify whether you want the new ACL
|
|
// to inherit the parent settings.
|
|
// (TRUE is the default.)
|
|
//
|
|
// bOverwriteExisting - Specify whether you want the existing
|
|
// ACL on the object to remain.
|
|
// (FALSE is the default.)
|
|
//
|
|
// nInheritance = Specify the type of inheritance you
|
|
// want.
|
|
// ((OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE)
|
|
// is the default.)
|
|
//
|
|
// (NOTE: If you want it to apply to
|
|
// directory objects only, use only the
|
|
// CONTAINER_INHERIT_ACE.)
|
|
//
|
|
////////////////////////////////////////////////////////////////
|
|
|
|
#ifndef _FILEPERMS_H
|
|
#define _FILEPERMS_H
|
|
|
|
inline HRESULT _AddPermissionToPath( LPCTSTR pszPath,
|
|
SID* pSID,
|
|
UINT nAccess = FILE_ALL_ACCESS,
|
|
BOOL bInheritFromParent = TRUE,
|
|
BOOL bOverwriteExisting = FALSE,
|
|
UINT nInheritance = (OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE) )
|
|
{
|
|
if( !pszPath ) return E_POINTER;
|
|
if( !pSID ) return E_POINTER;
|
|
|
|
PSECURITY_DESCRIPTOR pSD = NULL;
|
|
PACL pOldAcl = NULL;
|
|
PACL pNewAcl = NULL;
|
|
DWORD dwError = 0;
|
|
DWORD dwOldSize = 0;
|
|
DWORD dwNewSize = 0;
|
|
|
|
ACL_SIZE_INFORMATION pACLSize;
|
|
ZeroMemory(&pACLSize, sizeof(ACL_SIZE_INFORMATION));
|
|
|
|
// Get the current information for the path
|
|
dwError = GetNamedSecurityInfo( (LPTSTR)pszPath, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, NULL, NULL, &pOldAcl, NULL, &pSD );
|
|
if( dwError != ERROR_SUCCESS )
|
|
{
|
|
goto cleanup;
|
|
}
|
|
|
|
// If there was any current information, let's make sure we allocate enough
|
|
// size for it when we go to add our new ACE.
|
|
if( !bOverwriteExisting && pOldAcl )
|
|
{
|
|
if (!::GetAclInformation( pOldAcl, &pACLSize, sizeof(ACL_SIZE_INFORMATION), AclSizeInformation ))
|
|
{
|
|
dwError = GetLastError();
|
|
goto cleanup;
|
|
}
|
|
|
|
dwOldSize = pACLSize.AclBytesInUse;
|
|
}
|
|
|
|
dwNewSize = dwOldSize + sizeof(ACL) + sizeof (ACCESS_ALLOWED_ACE) - sizeof(DWORD) + GetLengthSid( pSID );
|
|
pNewAcl = (ACL*)malloc(dwNewSize);
|
|
if (pNewAcl == NULL)
|
|
{
|
|
dwError = ERROR_NOT_ENOUGH_MEMORY;
|
|
goto cleanup;
|
|
}
|
|
|
|
ZeroMemory( pNewAcl, dwNewSize );
|
|
if ( !::InitializeAcl(pNewAcl, dwNewSize, ACL_REVISION) )
|
|
{
|
|
dwError = GetLastError();
|
|
goto cleanup;
|
|
}
|
|
|
|
// Copy existing entries into new DACL.
|
|
if( !bOverwriteExisting )
|
|
{
|
|
for ( DWORD dwCount = 0; dwCount < pACLSize.AceCount; dwCount++ )
|
|
{
|
|
PACCESS_ALLOWED_ACE pACE = NULL;
|
|
|
|
// Get the Old ACE
|
|
if ( !::GetAce(pOldAcl, dwCount, (void**)&pACE) )
|
|
{
|
|
ASSERT(FALSE);
|
|
continue;
|
|
}
|
|
|
|
if( bInheritFromParent || !(pACE->Header.AceFlags & INHERITED_ACE) )
|
|
{
|
|
// Add it to the new ACL
|
|
if ( !::AddAce(pNewAcl, ACL_REVISION, (DWORD)-1, pACE, pACE->Header.AceSize) )
|
|
{
|
|
ASSERT(FALSE);
|
|
continue;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if( !::AddAccessAllowedAceEx(pNewAcl, ACL_REVISION, nInheritance, nAccess, pSID) )
|
|
{
|
|
dwError = GetLastError();
|
|
goto cleanup;
|
|
}
|
|
|
|
SECURITY_INFORMATION siType = DACL_SECURITY_INFORMATION;
|
|
siType |= bInheritFromParent ? 0 : PROTECTED_DACL_SECURITY_INFORMATION;
|
|
|
|
dwError = SetNamedSecurityInfo( (LPTSTR)pszPath, SE_FILE_OBJECT, siType, NULL, NULL, pNewAcl, NULL );
|
|
if( dwError != ERROR_SUCCESS )
|
|
{
|
|
goto cleanup;
|
|
}
|
|
|
|
cleanup:
|
|
|
|
if ( pNewAcl != NULL )
|
|
{
|
|
free( pNewAcl );
|
|
pNewAcl = NULL;
|
|
}
|
|
|
|
if ( pSD != NULL )
|
|
{
|
|
LocalFree( pSD );
|
|
pSD = NULL;
|
|
pOldAcl = NULL;
|
|
}
|
|
|
|
return HRESULT_FROM_WIN32( dwError );
|
|
}
|
|
|
|
//
|
|
// Well-Known RID Version
|
|
//
|
|
|
|
inline HRESULT AddPermissionToPath( LPCTSTR pszPath,
|
|
DWORD dwRID,
|
|
UINT nAccess = FILE_ALL_ACCESS,
|
|
BOOL bInheritFromParent = TRUE,
|
|
BOOL bOverwriteExisting = FALSE,
|
|
UINT nInheritance = (OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE) )
|
|
{
|
|
if( !pszPath ) return E_POINTER;
|
|
if( _tcslen(pszPath) == 0 ) return E_INVALIDARG;
|
|
|
|
PSID psid = NULL;
|
|
SID_IDENTIFIER_AUTHORITY sia = SECURITY_NT_AUTHORITY;
|
|
BOOL bRet = AllocateAndInitializeSid( &sia,
|
|
2,
|
|
SECURITY_BUILTIN_DOMAIN_RID,
|
|
dwRID,
|
|
0, 0, 0, 0, 0, 0,
|
|
&psid);
|
|
if( !bRet )
|
|
{
|
|
return HRESULT_FROM_WIN32( GetLastError() );
|
|
}
|
|
else if( !psid )
|
|
{
|
|
return E_FAIL;
|
|
}
|
|
|
|
HRESULT hr = _AddPermissionToPath( pszPath, (SID*)psid, nAccess, bInheritFromParent, bOverwriteExisting, nInheritance );
|
|
FreeSid( psid );
|
|
return hr;
|
|
}
|
|
|
|
//
|
|
// SAM Account version
|
|
//
|
|
|
|
inline HRESULT AddPermissionToPath( LPCTSTR pszPath,
|
|
LPCTSTR pszSAM,
|
|
UINT nAccess = FILE_ALL_ACCESS,
|
|
BOOL bInheritFromParent = TRUE,
|
|
BOOL bOverwriteExisting = FALSE,
|
|
UINT nInheritance = (OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE) )
|
|
{
|
|
if( !pszPath || !pszSAM ) return E_POINTER;
|
|
if( (_tcslen(pszPath) == 0) || (_tcslen(pszSAM) == 0 ) ) return E_INVALIDARG;
|
|
|
|
HRESULT hr = S_OK;
|
|
DWORD dwSize = 0;
|
|
DWORD dwDomainSize = 0;
|
|
SID_NAME_USE snu;
|
|
if( !LookupAccountName(NULL, pszSAM, NULL, &dwSize, NULL, &dwDomainSize, &snu) &&
|
|
GetLastError() == ERROR_INSUFFICIENT_BUFFER )
|
|
{
|
|
SID* psid = (SID*)new BYTE[dwSize];
|
|
if( !psid )
|
|
{
|
|
return E_OUTOFMEMORY;
|
|
}
|
|
|
|
TCHAR* pszDomain = new TCHAR[dwDomainSize];
|
|
if( !pszDomain )
|
|
{
|
|
delete[] psid;
|
|
return E_OUTOFMEMORY;
|
|
}
|
|
|
|
if( LookupAccountName(NULL, pszSAM, psid, &dwSize, pszDomain, &dwDomainSize, &snu) )
|
|
{
|
|
hr = _AddPermissionToPath( pszPath, psid, nAccess, bInheritFromParent, bOverwriteExisting, nInheritance );
|
|
}
|
|
else
|
|
{
|
|
hr = HRESULT_FROM_WIN32( GetLastError() );
|
|
}
|
|
|
|
delete[] psid;
|
|
delete[] pszDomain;
|
|
}
|
|
else
|
|
{
|
|
return E_FAIL;
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
#endif // _FILEPERMS_H
|