Ejemplo n.º 1
0
/**********************************************************************
 * NAME							EXPORTED
 * 	RtlCopyRangeList
 *
 * DESCRIPTION
 *	Copy a range list.
 *
 * ARGUMENTS
 *	CopyRangeList	Pointer to the destination range list.
 *	RangeList	Pointer to the source range list.
 *
 * RETURN VALUE
 *	Status
 *
 * @implemented
 */
NTSTATUS NTAPI
RtlCopyRangeList (OUT PRTL_RANGE_LIST CopyRangeList,
		  IN PRTL_RANGE_LIST RangeList)
{
  PRTL_RANGE_ENTRY Current;
  PRTL_RANGE_ENTRY NewEntry;
  PLIST_ENTRY Entry;

  CopyRangeList->Flags = RangeList->Flags;

  Entry = RangeList->ListHead.Flink;
  while (Entry != &RangeList->ListHead)
    {
      Current = CONTAINING_RECORD (Entry, RTL_RANGE_ENTRY, Entry);

      NewEntry = RtlpAllocateMemory(sizeof(RTL_RANGE_ENTRY), 'elRR');
      if (NewEntry == NULL)
	return STATUS_INSUFFICIENT_RESOURCES;

      RtlCopyMemory (&NewEntry->Range,
		     &Current->Range,
		     sizeof(RTL_RANGE_ENTRY));

      InsertTailList (&CopyRangeList->ListHead,
		      &NewEntry->Entry);

      CopyRangeList->Count++;

      Entry = Entry->Flink;
    }

  CopyRangeList->Stamp++;

  return STATUS_SUCCESS;
}
Ejemplo n.º 2
0
/*
 * @implemented
 */
NTSTATUS NTAPI
RtlAllocateAndInitializeSid(PSID_IDENTIFIER_AUTHORITY IdentifierAuthority,
			    UCHAR SubAuthorityCount,
			    ULONG SubAuthority0,
			    ULONG SubAuthority1,
			    ULONG SubAuthority2,
			    ULONG SubAuthority3,
			    ULONG SubAuthority4,
			    ULONG SubAuthority5,
			    ULONG SubAuthority6,
			    ULONG SubAuthority7,
			    PSID *Sid)
{
  PISID pSid;

  PAGED_CODE_RTL();

  if (SubAuthorityCount > 8)
    return STATUS_INVALID_SID;

  if (Sid == NULL)
    return STATUS_INVALID_PARAMETER;

  pSid = RtlpAllocateMemory(RtlLengthRequiredSid(SubAuthorityCount),
                            TAG_SID);
  if (pSid == NULL)
    return STATUS_NO_MEMORY;

  pSid->Revision = SID_REVISION;
  pSid->SubAuthorityCount = SubAuthorityCount;
  memcpy(&pSid->IdentifierAuthority,
         IdentifierAuthority,
         sizeof(SID_IDENTIFIER_AUTHORITY));

  switch (SubAuthorityCount)
    {
      case 8:
         pSid->SubAuthority[7] = SubAuthority7;
      case 7:
         pSid->SubAuthority[6] = SubAuthority6;
      case 6:
         pSid->SubAuthority[5] = SubAuthority5;
      case 5:
         pSid->SubAuthority[4] = SubAuthority4;
      case 4:
         pSid->SubAuthority[3] = SubAuthority3;
      case 3:
         pSid->SubAuthority[2] = SubAuthority2;
      case 2:
         pSid->SubAuthority[1] = SubAuthority1;
      case 1:
         pSid->SubAuthority[0] = SubAuthority0;
         break;
    }

  *Sid = pSid;

  return STATUS_SUCCESS;
}
Ejemplo n.º 3
0
/**********************************************************************
 * NAME							EXPORTED
 * 	RtlAddRange
 *
 * DESCRIPTION
 *	Adds a range to a range list.
 *
 * ARGUMENTS
 *	RangeList		Range list.
 *	Start
 *	End
 *	Attributes
 *	Flags
 *	UserData
 *	Owner
 *
 * RETURN VALUE
 *	Status
 *
 * TODO:
 *   - Support shared ranges.
 *
 * @implemented
 */
