221 lines
6.3 KiB
C
221 lines
6.3 KiB
C
/*
|
|
* __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 <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, IWbemContext *context, 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( L"__SystemSecurity", L"GetSD", 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, L"SD", 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, L"ReturnValue", 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, IWbemContext *context, IWbemClassObject *in, IWbemClassObject **out )
|
|
{
|
|
VARIANT retval;
|
|
IWbemClassObject *sig, *out_params = NULL;
|
|
HRESULT hr;
|
|
|
|
FIXME("stub\n");
|
|
|
|
hr = create_signature( L"__SystemSecurity", L"SetSD", 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, L"ReturnValue", 0, &retval, CIM_UINT32 );
|
|
|
|
if (SUCCEEDED(hr) && out)
|
|
{
|
|
*out = out_params;
|
|
IWbemClassObject_AddRef( out_params );
|
|
}
|
|
|
|
IWbemClassObject_Release( out_params );
|
|
}
|
|
|
|
return hr;
|
|
}
|