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
to_byte_array(void * data,DWORD size,VARIANT * var)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
get_sd(SECURITY_DESCRIPTOR ** sd,DWORD * size)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
security_get_sd(IWbemClassObject * obj,IWbemClassObject * in,IWbemClassObject ** out)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
security_set_sd(IWbemClassObject * obj,IWbemClassObject * in,IWbemClassObject ** out)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