Leaked source code of windows server 2003
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

//
// 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;
}