| /* |
| * __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; |
| } |