/************************************************************************* * * file.c * * Process the security on a file * * Copyright Microsoft, 1998 * * * *************************************************************************/ #include #include #include #include #include #include #include #include #include "security.h" #if DBG ULONG DbgPrint( PCH Format, ... ); #ifdef FULL_DEBUG #define DBGPRINT(x) DbgPrint x #else #define DBGPRINT(x) #endif #if DBGTRACE #define TRACE0(x) DbgPrint x #define TRACE1(x) DbgPrint x #else #define TRACE0(x) #define TRACE1(x) #endif #else #define DBGPRINT(x) #define TRACE0(x) #define TRACE1(x) #endif // External data // data.c extern ACCESS_MASK DeniedAccess; // security.c extern PSID SeCreatorOwnerSid; extern PSID SeCreatorGroupSid; FILE_RESULT xxxSetFileSecurity( PWCHAR pFile ); /***************************************************************************** * * xxxProcessFile * * Process the given file for access security holes * * ENTRY: * Param1 (input/output) * Comments * * EXIT: * STATUS_SUCCESS - no error * ****************************************************************************/ FILE_RESULT xxxProcessFile( PWCHAR pFile, PWIN32_FIND_DATAW p, DWORD Level, DWORD Index ) { FILE_RESULT rc; rc = xxxSetFileSecurity( pFile ); return( rc ); } /***************************************************************************** * * xxxSetFileSecurity * * Set the security properties for the given file * * ENTRY: * Param1 (input/output) * Comments * * EXIT: * STATUS_SUCCESS - no error * ****************************************************************************/ FILE_RESULT xxxSetFileSecurity( PWCHAR pFile ) { BOOL rc; BOOL DaclPresent; BOOL Default; BOOL OwnerDefaulted; BOOL GroupDefaulted; FILE_RESULT Result, ReturnResult; DWORD Size, Index; PACL pACL = NULL; PVOID pAce = NULL; SECURITY_INFORMATION Info = 0; DWORD Error; PSECURITY_DESCRIPTOR pSelfSd = NULL; // Absolute SD values PSECURITY_DESCRIPTOR pAbsSd = NULL; DWORD AbsSdSize = 0; PACL pAbsAcl = NULL; DWORD AbsAclSize = 0; PACL pAbsSacl = NULL; DWORD AbsSaclSize = 0; PSID pAbsOwner = NULL; DWORD AbsOwnerSize = 0; PSID pAbsGroup = NULL; DWORD AbsGroupSize = 0; DBGPRINT(( "entering xxxSetFileSecurity(pFile=%ws)\n", pFile )); /* * Get the files current security descriptor */ Size = 0; rc = GetFileSecurityW( pFile, DACL_SECURITY_INFORMATION | OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION, NULL, // pSelfSd 0, &Size ); if( rc ) { Error = GetLastError(); ReportFileResult( FileAccessErrorUserFormat, 0, // Access pFile, NULL, // pAccountName NULL, // pDomainName "%d has no DACL", Error ); DBGPRINT(( "leaving xxxSetFileSecurity(1); returning=FileAccessError\n" )); return( FileAccessError ); } else { pSelfSd = LocalAlloc( LMEM_FIXED, Size ); if( pSelfSd == NULL ) { ReportFileResult( FileAccessErrorUserFormat, 0, // Access pFile, NULL, // pAccountName NULL, // pDomainName "Out of memory skipped entry" ); DBGPRINT(( "leaving xxxSetFileSecurity(2); returning=0\n" )); return( FALSE ); } rc = GetFileSecurityW( pFile, DACL_SECURITY_INFORMATION | OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION, pSelfSd, Size, &Size ); if( !rc ) { Error = GetLastError(); ReportFileResult( FileAccessErrorUserFormat, 0, // Access pFile, NULL, // pAccountName NULL, // pDomainName "%d Could not get DACL", Error ); LocalFree( pSelfSd ); DBGPRINT(( "leaving xxxSetFileSecurity(3); returning=FileAccessError\n" )); return( FileAccessError ); } } // // Now convert the self relative SD to an absolute one. // rc = MakeAbsoluteSD ( pSelfSd, pAbsSd, &AbsSdSize, pAbsAcl, &AbsAclSize, pAbsSacl, &AbsSaclSize, pAbsOwner, &AbsOwnerSize, pAbsGroup, &AbsGroupSize ); if( !rc ) { Error = GetLastError(); if( Error != ERROR_INSUFFICIENT_BUFFER ) { ReportFileResult( FileAccessErrorUserFormat, 0, // Access pFile, NULL, // pAccountName NULL, // pDomainName "%d converting SECURITY_DESCRIPTOR", Error ); LocalFree( pSelfSd ); DBGPRINT(( "leaving xxxSetFileSecurity(4); returning=FileAccessError\n" )); return( FileAccessError ); } // Allocate buffers and now really get the SD pAbsSd = LocalAlloc( LMEM_FIXED, AbsSdSize ); pAbsAcl = LocalAlloc( LMEM_FIXED, AbsAclSize ); pAbsSacl = LocalAlloc( LMEM_FIXED, AbsSaclSize ); pAbsOwner = LocalAlloc( LMEM_FIXED, AbsOwnerSize ); pAbsGroup = LocalAlloc( LMEM_FIXED, AbsGroupSize ); if( !( pAbsSd && pAbsAcl && pAbsSacl && pAbsOwner && pAbsGroup ) ) { ReportFileResult( FileAccessErrorUserFormat, 0, // Access pFile, NULL, // pAccountName NULL, // pDomainName "Allocating memory" ); if( pAbsSd ) LocalFree( pAbsSd ); if( pAbsAcl ) LocalFree( pAbsAcl ); if( pAbsSacl ) LocalFree( pAbsSacl ); if( pAbsOwner ) LocalFree( pAbsOwner ); if( pAbsGroup ) LocalFree( pAbsGroup ); LocalFree( pSelfSd ); DBGPRINT(( "leaving xxxSetFileSecurity(5); returning=FileAccessError\n" )); return( FileAccessError ); } // Try it again rc = MakeAbsoluteSD ( pSelfSd, pAbsSd, &AbsSdSize, pAbsAcl, &AbsAclSize, pAbsSacl, &AbsSaclSize, pAbsOwner, &AbsOwnerSize, pAbsGroup, &AbsGroupSize ); if( !rc ) { Error = GetLastError(); ReportFileResult( FileAccessErrorUserFormat, 0, // Access pFile, NULL, // pAccountName NULL, // pDomainName "%d Making ABSOLUTE SD", Error ); if( pAbsSd ) LocalFree( pAbsSd ); if( pAbsAcl ) LocalFree( pAbsAcl ); if( pAbsSacl ) LocalFree( pAbsSacl ); if( pAbsOwner ) LocalFree( pAbsOwner ); if( pAbsGroup ) LocalFree( pAbsGroup ); LocalFree( pSelfSd ); DBGPRINT(( "leaving xxxSetFileSecurity(6); returning=FileAccessError\n" )); return( FileAccessError ); } } // // Get our new trusted ACL // pACL = GetSecureAcl(); if( pACL == NULL ) { ReportFileResult( FileAccessErrorUserFormat, 0, // Access pFile, NULL, // pAccountName NULL, // pDomainName "Could not get New ACL" ); if( pAbsSd ) LocalFree( pAbsSd ); if( pAbsAcl ) LocalFree( pAbsAcl ); if( pAbsSacl ) LocalFree( pAbsSacl ); if( pAbsOwner ) LocalFree( pAbsOwner ); if( pAbsGroup ) LocalFree( pAbsGroup ); LocalFree( pSelfSd ); DBGPRINT(( "leaving xxxSetFileSecurity(7); returning=FileAccessError\n" )); return( FileAccessError ); } // // Now set the trusted ACL onto the security descriptor // rc = SetSecurityDescriptorDacl( pAbsSd, TRUE, // DACL present pACL, FALSE // Not default ); if( !rc ) { Error = GetLastError(); ReportFileResult( FileAccessErrorUserFormat, 0, // Access pFile, NULL, // pAccountName NULL, // pDomainName "Could not set new ACL in Security Descriptor %d", Error ); if( pAbsSd ) LocalFree( pAbsSd ); if( pAbsAcl ) LocalFree( pAbsAcl ); if( pAbsSacl ) LocalFree( pAbsSacl ); if( pAbsOwner ) LocalFree( pAbsOwner ); if( pAbsGroup ) LocalFree( pAbsGroup ); LocalFree( pSelfSd ); DBGPRINT(( "leaving xxxSetFileSecurity(8); returning=FileAccessError\n" )); return( FileAccessError ); } Info |= DACL_SECURITY_INFORMATION; // // If the owner is not one of the admins, we will grab // it and local admin will now own it // if( pAbsOwner && !IsAllowSid( pAbsOwner ) ) { // Make the local admin own it rc = SetSecurityDescriptorOwner( pAbsSd, GetAdminSid(), FALSE // Not defaulted ); if( !rc ) { Error = GetLastError(); ReportFileResult( FileAccessErrorUserFormat, 0, // Access pFile, NULL, // pAccountName NULL, // pDomainName "Could not set file owner %d", Error ); if( pAbsSd ) LocalFree( pAbsSd ); if( pAbsAcl ) LocalFree( pAbsAcl ); if( pAbsSacl ) LocalFree( pAbsSacl ); if( pAbsOwner ) LocalFree( pAbsOwner ); if( pAbsGroup ) LocalFree( pAbsGroup ); LocalFree( pSelfSd ); DBGPRINT(( "leaving xxxSetFileSecurity(9); returning=FileAccessError\n" )); return( FileAccessError ); } else { Info |= OWNER_SECURITY_INFORMATION; } } #ifdef notdef // WWM - don't worry about the group if( pAbsGroup && !IsAllowSid( pAbsGroup ) ) { // Make the local admin group own it rc = SetSecurityDescriptorGroup( pAbsSd, GetLocalAdminGroupSid(), FALSE // Not defaulted ); if( !rc ) { Error = GetLastError(); ReportFileResult( FileAccessErrorUserFormat, 0, // Access pFile, NULL, // pAccountName NULL, // pDomainName "Could not set file group %d", Error ); if( pAbsSd ) LocalFree( pAbsSd ); if( pAbsAcl ) LocalFree( pAbsAcl ); if( pAbsSacl ) LocalFree( pAbsSacl ); if( pAbsOwner ) LocalFree( pAbsOwner ); if( pAbsGroup ) LocalFree( pAbsGroup ); LocalFree( pSelfSd ); DBGPRINT(( "leaving xxxSetFileSecurity(10); returning=FileAccessError\n" )); return( FileAccessError ); } else { Info |= GROUP_SECURITY_INFORMATION; } } #endif // // Now set the new security descriptor onto the file // rc = SetFileSecurityW( pFile, Info, pAbsSd ); if( !rc ) { Error = GetLastError(); ReportFileResult( FileAccessErrorUserFormat, 0, // Access pFile, NULL, // pAccountName NULL, // pDomainName "Could not set new Security Descriptor %d", Error ); if( pAbsSd ) LocalFree( pAbsSd ); if( pAbsAcl ) LocalFree( pAbsAcl ); if( pAbsSacl ) LocalFree( pAbsSacl ); if( pAbsOwner ) LocalFree( pAbsOwner ); if( pAbsGroup ) LocalFree( pAbsGroup ); LocalFree( pSelfSd ); DBGPRINT(( "leaving xxxSetFileSecurity(11); returning=FileAccessError\n" )); return( FileAccessError ); } if( pAbsSd ) LocalFree( pAbsSd ); if( pAbsAcl ) LocalFree( pAbsAcl ); if( pAbsSacl ) LocalFree( pAbsSacl ); if( pAbsOwner ) LocalFree( pAbsOwner ); if( pAbsGroup ) LocalFree( pAbsGroup ); LocalFree( pSelfSd ); DBGPRINT(( "leaving xxxSetFileSecurity(12); returning=FileOk\n" )); return( FileOk ); } #ifdef notdef // // Get the owner SID // rc = GetSecurityDescriptorOwner( pSelfSd, &Owner, &OwnerDefaulted ); if( !rc ) { // No owner info Owner = NULL; } // // Get the group SID // rc = GetSecurityDescriptorGroup( pSelfSd, &Group, &GroupDefaulted ); if( !rc ) { // No group info Group = NULL; } #endif