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