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.
370 lines
9.8 KiB
370 lines
9.8 KiB
//
|
|
// 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;
|
|
}
|