|
|
//
// Copyright (C) 2000, Microsoft Corporation
//
// File: regsecurity.c
//
// Contents: miscellaneous dfs functions.
//
// History: April. 17 2002, Author: rohanp
//
//-----------------------------------------------------------------------------
#include <nt.h>
#include <ntrtl.h>
#include <nturtl.h>
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <malloc.h>
#include "rpc.h"
#include "rpcdce.h"
#include <dfsheader.h>
#include "lm.h"
#include "lmdfs.h"
#include <strsafe.h>
#include <dfsmisc.h>
#include <seopaque.h>
#include <sertlp.h>
#define FLAG_ON(x, y) ((y)==((x)&(y)))
//
// Registry generic mapping
//
GENERIC_MAPPING DfsRegGenMapping = {STANDARD_RIGHTS_READ | 0x1, STANDARD_RIGHTS_WRITE | 0x2, STANDARD_RIGHTS_EXECUTE | 0x4, STANDARD_RIGHTS_REQUIRED | 0x3F};
//
// Security open type (used to help determine permissions to use on open)
//
typedef enum _DFS_SECURITY_OPEN_TYPE { READ_ACCESS_RIGHTS = 0, WRITE_ACCESS_RIGHTS, MODIFY_ACCESS_RIGHTS, NO_ACCESS_RIGHTS, RESET_ACCESS_RIGHTS } DFS_SECURITY_OPEN_TYPE, *PDFS_SECURITY_OPEN_TYPE;
ACCESS_MASK DfsRegGetDesiredAccess(IN DFS_SECURITY_OPEN_TYPE OpenType, IN SECURITY_INFORMATION SecurityInfo) { ACCESS_MASK DesiredAccess = 0;
if ( (SecurityInfo & OWNER_SECURITY_INFORMATION) || (SecurityInfo & GROUP_SECURITY_INFORMATION) ) { switch (OpenType) { case READ_ACCESS_RIGHTS: DesiredAccess |= READ_CONTROL; break; case WRITE_ACCESS_RIGHTS: DesiredAccess |= WRITE_OWNER; break; case MODIFY_ACCESS_RIGHTS: DesiredAccess |= READ_CONTROL | WRITE_OWNER; break; } }
if (SecurityInfo & DACL_SECURITY_INFORMATION) { switch (OpenType) { case READ_ACCESS_RIGHTS: DesiredAccess |= READ_CONTROL; break; case WRITE_ACCESS_RIGHTS: DesiredAccess |= WRITE_DAC; break; case MODIFY_ACCESS_RIGHTS: DesiredAccess |= READ_CONTROL | WRITE_DAC; break; } }
if (SecurityInfo & SACL_SECURITY_INFORMATION) { DesiredAccess |= READ_CONTROL | ACCESS_SYSTEM_SECURITY; }
return DesiredAccess; }
DFSSTATUS MakeSDAbsolute(IN PSECURITY_DESCRIPTOR pOriginalSD, IN SECURITY_INFORMATION SeInfo, OUT PSECURITY_DESCRIPTOR *ppNewSD, IN PSID pOwnerToAdd, IN PSID pGroupToAdd) { DFSSTATUS dwErr = ERROR_SUCCESS;
BOOL fDAclPresent = FALSE; BOOL fSAclPresent = FALSE; BOOL fDAclDef = FALSE, fSAclDef = FALSE; BOOL fOwnerDef = FALSE, fGroupDef = FALSE; PACL pDAcl = NULL, pSAcl = NULL; PSID pOwner = NULL, pGroup = NULL; ULONG cSize = 0; PBYTE pbEndOBuf = NULL; DWORD cLen = 0;
//
// First, get the info out of the current SD
//
if(FLAG_ON(SeInfo, DACL_SECURITY_INFORMATION)) { if(GetSecurityDescriptorDacl(pOriginalSD, &fDAclPresent, &pDAcl, &fDAclDef) == FALSE) { dwErr = GetLastError(); } else { if(pDAcl != NULL) { cSize += pDAcl->AclSize; } } }
if(dwErr == ERROR_SUCCESS && FLAG_ON(SeInfo, SACL_SECURITY_INFORMATION)) { if(GetSecurityDescriptorSacl(pOriginalSD, &fSAclPresent, &pSAcl, &fSAclDef) == FALSE) { dwErr = GetLastError(); } else { if(pSAcl != NULL) { cSize += pSAcl->AclSize; } } }
if(pOwnerToAdd != NULL) { pOwner = pOwnerToAdd; } else { if(dwErr == ERROR_SUCCESS && FLAG_ON(SeInfo, OWNER_SECURITY_INFORMATION)) { if(GetSecurityDescriptorOwner(pOriginalSD, &pOwner, &fOwnerDef) == FALSE) { dwErr = GetLastError(); } } }
if(pGroupToAdd != NULL) { pGroup = pGroupToAdd; } else { if(dwErr == ERROR_SUCCESS && FLAG_ON(SeInfo, GROUP_SECURITY_INFORMATION)) { if(GetSecurityDescriptorGroup(pOriginalSD, &pGroup, &fGroupDef) == FALSE) { dwErr = GetLastError(); } } }
if(pOwner != NULL) { cSize += RtlLengthSid(pOwner); }
if(pGroup != NULL) { cSize += RtlLengthSid(pGroup); }
if(dwErr == ERROR_SUCCESS) { //
// Allocate the buffer...
//
PBYTE pBuff = (PBYTE)HeapAlloc(GetProcessHeap(), 0 ,(cSize + sizeof(SECURITY_DESCRIPTOR))); if(pBuff == NULL) { dwErr = ERROR_NOT_ENOUGH_MEMORY; } else { //
// Start copying in the existing items...
//
pbEndOBuf = pBuff + cSize + sizeof(SECURITY_DESCRIPTOR);
if(pOwner != NULL) { cLen = RtlLengthSid(pOwner); pbEndOBuf -= cLen; RtlCopyMemory(pbEndOBuf, pOwner, cLen); pOwner = (PSID)pbEndOBuf; }
if(pGroup != NULL) { cLen = RtlLengthSid(pGroup); pbEndOBuf -= cLen; RtlCopyMemory(pbEndOBuf, pGroup, cLen); pGroup = (PSID)pbEndOBuf; }
if(pDAcl != NULL) { pbEndOBuf -= pDAcl->AclSize; RtlCopyMemory(pbEndOBuf, pDAcl, pDAcl->AclSize); pDAcl = (PACL)pbEndOBuf; }
if(pSAcl != NULL) { pbEndOBuf -= pSAcl->AclSize; RtlCopyMemory(pbEndOBuf, pSAcl, pSAcl->AclSize); pSAcl = (PACL)pbEndOBuf; }
//
// Ok, now build it...
//
*ppNewSD = (PSECURITY_DESCRIPTOR)pBuff; if(InitializeSecurityDescriptor(*ppNewSD, SECURITY_DESCRIPTOR_REVISION) == FALSE) { dwErr = GetLastError(); }
if(dwErr == ERROR_SUCCESS && fDAclPresent == TRUE) { if(SetSecurityDescriptorDacl(*ppNewSD, TRUE, pDAcl, fDAclDef) == FALSE) { dwErr = GetLastError(); } }
if(dwErr == ERROR_SUCCESS && fSAclPresent == TRUE) { if(SetSecurityDescriptorSacl(*ppNewSD, TRUE, pSAcl, fSAclDef) == FALSE) { dwErr = GetLastError(); } }
if(dwErr == ERROR_SUCCESS && pOwner != NULL)
{ if(SetSecurityDescriptorOwner(*ppNewSD, pOwner, fOwnerDef) == FALSE) { dwErr = GetLastError(); } }
if(dwErr == ERROR_SUCCESS && pGroup != NULL)
{ if(SetSecurityDescriptorGroup(*ppNewSD, pGroup, fGroupDef) == FALSE) { dwErr = GetLastError(); } }
//
// Set the new control bits to look like the old ones (minus the selfrel flag, of
// course...
//
if(dwErr == ERROR_SUCCESS) { RtlpPropagateControlBits((PISECURITY_DESCRIPTOR)*ppNewSD, (PISECURITY_DESCRIPTOR)pOriginalSD, ~SE_SELF_RELATIVE ); }
if(dwErr != ERROR_SUCCESS) { HeapFree(GetProcessHeap, 0,(*ppNewSD)); *ppNewSD = NULL; }
}
}
return(dwErr); }
DFSSTATUS DfsReadRegistrySecurityInfo(IN HKEY hRegistry, IN SECURITY_INFORMATION SeInfo, OUT PSECURITY_DESCRIPTOR *ppSD) {
ULONG cSize = 0; DWORD Status = 0; PSECURITY_DESCRIPTOR pAbs = NULL;
//
// First, get the size we need
//
Status = RegGetKeySecurity(hRegistry, SeInfo, *ppSD, &cSize); if(Status == ERROR_INSUFFICIENT_BUFFER) { Status = ERROR_SUCCESS; *ppSD = (PISECURITY_DESCRIPTOR)HeapAlloc(GetProcessHeap(), 0, cSize); if(*ppSD == NULL) { Status = ERROR_NOT_ENOUGH_MEMORY; } else { Status = RegGetKeySecurity((HKEY)hRegistry, SeInfo, *ppSD, &cSize);
} }
return Status; }
DFSSTATUS DfsSetRegistrySecurityInfo(IN HKEY hRegistry, IN SECURITY_INFORMATION SeInfo, IN PSECURITY_DESCRIPTOR pSD) { DFSSTATUS Status = 0;
if(FLAG_ON(SeInfo, DACL_SECURITY_INFORMATION)) { ((PISECURITY_DESCRIPTOR)pSD)->Control |= SE_DACL_AUTO_INHERIT_REQ; }
if(FLAG_ON(SeInfo, SACL_SECURITY_INFORMATION)) { ((PISECURITY_DESCRIPTOR)pSD)->Control |= SE_SACL_AUTO_INHERIT_REQ; }
Status = RegSetKeySecurity(hRegistry, SeInfo, pSD);
return Status; }
|