2 * Unix SMB/CIFS implementation.
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/>.
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];
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
,
63 sd
= make_sec_desc(mem_ctx
,
64 SECURITY_DESCRIPTOR_REVISION_1
,
65 SEC_DESC_SELF_RELATIVE
,
78 struct security_descriptor
*svcctl_get_secdesc(TALLOC_CTX
*mem_ctx
,
79 struct messaging_context
*msg_ctx
,
80 const struct auth_serversupplied_info
*server_info
,
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
;
89 WERROR result
= WERR_OK
;
91 key
= talloc_asprintf(mem_ctx
,
93 TOP_LEVEL_SERVICES_KEY
, name
);
98 status
= dcerpc_winreg_int_hklm_openkey(mem_ctx
,
108 if (!NT_STATUS_IS_OK(status
)) {
109 DEBUG(2, ("svcctl_set_secdesc: Could not open %s - %s\n",
110 key
, nt_errstr(status
)));
113 if (!W_ERROR_IS_OK(result
)) {
114 DEBUG(2, ("svcctl_set_secdesc: Could not open %s - %s\n",
115 key
, win_errstr(result
)));
119 status
= dcerpc_winreg_query_sd(mem_ctx
,
125 if (!NT_STATUS_IS_OK(status
)) {
126 DEBUG(2, ("svcctl_get_secdesc: error getting value 'Security': "
127 "%s\n", nt_errstr(status
)));
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
)));
140 fallback_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
);
149 bool svcctl_set_secdesc(struct messaging_context
*msg_ctx
,
150 const struct auth_serversupplied_info
*server_info
,
152 struct security_descriptor
*sd
)
154 struct dcerpc_binding_handle
*h
= NULL
;
155 uint32_t access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
156 struct policy_handle hive_hnd
, key_hnd
;
161 WERROR result
= WERR_OK
;
163 tmp_ctx
= talloc_stackframe();
164 if (tmp_ctx
== NULL
) {
168 key
= talloc_asprintf(tmp_ctx
, "%s\\%s", TOP_LEVEL_SERVICES_KEY
, name
);
173 status
= dcerpc_winreg_int_hklm_openkey(tmp_ctx
,
183 if (!NT_STATUS_IS_OK(status
)) {
184 DEBUG(0, ("svcctl_set_secdesc: Could not open %s - %s\n",
185 key
, nt_errstr(status
)));
188 if (!W_ERROR_IS_OK(result
)) {
189 DEBUG(0, ("svcctl_set_secdesc: Could not open %s - %s\n",
190 key
, win_errstr(result
)));
194 if (is_valid_policy_hnd(&key_hnd
)) {
195 dcerpc_winreg_CloseKey(h
, tmp_ctx
, &key_hnd
, &result
);
199 enum winreg_CreateAction action
= REG_ACTION_NONE
;
200 struct winreg_String wkey
= { 0, };
201 struct winreg_String wkeyclass
;
203 wkey
.name
= talloc_asprintf(tmp_ctx
, "%s\\Security", key
);
204 if (wkey
.name
== NULL
) {
209 ZERO_STRUCT(wkeyclass
);
212 status
= dcerpc_winreg_CreateKey(h
,
223 if (!NT_STATUS_IS_OK(status
)) {
224 DEBUG(2, ("svcctl_set_secdesc: Could not create key %s: %s\n",
225 wkey
.name
, nt_errstr(status
)));
228 if (!W_ERROR_IS_OK(result
)) {
229 DEBUG(2, ("svcctl_set_secdesc: Could not create key %s: %s\n",
230 wkey
.name
, win_errstr(result
)));
234 status
= dcerpc_winreg_set_sd(tmp_ctx
,
240 if (!NT_STATUS_IS_OK(status
)) {
243 if (!W_ERROR_IS_OK(result
)) {
251 if (is_valid_policy_hnd(&key_hnd
)) {
252 dcerpc_winreg_CloseKey(h
, tmp_ctx
, &key_hnd
, &result
);
255 talloc_free(tmp_ctx
);
259 const char *svcctl_get_string_value(TALLOC_CTX
*mem_ctx
,
260 struct messaging_context
*msg_ctx
,
261 const struct auth_serversupplied_info
*server_info
,
262 const char *key_name
,
263 const char *value_name
)
265 struct dcerpc_binding_handle
*h
= NULL
;
266 uint32_t access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
267 struct policy_handle hive_hnd
, key_hnd
;
268 const char *data
= NULL
;
272 WERROR result
= WERR_OK
;
274 tmp_ctx
= talloc_stackframe();
275 if (tmp_ctx
== NULL
) {
279 path
= talloc_asprintf(tmp_ctx
, "%s\\%s",
280 TOP_LEVEL_SERVICES_KEY
, key_name
);
285 status
= dcerpc_winreg_int_hklm_openkey(tmp_ctx
,
295 if (!NT_STATUS_IS_OK(status
)) {
296 DEBUG(2, ("svcctl_get_string_value: Could not open %s - %s\n",
297 path
, nt_errstr(status
)));
300 if (!W_ERROR_IS_OK(result
)) {
301 DEBUG(2, ("svcctl_get_string_value: Could not open %s - %s\n",
302 path
, win_errstr(result
)));
306 status
= dcerpc_winreg_query_sz(mem_ctx
,
314 talloc_free(tmp_ctx
);
318 /********************************************************************
319 ********************************************************************/
321 const char *svcctl_lookup_dispname(TALLOC_CTX
*mem_ctx
,
322 struct messaging_context
*msg_ctx
,
323 const struct auth_serversupplied_info
*server_info
,
326 const char *display_name
= NULL
;
328 display_name
= svcctl_get_string_value(mem_ctx
,
334 if (display_name
== NULL
) {
335 display_name
= talloc_strdup(mem_ctx
, name
);
341 /********************************************************************
342 ********************************************************************/
344 const char *svcctl_lookup_description(TALLOC_CTX
*mem_ctx
,
345 struct messaging_context
*msg_ctx
,
346 const struct auth_serversupplied_info
*server_info
,
349 const char *description
= NULL
;
351 description
= svcctl_get_string_value(mem_ctx
,
357 if (description
== NULL
) {
358 description
= talloc_strdup(mem_ctx
, "Unix Service");
364 /* vim: set ts=8 sw=8 noet cindent syntax=c.doxygen: */