NTSTATUS NTAPI
RtlAddRange (IN OUT PRTL_RANGE_LIST RangeList,
	     IN ULONGLONG Start,
	     IN ULONGLONG End,
	     IN UCHAR Attributes,
	     IN ULONG Flags,
	     IN PVOID UserData OPTIONAL,
	     IN PVOID Owner OPTIONAL)
{
  PRTL_RANGE_ENTRY RangeEntry;
  PRTL_RANGE_ENTRY Previous;
  PRTL_RANGE_ENTRY Current;
  PLIST_ENTRY Entry;

  if (Start > End)
    return STATUS_INVALID_PARAMETER;

  /* Create new range entry */
  RangeEntry = RtlpAllocateMemory(sizeof(RTL_RANGE_ENTRY), 'elRR');
  if (RangeEntry == NULL)
    return STATUS_INSUFFICIENT_RESOURCES;

  /* Initialize range entry */
  RangeEntry->Range.Start = Start;
  RangeEntry->Range.End = End;
  RangeEntry->Range.Attributes = Attributes;
  RangeEntry->Range.UserData = UserData;
  RangeEntry->Range.Owner = Owner;

  RangeEntry->Range.Flags = 0;
  if (Flags & RTL_RANGE_LIST_ADD_SHARED)
    RangeEntry->Range.Flags |= RTL_RANGE_SHARED;

  /* Insert range entry */
  if (RangeList->Count == 0)
    {
      InsertTailList (&RangeList->ListHead,
		      &RangeEntry->Entry);
      RangeList->Count++;
      RangeList->Stamp++;
      return STATUS_SUCCESS;
    }
  else
    {
      Previous = NULL;
      Entry = RangeList->ListHead.Flink;
      while (Entry != &RangeList->ListHead)
	{
	  Current = CONTAINING_RECORD (Entry, RTL_RANGE_ENTRY, Entry);
	  if (Current->Range.Start > RangeEntry->Range.End)
	    {
	      /* Insert before current */
	      DPRINT ("Insert before current\n");
	      InsertTailList (&Current->Entry,
			      &RangeEntry->Entry);

	      RangeList->Count++;
	      RangeList->Stamp++;
	      return STATUS_SUCCESS;
	    }

	  Previous = Current;
	  Entry = Entry->Flink;
	}

      DPRINT ("Insert tail\n");
      InsertTailList (&RangeList->ListHead,
		      &RangeEntry->Entry);
      RangeList->Count++;
      RangeList->Stamp++;
      return STATUS_SUCCESS;
    }

  RtlpFreeMemory(RangeEntry, 0);

  return STATUS_UNSUCCESSFUL;
}
Ejemplo n.º 4
0
static NTSTATUS
RtlpSysVolCreateSecurityDescriptor(OUT PISECURITY_DESCRIPTOR *SecurityDescriptor,
                                   OUT PSID *SystemSid)
{
    PSECURITY_DESCRIPTOR AbsSD = NULL;
    PSID LocalSystemSid = NULL;
    PACL Dacl = NULL;
    ULONG DaclSize;
    NTSTATUS Status;

    /* create the local SYSTEM SID */
    Status = RtlAllocateAndInitializeSid(&LocalSystemAuthority,
                                         1,
                                         SECURITY_LOCAL_SYSTEM_RID,
                                         0,
                                         0,
                                         0,
                                         0,
                                         0,
                                         0,
                                         0,
                                         &LocalSystemSid);
    if (!NT_SUCCESS(Status))
    {
        return Status;
    }

    /* allocate and initialize the security descriptor */
    AbsSD = RtlpAllocateMemory(sizeof(SECURITY_DESCRIPTOR),
                               'dSeS');
    if (AbsSD == NULL)
    {
        Status = STATUS_NO_MEMORY;
        goto Cleanup;
    }

    Status = RtlCreateSecurityDescriptor(AbsSD,
                                         SECURITY_DESCRIPTOR_REVISION);
    if (!NT_SUCCESS(Status))
    {
        goto Cleanup;
    }

    /* allocate and create the DACL */
    DaclSize = sizeof(ACL) + sizeof(ACE) +
               RtlLengthSid(LocalSystemSid);
    Dacl = RtlpAllocateMemory(DaclSize,
                              'cAeS');
    if (Dacl == NULL)
    {
        Status = STATUS_NO_MEMORY;
        goto Cleanup;
    }

    Status = RtlCreateAcl(Dacl,
                          DaclSize,
                          ACL_REVISION);
    if (!NT_SUCCESS(Status))
    {
        goto Cleanup;
    }

    Status = RtlAddAccessAllowedAceEx(Dacl,
                                      ACL_REVISION,
                                      OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE,
                                      STANDARD_RIGHTS_ALL | SPECIFIC_RIGHTS_ALL,
                                      LocalSystemSid);
    if (!NT_SUCCESS(Status))
    {
        goto Cleanup;
    }

    /* set the DACL in the security descriptor */
    Status = RtlSetDaclSecurityDescriptor(AbsSD,
                                          TRUE,
                                          Dacl,
                                          FALSE);

    /* all done */
    if (NT_SUCCESS(Status))
    {
        *SecurityDescriptor = AbsSD;
        *SystemSid = LocalSystemSid;
    }
    else
    {
Cleanup:
        if (LocalSystemSid != NULL)
        {
            RtlFreeSid(LocalSystemSid);
        }

        if (Dacl != NULL)
        {
            RtlpFreeMemory(Dacl,
                           'cAeS');
        }

        if (AbsSD != NULL)
        {
            RtlpFreeMemory(AbsSD,
                           'dSeS');
        }
    }

    return Status;
}
Ejemplo n.º 5
0
static NTSTATUS
RtlpSysVolCheckOwnerAndSecurity(IN HANDLE DirectoryHandle,
                                IN PISECURITY_DESCRIPTOR SecurityDescriptor)
{
    PSECURITY_DESCRIPTOR RelSD = NULL;
    PSECURITY_DESCRIPTOR NewRelSD = NULL;
    PSECURITY_DESCRIPTOR AbsSD = NULL;
#ifdef _WIN64
    BOOLEAN AbsSDAllocated = FALSE;
#endif
    PSID AdminSid = NULL;
    PSID LocalSystemSid = NULL;
    ULONG DescriptorSize;
    ULONG AbsSDSize, RelSDSize = 0;
    PACL Dacl;
    BOOLEAN DaclPresent, DaclDefaulted;
    PSID OwnerSid;
    BOOLEAN OwnerDefaulted;
    ULONG AceIndex;
    PACE Ace = NULL;
    NTSTATUS Status;

    /* find out how much memory we need to allocate for the self-relative
       descriptor we're querying */
    Status = ZwQuerySecurityObject(DirectoryHandle,
                                   OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION,
                                   NULL,
                                   0,
                                   &DescriptorSize);
    if (Status != STATUS_BUFFER_TOO_SMALL)
    {
        /* looks like the FS doesn't support security... return success */
        Status = STATUS_SUCCESS;
        goto Cleanup;
    }

    /* allocate enough memory for the security descriptor */
    RelSD = RtlpAllocateMemory(DescriptorSize,
                               'dSeS');
    if (RelSD == NULL)
    {
        Status = STATUS_NO_MEMORY;
        goto Cleanup;
    }

    /* query the self-relative security descriptor */
    Status = ZwQuerySecurityObject(DirectoryHandle,
                                   OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION,
                                   RelSD,
                                   DescriptorSize,
                                   &DescriptorSize);
    if (!NT_SUCCESS(Status))
    {
        /* FIXME - handle the case where someone else modified the owner and/or
                   DACL while we allocated memory. But that should be *very*
                   unlikely.... */
        goto Cleanup;
    }

    /* query the owner and DACL from the descriptor */
    Status = RtlGetOwnerSecurityDescriptor(RelSD,
                                           &OwnerSid,
                                           &OwnerDefaulted);
    if (!NT_SUCCESS(Status))
    {
        goto Cleanup;
    }

    Status = RtlGetDaclSecurityDescriptor(RelSD,
                                          &DaclPresent,
                                          &Dacl,
                                          &DaclDefaulted);
    if (!NT_SUCCESS(Status))
    {
        goto Cleanup;
    }

    /* create the Administrators SID */
    Status = RtlAllocateAndInitializeSid(&LocalSystemAuthority,
                                         2,
                                         SECURITY_BUILTIN_DOMAIN_RID,
                                         DOMAIN_ALIAS_RID_ADMINS,
                                         0,
                                         0,
                                         0,
                                         0,
                                         0,
                                         0,
                                         &AdminSid);
    if (!NT_SUCCESS(Status))
    {
        goto Cleanup;
    }

    /* create the local SYSTEM SID */
    Status = RtlAllocateAndInitializeSid(&LocalSystemAuthority,
                                         1,
                                         SECURITY_LOCAL_SYSTEM_RID,
                                         0,
                                         0,
                                         0,
                                         0,
                                         0,
                                         0,
                                         0,
                                         &LocalSystemSid);
    if (!NT_SUCCESS(Status))
    {
        goto Cleanup;
    }

    /* check if the Administrators are the owner and at least a not-NULL DACL
       is present */
    if (OwnerSid != NULL &&
        RtlEqualSid(OwnerSid,
                    AdminSid) &&
        DaclPresent && Dacl != NULL)
    {
        /* check the DACL for an Allowed ACE for the SYSTEM account */
        AceIndex = 0;
        do
        {
            Status = RtlGetAce(Dacl,
                               AceIndex++,
                               (PVOID*)&Ace);
            if (!NT_SUCCESS(Status))
            {
                Ace = NULL;
            }
            else if (Ace != NULL && Ace->Header.AceType == ACCESS_ALLOWED_ACE_TYPE)
            {
                /* check if the the ACE is a set of allowed permissions for the
                   local SYSTEM account */
                if (RtlEqualSid((PSID)(Ace + 1),
                                LocalSystemSid))
                {
                    /* check if the ACE is inherited by noncontainer and
                       container objects, if not attempt to change that */
                    if (!(Ace->Header.AceFlags & OBJECT_INHERIT_ACE) ||
                        !(Ace->Header.AceFlags & CONTAINER_INHERIT_ACE))
                    {
                        Ace->Header.AceFlags |= OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE;
                        Status = ZwSetSecurityObject(DirectoryHandle,
                                                     DACL_SECURITY_INFORMATION,
                                                     RelSD);
                    }
                    else
                    {
                        /* all done, we have access */
                        Status = STATUS_SUCCESS;
                    }

                    goto Cleanup;
                }
            }
        } while (Ace != NULL);
    }

    AbsSDSize = DescriptorSize;

    /* because we need to change any existing data we need to convert it to
       an absolute security descriptor first */
    Status = RtlSelfRelativeToAbsoluteSD2(RelSD,
                                          &AbsSDSize);
#ifdef _WIN64
    if (Status == STATUS_BUFFER_TOO_SMALL)
    {
        /* this error code can only be returned on 64 bit builds because
           the size of an absolute security descriptor is greater than the
           size of a self-relative security descriptor */
        ASSERT(AbsSDSize > DescriptorSize);

        AbsSD = RtlpAllocateMemory(DescriptorSize,
                                   'dSeS');
        if (AbsSD == NULL)
        {
            Status = STATUS_NO_MEMORY;
            goto Cleanup;
        }

        AbsSDAllocated = TRUE;

        /* make a raw copy of the self-relative descriptor */
        RtlCopyMemory(AbsSD,
                      RelSD,
                      DescriptorSize);

        /* finally convert it */
        Status = RtlSelfRelativeToAbsoluteSD2(AbsSD,
                                              &AbsSDSize);
    }
    else
#endif
    {
        AbsSD = RelSD;
    }

    if (!NT_SUCCESS(Status))
    {
        goto Cleanup;
    }

    /* set the owner SID */
    Status = RtlSetOwnerSecurityDescriptor(AbsSD,
                                           AdminSid,
                                           FALSE);
    if (!NT_SUCCESS(Status))
    {
        goto Cleanup;
    }

    /* set the DACL in the security descriptor */
    Status = RtlSetDaclSecurityDescriptor(AbsSD,
                                          TRUE,
                                          SecurityDescriptor->Dacl,
                                          FALSE);
    if (!NT_SUCCESS(Status))
    {
        goto Cleanup;
    }

    /* convert it back to a self-relative descriptor, find out how much
       memory we need */
    Status = RtlAbsoluteToSelfRelativeSD(AbsSD,
                                         NULL,
                                         &RelSDSize);
    if (Status != STATUS_BUFFER_TOO_SMALL)
    {
        goto Cleanup;
    }

    /* allocate enough memory for the new self-relative descriptor */
    NewRelSD = RtlpAllocateMemory(RelSDSize,
                                  'dSeS');
    if (NewRelSD == NULL)
    {
        Status = STATUS_NO_MEMORY;
        goto Cleanup;
    }

    /* convert the security descriptor to self-relative format */
    Status = RtlAbsoluteToSelfRelativeSD(AbsSD,
                                         NewRelSD,
                                         &RelSDSize);
    if (Status == STATUS_BUFFER_TOO_SMALL)
    {
        goto Cleanup;
    }

    /* finally attempt to change the security information */
    Status = ZwSetSecurityObject(DirectoryHandle,
                                 OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION,
                                 NewRelSD);

Cleanup:
    if (AdminSid != NULL)
    {
        RtlFreeSid(AdminSid);
    }

    if (LocalSystemSid != NULL)
    {
        RtlFreeSid(LocalSystemSid);
    }

    if (RelSD != NULL)
    {
        RtlpFreeMemory(RelSD,
                       'dSeS');
    }

    if (NewRelSD != NULL)
    {
        RtlpFreeMemory(NewRelSD,
                       'dSeS');
    }

#ifdef _WIN64
    if (AbsSDAllocated)
    {
        RtlpFreeMemory(AbsSD,
                       'dSeS');
    }
#endif

    return Status;
}