/*
 * __SystemSecurity implementation
 *
 * Copyright 2014 Vincent Povirk for CodeWeavers
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library 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.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

#define COBJMACROS

#include "config.h"
#include <stdarg.h>

#include "windef.h"
#include "winbase.h"
#include "wbemcli.h"
#include "iads.h"

#include "wine/debug.h"
#include "wbemprox_private.h"

WINE_DEFAULT_DEBUG_CHANNEL(wbemprox);

static HRESULT to_byte_array( void *data, DWORD size, VARIANT *var )
{
    SAFEARRAY *sa;
    void *sadata;
    HRESULT hr;

    if (!(sa = SafeArrayCreateVector( VT_UI1, 0, size ))) return E_OUTOFMEMORY;

    hr = SafeArrayAccessData( sa, &sadata );

    if (SUCCEEDED(hr))
    {
        memcpy( sadata, data, size );

        SafeArrayUnaccessData( sa );
    }
    else
    {
        SafeArrayDestroy( sa );
        return hr;
    }

    set_variant( VT_UI1|VT_ARRAY, 0, sa, var );
    return S_OK;
}

static HRESULT get_sd( SECURITY_DESCRIPTOR **sd, DWORD *size )
{
    BYTE sid_admin_buffer[SECURITY_MAX_SID_SIZE];
    SID *sid_admin = (SID*)sid_admin_buffer;
    BYTE sid_network_buffer[SECURITY_MAX_SID_SIZE];
    SID *sid_network = (SID*)sid_network_buffer;
    BYTE sid_local_buffer[SECURITY_MAX_SID_SIZE];
    SID *sid_local = (SID*)sid_local_buffer;
    BYTE sid_users_buffer[SECURITY_MAX_SID_SIZE];
    SID *sid_users = (SID*)sid_users_buffer;
    BYTE acl_buffer[sizeof(ACL) + 4 * (sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) + SECURITY_MAX_SID_SIZE)];
    ACL *acl = (ACL*)acl_buffer;
    DWORD sid_size;
    SECURITY_DESCRIPTOR absolute_sd;
    HRESULT hr = S_OK;

    sid_size = sizeof(sid_admin_buffer);
    CreateWellKnownSid( WinBuiltinAdministratorsSid, NULL, sid_admin, &sid_size );

    sid_size = sizeof(sid_network_buffer);
    CreateWellKnownSid( WinNetworkServiceSid, NULL, sid_network, &sid_size );

    sid_size = sizeof(sid_local_buffer);
    CreateWellKnownSid( WinLocalServiceSid, NULL, sid_local, &sid_size );

    sid_size = sizeof(sid_users_buffer);
    CreateWellKnownSid( WinAuthenticatedUserSid, NULL, sid_users, &sid_size );

    InitializeAcl( acl, sizeof(acl_buffer), ACL_REVISION );

    AddAccessAllowedAceEx( acl, ACL_REVISION, CONTAINER_INHERIT_ACE|INHERITED_ACE,
        ADS_RIGHT_DS_CREATE_CHILD|ADS_RIGHT_DS_DELETE_CHILD|ADS_RIGHT_ACTRL_DS_LIST|ADS_RIGHT_DS_SELF|
        ADS_RIGHT_DS_READ_PROP|ADS_RIGHT_DS_WRITE_PROP|READ_CONTROL|WRITE_DAC,
        sid_admin );

    AddAccessAllowedAceEx( acl, ACL_REVISION, CONTAINER_INHERIT_ACE|INHERITED_ACE,
        ADS_RIGHT_DS_CREATE_CHILD|ADS_RIGHT_DS_DELETE_CHILD|ADS_RIGHT_DS_READ_PROP,
        sid_network );

    AddAccessAllowedAceEx( acl, ACL_REVISION, CONTAINER_INHERIT_ACE|INHERITED_ACE,
        ADS_RIGHT_DS_CREATE_CHILD|ADS_RIGHT_DS_DELETE_CHILD|ADS_RIGHT_DS_READ_PROP,
        sid_local );

    AddAccessAllowedAceEx( acl, ACL_REVISION, CONTAINER_INHERIT_ACE|INHERITED_ACE,
        ADS_RIGHT_DS_CREATE_CHILD|ADS_RIGHT_DS_DELETE_CHILD|ADS_RIGHT_DS_READ_PROP,
        sid_users );

    InitializeSecurityDescriptor( &absolute_sd, SECURITY_DESCRIPTOR_REVISION );

    SetSecurityDescriptorOwner( &absolute_sd, sid_admin, TRUE );
    SetSecurityDescriptorGroup( &absolute_sd, sid_admin, TRUE );
    SetSecurityDescriptorDacl( &absolute_sd, TRUE, acl, TRUE );

    *size = GetSecurityDescriptorLength( &absolute_sd );

    *sd = HeapAlloc( GetProcessHeap(), 0, *size );
    if (!*sd)
        hr = E_OUTOFMEMORY;

    if (SUCCEEDED(hr))
    {
        if (!MakeSelfRelativeSD(&absolute_sd, *sd, size)) {
            HeapFree( GetProcessHeap(), 0, *sd );
	    *sd = NULL;
            hr = E_FAIL;
        }
    }

    return hr;
}

HRESULT security_get_sd( IWbemClassObject *obj, IWbemClassObject *in, IWbemClassObject **out )
{
    VARIANT var_sd, retval;
    IWbemClassObject *sig, *out_params = NULL;
    HRESULT hr, ret;
    SECURITY_DESCRIPTOR *sd;
    DWORD sd_size;

    TRACE("%p, %p\n", in, out);

    hr = create_signature( class_systemsecurityW, method_getsdW, PARAM_OUT, &sig );

    if (SUCCEEDED(hr))
    {
        hr = IWbemClassObject_SpawnInstance( sig, 0, &out_params );

        IWbemClassObject_Release( sig );
    }

    if (SUCCEEDED(hr))
    {
        ret = get_sd( &sd, &sd_size );

        if (SUCCEEDED(ret))
        {
            VariantInit( &var_sd );

            hr = to_byte_array( sd, sd_size, &var_sd );

            if (SUCCEEDED(hr))
                hr = IWbemClassObject_Put( out_params, param_sdW, 0, &var_sd, CIM_UINT8|CIM_FLAG_ARRAY );

            HeapFree( GetProcessHeap(), 0, sd );
            VariantClear( &var_sd );
        }

        if (SUCCEEDED(hr))
        {
            set_variant( VT_UI4, ret, NULL, &retval );
            hr = IWbemClassObject_Put( out_params, param_returnvalueW, 0, &retval, CIM_UINT32 );
        }

        if (SUCCEEDED(hr) && out)
        {
            *out = out_params;
            IWbemClassObject_AddRef( out_params );
        }

        IWbemClassObject_Release( out_params );
    }

    return hr;
}


HRESULT security_set_sd( IWbemClassObject *obj, IWbemClassObject *in, IWbemClassObject **out )
{
    VARIANT retval;
    IWbemClassObject *sig, *out_params = NULL;
    HRESULT hr;

    FIXME("stub\n");

    hr = create_signature( class_systemsecurityW, method_setsdW, PARAM_OUT, &sig );

    if (SUCCEEDED(hr))
    {
        hr = IWbemClassObject_SpawnInstance( sig, 0, &out_params );

        IWbemClassObject_Release( sig );
    }

    if (SUCCEEDED(hr))
    {
        set_variant( VT_UI4, S_OK, NULL, &retval );
        hr = IWbemClassObject_Put( out_params, param_returnvalueW, 0, &retval, CIM_UINT32 );

        if (SUCCEEDED(hr) && out)
        {
            *out = out_params;
            IWbemClassObject_AddRef( out_params );
        }

        IWbemClassObject_Release( out_params );
    }

    return hr;
}
