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 <stdarg.h> 24 25 #include "windef.h" 26 #include "winbase.h" 27 #include "wbemcli.h" 28 #include "iads.h" 29 30 #include "wine/debug.h" 31 #include "wbemprox_private.h" 32 33 WINE_DEFAULT_DEBUG_CHANNEL(wbemprox); 34 35 static HRESULT to_byte_array( void *data, DWORD size, VARIANT *var ) 36 { 37 SAFEARRAY *sa; 38 void *sadata; 39 HRESULT hr; 40 41 if (!(sa = SafeArrayCreateVector( VT_UI1, 0, size ))) return E_OUTOFMEMORY; 42 43 hr = SafeArrayAccessData( sa, &sadata ); 44 45 if (SUCCEEDED(hr)) 46 { 47 memcpy( sadata, data, size ); 48 49 SafeArrayUnaccessData( sa ); 50 } 51 else 52 { 53 SafeArrayDestroy( sa ); 54 return hr; 55 } 56 57 set_variant( VT_UI1|VT_ARRAY, 0, sa, var ); 58 return S_OK; 59 } 60 61 static HRESULT get_sd( SECURITY_DESCRIPTOR **sd, DWORD *size ) 62 { 63 BYTE sid_admin_buffer[SECURITY_MAX_SID_SIZE]; 64 SID *sid_admin = (SID*)sid_admin_buffer; 65 BYTE sid_network_buffer[SECURITY_MAX_SID_SIZE]; 66 SID *sid_network = (SID*)sid_network_buffer; 67 BYTE sid_local_buffer[SECURITY_MAX_SID_SIZE]; 68 SID *sid_local = (SID*)sid_local_buffer; 69 BYTE sid_users_buffer[SECURITY_MAX_SID_SIZE]; 70 SID *sid_users = (SID*)sid_users_buffer; 71 BYTE acl_buffer[sizeof(ACL) + 4 * (sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) + SECURITY_MAX_SID_SIZE)]; 72 ACL *acl = (ACL*)acl_buffer; 73 DWORD sid_size; 74 SECURITY_DESCRIPTOR absolute_sd; 75 HRESULT hr = S_OK; 76 77 sid_size = sizeof(sid_admin_buffer); 78 CreateWellKnownSid( WinBuiltinAdministratorsSid, NULL, sid_admin, &sid_size ); 79 80 sid_size = sizeof(sid_network_buffer); 81 CreateWellKnownSid( WinNetworkServiceSid, NULL, sid_network, &sid_size ); 82 83 sid_size = sizeof(sid_local_buffer); 84 CreateWellKnownSid( WinLocalServiceSid, NULL, sid_local, &sid_size ); 85 86 sid_size = sizeof(sid_users_buffer); 87 CreateWellKnownSid( WinAuthenticatedUserSid, NULL, sid_users, &sid_size ); 88 89 InitializeAcl( acl, sizeof(acl_buffer), ACL_REVISION ); 90 91 AddAccessAllowedAceEx( acl, ACL_REVISION, CONTAINER_INHERIT_ACE|INHERITED_ACE, 92 ADS_RIGHT_DS_CREATE_CHILD|ADS_RIGHT_DS_DELETE_CHILD|ADS_RIGHT_ACTRL_DS_LIST|ADS_RIGHT_DS_SELF| 93 ADS_RIGHT_DS_READ_PROP|ADS_RIGHT_DS_WRITE_PROP|READ_CONTROL|WRITE_DAC, 94 sid_admin ); 95 96 AddAccessAllowedAceEx( acl, ACL_REVISION, CONTAINER_INHERIT_ACE|INHERITED_ACE, 97 ADS_RIGHT_DS_CREATE_CHILD|ADS_RIGHT_DS_DELETE_CHILD|ADS_RIGHT_DS_READ_PROP, 98 sid_network ); 99 100 AddAccessAllowedAceEx( acl, ACL_REVISION, CONTAINER_INHERIT_ACE|INHERITED_ACE, 101 ADS_RIGHT_DS_CREATE_CHILD|ADS_RIGHT_DS_DELETE_CHILD|ADS_RIGHT_DS_READ_PROP, 102 sid_local ); 103 104 AddAccessAllowedAceEx( acl, ACL_REVISION, CONTAINER_INHERIT_ACE|INHERITED_ACE, 105 ADS_RIGHT_DS_CREATE_CHILD|ADS_RIGHT_DS_DELETE_CHILD|ADS_RIGHT_DS_READ_PROP, 106 sid_users ); 107 108 InitializeSecurityDescriptor( &absolute_sd, SECURITY_DESCRIPTOR_REVISION ); 109 110 SetSecurityDescriptorOwner( &absolute_sd, sid_admin, TRUE ); 111 SetSecurityDescriptorGroup( &absolute_sd, sid_admin, TRUE ); 112 SetSecurityDescriptorDacl( &absolute_sd, TRUE, acl, TRUE ); 113 114 *size = GetSecurityDescriptorLength( &absolute_sd ); 115 116 *sd = HeapAlloc( GetProcessHeap(), 0, *size ); 117 if (!*sd) 118 hr = E_OUTOFMEMORY; 119 120 if (SUCCEEDED(hr)) 121 { 122 if (!MakeSelfRelativeSD(&absolute_sd, *sd, size)) { 123 HeapFree( GetProcessHeap(), 0, *sd ); 124 *sd = NULL; 125 hr = E_FAIL; 126 } 127 } 128 129 return hr; 130 } 131 132 HRESULT security_get_sd( IWbemClassObject *obj, IWbemClassObject *in, IWbemClassObject **out ) 133 { 134 VARIANT var_sd, retval; 135 IWbemClassObject *sig, *out_params = NULL; 136 HRESULT hr, ret; 137 SECURITY_DESCRIPTOR *sd; 138 DWORD sd_size; 139 140 TRACE("%p, %p\n", in, out); 141 142 hr = create_signature( class_systemsecurityW, method_getsdW, PARAM_OUT, &sig ); 143 144 if (SUCCEEDED(hr)) 145 { 146 hr = IWbemClassObject_SpawnInstance( sig, 0, &out_params ); 147 148 IWbemClassObject_Release( sig ); 149 } 150 151 if (SUCCEEDED(hr)) 152 { 153 ret = get_sd( &sd, &sd_size ); 154 155 if (SUCCEEDED(ret)) 156 { 157 VariantInit( &var_sd ); 158 159 hr = to_byte_array( sd, sd_size, &var_sd ); 160 161 if (SUCCEEDED(hr)) 162 hr = IWbemClassObject_Put( out_params, param_sdW, 0, &var_sd, CIM_UINT8|CIM_FLAG_ARRAY ); 163 164 HeapFree( GetProcessHeap(), 0, sd ); 165 VariantClear( &var_sd ); 166 } 167 168 if (SUCCEEDED(hr)) 169 { 170 set_variant( VT_UI4, ret, NULL, &retval ); 171 hr = IWbemClassObject_Put( out_params, param_returnvalueW, 0, &retval, CIM_UINT32 ); 172 } 173 174 if (SUCCEEDED(hr) && out) 175 { 176 *out = out_params; 177 IWbemClassObject_AddRef( out_params ); 178 } 179 180 IWbemClassObject_Release( out_params ); 181 } 182 183 return hr; 184 } 185 186 187 HRESULT security_set_sd( IWbemClassObject *obj, IWbemClassObject *in, IWbemClassObject **out ) 188 { 189 VARIANT retval; 190 IWbemClassObject *sig, *out_params = NULL; 191 HRESULT hr; 192 193 FIXME("stub\n"); 194 195 hr = create_signature( class_systemsecurityW, method_setsdW, PARAM_OUT, &sig ); 196 197 if (SUCCEEDED(hr)) 198 { 199 hr = IWbemClassObject_SpawnInstance( sig, 0, &out_params ); 200 201 IWbemClassObject_Release( sig ); 202 } 203 204 if (SUCCEEDED(hr)) 205 { 206 set_variant( VT_UI4, S_OK, NULL, &retval ); 207 hr = IWbemClassObject_Put( out_params, param_returnvalueW, 0, &retval, CIM_UINT32 ); 208 209 if (SUCCEEDED(hr) && out) 210 { 211 *out = out_params; 212 IWbemClassObject_AddRef( out_params ); 213 } 214 215 IWbemClassObject_Release( out_params ); 216 } 217 218 return hr; 219 } 220