source: trunk/server/source3/services/svc_winreg_glue.c

Last change on this file was 745, checked in by Silvan Scherrer, 13 years ago

Samba Server: updated trunk to 3.6.0

File size: 9.2 KB
Line 
1/*
2 * Unix SMB/CIFS implementation.
3 *
4 * SVC winreg glue
5 *
6 * Copyright (c) 2005 Marcin Krzysztof Porwit
7 * Copyright (c) 2005 Gerald (Jerry) Carter
8 * Copyright (c) 2011 Andreas Schneider <asn@samba.org>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 3 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, see <http://www.gnu.org/licenses/>.
22 */
23
24#include "includes.h"
25#include "services/services.h"
26#include "services/svc_winreg_glue.h"
27#include "rpc_client/cli_winreg_int.h"
28#include "rpc_client/cli_winreg.h"
29#include "../librpc/gen_ndr/ndr_winreg_c.h"
30#include "../libcli/security/security.h"
31
32#define TOP_LEVEL_SERVICES_KEY "SYSTEM\\CurrentControlSet\\Services"
33
34struct security_descriptor* svcctl_gen_service_sd(TALLOC_CTX *mem_ctx)
35{
36 struct security_descriptor *sd = NULL;
37 struct security_acl *theacl = NULL;
38 struct security_ace ace[4];
39 size_t sd_size;
40 size_t i = 0;
41
42 /* Basic access for everyone */
43 init_sec_ace(&ace[i++], &global_sid_World,
44 SEC_ACE_TYPE_ACCESS_ALLOWED, SERVICE_READ_ACCESS, 0);
45
46 init_sec_ace(&ace[i++], &global_sid_Builtin_Power_Users,
47 SEC_ACE_TYPE_ACCESS_ALLOWED, SERVICE_EXECUTE_ACCESS, 0);
48
49 init_sec_ace(&ace[i++], &global_sid_Builtin_Server_Operators,
50 SEC_ACE_TYPE_ACCESS_ALLOWED, SERVICE_ALL_ACCESS, 0);
51 init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators,
52 SEC_ACE_TYPE_ACCESS_ALLOWED, SERVICE_ALL_ACCESS, 0);
53
54 /* Create the security descriptor */
55 theacl = make_sec_acl(mem_ctx,
56 NT4_ACL_REVISION,
57 i,
58 ace);
59 if (theacl == NULL) {
60 return NULL;
61 }
62
63 sd = make_sec_desc(mem_ctx,
64 SECURITY_DESCRIPTOR_REVISION_1,
65 SEC_DESC_SELF_RELATIVE,
66 NULL,
67 NULL,
68 NULL,
69 theacl,
70 &sd_size);
71 if (sd == NULL) {
72 return NULL;
73 }
74
75 return sd;
76}
77
78struct security_descriptor *svcctl_get_secdesc(TALLOC_CTX *mem_ctx,
79 struct messaging_context *msg_ctx,
80 const struct auth_serversupplied_info *session_info,
81 const char *name)
82{
83 struct dcerpc_binding_handle *h = NULL;
84 uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
85 struct policy_handle hive_hnd, key_hnd;
86 struct security_descriptor *sd = NULL;
87 char *key = NULL;
88 NTSTATUS status;
89 WERROR result = WERR_OK;
90
91 key = talloc_asprintf(mem_ctx,
92 "%s\\%s\\Security",
93 TOP_LEVEL_SERVICES_KEY, name);
94 if (key == NULL) {
95 return NULL;
96 }
97
98 status = dcerpc_winreg_int_hklm_openkey(mem_ctx,
99 session_info,
100 msg_ctx,
101 &h,
102 key,
103 false,
104 access_mask,
105 &hive_hnd,
106 &key_hnd,
107 &result);
108 if (!NT_STATUS_IS_OK(status)) {
109 DEBUG(2, ("svcctl_set_secdesc: Could not open %s - %s\n",
110 key, nt_errstr(status)));
111 return NULL;
112 }
113 if (!W_ERROR_IS_OK(result)) {
114 DEBUG(2, ("svcctl_set_secdesc: Could not open %s - %s\n",
115 key, win_errstr(result)));
116 return NULL;
117 }
118
119 status = dcerpc_winreg_query_sd(mem_ctx,
120 h,
121 &key_hnd,
122 "Security",
123 &sd,
124 &result);
125 if (!NT_STATUS_IS_OK(status)) {
126 DEBUG(2, ("svcctl_get_secdesc: error getting value 'Security': "
127 "%s\n", nt_errstr(status)));
128 return NULL;
129 }
130 if (W_ERROR_EQUAL(result, WERR_BADFILE)) {
131 goto fallback_to_default_sd;
132 } else if (!W_ERROR_IS_OK(result)) {
133 DEBUG(2, ("svcctl_get_secdesc: error getting value 'Security': "
134 "%s\n", win_errstr(result)));
135 return NULL;
136 }
137
138 goto done;
139
140fallback_to_default_sd:
141 DEBUG(6, ("svcctl_get_secdesc: constructing default secdesc for "
142 "service [%s]\n", name));
143 sd = svcctl_gen_service_sd(mem_ctx);
144
145done:
146 return sd;
147}
148
149bool svcctl_set_secdesc(struct messaging_context *msg_ctx,
150 const struct auth_serversupplied_info *session_info,
151 const char *name,
152 struct security_descriptor *sd)
153{
154 struct dcerpc_binding_handle *h = NULL;
155 uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
156 struct policy_handle hive_hnd;
157 struct policy_handle key_hnd = { 0, };
158 char *key = NULL;
159 bool ok = false;
160 TALLOC_CTX *tmp_ctx;
161 NTSTATUS status;
162 WERROR result = WERR_OK;
163
164 tmp_ctx = talloc_stackframe();
165 if (tmp_ctx == NULL) {
166 return false;
167 }
168
169 key = talloc_asprintf(tmp_ctx, "%s\\%s", TOP_LEVEL_SERVICES_KEY, name);
170 if (key == NULL) {
171 goto done;
172 }
173
174 status = dcerpc_winreg_int_hklm_openkey(tmp_ctx,
175 session_info,
176 msg_ctx,
177 &h,
178 key,
179 false,
180 access_mask,
181 &hive_hnd,
182 &key_hnd,
183 &result);
184 if (!NT_STATUS_IS_OK(status)) {
185 DEBUG(0, ("svcctl_set_secdesc: Could not open %s - %s\n",
186 key, nt_errstr(status)));
187 goto done;
188 }
189 if (!W_ERROR_IS_OK(result)) {
190 DEBUG(0, ("svcctl_set_secdesc: Could not open %s - %s\n",
191 key, win_errstr(result)));
192 goto done;
193 }
194
195 if (is_valid_policy_hnd(&key_hnd)) {
196 dcerpc_winreg_CloseKey(h, tmp_ctx, &key_hnd, &result);
197 }
198
199 {
200 enum winreg_CreateAction action = REG_ACTION_NONE;
201 struct winreg_String wkey = { 0, };
202 struct winreg_String wkeyclass;
203
204 wkey.name = talloc_asprintf(tmp_ctx, "%s\\Security", key);
205 if (wkey.name == NULL) {
206 result = WERR_NOMEM;
207 goto done;
208 }
209
210 ZERO_STRUCT(wkeyclass);
211 wkeyclass.name = "";
212
213 status = dcerpc_winreg_CreateKey(h,
214 tmp_ctx,
215 &hive_hnd,
216 wkey,
217 wkeyclass,
218 0,
219 access_mask,
220 NULL,
221 &key_hnd,
222 &action,
223 &result);
224 if (!NT_STATUS_IS_OK(status)) {
225 DEBUG(2, ("svcctl_set_secdesc: Could not create key %s: %s\n",
226 wkey.name, nt_errstr(status)));
227 goto done;
228 }
229 if (!W_ERROR_IS_OK(result)) {
230 DEBUG(2, ("svcctl_set_secdesc: Could not create key %s: %s\n",
231 wkey.name, win_errstr(result)));
232 goto done;
233 }
234
235 status = dcerpc_winreg_set_sd(tmp_ctx,
236 h,
237 &key_hnd,
238 "Security",
239 sd,
240 &result);
241 if (!NT_STATUS_IS_OK(status)) {
242 goto done;
243 }
244 if (!W_ERROR_IS_OK(result)) {
245 goto done;
246 }
247 }
248
249 ok = true;
250
251done:
252 if (is_valid_policy_hnd(&key_hnd)) {
253 dcerpc_winreg_CloseKey(h, tmp_ctx, &key_hnd, &result);
254 }
255
256 talloc_free(tmp_ctx);
257 return ok;
258}
259
260const char *svcctl_get_string_value(TALLOC_CTX *mem_ctx,
261 struct messaging_context *msg_ctx,
262 const struct auth_serversupplied_info *session_info,
263 const char *key_name,
264 const char *value_name)
265{
266 struct dcerpc_binding_handle *h = NULL;
267 uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
268 struct policy_handle hive_hnd, key_hnd;
269 const char *data = NULL;
270 char *path = NULL;
271 TALLOC_CTX *tmp_ctx;
272 NTSTATUS status;
273 WERROR result = WERR_OK;
274
275 tmp_ctx = talloc_stackframe();
276 if (tmp_ctx == NULL) {
277 return NULL;
278 }
279
280 path = talloc_asprintf(tmp_ctx, "%s\\%s",
281 TOP_LEVEL_SERVICES_KEY, key_name);
282 if (path == NULL) {
283 goto done;
284 }
285
286 status = dcerpc_winreg_int_hklm_openkey(tmp_ctx,
287 session_info,
288 msg_ctx,
289 &h,
290 path,
291 false,
292 access_mask,
293 &hive_hnd,
294 &key_hnd,
295 &result);
296 if (!NT_STATUS_IS_OK(status)) {
297 DEBUG(2, ("svcctl_get_string_value: Could not open %s - %s\n",
298 path, nt_errstr(status)));
299 goto done;
300 }
301 if (!W_ERROR_IS_OK(result)) {
302 DEBUG(2, ("svcctl_get_string_value: Could not open %s - %s\n",
303 path, win_errstr(result)));
304 goto done;
305 }
306
307 status = dcerpc_winreg_query_sz(mem_ctx,
308 h,
309 &key_hnd,
310 value_name,
311 &data,
312 &result);
313
314done:
315 talloc_free(tmp_ctx);
316 return data;
317}
318
319/********************************************************************
320********************************************************************/
321
322const char *svcctl_lookup_dispname(TALLOC_CTX *mem_ctx,
323 struct messaging_context *msg_ctx,
324 const struct auth_serversupplied_info *session_info,
325 const char *name)
326{
327 const char *display_name = NULL;
328
329 display_name = svcctl_get_string_value(mem_ctx,
330 msg_ctx,
331 session_info,
332 name,
333 "DisplayName");
334
335 if (display_name == NULL) {
336 display_name = talloc_strdup(mem_ctx, name);
337 }
338
339 return display_name;
340}
341
342/********************************************************************
343********************************************************************/
344
345const char *svcctl_lookup_description(TALLOC_CTX *mem_ctx,
346 struct messaging_context *msg_ctx,
347 const struct auth_serversupplied_info *session_info,
348 const char *name)
349{
350 const char *description = NULL;
351
352 description = svcctl_get_string_value(mem_ctx,
353 msg_ctx,
354 session_info,
355 name,
356 "Description");
357
358 if (description == NULL) {
359 description = talloc_strdup(mem_ctx, "Unix Service");
360 }
361
362 return description;
363}
364
365/* vim: set ts=8 sw=8 noet cindent syntax=c.doxygen: */
Note: See TracBrowser for help on using the repository browser.