

/******************************************************************************
**
**  Copyright (C) 2001  - the shmoo group -
**
**  This program is free software; you can redistribute it and/or
**  modify it, however, you cannot sell it.
**
**  This program is distributed in the hope that it will be useful,
**  but WITHOUT ANY WARRANTY; without even the implied warranty of
**  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
**
**  You should have received a copy of the license attached to the
**  use of this software.  If not, visit www.shmoo.com/osiris for
**  details.
**
******************************************************************************/

/******************************************************************************
**
**    The Shmoo Group (TSG)
**
**    File:      filter_sid.c
**    Author:    Brian Wotring
**
**    Date:      April 2, 2002.
**    Project:   osiris
**
******************************************************************************/

#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
#include <string.h>

#include <sys/stat.h>

#include "utilities.h"
#include "scan_record.h"
#include "filter.h"


#ifdef WIN32

#include "accctrl.h"
#include "aclapi.h"

osi_bool GetTextualSid( PSID pSid, LPSTR szTextualSid, LPDWORD dwBufferLen );

osi_bool filter_sid( const char *file_path, FILTER_CONTEXT *context )
{
    char buffer[100] = "\0";

    DWORD result;
    PSID owner_sid;
    PSID group_sid;

    PSECURITY_DESCRIPTOR sd;
    DWORD buffer_size = 99;

    unsigned char psd[sizeof(PSECURITY_DESCRIPTOR)];
    unsigned char osid[sizeof(PSID)];
    unsigned char gsid[sizeof(PSID)];
   
    sd = (PSECURITY_DESCRIPTOR)psd;
    owner_sid = (PSID)osid;
    group_sid = (PSID)gsid;
  

    if( ( file_path ) != NULL && ( context != NULL ) )
    {

        result = GetNamedSecurityInfo( (LPTSTR)file_path,
                                            SE_FILE_OBJECT,
                                            OWNER_SECURITY_INFORMATION,
                                            &owner_sid,
                                            &group_sid,
                                            NULL,
                                            NULL,
                                            &sd );

        if( result == ERROR_SUCCESS  )
        {
            LocalFree( sd );
            LocalFree( owner_sid );
            LocalFree( group_sid );

            if( GetTextualSid( owner_sid, buffer, &buffer_size ) )
            {

                if( strcmp( context->filter_argument, buffer ) == 0 )
                {
                    return TRUE;
                }
            }
        }
    }

    return FALSE;
}


osi_bool GetTextualSid( PSID pSid, LPSTR szTextualSid, LPDWORD dwBufferLen )
{
   PSID_IDENTIFIER_AUTHORITY psia;
   DWORD dwSubAuthorities;
   DWORD dwSidRev = SID_REVISION;
   DWORD dwCounter;
   DWORD dwSidSize;

   // Test if SID passed in is valid.
   if(!IsValidSid(pSid))
   {
      return FALSE;
   }

   // Obtain SidIdentifierAuthority.
   psia = GetSidIdentifierAuthority(pSid);

   // Obtain sidsubauthority count.
   dwSubAuthorities = *GetSidSubAuthorityCount(pSid);

   // Compute buffer length.
   // S-SID_REVISION- + identifierauthority- + subauthorities- + NULL
   dwSidSize = (15 + 12 + (12 * dwSubAuthorities) + 1) * sizeof(TCHAR);

   // Check provided buffer length.
   // If not large enough, indicate proper size and setlasterror

   if (*dwBufferLen < dwSidSize)
   {
     *dwBufferLen = dwSidSize;
     SetLastError(ERROR_INSUFFICIENT_BUFFER);
     return FALSE;
   }

   // Prepare S-SID_REVISION-.
   dwSidSize = wsprintf(szTextualSid, TEXT("S-%lu-"), dwSidRev);

   // Prepare SidIdentifierAuthority.
   if ((psia->Value[0] != 0) || (psia->Value[1] != 0))
   {

      dwSidSize += wsprintf(szTextualSid + lstrlen(szTextualSid),
            TEXT("0x%02hx%02hx%02hx%02hx%02hx%02hx"),
            (USHORT) psia->Value[0],
            (USHORT) psia->Value[1],
            (USHORT) psia->Value[2],
            (USHORT) psia->Value[3],
            (USHORT) psia->Value[4],
            (USHORT) psia->Value[5]);

   }

   else
   {

      dwSidSize += wsprintf(szTextualSid + lstrlen(szTextualSid),
            TEXT("%lu"),
            (ULONG) (psia->Value[5]      ) +
            (ULONG) (psia->Value[4] <<  8) +
            (ULONG) (psia->Value[3] << 16) +
            (ULONG) (psia->Value[2] << 24));
   }

   // Loop through SidSubAuthorities.
   for (dwCounter = 0; dwCounter < dwSubAuthorities; dwCounter++)
   {

      dwSidSize += wsprintf(szTextualSid + dwSidSize, TEXT("-%lu"),
            *GetSidSubAuthority(pSid, dwCounter));
   }

   return TRUE;
}

#else

osi_bool filter_sid( const char *file_path, FILTER_CONTEXT *context )
{
    return FALSE;
}

#endif
