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.
 
 
 
 
 
 

437 lines
12 KiB

/*++
Copyright (c) 2002 Microsoft Corporation
Module Name:
tunsd.c
Abstract:
utility routines to handle setting security descriptor on tunmp device.
Environment:
Kernel mode only.
Revision History:
alid 5/17/2002
--*/
#include <ntosp.h>
#include <ntrtl.h>
#define TUN_ALLOC_TAG 'untN'
PACL NetConfigAcl = NULL;
PSID NetConfigOpsSid = NULL;
CHAR NetConfigSecurityDescriptor[SECURITY_DESCRIPTOR_MIN_LENGTH];
PACL
TunCreateAcl(
BOOLEAN Admins,
BOOLEAN LocalSystem,
BOOLEAN LocalService,
BOOLEAN NetworkService,
BOOLEAN NetConfigOps,
BOOLEAN Users,
ACCESS_MASK AccessMask
);
NTSTATUS
TunCreateGenericSD(
PACL Acl,
PCHAR AccessSecurityDescriptor
);
PACL
TunCreateAcl(
BOOLEAN Admins,
BOOLEAN LocalSystem,
BOOLEAN LocalService,
BOOLEAN NetworkService,
BOOLEAN NetConfigOps,
BOOLEAN Users,
ACCESS_MASK AccessMask
)
{
PACL AccessDacl = NULL, pAcl = NULL;
ULONG AclLength = 0;
ULONG NetConfigOpsSidSize;
SID_IDENTIFIER_AUTHORITY NetConfigOpsSidAuth = SECURITY_NT_AUTHORITY;
PISID ISid;
NTSTATUS Status;
do
{
if (Admins)
{
AclLength += sizeof(ACL) +
FIELD_OFFSET (ACCESS_ALLOWED_ACE, SidStart) +
RtlLengthSid(SeExports->SeAliasAdminsSid);
}
if (LocalSystem)
{
AclLength += sizeof(ACL) +
FIELD_OFFSET (ACCESS_ALLOWED_ACE, SidStart) +
RtlLengthSid(SeExports->SeLocalSystemSid);
}
if (LocalService)
{
AclLength += sizeof(ACL) +
FIELD_OFFSET (ACCESS_ALLOWED_ACE, SidStart) +
RtlLengthSid(SeExports->SeLocalServiceSid);
}
if (NetworkService)
{
AclLength += sizeof(ACL) +
FIELD_OFFSET (ACCESS_ALLOWED_ACE, SidStart) +
RtlLengthSid(SeExports->SeNetworkServiceSid);
}
if (NetConfigOps)
{
NetConfigOpsSidSize = RtlLengthRequiredSid(2);
NetConfigOpsSid = (PSID)ExAllocatePoolWithTag(PagedPool, NetConfigOpsSidSize, TUN_ALLOC_TAG);
if (NULL == NetConfigOpsSid)
{
Status = STATUS_INSUFFICIENT_RESOURCES;
break;
}
Status = RtlInitializeSid(NetConfigOpsSid, &NetConfigOpsSidAuth, 2);
if (Status != STATUS_SUCCESS)
{
Status = STATUS_INSUFFICIENT_RESOURCES;
break;
}
ISid = (PISID)(NetConfigOpsSid);
ISid->SubAuthority[0] = SECURITY_BUILTIN_DOMAIN_RID;
ISid->SubAuthority[1] = DOMAIN_ALIAS_RID_NETWORK_CONFIGURATION_OPS;
AclLength += sizeof(ACL) +
FIELD_OFFSET (ACCESS_ALLOWED_ACE, SidStart) +
RtlLengthSid(NetConfigOpsSid);
}
if (Users)
{
AclLength += sizeof(ACL) +
FIELD_OFFSET (ACCESS_ALLOWED_ACE, SidStart) +
RtlLengthSid(SeExports->SeAliasUsersSid);
}
AccessDacl = (PACL)ExAllocatePoolWithTag(PagedPool,
AclLength,
TUN_ALLOC_TAG);
if (AccessDacl == NULL)
{
Status = STATUS_INSUFFICIENT_RESOURCES;
break;
}
Status = RtlCreateAcl(AccessDacl,
AclLength,
ACL_REVISION2);
if (!NT_SUCCESS(Status))
{
#if DBG
DbgPrint("RtlCreateAcl failed, Status %lx.\n", Status);
#endif
break;
}
if (Admins)
{
Status = RtlAddAccessAllowedAce(
AccessDacl,
ACL_REVISION2,
(STANDARD_RIGHTS_ALL | SPECIFIC_RIGHTS_ALL),
SeExports->SeAliasAdminsSid
);
if (!NT_SUCCESS(Status))
{
#if DBG
DbgPrint("RtlAddAccessAllowedAce failed, Status %lx.\n", Status);
#endif
break;
}
}
if (LocalSystem)
{
Status = RtlAddAccessAllowedAce(
AccessDacl,
ACL_REVISION2,
(STANDARD_RIGHTS_ALL | SPECIFIC_RIGHTS_ALL),
SeExports->SeLocalSystemSid
);
if (!NT_SUCCESS(Status))
{
#if DBG
DbgPrint("RtlAddAccessAllowedAce failed, Status %lx.\n", Status);
#endif
break;
}
}
if (LocalService)
{
Status = RtlAddAccessAllowedAce(
AccessDacl,
ACL_REVISION2,
(STANDARD_RIGHTS_ALL | SPECIFIC_RIGHTS_ALL),
SeExports->SeLocalServiceSid
);
if (!NT_SUCCESS(Status))
{
#if DBG
DbgPrint("RtlAddAccessAllowedAce failed, Status %lx.\n", Status);
#endif
break;
}
}
if (NetworkService)
{
Status = RtlAddAccessAllowedAce(
AccessDacl,
ACL_REVISION2,
(STANDARD_RIGHTS_ALL | SPECIFIC_RIGHTS_ALL),
SeExports->SeNetworkServiceSid
);
if (!NT_SUCCESS(Status))
{
#if DBG
DbgPrint("RtlAddAccessAllowedAce failed, Status %lx.\n", Status);
#endif
break;
}
}
if (NetConfigOps)
{
Status = RtlAddAccessAllowedAce(
AccessDacl,
ACL_REVISION2,
(STANDARD_RIGHTS_ALL | SPECIFIC_RIGHTS_ALL),
NetConfigOpsSid
);
if (!NT_SUCCESS(Status))
{
#if DBG
DbgPrint("RtlAddAccessAllowedAce failed, Status %lx.\n", Status);
#endif
break;
}
}
if (Users)
{
Status = RtlAddAccessAllowedAce(
AccessDacl,
ACL_REVISION2,
AccessMask,
SeExports->SeAliasUsersSid
);
if (!NT_SUCCESS(Status))
{
DbgPrint("RtlAddAccessAllowedAce failed, Status %lx.\n", Status);
break;
}
}
pAcl = AccessDacl;
}while (FALSE);
if (pAcl == NULL)
{
if (AccessDacl)
ExFreePool(AccessDacl);
if (NetConfigOpsSid)
{
ExFreePool(NetConfigOpsSid);
NetConfigOpsSid = NULL;
}
}
return pAcl;
}
NTSTATUS
TunCreateGenericSD(
PACL Acl,
PCHAR AccessSecurityDescriptor
)
/*++
Routine Description:
Creates the SD responsible for giving access to different users.
Arguments:
None.
Return Value:
STATUS_SUCCESS or an appropriate error code.
--*/
{
PSECURITY_DESCRIPTOR AccessSd;
NTSTATUS Status;
if (Acl == NULL)
return STATUS_UNSUCCESSFUL;
do
{
AccessSd = AccessSecurityDescriptor;
Status = RtlCreateSecurityDescriptor(
AccessSd,
SECURITY_DESCRIPTOR_REVISION1
);
if (!NT_SUCCESS(Status))
{
DbgPrint("RtlCreateSecurityDescriptor failed, Status %lx.\n", Status);
break;
}
Status = RtlSetDaclSecurityDescriptor(
AccessSd,
TRUE, // DaclPresent
Acl,
FALSE // DaclDefaulted
);
if (!NT_SUCCESS(Status))
{
DbgPrint("RtlSetDaclSecurityDescriptor failed, Status %lx.\n", Status);
break;
}
Status = RtlSetOwnerSecurityDescriptor(AccessSd,
SeExports->SeAliasAdminsSid,
FALSE);
if (!NT_SUCCESS(Status))
{
DbgPrint("RtlSetOwnerSecurityDescriptor failed, Status %lx.\n", Status);
break;
}
Status = RtlSetGroupSecurityDescriptor(AccessSd,
SeExports->SeAliasAdminsSid,
FALSE);
if (!NT_SUCCESS(Status))
{
DbgPrint("RtlSetGroupSecurityDescriptor failed, Status %lx.\n", Status);
break;
}
}while (FALSE);
return (Status);
}
NTSTATUS
TunCreateSD(
VOID
)
{
NTSTATUS Status;
//
// create an ACL for admin types
//
NetConfigAcl = TunCreateAcl(TRUE, // Admins
TRUE, //LocalSystem
TRUE, //LocalService
TRUE, //NetworkService
TRUE, //NetConfigOps
FALSE, //Users
GENERIC_READ | GENERIC_WRITE
);
if (NetConfigAcl != NULL)
{
Status = TunCreateGenericSD(NetConfigAcl, NetConfigSecurityDescriptor);
}
else
{
Status = STATUS_UNSUCCESSFUL;
}
return Status;
}
NTSTATUS
TunSetSecurity(
IN PDEVICE_OBJECT DeviceObject
)
{
NTSTATUS Status;
SECURITY_INFORMATION secInfo = OWNER_SECURITY_INFORMATION |
GROUP_SECURITY_INFORMATION |
DACL_SECURITY_INFORMATION;
Status = ObSetSecurityObjectByPointer(DeviceObject,
secInfo,
NetConfigSecurityDescriptor);
ASSERT(NT_SUCCESS(Status));
return Status;
}
VOID
TunDeleteSD(
VOID
)
/*
delete NetConfigAcl
*/
{
if (NetConfigAcl != NULL)
{
ExFreePool(NetConfigAcl);
NetConfigAcl = NULL;
}
if (NetConfigOpsSid != NULL)
{
ExFreePool(NetConfigOpsSid);
NetConfigOpsSid = NULL;
}
}