Пример #1
0
/*
 * @implemented
 */
BOOL
WINAPI
IsValidSecurityDescriptor(PSECURITY_DESCRIPTOR pSecurityDescriptor)
{
    BOOLEAN Result;

    Result = RtlValidSecurityDescriptor (pSecurityDescriptor);
    if (Result == FALSE)
        SetLastError(RtlNtStatusToDosError(STATUS_INVALID_SECURITY_DESCR));

    return (BOOL)Result;
}
Пример #2
0
static NTSTATUS FspFsvolSetSecurity(
    PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
{
    PAGED_CODE();

    /* is this a valid FileObject? */
    if (!FspFileNodeIsValid(IrpSp->FileObject->FsContext))
        return STATUS_INVALID_DEVICE_REQUEST;

    NTSTATUS Result;
    PFILE_OBJECT FileObject = IrpSp->FileObject;
    FSP_FILE_NODE *FileNode = FileObject->FsContext;
    FSP_FILE_DESC *FileDesc = FileObject->FsContext2;
    SECURITY_INFORMATION SecurityInformation = IrpSp->Parameters.SetSecurity.SecurityInformation;
    PSECURITY_DESCRIPTOR SecurityDescriptor = IrpSp->Parameters.SetSecurity.SecurityDescriptor;
    ULONG SecurityDescriptorSize = 0;

    ASSERT(FileNode == FileDesc->FileNode);

#if 0
    /* captured security descriptor is always valid */
    if (0 == SecurityDescriptor || !RtlValidSecurityDescriptor(SecurityDescriptor))
        return STATUS_INVALID_PARAMETER;
#endif
    SecurityDescriptorSize = RtlLengthSecurityDescriptor(SecurityDescriptor);

    FspFileNodeAcquireExclusive(FileNode, Full);

    FSP_FSCTL_TRANSACT_REQ *Request;

    Result = FspIopCreateRequestEx(Irp, 0, SecurityDescriptorSize, FspFsvolSetSecurityRequestFini,
        &Request);
    if (!NT_SUCCESS(Result))
    {
        FspFileNodeRelease(FileNode, Full);
        return Result;
    }

    Request->Kind = FspFsctlTransactSetSecurityKind;
    Request->Req.SetSecurity.UserContext = FileNode->UserContext;
    Request->Req.SetSecurity.UserContext2 = FileDesc->UserContext2;
    Request->Req.SetSecurity.SecurityInformation = SecurityInformation;
    Request->Req.SetSecurity.SecurityDescriptor.Offset = 0;
    Request->Req.SetSecurity.SecurityDescriptor.Size = (UINT16)SecurityDescriptorSize;
    RtlCopyMemory(Request->Buffer, SecurityDescriptor, SecurityDescriptorSize);

    FspFileNodeSetOwner(FileNode, Full, Request);
    FspIopRequestContext(Request, RequestFileNode) = FileNode;

    return FSP_STATUS_IOQ_POST;
}
Пример #3
0
//----------------------------------------------------------------------
//
// NTIRemoveWorldAce
// 
// Scans the passed security descriptor's DACL, looking for
// the World SID's ACE (its first because the of the way device object
// security descriptors are created) and removes it.
//
// If successful, the original security descriptor is deallocated
// and a new one is returned.
//
//----------------------------------------------------------------------
NTSTATUS NTIRemoveWorldAce( PSECURITY_DESCRIPTOR SecurityDescriptor,
			    PSECURITY_DESCRIPTOR *NewSecurityDescriptor )
{
   PSECURITY_DESCRIPTOR	     absSecurityDescriptor;
   PSECURITY_DESCRIPTOR	     relSecurityDescriptor;
   PACE_HEADER               aceHeader;
   NTSTATUS		     status;
   PACL			     Dacl;
   BOOLEAN		     DaclPresent, DaclDefaulted;
   USHORT                    aceIndex;
   ULONG                     worldSidLength;
   SID_IDENTIFIER_AUTHORITY  worldSidAuthority = SECURITY_WORLD_SID_AUTHORITY;
   PULONG                    worldSidSubAuthority;
   ULONG                     relLength;
   PSID                      worldSid;
   PSID                      aceSid;

   //
   // First, get an absolute version of the self-relative descriptor
   //
   relLength = RtlLengthSecurityDescriptor( SecurityDescriptor );
   status = NTIMakeAbsoluteSD( SecurityDescriptor, 
			       &absSecurityDescriptor );
   if( !NT_SUCCESS( status )) {
	  
     return status;
   }

   //
   // Pull the DACL out so that we can scan it
   //
   status = RtlGetDaclSecurityDescriptor( absSecurityDescriptor,
					  &DaclPresent,
					  &Dacl,
					  &DaclDefaulted );
   if( !NT_SUCCESS( status ) || !DaclPresent ) {

     DbgPrint(("Secsys: strange - couldn't get DACL from our absolute SD: %x\n", 
	       status ));
     ExFreePool( absSecurityDescriptor );
     return status;
   }

   //
   // Initialize a SID that identifies the world-authority so
   // that we can recognize it in the ACL
   //
   worldSidLength = RtlLengthRequiredSid( 1 );
   worldSid = (PSID) ExAllocatePool( PagedPool, worldSidLength );
   RtlInitializeSid( worldSid, &worldSidAuthority, 1 );
   worldSidSubAuthority = RtlSubAuthoritySid( worldSid, 0 );
   *worldSidSubAuthority = SECURITY_WORLD_RID;

   //
   // Now march through the ACEs looking for the World ace. We could 
   // do one of two things: 
   //
   //	- remove the ACE
   //	- convert it into a grant-nothing ACE
   //
   // For demonstration purposes I'll remove the ACE. In addition,
   // this requires that I implement kernel-mode GetAce and DeleteAce functions,
   // since they are not implemented by the NT kernel.
   //
   DbgPrint(("Secsys: %d ACEs in DACL\n", Dacl->AceCount ));

   for( aceIndex = 0; aceIndex < Dacl->AceCount; aceIndex++ ) {

     aceHeader = NTIGetAce( Dacl, aceIndex );
     
     DbgPrint(("  ACE: type: %s mask: %x\n", 
	       (aceHeader->AceType & ACCESS_DENIED_ACE_TYPE ? "Deny" : "Allow"),
	       *(PULONG) ((PUCHAR) aceHeader + sizeof(ACE_HEADER))));

     //
     // Get the SID in this ACE and see if its the WORLD (Everyone) SID
     //
     aceSid    = (PSID) ((PUCHAR) aceHeader + sizeof(ACE_HEADER) + sizeof(ULONG));
     if( RtlEqualSid( worldSid, aceSid )) {

       //
       // We found it: remove it.
       //
       DbgPrint(("Secsys: Deleting ace %d\n", aceIndex ));
       NTIDeleteAce( Dacl, aceIndex );
       break;
     }
   }

   // 
   // Write new DACL back to security descriptor
   //
   status = RtlSetDaclSecurityDescriptor( absSecurityDescriptor,
					  TRUE,
					  Dacl,
					  FALSE );
   if( !NT_SUCCESS( status )) {

      DbgPrint(("Secsys: Could not update SD Dacl: %x\n", status ));
      goto cleanup;
   }

   // 
   // Make sure its valid
   //
   if( !RtlValidSecurityDescriptor( absSecurityDescriptor )) {

      DbgPrint(("Secsys: SD after remove is invalid!\n"));
      status = STATUS_UNSUCCESSFUL;
      goto cleanup;
   }

   //
   // Now convert the security descriptor back to 
   // self-relative
   //
   relSecurityDescriptor = ExAllocatePool( PagedPool, relLength );
   status = RtlAbsoluteToSelfRelativeSD( absSecurityDescriptor,
					 relSecurityDescriptor, &relLength );
   if( !NT_SUCCESS( status )) {

     DbgPrint(("Could not convert absolute SD to relative: %x\n", status ));
   }

   //
   // Final step, free the original security descriptor and return the new one
   //
   ExFreePool( SecurityDescriptor );
   *NewSecurityDescriptor = relSecurityDescriptor;

cleanup:
   ExFreePool( worldSid );
   ExFreePool( absSecurityDescriptor );
   return status;
}
Пример #4
0
//----------------------------------------------------------------------
//
// NTIMakeAbsoluteSD
//
// Takes a self-relative security descriptor and returns an allocated
// absolute version. Caller is responsibile for freeing the allocated
// buffer on success.
// 
//----------------------------------------------------------------------
NTSTATUS NTIMakeAbsoluteSD( PSECURITY_DESCRIPTOR RelSecurityDescriptor, 
			    PSECURITY_DESCRIPTOR *pAbsSecurityDescriptor )
{
   NTSTATUS		status;
   BOOLEAN		DaclPresent, DaclDefaulted, OwnerDefaulted, GroupDefaulted;
   PACL			Dacl;
   PSID			Owner, Group;
   PSECURITY_DESCRIPTOR	 absSecurityDescriptor;

   //
   // Initialize buffer pointers
   //
   absSecurityDescriptor = (PSECURITY_DESCRIPTOR) ExAllocatePool( NonPagedPool, 1024 );
   *pAbsSecurityDescriptor = absSecurityDescriptor;

   //
   // Create an absolute-form security descriptor for manipulation.
   // The one on the security descriptor is in self-relative form.
   //
   status = RtlCreateSecurityDescriptor( absSecurityDescriptor,
					 SECURITY_DESCRIPTOR_REVISION );
   if( !NT_SUCCESS( status ) ) {

	  DbgPrint(("Secsys: Unable to initialize security descriptor\n"));
	  goto cleanup;
   }

   //
   // Locate the descriptor's DACL and apply the DACL to the new 
   // descriptor we're going to modify
   //
   status = RtlGetDaclSecurityDescriptor( RelSecurityDescriptor,
					  &DaclPresent,
					  &Dacl,
					  &DaclDefaulted );
   if( !NT_SUCCESS( status ) || !DaclPresent ) {

     if( !NT_SUCCESS( status )) {

       DbgPrint(("Secsys: Error obtaining security descriptor's DACL: %x\n", status ));

     } else {

       DbgPrint(("Secsys: Security descriptor does not have a DACL\n" ));
     }

     goto cleanup;
   }

   status = RtlSetDaclSecurityDescriptor( absSecurityDescriptor,
					  DaclPresent,
					  Dacl,
					  DaclDefaulted );
   if( !NT_SUCCESS( status )) {

     DbgPrint(("Secsys: Coult not set new security descriptor DACL: %x\n", status ));
     goto cleanup;
   }

   //
   // We would get and apply the SACL at this point, but NT does not export 
   // the appropriate function, RtlGetSaclSecurityDescriptor :-(
   //

   // 
   // Get and apply the owner
   //
   status = RtlGetOwnerSecurityDescriptor( RelSecurityDescriptor,
					   &Owner,
					   &OwnerDefaulted );
   if( !NT_SUCCESS( status )) {

     DbgPrint(("Secsys: Could not security descriptor owner: %x\n", Owner ));
     goto cleanup;
   }

   status = RtlSetOwnerSecurityDescriptor( absSecurityDescriptor,
					   Owner,
					   OwnerDefaulted );

   if( !NT_SUCCESS( status )) {

     DbgPrint(("Secsys: Could not set owner: %x\n", status ));
     goto cleanup;
   }

   //
   // Get and apply group
   //
   status = RtlGetGroupSecurityDescriptor( RelSecurityDescriptor,
					   &Group,
					   &GroupDefaulted );
   if( !NT_SUCCESS( status )) {

     DbgPrint(("Secsys: Could not security descriptor group: %x\n", Owner ));
     goto cleanup;
   }

   status = RtlSetGroupSecurityDescriptor( absSecurityDescriptor,
					   Group,
					   GroupDefaulted );

   if( !NT_SUCCESS( status )) {

     DbgPrint(("Secsys: Could not set group: %x\n", status ));
     goto cleanup;
   }

   //
   // Finally, make sure that what we made is valid
   //
   if( !RtlValidSecurityDescriptor( absSecurityDescriptor )) {

     DbgPrint(("Secsys: absolute descriptor not valid!\n"));
     status = STATUS_UNSUCCESSFUL;
   }

   //
   // Done! Return.
   //
   
  cleanup:

   if( !NT_SUCCESS( status ) ) {

     ExFreePool( absSecurityDescriptor );
   }
   return status;
}
static
DWORD
LwpsLegacyCreateSecurityDescriptor(
    IN BOOLEAN bIsWorldReadable,
    IN OUT PSECURITY_DESCRIPTOR_ABSOLUTE *ppSecurityDescriptor
    )
{
    NTSTATUS status = STATUS_SUCCESS;
    int EE = 0;
    PSECURITY_DESCRIPTOR_ABSOLUTE pSecDesc = NULL;
    PACL pDacl = NULL;
    PSID pRootSid = NULL;
    PSID pAdminsSid = NULL;
    PSID pEveryoneSid = NULL;
    PSID pOwnerSid = NULL;
    PSID pGroupSid = NULL;
    DWORD dwError = 0;

    status = RtlAllocateWellKnownSid(WinLocalSystemSid, NULL, &pRootSid);
    GOTO_CLEANUP_ON_STATUS_EE(status, EE);

    status = RtlAllocateWellKnownSid(WinBuiltinAdministratorsSid, NULL, &pAdminsSid);
    GOTO_CLEANUP_ON_STATUS_EE(status, EE);

    if (bIsWorldReadable)
    {
        status = RtlAllocateWellKnownSid(WinWorldSid, NULL, &pEveryoneSid);
        GOTO_CLEANUP_ON_STATUS_EE(status, EE);
    }

    status = LW_RTL_ALLOCATE(
                    &pSecDesc,
                    VOID,
                    SECURITY_DESCRIPTOR_ABSOLUTE_MIN_SIZE);
    GOTO_CLEANUP_ON_STATUS_EE(status, EE);

    status = RtlCreateSecurityDescriptorAbsolute(
                    pSecDesc,
                    SECURITY_DESCRIPTOR_REVISION);
    GOTO_CLEANUP_ON_STATUS_EE(status, EE);

    // Owner: Root

    status = RtlDuplicateSid(&pOwnerSid, pRootSid);
    GOTO_CLEANUP_ON_STATUS_EE(status, EE);

    status = RtlSetOwnerSecurityDescriptor(
                    pSecDesc,
                    pOwnerSid,
                    FALSE);
    GOTO_CLEANUP_ON_STATUS_EE(status, EE);
    pOwnerSid = NULL;

    // Group: Administrators

    status = RtlDuplicateSid(&pGroupSid, pAdminsSid);
    GOTO_CLEANUP_ON_STATUS_EE(status, EE);

    status = RtlSetGroupSecurityDescriptor(
                    pSecDesc,
                    pGroupSid,
                    FALSE);
    GOTO_CLEANUP_ON_STATUS_EE(status, EE);
    pGroupSid = NULL;

    // Do not set Sacl currently

    // DACL
    status = LwpsLegacyBuildRestrictedDaclForKey(
                    pRootSid,
                    pEveryoneSid,
                    &pDacl);
    GOTO_CLEANUP_ON_STATUS_EE(status, EE);

    status = RtlSetDaclSecurityDescriptor(
                    pSecDesc,
                    TRUE,
                    pDacl,
                    FALSE);
    GOTO_CLEANUP_ON_STATUS_EE(status, EE);
    pDacl = NULL;

    if (!RtlValidSecurityDescriptor(pSecDesc))
    {
        status = STATUS_INVALID_SECURITY_DESCR;
        GOTO_CLEANUP_ON_STATUS_EE(status, EE);
    }

cleanup:
    if (status)
    {
        if (pSecDesc)
        {
            LwpsLegacyFreeSecurityDescriptor(&pSecDesc);
        }
    }

    LW_RTL_FREE(&pDacl);
    LW_RTL_FREE(&pRootSid);
    LW_RTL_FREE(&pAdminsSid);
    LW_RTL_FREE(&pEveryoneSid);
    LW_RTL_FREE(&pOwnerSid);
    LW_RTL_FREE(&pGroupSid);

    *ppSecurityDescriptor = pSecDesc;

    dwError = LwNtStatusToWin32Error(status);
    LSA_PSTORE_LOG_LEAVE_ERROR_EE(dwError, EE);
    return dwError;
}
Пример #6
0
/******************************************************************************
 * IsValidSecurityDescriptor [ADVAPI32.@]
 *
 * PARAMS
 *   lpsecdesc []
 */
BOOL WINAPI
IsValidSecurityDescriptor( PSECURITY_DESCRIPTOR SecurityDescriptor )
{
    CallWin32ToNt (RtlValidSecurityDescriptor(SecurityDescriptor));
}
Пример #7
0
BOOL
EditDefaultDacl(
    HWND    hwndOwner,
    HANDLE  Instance,
    HANDLE  MyToken
    )
{
    NTSTATUS Status;
    BOOL    Success = FALSE;
    DWORD   EditResult;
    HANDLE  Token = NULL;
    PTOKEN_DEFAULT_DACL DefaultDacl = NULL;
    PSECURITY_DESCRIPTOR SecurityDescriptor = NULL;
    PTOKEN_OWNER Owner = NULL;
    PTOKEN_PRIMARY_GROUP PrimaryGroup = NULL;
    WCHAR string[MAX_STRING_LENGTH];

    //
    // Get the window text so we can use it as the token name
    //

    GetWindowTextW(((PMYTOKEN)MyToken)->hwnd, string, sizeof(string)/sizeof(*string));


    //
    // Get a handle to the token
    //

    Token = OpenToken(MyToken, TOKEN_QUERY);

    if (Token == NULL) {
        DbgPrint("SECEDIT : Failed to open the token with TOKEN_QUERY access\n");
        goto CleanupAndExit;
    }


    //
    // Read the default DACL from the token
    //

    if (!GetTokenInfo(Token, TokenDefaultDacl, (PPVOID)&DefaultDacl)) {
        DbgPrint("SECEDIT : Failed to read default DACL from token\n");
        goto CleanupAndExit;
    }


    //
    // Get the owner and group of the token
    //

    if (!GetTokenInfo(Token, TokenOwner, (PPVOID)&Owner)) {
        DbgPrint("SECEDIT : Failed to read owner from token\n");
        goto CleanupAndExit;
    }

    if (!GetTokenInfo(Token, TokenPrimaryGroup, (PPVOID)&PrimaryGroup)) {
        DbgPrint("SECEDIT : Failed to read primary group from token\n");
        goto CleanupAndExit;
    }




    //
    // Create a security descriptor
    //

    SecurityDescriptor = Alloc(SECURITY_DESCRIPTOR_MIN_LENGTH);

    if (SecurityDescriptor == NULL) {
        DbgPrint("SECEDIT : Failed to allocate security descriptor\n");
        goto CleanupAndExit;
    }

    Status = RtlCreateSecurityDescriptor(SecurityDescriptor, SECURITY_DESCRIPTOR_REVISION);
    ASSERT(NT_SUCCESS(Status));




    //
    // Set the DACL on the security descriptor
    //

    Status = RtlSetDaclSecurityDescriptor(
                        SecurityDescriptor,
                        TRUE,   // DACL present
                        DefaultDacl->DefaultDacl,
                        FALSE   // DACL defaulted
                        );
    ASSERT(NT_SUCCESS(Status));

    //
    // Put the owner and group in the security descriptor to keep the
    // ACL editor happy
    //

    Status = RtlSetOwnerSecurityDescriptor(
                        SecurityDescriptor,
                        Owner->Owner,
                        FALSE // Owner defaulted
                        );
    ASSERT(NT_SUCCESS(Status));


    Status = RtlSetGroupSecurityDescriptor(
                        SecurityDescriptor,
                        PrimaryGroup->PrimaryGroup,
                        FALSE // Owner defaulted
                        );
    ASSERT(NT_SUCCESS(Status));



    ASSERT(RtlValidSecurityDescriptor(SecurityDescriptor));

    //
    // Call the ACL editor, it will call our ApplySecurity function
    // to store any ACL changes in the token.
    //

    Success = EditTokenDefaultAcl(
                        hwndOwner,
                        Instance,
                        string,
                        MyToken,
                        SecurityDescriptor,
                        &EditResult
                        );
    if (!Success) {
        DbgPrint("SECEDIT: Failed to edit token DACL\n");
    }

CleanupAndExit:

    if (DefaultDacl != NULL) {
        FreeTokenInfo(DefaultDacl);
    }
    if (SecurityDescriptor != NULL) {
        FreeTokenInfo(SecurityDescriptor);
    }
    if (PrimaryGroup != NULL) {
        FreeTokenInfo(PrimaryGroup);
    }
    if (Owner != NULL) {
        FreeTokenInfo(Owner);
    }

    if (Token != NULL) {
        CloseToken(Token);
    }


    return(Success);
}