1 /* 2 * __SystemSecurity implementation 3 * 4 * Copyright 2014 Vincent Povirk for CodeWeavers 5 * 6 * This library is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Lesser General Public 8 * License as published by the Free Software Foundation; either 9 * version 2.1 of the License, or (at your option) any later version. 10 * 11 * This library is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with this library; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 19 */ 20 21 #define COBJMACROS 22 23 #include "config.h" 24 #include <stdarg.h> 25 26 #include "windef.h" 27 #include "winbase.h" 28 #include "wbemcli.h" 29 #include "iads.h" 30 31 #include "wine/debug.h" 32 #include "wbemprox_private.h" 33 34 WINE_DEFAULT_DEBUG_CHANNEL(wbemprox); 35 36 static HRESULT to_byte_array( void *data, DWORD size, VARIANT *var ) 37 { 38 SAFEARRAY *sa; 39 void *sadata; 40 HRESULT hr; 41 42 if (!(sa = SafeArrayCreateVector( VT_UI1, 0, size ))) return E_OUTOFMEMORY; 43 44 hr = SafeArrayAccessData( sa, &sadata ); 45 46 if (SUCCEEDED(hr)) 47 { 48 memcpy( sadata, data, size ); 49 50 SafeArrayUnaccessData( sa ); 51 } 52 else 53 { 54 SafeArrayDestroy( sa ); 55 return hr; 56 } 57 58 set_variant( VT_UI1|VT_ARRAY, 0, sa, var ); 59 return S_OK; 60 } 61 62 static HRESULT get_sd( SECURITY_DESCRIPTOR **sd, DWORD *size ) 63 { 64 BYTE sid_admin_buffer[SECURITY_MAX_SID_SIZE]; 65 SID *sid_admin = (SID*)sid_admin_buffer; 66 BYTE sid_network_buffer[SECURITY_MAX_SID_SIZE]; 67 SID *sid_network = (SID*)sid_network_buffer; 68 BYTE sid_local_buffer[SECURITY_MAX_SID_SIZE]; 69 SID *sid_local = (SID*)sid_local_buffer; 70 BYTE sid_users_buffer[SECURITY_MAX_SID_SIZE]; 71 SID *sid_users = (SID*)sid_users_buffer; 72 BYTE acl_buffer[sizeof(ACL) + 4 * (sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) + SECURITY_MAX_SID_SIZE)]; 73 ACL *acl = (ACL*)acl_buffer; 74 DWORD sid_size; 75 SECURITY_DESCRIPTOR absolute_sd; 76 HRESULT hr = S_OK; 77 78 sid_size = sizeof(sid_admin_buffer); 79 CreateWellKnownSid( WinBuiltinAdministratorsSid, NULL, sid_admin, &sid_size ); 80 81 sid_size = sizeof(sid_network_buffer); 82 CreateWellKnownSid( WinNetworkServiceSid, NULL, sid_network, &sid_size ); 83 84 sid_size = sizeof(sid_local_buffer); 85 CreateWellKnownSid( WinLocalServiceSid, NULL, sid_local, &sid_size ); 86 87 sid_size = sizeof(sid_users_buffer); 88 CreateWellKnownSid( WinAuthenticatedUserSid, NULL, sid_users, &sid_size ); 89 90 InitializeAcl( acl, sizeof(acl_buffer), ACL_REVISION ); 91 92 AddAccessAllowedAceEx( acl, ACL_REVISION, CONTAINER_INHERIT_ACE|INHERITED_ACE, 93 ADS_RIGHT_DS_CREATE_CHILD|ADS_RIGHT_DS_DELETE_CHILD|ADS_RIGHT_ACTRL_DS_LIST|ADS_RIGHT_DS_SELF| 94 ADS_RIGHT_DS_READ_PROP|ADS_RIGHT_DS_WRITE_PROP|READ_CONTROL|WRITE_DAC, 95 sid_admin ); 96 97 AddAccessAllowedAceEx( acl, ACL_REVISION, CONTAINER_INHERIT_ACE|INHERITED_ACE, 98 ADS_RIGHT_DS_CREATE_CHILD|ADS_RIGHT_DS_DELETE_CHILD|ADS_RIGHT_DS_READ_PROP, 99 sid_network ); 100 101 AddAccessAllowedAceEx( acl, ACL_REVISION, CONTAINER_INHERIT_ACE|INHERITED_ACE, 102 ADS_RIGHT_DS_CREATE_CHILD|ADS_RIGHT_DS_DELETE_CHILD|ADS_RIGHT_DS_READ_PROP, 103 sid_local ); 104 105 AddAccessAllowedAceEx( acl, ACL_REVISION, CONTAINER_INHERIT_ACE|INHERITED_ACE, 106 ADS_RIGHT_DS_CREATE_CHILD|ADS_RIGHT_DS_DELETE_CHILD|ADS_RIGHT_DS_READ_PROP, 107 sid_users ); 108 109 InitializeSecurityDescriptor( &absolute_sd, SECURITY_DESCRIPTOR_REVISION ); 110 111 SetSecurityDescriptorOwner( &absolute_sd, sid_admin, TRUE ); 112 SetSecurityDescriptorGroup( &absolute_sd, sid_admin, TRUE ); 113 SetSecurityDescriptorDacl( &absolute_sd, TRUE, acl, TRUE ); 114 115 *size = GetSecurityDescriptorLength( &absolute_sd ); 116 117 *sd = HeapAlloc( GetProcessHeap(), 0, *size ); 118 if (!*sd) 119 hr = E_OUTOFMEMORY; 120 121 if (SUCCEEDED(hr)) 122 { 123 if (!MakeSelfRelativeSD(&absolute_sd, *sd, size)) { 124 HeapFree( GetProcessHeap(), 0, *sd ); 125 *sd = NULL; 126 hr = E_FAIL; 127 } 128 } 129 130 return hr; 131 } 132 133 HRESULT security_get_sd( IWbemClassObject *obj, IWbemClassObject *in, IWbemClassObject **out ) 134 { 135 VARIANT var_sd, retval; 136 IWbemClassObject *sig, *out_params = NULL; 137 HRESULT hr, ret; 138 SECURITY_DESCRIPTOR *sd; 139 DWORD sd_size; 140 141 TRACE("%p, %p\n", in, out); 142 143 hr = create_signature( class_systemsecurityW, method_getsdW, PARAM_OUT, &sig ); 144 145 if (SUCCEEDED(hr)) 146 { 147 hr = IWbemClassObject_SpawnInstance( sig, 0, &out_params ); 148 149 IWbemClassObject_Release( sig ); 150 } 151 152 if (SUCCEEDED(hr)) 153 { 154 ret = get_sd( &sd, &sd_size ); 155 156 if (SUCCEEDED(ret)) 157 { 158 VariantInit( &var_sd ); 159 160 hr = to_byte_array( sd, sd_size, &var_sd ); 161 162 if (SUCCEEDED(hr)) 163 hr = IWbemClassObject_Put( out_params, param_sdW, 0, &var_sd, CIM_UINT8|CIM_FLAG_ARRAY ); 164 165 HeapFree( GetProcessHeap(), 0, sd ); 166 VariantClear( &var_sd ); 167 } 168 169 if (SUCCEEDED(hr)) 170 { 171 set_variant( VT_UI4, ret, NULL, &retval ); 172 hr = IWbemClassObject_Put( out_params, param_returnvalueW, 0, &retval, CIM_UINT32 ); 173 } 174 175 if (SUCCEEDED(hr) && out) 176 { 177 *out = out_params; 178 IWbemClassObject_AddRef( out_params ); 179 } 180 181 IWbemClassObject_Release( out_params ); 182 } 183 184 return hr; 185 } 186 187 188 HRESULT security_set_sd( IWbemClassObject *obj, IWbemClassObject *in, IWbemClassObject **out ) 189 { 190 VARIANT retval; 191 IWbemClassObject *sig, *out_params = NULL; 192 HRESULT hr; 193 194 FIXME("stub\n"); 195 196 hr = create_signature( class_systemsecurityW, method_setsdW, PARAM_OUT, &sig ); 197 198 if (SUCCEEDED(hr)) 199 { 200 hr = IWbemClassObject_SpawnInstance( sig, 0, &out_params ); 201 202 IWbemClassObject_Release( sig ); 203 } 204 205 if (SUCCEEDED(hr)) 206 { 207 set_variant( VT_UI4, S_OK, NULL, &retval ); 208 hr = IWbemClassObject_Put( out_params, param_returnvalueW, 0, &retval, CIM_UINT32 ); 209 210 if (SUCCEEDED(hr) && out) 211 { 212 *out = out_params; 213 IWbemClassObject_AddRef( out_params ); 214 } 215 216 IWbemClassObject_Release( out_params ); 217 } 218 219 return hr; 220 } 221