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