2 * Unix SMB/CIFS implementation.
4 * WINREG internal client routines
6 * Copyright (c) 2011 Andreas Schneider <asn@samba.org>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 3 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, see <http://www.gnu.org/licenses/>.
23 #include "include/registry.h"
24 #include "librpc/gen_ndr/ndr_winreg_c.h"
25 #include "rpc_client/cli_winreg_int.h"
26 #include "rpc_server/rpc_ncacn_np.h"
29 * Split path into hive name and subkeyname
30 * normalizations performed:
31 * - if the path contains no '\\' characters,
32 * assume that the legacy format of using '/'
33 * as a separator is used and convert '/' to '\\'
34 * - strip trailing '\\' chars
36 static WERROR
_split_hive_key(TALLOC_CTX
*mem_ctx
,
42 const char *tmp_subkeyname
;
44 if ((path
== NULL
) || (hivename
== NULL
) || (subkeyname
== NULL
)) {
45 return WERR_INVALID_PARAM
;
48 if (strlen(path
) == 0) {
49 return WERR_INVALID_PARAM
;
52 if (strchr(path
, '\\') == NULL
) {
53 *hivename
= talloc_string_sub(mem_ctx
, path
, "/", "\\");
55 *hivename
= talloc_strdup(mem_ctx
, path
);
58 if (*hivename
== NULL
) {
62 /* strip trailing '\\' chars */
63 p
= strrchr(*hivename
, '\\');
64 while ((p
!= NULL
) && (p
[1] == '\0')) {
66 p
= strrchr(*hivename
, '\\');
69 p
= strchr(*hivename
, '\\');
71 if ((p
== NULL
) || (*p
== '\0')) {
72 /* just the hive - no subkey given */
78 *subkeyname
= talloc_strdup(mem_ctx
, tmp_subkeyname
);
79 if (*subkeyname
== NULL
) {
86 static NTSTATUS
_winreg_int_openkey(TALLOC_CTX
*mem_ctx
,
87 const struct auth_serversupplied_info
*session_info
,
88 struct messaging_context
*msg_ctx
,
89 struct dcerpc_binding_handle
**h
,
94 struct policy_handle
*hive_handle
,
95 struct policy_handle
*key_handle
,
98 static struct client_address client_id
;
99 struct dcerpc_binding_handle
*binding_handle
;
100 struct winreg_String wkey
, wkeyclass
;
102 WERROR result
= WERR_OK
;
104 strlcpy(client_id
.addr
, "127.0.0.1", sizeof(client_id
.addr
));
105 client_id
.name
= "127.0.0.1";
107 status
= rpcint_binding_handle(mem_ctx
,
113 if (!NT_STATUS_IS_OK(status
)) {
114 DEBUG(0, ("dcerpc_winreg_int_openkey: Could not connect to winreg pipe: %s\n",
120 case HKEY_LOCAL_MACHINE
:
121 status
= dcerpc_winreg_OpenHKLM(binding_handle
,
128 case HKEY_CLASSES_ROOT
:
129 status
= dcerpc_winreg_OpenHKCR(binding_handle
,
137 status
= dcerpc_winreg_OpenHKU(binding_handle
,
144 case HKEY_CURRENT_USER
:
145 status
= dcerpc_winreg_OpenHKCU(binding_handle
,
152 case HKEY_PERFORMANCE_DATA
:
153 status
= dcerpc_winreg_OpenHKPD(binding_handle
,
161 result
= WERR_INVALID_PARAMETER
;
162 status
= NT_STATUS_OK
;
164 if (!NT_STATUS_IS_OK(status
)) {
165 talloc_free(binding_handle
);
168 if (!W_ERROR_IS_OK(result
)) {
169 talloc_free(binding_handle
);
178 enum winreg_CreateAction action
= REG_ACTION_NONE
;
180 ZERO_STRUCT(wkeyclass
);
183 status
= dcerpc_winreg_CreateKey(binding_handle
,
195 case REG_ACTION_NONE
:
196 DEBUG(8, ("dcerpc_winreg_int_openkey: createkey"
197 " did nothing -- huh?\n"));
199 case REG_CREATED_NEW_KEY
:
200 DEBUG(8, ("dcerpc_winreg_int_openkey: createkey"
201 " created %s\n", key
));
203 case REG_OPENED_EXISTING_KEY
:
204 DEBUG(8, ("dcerpc_winreg_int_openkey: createkey"
205 " opened existing %s\n", key
));
209 status
= dcerpc_winreg_OpenKey(binding_handle
,
218 if (!NT_STATUS_IS_OK(status
)) {
219 talloc_free(binding_handle
);
222 if (!W_ERROR_IS_OK(result
)) {
223 talloc_free(binding_handle
);
233 NTSTATUS
dcerpc_winreg_int_openkey(TALLOC_CTX
*mem_ctx
,
234 const struct auth_serversupplied_info
*server_info
,
235 struct messaging_context
*msg_ctx
,
236 struct dcerpc_binding_handle
**h
,
239 uint32_t access_mask
,
240 struct policy_handle
*hive_handle
,
241 struct policy_handle
*key_handle
,
244 char *hivename
= NULL
;
249 result
= _split_hive_key(mem_ctx
, key
, &hivename
, &subkey
);
250 if (!W_ERROR_IS_OK(result
)) {
255 if (strequal(hivename
, "HKLM") ||
256 strequal(hivename
, "HKEY_LOCAL_MACHINE")) {
257 reg_type
= HKEY_LOCAL_MACHINE
;
258 } else if (strequal(hivename
, "HKCR") ||
259 strequal(hivename
, "HKEY_CLASSES_ROOT")) {
260 reg_type
= HKEY_CLASSES_ROOT
;
261 } else if (strequal(hivename
, "HKU") ||
262 strequal(hivename
, "HKEY_USERS")) {
263 reg_type
= HKEY_USERS
;
264 } else if (strequal(hivename
, "HKCU") ||
265 strequal(hivename
, "HKEY_CURRENT_USER")) {
266 reg_type
= HKEY_CURRENT_USER
;
267 } else if (strequal(hivename
, "HKPD") ||
268 strequal(hivename
, "HKEY_PERFORMANCE_DATA")) {
269 reg_type
= HKEY_PERFORMANCE_DATA
;
271 DEBUG(10,("dcerpc_winreg_int_openkey: unrecognised hive key %s\n",
273 *pwerr
= WERR_INVALID_PARAMETER
;
277 return _winreg_int_openkey(mem_ctx
,
290 NTSTATUS
dcerpc_winreg_int_hklm_openkey(TALLOC_CTX
*mem_ctx
,
291 const struct auth_serversupplied_info
*server_info
,
292 struct messaging_context
*msg_ctx
,
293 struct dcerpc_binding_handle
**h
,
296 uint32_t access_mask
,
297 struct policy_handle
*hive_handle
,
298 struct policy_handle
*key_handle
,
301 return _winreg_int_openkey(mem_ctx
,
314 /* vim: set ts=8 sw=8 noet cindent syntax=c.doxygen: */