vfs_ceph: fix strict_allocate_ftruncate()
[Samba.git] / source3 / services / svc_winreg_glue.c
blob50b9897acde0a4761a8f7657d9263c24cfe6b3b8
1 /*
2 * Unix SMB/CIFS implementation.
4 * SVC winreg glue
6 * Copyright (c) 2005 Marcin Krzysztof Porwit
7 * Copyright (c) 2005 Gerald (Jerry) Carter
8 * Copyright (c) 2011 Andreas Schneider <asn@samba.org>
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.
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.
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/>.
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"
32 #define TOP_LEVEL_SERVICES_KEY "SYSTEM\\CurrentControlSet\\Services"
34 struct security_descriptor* svcctl_gen_service_sd(TALLOC_CTX *mem_ctx)
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;
42 /* Basic access for everyone */
43 init_sec_ace(&ace[i++], &global_sid_World,
44 SEC_ACE_TYPE_ACCESS_ALLOWED, SERVICE_READ_ACCESS, 0);
46 init_sec_ace(&ace[i++], &global_sid_Builtin_Power_Users,
47 SEC_ACE_TYPE_ACCESS_ALLOWED, SERVICE_EXECUTE_ACCESS, 0);
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);
54 /* Create the security descriptor */
55 theacl = make_sec_acl(mem_ctx,
56 NT4_ACL_REVISION,
58 ace);
59 if (theacl == NULL) {
60 return NULL;
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;
75 return sd;
78 WERROR svcctl_get_secdesc(struct messaging_context *msg_ctx,
79 const struct auth_session_info *session_info,
80 const char *name,
81 TALLOC_CTX *mem_ctx,
82 struct security_descriptor **psd)
84 struct dcerpc_binding_handle *h = NULL;
85 uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
86 struct policy_handle hive_hnd, key_hnd;
87 struct security_descriptor *sd = NULL;
88 char *key = NULL;
89 NTSTATUS status;
90 WERROR result = WERR_OK;
92 key = talloc_asprintf(mem_ctx,
93 "%s\\%s\\Security",
94 TOP_LEVEL_SERVICES_KEY, name);
95 if (key == NULL) {
96 return WERR_NOT_ENOUGH_MEMORY;
99 status = dcerpc_winreg_int_hklm_openkey(mem_ctx,
100 session_info,
101 msg_ctx,
103 key,
104 false,
105 access_mask,
106 &hive_hnd,
107 &key_hnd,
108 &result);
109 if (!NT_STATUS_IS_OK(status)) {
110 DEBUG(2, ("svcctl_set_secdesc: Could not open %s - %s\n",
111 key, nt_errstr(status)));
112 return WERR_INTERNAL_ERROR;
114 if (!W_ERROR_IS_OK(result)) {
115 DEBUG(2, ("svcctl_set_secdesc: Could not open %s - %s\n",
116 key, win_errstr(result)));
117 return result;
120 status = dcerpc_winreg_query_sd(mem_ctx,
122 &key_hnd,
123 "Security",
124 &sd,
125 &result);
126 if (!NT_STATUS_IS_OK(status)) {
127 DEBUG(2, ("svcctl_get_secdesc: error getting value 'Security': "
128 "%s\n", nt_errstr(status)));
129 return WERR_INTERNAL_ERROR;
131 if (W_ERROR_EQUAL(result, WERR_FILE_NOT_FOUND)) {
132 goto fallback_to_default_sd;
133 } else if (!W_ERROR_IS_OK(result)) {
134 DEBUG(2, ("svcctl_get_secdesc: error getting value 'Security': "
135 "%s\n", win_errstr(result)));
136 return result;
139 goto done;
141 fallback_to_default_sd:
142 DEBUG(6, ("svcctl_get_secdesc: constructing default secdesc for "
143 "service [%s]\n", name));
144 sd = svcctl_gen_service_sd(mem_ctx);
145 if (sd == NULL) {
146 return WERR_NOT_ENOUGH_MEMORY;
149 done:
150 *psd = sd;
151 return WERR_OK;
154 bool svcctl_set_secdesc(struct messaging_context *msg_ctx,
155 const struct auth_session_info *session_info,
156 const char *name,
157 struct security_descriptor *sd)
159 struct dcerpc_binding_handle *h = NULL;
160 uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
161 struct policy_handle hive_hnd;
162 struct policy_handle key_hnd = { 0, };
163 char *key = NULL;
164 bool ok = false;
165 TALLOC_CTX *tmp_ctx;
166 NTSTATUS status;
167 WERROR result = WERR_OK;
169 tmp_ctx = talloc_stackframe();
170 if (tmp_ctx == NULL) {
171 return false;
174 key = talloc_asprintf(tmp_ctx, "%s\\%s", TOP_LEVEL_SERVICES_KEY, name);
175 if (key == NULL) {
176 goto done;
179 status = dcerpc_winreg_int_hklm_openkey(tmp_ctx,
180 session_info,
181 msg_ctx,
183 key,
184 false,
185 access_mask,
186 &hive_hnd,
187 &key_hnd,
188 &result);
189 if (!NT_STATUS_IS_OK(status)) {
190 DEBUG(0, ("svcctl_set_secdesc: Could not open %s - %s\n",
191 key, nt_errstr(status)));
192 goto done;
194 if (!W_ERROR_IS_OK(result)) {
195 DEBUG(0, ("svcctl_set_secdesc: Could not open %s - %s\n",
196 key, win_errstr(result)));
197 goto done;
200 if (is_valid_policy_hnd(&key_hnd)) {
201 dcerpc_winreg_CloseKey(h, tmp_ctx, &key_hnd, &result);
205 enum winreg_CreateAction action = REG_ACTION_NONE;
206 struct winreg_String wkey = { 0, };
207 struct winreg_String wkeyclass;
209 wkey.name = talloc_asprintf(tmp_ctx, "%s\\Security", key);
210 if (wkey.name == NULL) {
211 result = WERR_NOT_ENOUGH_MEMORY;
212 goto done;
215 ZERO_STRUCT(wkeyclass);
216 wkeyclass.name = "";
218 status = dcerpc_winreg_CreateKey(h,
219 tmp_ctx,
220 &hive_hnd,
221 wkey,
222 wkeyclass,
224 access_mask,
225 NULL,
226 &key_hnd,
227 &action,
228 &result);
229 if (!NT_STATUS_IS_OK(status)) {
230 DEBUG(2, ("svcctl_set_secdesc: Could not create key %s: %s\n",
231 wkey.name, nt_errstr(status)));
232 goto done;
234 if (!W_ERROR_IS_OK(result)) {
235 DEBUG(2, ("svcctl_set_secdesc: Could not create key %s: %s\n",
236 wkey.name, win_errstr(result)));
237 goto done;
240 status = dcerpc_winreg_set_sd(tmp_ctx,
242 &key_hnd,
243 "Security",
245 &result);
246 if (!NT_STATUS_IS_OK(status)) {
247 goto done;
249 if (!W_ERROR_IS_OK(result)) {
250 goto done;
254 ok = true;
256 done:
257 if (is_valid_policy_hnd(&key_hnd)) {
258 dcerpc_winreg_CloseKey(h, tmp_ctx, &key_hnd, &result);
261 talloc_free(tmp_ctx);
262 return ok;
265 const char *svcctl_get_string_value(TALLOC_CTX *mem_ctx,
266 struct messaging_context *msg_ctx,
267 const struct auth_session_info *session_info,
268 const char *key_name,
269 const char *value_name)
271 struct dcerpc_binding_handle *h = NULL;
272 uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
273 struct policy_handle hive_hnd, key_hnd;
274 const char *data = NULL;
275 char *path = NULL;
276 TALLOC_CTX *tmp_ctx;
277 NTSTATUS status;
278 WERROR result = WERR_OK;
280 tmp_ctx = talloc_stackframe();
281 if (tmp_ctx == NULL) {
282 return NULL;
285 path = talloc_asprintf(tmp_ctx, "%s\\%s",
286 TOP_LEVEL_SERVICES_KEY, key_name);
287 if (path == NULL) {
288 goto done;
291 status = dcerpc_winreg_int_hklm_openkey(tmp_ctx,
292 session_info,
293 msg_ctx,
295 path,
296 false,
297 access_mask,
298 &hive_hnd,
299 &key_hnd,
300 &result);
301 if (!NT_STATUS_IS_OK(status)) {
302 DEBUG(2, ("svcctl_get_string_value: Could not open %s - %s\n",
303 path, nt_errstr(status)));
304 goto done;
306 if (!W_ERROR_IS_OK(result)) {
307 DEBUG(2, ("svcctl_get_string_value: Could not open %s - %s\n",
308 path, win_errstr(result)));
309 goto done;
312 status = dcerpc_winreg_query_sz(mem_ctx,
314 &key_hnd,
315 value_name,
316 &data,
317 &result);
319 done:
320 talloc_free(tmp_ctx);
321 return data;
324 /********************************************************************
325 ********************************************************************/
327 const char *svcctl_lookup_dispname(TALLOC_CTX *mem_ctx,
328 struct messaging_context *msg_ctx,
329 const struct auth_session_info *session_info,
330 const char *name)
332 const char *display_name = NULL;
334 display_name = svcctl_get_string_value(mem_ctx,
335 msg_ctx,
336 session_info,
337 name,
338 "DisplayName");
340 if (display_name == NULL) {
341 display_name = talloc_strdup(mem_ctx, name);
344 return display_name;
347 /********************************************************************
348 ********************************************************************/
350 const char *svcctl_lookup_description(TALLOC_CTX *mem_ctx,
351 struct messaging_context *msg_ctx,
352 const struct auth_session_info *session_info,
353 const char *name)
355 const char *description = NULL;
357 description = svcctl_get_string_value(mem_ctx,
358 msg_ctx,
359 session_info,
360 name,
361 "Description");
363 if (description == NULL) {
364 description = talloc_strdup(mem_ctx, "Unix Service");
367 return description;
370 /* vim: set ts=8 sw=8 noet cindent syntax=c.doxygen: */