
/******************************************************************************
**
**  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_group.c
**    Author:    Brian Wotring
**
**    Date:      March 14, 2002.
**    Project:   osiris
**
******************************************************************************/

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

#include <sys/types.h>
#include <sys/stat.h>

#ifdef WIN32
#include "accctrl.h"
#include "aclapi.h"
#else
#include <grp.h>
#endif

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

#ifdef WIN32

osi_bool filter_group( const char *file_path, FILTER_CONTEXT *context )
{
    DWORD dwRtnCode = 0;
    PSID pSidGroup;
    BOOL result     = TRUE;
    LPTSTR GroupName   = NULL;
    DWORD dwGroupName  = 1;
    DWORD dwDomainName = 1;
    SID_NAME_USE eUse  = SidTypeUnknown;

    PSECURITY_DESCRIPTOR pSD;

    unsigned char psd[sizeof(PSECURITY_DESCRIPTOR)];
    unsigned char psid[sizeof(PSID)];

    if( ( context != NULL ) && ( file_path != NULL ) )
    {
        // Allocate memory for the SID structure.
        pSidGroup = (PSID)psid;
    
        // Allocate memory for the security descriptor structure.
        pSD = (PSECURITY_DESCRIPTOR)psd;
    
        // Get the owner SID of the file.
        dwRtnCode = GetNamedSecurityInfo(
                    (LPTSTR)file_path,
                    SE_FILE_OBJECT,
                    GROUP_SECURITY_INFORMATION,
                    NULL,
                    &pSidGroup,
                    NULL,
                    NULL,
                    &pSD);

        // Check GetLastError for GetSecurityInfo error condition.
        if( dwRtnCode != ERROR_SUCCESS ) 
        {
            result = FALSE;
            goto exit_error;
        }
        
        // First call to LookupAccountSid to get the buffer sizes.
        result = LookupAccountSid(
                        NULL,           // local computer
                        pSidGroup,
                        GroupName,
                        (LPDWORD)&dwGroupName,
                        NULL,
                        (LPDWORD)&dwDomainName,
                        &eUse);
        
        // Reallocate memory for the buffers.
        GroupName = (char *)GlobalAlloc( GMEM_FIXED, dwGroupName );
        
        // Check GetLastError for GlobalAlloc error condition.
        if( GroupName == NULL ) 
        {
            result = FALSE;
            goto exit_error;
        }
        
        // Second call to LookupAccountSid to get the account name.
        result = LookupAccountSid(
                NULL,                      // name of local or remote computer
                pSidGroup,                 // security identifier
                GroupName,                 // account name buffer
                (LPDWORD)&dwGroupName,     // size of account name buffer
                NULL,			           // domain name
                (LPDWORD)&dwDomainName,    // size of domain name buffer
                &eUse);                    // SID type
        
        if( ( result == TRUE ) && ( context->filter_argument != NULL ) )
        {
            if( strcmp( context->filter_argument, GroupName ) == 0 )
            {
                result = TRUE;
                goto exit_gracefully;
            }
        }
    }

exit_gracefully:

    GlobalFree( (HGLOBAL)GroupName );

exit_error:

    GlobalFree( (HGLOBAL)pSD );
    GlobalFree( (HGLOBAL)pSidGroup );

    return result;
}

#else

osi_bool filter_group( const char *file_path, FILTER_CONTEXT *context )
{
    struct group *file_group;
    
    if( context != NULL )
    {
        file_group = getgrgid( context->file_stats->st_gid );
    
        if( ( file_group != NULL ) && ( context->filter_argument != NULL ) )
        {
            if( strcmp( file_group->gr_name, context->filter_argument ) == 0 )
            {                
                return TRUE;
            }
        }
    }

    return FALSE;
}

#endif
